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
    Commented Mar 16, 2021 at 19:07

2 Answers 2

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
    Commented Mar 16, 2021 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\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .