X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffreeglut_window.c;h=cc73b88c733e3ad9a6405d84c415ad0a9ca60808;hb=2cc3ae61ee06893f31662b961e637d1e9210580a;hp=8450e060b624d8a59a56c7210e3cdc89551f34e9;hpb=0850bcd142570b0e7ae0f8be1b9a6fd0daac59bb;p=freeglut diff --git a/src/freeglut_window.c b/src/freeglut_window.c index 8450e06..cc73b88 100644 --- a/src/freeglut_window.c +++ b/src/freeglut_window.c @@ -283,6 +283,81 @@ typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAt #define WGL_SAMPLES_ARB 0x2042 +#ifndef WGL_ARB_create_context +#define WGL_ARB_create_context 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern HGLRC WINAPI wglCreateContextAttribsARB (HDC, HGLRC, const int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList); + +#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 +#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 +#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 +#define WGL_CONTEXT_FLAGS_ARB 0x2094 +#define ERROR_INVALID_VERSION_ARB 0x2095 +#endif + + +void fgNewWGLCreateContext( SFG_Window* window ) +{ + PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetEntensionsStringARB; + HGLRC context; + int attribs[7]; + PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB; + const char * pWglExtString; + + /* If nothing fancy has been required, leave the context as it is */ + if ( fgState.MajorVersion == 1 && fgState.MinorVersion == 0 && fgState.ContextFlags == 0 ) + { + return; + } + + wglMakeCurrent( window->Window.Device, + window->Window.Context ); + + wglGetEntensionsStringARB=(PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB"); + if ( wglGetEntensionsStringARB == NULL ) + { + return; + } + + pWglExtString=wglGetEntensionsStringARB(window->Window.Device); + if (( pWglExtString == NULL ) || ( strstr(pWglExtString, "WGL_ARB_create_context") == NULL )) + { + return; + } + + /* new context creation */ + attribs[0] = WGL_CONTEXT_MAJOR_VERSION_ARB; + attribs[1] = fgState.MajorVersion; + attribs[2] = WGL_CONTEXT_MINOR_VERSION_ARB; + attribs[3] = fgState.MinorVersion; + attribs[4] = WGL_CONTEXT_FLAGS_ARB; + attribs[5] = ((fgState.ContextFlags & GLUT_DEBUG) ? WGL_CONTEXT_DEBUG_BIT_ARB : 0) | + ((fgState.ContextFlags & GLUT_FORWARD_COMPATIBLE) ? WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB : 0); + attribs[6] = 0; + + wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) wglGetProcAddress( "wglCreateContextAttribsARB" ); + if ( wglCreateContextAttribsARB == NULL ) + { + fgError( "wglCreateContextAttribsARB not found" ); + } + + context = wglCreateContextAttribsARB( window->Window.Device, 0, attribs ); + if ( context == NULL ) + { + fgError( "Unable to create OpenGL %d.%d context (flags %x)", + fgState.MajorVersion, fgState.MinorVersion, fgState.ContextFlags ); + } + + wglMakeCurrent( NULL, NULL ); + wglDeleteContext( window->Window.Context ); + window->Window.Context = context; +} + + GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly, unsigned char layer_type ) { @@ -376,17 +451,16 @@ GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly, HWND hWnd; HDC hDC, hDC_before=wglGetCurrentDC(); WNDCLASS wndCls; - ATOM atom; /* create a dummy window */ ZeroMemory(&wndCls, sizeof(wndCls)); - wndCls.lpfnWndProc = DefWindowProc; - wndCls.hInstance = fgDisplay.Instance; - wndCls.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; - wndCls.lpszClassName = _T("FREEGLUT_dummy"); - atom = RegisterClass( &wndCls ); + wndCls.lpfnWndProc = DefWindowProc; + wndCls.hInstance = fgDisplay.Instance; + wndCls.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; + wndCls.lpszClassName = _T("FREEGLUT_dummy"); + RegisterClass( &wndCls ); - hWnd=CreateWindow((LPCSTR)atom, _T(""), WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW , 0,0,0,0, 0, 0, fgDisplay.Instance, 0 ); + hWnd=CreateWindow(_T("FREEGLUT_dummy"), _T(""), WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW , 0,0,0,0, 0, 0, fgDisplay.Instance, 0 ); hDC=GetDC(hWnd); SetPixelFormat( hDC, pixelformat, ppfd ); @@ -485,17 +559,84 @@ void fgSetWindow ( SFG_Window *window ) #if TARGET_HOST_POSIX_X11 + +#ifndef GLX_CONTEXT_MAJOR_VERSION_ARB +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#endif + +#ifndef GLX_CONTEXT_MINOR_VERSION_ARB +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +#endif + +#ifndef GLX_CONTEXT_FLAGS_ARB +#define GLX_CONTEXT_FLAGS_ARB 0x2094 +#endif + +#ifndef GLX_CONTEXT_DEBUG_BIT_ARB +#define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001 +#endif + +#ifndef GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB +#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 +#endif + +typedef GLXContext (*CreateContextAttribsProc)(Display *dpy, GLXFBConfig config, + GLXContext share_list, Bool direct, + const int *attrib_list); + static GLXContext fghCreateNewContext( SFG_Window* window ) { + /* for color model calculation */ int menu = ( window->IsMenu && !fgStructure.MenuContext ); int index_mode = ( fgState.DisplayMode & GLUT_INDEX ); + + /* "classic" context creation */ Display *dpy = fgDisplay.Display; GLXFBConfig config = *(window->Window.FBConfig); int render_type = ( !menu && index_mode ) ? GLX_COLOR_INDEX_TYPE : GLX_RGBA_TYPE; GLXContext share_list = NULL; Bool direct = ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ); - - return glXCreateNewContext( dpy, config, render_type, share_list, direct ); + GLXContext context; + + /* new context creation */ + int attribs[7]; + CreateContextAttribsProc createContextAttribs; + + /* If nothing fancy has been required, simply use the old context creation GLX API entry */ + if ( fgState.MajorVersion == 1 && fgState.MinorVersion == 0 && fgState.ContextFlags == 0) + { + context = glXCreateNewContext( dpy, config, render_type, share_list, direct ); + if ( context == NULL ) { + fgError( "could not create new OpenGL context" ); + } + return context; + } + + /* color index mode is not available anymore with OpenGL 3.0 */ + if ( render_type == GLX_COLOR_INDEX_TYPE ) { + fgWarning( "color index mode is deprecated, using RGBA mode" ); + } + + attribs[0] = GLX_CONTEXT_MAJOR_VERSION_ARB; + attribs[1] = fgState.MajorVersion; + attribs[2] = GLX_CONTEXT_MINOR_VERSION_ARB; + attribs[3] = fgState.MinorVersion; + attribs[4] = GLX_CONTEXT_FLAGS_ARB; + attribs[5] = ((fgState.ContextFlags & GLUT_DEBUG) ? GLX_CONTEXT_DEBUG_BIT_ARB : 0) | + ((fgState.ContextFlags & GLUT_FORWARD_COMPATIBLE) ? GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB : 0); + attribs[6] = 0; + + createContextAttribs = (CreateContextAttribsProc) fghGetProcAddress( "glXCreateContextAttribsARB" ); + if ( createContextAttribs == NULL ) { + fgError( "glXCreateContextAttribsARB not found" ); + } + + context = createContextAttribs( dpy, config, share_list, direct, attribs ); + if ( context == NULL ) { + fgError( "could not create new OpenGL %d.%d context (flags %x)", + fgState.MajorVersion, fgState.MinorVersion, fgState.ContextFlags ); + } + return context; } #endif @@ -640,9 +781,6 @@ void fgOpenWindow( SFG_Window* window, const char* title, if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT ) fgError( "Unable to force direct context rendering for window '%s'", title ); - else if( fgState.DirectContext == GLUT_TRY_DIRECT_CONTEXT ) - fgWarning( "Unable to create direct context rendering for window '%s'\nThis may hurt performance.", - title ); } #endif @@ -887,7 +1025,8 @@ void fgCloseWindow( SFG_Window* window ) { #if TARGET_HOST_POSIX_X11 - glXDestroyContext( fgDisplay.Display, window->Window.Context ); + if( window->Window.Context ) + glXDestroyContext( fgDisplay.Display, window->Window.Context ); XFree( window->Window.FBConfig ); XDestroyWindow( fgDisplay.Display, window->Window.Handle ); /* XFlush( fgDisplay.Display ); */ /* XXX Shouldn't need this */