I'm writing a ray tracer using SDL2, but to be able to manipulate image pixel by pixel I had to improvise a little:
I create SDL window, then SDL renderer and then SDL texture.
In each iteration of main loop I handle input, then fill pixel buffer with ray tracing results (it's basically an array of unsigned longs, so every pixel is represented as hex 6 numbers), then copy all pixel array to SDL texture, then copy the texture to SDL renderer and then render the frame.
Sounds weird, but I'm more or less happy with how it works now (suggestions welcome though).
The real question is: how would I go with integrating imgui to application that uses such approach?
I've added imgui and SDL bindings from example and tried to integrate it like that, but I do understand that I'm missing a really important part.
int main( int argc, char **argv ) {
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
printf("[Core] SDL error: %s\n", SDL_GetError());
return EXIT_FAILURE;
}
window = SDL_CreateWindow("Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCRWIDTH, SCRHEIGHT, SDL_WINDOW_OPENGL);
SDL_Renderer* renderer = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC );
SDL_Texture* frameBuffer = SDL_CreateTexture( renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, SCRWIDTH, SCRHEIGHT );
ImGui_ImplSdl_Init(window);
ImGuiIO& io = ImGui::GetIO();
io.Fonts->AddFontDefault();
// omitted some stuff
while (!exitapp) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
// omitted some stuff
}
ImGui_ImplSdl_NewFrame(window);
// omitted ray tracing stuff
// Imgui, a little bit modified example code
ImGui::Text("Hello, world!");
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
// locking texture, writing the pixel data to texture, unlocking texture
void* target = 0;
int pitch;
SDL_LockTexture(frameBuffer, NULL, &target, &pitch);
// screen->GetBuffer returns the mentioned before array of unsigned longs with pixel data
memcpy(target, screen->GetBuffer(), SCRWIDTH * SCRHEIGHT * 4);
SDL_UnlockTexture(frameBuffer);
// here's the part where I miss actually getting imgui stuff into frame
// copying whole texture to renderer and actually rendering
SDL_RenderCopy(renderer, frameBuffer, NULL, NULL);
SDL_RenderPresent(renderer);
}
ImGui_ImplSdl_Shutdown();
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
My SDL and OpenGL knowledge is too shallow, so I've decided to go easy way and just create a second SDL window, only for imgui. Not the perfect solution, but it works.
Screenshot here, if anybody is interested.
Ideas on how to solve this are still very welcome though.
Hello,
I am not sure what "SDL Renderer" stands for exactly. ImGui needs rendering of textures triangles, which is supported by any 3d compatible hardware. If your raytracer output a bitmap/texture, what you would typically do in a 3d accelerated rendering context is to splat your texture over your window using 1 textured quad (or 2 triangles). You can freely render the triangles of ImGui over that.
Closing this. Let me know if you have extra questions.
Most helpful comment
Closing this. Let me know if you have extra questions.