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

Author Topic: [SFML 2.0]Rendering and Event Handling in separate threads  (Read 2678 times)

0 Members and 2 Guests are viewing this topic.

Katherine1

  • Newbie
  • *
  • Posts: 4
    • View Profile
[SFML 2.0]Rendering and Event Handling in separate threads
« on: July 15, 2012, 11:25:08 pm »
I am writing and OpenGL application with SFML 2.0. According to the tutorial, rendering can be performed in a separate thread with event handling in the main thread. So I set up my code like the tutorial (set the main thread context as not active, and then set the thread's context as active), and the application crashes when it goes to pop an event off the stack. The only documentation ( the tutorial ) says separating these into separate threads is doable, and the code worked fine when the application was single threaded. I am not sure what is wrong as I am still too new to SFML to know the ins and outs of the event handling system. Does anyone know what could be wrong?

Here is the relevant code:
int main(int argc, char *argv[]) {

    sf::ContextSettings settings;
    settings.depthBits = 0;
    settings.stencilBits = 0;
    settings.antialiasingLevel = 0;
    settings.majorVersion = 2;
    settings.minorVersion = 0;

    //Close style disables window resizing :)
    sf::Window window(sf::VideoMode(SCREEN_WIDTH, SCREEN_HEIGHT), "SFML Graphical Test", sf::Style::Close, settings);

    // deactivate its OpenGL context
    window.setActive(false);

    // launch the rendering thread
    sf::Thread thread(&renderThread, &window);
    thread.launch();

    while (window.isOpen()) {
        sf::Event event;

        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed) {
                // end the program
                window.close();
            }
            else if (event.type == sf::Event::KeyPressed) {
                if (event.key.code == sf::Keyboard::Escape) {
                    done = true;
                }
                if (event.key.code == sf::Keyboard::W) {
                    up = true;
                }
                if (event.key.code == sf::Keyboard::S) {
                    down = true;
                }
                if (event.key.code == sf::Keyboard::A) {
                    left = true;
                }
                if (event.key.code == sf::Keyboard::D) {
                    right = true;
                }
            }
            else if (event.type == sf::Event::KeyReleased) {
                if (event.key.code == sf::Keyboard::W) {
                    up = false;
                }
                if (event.key.code == sf::Keyboard::S) {
                    down = false;
                }
                if (event.key.code == sf::Keyboard::A) {
                    left = false;
                }
                if (event.key.code == sf::Keyboard::D) {
                    right = false;
                }
            }
        }
    }

    thread.wait();

    return 0;

}

void setupVBO(RenderInfo info) {
    //Bind the VBO buffer
    glBindBuffer(GL_ARRAY_BUFFER, verVBOID);

    int vertBufferSize = sizeof(Vertex)*info.vertLength;
    //Set up the buffer, but don't give it the data yet.
    glBufferData(GL_ARRAY_BUFFER, vertBufferSize, NULL, GL_STATIC_DRAW);

    //Put the vertex array in the buffer
    glBufferSubData(GL_ARRAY_BUFFER, 0, vertBufferSize, &info.verticies[0].location[0]);

    int indexBufferSize = sizeof(Vertex)*info.indexLength;

    //Bind the index vob and set up the buffer
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indVBOID);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBufferSize, NULL, GL_STATIC_DRAW);


    //unsigned short *indicies = info.indecies;
    //Put the index in the buffer
    glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indexBufferSize, &info.indecies[0]);

    //Go back to the vertex buffer
    glBindBuffer(GL_ARRAY_BUFFER, verVBOID);

    //Enable the vertex array
    glEnableClientState(GL_VERTEX_ARRAY);
    //Point to where the vertexes are in the vertex struct
    glVertexPointer(3, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(0));
    //Enable first texture for rendering
    glClientActiveTexture(GL_TEXTURE0);
    //Enable use of the texture coordinates in the array
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    //Point to the texture coordinates in the buffer
    glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(12));

    //Bind the index buffer again.
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indVBOID);
}

void renderThread(sf::Window* window) {

    window->setFramerateLimit(FPS);
    window->setVerticalSyncEnabled(true);
    window->setActive(true);

    //Enable Texturing and Alpha Tansparency
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    //Set the viewport
    glViewport( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT );
    //Set the clear function
    glClear( GL_COLOR_BUFFER_BIT );

    //Switch to projection mode and reset the matrix
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();

    //Set up a 2D projection
    gluOrtho2D(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0);

    //Switch to modelview and reset to identity matrix
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    //Generate VBOIDs
    glGenBuffers(1, &verVBOID);
    glGenBuffers(1, &indVBOID);

    //Set clear color and clear screen
    glClearColor ( 0.0, 0.0, 0.0, 1.0 );
    glClear ( GL_COLOR_BUFFER_BIT );

    //Set initial camera position
    camera.setPos(-1*SCREEN_WIDTH/2,-1*SCREEN_HEIGHT/2);

    //Load stuff
    Map testMap;
    testMap.loadMap("maps/0.map");

    RenderInfo info = testMap.makeRenderList(0);
    setupVBO(info);

    while(window->isOpen()) {

        glLoadIdentity();
                glClear( GL_COLOR_BUFFER_BIT );

        if (up)
            camera.moveUp(1);
        if (down)
            camera.moveDown(1);
        if (left)
            camera.moveLeft(1);
        if (right)
            camera.moveRight(1);
        camera.place();

        //Draw the elements in the buffer.
        //We want to draw quads, we will render all elements, they are unsigned shorts, and they are at Buffer offset 0.
        glDrawElements(GL_QUADS, info.indexLength, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));


        window->display();
    }

    //Disable the client states we used
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    //Delete the buffers
    glDeleteBuffers(1, &indVBOID);
    glDeleteBuffers(1, &verVBOID);

}
 
« Last Edit: July 15, 2012, 11:41:02 pm by Katherine1 »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: [SFML 2.0]Rendering and Event Handling in separate threads
« Reply #1 on: July 16, 2012, 07:59:25 am »
Quote
the application crashes when it goes to pop an event off the stack
Have you run the debugger to get more details about the crash?
Does it happen on the first event, or after a while?

What's your graphics card, and are its drivers up to date?
Laurent Gomila - SFML developer

Katherine1

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: [SFML 2.0]Rendering and Event Handling in separate threads
« Reply #2 on: July 16, 2012, 04:10:28 pm »
Well, when I put a breakpoint on the even loop, I get crashes in the render loop. I know it is it running at least once as the window does pop up with the rendered item before crashing.

I'm running on 64-bit Arch Linux with an ATI HD4200 series graphics card. Everything is up to date. This worked perfectly fine as a single threaded application.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: [SFML 2.0]Rendering and Event Handling in separate threads
« Reply #3 on: July 16, 2012, 04:34:44 pm »
Have you run the debugger?
Laurent Gomila - SFML developer

Katherine1

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: [SFML 2.0]Rendering and Event Handling in separate threads
« Reply #4 on: July 16, 2012, 04:41:51 pm »
Yes. It's not giving me much to go on.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: [SFML 2.0]Rendering and Event Handling in separate threads
« Reply #5 on: July 16, 2012, 04:50:57 pm »
It should at least point to the line that produces the crash.
Laurent Gomila - SFML developer

Katherine1

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: [SFML 2.0]Rendering and Event Handling in separate threads
« Reply #6 on: July 16, 2012, 05:33:45 pm »
I already stated where the debugger points. With no breakpoints, it points to window.pollEvent(), with a breakpoint in the event loop, it crashes on glClear in the render loop.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: [SFML 2.0]Rendering and Event Handling in separate threads
« Reply #7 on: July 16, 2012, 08:41:01 pm »
Have you tried the same code on other PCs?
Laurent Gomila - SFML developer

 

anything