ocornut/imgui

SDL2: Use of SDL_Renderer messes up font rendering

THUNDERGROOVE opened this issue · 4 comments

Given the modified sdl_opengl_example:

// ImGui - standalone example application for SDL2 + OpenGL

#include <imgui.h>
#include "imgui_impl_sdl.h"
#include <stdio.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>

int main(int, char**)
{
    if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
        {
            printf("Error: %s\n", SDL_GetError());
            return -1;
        }

    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
    SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
    SDL_DisplayMode current;
    SDL_GetCurrentDisplayMode(0, &current);
    SDL_Window *window = SDL_CreateWindow("ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
    SDL_GLContext glcontext = SDL_GL_CreateContext(window);

    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

    ImGui_ImplSdl_Init(window);

    ImGuiIO& io = ImGui::GetIO();
    io.Fonts->AddFontDefault();

    bool show_test_window = true;
    bool show_another_window = false;
    ImVec4 clear_color = ImColor(114, 144, 154);

    // Main loop
    bool done = false;
    while (!done)
        {
            SDL_Event event;
            while (SDL_PollEvent(&event))
                {
                    ImGui_ImplSdl_ProcessEvent(&event);
                    if (event.type == SDL_QUIT)
                        done = true;
                }
            ImGui_ImplSdl_NewFrame(window);

            {
                static float f = 0.0f;
                ImGui::Text("Hello, world!");
                ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
                ImGui::ColorEdit3("clear color", (float*)&clear_color);
                if (ImGui::Button("Test Window")) show_test_window ^= 1;
                if (ImGui::Button("Another Window")) show_another_window ^= 1;
                ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
            }

            if (show_another_window)
                {
                    ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver);
                    ImGui::Begin("Another Window", &show_another_window);
                    ImGui::Text("Hello");
                    ImGui::End();
                }

            if (show_test_window)
                {
                    ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
                    ImGui::ShowTestWindow(&show_test_window);
                }

            SDL_Rect rect;
            rect.x = 100;
            rect.y = 100;
            rect.w = 50;
            rect.h = 50;

            glViewport(0, 0, (int)ImGui::GetIO().DisplaySize.x, (int)ImGui::GetIO().DisplaySize.y);
            glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
            glClear(GL_COLOR_BUFFER_BIT);
            ImGui::Render();
            SDL_RenderDrawRect(renderer, &rect);
            SDL_RenderPresent(renderer);
            // SDL_GL_SwapWindow(window);  No longer needed.  SDL_RenderPresent does it for us
        }
    ImGui_ImplSdl_Shutdown();
    SDL_GL_DeleteContext(glcontext);  
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}

The each glyph of text is rendered as a solid white rectangle.
Example image

Even if we stop calling SDL_RenderDrawRect in our loop the fonts continue to render incorrectly.

I wish I had more information/knowledge on the subject but I don't have a whole lot of experience with OpenGL.

Thanks.

It looks like SDLRenderer is not compatible with using OpenGL2 calls directly.
Perhaps using the OpenGL3 version (which is unmerged yet) would fix it.
#356

I have now merged the aforementioned example in trunk, see updates in #356
It should work better.

Howver note that SDL_Renderer support different backends and doesn't guarantee OpenGL unlessyou force the underlying render driver when calling SDL_CreateRenderer(). See http://hg.libsdl.org/SDL/file/31b7adf67756/src/render/SDL_sysrender.h

I'm sure that mixing GL and SDL_RenderPresent actually isn't supported

We have a new imgui_impl_sdlrenderer.cpp backend!

FYI, although I personally recommend using native-backends, SDL 2.0.18 (tentative scheduled in 52 days) will add support for a new SDL_RenderGeometry() function which allowed a SDL_Renderer backend to be created.

This is now available on master (currently requires building SDL from latest sources)
#3926 (comment)

(Note the backend currently doesn't support multi-viewports.)