1

I'm trying to use all 3 libraries or whatnot but i'm quite confused by the sample code and I can't quite follow the documentation. This is the code and ill explain my confusions below:


#include <iostream>
#include <string> 

#include <SDL2/SDL.h>

#include <GL/glew.h>

#include <imgui/imgui.h>
#include <imgui/imgui_stdlib.h>
#include <imgui/imgui_impl_sdl.h>
#include <imgui/imgui_impl_opengl3.h>




// Main code
int main(int argc, char* argv[])
{
    if (SDL_Init(SDL_INIT_VIDEO) != 0)
    {
        std::cout << SDL_GetError() << std::endl;
        return -1;
    }

    // GL 3.0 + GLSL 130
    const char* glsl_version = "#version 130";
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);

    // Create window with graphics context
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
    SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
    SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
    SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL3 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
    SDL_GLContext gl_context = SDL_GL_CreateContext(window);
    SDL_GL_MakeCurrent(window, gl_context);
    SDL_GL_SetSwapInterval(0); // Disable vsync

    
    if (glewInit() != GLEW_OK) {
        std::cout << "Error initializing glew\n";
    }

    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO();
    io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;     // Enable Keyboard Controls
    //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;      // Enable Gamepad Controls

    // Setup Dear ImGui style
    ImGui::StyleColorsDark();
    //ImGui::StyleColorsClassic();

    // Setup Platform/Renderer backends
    ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
    ImGui_ImplOpenGL3_Init(glsl_version);



    ImFont* font = io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\Arial.ttf", 30.0f);

    ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);

    // Main loop
    bool running = false;
    SDL_Event event;

    while (!running)
    {

        while (SDL_PollEvent(&event))
        {
            ImGui_ImplSDL2_ProcessEvent(&event);
            if (event.type == SDL_QUIT)
                running = true;
            if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window))
                running = true;
        }

        // Start the Dear ImGui frame
        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplSDL2_NewFrame(window);
        ImGui::NewFrame();


        {
                
            static std::string buf = "";

            ImGui::PushFont(font);

            ImGui::Begin("Window");


            ImGui::InputText("Hello", &buf);
            //std::cout << io.Fonts->Fonts.size() << std::endl;


            ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);


            ImGui::End();

            ImGui::PopFont();

        }



        // Rendering
        
        glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
        glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
        glClear(GL_COLOR_BUFFER_BIT);
        ImGui::Render();
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
        SDL_GL_SwapWindow(window);

    }

    // Cleanup
    ImGui_ImplOpenGL3_Shutdown();
    ImGui_ImplSDL2_Shutdown();
    ImGui::DestroyContext();

    SDL_GL_DeleteContext(gl_context);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}


There are a few confusions I have here, starting with there being no SDL_Renderer anywhere within the code. I notice that the display draw color is handled by OpenGL, but the rendering is called via glClear(GL_COLOR_BUFFER_BIT); (I THINK). I'm unsure, though, how I could actually then call any SDL2 functions such as SDL_RenderFillRect() with no SDL_Renderer ? My best hint is this line:

ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
SDL_GL_SwapWindow(window);

where its SDL_GL_SwapWindow() but this I believe just also renders for the OpenGL? I'm not really sure what line out of all the rending actually does what. I mean I would have thought ImGui::Render() would render all ImGui things, but then theres an ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); and then I'm not sure how the SDL_GL_SwapWindow ties in since i've already called glClear(). Additionally, why is there a function called ImGui::EndFrame() but not called in the sample code at the end of a frame and then there is ImGui::NewFrame() for each loop and same for ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplSDL2_NewFrame(window); Can someone please explain some of these things its very confusing.

1 Answers1

0

SDL_Renderer is something you need if you want to use the SDL API for drawing tasks, but it is not required if you just create the OpenGL context with SDL and do all the drawing directly with OpenGL.

but the rendering is called via glClear(GL_COLOR_BUFFER_BIT);

No, glClearclearse part of the current render buffer, in this case, the color (What is the purpose of GL_COLOR_BUFFER_BIT and GL_DEPTH_BUFFER_BIT? )

SDL_GL_SwapWindow(window); brings the contents of the current render buffer (the rendering) to the window SDL_GL_SwapWindow

ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); invokes he drawing of the ImGUI components.

t.niese
  • 39,256
  • 9
  • 74
  • 101
  • thanks! that clears up quite alot of things. I'm still a bit confused what it means to `invoke the drawing of ImGui components and why that's necessary` as well as the reasoning behind having `ImGui::NewFrame()` and the `ImplSDL2 and ImplOpenGL3` ones too per loop but not calling `EndFrame` on them aswell? –  Feb 10 '21 at 14:48
  • for the `SDL_Renderer` api's, is there any reason then to even include SDL2 as part of the project if you can't use its api's considering you already have a renderer? Would it not be more efficient to use GLFW instead? –  Feb 10 '21 at 14:51
  • @wiourowseoif `invoke the drawing of ImGui components` ImgGUI does different OpenGL calls to draw the components, and that has to be done in every frame. `…as part of the project if you can't use its api's considering you already have a renderer` the SDL provides the context and does the swapping, and you still could (if you want) use `SDL_Renderer` in combination with `ImgUI` if you want to do that. `Would it not be more efficient to use GLFW instead?` if you don't need any of the other features SDL provides you could also use GLFW. GLFW is just a slimmer framework than SDL is. – t.niese Feb 10 '21 at 14:54
  • is that line just for ImGUi opengl calls? does `ImGui::Render` do other calles that aren't opengl ones then instead? Uhm im a little unsure still about SDL, when you say context do you mean event handling? And the swapping im not sure about that too much because couldnt you just call something like `glpresentrender()` or whatever the correct opengl function is to draw everything in the renderer, then that way theres no reason to use SDL2 for that? –  Feb 10 '21 at 15:06