-/*===========================================================================*/\r
-/* */\r
-/* Mesa-3.0 Makefile for DirectX 6 */\r
-/* */\r
-/* By Leigh McRae */\r
-/* */\r
-/* http://www.altsoftware.com/ */\r
-/* */\r
-/* Copyright (c) 1998-1997 alt.software inc. All Rights Reserved */\r
-/*===========================================================================*/\r
-#include "D3DMesa.h"\r
-/*===========================================================================*/\r
-/* Window managment. */\r
-/*===========================================================================*/\r
-static BOOL InitOpenGL( HINSTANCE hInst );\r
-static BOOL TermOpenGL( HINSTANCE hInst );\r
-static BOOL ResizeContext( GLcontext *ctx );\r
-static BOOL MakeCurrent( D3DMESACONTEXT *pContext );\r
-static void DestroyContext( D3DMESACONTEXT *pContext );\r
-static BOOL UnBindWindow( D3DMESACONTEXT *pContext );\r
-LONG APIENTRY wglMonitorProc( HWND hwnd, UINT message, UINT wParam, LONG lParam );\r
-/*===========================================================================*/\r
-/* Mesa hooks. */\r
-/*===========================================================================*/\r
-static void SetupDDPointers( GLcontext *ctx );\r
-static void SetupSWDDPointers( GLcontext *ctx );\r
-static void SetupHWDDPointers( GLcontext *ctx );\r
-static void SetupNULLDDPointers( GLcontext *ctx );\r
-static const char *RendererString( void );\r
-\r
-/* State Management hooks. */\r
-static void SetColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a );\r
-static void ClearColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a );\r
-static GLboolean SetBuffer( GLcontext *ctx, GLenum buffer );\r
-\r
-/* Window Management hooks. */\r
-static void GetBufferSize( GLcontext *ctx, GLuint *width, GLuint *height );\r
-static void SetViewport( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h );\r
-static void Flush( GLcontext *ctx );\r
-\r
-/* Span rendering hooks. */\r
-void WSpanRGB( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte rgb[][3], const GLubyte mask[] );\r
-void WSpanRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte rgba[][4], const GLubyte mask[] );\r
-void WSpanRGBAMono( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte mask[] );\r
-void WPixelsRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte rgba[][4], const GLubyte mask[] );\r
-void WPixelsRGBAMono( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte mask[] );\r
-void RSpanRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, GLubyte rgba[][4] );\r
-void RPixelsRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], GLubyte rgba[][4], const GLubyte mask[] );\r
-GLbitfield ClearBuffers( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height );\r
-\r
-/* Primitve rendering hooks. */\r
-GLboolean RenderVertexBuffer( GLcontext *ctx, GLboolean allDone );\r
-void RenderOneTriangle( GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint pv );\r
-void RenderOneLine( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv );\r
-GLbitfield ClearBuffersD3D( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height );\r
-\r
-/* Texture Management hooks. */\r
-static void TextureBind( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj );\r
-static void TextureLoad( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint internalFormat, const struct gl_texture_image *image );\r
-static void TextureSubImage( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLint internalFormat, const struct gl_texture_image *image );\r
-/*===========================================================================*/\r
-/* Global variables. */\r
-/*===========================================================================*/\r
-D3DMESACONTEXT *pD3DCurrent, \r
- *pD3DDefault; /* Thin support context. */\r
-\r
-struct __extensions__ ext[] = {\r
-\r
- { (PROC)glPolygonOffsetEXT, "glPolygonOffsetEXT" },\r
- { (PROC)glBlendEquationEXT, "glBlendEquationEXT" },\r
- { (PROC)glBlendColorEXT, "glBlendColorExt" },\r
- { (PROC)glVertexPointerEXT, "glVertexPointerEXT" },\r
- { (PROC)glNormalPointerEXT, "glNormalPointerEXT" },\r
- { (PROC)glColorPointerEXT, "glColorPointerEXT" },\r
- { (PROC)glIndexPointerEXT, "glIndexPointerEXT" },\r
- { (PROC)glTexCoordPointerEXT, "glTexCoordPointer" },\r
- { (PROC)glEdgeFlagPointerEXT, "glEdgeFlagPointerEXT" },\r
- { (PROC)glGetPointervEXT, "glGetPointervEXT" },\r
- { (PROC)glArrayElementEXT, "glArrayElementEXT" },\r
- { (PROC)glDrawArraysEXT, "glDrawArrayEXT" },\r
- { (PROC)glAreTexturesResidentEXT, "glAreTexturesResidentEXT" },\r
- { (PROC)glBindTextureEXT, "glBindTextureEXT" },\r
- { (PROC)glDeleteTexturesEXT, "glDeleteTexturesEXT" },\r
- { (PROC)glGenTexturesEXT, "glGenTexturesEXT" },\r
- { (PROC)glIsTextureEXT, "glIsTextureEXT" },\r
- { (PROC)glPrioritizeTexturesEXT, "glPrioritizeTexturesEXT" },\r
- { (PROC)glCopyTexSubImage3DEXT, "glCopyTexSubImage3DEXT" },\r
- { (PROC)glTexImage3DEXT, "glTexImage3DEXT" },\r
- { (PROC)glTexSubImage3DEXT, "glTexSubImage3DEXT" },\r
-};\r
-\r
-int qt_ext = sizeof(ext) / sizeof(ext[0]);\r
-float g_DepthScale,\r
- g_MaxDepth;\r
-/*===========================================================================*/\r
-/* When a process loads this DLL we will setup the linked list for context */\r
-/* management and create a default context that will support the API until */\r
-/* the user creates and binds thier own. This THIN default context is useful*/\r
-/* to have around. */\r
-/* When the process terminates we will clean up all resources here. */\r
-/*===========================================================================*/\r
-/* RETURN: TRUE, FALSE. */\r
-/*===========================================================================*/\r
-BOOL APIENTRY DllMain( HINSTANCE hInst, DWORD reason, LPVOID reserved )\r
-{\r
- switch( reason ) \r
- {\r
- case DLL_PROCESS_ATTACH:\r
- return InitOpenGL( hInst );\r
-\r
- case DLL_PROCESS_DETACH:\r
- return TermOpenGL( hInst );\r
- } \r
-\r
- return TRUE;\r
-}\r
-/*===========================================================================*/\r
-/* The first thing we do when this dll is hit is connect to the dll that has*/\r
-/* handles all the DirectX 6 rendering. I decided to use another dll as DX6 */\r
-/* is all C++ and Mesa-3.0 is C (thats a good thing). This way I can write */\r
-/* the DX6 in C++ and Mesa-3.0 in C without having to worry about linkage. */\r
-/* I feel this is easy and better then using static wrappers as it is likely */\r
-/* faster and it allows me to just develope the one without compiling the */\r
-/* other. */\r
-/* NOTE that at this point we don't have much other than a very thin context*/\r
-/* that will support the API calls only to the point of not causing the app */\r
-/* to crash from the API table being empty. */\r
-/*===========================================================================*/\r
-/* RETURN: TRUE, FALSE. */\r
-/*===========================================================================*/\r
-static BOOL InitOpenGL( HINSTANCE hInst )\r
-{\r
- /* Allocate and clear the default context. */\r
- pD3DDefault = (PD3DMESACONTEXT)ALLOC( sizeof(D3DMESACONTEXT) );\r
- if ( pD3DDefault == NULL )\r
- return FALSE;\r
- memset( pD3DDefault, 0, sizeof(D3DMESACONTEXT) );\r
-\r
- /* Clear the D3D vertex buffer so that values not used will be zero. This */\r
- /* save me from some redundant work. */\r
- memset( &D3DTLVertices, 0, sizeof(D3DTLVertices) );\r
-\r
- /* Update the link. We uses a circular list so that it is easy to */\r
- /* add and search. This context will also be used for head and tail.*/\r
- pD3DDefault->next = pD3DDefault;\r
-\r
- /*========================================================================*/\r
- /* Do all core Mesa stuff. */\r
- /*========================================================================*/\r
- pD3DDefault->gl_visual = _mesa_create_visual( TRUE,\r
- FALSE, /* db_flag */\r
- GL_FALSE, /* stereo */\r
- 8,8,8,8, /* r, g, b, a bits */\r
- 0, /* index bits */\r
- 16, /* depth_bits */\r
- 8, /* stencil_bits */\r
- 8,8,8,8, /* accum_bits */\r
- 1 );\r
-\r
- if ( pD3DDefault->gl_visual == NULL) \r
- {\r
- FREE( pD3DDefault );\r
- return FALSE;\r
- }\r
-\r
- /* Allocate a new Mesa context */\r
- pD3DDefault->gl_ctx = _mesa_create_context( pD3DDefault->gl_visual, NULL, pD3DDefault, GL_TRUE );\r
- if ( pD3DDefault->gl_ctx == NULL ) \r
- {\r
- _mesa_destroy_visual( pD3DDefault->gl_visual );\r
- FREE( pD3DDefault );\r
- return FALSE;\r
- }\r
-\r
- /* Allocate a new Mesa frame buffer */\r
- pD3DDefault->gl_buffer = _mesa_create_framebuffer( pD3DDefault->gl_visual );\r
- if ( pD3DDefault->gl_buffer == NULL )\r
- {\r
- _mesa_destroy_visual( pD3DDefault->gl_visual );\r
- _mesa_destroy_context( pD3DDefault->gl_ctx );\r
- FREE( pD3DDefault );\r
- return FALSE;\r
- }\r
- SetupDDPointers( pD3DDefault->gl_ctx );\r
- _mesa_make_current( pD3DDefault->gl_ctx, pD3DDefault->gl_buffer );\r
-\r
- return TRUE;\r
-}\r
-/*===========================================================================*/\r
-/* This function will create a new D3D context but will not create the D3D */\r
-/* surfaces or even an instance of D3D (see at GetBufferSize). The only stuff*/\r
-/* done here is the internal Mesa stuff and some Win32 handles. */\r
-/*===========================================================================*/\r
-/* RETURN: casted pointer to the context, NULL. */\r
-/*===========================================================================*/\r
-HGLRC APIENTRY wglCreateContext( HDC hdc )\r
-{\r
- D3DMESACONTEXT *pNewContext;\r
- DWORD dwCoopFlags = DDSCL_NORMAL;\r
- RECT rectClient;\r
- POINT pt;\r
-\r
- /* ALLOC and clear the new context. */\r
- pNewContext = (PD3DMESACONTEXT)ALLOC( sizeof(D3DMESACONTEXT) );\r
- if ( pNewContext == NULL )\r
- {\r
- SetLastError( 0 );\r
- return (HGLRC)NULL;\r
- }\r
- memset( pNewContext, 0, sizeof(D3DMESACONTEXT) );\r
-\r
- /*========================================================================*/\r
- /* Do all core Mesa stuff. */\r
- /*========================================================================*/\r
-\r
- /* TODO: support more then one visual. */\r
- pNewContext->gl_visual = _mesa_create_visual( TRUE,\r
- TRUE, /* db_flag */\r
- GL_FALSE, /* stereo */\r
- 8,8,8,8, /* r, g, b, a bits */\r
- 0, /* index bits */\r
- 16, /* depth_bits */\r
- 8, /* stencil_bits */\r
- 16,16,16,16,/* accum_bits */\r
- 1 );\r
- if ( pNewContext->gl_visual == NULL) \r
- {\r
- FREE( pNewContext );\r
- SetLastError( 0 );\r
- return (HGLRC)NULL;\r
- }\r
-\r
- /* Allocate a new Mesa context */\r
- pNewContext->gl_ctx = _mesa_create_context( pNewContext->gl_visual, NULL, pNewContext, GL_TRUE );\r
- if ( pNewContext->gl_ctx == NULL ) \r
- {\r
- _mesa_destroy_visual( pNewContext->gl_visual );\r
- FREE( pNewContext );\r
- SetLastError( 0 );\r
- return (HGLRC)NULL;\r
- }\r
-\r
- /* Allocate a new Mesa frame buffer */\r
- pNewContext->gl_buffer = _mesa_create_framebuffer( pNewContext->gl_visual );\r
- if ( pNewContext->gl_buffer == NULL )\r
- {\r
- _mesa_destroy_visual( pNewContext->gl_visual );\r
- _mesa_destroy_context( pNewContext->gl_ctx );\r
- FREE( pNewContext );\r
- SetLastError( 0 );\r
- return (HGLRC)NULL;\r
- }\r
-\r
- /*========================================================================*/\r
- /* Do all the driver stuff. */\r
- /*========================================================================*/\r
- pNewContext->hdc = hdc;\r
- pNewContext->next = pD3DDefault->next;\r
- pD3DDefault->next = pNewContext; /* Add to circular list. */\r
-\r
- /* Create the HAL for the new context. */\r
- pNewContext->pShared = InitHAL( WindowFromDC(hdc) );\r
-\r
- return (HGLRC)pNewContext;\r
-}\r
-/*===========================================================================*/\r
-/* This is a wrapper function that is supported by MakeCurrent. */\r
-/*===========================================================================*/\r
-/* RETURN: TRUE, FALSE. */\r
-/*===========================================================================*/\r
-BOOL APIENTRY wglMakeCurrent( HDC hdc, HGLRC hglrc )\r
-{\r
- return MakeCurrent((D3DMESACONTEXT *)hglrc);\r
-}\r
-/*===========================================================================*/\r
-/* MakeCurrent will unbind whatever context is current (if any) & then bind */\r
-/* the supplied context. A context that is bound has it's window proc hooked*/\r
-/* with the wglMonitorProc and the context pointer is saved in pD3DCurrent. */\r
-/* Once the context is bound we update the Mesa-3.0 hooks (SetDDPointers) and*/\r
-/* the viewport (Mesa-.30 and DX6). */\r
-/* */\r
-/* TODO: this function can't fail. */\r
-/*===========================================================================*/\r
-/* RETURN: TRUE */\r
-/*===========================================================================*/\r
-static BOOL MakeCurrent( D3DMESACONTEXT *pContext )\r
-{\r
- D3DMESACONTEXT *pNext;\r
-\r
- /*====================================================================*/\r
- /* This is a special case that is a request to have no context bound. */\r
- /*====================================================================*/\r
- if ( pContext == NULL )\r
- {\r
- /* Walk the whole list. We start and end at the Default context. */\r
- for( pNext = pD3DDefault->next; pNext != pD3DDefault; pNext = pNext->next )\r
- UnBindWindow( pNext );\r
- \r
- return TRUE;\r
- }\r
-\r
- /*=================================================*/\r
- /* Make for a fast redundant use of this function. */\r
- /*=================================================*/\r
- if ( pD3DCurrent == pContext )\r
- return TRUE;\r
-\r
- /*=============================*/\r
- /* Unbind the current context. */\r
- /*=============================*/\r
- UnBindWindow( pD3DCurrent );\r
-\r
- /*=====================================*/\r
- /* Let Mesa-3.0 we have a new context. */\r
- /*=====================================*/\r
- SetupDDPointers( pContext->gl_ctx );\r
- _mesa_make_current( pContext->gl_ctx, pContext->gl_buffer );\r
-\r
- /* We are done so set the internal current context. */\r
- if ( pContext != pD3DDefault )\r
- {\r
- ResizeContext( pContext->gl_ctx );\r
- pContext->hOldProc = (WNDPROC)GetWindowLong( pContext->pShared->hwnd, GWL_WNDPROC );\r
- SetWindowLong( pContext->pShared->hwnd, GWL_WNDPROC, (LONG)wglMonitorProc );\r
- }\r
- pD3DCurrent = pContext;\r
-\r
- return TRUE;\r
-}\r
-/*===========================================================================*/\r
-/* This function will only return the current window size. I have re-done */ \r
-/* this function so that it doesn't check the current size and react to it as*/ \r
-/* I should be able to have all the react code in the WM_SIZE message. The */ \r
-/* old version would check the current window size and create/resize the HAL */ \r
-/* surfaces if they have changed. I needed to delay the creation if the */ \r
-/* surfaces because sometimes I wouldn't have a window size so this is where */ \r
-/* I delayed it. If you are reading this then all went ok! */ \r
-/* The default context will return a zero sized window and I'm not sure if */\r
-/* this is ok at this point (TODO). */\r
-/*===========================================================================*/\r
-/* RETURN: */\r
-/*===========================================================================*/\r
-static void GetBufferSize( GLcontext *ctx, GLuint *width, GLuint *height )\r
-{\r
- D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
-\r
- /* Fall through for the default because that is one of the uses for it. */\r
- if ( pContext == pD3DDefault )\r
- {\r
- *width = 0;\r
- *height = 0;\r
- }\r
- else\r
- {\r
- *width = pContext->pShared->dwWidth;\r
- *height = pContext->pShared->dwHeight;\r
- }\r
-}\r
-/*===========================================================================*/\r
-/* */\r
-/* */\r
-/*===========================================================================*/\r
-/* RETURN: */\r
-/*===========================================================================*/\r
-static BOOL ResizeContext( GLcontext *ctx )\r
-{\r
- D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx,\r
- *pCurrentTemp;\r
- RECT rectClient;\r
- POINT pt;\r
- DWORD dwWidth,\r
- dwHeight;\r
- static BOOL bDDrawLock = FALSE;\r
-\r
- /* Make sure we have some values. */\r
- if ( (pContext->hdc == NULL ) || \r
- (pContext->pShared->hwnd != WindowFromDC(pContext->hdc)) ||\r
- (pContext == pD3DDefault) )\r
- return FALSE;\r
-\r
- /* Having problems with DDraw sending resize messages before I was done. */\r
- if( bDDrawLock == TRUE )\r
- return FALSE;\r
-\r
- // TODO: don't think I need this anymore.\r
- pCurrentTemp = pD3DCurrent;\r
- pD3DCurrent = pD3DDefault;\r
- bDDrawLock = TRUE;\r
-\r
- /* Get the current window dimentions. */\r
- UpdateScreenPosHAL( pContext->pShared );\r
- dwWidth = pContext->pShared->rectW.right - pContext->pShared->rectW.left;\r
- dwHeight = pContext->pShared->rectW.bottom - pContext->pShared->rectW.top;\r
-\r
- /* Is the size of the OffScreen Render different? */\r
- if ( (dwWidth != pContext->pShared->dwWidth) || (dwHeight != pContext->pShared->dwHeight) )\r
- {\r
- /* Create all the D3D surfaces and device. */\r
- CreateHAL( pContext->pShared );\r
-\r
- /* I did this so that software rendering would still work as */\r
- /* I don't need to scale the z values twice. */\r
- g_DepthScale = (pContext->pShared->bHardware) ? 1.0 : ((float)0x00FFFFFF);\r
- g_MaxDepth = (pContext->pShared->bHardware) ? 1.0 : ((float)0x00FFFFFF);\r
- gl_DepthRange( pContext->gl_ctx, ctx->Viewport.Near, ctx->Viewport.Far );\r
-\r
- /* Make sure we have a viewport. */\r
- gl_Viewport( pContext->gl_ctx, 0, 0, dwWidth, dwHeight );\r
-\r
- /* Update Mesa as we might have changed from SW <-> HW. */\r
- SetupDDPointers( pContext->gl_ctx );\r
- _mesa_make_current( pContext->gl_ctx, pContext->gl_buffer );\r
-\r
- /* If we are in HW we need to load the current texture if there is one already. */\r
- // if ( (ctx->Texture.Set[ctx->Texture.CurrentSet].Current != NULL) &&\r
- // (pContext->pShared->bHardware == TRUE) )\r
- // {\r
- // CreateTMgrHAL( pContext->pShared,\r
- // ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Name,\r
- // 0, \r
- // ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Format,\r
- // (RECT *)NULL,\r
- // ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Width,\r
- // ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Height,\r
- // TM_ACTION_BIND,\r
- // (void *)ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Data );\r
- // }\r
- }\r
-\r
- // TODO: don't think I need this anymore.\r
- pD3DCurrent = pCurrentTemp;\r
- bDDrawLock = FALSE;\r
-\r
- return TRUE;\r
-}\r
-\r
-/*===========================================================================*\r
-/* This function will Blt the render buffer to the PRIMARY surface. I repeat*/\r
-/* this code for the other SwapBuffer like functions and the flush (didn't */\r
-/* want the function calling overhead). Thsi could have been a macro... */\r
-/* */\r
-/* TODO: there are some problems with viewport/scissoring. */\r
-/*===========================================================================*/\r
-/* RETURN: TRUE, FALSE. */\r
-/*===========================================================================*/\r
-BOOL APIENTRY wglSwapBuffers( HDC hdc )\r
-{\r
- /* Fall through for the default because that is one of the uses for it. */\r
- if ( pD3DCurrent == pD3DDefault )\r
- return FALSE;\r
-\r
- SwapBuffersHAL( pD3DCurrent->pShared );\r
-\r
- return TRUE;\r
-}\r
-/*===========================================================================*/\r
-/* Same as wglSwapBuffers. */\r
-/*===========================================================================*/\r
-/* RETURN: TRUE, FALSE. */\r
-/*===========================================================================*/\r
-BOOL APIENTRY SwapBuffers( HDC hdc )\r
-{\r
- /* Fall through for the default because that is one of the uses for it. */\r
- if ( pD3DCurrent == pD3DDefault )\r
- return FALSE;\r
-\r
- SwapBuffersHAL( pD3DCurrent->pShared );\r
-\r
- return TRUE;\r
-}\r
-/*===========================================================================*/\r
-/* This should be ok as none of the SwapBuffers will cause a redundant Blt */\r
-/* as none of my Swap functions will call flush. This should also allow */\r
-/* sinlge buffered applications to work (not really worried though). Some */\r
-/* applications may flush then swap but then this is there fault IMHO. */\r
-/*===========================================================================*/\r
-/* RETURN: */\r
-/*===========================================================================*/\r
-static void Flush( GLcontext *ctx )\r
-{\r
- /* Fall through for the default because that is one of the uses for it. */\r
- if ( pD3DCurrent == pD3DDefault )\r
- return;\r
-\r
- SwapBuffersHAL( pD3DCurrent->pShared );\r
-}\r
-/*===========================================================================*/\r
-/* For now this function will ignore the supplied PF. If I'm going to allow */\r
-/* the user to choice the mode and device at startup I'm going to have to do */\r
-/* something different. */\r
-/* */\r
-/* TODO: use the linked list of modes to build a pixel format to be returned */\r
-/* to the caller. */\r
-/*===========================================================================*/\r
-/* RETURN: 1. */\r
-/*===========================================================================*/\r
-int APIENTRY wglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *ppfd )\r
-{\r
- return 1;\r
-}\r
-/*===========================================================================*/\r
-/* See wglChoosePixelFormat. */\r
-/*===========================================================================*/\r
-/* RETURN: 1. */\r
-/*===========================================================================*/\r
-int APIENTRY ChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *ppfd )\r
-{\r
- return wglChoosePixelFormat(hdc,ppfd);\r
-}\r
-/*===========================================================================*/\r
-/* This function (for now) returns a static PF everytime. This is just to */\r
-/* allow things to continue. */\r
-/*===========================================================================*/\r
-/* RETURN: 1. */\r
-/*===========================================================================*/\r
-int APIENTRY wglDescribePixelFormat( HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd )\r
-{\r
- static PIXELFORMATDESCRIPTOR pfd = \r
- {\r
- sizeof(PIXELFORMATDESCRIPTOR), /* size */\r
- 1, /* version */\r
- PFD_SUPPORT_OPENGL |\r
- PFD_DRAW_TO_WINDOW |\r
- PFD_DOUBLEBUFFER, /* support double-buffering */\r
- PFD_TYPE_RGBA, /* color type */\r
- 16, /* prefered color depth */\r
- 0, 0, 0, 0, 0, 0, /* color bits (ignored) */\r
- 0, /* no alpha buffer */\r
- 0, /* alpha bits (ignored) */\r
- 0, /* no accumulation buffer */\r
- 0, 0, 0, 0, /* accum bits (ignored) */\r
- 16, /* depth buffer */\r
- 0, /* no stencil buffer */\r
- 0, /* no auxiliary buffers */\r
- PFD_MAIN_PLANE, /* main layer */\r
- 0, /* reserved */\r
- 0, 0, 0, /* no layer, visible, damage masks */\r
- };\r
-\r
- /* Return the address of this static PF if one was requested. */\r
- if ( ppfd != NULL )\r
- memcpy( ppfd, &pfd, sizeof(PIXELFORMATDESCRIPTOR) );\r
-\r
- return 1;\r
-}\r
-/*===========================================================================*/\r
-/* See wglDescribePixelFormat. */\r
-/*===========================================================================*/\r
-/* RETURN: 1. */\r
-/*===========================================================================*/\r
-int APIENTRY DescribePixelFormat( HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd )\r
-{\r
- return wglDescribePixelFormat(hdc,iPixelFormat,nBytes,ppfd);\r
-}\r
-/*===========================================================================*/\r
-/* This function will always return 1 for now. Just to allow for support. */\r
-/*===========================================================================*/\r
-/* RETURN: 1. */\r
-/*===========================================================================*/\r
-int APIENTRY wglGetPixelFormat( HDC hdc )\r
-{\r
- return 1;\r
-}\r
-/*===========================================================================*/\r
-/* See wglGetPixelFormat. */\r
-/*===========================================================================*/\r
-/* RETURN: 1. */\r
-/*===========================================================================*/\r
-int APIENTRY GetPixelFormat( HDC hdc )\r
-{\r
- return wglGetPixelFormat(hdc);\r
-}\r
-/*===========================================================================*/\r
-/* This will aways work for now. */\r
-/*===========================================================================*/\r
-/* RETURN: TRUE. */\r
-/*===========================================================================*/\r
-BOOL APIENTRY wglSetPixelFormat( HDC hdc, int iPixelFormat, CONST PIXELFORMATDESCRIPTOR *ppfd )\r
-{\r
- return TRUE;\r
-}\r
-/*===========================================================================*/\r
-/* See wglSetPixelFormat. */\r
-/*===========================================================================*/\r
-/* RETURN: TRUE, FALSE. */\r
-/*===========================================================================*/\r
-BOOL APIENTRY SetPixelFormat( HDC hdc, int iPixelFormat, CONST PIXELFORMATDESCRIPTOR *ppfd )\r
-{\r
- return wglSetPixelFormat(hdc,iPixelFormat,ppfd);\r
-}\r
-/*===========================================================================*/\r
-/* This is a wrapper function that is supported by my own internal function.*/\r
-/* that takes my own D3D Mesa context structure. This so I can reuse the */\r
-/* function (no need for speed). */\r
-/*===========================================================================*/\r
-/* RETURN: TRUE. */\r
-/*===========================================================================*/\r
-BOOL APIENTRY wglDeleteContext( HGLRC hglrc )\r
-{\r
- DestroyContext( (D3DMESACONTEXT *)hglrc );\r
-\r
- return TRUE;\r
-}\r
-/*===========================================================================*/\r
-/* Simple getter function that uses a cast. */\r
-/*===========================================================================*/\r
-/* RETURN: casted pointer to the context, NULL. */\r
-/*===========================================================================*/\r
-HGLRC APIENTRY wglGetCurrentContext( VOID )\r
-{\r
- return (pD3DCurrent) ? (HGLRC)pD3DCurrent : (HGLRC)NULL;\r
-}\r
-/*===========================================================================*/\r
-/* No support. */\r
-/*===========================================================================*/\r
-/* RETURN: FALSE. */\r
-/*===========================================================================*/\r
-BOOL APIENTRY wglCopyContext( HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask )\r
-{\r
- SetLastError( 0 );\r
- return FALSE;\r
-}\r
-/*===========================================================================*/\r
-/* No support. */\r
-/*===========================================================================*/\r
-/* RETURN: NULL. */\r
-/*===========================================================================*/\r
-HGLRC APIENTRY wglCreateLayerContext( HDC hdc,int iLayerPlane )\r
-{\r
- SetLastError( 0 );\r
- return (HGLRC)NULL;\r
-}\r
-/*===========================================================================*/\r
-/* Simple getter function. */\r
-/*===========================================================================*/\r
-/* RETURN: FALSE. */\r
-/*===========================================================================*/\r
-HDC APIENTRY wglGetCurrentDC( VOID )\r
-{\r
- return (pD3DCurrent) ? pD3DCurrent->hdc : (HDC)NULL;\r
-}\r
-/*===========================================================================*/\r
-/* Simply call that searches the supported extensions for a match & returns */\r
-/* the pointer to the function that lends support. */\r
-/*===========================================================================*/\r
-/* RETURN: pointer to API call, NULL. */\r
-/*===========================================================================*/\r
-PROC APIENTRY wglGetProcAddress( LPCSTR lpszProc )\r
-{\r
- int index;\r
-\r
- for( index = 0; index < qt_ext; index++ )\r
- if( !strcmp(lpszProc,ext[index].name) )\r
- return ext[index].proc;\r
-\r
- SetLastError( 0 );\r
- return NULL;\r
-}\r
-/*===========================================================================*/\r
-/* No support. */\r
-/*===========================================================================*/\r
-/* RETURN: FALSE. */\r
-/*===========================================================================*/\r
-BOOL APIENTRY wglShareLists( HGLRC hglrc1, HGLRC hglrc2 )\r
-{\r
- SetLastError( 0 );\r
- return FALSE;\r
-}\r
-/*===========================================================================*/\r
-/* No support. */\r
-/*===========================================================================*/\r
-/* RETURN: FALSE. */\r
-/*===========================================================================*/\r
-BOOL APIENTRY wglUseFontBitmaps( HDC fontDevice, DWORD firstChar, DWORD numChars, DWORD listBase )\r
-{\r
- SetLastError( 0 );\r
- return FALSE;\r
-}\r
-/*===========================================================================*/\r
-/* No support. */\r
-/*===========================================================================*/\r
-/* RETURN: FALSE. */\r
-/*===========================================================================*/\r
-BOOL APIENTRY wglUseFontBitmapsW( HDC hdc,DWORD first,DWORD count,DWORD listBase )\r
-{\r
- SetLastError( 0 );\r
- return FALSE;\r
-}\r
-/*===========================================================================*/\r
-/* No support. */\r
-/*===========================================================================*/\r
-/* RETURN: FALSE. */\r
-/*===========================================================================*/\r
-BOOL APIENTRY wglUseFontOutlinesA( HDC hdc, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf )\r
-{\r
- SetLastError( 0 );\r
- return FALSE;\r
-}\r
-/*===========================================================================*/\r
-/* No support. */\r
-/*===========================================================================*/\r
-/* RETURN: FALSE. */\r
-/*===========================================================================*/\r
-BOOL APIENTRY wglUseFontOutlinesW( HDC hdc,DWORD first,DWORD count, DWORD listBase,FLOAT deviation, FLOAT extrusion,int format, LPGLYPHMETRICSFLOAT lpgmf )\r
-{\r
- SetLastError( 0 );\r
- return FALSE ;\r
-}\r
-/*===========================================================================*/\r
-/* No support. */\r
-/*===========================================================================*/\r
-/* RETURN: FALSE. */\r
-/*===========================================================================*/\r
-BOOL APIENTRY wglSwapLayerBuffers( HDC hdc, UINT fuPlanes )\r
-{\r
- SetLastError( 0 );\r
- return FALSE;\r
-}\r
-/*===========================================================================*/\r
-/* This function will be hooked into the window that has been bound. Right */\r
-/* now it is used to track the window size and position. Also the we clean */\r
-/* up the currrent context when the window is close/destroyed. */\r
-/* */\r
-/* TODO: there might be something wrong here as some games (Heretic II) don't*/\r
-/* track the window quit right. */\r
-/*===========================================================================*/\r
-/* RETURN: */\r
-/*===========================================================================*/\r
-LONG APIENTRY wglMonitorProc( HWND hwnd, UINT message, UINT wParam, LONG lParam )\r
-{\r
- WNDPROC hOldProc;\r
- GLint width,\r
- height;\r
-\r
- switch( message ) \r
- {\r
-// case WM_PAINT:\r
-// break;\r
-// case WM_ACTIVATE:\r
-// break;\r
-// case WM_SHOWWINDOW:\r
-// break;\r
-\r
- case UM_FATALSHUTDOWN:\r
- /* Support the API until we die... */\r
- MakeCurrent( pD3DDefault );\r
- break;\r
-\r
- case WM_MOVE:\r
- case WM_DISPLAYCHANGE:\r
- case WM_SIZE:\r
- ResizeContext( pD3DCurrent->gl_ctx );\r
- break;\r
-\r
- case WM_CLOSE:\r
- case WM_DESTROY:\r
- /* Support the API until we die... */\r
- hOldProc = pD3DCurrent->hOldProc;\r
- DestroyContext( pD3DCurrent );\r
- return (hOldProc)(hwnd,message,wParam,lParam);\r
- }\r
-\r
- return (pD3DCurrent->hOldProc)(hwnd,message,wParam,lParam);\r
-}\r
-\r
-/**********************************************************************/\r
-/***** Miscellaneous device driver funcs *****/\r
-/**********************************************************************/\r
-\r
-/*===========================================================================*/\r
-/* Not reacting to this as I'm only supporting drawing to the back buffer */\r
-/* right now. */\r
-/*===========================================================================*/\r
-/* RETURN: TRUE. */\r
-/*===========================================================================*/\r
-static GLboolean SetBuffer( GLcontext *ctx, GLenum buffer )\r
-{\r
- if (buffer == GL_BACK_LEFT)\r
- return GL_TRUE;\r
- else\r
- return GL_FALSE;\r
-}\r
-/*===========================================================================*/\r
-/* This proc will be called by Mesa when the viewport has been set. So if */\r
-/* we have a context and it isn't the default then we should let D3D know of */\r
-/* the change. */\r
-/*===========================================================================*/\r
-/* RETURN: */\r
-/*===========================================================================*/\r
-static void SetViewport( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h )\r
-{\r
- D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
- RECT rect;\r
-\r
- /* Make sure we can set a viewport. */\r
- if ( pContext->pShared && (pContext != pD3DDefault) )\r
- {\r
- // TODO: might be needed.\r
- UpdateScreenPosHAL( pContext->pShared );\r
- rect.left = x;\r
- rect.right = x + w;\r
- rect.top = y;\r
- rect.bottom = y + h;\r
-\r
- // TODO: shared struct should make this call smaller\r
- SetViewportHAL( pContext->pShared, &rect, 0.0F, 1.0F );\r
- }\r
-}\r
-/*===========================================================================*/\r
-/* This function could be better I guess but I decided just to grab the four*/\r
-/* components and store then seperately. Makes it easier to use IMHO. */\r
-/*===========================================================================*/\r
-/* RETURN: */\r
-/*===========================================================================*/\r
-static void ClearColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )\r
-{\r
- D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
-\r
- pContext->aClear = a;\r
- pContext->bClear = b;\r
- pContext->gClear = g;\r
- pContext->rClear = r;\r
-}\r
-/*===========================================================================*/\r
-/* This function could be better I guess but I decided just to grab the four*/\r
-/* components and store then seperately. Makes it easier to use IMHO. */\r
-/* (is there an echo in here?) */\r
-/*===========================================================================*/\r
-/* RETURN: */\r
-/*===========================================================================*/\r
-static void SetColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )\r
-{\r
- D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
-\r
- pContext->aCurrent = a;\r
- pContext->bCurrent = b;\r
- pContext->gCurrent = g;\r
- pContext->rCurrent = r;\r
-}\r
-/*===========================================================================*/\r
-/* */\r
-/* */\r
-/*===========================================================================*/\r
-/* RETURN: */\r
-/*===========================================================================*/\r
-static const char *RendererString( void )\r
-{\r
- static char pszRender[64];\r
-\r
- strcpy( pszRender, "altD3D " );\r
-\r
- if ( pD3DCurrent->pShared->bHardware )\r
- strcat( pszRender, "(HW)");\r
- else\r
- strcat( pszRender, "(SW)");\r
-\r
- return (const char *)pszRender;\r
-}\r
-/*===========================================================================*/\r
-/* This function will choose which set of pointers Mesa will use based on */\r
-/* whether we hard using hardware or software. I have added another set of */\r
-/* pointers that will do nothing but stop the API from crashing. */\r
-/*===========================================================================*/\r
-/* RETURN: */\r
-/*===========================================================================*/\r
-static void SetupDDPointers( GLcontext *ctx )\r
-{\r
- D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
-\r
- // TODO: write a generic NULL support for the span render. \r
- if ( pContext->pShared && pContext->pShared->bHardware )\r
- {\r
- ctx->Driver.UpdateState = SetupHWDDPointers;\r
- }\r
- else if ( pContext == pD3DDefault )\r
- {\r
- ctx->Driver.UpdateState = SetupNULLDDPointers;\r
- }\r
- else\r
- {\r
- ctx->Driver.UpdateState = SetupSWDDPointers;\r
- }\r
-}\r
-/*===========================================================================*/\r
-/* This function will populate all the Mesa driver hooks. This version of */\r
-/* hooks will do nothing but support the API when we don't have a valid */\r
-/* context bound. This is mostly for applications that don't behave right */\r
-/* and also to help exit as clean as possable when we have a FatalError. */\r
-/*===========================================================================*/\r
-/* RETURN: pointer to the specific function. */\r
-/*===========================================================================*/\r
-static void SetupNULLDDPointers( GLcontext *ctx )\r
-{\r
- D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
-\r
- /* Initialize all the pointers in the DD struct. Do this whenever */\r
- /* a new context is made current or we change buffers via set_buffer! */\r
- ctx->Driver.UpdateState = SetupNULLDDPointers;\r
-\r
- /* State management hooks. */\r
- ctx->Driver.Color = NULLSetColor;\r
- ctx->Driver.ClearColor = NULLClearColor;\r
- ctx->Driver.Clear = NULLClearBuffers;\r
- ctx->Driver.SetBuffer = NULLSetBuffer;\r
-\r
- /* Window management hooks. */\r
- ctx->Driver.GetBufferSize = NULLGetBufferSize;\r
-\r
- /* Primitive rendering hooks. */\r
- ctx->Driver.TriangleFunc = NULL;\r
- ctx->Driver.RenderVB = NULL;\r
-\r
- /* Pixel/span writing functions: */\r
- ctx->Driver.WriteRGBASpan = NULLWrSpRGBA;\r
- ctx->Driver.WriteRGBSpan = NULLWrSpRGB;\r
- ctx->Driver.WriteMonoRGBASpan = NULLWrSpRGBAMono;\r
- ctx->Driver.WriteRGBAPixels = NULLWrPiRGBA;\r
- ctx->Driver.WriteMonoRGBAPixels = NULLWrPiRGBAMono;\r
-\r
- /* Pixel/span reading functions: */\r
- ctx->Driver.ReadRGBASpan = NULLReSpRGBA;\r
- ctx->Driver.ReadRGBAPixels = NULLRePiRGBA;\r
-\r
- /* Misc. hooks. */\r
- ctx->Driver.RendererString = RendererString;\r
-}\r
-/*===========================================================================*/\r
-/* This function will populate all the Mesa driver hooks. There are two of */\r
-/* these functions. One if we have hardware support and one is there is only*/\r
-/* software. These functions will be called by Mesa and by the wgl.c when we*/\r
-/* have resized (or created) the buffers. The thing is that if a window gets*/\r
-/* resized we may loose hardware support or gain it... */\r
-/*===========================================================================*/\r
-/* RETURN: pointer to the specific function. */\r
-/*===========================================================================*/\r
-static void SetupSWDDPointers( GLcontext *ctx )\r
-{\r
- D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
-\r
- /* Initialize all the pointers in the DD struct. Do this whenever */\r
- /* a new context is made current or we change buffers via set_buffer! */\r
- ctx->Driver.UpdateState = SetupSWDDPointers;\r
-\r
- /* State management hooks. */\r
- ctx->Driver.Color = SetColor;\r
- ctx->Driver.ClearColor = ClearColor;\r
- ctx->Driver.Clear = ClearBuffers;\r
- ctx->Driver.SetBuffer = SetBuffer;\r
-\r
- /* Window management hooks. */\r
- ctx->Driver.GetBufferSize = GetBufferSize;\r
- ctx->Driver.Viewport = SetViewport;\r
-\r
- /* Primitive rendering hooks. */\r
- ctx->Driver.TriangleFunc = NULL;\r
- ctx->Driver.RenderVB = NULL;\r
-\r
- /* Texture management hooks. */\r
-\r
- /* Pixel/span writing functions: */\r
- ctx->Driver.WriteRGBASpan = WSpanRGBA;\r
- ctx->Driver.WriteRGBSpan = WSpanRGB;\r
- ctx->Driver.WriteMonoRGBASpan = WSpanRGBAMono;\r
- ctx->Driver.WriteRGBAPixels = WPixelsRGBA;\r
- ctx->Driver.WriteMonoRGBAPixels = WPixelsRGBAMono;\r
-\r
- /* Pixel/span reading functions: */\r
- ctx->Driver.ReadRGBASpan = RSpanRGBA;\r
- ctx->Driver.ReadRGBAPixels = RPixelsRGBA;\r
-\r
- /* Misc. hooks. */\r
- ctx->Driver.Flush = Flush;\r
- ctx->Driver.RendererString = RendererString;\r
-}\r
-/*===========================================================================*/\r
-/* This function will populate all the Mesa driver hooks. There are two of */\r
-/* these functions. One if we have hardware support and one is there is only*/\r
-/* software. These functions will be called by Mesa and by the wgl.c when we*/\r
-/* have resized (or created) the buffers. The thing is that if a window gets*/\r
-/* resized we may loose hardware support or gain it... */\r
-/*===========================================================================*/\r
-/* RETURN: pointer to the specific function. */\r
-/*===========================================================================*/\r
-static void SetupHWDDPointers( GLcontext *ctx )\r
-{\r
- D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
-\r
- /* Initialize all the pointers in the DD struct. Do this whenever */\r
- /* a new context is made current or we change buffers via set_buffer! */\r
- ctx->Driver.UpdateState = SetupHWDDPointers;\r
-\r
- /* State management hooks. */\r
- ctx->Driver.Color = SetColor;\r
- ctx->Driver.ClearColor = ClearColor;\r
- ctx->Driver.Clear = ClearBuffersD3D;\r
- ctx->Driver.SetBuffer = SetBuffer;\r
-\r
- /* Window management hooks. */\r
- ctx->Driver.GetBufferSize = GetBufferSize;\r
- ctx->Driver.Viewport = SetViewport;\r
-\r
- /* Primitive rendering hooks. */\r
- ctx->Driver.TriangleFunc = RenderOneTriangle;\r
- ctx->Driver.LineFunc = RenderOneLine;\r
- ctx->Driver.RenderVB = RenderVertexBuffer;\r
-\r
- /* Pixel/span writing functions: */\r
- ctx->Driver.WriteRGBASpan = WSpanRGBA;\r
- ctx->Driver.WriteRGBSpan = WSpanRGB;\r
- ctx->Driver.WriteMonoRGBASpan = WSpanRGBAMono;\r
- ctx->Driver.WriteRGBAPixels = WPixelsRGBA;\r
- ctx->Driver.WriteMonoRGBAPixels = WPixelsRGBAMono;\r
-\r
- /* Pixel/span reading functions: */\r
- ctx->Driver.ReadRGBASpan = RSpanRGBA;\r
- ctx->Driver.ReadRGBAPixels = RPixelsRGBA;\r
-\r
- /* Texture management hooks. */\r
- // ctx->Driver.BindTexture = TextureBind;\r
- ctx->Driver.TexImage = TextureLoad;\r
- ctx->Driver.TexSubImage = TextureSubImage;\r
-\r
- /* Misc. hooks. */\r
- ctx->Driver.Flush = Flush;\r
- ctx->Driver.RendererString = RendererString;\r
-}\r
-/*===========================================================================*/\r
-/* This function will release all resources used by the DLL. Every context */\r
-/* will be clobbered by releaseing all driver desources and then freeing the */\r
-/* context memory. Most all the work is done in DestroyContext. */\r
-/*===========================================================================*/\r
-/* RETURN: TRUE. */\r
-/*===========================================================================*/\r
-static BOOL TermOpenGL( HINSTANCE hInst )\r
-{\r
- D3DMESACONTEXT *pTmp,\r
- *pNext;\r
-\r
- /* Just incase we are still getting paint msg. */\r
- MakeCurrent( pD3DDefault );\r
-\r
- /* Walk the list until we get back to the default context. */\r
- for( pTmp = pD3DDefault->next; pTmp != pD3DDefault; pTmp = pNext )\r
- {\r
- pNext = pTmp->next;\r
- DestroyContext( pTmp );\r
- }\r
- DestroyContext( pD3DDefault );\r
-\r
- return TRUE;\r
-}\r
-/*===========================================================================*/\r
-/* This function is an internal function that will clean up all the Mesa */\r
-/* context bound to this D3D context. Also any D3D stuff that this context */\r
-/* uses will be unloaded. */\r
-/*===========================================================================*/\r
-/* RETURN: TRUE, FALSE. */\r
-/*===========================================================================*/\r
-static void DestroyContext( D3DMESACONTEXT *pContext )\r
-{\r
- D3DMESACONTEXT *pTmp;\r
-\r
- /* Walk the list until we find the context before this one. */\r
- for( pTmp = pD3DDefault; pTmp && (pTmp->next != pContext); pTmp = pTmp->next )\r
- if ( pTmp == pTmp->next )\r
- break;\r
-\r
- /* If we never found it it must already be deleted. */\r
- if ( pTmp->next != pContext )\r
- return;\r
-\r
- /* Make sure we are not using this context. */\r
- if ( pContext == pD3DCurrent )\r
- MakeCurrent( pD3DDefault );\r
-\r
- /* Free the Mesa stuff. */\r
- if ( pContext->gl_visual ) \r
- {\r
- _mesa_destroy_visual( pContext->gl_visual );\r
- pContext->gl_visual = NULL;\r
- }\r
- if ( pContext->gl_buffer ) \r
- {\r
- _mesa_destroy_framebuffer( pContext->gl_buffer );\r
- pContext->gl_buffer = NULL;\r
- }\r
- if ( pContext->gl_ctx ) \r
- {\r
- _mesa_destroy_context( pContext->gl_ctx );\r
- pContext->gl_ctx = NULL;\r
- }\r
-\r
- /* Now dump the D3D. */\r
- if ( pContext->pShared )\r
- TermHAL( pContext->pShared );\r
-\r
- /* Update the previous context's link. */\r
- pTmp->next = pContext->next;\r
-\r
- /* Gonzo. */\r
- FREE( pContext );\r
-}\r
-/*===========================================================================*/\r
-/* This function will pull the supplied context away from Win32. Basicly it*/\r
-/* will remove the hook from the window Proc. */\r
-/* */\r
-/* TODO: might want to serialize this stuff... */\r
-/*===========================================================================*/\r
-/* RETURN: TRUE, FALSE. */\r
-/*===========================================================================*/\r
-static BOOL UnBindWindow( D3DMESACONTEXT *pContext )\r
-{\r
- if ( pContext == NULL )\r
- return FALSE;\r
-\r
- if ( pContext == pD3DDefault )\r
- return TRUE;\r
-\r
- /* Make sure we always have a context bound. */\r
- if ( pContext == pD3DCurrent )\r
- pD3DCurrent = pD3DDefault;\r
-\r
- SetWindowLong( pContext->pShared->hwnd, GWL_WNDPROC, (LONG)pContext->hOldProc );\r
- pContext->hOldProc = NULL;\r
-\r
- return TRUE;\r
-}\r
-/*===========================================================================*/\r
-/* There are two cases that allow for a faster clear when we know that the */\r
-/* whole buffer is cleared and that there is no clipping. */\r
-/*===========================================================================*/\r
-/* RETURN: the original mask with the bits cleared that represents the buffer*\r
-/* or buffers we just cleared. */\r
-/*===========================================================================*/\r
-GLbitfield ClearBuffersD3D( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height )\r
-{\r
- D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
- DWORD dwFlags = 0;\r
-\r
- if ( mask & GL_COLOR_BUFFER_BIT )\r
- {\r
- dwFlags |= D3DCLEAR_TARGET;\r
- mask &= ~GL_COLOR_BUFFER_BIT;\r
- }\r
- if ( mask & GL_DEPTH_BUFFER_BIT )\r
- {\r
- dwFlags |= D3DCLEAR_ZBUFFER;\r
- mask &= ~GL_DEPTH_BUFFER_BIT;\r
- }\r
- if ( dwFlags == 0 )\r
- return mask;\r
-\r
- ClearHAL( pContext->pShared, \r
- dwFlags, \r
- all, \r
- x, y, \r
- width, height, \r
- ((pContext->aClear<<24) | (pContext->rClear<<16) | (pContext->gClear<<8) | (pContext->bClear)), \r
- ctx->Depth.Clear, \r
- 0 );\r
-\r
- return mask;\r
-}\r
-\r
-\r
-\r
-/*===========================================================================*/\r
-/* TEXTURE MANAGER: ok here is how I did textures. Mesa-3.0 will keep track*/\r
-/* of all the textures for us. So this means that at anytime we can go to */\r
-/* the Mesa context and get the current texture. With this in mind this is */\r
-/* what I did. I really don't care about what textures get or are loaded */\r
-/* until I actually have to draw a tri that is textured. At this point I */\r
-/* must have the texture so I demand the texture by destorying all other */\r
-/* texture surfaces if need be and load the current one. This allows for the*/\r
-/* best preformance on low memory cards as time is not wasted loading and */\r
-/* unload textures. */\r
-/*===========================================================================*/\r
-\r
-\r
-\r
-\r
-\r
-/*===========================================================================*/\r
-/* TextureLoad will try and create a D3D surface from the supplied texture */\r
-/* object if its level 0 (first). The surface will be fully filled with the */\r
-/* texture. */\r
-/*===========================================================================*/\r
-/* RETURN: */\r
-/*===========================================================================*/\r
-static void TextureLoad( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint internalFormat, const struct gl_texture_image *image )\r
-{\r
- D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
-\r
- /* TODO: only doing first LOD. */\r
- if ( (ctx->DriverCtx == NULL) || (level != 0) )\r
- return;\r
-\r
- CreateTMgrHAL( pContext->pShared, \r
- tObj->Name, \r
- level,\r
- tObj->Image[level]->Format,\r
- (RECT *)NULL,\r
- tObj->Image[level]->Width, \r
- tObj->Image[level]->Height,\r
- TM_ACTION_LOAD,\r
- (void *)tObj->Image[level]->Data );\r
-}\r
-/*===========================================================================*/\r
-/* TextureBind make sure that the texture is on the card. Thats it. */\r
-/*===========================================================================*/\r
-/* RETURN: */\r
-/*===========================================================================*/\r
-static void TextureBind( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj )\r
-{\r
- D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
-\r
- /* TODO: only doing first LOD. */\r
- if ( (tObj->Image[0] == NULL) || (ctx->DriverCtx == NULL) )\r
- return;\r
-\r
- CreateTMgrHAL( pContext->pShared, \r
- tObj->Name, \r
- 0,\r
- tObj->Image[0]->Format,\r
- (RECT *)NULL,\r
- tObj->Image[0]->Width, \r
- tObj->Image[0]->Height,\r
- TM_ACTION_BIND,\r
- (void *)tObj->Image[0]->Data );\r
-}\r
-/*===========================================================================*/\r
-/* TextureSubImage will make sure that the texture being updated is updated */\r
-/* if its on the card. */\r
-/*===========================================================================*/\r
-/* RETURN: */\r
-/*===========================================================================*/\r
-static void TextureSubImage( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLint internalFormat, const struct gl_texture_image *image )\r
-{\r
- D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
- RECT rect;\r
-\r
- /* TODO: only doing first LOD. */\r
- if ( (ctx->DriverCtx == NULL) || (level > 0) )\r
- return;\r
-\r
- /* Create a dirty rectangle structure. */\r
- rect.left = xoffset;\r
- rect.right = xoffset + width;\r
- rect.top = yoffset;\r
- rect.bottom = yoffset + height;\r
- \r
- CreateTMgrHAL( pContext->pShared, \r
- tObj->Name, \r
- 0,\r
- tObj->Image[0]->Format, \r
- &rect,\r
- tObj->Image[0]->Width, \r
- tObj->Image[0]->Height,\r
- TM_ACTION_UPDATE,\r
- (void *)tObj->Image[0]->Data );\r
-}\r
-\r
+/*===========================================================================*/
+/* */
+/* Mesa-3.0 Makefile for DirectX 6 */
+/* */
+/* By Leigh McRae */
+/* */
+/* http://www.altsoftware.com/ */
+/* */
+/* Copyright (c) 1998-1997 alt.software inc. All Rights Reserved */
+/*===========================================================================*/
+#include "D3DMesa.h"
+/*===========================================================================*/
+/* Window managment. */
+/*===========================================================================*/
+static BOOL InitOpenGL( HINSTANCE hInst );
+static BOOL TermOpenGL( HINSTANCE hInst );
+static BOOL ResizeContext( GLcontext *ctx );
+static BOOL MakeCurrent( D3DMESACONTEXT *pContext );
+static void DestroyContext( D3DMESACONTEXT *pContext );
+static BOOL UnBindWindow( D3DMESACONTEXT *pContext );
+LONG APIENTRY wglMonitorProc( HWND hwnd, UINT message, UINT wParam, LONG lParam );
+/*===========================================================================*/
+/* Mesa hooks. */
+/*===========================================================================*/
+static void SetupDDPointers( GLcontext *ctx );
+static void SetupSWDDPointers( GLcontext *ctx );
+static void SetupHWDDPointers( GLcontext *ctx );
+static void SetupNULLDDPointers( GLcontext *ctx );
+static const char *RendererString( void );
+
+/* State Management hooks. */
+static void SetColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a );
+static void ClearColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a );
+static GLboolean SetBuffer( GLcontext *ctx, GLenum buffer );
+
+/* Window Management hooks. */
+static void GetBufferSize( GLcontext *ctx, GLuint *width, GLuint *height );
+static void SetViewport( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h );
+static void Flush( GLcontext *ctx );
+
+/* Span rendering hooks. */
+void WSpanRGB( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte rgb[][3], const GLubyte mask[] );
+void WSpanRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte rgba[][4], const GLubyte mask[] );
+void WSpanRGBAMono( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte mask[] );
+void WPixelsRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte rgba[][4], const GLubyte mask[] );
+void WPixelsRGBAMono( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte mask[] );
+void RSpanRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, GLubyte rgba[][4] );
+void RPixelsRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], GLubyte rgba[][4], const GLubyte mask[] );
+GLbitfield ClearBuffers( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height );
+
+/* Primitve rendering hooks. */
+GLboolean RenderVertexBuffer( GLcontext *ctx, GLboolean allDone );
+void RenderOneTriangle( GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint pv );
+void RenderOneLine( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv );
+GLbitfield ClearBuffersD3D( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height );
+
+/* Texture Management hooks. */
+static void TextureBind( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj );
+static void TextureLoad( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint internalFormat, const struct gl_texture_image *image );
+static void TextureSubImage( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLint internalFormat, const struct gl_texture_image *image );
+/*===========================================================================*/
+/* Global variables. */
+/*===========================================================================*/
+D3DMESACONTEXT *pD3DCurrent,
+ *pD3DDefault; /* Thin support context. */
+
+struct __extensions__ ext[] = {
+
+ { (PROC)glPolygonOffsetEXT, "glPolygonOffsetEXT" },
+ { (PROC)glBlendEquationEXT, "glBlendEquationEXT" },
+ { (PROC)glBlendColorEXT, "glBlendColorExt" },
+ { (PROC)glVertexPointerEXT, "glVertexPointerEXT" },
+ { (PROC)glNormalPointerEXT, "glNormalPointerEXT" },
+ { (PROC)glColorPointerEXT, "glColorPointerEXT" },
+ { (PROC)glIndexPointerEXT, "glIndexPointerEXT" },
+ { (PROC)glTexCoordPointerEXT, "glTexCoordPointer" },
+ { (PROC)glEdgeFlagPointerEXT, "glEdgeFlagPointerEXT" },
+ { (PROC)glGetPointervEXT, "glGetPointervEXT" },
+ { (PROC)glArrayElementEXT, "glArrayElementEXT" },
+ { (PROC)glDrawArraysEXT, "glDrawArrayEXT" },
+ { (PROC)glAreTexturesResidentEXT, "glAreTexturesResidentEXT" },
+ { (PROC)glBindTextureEXT, "glBindTextureEXT" },
+ { (PROC)glDeleteTexturesEXT, "glDeleteTexturesEXT" },
+ { (PROC)glGenTexturesEXT, "glGenTexturesEXT" },
+ { (PROC)glIsTextureEXT, "glIsTextureEXT" },
+ { (PROC)glPrioritizeTexturesEXT, "glPrioritizeTexturesEXT" },
+ { (PROC)glCopyTexSubImage3DEXT, "glCopyTexSubImage3DEXT" },
+ { (PROC)glTexImage3DEXT, "glTexImage3DEXT" },
+ { (PROC)glTexSubImage3DEXT, "glTexSubImage3DEXT" },
+};
+
+int qt_ext = sizeof(ext) / sizeof(ext[0]);
+float g_DepthScale,
+ g_MaxDepth;
+/*===========================================================================*/
+/* When a process loads this DLL we will setup the linked list for context */
+/* management and create a default context that will support the API until */
+/* the user creates and binds thier own. This THIN default context is useful*/
+/* to have around. */
+/* When the process terminates we will clean up all resources here. */
+/*===========================================================================*/
+/* RETURN: TRUE, FALSE. */
+/*===========================================================================*/
+BOOL APIENTRY DllMain( HINSTANCE hInst, DWORD reason, LPVOID reserved )
+{
+ switch( reason )
+ {
+ case DLL_PROCESS_ATTACH:
+ return InitOpenGL( hInst );
+
+ case DLL_PROCESS_DETACH:
+ return TermOpenGL( hInst );
+ }
+
+ return TRUE;
+}
+/*===========================================================================*/
+/* The first thing we do when this dll is hit is connect to the dll that has*/
+/* handles all the DirectX 6 rendering. I decided to use another dll as DX6 */
+/* is all C++ and Mesa-3.0 is C (thats a good thing). This way I can write */
+/* the DX6 in C++ and Mesa-3.0 in C without having to worry about linkage. */
+/* I feel this is easy and better then using static wrappers as it is likely */
+/* faster and it allows me to just develope the one without compiling the */
+/* other. */
+/* NOTE that at this point we don't have much other than a very thin context*/
+/* that will support the API calls only to the point of not causing the app */
+/* to crash from the API table being empty. */
+/*===========================================================================*/
+/* RETURN: TRUE, FALSE. */
+/*===========================================================================*/
+static BOOL InitOpenGL( HINSTANCE hInst )
+{
+ /* Allocate and clear the default context. */
+ pD3DDefault = (PD3DMESACONTEXT)ALLOC( sizeof(D3DMESACONTEXT) );
+ if ( pD3DDefault == NULL )
+ return FALSE;
+ memset( pD3DDefault, 0, sizeof(D3DMESACONTEXT) );
+
+ /* Clear the D3D vertex buffer so that values not used will be zero. This */
+ /* save me from some redundant work. */
+ memset( &D3DTLVertices, 0, sizeof(D3DTLVertices) );
+
+ /* Update the link. We uses a circular list so that it is easy to */
+ /* add and search. This context will also be used for head and tail.*/
+ pD3DDefault->next = pD3DDefault;
+
+ /*========================================================================*/
+ /* Do all core Mesa stuff. */
+ /*========================================================================*/
+ pD3DDefault->gl_visual = _mesa_create_visual( TRUE,
+ FALSE, /* db_flag */
+ GL_FALSE, /* stereo */
+ 8,8,8,8, /* r, g, b, a bits */
+ 0, /* index bits */
+ 16, /* depth_bits */
+ 8, /* stencil_bits */
+ 8,8,8,8, /* accum_bits */
+ 1 );
+
+ if ( pD3DDefault->gl_visual == NULL)
+ {
+ FREE( pD3DDefault );
+ return FALSE;
+ }
+
+ /* Allocate a new Mesa context */
+ pD3DDefault->gl_ctx = _mesa_create_context( pD3DDefault->gl_visual, NULL, pD3DDefault, GL_TRUE );
+ if ( pD3DDefault->gl_ctx == NULL )
+ {
+ _mesa_destroy_visual( pD3DDefault->gl_visual );
+ FREE( pD3DDefault );
+ return FALSE;
+ }
+
+ /* Allocate a new Mesa frame buffer */
+ pD3DDefault->gl_buffer = _mesa_create_framebuffer( pD3DDefault->gl_visual );
+ if ( pD3DDefault->gl_buffer == NULL )
+ {
+ _mesa_destroy_visual( pD3DDefault->gl_visual );
+ _mesa_destroy_context( pD3DDefault->gl_ctx );
+ FREE( pD3DDefault );
+ return FALSE;
+ }
+ SetupDDPointers( pD3DDefault->gl_ctx );
+ _mesa_make_current( pD3DDefault->gl_ctx, pD3DDefault->gl_buffer );
+
+ return TRUE;
+}
+/*===========================================================================*/
+/* This function will create a new D3D context but will not create the D3D */
+/* surfaces or even an instance of D3D (see at GetBufferSize). The only stuff*/
+/* done here is the internal Mesa stuff and some Win32 handles. */
+/*===========================================================================*/
+/* RETURN: casted pointer to the context, NULL. */
+/*===========================================================================*/
+HGLRC APIENTRY wglCreateContext( HDC hdc )
+{
+ D3DMESACONTEXT *pNewContext;
+ DWORD dwCoopFlags = DDSCL_NORMAL;
+ RECT rectClient;
+ POINT pt;
+
+ /* ALLOC and clear the new context. */
+ pNewContext = (PD3DMESACONTEXT)ALLOC( sizeof(D3DMESACONTEXT) );
+ if ( pNewContext == NULL )
+ {
+ SetLastError( 0 );
+ return (HGLRC)NULL;
+ }
+ memset( pNewContext, 0, sizeof(D3DMESACONTEXT) );
+
+ /*========================================================================*/
+ /* Do all core Mesa stuff. */
+ /*========================================================================*/
+
+ /* TODO: support more then one visual. */
+ pNewContext->gl_visual = _mesa_create_visual( TRUE,
+ TRUE, /* db_flag */
+ GL_FALSE, /* stereo */
+ 8,8,8,8, /* r, g, b, a bits */
+ 0, /* index bits */
+ 16, /* depth_bits */
+ 8, /* stencil_bits */
+ 16,16,16,16,/* accum_bits */
+ 1 );
+ if ( pNewContext->gl_visual == NULL)
+ {
+ FREE( pNewContext );
+ SetLastError( 0 );
+ return (HGLRC)NULL;
+ }
+
+ /* Allocate a new Mesa context */
+ pNewContext->gl_ctx = _mesa_create_context( pNewContext->gl_visual, NULL, pNewContext, GL_TRUE );
+ if ( pNewContext->gl_ctx == NULL )
+ {
+ _mesa_destroy_visual( pNewContext->gl_visual );
+ FREE( pNewContext );
+ SetLastError( 0 );
+ return (HGLRC)NULL;
+ }
+
+ /* Allocate a new Mesa frame buffer */
+ pNewContext->gl_buffer = _mesa_create_framebuffer( pNewContext->gl_visual );
+ if ( pNewContext->gl_buffer == NULL )
+ {
+ _mesa_destroy_visual( pNewContext->gl_visual );
+ _mesa_destroy_context( pNewContext->gl_ctx );
+ FREE( pNewContext );
+ SetLastError( 0 );
+ return (HGLRC)NULL;
+ }
+
+ /*========================================================================*/
+ /* Do all the driver stuff. */
+ /*========================================================================*/
+ pNewContext->hdc = hdc;
+ pNewContext->next = pD3DDefault->next;
+ pD3DDefault->next = pNewContext; /* Add to circular list. */
+
+ /* Create the HAL for the new context. */
+ pNewContext->pShared = InitHAL( WindowFromDC(hdc) );
+
+ return (HGLRC)pNewContext;
+}
+/*===========================================================================*/
+/* This is a wrapper function that is supported by MakeCurrent. */
+/*===========================================================================*/
+/* RETURN: TRUE, FALSE. */
+/*===========================================================================*/
+BOOL APIENTRY wglMakeCurrent( HDC hdc, HGLRC hglrc )
+{
+ return MakeCurrent((D3DMESACONTEXT *)hglrc);
+}
+/*===========================================================================*/
+/* MakeCurrent will unbind whatever context is current (if any) & then bind */
+/* the supplied context. A context that is bound has it's window proc hooked*/
+/* with the wglMonitorProc and the context pointer is saved in pD3DCurrent. */
+/* Once the context is bound we update the Mesa-3.0 hooks (SetDDPointers) and*/
+/* the viewport (Mesa-.30 and DX6). */
+/* */
+/* TODO: this function can't fail. */
+/*===========================================================================*/
+/* RETURN: TRUE */
+/*===========================================================================*/
+static BOOL MakeCurrent( D3DMESACONTEXT *pContext )
+{
+ D3DMESACONTEXT *pNext;
+
+ /*====================================================================*/
+ /* This is a special case that is a request to have no context bound. */
+ /*====================================================================*/
+ if ( pContext == NULL )
+ {
+ /* Walk the whole list. We start and end at the Default context. */
+ for( pNext = pD3DDefault->next; pNext != pD3DDefault; pNext = pNext->next )
+ UnBindWindow( pNext );
+
+ return TRUE;
+ }
+
+ /*=================================================*/
+ /* Make for a fast redundant use of this function. */
+ /*=================================================*/
+ if ( pD3DCurrent == pContext )
+ return TRUE;
+
+ /*=============================*/
+ /* Unbind the current context. */
+ /*=============================*/
+ UnBindWindow( pD3DCurrent );
+
+ /*=====================================*/
+ /* Let Mesa-3.0 we have a new context. */
+ /*=====================================*/
+ SetupDDPointers( pContext->gl_ctx );
+ _mesa_make_current( pContext->gl_ctx, pContext->gl_buffer );
+
+ /* We are done so set the internal current context. */
+ if ( pContext != pD3DDefault )
+ {
+ ResizeContext( pContext->gl_ctx );
+ pContext->hOldProc = (WNDPROC)GetWindowLong( pContext->pShared->hwnd, GWL_WNDPROC );
+ SetWindowLong( pContext->pShared->hwnd, GWL_WNDPROC, (LONG)wglMonitorProc );
+ }
+ pD3DCurrent = pContext;
+
+ return TRUE;
+}
+/*===========================================================================*/
+/* This function will only return the current window size. I have re-done */
+/* this function so that it doesn't check the current size and react to it as*/
+/* I should be able to have all the react code in the WM_SIZE message. The */
+/* old version would check the current window size and create/resize the HAL */
+/* surfaces if they have changed. I needed to delay the creation if the */
+/* surfaces because sometimes I wouldn't have a window size so this is where */
+/* I delayed it. If you are reading this then all went ok! */
+/* The default context will return a zero sized window and I'm not sure if */
+/* this is ok at this point (TODO). */
+/*===========================================================================*/
+/* RETURN: */
+/*===========================================================================*/
+static void GetBufferSize( GLcontext *ctx, GLuint *width, GLuint *height )
+{
+ D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+
+ /* Fall through for the default because that is one of the uses for it. */
+ if ( pContext == pD3DDefault )
+ {
+ *width = 0;
+ *height = 0;
+ }
+ else
+ {
+ *width = pContext->pShared->dwWidth;
+ *height = pContext->pShared->dwHeight;
+ }
+}
+/*===========================================================================*/
+/* */
+/* */
+/*===========================================================================*/
+/* RETURN: */
+/*===========================================================================*/
+static BOOL ResizeContext( GLcontext *ctx )
+{
+ D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx,
+ *pCurrentTemp;
+ RECT rectClient;
+ POINT pt;
+ DWORD dwWidth,
+ dwHeight;
+ static BOOL bDDrawLock = FALSE;
+
+ /* Make sure we have some values. */
+ if ( (pContext->hdc == NULL ) ||
+ (pContext->pShared->hwnd != WindowFromDC(pContext->hdc)) ||
+ (pContext == pD3DDefault) )
+ return FALSE;
+
+ /* Having problems with DDraw sending resize messages before I was done. */
+ if( bDDrawLock == TRUE )
+ return FALSE;
+
+ // TODO: don't think I need this anymore.
+ pCurrentTemp = pD3DCurrent;
+ pD3DCurrent = pD3DDefault;
+ bDDrawLock = TRUE;
+
+ /* Get the current window dimentions. */
+ UpdateScreenPosHAL( pContext->pShared );
+ dwWidth = pContext->pShared->rectW.right - pContext->pShared->rectW.left;
+ dwHeight = pContext->pShared->rectW.bottom - pContext->pShared->rectW.top;
+
+ /* Is the size of the OffScreen Render different? */
+ if ( (dwWidth != pContext->pShared->dwWidth) || (dwHeight != pContext->pShared->dwHeight) )
+ {
+ /* Create all the D3D surfaces and device. */
+ CreateHAL( pContext->pShared );
+
+ /* I did this so that software rendering would still work as */
+ /* I don't need to scale the z values twice. */
+ g_DepthScale = (pContext->pShared->bHardware) ? 1.0 : ((float)0x00FFFFFF);
+ g_MaxDepth = (pContext->pShared->bHardware) ? 1.0 : ((float)0x00FFFFFF);
+ gl_DepthRange( pContext->gl_ctx, ctx->Viewport.Near, ctx->Viewport.Far );
+
+ /* Make sure we have a viewport. */
+ gl_Viewport( pContext->gl_ctx, 0, 0, dwWidth, dwHeight );
+
+ /* Update Mesa as we might have changed from SW <-> HW. */
+ SetupDDPointers( pContext->gl_ctx );
+ _mesa_make_current( pContext->gl_ctx, pContext->gl_buffer );
+
+ /* If we are in HW we need to load the current texture if there is one already. */
+ // if ( (ctx->Texture.Set[ctx->Texture.CurrentSet].Current != NULL) &&
+ // (pContext->pShared->bHardware == TRUE) )
+ // {
+ // CreateTMgrHAL( pContext->pShared,
+ // ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Name,
+ // 0,
+ // ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Format,
+ // (RECT *)NULL,
+ // ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Width,
+ // ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Height,
+ // TM_ACTION_BIND,
+ // (void *)ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Data );
+ // }
+ }
+
+ // TODO: don't think I need this anymore.
+ pD3DCurrent = pCurrentTemp;
+ bDDrawLock = FALSE;
+
+ return TRUE;
+}
+
+/*===========================================================================*
+/* This function will Blt the render buffer to the PRIMARY surface. I repeat*/
+/* this code for the other SwapBuffer like functions and the flush (didn't */
+/* want the function calling overhead). Thsi could have been a macro... */
+/* */
+/* TODO: there are some problems with viewport/scissoring. */
+/*===========================================================================*/
+/* RETURN: TRUE, FALSE. */
+/*===========================================================================*/
+BOOL APIENTRY wglSwapBuffers( HDC hdc )
+{
+ /* Fall through for the default because that is one of the uses for it. */
+ if ( pD3DCurrent == pD3DDefault )
+ return FALSE;
+
+ SwapBuffersHAL( pD3DCurrent->pShared );
+
+ return TRUE;
+}
+/*===========================================================================*/
+/* Same as wglSwapBuffers. */
+/*===========================================================================*/
+/* RETURN: TRUE, FALSE. */
+/*===========================================================================*/
+BOOL APIENTRY SwapBuffers( HDC hdc )
+{
+ /* Fall through for the default because that is one of the uses for it. */
+ if ( pD3DCurrent == pD3DDefault )
+ return FALSE;
+
+ SwapBuffersHAL( pD3DCurrent->pShared );
+
+ return TRUE;
+}
+/*===========================================================================*/
+/* This should be ok as none of the SwapBuffers will cause a redundant Blt */
+/* as none of my Swap functions will call flush. This should also allow */
+/* sinlge buffered applications to work (not really worried though). Some */
+/* applications may flush then swap but then this is there fault IMHO. */
+/*===========================================================================*/
+/* RETURN: */
+/*===========================================================================*/
+static void Flush( GLcontext *ctx )
+{
+ /* Fall through for the default because that is one of the uses for it. */
+ if ( pD3DCurrent == pD3DDefault )
+ return;
+
+ SwapBuffersHAL( pD3DCurrent->pShared );
+}
+/*===========================================================================*/
+/* For now this function will ignore the supplied PF. If I'm going to allow */
+/* the user to choice the mode and device at startup I'm going to have to do */
+/* something different. */
+/* */
+/* TODO: use the linked list of modes to build a pixel format to be returned */
+/* to the caller. */
+/*===========================================================================*/
+/* RETURN: 1. */
+/*===========================================================================*/
+int APIENTRY wglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *ppfd )
+{
+ return 1;
+}
+/*===========================================================================*/
+/* See wglChoosePixelFormat. */
+/*===========================================================================*/
+/* RETURN: 1. */
+/*===========================================================================*/
+int APIENTRY ChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *ppfd )
+{
+ return wglChoosePixelFormat(hdc,ppfd);
+}
+/*===========================================================================*/
+/* This function (for now) returns a static PF everytime. This is just to */
+/* allow things to continue. */
+/*===========================================================================*/
+/* RETURN: 1. */
+/*===========================================================================*/
+int APIENTRY wglDescribePixelFormat( HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd )
+{
+ static PIXELFORMATDESCRIPTOR pfd =
+ {
+ sizeof(PIXELFORMATDESCRIPTOR), /* size */
+ 1, /* version */
+ PFD_SUPPORT_OPENGL |
+ PFD_DRAW_TO_WINDOW |
+ PFD_DOUBLEBUFFER, /* support double-buffering */
+ PFD_TYPE_RGBA, /* color type */
+ 16, /* prefered color depth */
+ 0, 0, 0, 0, 0, 0, /* color bits (ignored) */
+ 0, /* no alpha buffer */
+ 0, /* alpha bits (ignored) */
+ 0, /* no accumulation buffer */
+ 0, 0, 0, 0, /* accum bits (ignored) */
+ 16, /* depth buffer */
+ 0, /* no stencil buffer */
+ 0, /* no auxiliary buffers */
+ PFD_MAIN_PLANE, /* main layer */
+ 0, /* reserved */
+ 0, 0, 0, /* no layer, visible, damage masks */
+ };
+
+ /* Return the address of this static PF if one was requested. */
+ if ( ppfd != NULL )
+ memcpy( ppfd, &pfd, sizeof(PIXELFORMATDESCRIPTOR) );
+
+ return 1;
+}
+/*===========================================================================*/
+/* See wglDescribePixelFormat. */
+/*===========================================================================*/
+/* RETURN: 1. */
+/*===========================================================================*/
+int APIENTRY DescribePixelFormat( HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd )
+{
+ return wglDescribePixelFormat(hdc,iPixelFormat,nBytes,ppfd);
+}
+/*===========================================================================*/
+/* This function will always return 1 for now. Just to allow for support. */
+/*===========================================================================*/
+/* RETURN: 1. */
+/*===========================================================================*/
+int APIENTRY wglGetPixelFormat( HDC hdc )
+{
+ return 1;
+}
+/*===========================================================================*/
+/* See wglGetPixelFormat. */
+/*===========================================================================*/
+/* RETURN: 1. */
+/*===========================================================================*/
+int APIENTRY GetPixelFormat( HDC hdc )
+{
+ return wglGetPixelFormat(hdc);
+}
+/*===========================================================================*/
+/* This will aways work for now. */
+/*===========================================================================*/
+/* RETURN: TRUE. */
+/*===========================================================================*/
+BOOL APIENTRY wglSetPixelFormat( HDC hdc, int iPixelFormat, CONST PIXELFORMATDESCRIPTOR *ppfd )
+{
+ return TRUE;
+}
+/*===========================================================================*/
+/* See wglSetPixelFormat. */
+/*===========================================================================*/
+/* RETURN: TRUE, FALSE. */
+/*===========================================================================*/
+BOOL APIENTRY SetPixelFormat( HDC hdc, int iPixelFormat, CONST PIXELFORMATDESCRIPTOR *ppfd )
+{
+ return wglSetPixelFormat(hdc,iPixelFormat,ppfd);
+}
+/*===========================================================================*/
+/* This is a wrapper function that is supported by my own internal function.*/
+/* that takes my own D3D Mesa context structure. This so I can reuse the */
+/* function (no need for speed). */
+/*===========================================================================*/
+/* RETURN: TRUE. */
+/*===========================================================================*/
+BOOL APIENTRY wglDeleteContext( HGLRC hglrc )
+{
+ DestroyContext( (D3DMESACONTEXT *)hglrc );
+
+ return TRUE;
+}
+/*===========================================================================*/
+/* Simple getter function that uses a cast. */
+/*===========================================================================*/
+/* RETURN: casted pointer to the context, NULL. */
+/*===========================================================================*/
+HGLRC APIENTRY wglGetCurrentContext( VOID )
+{
+ return (pD3DCurrent) ? (HGLRC)pD3DCurrent : (HGLRC)NULL;
+}
+/*===========================================================================*/
+/* No support. */
+/*===========================================================================*/
+/* RETURN: FALSE. */
+/*===========================================================================*/
+BOOL APIENTRY wglCopyContext( HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask )
+{
+ SetLastError( 0 );
+ return FALSE;
+}
+/*===========================================================================*/
+/* No support. */
+/*===========================================================================*/
+/* RETURN: NULL. */
+/*===========================================================================*/
+HGLRC APIENTRY wglCreateLayerContext( HDC hdc,int iLayerPlane )
+{
+ SetLastError( 0 );
+ return (HGLRC)NULL;
+}
+/*===========================================================================*/
+/* Simple getter function. */
+/*===========================================================================*/
+/* RETURN: FALSE. */
+/*===========================================================================*/
+HDC APIENTRY wglGetCurrentDC( VOID )
+{
+ return (pD3DCurrent) ? pD3DCurrent->hdc : (HDC)NULL;
+}
+/*===========================================================================*/
+/* Simply call that searches the supported extensions for a match & returns */
+/* the pointer to the function that lends support. */
+/*===========================================================================*/
+/* RETURN: pointer to API call, NULL. */
+/*===========================================================================*/
+PROC APIENTRY wglGetProcAddress( LPCSTR lpszProc )
+{
+ int index;
+
+ for( index = 0; index < qt_ext; index++ )
+ if( !strcmp(lpszProc,ext[index].name) )
+ return ext[index].proc;
+
+ SetLastError( 0 );
+ return NULL;
+}
+/*===========================================================================*/
+/* No support. */
+/*===========================================================================*/
+/* RETURN: FALSE. */
+/*===========================================================================*/
+BOOL APIENTRY wglShareLists( HGLRC hglrc1, HGLRC hglrc2 )
+{
+ SetLastError( 0 );
+ return FALSE;
+}
+/*===========================================================================*/
+/* No support. */
+/*===========================================================================*/
+/* RETURN: FALSE. */
+/*===========================================================================*/
+BOOL APIENTRY wglUseFontBitmaps( HDC fontDevice, DWORD firstChar, DWORD numChars, DWORD listBase )
+{
+ SetLastError( 0 );
+ return FALSE;
+}
+/*===========================================================================*/
+/* No support. */
+/*===========================================================================*/
+/* RETURN: FALSE. */
+/*===========================================================================*/
+BOOL APIENTRY wglUseFontBitmapsW( HDC hdc,DWORD first,DWORD count,DWORD listBase )
+{
+ SetLastError( 0 );
+ return FALSE;
+}
+/*===========================================================================*/
+/* No support. */
+/*===========================================================================*/
+/* RETURN: FALSE. */
+/*===========================================================================*/
+BOOL APIENTRY wglUseFontOutlinesA( HDC hdc, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf )
+{
+ SetLastError( 0 );
+ return FALSE;
+}
+/*===========================================================================*/
+/* No support. */
+/*===========================================================================*/
+/* RETURN: FALSE. */
+/*===========================================================================*/
+BOOL APIENTRY wglUseFontOutlinesW( HDC hdc,DWORD first,DWORD count, DWORD listBase,FLOAT deviation, FLOAT extrusion,int format, LPGLYPHMETRICSFLOAT lpgmf )
+{
+ SetLastError( 0 );
+ return FALSE ;
+}
+/*===========================================================================*/
+/* No support. */
+/*===========================================================================*/
+/* RETURN: FALSE. */
+/*===========================================================================*/
+BOOL APIENTRY wglSwapLayerBuffers( HDC hdc, UINT fuPlanes )
+{
+ SetLastError( 0 );
+ return FALSE;
+}
+/*===========================================================================*/
+/* This function will be hooked into the window that has been bound. Right */
+/* now it is used to track the window size and position. Also the we clean */
+/* up the currrent context when the window is close/destroyed. */
+/* */
+/* TODO: there might be something wrong here as some games (Heretic II) don't*/
+/* track the window quit right. */
+/*===========================================================================*/
+/* RETURN: */
+/*===========================================================================*/
+LONG APIENTRY wglMonitorProc( HWND hwnd, UINT message, UINT wParam, LONG lParam )
+{
+ WNDPROC hOldProc;
+ GLint width,
+ height;
+
+ switch( message )
+ {
+// case WM_PAINT:
+// break;
+// case WM_ACTIVATE:
+// break;
+// case WM_SHOWWINDOW:
+// break;
+
+ case UM_FATALSHUTDOWN:
+ /* Support the API until we die... */
+ MakeCurrent( pD3DDefault );
+ break;
+
+ case WM_MOVE:
+ case WM_DISPLAYCHANGE:
+ case WM_SIZE:
+ ResizeContext( pD3DCurrent->gl_ctx );
+ break;
+
+ case WM_CLOSE:
+ case WM_DESTROY:
+ /* Support the API until we die... */
+ hOldProc = pD3DCurrent->hOldProc;
+ DestroyContext( pD3DCurrent );
+ return (hOldProc)(hwnd,message,wParam,lParam);
+ }
+
+ return (pD3DCurrent->hOldProc)(hwnd,message,wParam,lParam);
+}
+
+/**********************************************************************/
+/***** Miscellaneous device driver funcs *****/
+/**********************************************************************/
+
+/*===========================================================================*/
+/* Not reacting to this as I'm only supporting drawing to the back buffer */
+/* right now. */
+/*===========================================================================*/
+/* RETURN: TRUE. */
+/*===========================================================================*/
+static GLboolean SetBuffer( GLcontext *ctx, GLenum buffer )
+{
+ if (buffer == GL_BACK_LEFT)
+ return GL_TRUE;
+ else
+ return GL_FALSE;
+}
+/*===========================================================================*/
+/* This proc will be called by Mesa when the viewport has been set. So if */
+/* we have a context and it isn't the default then we should let D3D know of */
+/* the change. */
+/*===========================================================================*/
+/* RETURN: */
+/*===========================================================================*/
+static void SetViewport( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h )
+{
+ D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+ RECT rect;
+
+ /* Make sure we can set a viewport. */
+ if ( pContext->pShared && (pContext != pD3DDefault) )
+ {
+ // TODO: might be needed.
+ UpdateScreenPosHAL( pContext->pShared );
+ rect.left = x;
+ rect.right = x + w;
+ rect.top = y;
+ rect.bottom = y + h;
+
+ // TODO: shared struct should make this call smaller
+ SetViewportHAL( pContext->pShared, &rect, 0.0F, 1.0F );
+ }
+}
+/*===========================================================================*/
+/* This function could be better I guess but I decided just to grab the four*/
+/* components and store then seperately. Makes it easier to use IMHO. */
+/*===========================================================================*/
+/* RETURN: */
+/*===========================================================================*/
+static void ClearColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
+{
+ D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+
+ pContext->aClear = a;
+ pContext->bClear = b;
+ pContext->gClear = g;
+ pContext->rClear = r;
+}
+/*===========================================================================*/
+/* This function could be better I guess but I decided just to grab the four*/
+/* components and store then seperately. Makes it easier to use IMHO. */
+/* (is there an echo in here?) */
+/*===========================================================================*/
+/* RETURN: */
+/*===========================================================================*/
+static void SetColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
+{
+ D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+
+ pContext->aCurrent = a;
+ pContext->bCurrent = b;
+ pContext->gCurrent = g;
+ pContext->rCurrent = r;
+}
+/*===========================================================================*/
+/* */
+/* */
+/*===========================================================================*/
+/* RETURN: */
+/*===========================================================================*/
+static const char *RendererString( void )
+{
+ static char pszRender[64];
+
+ strcpy( pszRender, "altD3D " );
+
+ if ( pD3DCurrent->pShared->bHardware )
+ strcat( pszRender, "(HW)");
+ else
+ strcat( pszRender, "(SW)");
+
+ return (const char *)pszRender;
+}
+/*===========================================================================*/
+/* This function will choose which set of pointers Mesa will use based on */
+/* whether we hard using hardware or software. I have added another set of */
+/* pointers that will do nothing but stop the API from crashing. */
+/*===========================================================================*/
+/* RETURN: */
+/*===========================================================================*/
+static void SetupDDPointers( GLcontext *ctx )
+{
+ D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+
+ // TODO: write a generic NULL support for the span render.
+ if ( pContext->pShared && pContext->pShared->bHardware )
+ {
+ ctx->Driver.UpdateState = SetupHWDDPointers;
+ }
+ else if ( pContext == pD3DDefault )
+ {
+ ctx->Driver.UpdateState = SetupNULLDDPointers;
+ }
+ else
+ {
+ ctx->Driver.UpdateState = SetupSWDDPointers;
+ }
+}
+/*===========================================================================*/
+/* This function will populate all the Mesa driver hooks. This version of */
+/* hooks will do nothing but support the API when we don't have a valid */
+/* context bound. This is mostly for applications that don't behave right */
+/* and also to help exit as clean as possable when we have a FatalError. */
+/*===========================================================================*/
+/* RETURN: pointer to the specific function. */
+/*===========================================================================*/
+static void SetupNULLDDPointers( GLcontext *ctx )
+{
+ D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+
+ /* Initialize all the pointers in the DD struct. Do this whenever */
+ /* a new context is made current or we change buffers via set_buffer! */
+ ctx->Driver.UpdateState = SetupNULLDDPointers;
+
+ /* State management hooks. */
+ ctx->Driver.Color = NULLSetColor;
+ ctx->Driver.ClearColor = NULLClearColor;
+ ctx->Driver.Clear = NULLClearBuffers;
+ ctx->Driver.SetBuffer = NULLSetBuffer;
+
+ /* Window management hooks. */
+ ctx->Driver.GetBufferSize = NULLGetBufferSize;
+
+ /* Primitive rendering hooks. */
+ ctx->Driver.TriangleFunc = NULL;
+ ctx->Driver.RenderVB = NULL;
+
+ /* Pixel/span writing functions: */
+ ctx->Driver.WriteRGBASpan = NULLWrSpRGBA;
+ ctx->Driver.WriteRGBSpan = NULLWrSpRGB;
+ ctx->Driver.WriteMonoRGBASpan = NULLWrSpRGBAMono;
+ ctx->Driver.WriteRGBAPixels = NULLWrPiRGBA;
+ ctx->Driver.WriteMonoRGBAPixels = NULLWrPiRGBAMono;
+
+ /* Pixel/span reading functions: */
+ ctx->Driver.ReadRGBASpan = NULLReSpRGBA;
+ ctx->Driver.ReadRGBAPixels = NULLRePiRGBA;
+
+ /* Misc. hooks. */
+ ctx->Driver.RendererString = RendererString;
+}
+/*===========================================================================*/
+/* This function will populate all the Mesa driver hooks. There are two of */
+/* these functions. One if we have hardware support and one is there is only*/
+/* software. These functions will be called by Mesa and by the wgl.c when we*/
+/* have resized (or created) the buffers. The thing is that if a window gets*/
+/* resized we may loose hardware support or gain it... */
+/*===========================================================================*/
+/* RETURN: pointer to the specific function. */
+/*===========================================================================*/
+static void SetupSWDDPointers( GLcontext *ctx )
+{
+ D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+
+ /* Initialize all the pointers in the DD struct. Do this whenever */
+ /* a new context is made current or we change buffers via set_buffer! */
+ ctx->Driver.UpdateState = SetupSWDDPointers;
+
+ /* State management hooks. */
+ ctx->Driver.Color = SetColor;
+ ctx->Driver.ClearColor = ClearColor;
+ ctx->Driver.Clear = ClearBuffers;
+ ctx->Driver.SetBuffer = SetBuffer;
+
+ /* Window management hooks. */
+ ctx->Driver.GetBufferSize = GetBufferSize;
+ ctx->Driver.Viewport = SetViewport;
+
+ /* Primitive rendering hooks. */
+ ctx->Driver.TriangleFunc = NULL;
+ ctx->Driver.RenderVB = NULL;
+
+ /* Texture management hooks. */
+
+ /* Pixel/span writing functions: */
+ ctx->Driver.WriteRGBASpan = WSpanRGBA;
+ ctx->Driver.WriteRGBSpan = WSpanRGB;
+ ctx->Driver.WriteMonoRGBASpan = WSpanRGBAMono;
+ ctx->Driver.WriteRGBAPixels = WPixelsRGBA;
+ ctx->Driver.WriteMonoRGBAPixels = WPixelsRGBAMono;
+
+ /* Pixel/span reading functions: */
+ ctx->Driver.ReadRGBASpan = RSpanRGBA;
+ ctx->Driver.ReadRGBAPixels = RPixelsRGBA;
+
+ /* Misc. hooks. */
+ ctx->Driver.Flush = Flush;
+ ctx->Driver.RendererString = RendererString;
+}
+/*===========================================================================*/
+/* This function will populate all the Mesa driver hooks. There are two of */
+/* these functions. One if we have hardware support and one is there is only*/
+/* software. These functions will be called by Mesa and by the wgl.c when we*/
+/* have resized (or created) the buffers. The thing is that if a window gets*/
+/* resized we may loose hardware support or gain it... */
+/*===========================================================================*/
+/* RETURN: pointer to the specific function. */
+/*===========================================================================*/
+static void SetupHWDDPointers( GLcontext *ctx )
+{
+ D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+
+ /* Initialize all the pointers in the DD struct. Do this whenever */
+ /* a new context is made current or we change buffers via set_buffer! */
+ ctx->Driver.UpdateState = SetupHWDDPointers;
+
+ /* State management hooks. */
+ ctx->Driver.Color = SetColor;
+ ctx->Driver.ClearColor = ClearColor;
+ ctx->Driver.Clear = ClearBuffersD3D;
+ ctx->Driver.SetBuffer = SetBuffer;
+
+ /* Window management hooks. */
+ ctx->Driver.GetBufferSize = GetBufferSize;
+ ctx->Driver.Viewport = SetViewport;
+
+ /* Primitive rendering hooks. */
+ ctx->Driver.TriangleFunc = RenderOneTriangle;
+ ctx->Driver.LineFunc = RenderOneLine;
+ ctx->Driver.RenderVB = RenderVertexBuffer;
+
+ /* Pixel/span writing functions: */
+ ctx->Driver.WriteRGBASpan = WSpanRGBA;
+ ctx->Driver.WriteRGBSpan = WSpanRGB;
+ ctx->Driver.WriteMonoRGBASpan = WSpanRGBAMono;
+ ctx->Driver.WriteRGBAPixels = WPixelsRGBA;
+ ctx->Driver.WriteMonoRGBAPixels = WPixelsRGBAMono;
+
+ /* Pixel/span reading functions: */
+ ctx->Driver.ReadRGBASpan = RSpanRGBA;
+ ctx->Driver.ReadRGBAPixels = RPixelsRGBA;
+
+ /* Texture management hooks. */
+ // ctx->Driver.BindTexture = TextureBind;
+ ctx->Driver.TexImage = TextureLoad;
+ ctx->Driver.TexSubImage = TextureSubImage;
+
+ /* Misc. hooks. */
+ ctx->Driver.Flush = Flush;
+ ctx->Driver.RendererString = RendererString;
+}
+/*===========================================================================*/
+/* This function will release all resources used by the DLL. Every context */
+/* will be clobbered by releaseing all driver desources and then freeing the */
+/* context memory. Most all the work is done in DestroyContext. */
+/*===========================================================================*/
+/* RETURN: TRUE. */
+/*===========================================================================*/
+static BOOL TermOpenGL( HINSTANCE hInst )
+{
+ D3DMESACONTEXT *pTmp,
+ *pNext;
+
+ /* Just incase we are still getting paint msg. */
+ MakeCurrent( pD3DDefault );
+
+ /* Walk the list until we get back to the default context. */
+ for( pTmp = pD3DDefault->next; pTmp != pD3DDefault; pTmp = pNext )
+ {
+ pNext = pTmp->next;
+ DestroyContext( pTmp );
+ }
+ DestroyContext( pD3DDefault );
+
+ return TRUE;
+}
+/*===========================================================================*/
+/* This function is an internal function that will clean up all the Mesa */
+/* context bound to this D3D context. Also any D3D stuff that this context */
+/* uses will be unloaded. */
+/*===========================================================================*/
+/* RETURN: TRUE, FALSE. */
+/*===========================================================================*/
+static void DestroyContext( D3DMESACONTEXT *pContext )
+{
+ D3DMESACONTEXT *pTmp;
+
+ /* Walk the list until we find the context before this one. */
+ for( pTmp = pD3DDefault; pTmp && (pTmp->next != pContext); pTmp = pTmp->next )
+ if ( pTmp == pTmp->next )
+ break;
+
+ /* If we never found it it must already be deleted. */
+ if ( pTmp->next != pContext )
+ return;
+
+ /* Make sure we are not using this context. */
+ if ( pContext == pD3DCurrent )
+ MakeCurrent( pD3DDefault );
+
+ /* Free the Mesa stuff. */
+ if ( pContext->gl_visual )
+ {
+ _mesa_destroy_visual( pContext->gl_visual );
+ pContext->gl_visual = NULL;
+ }
+ if ( pContext->gl_buffer )
+ {
+ _mesa_destroy_framebuffer( pContext->gl_buffer );
+ pContext->gl_buffer = NULL;
+ }
+ if ( pContext->gl_ctx )
+ {
+ _mesa_destroy_context( pContext->gl_ctx );
+ pContext->gl_ctx = NULL;
+ }
+
+ /* Now dump the D3D. */
+ if ( pContext->pShared )
+ TermHAL( pContext->pShared );
+
+ /* Update the previous context's link. */
+ pTmp->next = pContext->next;
+
+ /* Gonzo. */
+ FREE( pContext );
+}
+/*===========================================================================*/
+/* This function will pull the supplied context away from Win32. Basicly it*/
+/* will remove the hook from the window Proc. */
+/* */
+/* TODO: might want to serialize this stuff... */
+/*===========================================================================*/
+/* RETURN: TRUE, FALSE. */
+/*===========================================================================*/
+static BOOL UnBindWindow( D3DMESACONTEXT *pContext )
+{
+ if ( pContext == NULL )
+ return FALSE;
+
+ if ( pContext == pD3DDefault )
+ return TRUE;
+
+ /* Make sure we always have a context bound. */
+ if ( pContext == pD3DCurrent )
+ pD3DCurrent = pD3DDefault;
+
+ SetWindowLong( pContext->pShared->hwnd, GWL_WNDPROC, (LONG)pContext->hOldProc );
+ pContext->hOldProc = NULL;
+
+ return TRUE;
+}
+/*===========================================================================*/
+/* There are two cases that allow for a faster clear when we know that the */
+/* whole buffer is cleared and that there is no clipping. */
+/*===========================================================================*/
+/* RETURN: the original mask with the bits cleared that represents the buffer*
+/* or buffers we just cleared. */
+/*===========================================================================*/
+GLbitfield ClearBuffersD3D( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height )
+{
+ D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+ DWORD dwFlags = 0;
+
+ if ( mask & GL_COLOR_BUFFER_BIT )
+ {
+ dwFlags |= D3DCLEAR_TARGET;
+ mask &= ~GL_COLOR_BUFFER_BIT;
+ }
+ if ( mask & GL_DEPTH_BUFFER_BIT )
+ {
+ dwFlags |= D3DCLEAR_ZBUFFER;
+ mask &= ~GL_DEPTH_BUFFER_BIT;
+ }
+ if ( dwFlags == 0 )
+ return mask;
+
+ ClearHAL( pContext->pShared,
+ dwFlags,
+ all,
+ x, y,
+ width, height,
+ ((pContext->aClear<<24) | (pContext->rClear<<16) | (pContext->gClear<<8) | (pContext->bClear)),
+ ctx->Depth.Clear,
+ 0 );
+
+ return mask;
+}
+
+
+
+/*===========================================================================*/
+/* TEXTURE MANAGER: ok here is how I did textures. Mesa-3.0 will keep track*/
+/* of all the textures for us. So this means that at anytime we can go to */
+/* the Mesa context and get the current texture. With this in mind this is */
+/* what I did. I really don't care about what textures get or are loaded */
+/* until I actually have to draw a tri that is textured. At this point I */
+/* must have the texture so I demand the texture by destorying all other */
+/* texture surfaces if need be and load the current one. This allows for the*/
+/* best preformance on low memory cards as time is not wasted loading and */
+/* unload textures. */
+/*===========================================================================*/
+
+
+
+
+
+/*===========================================================================*/
+/* TextureLoad will try and create a D3D surface from the supplied texture */
+/* object if its level 0 (first). The surface will be fully filled with the */
+/* texture. */
+/*===========================================================================*/
+/* RETURN: */
+/*===========================================================================*/
+static void TextureLoad( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint internalFormat, const struct gl_texture_image *image )
+{
+ D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+
+ /* TODO: only doing first LOD. */
+ if ( (ctx->DriverCtx == NULL) || (level != 0) )
+ return;
+
+ CreateTMgrHAL( pContext->pShared,
+ tObj->Name,
+ level,
+ tObj->Image[level]->Format,
+ (RECT *)NULL,
+ tObj->Image[level]->Width,
+ tObj->Image[level]->Height,
+ TM_ACTION_LOAD,
+ (void *)tObj->Image[level]->Data );
+}
+/*===========================================================================*/
+/* TextureBind make sure that the texture is on the card. Thats it. */
+/*===========================================================================*/
+/* RETURN: */
+/*===========================================================================*/
+static void TextureBind( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj )
+{
+ D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+
+ /* TODO: only doing first LOD. */
+ if ( (tObj->Image[0] == NULL) || (ctx->DriverCtx == NULL) )
+ return;
+
+ CreateTMgrHAL( pContext->pShared,
+ tObj->Name,
+ 0,
+ tObj->Image[0]->Format,
+ (RECT *)NULL,
+ tObj->Image[0]->Width,
+ tObj->Image[0]->Height,
+ TM_ACTION_BIND,
+ (void *)tObj->Image[0]->Data );
+}
+/*===========================================================================*/
+/* TextureSubImage will make sure that the texture being updated is updated */
+/* if its on the card. */
+/*===========================================================================*/
+/* RETURN: */
+/*===========================================================================*/
+static void TextureSubImage( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLint internalFormat, const struct gl_texture_image *image )
+{
+ D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+ RECT rect;
+
+ /* TODO: only doing first LOD. */
+ if ( (ctx->DriverCtx == NULL) || (level > 0) )
+ return;
+
+ /* Create a dirty rectangle structure. */
+ rect.left = xoffset;
+ rect.right = xoffset + width;
+ rect.top = yoffset;
+ rect.bottom = yoffset + height;
+
+ CreateTMgrHAL( pContext->pShared,
+ tObj->Name,
+ 0,
+ tObj->Image[0]->Format,
+ &rect,
+ tObj->Image[0]->Width,
+ tObj->Image[0]->Height,
+ TM_ACTION_UPDATE,
+ (void *)tObj->Image[0]->Data );
+}
+