Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [Solved] VBO creates bug ?  (Read 6483 times)

0 Members and 1 Guest are viewing this topic.

Andarann

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
[Solved] VBO creates bug ?
« on: June 02, 2017, 03:57:01 am »
Hello everyone, I hope your projects are all working fine. Because mine, not so much.

I recently started adding OpenGL to my project, to do the 3d rendering while SFML is supposed to manage the windowing and GUI parts. The GUI system itself works very fine without OpenGL, but since I added it graphical bugs have risen.

Some pin-pointing and debugging led me to the conclusion that the command "glBindBuffer" is responsible for my misery, because without it my GUI system works like usual.

Here are the important code chunks :

1)The drawing function of the Container class. This class contains other widgets/parts of the GUI system and renders them if asked. With VBO generated, it only has the color given in"myRenderTexture.get()->clear(sf::Color(0,0,0,200));"
void Container::draw(sf::RenderTarget& target) const
{
    if (updated)//We only do that if there is a need to re-draw the Container
    {
        background.setPosition(sf::Vector2f(0,0));

        myRenderTexture.get()->clear(sf::Color(0,0,0,200));
        background.draw(*myRenderTexture.get());

        for (auto it = allWidgets.begin() ; it != allWidgets.end() ; it++)
            if (it->second.hideState == false)
                renderWidgetDirection(*((it->second).widget), *myRenderTexture.get());

        myRenderTexture.get()->display();

        renderSprite.setTexture(myRenderTexture.get()->getTexture());
    }
    target.draw(renderSprite);
}

2)Most of the Container class declaration
class Container : public Widget{//Ok
public:
     /** Irrelevant stuff */

    virtual void update(sf::RenderWindow& window, sf::Vector2f origin = sf::Vector2f(0,0));
    virtual void draw(sf::RenderTarget& target) const;

private:

    /** Irrelevant stuff */

    sf::Sprite renderSprite;
    std::shared_ptr<sf::RenderTexture> myRenderTexture;

};

3)Constructor of the OpenGLRenderer class. This is where the faulty code bits lie
OpenGLRenderer::OpenGLRenderer()
{
    if (gl3wInit())
    {
        std::cerr << "Failed to initialize gl3w\n";
    }

    if (!sf::Shader::isAvailable())
    {
        std::cerr << "Can't use shaders. Maybe your graphic card is too old ? Check your drivers too !\n";
    }

    GLfloat g_vertex_buffer_data[] = {
    0.1, 0.0, 0.5, -0.5f, -0.5f, 0.0f,
    0.5, 0.4, 0.1, 0.5f, -0.5f, 0.0f,
    1.0, 0.7, 0.0, 0.0f,  0.5f, 0.0f
    };

    glGenBuffers(1, &vertexBufferID);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

    shader.loadFromFile("src/shaders/vertex_test.txt", "src/shaders/frag_test.txt");
}

I really have no idea why this bug occurs. My understanding is that sfml uses opengl, so maybe there is some deadly overlap somewhere ? If anyone could explain me why this doesn't work, I would be thankful forever !
« Last Edit: June 03, 2017, 04:16:30 pm by Andarann »

Andarann

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
Re: VBO creates bug ?
« Reply #1 on: June 02, 2017, 06:17:47 pm »
Some more pin-pointing made me able to add the following elements : the VBO is not the source of the problem.

What happens is the following : the OpenGL triangle is rendering once, then the GUI is rendered, then the program crashes at the function "glDrawArrays". Any idea why ?

dabbertorres

  • Hero Member
  • *****
  • Posts: 505
    • View Profile
    • website/blog
Re: VBO creates bug ?
« Reply #2 on: June 02, 2017, 06:21:03 pm »
The code you've posted doesn't reflect this, so, have you read this?

tl;dr:
sf::RenderWindow::popGLStates()
sf::RenderWindow::pushGLStates()
sf::RenderWindow::resetGLStates()

Andarann

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
Re: VBO creates bug ?
« Reply #3 on: June 02, 2017, 06:34:01 pm »
Hello ! Yes, I added those functions to my code (even with an added resetGLStates(), even if pushGlStates() apparently already does that). The rendering code is the following :

void System::Render()
{
    //if (primaryContainer.wasUpdated())
    //{

    windowMain.clear(sf::Color(0,255,127));//Rendering part

        renderOpenGL();

        windowMain.pushGLStates();
        windowMain.resetGLStates();

            renderWidgets();

        windowMain.popGLStates();

        windowMain.display();
    //}

    numberOfFrames++;
}

Again, they all work separately, but together I'm greeted with a seg fault...

dabbertorres

  • Hero Member
  • *****
  • Posts: 505
    • View Profile
    • website/blog
Re: VBO creates bug ?
« Reply #4 on: June 02, 2017, 06:56:36 pm »
You should be using either resetGLStates() alone, OR pushGLStates() and popGLStates(). Not both. Does that make a difference?

Andarann

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
Re: VBO creates bug ?
« Reply #5 on: June 02, 2017, 07:05:50 pm »
No it doesn't, both these codes result in a seg fault :

windowMain.clear(sf::Color(50,0,0));//Rendering part

        renderOpenGL();

            windowMain.pushGLStates();

            renderWidgets();

            windowMain.popGLStates();

        windowMain.display();

and

windowMain.clear(sf::Color(50,0,0));//Rendering part

        renderOpenGL();

            windowMain.resetGLStates();

            renderWidgets();

        windowMain.display();





dabbertorres

  • Hero Member
  • *****
  • Posts: 505
    • View Profile
    • website/blog
Re: VBO creates bug ?
« Reply #6 on: June 02, 2017, 07:09:14 pm »
Have you used a debugger to trace the source of the seg fault?

Andarann

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
Re: VBO creates bug ?
« Reply #7 on: June 02, 2017, 07:37:53 pm »
Yes : every time the error leads me to glDrawArrays. The following happens : gl is rendered once, then SFML, then the RenderWindow is displayed, then the gl starts and crashes at glDrawArrays. glGetError() doesn't give any error code before the crash. Maybe the problem comes from the gl states set by SFML ?

dabbertorres

  • Hero Member
  • *****
  • Posts: 505
    • View Profile
    • website/blog
Re: VBO creates bug ?
« Reply #8 on: June 02, 2017, 08:01:56 pm »
What code of yours does it pass through first?
First, let's try to prove it's not your code, before looking at SFML.

Can you paste a stack trace, and any relevant code?

Andarann

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
Re: VBO creates bug ?
« Reply #9 on: June 02, 2017, 09:12:05 pm »
Ok so here's the OpenGLRender class :
#include "OpenGLRenderer.hpp"

OpenGLRenderer::OpenGLRenderer()
{
    if (gl3wInit())
    {
        std::cout << "FUCK";
    }

    if (!sf::Shader::isAvailable())
    {
        std::cerr << "Can't use shaders. Maybe your graphic card is too old ? Check your drivers too !\n";
    }

    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);

    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindVertexArray(0);

    shader.loadFromFile("src/shaders/vertex_test.txt", "src/shaders/frag_test.txt");
}

OpenGLRenderer::~OpenGLRenderer()
{

}

void OpenGLRenderer::render(sf::RenderWindow& window)
{
    sf::Shader::bind(&shader);

    glBindVertexArray(VAO);

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

    sf::Shader::bind(NULL);
}

The System class contains both the SFML widget to render and an instance of OpenGLRenderer. Here's the part of the constructor concerning those :

System::System() :  oglpart(),//The OpenGLRenderer instance. It also initializes gl3w here
                    windowMain(sf::VideoMode(INITIAL_WINDOW_WIDTH, INITIAL_WINDOW_HEIGHT), "Game", sf::Style::Resize),
                    primaryContainer(sf::Vector2f(50,50), sf::Vector2f(500, 500), "resources/window_background.png")
{
    /** Initialization of other variables. Does not concern SFML or OpenGL so irrelevant*/
}

And again, the render code :
void System::Render()
{
    if (primaryContainer.wasUpdated())
    {
        windowMain.clear(sf::Color(50,0,0));

            renderOpenGL();

                windowMain.pushGLStates();

                    renderWidgets();

                windowMain.popGLStates();

        windowMain.display();
    }

    numberOfFrames++;
}

Thank you for your time btw. Hope we can solve this quickly... I'm pretty sure this is another function I forget to use/didn't use correctly  ;D

Andarann

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
Re: VBO creates bug ?
« Reply #10 on: June 02, 2017, 09:53:12 pm »
By the way, the Container class renders using a shared_ptr<sf::RenderTexture> and a sf::Sprite. Maybe having sf::RenderTexture as a shared_ptr creates an issue ? I will test & edit, but if the problem comes from here it's a shame because it was effective and convenient.
Code of the Container rendering is here again :
if (updated)//We only do that if there is a need to re-draw the Container
    {
        std::cout << "Drawn\n";
        background.setPosition(sf::Vector2f(0,0));

        myRenderTexture.get()->clear(sf::Color(0,255,0,200));
        background.draw(*myRenderTexture.get());

        for (auto it = allWidgets.begin() ; it != allWidgets.end() ; it++)
            if (it->second.hideState == false)
                renderWidgetDirection(*((it->second).widget), *myRenderTexture.get());

        myRenderTexture.get()->display();

        renderSprite.setTexture(myRenderTexture.get()->getTexture());
    }
    target.draw(renderSprite);

EDIT : Nope, changed to a regular sf::RenderTexture created at each rendering cycle, no change. Now, there's no crash, but the SFML part just doesn't show.
« Last Edit: June 02, 2017, 10:25:58 pm by Andarann »

dabbertorres

  • Hero Member
  • *****
  • Posts: 505
    • View Profile
    • website/blog
Re: VBO creates bug ?
« Reply #11 on: June 03, 2017, 03:17:45 am »
Stack trace of the crash?

Nope, changed to a regular sf::RenderTexture created at each rendering cycle, no change. Now, there's no crash, but the SFML part just doesn't show.
Your System::Render(), shouldn't you only be conditionally calling renderWidgets() if the container was updated? Something like:
void System::Render()
{
    windowMain.clear(sf::Color(50,0,0));
 
    renderOpenGL();

    if (primaryContainer.wasUpdated())
    {
        windowMain.pushGLStates();

            renderWidgets();

        windowMain.popGLStates();
    }

    windowMain.display();
 
    numberOfFrames++;
}

Andarann

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
Re: VBO creates bug ?
« Reply #12 on: June 03, 2017, 03:54:19 am »
No no I can't apply this code, it would cause a lot of problems in the application : the OpenGL rendering would always hide the interface, except when it is updated.

Anyway, I think I've found something really interesting : when I switch to my crappy Integrated graphic card, everything is fine. The crash is only with my "better" Nvidia card.

dabbertorres

  • Hero Member
  • *****
  • Posts: 505
    • View Profile
    • website/blog
Re: VBO creates bug ?
« Reply #13 on: June 03, 2017, 09:57:45 am »
Oh I see how you're using it now, that makes sense. I meant for the drawing to the sf::RenderTexture to go in an if().
Though I don't think you should have an if() at all in System::Render() then?

As for the Intel vs Nvidia case, I'm afraid someone else with some more familiarity with drivers will have to help you, I'm not familiar enough with the drivers to be of much use.

If you get a stack trace, I might be able to help, otherwise you'll have to wait for someone else to come along.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Re: VBO creates bug ?
« Reply #14 on: June 03, 2017, 10:41:34 am »
Provide an MCVE so everyone can see everything that is going on and can actually test your code.
If it's a bug with SFML, then it can be reproduced in a few lines of code. If it can't be minimized to that size, then it often is a user code issue. ;)

Don't forget to test all your code with SFML 2.4.2.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/