SFML community forums

Help => Graphics => Topic started by: merl on October 09, 2016, 09:44:22 pm

Title: SFML Graphics module with OpenGL 3.3+
Post by: merl on October 09, 2016, 09:44:22 pm
Hello guys, I want to use the SFML Graphics module for 2D stuff along with OpenGL 3.3+ for 3D stuff. The RenderWindow constructor gives me a 4.5 context.
The problem is that I can either draw my 3D stuff or the 2D stuff but it does not work together. From the tutorial I understand that the graphics module depends on OpenGL legacy functions so I set the context attributeFlags to Default. Is that right?

window creation:
sf::ContextSettings settings;
settings.depthBits = 24;
settings.stencilBits = 8;
settings.attributeFlags = sf::ContextSettings::Default;
sf::RenderWindow window(sf::VideoMode(800, 600, 32), "OpenGL", sf::Style::Titlebar | sf::Style::Close, settings);

main loop for 3D:
while (running)
{
        sf::Event windowEvent;
        while (window.pollEvent(windowEvent))
        {
                switch (windowEvent.type)
                {
                case sf::Event::Closed:
                        running = false;
                        break;
                }
        }
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        window.display();
}

window.close();
this works fine.


main loop for 2D:
sf::Texture tex;
tex.loadFromFile("test.png");
sf::Sprite sprite;
sprite.setTexture(tex);

while (running)
{
        sf::Event windowEvent;
        while (window.pollEvent(windowEvent))
        {
                switch (windowEvent.type)
                {
                case sf::Event::Closed:
                        running = false;
                break;
                        }
        }
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT); // is this equivalent to window.clear()?
        window.draw(sprite);
        window.display();
}

window.close();
this only works if i comment out all gl... calls except the glClear stuff. If I don't the window is either black or I get access violations :/

What I want to do is really:
while (running)
{
        sf::Event windowEvent;
        while (window.pollEvent(windowEvent))
        {
                switch (windowEvent.type)
                {
                case sf::Event::Closed:
                        running = false;
                        break;
                }
        }
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        window.pushGLStates();
        window.resetGLStates();
        window.draw(sprite);
        window.popGLStates();
        window.display();
}

window.close();

Unfortunately, this only gives me a black window. The full source is in the spoiler. I hope someone can help.
Thanks in advance :)

full source:
(click to show/hide)
Title: Re: SFML Graphics module with OpenGL 3.3+
Post by: binary1248 on October 10, 2016, 01:43:46 am
SFML doesn't track 3.0+ OpenGL state (i.e. VAO, VBO, etc.). Make sure you reset all 3.0+ state back to their default values and call window.resetGLStates() before trying to draw with the SFML graphics module.
Title: Re: SFML Graphics module with OpenGL 3.3+
Post by: merl on October 10, 2016, 01:49:11 pm
Thanks, that worked for me. For anyone having similar problems here is my new main loop:

while (running)
{
        sf::Event windowEvent;
        while (window.pollEvent(windowEvent))
        {
                switch (windowEvent.type)
                {
                case sf::Event::Closed:
                        running = false;
                        break;
                }
        }
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        glBindVertexArray(vao); // this line is new
        glBindBuffer(GL_ARRAY_BUFFER, vbo); // this one as well
        glDrawArrays(GL_TRIANGLES, 0, 3);
        glBindBuffer(GL_ARRAY_BUFFER, 0); // !! this one as well
        glBindVertexArray(0); // this one as well

        window.pushGLStates();
        window.resetGLStates();
        window.draw(sprite);
        window.popGLStates();

        window.display();
}