Imgui: Question: ImGui with SDL2, using texture as a frame buffer

Created on 23 May 2016  路  3Comments  路  Source: ocornut/imgui

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;
}
backenbinding opengl

Most helpful comment

Closing this. Let me know if you have extra questions.

All 3 comments

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

GrammarLord picture GrammarLord  路  3Comments

ILoveImgui picture ILoveImgui  路  3Comments

bogdaNNNN1 picture bogdaNNNN1  路  3Comments

Folling picture Folling  路  3Comments

ocornut picture ocornut  路  3Comments