Troubleshooting SFGUI in shader based OpenGL in SFML

As of this writing I am using SFML 2.1 and SFGUI 0.2.3.

The snippets of code here are part of a commit I made in my personal project OGLMan when getting my OpenGL window to work with SFGUI: see it here.

My goal is simply to get this to render in my SFML OpenGL window:

Image

And I bump to a dozen problems that cause SFGUI to not appear at all. Why? It’s because SFGUI uses OpenGL to draw the GUI!

I assume you are using sf::Window as your OpenGL window, and that the GUI code is inside your subclass:

MyOpenGLWindow::MyOpenGLWindow(sf::VideoMode mode,
                               const sf::String &title,
                               unsigned int style) :
sf::Window(mode, title, style) 
{
 // bla bla bla...
}

Before anything begins, first things first. Add the following function call

setActive();

into your constructor.

Next thing to bear in mind is that you need a sfg::Desktop and sfg::SFGUI object as your private attributes:

sfg::SFGUI sfgui; // you need this
sfg::Desktop desktop; // ...and this
sfg::Label::Ptr test_label;

Now also in the constructor we top on the code to setup the GUI:

auto window = sfg::Window::Create();
window->SetTitle("An amazing title");
test_label = sfg::Label::Create( "Hello I am a window\nthat serves to occupy\nspace");
window->Add(test_label);
desktop.Add(window);

Then we need to have SFGUI dip its fingers into the event loop:

sf::Event e;
while (this->pollEvent(e)) {
    desktop.HandleEvent(e); // add this.
    switch (e.type) {
        case sf::Event::Closed:
        this->close();
        return true;
        break;
// more events...

When drawing the GUI, you have to disable GL_DEPTH_TEST, if you have enabled somewhere in your code (you most likely have). So you need to switch back and forth enabling GL_DEPTH_TEST to render your geometry and disabling it when rendering the GUI.

void MyGLWindow::guiDraw()
{
    // disable depth test so SFGUI can render
    glDisable(GL_DEPTH_TEST);
    desktop.Update(1.0f);
    sfgui.Display(*this);
}

note that the SFGUI object’s Display() method call have to be called BEFORE SFML window’s display().

Also, when using VAO (Vertex Array Object), each time you call a

glBindVertexArray(vao);

you must finish it with a

glBindVertexArray(0);

Otherwise you get really strange and notoriously hard to debug problems with your render, and your GUI is no where to be found

Image

Here’s how it should look:

Image

Here’s an example code snippet:

glBindVertexArray(vao);
glUniformMatrix4fv(normals_loc, 1,
                       GL_FALSE, &normal_matrix[0][0]);
// bla bla bla...
glDrawElements(DRAW_MODE, indices.size(), GL_UNSIGNED_SHORT, (void*)index_buffer_offset);
glBindVertexArray(0); // don't forget this!

Also, when you use a shader program:

glUseProgram(programID);

You must nullify it BEFORE you draw any GUI:

glUseProgram(0);

So again, you have this switching back and forth thing for every single frame. Note that you don’t have to call glGetUniformLocation again when switching on and off your active shader program.

Lastly, if you have wireframe rendering in your scene, you should know that SFGUI will also be affected. So if you just place

glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

before you render, your GUI is going to look like this:

Image

Those white scratches are suppose to be text. Cool huh? It shows that SFGUI GUI components are really all made of triangles!

So anyhow, if you are rendering wireframe of your 3D geometry, you need to be switching back and forth from wireframe polygon mode and fill polygon mode. Fill mode is as follows:

glPolygonMode(GL_FRONT, GL_FILL);

Yup – that’s all the problems I came across…  Hope this helped somebody; leave a comment if you find other things that needed to be addressed when using OpenGL with SFGUI.

To conclude, here’s SFGUI working happily in my OpenGL window:

2014-08-03 00_20_50-C__Qt_Qt5.3.0_Tools_QtCreator_bin_qtcreator_process_stub.exe

References: