Exemplo n.º 1
0
Arquivo: window.c Projeto: kayson/glfw
GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
                                     const char* title,
                                     GLFWmonitor* monitor,
                                     GLFWwindow* share)
{
    _GLFWfbconfig fbconfig;
    _GLFWwndconfig wndconfig;
    _GLFWwindow* window;
    _GLFWwindow* previous;

    if (!_glfwInitialized)
    {
        _glfwInputError(GLFW_NOT_INITIALIZED, NULL);
        return NULL;
    }

    if (width <= 0 || height <= 0)
    {
        _glfwInputError(GLFW_INVALID_VALUE, "Invalid window size");
        return GL_FALSE;
    }

    // Set up desired framebuffer config
    fbconfig.redBits        = Max(_glfw.hints.redBits, 0);
    fbconfig.greenBits      = Max(_glfw.hints.greenBits, 0);
    fbconfig.blueBits       = Max(_glfw.hints.blueBits, 0);
    fbconfig.alphaBits      = Max(_glfw.hints.alphaBits, 0);
    fbconfig.depthBits      = Max(_glfw.hints.depthBits, 0);
    fbconfig.stencilBits    = Max(_glfw.hints.stencilBits, 0);
    fbconfig.accumRedBits   = Max(_glfw.hints.accumRedBits, 0);
    fbconfig.accumGreenBits = Max(_glfw.hints.accumGreenBits, 0);
    fbconfig.accumBlueBits  = Max(_glfw.hints.accumBlueBits, 0);
    fbconfig.accumAlphaBits = Max(_glfw.hints.accumAlphaBits, 0);
    fbconfig.auxBuffers     = Max(_glfw.hints.auxBuffers, 0);
    fbconfig.stereo         = _glfw.hints.stereo ? GL_TRUE : GL_FALSE;
    fbconfig.samples        = Max(_glfw.hints.samples, 0);
    fbconfig.sRGB           = _glfw.hints.sRGB ? GL_TRUE : GL_FALSE;

    // Set up desired window config
    wndconfig.title         = title;
    wndconfig.resizable     = _glfw.hints.resizable ? GL_TRUE : GL_FALSE;
    wndconfig.visible       = _glfw.hints.visible ? GL_TRUE : GL_FALSE;
    wndconfig.positionX     = _glfw.hints.positionX;
    wndconfig.positionY     = _glfw.hints.positionY;
    wndconfig.clientAPI     = _glfw.hints.clientAPI;
    wndconfig.glMajor       = _glfw.hints.glMajor;
    wndconfig.glMinor       = _glfw.hints.glMinor;
    wndconfig.glForward     = _glfw.hints.glForward ? GL_TRUE : GL_FALSE;
    wndconfig.glDebug       = _glfw.hints.glDebug ? GL_TRUE : GL_FALSE;
    wndconfig.glProfile     = _glfw.hints.glProfile;
    wndconfig.glRobustness  = _glfw.hints.glRobustness;
    wndconfig.monitor       = (_GLFWmonitor*) monitor;
    wndconfig.share         = (_GLFWwindow*) share;

    // Check the OpenGL bits of the window config
    if (!_glfwIsValidContextConfig(&wndconfig))
        return GL_FALSE;

    window = (_GLFWwindow*) calloc(1, sizeof(_GLFWwindow));
    if (!window)
    {
        _glfwInputError(GLFW_OUT_OF_MEMORY, NULL);
        return NULL;
    }

    window->next = _glfw.windowListHead;
    _glfw.windowListHead = window;

    if (wndconfig.monitor)
    {
        wndconfig.resizable = GL_TRUE;
        wndconfig.visible   = GL_TRUE;

        window->videoMode.width     = width;
        window->videoMode.height    = height;
        window->videoMode.redBits   = fbconfig.redBits;
        window->videoMode.greenBits = fbconfig.greenBits;
        window->videoMode.blueBits  = fbconfig.blueBits;
    }

    window->width      = width;
    window->height     = height;
    window->monitor    = wndconfig.monitor;
    window->resizable  = wndconfig.resizable;
    window->cursorMode = GLFW_CURSOR_NORMAL;

    // Save the currently current context so it can be restored later
    previous = (_GLFWwindow*) glfwGetCurrentContext();

    // Open the actual window and create its context
    if (!_glfwPlatformCreateWindow(window, &wndconfig, &fbconfig))
    {
        glfwDestroyWindow((GLFWwindow*) window);
        glfwMakeContextCurrent((GLFWwindow*) previous);
        return GL_FALSE;
    }

    glfwMakeContextCurrent((GLFWwindow*) window);

    // Cache the actual (as opposed to requested) context parameters
    if (!_glfwRefreshContextParams())
    {
        glfwDestroyWindow((GLFWwindow*) window);
        glfwMakeContextCurrent((GLFWwindow*) previous);
        return GL_FALSE;
    }

    // Verify the context against the requested parameters
    if (!_glfwIsValidContext(&wndconfig))
    {
        glfwDestroyWindow((GLFWwindow*) window);
        glfwMakeContextCurrent((GLFWwindow*) previous);
        return GL_FALSE;
    }

    // Clearing the front buffer to black to avoid garbage pixels left over
    // from previous uses of our bit of VRAM
    glClear(GL_COLOR_BUFFER_BIT);
    _glfwPlatformSwapBuffers(window);

    // Restore the previously current context (or NULL)
    glfwMakeContextCurrent((GLFWwindow*) previous);

    // The GLFW specification states that fullscreen windows have the cursor
    // captured by default
    if (wndconfig.monitor)
        glfwSetInputMode((GLFWwindow*) window, GLFW_CURSOR_MODE, GLFW_CURSOR_CAPTURED);

    if (wndconfig.monitor == NULL && wndconfig.visible)
        glfwShowWindow((GLFWwindow*) window);

    return (GLFWwindow*) window;
}
Exemplo n.º 2
0
GLFWAPI int GLFWAPIENTRY glfwOpenWindow( int width, int height,
    int redbits, int greenbits, int bluebits, int alphabits,
    int depthbits, int stencilbits, int mode )
{
    _GLFWfbconfig fbconfig;
    _GLFWwndconfig wndconfig;

    if( !_glfwInitialized || _glfwWin.opened )
    {
        return GL_FALSE;
    }

    // Set up desired framebuffer config
    fbconfig.redBits        = Max( redbits, 0 );
    fbconfig.greenBits      = Max( greenbits, 0 );
    fbconfig.blueBits       = Max( bluebits, 0 );
    fbconfig.alphaBits      = Max( alphabits, 0 );
    fbconfig.depthBits      = Max( depthbits, 0 );
    fbconfig.stencilBits    = Max( stencilbits, 0 );
    fbconfig.accumRedBits   = Max( _glfwLibrary.hints.accumRedBits, 0 );
    fbconfig.accumGreenBits = Max( _glfwLibrary.hints.accumGreenBits, 0 );
    fbconfig.accumBlueBits  = Max( _glfwLibrary.hints.accumBlueBits, 0 );
    fbconfig.accumAlphaBits = Max( _glfwLibrary.hints.accumAlphaBits, 0 );
    fbconfig.auxBuffers     = Max( _glfwLibrary.hints.auxBuffers, 0 );
    fbconfig.stereo         = _glfwLibrary.hints.stereo ? GL_TRUE : GL_FALSE;
    fbconfig.samples        = Max( _glfwLibrary.hints.samples, 0 );

    // Set up desired window config
    wndconfig.mode           = mode;
    wndconfig.refreshRate    = Max( _glfwLibrary.hints.refreshRate, 0 );
    wndconfig.windowNoResize = _glfwLibrary.hints.windowNoResize ? GL_TRUE : GL_FALSE;
    wndconfig.glMajor        = Max( _glfwLibrary.hints.glMajor, 1 );
    wndconfig.glMinor        = Max( _glfwLibrary.hints.glMinor, 0 );
    wndconfig.glForward      = _glfwLibrary.hints.glForward ? GL_TRUE : GL_FALSE;
    wndconfig.glDebug        = _glfwLibrary.hints.glDebug ? GL_TRUE : GL_FALSE;
    wndconfig.glProfile      = _glfwLibrary.hints.glProfile;

    if( wndconfig.glMajor == 1 && wndconfig.glMinor > 5 )
    {
        // OpenGL 1.x series ended with version 1.5
        return GL_FALSE;
    }
    else if( wndconfig.glMajor == 2 && wndconfig.glMinor > 1 )
    {
        // OpenGL 2.x series ended with version 2.1
        return GL_FALSE;
    }
    else if( wndconfig.glMajor == 3 && wndconfig.glMinor > 3 )
    {
        // OpenGL 3.x series ended with version 3.3
        return GL_FALSE;
    }
    else
    {
        // For now, let everything else through
    }

    if( wndconfig.glProfile &&
        ( wndconfig.glMajor < 3 || ( wndconfig.glMajor == 3 && wndconfig.glMinor < 2 ) ) )
    {
        // Context profiles are only defined for OpenGL version 3.2 and above
        return GL_FALSE;
    }

    if( wndconfig.glForward && wndconfig.glMajor < 3 )
    {
        // Forward-compatible contexts are only defined for OpenGL version 3.0 and above
        return GL_FALSE;
    }

    // Clear for next open call
    _glfwClearWindowHints();

    // Check input arguments
    if( mode != GLFW_WINDOW && mode != GLFW_FULLSCREEN )
    {
        return GL_FALSE;
    }

    // Clear GLFW window state
    _glfwWin.active         = GL_TRUE;
    _glfwWin.iconified      = GL_FALSE;
    _glfwWin.mouseLock      = GL_FALSE;
    _glfwWin.autoPollEvents = GL_TRUE;
    _glfwClearInput();

    // Unregister all callback functions
    _glfwWin.windowSizeCallback    = NULL;
    _glfwWin.windowCloseCallback   = NULL;
    _glfwWin.windowRefreshCallback = NULL;
    _glfwWin.keyCallback           = NULL;
    _glfwWin.charCallback          = NULL;
    _glfwWin.mousePosCallback      = NULL;
    _glfwWin.mouseButtonCallback   = NULL;
    _glfwWin.mouseWheelCallback    = NULL;

    // Check width & height
    if( width > 0 && height <= 0 )
    {
        // Set the window aspect ratio to 4:3
        height = (width * 3) / 4;
    }
    else if( width <= 0 && height > 0 )
    {
        // Set the window aspect ratio to 4:3
        width = (height * 4) / 3;
    }
    else if( width <= 0 && height <= 0 )
    {
        // Default window size
        width  = 640;
        height = 480;
    }

    // Remember window settings
    _glfwWin.width      = width;
    _glfwWin.height     = height;
    _glfwWin.fullscreen = (mode == GLFW_FULLSCREEN ? GL_TRUE : GL_FALSE);

    // Platform specific window opening routine
    if( !_glfwPlatformOpenWindow( width, height, &wndconfig, &fbconfig ) )
    {
        glfwCloseWindow();
        return GL_FALSE;
    }

    // Flag that window is now opened
    _glfwWin.opened = GL_TRUE;

    // Read back window and context parameters
    _glfwPlatformRefreshWindowParams();
    _glfwRefreshContextParams();

    if( _glfwWin.glMajor < wndconfig.glMajor ||
        ( _glfwWin.glMajor == wndconfig.glMajor &&
          _glfwWin.glMinor < wndconfig.glMinor ) )
    {
        glfwCloseWindow();
        return GL_FALSE;
    }

    // Do we have non-power-of-two textures (added to core in version 2.0)?
    _glfwWin.has_GL_ARB_texture_non_power_of_two =
        ( _glfwWin.glMajor >= 2 ) ||
        glfwExtensionSupported( "GL_ARB_texture_non_power_of_two" );

    // Do we have automatic mipmap generation (added to core in version 1.4)?
    _glfwWin.has_GL_SGIS_generate_mipmap =
        ( _glfwWin.glMajor >= 2 ) || ( _glfwWin.glMinor >= 4 ) ||
        glfwExtensionSupported( "GL_SGIS_generate_mipmap" );

    if( _glfwWin.glMajor > 2 )
    {
        _glfwWin.GetStringi = (PFNGLGETSTRINGIPROC) glfwGetProcAddress( "glGetStringi" );
        if( !_glfwWin.GetStringi )
        {
            // This is a very common problem among people who compile GLFW
            // on X11/GLX using custom build systems, as the glfwGetProcAddress
            // code path selection needs explicit configuration
            //
            // See readme.html section 2.2 for details

            glfwCloseWindow();
            return GL_FALSE;
        }
    }

    // If full-screen mode was requested, disable mouse cursor
    if( mode == GLFW_FULLSCREEN )
    {
        glfwDisable( GLFW_MOUSE_CURSOR );
    }

    // Start by clearing the front buffer to black (avoid ugly desktop
    // remains in our OpenGL window)
    glClear( GL_COLOR_BUFFER_BIT );
    _glfwPlatformSwapBuffers();

    return GL_TRUE;
}