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

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - Katherine1

Pages: [1]
1
General / [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);

}
 

Pages: [1]
anything