Sections

Lightweight GUI library for C++

I recently discovered this tiny, awesome graphical-user-interface library by ocornut.

The best part is that it's really easy to integrate into your OpenGL/DirectX/SDL or whatever project. You need to include 3 files, and define a function callback to render the vertices that the library pumps out each frame.

You'll also want user-input, like mouse-clicks and text-input. These are usually handled in your update-routine or where you poll for events. For example, here's how I do it in my prototyping framework:

void poll_events(const SDL_Event &event)
{
    ImGuiIO &io = ImGui::GetIO();
    switch (event.type)
    {
    case SDL_TEXTINPUT:
        io.AddInputCharacter(event.text.text[0]);
        break;
    case SDL_KEYUP:
        io.KeysDown[event.key.keysym.scancode] = false;
        io.KeyCtrl = (event.key.keysym.mod & KMOD_CTRL) != 0;
        io.KeyShift = (event.key.keysym.mod & KMOD_SHIFT) != 0;
        break;
    // etc...
    }
}

Because the library is a so-called immediate mode GUI, using it is super simple as well:

void render_game(float dt)
{
    clear(0xcc9999ff, 1.0f);
    static float lightColor[4];
    static float attenuation;
    ImGui::NewFrame();
    ImGui::ShowTestWindow();
    ImGui::Begin("Diffuse Shader");
    ImGui::ColorEdit4("lightColor", &lightColor);
    ImGui::SliderFloat("attenuation", &attenuation, 1.0f, 16.0f);
    ImGui::End();
    ImGui::Render();
}

which produces the following result:

imgui_result

I needed to make some small changes to the original code to get pixel perfect text with AA enabled. The first I did was to change the RenderText function to properly round the text position to to integer coordinates, so:

void ImBitmapFont::RenderText(...) const
{
    //...
    // Align to be pixel perfect
    pos.x = (float)(int)pos.x + 0.5f;
    pos.y = (float)(int)pos.y + 0.5f;
    //...
}

becomes

pos.x = (float)(int)(pos.x + 0.5f);
pos.y = (float)(int)(pos.y + 0.5f);

Note that x and y are both positive numbers, so we don't need to handle rounding negative numbers. The second thing I did was to adjust the PixelCenterOffset constant to 0.375 instead of 0.5. A search on Google will give you some interesting stories aboud this magic number ;)

No comments:

Post a Comment