1
\$\begingroup\$

I've tried drawing RenderTexture directly to the ImGui window and I've stumbled upon a bug. Everything is drawn correctly until I center ImGui Image inside the ImGui window.

Centered Image: 11

Not centered Image: 2

As you can see when Image is centered in the ImGui window some lines aren't showing up (they are drawn and I'm not talking about first vertical line, last horizontal etc.) but when Image is slightly off-centered RenderTexture is drawn properly. Is it a bug or am I doing something wrong?

Example source code:

#include "imgui.h"
#include "imgui-SFML.h"

#include <SFML/Graphics.hpp>

const sf::Time TIME_PER_FRAME = sf::seconds(1.0f / 60.0f);
bool isTextureLoaded = false;

void render_grid(sf::RenderTexture &renderTexture)
{
    sf::Vertex line[2];
    for (int i = 0; i <= renderTexture.getSize().y; i += 32)
    {
        line[0] = sf::Vector2f(0, i);
        line[1] = sf::Vector2f(renderTexture.getSize().x, i);
        renderTexture.draw(line, 2, sf::Lines);
    }

    for (int i = 0; i <= renderTexture.getSize().x; i += 32)
    {
        line[0] = sf::Vector2f(i, 0);
        line[1] = sf::Vector2f(i, renderTexture.getSize().y);
        renderTexture.draw(line, 2, sf::Lines);
    }
}

void process_imgui(sf::RenderWindow &window, sf::RenderTexture &renderTexture, sf::Sprite &sprite)
{
    //ImGui::SetNextWindowPos(ImVec2{ 251, 20 });
    ImGui::SetNextWindowSize(ImVec2{ static_cast<float>(window.getSize().x - 251.0f), static_cast<float>(window.getSize().y - 20.0f) });
    ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 0, 0 });
    ImGui::Begin("Tileset", nullptr, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysHorizontalScrollbar);

    renderTexture.clear();
    renderTexture.draw(sprite);
    render_grid(renderTexture);

    //float x = (ImGui::GetWindowSize().x - static_cast<float>(renderTexture.getSize().x)) * 0.5f; //doesn't draw grid correctly
    float x = (ImGui::GetWindowSize().x - static_cast<float>(renderTexture.getSize().x)) * 0.499f; //draws grid correctly
    ImVec2 imagePosition(x, 20.0f);
    ImGui::SetCursorPos(imagePosition);
    ImGui::Image(renderTexture, ImVec2(static_cast<float>(renderTexture.getSize().x), static_cast<float>(renderTexture.getSize().y)));

    static bool saveToFile = true;
    if (saveToFile)
    {
        sf::Image image(renderTexture.getTexture().copyToImage());
        image.saveToFile("correct.png");
        saveToFile = false;
    }

    ImGui::End();
    ImGui::PopStyleVar();
}

int main(void)
{
    sf::RenderTexture renderTexture;
    sf::Texture texture;
    sf::Sprite sprite;

    sf::RenderWindow window(sf::VideoMode(1600, 900), "Test");
    window.setFramerateLimit(60);
    window.resetGLStates();

    texture.loadFromFile("test1.png");
    renderTexture.create(texture.getSize().x, texture.getSize().y);
    sprite.setTexture(texture);

    renderTexture.draw(sprite);
    render_grid(renderTexture);

    ImGui::SFML::Init(window);

    sf::Clock clock;
    sf::Time timeSinceLastUpdate = sf::Time::Zero;

    while (window.isOpen())
    {
        sf::Time elapsedTime = clock.restart();
        timeSinceLastUpdate += elapsedTime;

        while (timeSinceLastUpdate > TIME_PER_FRAME)
        {
            timeSinceLastUpdate -= TIME_PER_FRAME;

            sf::Event event;
            while (window.pollEvent(event))
            {
                ImGui::SFML::ProcessEvent(event);

                if (event.type == sf::Event::Closed)
                    window.close();
            }
        }

        ImGui::SFML::Update(window, elapsedTime);
        process_imgui(window, renderTexture, sprite);

        window.clear();
        ImGui::SFML::Render(window);
        window.display();
    }

    ImGui::SFML::Shutdown();
    return 0;
}

Example texture: test1

\$\endgroup\$
1
  • \$\begingroup\$ It could be a rasterization/sub-pixel issue. The line thickness is small enough that during the rasterization process the lines end up between the pixels and are being discarded. \$\endgroup\$
    – Casey
    Mar 16 at 19:07
1
\$\begingroup\$

As noted in my comment, it could be a rasterization/sub-pixel issue.

The line thickness is small enough that during the rasterization process the lines end up between the pixels and are being discarded.

Try increasing the line thickness to see if that fixes the problem.

\$\endgroup\$
1
  • \$\begingroup\$ @wixy0 Instead of editing this question into a different one where the answer no longer applies, just mark the question as answered via the checkmark and post a new question. \$\endgroup\$
    – Casey
    Mar 16 at 20:41
1
\$\begingroup\$

It was a "rounding error". When you encounter similar bug then make sure your ImGui window/Image inside window are on rounded position. In my case "float x" variable was 39.5f and when I ceiled it everything was rendered correctly. Also you can check if your image size translates to the integer factor (e.g. it's drawn at 1x, 2x, 3x etc. of its real size). This fix is directly from the author of imgui-sfml.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.