SFML community forums

Help => Window => Topic started by: RaptorIV on March 30, 2012, 07:23:34 pm

Title: Having trouble with threaded opengl calls
Post by: RaptorIV on March 30, 2012, 07:23:34 pm
I am trying to make opengl calls to a window from a separate thread than the window is created in. Before calling the thread I call setActive(false) and in the thread I call setActive(true) but the clear color is not applied.

I didn't include my viewport or projection setup, but the code works when I replace drawThread.launch() with the contents of onDraw().

Code: [Select]
Renderer::Renderer()
:    drawThread(&Renderer::onDraw, this)
{}

Renderer::onDraw()
{
    sf::Context glContext; //I have included, excluded, and moved this around but it makes no difference
    m_window->setActive(true);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    m_window->display();
}

Renderer::startDraw()
{
    m_window->setActive(false);
    drawThread.launch();

   
    //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //This works when uncommented
   // m_window->display();
}

int main()
{
    while(window->isOpen()){
        startDraw();
    }
}

This results in "Failed to activate window's the context" spam
Title: Re: Having trouble with threaded opengl calls
Post by: Laurent on March 30, 2012, 08:48:53 pm
Could you please write a complete and minimal code that reproduces your problem? It's hard to debug incomplete pieces of a bigger project.
Title: Re: Having trouble with threaded opengl calls
Post by: RaptorIV on March 31, 2012, 02:07:01 am
#include <SFML/Window.hpp>
#include "gl/glew.h"

class Renderer
{
    sf::Window*     m_window;
    sf::Thread      m_drawThread;

    public:
        Renderer(sf::Window* window);
        virtual ~Renderer(){};

        void onThink();
        void onDrawFrame();
        void onInitialize();
        void event_resized(sf::Event& evt);
        void setViewport();
};

Renderer::Renderer(sf::Window* window)
:   m_drawThread(&Renderer::onDrawFrame, this)
{
    m_window = window;
}

void Renderer::onInitialize()
{
    sf::Context gl;
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    setViewport();
}

void Renderer::onDrawFrame(){
    m_window->setActive(true);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    m_window->display();
}

void Renderer::onThink()
{
    m_window->setActive(false);
    m_drawThread.launch();
}

void Renderer::event_resized(sf::Event& evt)
{
    setViewport();
}

void Renderer::setViewport()
{
    int width  =   m_window->getSize().x;
    int height =   m_window->getSize().y;

    glViewport(0, 0, (GLsizei)width, (GLsizei)height); // Set our viewport to the size of our window
    glMatrixMode(GL_PROJECTION); // Switch to the projection matrix so that we can manipulate how our scene is viewed
    glLoadIdentity(); // Reset the projection matrix to the identity matrix so that we don't get any artifacts (cleaning up)
    gluPerspective(60, (GLfloat)width / (GLfloat)height, 1.0, 100.0); // Set the Field of view angle (in degrees), the aspect ratio of our window, and the new and far planes
    glMatrixMode(GL_MODELVIEW);
}


int main()
{
    sf::Window window(sf::VideoMode(500, 500), "Test");
    Renderer myrenderer(&window);
    myrenderer.onInitialize();
    sf::Event evt;
    while(window.isOpen()){
        while(window.pollEvent(evt)){
            if(evt.type == sf::Event::KeyPressed){
                window.close();
            }
        }
        myrenderer.onThink();
    }
}
Title: Re: Having trouble with threaded opengl calls
Post by: Laurent on March 31, 2012, 10:21:08 am
You're creating the thread again and again every frame, you should really avoid that. You should run it at init time, and then have a loop inside the threaded function.
Title: Re: Having trouble with threaded opengl calls
Post by: RaptorIV on March 31, 2012, 07:20:10 pm
Worked like a charm, thanks Laurent