patch by blight:
authorRoyce Mitchell III <royce3@ev1.net>
Thu, 12 Feb 2004 23:56:15 +0000 (23:56 +0000)
committerRoyce Mitchell III <royce3@ev1.net>
Thu, 12 Feb 2004 23:56:15 +0000 (23:56 +0000)
Simple GL programs should work if you have hardware-accelerated video drivers installed, still some bugs left and things to implement; Have already played a model-flight simulator with it.

svn path=/trunk/; revision=8162

reactos/lib/opengl32/opengl32.c
reactos/lib/opengl32/opengl32.h
reactos/lib/opengl32/wgl.c

index 8ae6c95..ac35879 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: opengl32.c,v 1.14 2004/02/09 08:00:15 vizzini Exp $
+/* $Id: opengl32.c,v 1.15 2004/02/12 23:56:15 royce Exp $
  *
  * COPYRIGHT:            See COPYING in the top level directory
  * PROJECT:              ReactOS kernel
@@ -34,13 +34,6 @@ static DWORD OPENGL32_InitializeDriver( GLDRIVERDATA *icd );
 static BOOL OPENGL32_UnloadDriver( GLDRIVERDATA *icd );
 
 /* global vars */
-/*const char* OPENGL32_funcnames[GLIDX_COUNT] SHARED =
-{
-#define X(func, ret, typeargs, args) #func,
-       GLFUNCS_MACRO
-#undef X
-};*/
-
 DWORD OPENGL32_tls;
 GLPROCESSDATA OPENGL32_processdata;
 
@@ -51,6 +44,8 @@ OPENGL32_ThreadDetach()
 {
        /* FIXME - do we need to release some HDC or something? */
        GLTHREADDATA* lpData = NULL;
+       PROC *dispatchTable = NULL;
+
        lpData = (GLTHREADDATA*)TlsGetValue( OPENGL32_tls );
        if (lpData != NULL)
        {
@@ -58,6 +53,16 @@ OPENGL32_ThreadDetach()
                        DBGPRINT( "Warning: HeapFree() on GLTHREADDATA failed (%d)",
                                  GetLastError() );
        }
+
+
+       dispatchTable = NtCurrentTeb()->glTable;
+
+       if (dispatchTable != NULL)
+       {
+               if (!HeapFree( GetProcessHeap(), 0, dispatchTable ))
+                       DBGPRINT( "Warning: HeapFree() on dispatch table failed (%d)",
+                                 GetLastError() );
+       }
 }
 
 
@@ -66,7 +71,7 @@ WINAPI
 DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
 {
        GLTHREADDATA* lpData = NULL;
-       ICDTable *dispatchTable = NULL;
+       PROC *dispatchTable = NULL;
        TEB *teb = NULL;
        SECURITY_ATTRIBUTES attrib = { sizeof (SECURITY_ATTRIBUTES), /* nLength */
                                       NULL, /* lpSecurityDescriptor */
@@ -106,9 +111,9 @@ DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
 
        /* The attached process creates a new thread. */
        case DLL_THREAD_ATTACH:
-               dispatchTable = (ICDTable*)HeapAlloc( GetProcessHeap(),
+               dispatchTable = (PROC*)HeapAlloc( GetProcessHeap(),
                                            HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY,
-                                           sizeof (ICDTable) );
+                                           sizeof (((ICDTable *)(0))->dispatch_table) );
                if (dispatchTable == NULL)
                {
                        DBGPRINT( "Error: Couldn't allocate GL dispatch table" );
@@ -129,13 +134,13 @@ DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
 
                /* initialize dispatch table with empty functions */
                #define X(func, ret, typeargs, args, icdidx, tebidx, stack)            \
-                       dispatchTable->dispatch_table[icdidx] = (PROC)glEmptyFunc##stack;  \
+                       dispatchTable[icdidx] = (PROC)glEmptyFunc##stack;                  \
                        if (tebidx >= 0)                                                   \
                                teb->glDispatchTable[tebidx] = (PVOID)glEmptyFunc##stack;
                GLFUNCS_MACRO
                #undef X
 
-               teb->glTable = dispatchTable->dispatch_table;
+               teb->glTable = dispatchTable;
                TlsSetValue( OPENGL32_tls, lpData );
                break;
 
@@ -332,7 +337,7 @@ OPENGL32_InitializeDriver( GLDRIVERDATA *icd )
        LOAD_DRV_PROC(icd, DrvSwapLayerBuffers, TRUE);
 
        /* we require at least one of DrvCreateContext and DrvCreateLayerContext */
-       if (icd->DrvCreateContext == NULL || icd->DrvCreateLayerContext == NULL)
+       if (icd->DrvCreateContext == NULL && icd->DrvCreateLayerContext == NULL)
        {
                DBGPRINT( "Error: One of DrvCreateContext/DrvCreateLayerContext is required!" );
                FreeLibrary( icd->handle );
@@ -464,8 +469,10 @@ OPENGL32_UnloadICD( GLDRIVERDATA *icd )
        }
 
        icd->refcount--;
-       if (icd->refcount == 0)
+       //if (icd->refcount == 0)
+       if (0)
                ret = OPENGL32_UnloadDriver( icd );
+       /* FIXME: InitializeICD crashes when called a second time */
 
        /* release mutex */
        if (!ReleaseMutex( OPENGL32_processdata.driver_mutex ))
index 01e2ed3..fee6b96 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: opengl32.h,v 1.13 2004/02/11 17:39:24 vizzini Exp $
+/* $Id: opengl32.h,v 1.14 2004/02/12 23:56:15 royce Exp $
  *
  * COPYRIGHT:            See COPYING in the top level directory
  * PROJECT:              ReactOS kernel
@@ -115,7 +115,7 @@ typedef struct tagGLDRIVERDATA
        BOOL      APIENTRY (*DrvDescribeLayerPlane)( HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR );
        int       APIENTRY (*DrvDescribePixelFormat)( IN HDC, IN int, IN UINT, OUT LPPIXELFORMATDESCRIPTOR );
        int       APIENTRY (*DrvGetLayerPaletteEntries)( HDC, int, int, int, COLORREF * );
-       FARPROC   APIENTRY (*DrvGetProcAddress)( LPCSTR lpProcName );
+       PROC      APIENTRY (*DrvGetProcAddress)( LPCSTR lpProcName );
        void      APIENTRY (*DrvReleaseContext)();
        BOOL      APIENTRY (*DrvRealizeLayerPalette)( HDC, int, BOOL );
        PICDTable APIENTRY (*DrvSetContext)( HDC hdc, HGLRC hglrc, SetContextCallBack callback );
index 12d3d99..76bc728 100644 (file)
@@ -127,7 +127,7 @@ WGL_ContainsContext( GLRC *glrc )
  *           be multiple times for one DrvSetContext call.
  * ARGUMENTS: [IN] table  Function pointer table (first DWORD is number of
  *                        functions)
- * RETURNS: unkown
+ * RETURNS: unkown (maybe void?)
  */
 DWORD
 CALLBACK
@@ -136,18 +136,27 @@ WGL_SetContextCallBack( const ICDTable *table )
 /*     UINT i;*/
        TEB *teb;
        PROC *tebTable, *tebDispatchTable;
+       INT size;
 
        teb = NtCurrentTeb();
        tebTable = (PROC *)teb->glTable;
        tebDispatchTable = (PROC *)teb->glDispatchTable;
 
-       DBGPRINT( "Function count: %d\n", table->num_funcs );
+       if (table != NULL)
+       {
+               DBGPRINT( "Function count: %d\n", table->num_funcs );
 
-       /* save table */
-       memcpy( tebTable, table->dispatch_table,
-               sizeof (PROC) * table->num_funcs );
-       memset( tebTable + sizeof (PROC) * table->num_funcs, 0,
-               sizeof (table->dispatch_table) - (sizeof (PROC) * table->num_funcs) );
+               /* save table */
+               size = sizeof (PROC) * table->num_funcs;
+               memcpy( tebTable, table->dispatch_table, size );
+               memset( tebTable + table->num_funcs, 0,
+                               sizeof (table->dispatch_table) - size );
+       }
+       else
+       {
+               DBGPRINT( "Unsetting current context" );
+               memset( tebTable, 0, sizeof (table->dispatch_table) );
+       }
 
        /* FIXME: pull in software fallbacks -- need mesa */
 #if 0 /* unused atm */
@@ -165,7 +174,8 @@ WGL_SetContextCallBack( const ICDTable *table )
        #define X(func, ret, typeargs, args, icdidx, tebidx, stack)            \
                if (tebTable[icdidx] == NULL)                                      \
                {                                                                  \
-                       DBGPRINT( "Warning: GL proc '%s' is NULL", #func );            \
+                       if (table != NULL)                                             \
+                               DBGPRINT( "Warning: GL proc '%s' is NULL", #func );        \
                        tebTable[icdidx] = (PROC)glEmptyFunc##stack;                   \
                }
        GLFUNCS_MACRO
@@ -209,6 +219,7 @@ rosglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd )
        /* check input */
        if (pfd->nSize != sizeof (PIXELFORMATDESCRIPTOR) || pfd->nVersion != 1)
        {
+               OPENGL32_UnloadICD( icd );
                SetLastError( 0 ); /* FIXME: use appropriate errorcode */
                return 0;
        }
@@ -219,6 +230,7 @@ rosglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd )
        if (icdNumFormats == 0)
        {
                DBGPRINT( "Error: DrvDescribePixelFormat failed (%d)", GetLastError() );
+               OPENGL32_UnloadICD( icd );
                return 0;
        }
        DBGPRINT( "Info: Enumerating %d pixelformats", icdNumFormats );
@@ -269,6 +281,7 @@ rosglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd )
 
        if (best == 0)
                SetLastError( 0 ); /* FIXME: set appropriate error */
+       OPENGL32_UnloadICD( icd );
 
        DBGPRINT( "Info: Suggesting pixelformat %d", best );
        return best;
@@ -503,6 +516,7 @@ rosglDescribePixelFormat( HDC hdc, int iFormat, UINT nBytes,
                ret = icd->DrvDescribePixelFormat( hdc, iFormat, nBytes, pfd );
                if (ret == 0)
                        DBGPRINT( "Error: DrvDescribePixelFormat(format=%d) failed (%d)", iFormat, GetLastError() );
+               OPENGL32_UnloadICD( icd );
        }
 
        /* FIXME: implement own functionality? */
@@ -576,7 +590,9 @@ rosglGetProcAddress( LPCSTR proc )
 
        if (proc[0] == 'g' && proc[1] == 'l') /* glXXX */
        {
-               PROC glXXX = OPENGL32_threaddata->glrc->icd->DrvGetProcAddress( proc );
+               PROC glXXX = NULL;
+               GLDRIVERDATA *icd = OPENGL32_threaddata->glrc->icd;
+               glXXX = icd->DrvGetProcAddress( proc );
                if (glXXX)
                {
                        DBGPRINT( "Info: Proc \"%s\" loaded from ICD.", proc );
@@ -619,47 +635,61 @@ rosglMakeCurrent( HDC hdc, HGLRC hglrc )
                glFlush();
        }
 
-       /* check hdc */
-       if (GetObjectType( hdc ) != OBJ_DC)
+       /* check if current context is unset */
+       if (glrc == NULL)
        {
-               DBGPRINT( "Error: hdc is not a DC handle!" );
-               return FALSE;
+               if (OPENGL32_threaddata->glrc != NULL)
+               {
+                       OPENGL32_threaddata->glrc->is_current = FALSE;
+                       OPENGL32_threaddata->glrc = NULL;
+               }
        }
-
-       /* check if we know about this glrc */
-       if (!WGL_ContainsContext( glrc ))
+       else
        {
-               DBGPRINT( "Error: hglrc not found!" );
-               return FALSE; /* FIXME: SetLastError() */
-       }
+               /* check hdc */
+               if (GetObjectType( hdc ) != OBJ_DC && GetObjectType( hdc ) != OBJ_MEMDC)
+               {
+                       DBGPRINT( "Error: hdc is not a DC handle!" );
+                       return FALSE;
+               }
 
-       /* check if it is available */
-       if (glrc->is_current) /* used by another thread */
-       {
-               DBGPRINT( "Error: hglrc is current for thread 0x%08x", glrc->thread_id );
-               return FALSE; /* FIXME: SetLastError() */
-       }
+               /* check if we know about this glrc */
+               if (!WGL_ContainsContext( glrc ))
+               {
+                       DBGPRINT( "Error: hglrc not found!" );
+                       return FALSE; /* FIXME: SetLastError() */
+               }
 
-       /* call the ICD */
-       if (glrc->hglrc != NULL)
-       {
-               icdTable = glrc->icd->DrvSetContext( hdc, glrc->hglrc,
-                                                    WGL_SetContextCallBack );
-               if (icdTable == NULL)
+               /* check if it is available */
+               if (glrc->is_current && glrc->thread_id != GetCurrentThreadId()) /* used by another thread */
                {
-                       DBGPRINT( "Error: DrvSetContext failed (%d)\n", GetLastError() );
-                       return FALSE;
+                       DBGPRINT( "Error: hglrc is current for thread 0x%08x", glrc->thread_id );
+                       return FALSE; /* FIXME: SetLastError() */
                }
-               DBGPRINT( "Info: DrvSetContext succeeded!" );
+
+               /* call the ICD */
+               if (glrc->hglrc != NULL)
+               {
+                       icdTable = glrc->icd->DrvSetContext( hdc, glrc->hglrc,
+                                                                                                WGL_SetContextCallBack );
+                       if (icdTable == NULL)
+                       {
+                               DBGPRINT( "Error: DrvSetContext failed (%d)\n", GetLastError() );
+                               return FALSE;
+                       }
+                       DBGPRINT( "Info: DrvSetContext succeeded!" );
+               }
+
+               /* make it current */
+               if (OPENGL32_threaddata->glrc != NULL)
+                       OPENGL32_threaddata->glrc->is_current = FALSE;
+               glrc->is_current = TRUE;
+               glrc->thread_id = GetCurrentThreadId();
+               glrc->hdc = hdc;
+               OPENGL32_threaddata->glrc = glrc;
        }
 
-       /* make it current */
-       if (OPENGL32_threaddata->glrc != NULL)
-               OPENGL32_threaddata->glrc->is_current = FALSE;
-       glrc->is_current = TRUE;
-       glrc->thread_id = GetCurrentThreadId();
-       glrc->hdc = hdc;
-       OPENGL32_threaddata->glrc = glrc;
+       WGL_SetContextCallBack( icdTable );
 
        if (icdTable != NULL)
                if (WGL_SetContextCallBack( icdTable ) != ERROR_SUCCESS)
@@ -704,11 +734,13 @@ rosglSetPixelFormat( HDC hdc, int iFormat, CONST PIXELFORMATDESCRIPTOR *pfd )
        {
                DBGPRINT( "Warning: DrvSetPixelFormat(format=%d) failed (%d)",
                          iFormat, GetLastError() );
+               OPENGL32_UnloadICD( icd );
                return FALSE;
        }
 
        OPENGL32_processdata.cachedHdc = hdc;
        OPENGL32_processdata.cachedFormat = iFormat;
+       OPENGL32_UnloadICD( icd );
 
        return TRUE;
 }
@@ -764,8 +796,10 @@ rosglSwapBuffers( HDC hdc )
                if (!icd->DrvSwapBuffers( hdc ))
                {
                        DBGPRINT( "Error: DrvSwapBuffers failed (%d)", GetLastError() );
+                       OPENGL32_UnloadICD( icd );
                        return FALSE;
                }
+               OPENGL32_UnloadICD( icd );
                return TRUE;
        }