Correct use of the opaque window object?

Using GLFW
2013-10-10
2013-10-11
  • mariojmartin

    mariojmartin - 2013-10-10

    I am trying to understand how to use the opaque window handler. If I understand correctly, it is an incomplete struct. So I have made a simple code to experiment with, but something wrong is meshing with the memory.

    This example opens three windows in a separated thread. It is working fine until the windows are closed and an unhandled error is triggered in glfwDestroyWindow().

    Any suggestions?

    ~~~~~~~~

    include <thread>

    include <mutex>

    include <condition_variable>

    include <chrono>

    include <string.h>

    include <stdio.h>

    include "GLFW/glfw3.h"

    define MAX_NUMBER_WINDOWS 8

    define OPEN_WINDOW 1

    define CLOSE_WINDOW 2

    define FREEZE_WINDOW 3

    define TERMINATE 4

    define FRAMERATE_MILISECONDS 20

    struct UserDefined
    {
    int id;
    };

    struct WindowHandler
    {
    GLFWwindow* window;
    int status;
    };

    WindowHandler window_handler[MAX_NUMBER_WINDOWS] = {{NULL, 0}};

    / GLFW error callback, when an error is reported /
    static void error_callback( int error, const char* description )
    {
    printf( "%s\n", description );
    }

    / Callback that is triggered everytime the keyboard inputs /
    static void callback_keyboard( GLFWwindow window, int key, int scancode, int action, int mods )
    {
    UserDefined
    p = (UserDefined*)glfwGetWindowUserPointer( window );
    if (p != NULL){
    printf("[%i] %c\n", p->id, (char)key);
    }
    }

    static GLFWwindow create_window( const int window_number )
    {
    /
    Create the render context /
    char title[32];
    sprintf( title, "Window %i", window_number );
    GLFWwindow
    window = glfwCreateWindow(640, 640, title, NULL, NULL);
    UserDefined* p = new(UserDefined);
    p->id = window_number;
    glfwSetWindowUserPointer( window, p );

    if ( window == NULL ){
        return NULL;
    }
    
    glfwMakeContextCurrent( window );
    
    glfwSetKeyCallback( window, callback_keyboard );
    
    return window;
    

    }

    static void ow_glfw_render_loop()
    {
    std::mutex mutex;

    glfwSetErrorCallback(error_callback);
    
    if (glfwInit() == GL_FALSE){
        return;
    }
    
    while(1)
    {
        clock_t start_clock = clock();
    
        for (int slot = 0; slot < MAX_NUMBER_WINDOWS; slot++)
        {
            WindowHandler* handler = &(window_handler[slot]);
    
            if (handler->status == OPEN_WINDOW){
                /* Creates a new render context */ 
                mutex.lock();
                handler->window = create_window( slot );
                handler->status = 0;
                mutex.unlock();
            }
    
            if (handler->status == CLOSE_WINDOW)
            {
                /* Destroys the render context */
                mutex.lock();
                UserDefined* p = (UserDefined*)glfwGetWindowUserPointer( handler->window );
                if (p != NULL){
                    delete(p);
                }
                glfwDestroyWindow( handler->window );
                handler->window = NULL;
                handler->status = 0;
                mutex.unlock();
            }
    
            if (handler->window != NULL && handler->status == 0)
            {
                glfwMakeContextCurrent( handler->window );
    
                /* Display goes here */
    
                glfwSwapBuffers( handler->window );
    
                if (glfwWindowShouldClose( handler->window ) == GL_TRUE){
                    mutex.lock();
                    handler->status = CLOSE_WINDOW;
                    mutex.unlock();
                }
            }
        }
    
        glfwPollEvents();
    
        clock_t end_clock = clock();
        clock_t sleep_time = FRAMERATE_MILISECONDS 
            + ((start_clock - end_clock)* 1000)/CLOCKS_PER_SEC;
    
        if (sleep_time > 0){
            std::this_thread::sleep_for
                ( std::chrono::milliseconds( sleep_time ));
        }
    }
    
    glfwTerminate();
    

    }

    int main(int argc, char argv[])
    {
    /
    Launch the main loop in a thread */
    std::thread render_thread_loop(ow_glfw_render_loop);
    render_thread_loop.detach();

    std::mutex mutex;
    mutex.lock();
    window_handler[0].status = OPEN_WINDOW;
    window_handler[1].status = OPEN_WINDOW;
    window_handler[2].status = OPEN_WINDOW;
    mutex.unlock();
    
    getchar();
    

    }

    ~~~~~

     
    Last edit: mariojmartin 2013-10-11
  • Camilla Löwy

    Camilla Löwy - 2013-10-10

    GLFWwindow is an opaque struct. You should not define it or change anything inside it. See the documentation for information on how to use the GLFW API.

     
  • mariojmartin

    mariojmartin - 2013-10-11

    Ok. I missed that part. It makes more sense now. I modified the example and now is working right.

    Thanks very much.

     
    Last edit: mariojmartin 2013-10-11

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks