1 /*===========================================================================*/
3 /* Mesa-3.0 Makefile for DirectX 6 */
7 /* http://www.altsoftware.com/ */
9 /* Copyright (c) 1998-1997 alt.software inc. All Rights Reserved */
10 /*===========================================================================*/
12 /*===========================================================================*/
13 /* Window managment. */
14 /*===========================================================================*/
15 static BOOL InitOpenGL( HINSTANCE hInst );
16 static BOOL TermOpenGL( HINSTANCE hInst );
17 static BOOL ResizeContext( GLcontext *ctx );
18 static BOOL MakeCurrent( D3DMESACONTEXT *pContext );
19 static void DestroyContext( D3DMESACONTEXT *pContext );
20 static BOOL UnBindWindow( D3DMESACONTEXT *pContext );
21 LONG APIENTRY wglMonitorProc( HWND hwnd, UINT message, UINT wParam, LONG lParam );
22 /*===========================================================================*/
24 /*===========================================================================*/
25 static void SetupDDPointers( GLcontext *ctx );
26 static void SetupSWDDPointers( GLcontext *ctx );
27 static void SetupHWDDPointers( GLcontext *ctx );
28 static void SetupNULLDDPointers( GLcontext *ctx );
29 static const char *RendererString( void );
31 /* State Management hooks. */
32 static void SetColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a );
33 static void ClearColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a );
34 static GLboolean SetBuffer( GLcontext *ctx, GLenum buffer );
36 /* Window Management hooks. */
37 static void GetBufferSize( GLcontext *ctx, GLuint *width, GLuint *height );
38 static void SetViewport( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h );
39 static void Flush( GLcontext *ctx );
41 /* Span rendering hooks. */
42 void WSpanRGB( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte rgb[][3], const GLubyte mask[] );
43 void WSpanRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte rgba[][4], const GLubyte mask[] );
44 void WSpanRGBAMono( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte mask[] );
45 void WPixelsRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte rgba[][4], const GLubyte mask[] );
46 void WPixelsRGBAMono( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte mask[] );
47 void RSpanRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, GLubyte rgba[][4] );
48 void RPixelsRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], GLubyte rgba[][4], const GLubyte mask[] );
49 GLbitfield ClearBuffers( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height );
51 /* Primitve rendering hooks. */
52 GLboolean RenderVertexBuffer( GLcontext *ctx, GLboolean allDone );
53 void RenderOneTriangle( GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint pv );
54 void RenderOneLine( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv );
55 GLbitfield ClearBuffersD3D( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height );
57 /* Texture Management hooks. */
58 static void TextureBind( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj );
59 static void TextureLoad( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint internalFormat, const struct gl_texture_image *image );
60 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 );
61 /*===========================================================================*/
62 /* Global variables. */
63 /*===========================================================================*/
64 D3DMESACONTEXT *pD3DCurrent,
65 *pD3DDefault; /* Thin support context. */
67 struct __extensions__ ext[] = {
69 { (PROC)glPolygonOffsetEXT, "glPolygonOffsetEXT" },
70 { (PROC)glBlendEquationEXT, "glBlendEquationEXT" },
71 { (PROC)glBlendColorEXT, "glBlendColorExt" },
72 { (PROC)glVertexPointerEXT, "glVertexPointerEXT" },
73 { (PROC)glNormalPointerEXT, "glNormalPointerEXT" },
74 { (PROC)glColorPointerEXT, "glColorPointerEXT" },
75 { (PROC)glIndexPointerEXT, "glIndexPointerEXT" },
76 { (PROC)glTexCoordPointerEXT, "glTexCoordPointer" },
77 { (PROC)glEdgeFlagPointerEXT, "glEdgeFlagPointerEXT" },
78 { (PROC)glGetPointervEXT, "glGetPointervEXT" },
79 { (PROC)glArrayElementEXT, "glArrayElementEXT" },
80 { (PROC)glDrawArraysEXT, "glDrawArrayEXT" },
81 { (PROC)glAreTexturesResidentEXT, "glAreTexturesResidentEXT" },
82 { (PROC)glBindTextureEXT, "glBindTextureEXT" },
83 { (PROC)glDeleteTexturesEXT, "glDeleteTexturesEXT" },
84 { (PROC)glGenTexturesEXT, "glGenTexturesEXT" },
85 { (PROC)glIsTextureEXT, "glIsTextureEXT" },
86 { (PROC)glPrioritizeTexturesEXT, "glPrioritizeTexturesEXT" },
87 { (PROC)glCopyTexSubImage3DEXT, "glCopyTexSubImage3DEXT" },
88 { (PROC)glTexImage3DEXT, "glTexImage3DEXT" },
89 { (PROC)glTexSubImage3DEXT, "glTexSubImage3DEXT" },
92 int qt_ext = sizeof(ext) / sizeof(ext[0]);
95 /*===========================================================================*/
96 /* When a process loads this DLL we will setup the linked list for context */
97 /* management and create a default context that will support the API until */
98 /* the user creates and binds thier own. This THIN default context is useful*/
100 /* When the process terminates we will clean up all resources here. */
101 /*===========================================================================*/
102 /* RETURN: TRUE, FALSE. */
103 /*===========================================================================*/
104 BOOL APIENTRY DllMain( HINSTANCE hInst, DWORD reason, LPVOID reserved )
108 case DLL_PROCESS_ATTACH:
109 return InitOpenGL( hInst );
111 case DLL_PROCESS_DETACH:
112 return TermOpenGL( hInst );
117 /*===========================================================================*/
118 /* The first thing we do when this dll is hit is connect to the dll that has*/
119 /* handles all the DirectX 6 rendering. I decided to use another dll as DX6 */
120 /* is all C++ and Mesa-3.0 is C (thats a good thing). This way I can write */
121 /* the DX6 in C++ and Mesa-3.0 in C without having to worry about linkage. */
122 /* I feel this is easy and better then using static wrappers as it is likely */
123 /* faster and it allows me to just develope the one without compiling the */
125 /* NOTE that at this point we don't have much other than a very thin context*/
126 /* that will support the API calls only to the point of not causing the app */
127 /* to crash from the API table being empty. */
128 /*===========================================================================*/
129 /* RETURN: TRUE, FALSE. */
130 /*===========================================================================*/
131 static BOOL InitOpenGL( HINSTANCE hInst )
133 /* Allocate and clear the default context. */
134 pD3DDefault = (PD3DMESACONTEXT)ALLOC( sizeof(D3DMESACONTEXT) );
135 if ( pD3DDefault == NULL )
137 memset( pD3DDefault, 0, sizeof(D3DMESACONTEXT) );
139 /* Clear the D3D vertex buffer so that values not used will be zero. This */
140 /* save me from some redundant work. */
141 memset( &D3DTLVertices, 0, sizeof(D3DTLVertices) );
143 /* Update the link. We uses a circular list so that it is easy to */
144 /* add and search. This context will also be used for head and tail.*/
145 pD3DDefault->next = pD3DDefault;
147 /*========================================================================*/
148 /* Do all core Mesa stuff. */
149 /*========================================================================*/
150 pD3DDefault->gl_visual = _mesa_create_visual( TRUE,
152 GL_FALSE, /* stereo */
153 8,8,8,8, /* r, g, b, a bits */
156 8, /* stencil_bits */
157 8,8,8,8, /* accum_bits */
160 if ( pD3DDefault->gl_visual == NULL)
166 /* Allocate a new Mesa context */
167 pD3DDefault->gl_ctx = _mesa_create_context( pD3DDefault->gl_visual, NULL, pD3DDefault, GL_TRUE );
168 if ( pD3DDefault->gl_ctx == NULL )
170 _mesa_destroy_visual( pD3DDefault->gl_visual );
175 /* Allocate a new Mesa frame buffer */
176 pD3DDefault->gl_buffer = _mesa_create_framebuffer( pD3DDefault->gl_visual );
177 if ( pD3DDefault->gl_buffer == NULL )
179 _mesa_destroy_visual( pD3DDefault->gl_visual );
180 _mesa_destroy_context( pD3DDefault->gl_ctx );
184 SetupDDPointers( pD3DDefault->gl_ctx );
185 _mesa_make_current( pD3DDefault->gl_ctx, pD3DDefault->gl_buffer );
189 /*===========================================================================*/
190 /* This function will create a new D3D context but will not create the D3D */
191 /* surfaces or even an instance of D3D (see at GetBufferSize). The only stuff*/
192 /* done here is the internal Mesa stuff and some Win32 handles. */
193 /*===========================================================================*/
194 /* RETURN: casted pointer to the context, NULL. */
195 /*===========================================================================*/
196 HGLRC APIENTRY wglCreateContext( HDC hdc )
198 D3DMESACONTEXT *pNewContext;
199 DWORD dwCoopFlags = DDSCL_NORMAL;
203 /* ALLOC and clear the new context. */
204 pNewContext = (PD3DMESACONTEXT)ALLOC( sizeof(D3DMESACONTEXT) );
205 if ( pNewContext == NULL )
210 memset( pNewContext, 0, sizeof(D3DMESACONTEXT) );
212 /*========================================================================*/
213 /* Do all core Mesa stuff. */
214 /*========================================================================*/
216 /* TODO: support more then one visual. */
217 pNewContext->gl_visual = _mesa_create_visual( TRUE,
219 GL_FALSE, /* stereo */
220 8,8,8,8, /* r, g, b, a bits */
223 8, /* stencil_bits */
224 16,16,16,16,/* accum_bits */
226 if ( pNewContext->gl_visual == NULL)
233 /* Allocate a new Mesa context */
234 pNewContext->gl_ctx = _mesa_create_context( pNewContext->gl_visual, NULL, pNewContext, GL_TRUE );
235 if ( pNewContext->gl_ctx == NULL )
237 _mesa_destroy_visual( pNewContext->gl_visual );
243 /* Allocate a new Mesa frame buffer */
244 pNewContext->gl_buffer = _mesa_create_framebuffer( pNewContext->gl_visual );
245 if ( pNewContext->gl_buffer == NULL )
247 _mesa_destroy_visual( pNewContext->gl_visual );
248 _mesa_destroy_context( pNewContext->gl_ctx );
254 /*========================================================================*/
255 /* Do all the driver stuff. */
256 /*========================================================================*/
257 pNewContext->hdc = hdc;
258 pNewContext->next = pD3DDefault->next;
259 pD3DDefault->next = pNewContext; /* Add to circular list. */
261 /* Create the HAL for the new context. */
262 pNewContext->pShared = InitHAL( WindowFromDC(hdc) );
264 return (HGLRC)pNewContext;
266 /*===========================================================================*/
267 /* This is a wrapper function that is supported by MakeCurrent. */
268 /*===========================================================================*/
269 /* RETURN: TRUE, FALSE. */
270 /*===========================================================================*/
271 BOOL APIENTRY wglMakeCurrent( HDC hdc, HGLRC hglrc )
273 return MakeCurrent((D3DMESACONTEXT *)hglrc);
275 /*===========================================================================*/
276 /* MakeCurrent will unbind whatever context is current (if any) & then bind */
277 /* the supplied context. A context that is bound has it's window proc hooked*/
278 /* with the wglMonitorProc and the context pointer is saved in pD3DCurrent. */
279 /* Once the context is bound we update the Mesa-3.0 hooks (SetDDPointers) and*/
280 /* the viewport (Mesa-.30 and DX6). */
282 /* TODO: this function can't fail. */
283 /*===========================================================================*/
285 /*===========================================================================*/
286 static BOOL MakeCurrent( D3DMESACONTEXT *pContext )
288 D3DMESACONTEXT *pNext;
290 /*====================================================================*/
291 /* This is a special case that is a request to have no context bound. */
292 /*====================================================================*/
293 if ( pContext == NULL )
295 /* Walk the whole list. We start and end at the Default context. */
296 for( pNext = pD3DDefault->next; pNext != pD3DDefault; pNext = pNext->next )
297 UnBindWindow( pNext );
302 /*=================================================*/
303 /* Make for a fast redundant use of this function. */
304 /*=================================================*/
305 if ( pD3DCurrent == pContext )
308 /*=============================*/
309 /* Unbind the current context. */
310 /*=============================*/
311 UnBindWindow( pD3DCurrent );
313 /*=====================================*/
314 /* Let Mesa-3.0 we have a new context. */
315 /*=====================================*/
316 SetupDDPointers( pContext->gl_ctx );
317 _mesa_make_current( pContext->gl_ctx, pContext->gl_buffer );
319 /* We are done so set the internal current context. */
320 if ( pContext != pD3DDefault )
322 ResizeContext( pContext->gl_ctx );
323 pContext->hOldProc = (WNDPROC)GetWindowLong( pContext->pShared->hwnd, GWL_WNDPROC );
324 SetWindowLong( pContext->pShared->hwnd, GWL_WNDPROC, (LONG)wglMonitorProc );
326 pD3DCurrent = pContext;
330 /*===========================================================================*/
331 /* This function will only return the current window size. I have re-done */
332 /* this function so that it doesn't check the current size and react to it as*/
333 /* I should be able to have all the react code in the WM_SIZE message. The */
334 /* old version would check the current window size and create/resize the HAL */
335 /* surfaces if they have changed. I needed to delay the creation if the */
336 /* surfaces because sometimes I wouldn't have a window size so this is where */
337 /* I delayed it. If you are reading this then all went ok! */
338 /* The default context will return a zero sized window and I'm not sure if */
339 /* this is ok at this point (TODO). */
340 /*===========================================================================*/
342 /*===========================================================================*/
343 static void GetBufferSize( GLcontext *ctx, GLuint *width, GLuint *height )
345 D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
347 /* Fall through for the default because that is one of the uses for it. */
348 if ( pContext == pD3DDefault )
355 *width = pContext->pShared->dwWidth;
356 *height = pContext->pShared->dwHeight;
359 /*===========================================================================*/
362 /*===========================================================================*/
364 /*===========================================================================*/
365 static BOOL ResizeContext( GLcontext *ctx )
367 D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx,
373 static BOOL bDDrawLock = FALSE;
375 /* Make sure we have some values. */
376 if ( (pContext->hdc == NULL ) ||
377 (pContext->pShared->hwnd != WindowFromDC(pContext->hdc)) ||
378 (pContext == pD3DDefault) )
381 /* Having problems with DDraw sending resize messages before I was done. */
382 if( bDDrawLock == TRUE )
385 // TODO: don't think I need this anymore.
386 pCurrentTemp = pD3DCurrent;
387 pD3DCurrent = pD3DDefault;
390 /* Get the current window dimentions. */
391 UpdateScreenPosHAL( pContext->pShared );
392 dwWidth = pContext->pShared->rectW.right - pContext->pShared->rectW.left;
393 dwHeight = pContext->pShared->rectW.bottom - pContext->pShared->rectW.top;
395 /* Is the size of the OffScreen Render different? */
396 if ( (dwWidth != pContext->pShared->dwWidth) || (dwHeight != pContext->pShared->dwHeight) )
398 /* Create all the D3D surfaces and device. */
399 CreateHAL( pContext->pShared );
401 /* I did this so that software rendering would still work as */
402 /* I don't need to scale the z values twice. */
403 g_DepthScale = (pContext->pShared->bHardware) ? 1.0 : ((float)0x00FFFFFF);
404 g_MaxDepth = (pContext->pShared->bHardware) ? 1.0 : ((float)0x00FFFFFF);
405 gl_DepthRange( pContext->gl_ctx, ctx->Viewport.Near, ctx->Viewport.Far );
407 /* Make sure we have a viewport. */
408 gl_Viewport( pContext->gl_ctx, 0, 0, dwWidth, dwHeight );
410 /* Update Mesa as we might have changed from SW <-> HW. */
411 SetupDDPointers( pContext->gl_ctx );
412 _mesa_make_current( pContext->gl_ctx, pContext->gl_buffer );
414 /* If we are in HW we need to load the current texture if there is one already. */
415 // if ( (ctx->Texture.Set[ctx->Texture.CurrentSet].Current != NULL) &&
416 // (pContext->pShared->bHardware == TRUE) )
418 // CreateTMgrHAL( pContext->pShared,
419 // ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Name,
421 // ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Format,
423 // ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Width,
424 // ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Height,
426 // (void *)ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Data );
430 // TODO: don't think I need this anymore.
431 pD3DCurrent = pCurrentTemp;
437 /*===========================================================================*
438 /* This function will Blt the render buffer to the PRIMARY surface. I repeat*/
439 /* this code for the other SwapBuffer like functions and the flush (didn't */
440 /* want the function calling overhead). Thsi could have been a macro... */
442 /* TODO: there are some problems with viewport/scissoring. */
443 /*===========================================================================*/
444 /* RETURN: TRUE, FALSE. */
445 /*===========================================================================*/
446 BOOL APIENTRY wglSwapBuffers( HDC hdc )
448 /* Fall through for the default because that is one of the uses for it. */
449 if ( pD3DCurrent == pD3DDefault )
452 SwapBuffersHAL( pD3DCurrent->pShared );
456 /*===========================================================================*/
457 /* Same as wglSwapBuffers. */
458 /*===========================================================================*/
459 /* RETURN: TRUE, FALSE. */
460 /*===========================================================================*/
461 BOOL APIENTRY SwapBuffers( HDC hdc )
463 /* Fall through for the default because that is one of the uses for it. */
464 if ( pD3DCurrent == pD3DDefault )
467 SwapBuffersHAL( pD3DCurrent->pShared );
471 /*===========================================================================*/
472 /* This should be ok as none of the SwapBuffers will cause a redundant Blt */
473 /* as none of my Swap functions will call flush. This should also allow */
474 /* sinlge buffered applications to work (not really worried though). Some */
475 /* applications may flush then swap but then this is there fault IMHO. */
476 /*===========================================================================*/
478 /*===========================================================================*/
479 static void Flush( GLcontext *ctx )
481 /* Fall through for the default because that is one of the uses for it. */
482 if ( pD3DCurrent == pD3DDefault )
485 SwapBuffersHAL( pD3DCurrent->pShared );
487 /*===========================================================================*/
488 /* For now this function will ignore the supplied PF. If I'm going to allow */
489 /* the user to choice the mode and device at startup I'm going to have to do */
490 /* something different. */
492 /* TODO: use the linked list of modes to build a pixel format to be returned */
494 /*===========================================================================*/
496 /*===========================================================================*/
497 int APIENTRY wglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *ppfd )
501 /*===========================================================================*/
502 /* See wglChoosePixelFormat. */
503 /*===========================================================================*/
505 /*===========================================================================*/
506 int APIENTRY ChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *ppfd )
508 return wglChoosePixelFormat(hdc,ppfd);
510 /*===========================================================================*/
511 /* This function (for now) returns a static PF everytime. This is just to */
512 /* allow things to continue. */
513 /*===========================================================================*/
515 /*===========================================================================*/
516 int APIENTRY wglDescribePixelFormat( HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd )
518 static PIXELFORMATDESCRIPTOR pfd =
520 sizeof(PIXELFORMATDESCRIPTOR), /* size */
524 PFD_DOUBLEBUFFER, /* support double-buffering */
525 PFD_TYPE_RGBA, /* color type */
526 16, /* prefered color depth */
527 0, 0, 0, 0, 0, 0, /* color bits (ignored) */
528 0, /* no alpha buffer */
529 0, /* alpha bits (ignored) */
530 0, /* no accumulation buffer */
531 0, 0, 0, 0, /* accum bits (ignored) */
532 16, /* depth buffer */
533 0, /* no stencil buffer */
534 0, /* no auxiliary buffers */
535 PFD_MAIN_PLANE, /* main layer */
537 0, 0, 0, /* no layer, visible, damage masks */
540 /* Return the address of this static PF if one was requested. */
542 memcpy( ppfd, &pfd, sizeof(PIXELFORMATDESCRIPTOR) );
546 /*===========================================================================*/
547 /* See wglDescribePixelFormat. */
548 /*===========================================================================*/
550 /*===========================================================================*/
551 int APIENTRY DescribePixelFormat( HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd )
553 return wglDescribePixelFormat(hdc,iPixelFormat,nBytes,ppfd);
555 /*===========================================================================*/
556 /* This function will always return 1 for now. Just to allow for support. */
557 /*===========================================================================*/
559 /*===========================================================================*/
560 int APIENTRY wglGetPixelFormat( HDC hdc )
564 /*===========================================================================*/
565 /* See wglGetPixelFormat. */
566 /*===========================================================================*/
568 /*===========================================================================*/
569 int APIENTRY GetPixelFormat( HDC hdc )
571 return wglGetPixelFormat(hdc);
573 /*===========================================================================*/
574 /* This will aways work for now. */
575 /*===========================================================================*/
577 /*===========================================================================*/
578 BOOL APIENTRY wglSetPixelFormat( HDC hdc, int iPixelFormat, CONST PIXELFORMATDESCRIPTOR *ppfd )
582 /*===========================================================================*/
583 /* See wglSetPixelFormat. */
584 /*===========================================================================*/
585 /* RETURN: TRUE, FALSE. */
586 /*===========================================================================*/
587 BOOL APIENTRY SetPixelFormat( HDC hdc, int iPixelFormat, CONST PIXELFORMATDESCRIPTOR *ppfd )
589 return wglSetPixelFormat(hdc,iPixelFormat,ppfd);
591 /*===========================================================================*/
592 /* This is a wrapper function that is supported by my own internal function.*/
593 /* that takes my own D3D Mesa context structure. This so I can reuse the */
594 /* function (no need for speed). */
595 /*===========================================================================*/
597 /*===========================================================================*/
598 BOOL APIENTRY wglDeleteContext( HGLRC hglrc )
600 DestroyContext( (D3DMESACONTEXT *)hglrc );
604 /*===========================================================================*/
605 /* Simple getter function that uses a cast. */
606 /*===========================================================================*/
607 /* RETURN: casted pointer to the context, NULL. */
608 /*===========================================================================*/
609 HGLRC APIENTRY wglGetCurrentContext( VOID )
611 return (pD3DCurrent) ? (HGLRC)pD3DCurrent : (HGLRC)NULL;
613 /*===========================================================================*/
615 /*===========================================================================*/
617 /*===========================================================================*/
618 BOOL APIENTRY wglCopyContext( HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask )
623 /*===========================================================================*/
625 /*===========================================================================*/
627 /*===========================================================================*/
628 HGLRC APIENTRY wglCreateLayerContext( HDC hdc,int iLayerPlane )
633 /*===========================================================================*/
634 /* Simple getter function. */
635 /*===========================================================================*/
637 /*===========================================================================*/
638 HDC APIENTRY wglGetCurrentDC( VOID )
640 return (pD3DCurrent) ? pD3DCurrent->hdc : (HDC)NULL;
642 /*===========================================================================*/
643 /* Simply call that searches the supported extensions for a match & returns */
644 /* the pointer to the function that lends support. */
645 /*===========================================================================*/
646 /* RETURN: pointer to API call, NULL. */
647 /*===========================================================================*/
648 PROC APIENTRY wglGetProcAddress( LPCSTR lpszProc )
652 for( index = 0; index < qt_ext; index++ )
653 if( !strcmp(lpszProc,ext[index].name) )
654 return ext[index].proc;
659 /*===========================================================================*/
661 /*===========================================================================*/
663 /*===========================================================================*/
664 BOOL APIENTRY wglShareLists( HGLRC hglrc1, HGLRC hglrc2 )
669 /*===========================================================================*/
671 /*===========================================================================*/
673 /*===========================================================================*/
674 BOOL APIENTRY wglUseFontBitmaps( HDC fontDevice, DWORD firstChar, DWORD numChars, DWORD listBase )
679 /*===========================================================================*/
681 /*===========================================================================*/
683 /*===========================================================================*/
684 BOOL APIENTRY wglUseFontBitmapsW( HDC hdc,DWORD first,DWORD count,DWORD listBase )
689 /*===========================================================================*/
691 /*===========================================================================*/
693 /*===========================================================================*/
694 BOOL APIENTRY wglUseFontOutlinesA( HDC hdc, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf )
699 /*===========================================================================*/
701 /*===========================================================================*/
703 /*===========================================================================*/
704 BOOL APIENTRY wglUseFontOutlinesW( HDC hdc,DWORD first,DWORD count, DWORD listBase,FLOAT deviation, FLOAT extrusion,int format, LPGLYPHMETRICSFLOAT lpgmf )
709 /*===========================================================================*/
711 /*===========================================================================*/
713 /*===========================================================================*/
714 BOOL APIENTRY wglSwapLayerBuffers( HDC hdc, UINT fuPlanes )
719 /*===========================================================================*/
720 /* This function will be hooked into the window that has been bound. Right */
721 /* now it is used to track the window size and position. Also the we clean */
722 /* up the currrent context when the window is close/destroyed. */
724 /* TODO: there might be something wrong here as some games (Heretic II) don't*/
725 /* track the window quit right. */
726 /*===========================================================================*/
728 /*===========================================================================*/
729 LONG APIENTRY wglMonitorProc( HWND hwnd, UINT message, UINT wParam, LONG lParam )
741 // case WM_SHOWWINDOW:
744 case UM_FATALSHUTDOWN:
745 /* Support the API until we die... */
746 MakeCurrent( pD3DDefault );
750 case WM_DISPLAYCHANGE:
752 ResizeContext( pD3DCurrent->gl_ctx );
757 /* Support the API until we die... */
758 hOldProc = pD3DCurrent->hOldProc;
759 DestroyContext( pD3DCurrent );
760 return (hOldProc)(hwnd,message,wParam,lParam);
763 return (pD3DCurrent->hOldProc)(hwnd,message,wParam,lParam);
766 /**********************************************************************/
767 /***** Miscellaneous device driver funcs *****/
768 /**********************************************************************/
770 /*===========================================================================*/
771 /* Not reacting to this as I'm only supporting drawing to the back buffer */
773 /*===========================================================================*/
775 /*===========================================================================*/
776 static GLboolean SetBuffer( GLcontext *ctx, GLenum buffer )
778 if (buffer == GL_BACK_LEFT)
783 /*===========================================================================*/
784 /* This proc will be called by Mesa when the viewport has been set. So if */
785 /* we have a context and it isn't the default then we should let D3D know of */
787 /*===========================================================================*/
789 /*===========================================================================*/
790 static void SetViewport( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h )
792 D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
795 /* Make sure we can set a viewport. */
796 if ( pContext->pShared && (pContext != pD3DDefault) )
798 // TODO: might be needed.
799 UpdateScreenPosHAL( pContext->pShared );
805 // TODO: shared struct should make this call smaller
806 SetViewportHAL( pContext->pShared, &rect, 0.0F, 1.0F );
809 /*===========================================================================*/
810 /* This function could be better I guess but I decided just to grab the four*/
811 /* components and store then seperately. Makes it easier to use IMHO. */
812 /*===========================================================================*/
814 /*===========================================================================*/
815 static void ClearColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
817 D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
819 pContext->aClear = a;
820 pContext->bClear = b;
821 pContext->gClear = g;
822 pContext->rClear = r;
824 /*===========================================================================*/
825 /* This function could be better I guess but I decided just to grab the four*/
826 /* components and store then seperately. Makes it easier to use IMHO. */
827 /* (is there an echo in here?) */
828 /*===========================================================================*/
830 /*===========================================================================*/
831 static void SetColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
833 D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
835 pContext->aCurrent = a;
836 pContext->bCurrent = b;
837 pContext->gCurrent = g;
838 pContext->rCurrent = r;
840 /*===========================================================================*/
843 /*===========================================================================*/
845 /*===========================================================================*/
846 static const char *RendererString( void )
848 static char pszRender[64];
850 strcpy( pszRender, "altD3D " );
852 if ( pD3DCurrent->pShared->bHardware )
853 strcat( pszRender, "(HW)");
855 strcat( pszRender, "(SW)");
857 return (const char *)pszRender;
859 /*===========================================================================*/
860 /* This function will choose which set of pointers Mesa will use based on */
861 /* whether we hard using hardware or software. I have added another set of */
862 /* pointers that will do nothing but stop the API from crashing. */
863 /*===========================================================================*/
865 /*===========================================================================*/
866 static void SetupDDPointers( GLcontext *ctx )
868 D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
870 // TODO: write a generic NULL support for the span render.
871 if ( pContext->pShared && pContext->pShared->bHardware )
873 ctx->Driver.UpdateState = SetupHWDDPointers;
875 else if ( pContext == pD3DDefault )
877 ctx->Driver.UpdateState = SetupNULLDDPointers;
881 ctx->Driver.UpdateState = SetupSWDDPointers;
884 /*===========================================================================*/
885 /* This function will populate all the Mesa driver hooks. This version of */
886 /* hooks will do nothing but support the API when we don't have a valid */
887 /* context bound. This is mostly for applications that don't behave right */
888 /* and also to help exit as clean as possable when we have a FatalError. */
889 /*===========================================================================*/
890 /* RETURN: pointer to the specific function. */
891 /*===========================================================================*/
892 static void SetupNULLDDPointers( GLcontext *ctx )
894 D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
896 /* Initialize all the pointers in the DD struct. Do this whenever */
897 /* a new context is made current or we change buffers via set_buffer! */
898 ctx->Driver.UpdateState = SetupNULLDDPointers;
900 /* State management hooks. */
901 ctx->Driver.Color = NULLSetColor;
902 ctx->Driver.ClearColor = NULLClearColor;
903 ctx->Driver.Clear = NULLClearBuffers;
904 ctx->Driver.SetBuffer = NULLSetBuffer;
906 /* Window management hooks. */
907 ctx->Driver.GetBufferSize = NULLGetBufferSize;
909 /* Primitive rendering hooks. */
910 ctx->Driver.TriangleFunc = NULL;
911 ctx->Driver.RenderVB = NULL;
913 /* Pixel/span writing functions: */
914 ctx->Driver.WriteRGBASpan = NULLWrSpRGBA;
915 ctx->Driver.WriteRGBSpan = NULLWrSpRGB;
916 ctx->Driver.WriteMonoRGBASpan = NULLWrSpRGBAMono;
917 ctx->Driver.WriteRGBAPixels = NULLWrPiRGBA;
918 ctx->Driver.WriteMonoRGBAPixels = NULLWrPiRGBAMono;
920 /* Pixel/span reading functions: */
921 ctx->Driver.ReadRGBASpan = NULLReSpRGBA;
922 ctx->Driver.ReadRGBAPixels = NULLRePiRGBA;
925 ctx->Driver.RendererString = RendererString;
927 /*===========================================================================*/
928 /* This function will populate all the Mesa driver hooks. There are two of */
929 /* these functions. One if we have hardware support and one is there is only*/
930 /* software. These functions will be called by Mesa and by the wgl.c when we*/
931 /* have resized (or created) the buffers. The thing is that if a window gets*/
932 /* resized we may loose hardware support or gain it... */
933 /*===========================================================================*/
934 /* RETURN: pointer to the specific function. */
935 /*===========================================================================*/
936 static void SetupSWDDPointers( GLcontext *ctx )
938 D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
940 /* Initialize all the pointers in the DD struct. Do this whenever */
941 /* a new context is made current or we change buffers via set_buffer! */
942 ctx->Driver.UpdateState = SetupSWDDPointers;
944 /* State management hooks. */
945 ctx->Driver.Color = SetColor;
946 ctx->Driver.ClearColor = ClearColor;
947 ctx->Driver.Clear = ClearBuffers;
948 ctx->Driver.SetBuffer = SetBuffer;
950 /* Window management hooks. */
951 ctx->Driver.GetBufferSize = GetBufferSize;
952 ctx->Driver.Viewport = SetViewport;
954 /* Primitive rendering hooks. */
955 ctx->Driver.TriangleFunc = NULL;
956 ctx->Driver.RenderVB = NULL;
958 /* Texture management hooks. */
960 /* Pixel/span writing functions: */
961 ctx->Driver.WriteRGBASpan = WSpanRGBA;
962 ctx->Driver.WriteRGBSpan = WSpanRGB;
963 ctx->Driver.WriteMonoRGBASpan = WSpanRGBAMono;
964 ctx->Driver.WriteRGBAPixels = WPixelsRGBA;
965 ctx->Driver.WriteMonoRGBAPixels = WPixelsRGBAMono;
967 /* Pixel/span reading functions: */
968 ctx->Driver.ReadRGBASpan = RSpanRGBA;
969 ctx->Driver.ReadRGBAPixels = RPixelsRGBA;
972 ctx->Driver.Flush = Flush;
973 ctx->Driver.RendererString = RendererString;
975 /*===========================================================================*/
976 /* This function will populate all the Mesa driver hooks. There are two of */
977 /* these functions. One if we have hardware support and one is there is only*/
978 /* software. These functions will be called by Mesa and by the wgl.c when we*/
979 /* have resized (or created) the buffers. The thing is that if a window gets*/
980 /* resized we may loose hardware support or gain it... */
981 /*===========================================================================*/
982 /* RETURN: pointer to the specific function. */
983 /*===========================================================================*/
984 static void SetupHWDDPointers( GLcontext *ctx )
986 D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
988 /* Initialize all the pointers in the DD struct. Do this whenever */
989 /* a new context is made current or we change buffers via set_buffer! */
990 ctx->Driver.UpdateState = SetupHWDDPointers;
992 /* State management hooks. */
993 ctx->Driver.Color = SetColor;
994 ctx->Driver.ClearColor = ClearColor;
995 ctx->Driver.Clear = ClearBuffersD3D;
996 ctx->Driver.SetBuffer = SetBuffer;
998 /* Window management hooks. */
999 ctx->Driver.GetBufferSize = GetBufferSize;
1000 ctx->Driver.Viewport = SetViewport;
1002 /* Primitive rendering hooks. */
1003 ctx->Driver.TriangleFunc = RenderOneTriangle;
1004 ctx->Driver.LineFunc = RenderOneLine;
1005 ctx->Driver.RenderVB = RenderVertexBuffer;
1007 /* Pixel/span writing functions: */
1008 ctx->Driver.WriteRGBASpan = WSpanRGBA;
1009 ctx->Driver.WriteRGBSpan = WSpanRGB;
1010 ctx->Driver.WriteMonoRGBASpan = WSpanRGBAMono;
1011 ctx->Driver.WriteRGBAPixels = WPixelsRGBA;
1012 ctx->Driver.WriteMonoRGBAPixels = WPixelsRGBAMono;
1014 /* Pixel/span reading functions: */
1015 ctx->Driver.ReadRGBASpan = RSpanRGBA;
1016 ctx->Driver.ReadRGBAPixels = RPixelsRGBA;
1018 /* Texture management hooks. */
1019 // ctx->Driver.BindTexture = TextureBind;
1020 ctx->Driver.TexImage = TextureLoad;
1021 ctx->Driver.TexSubImage = TextureSubImage;
1024 ctx->Driver.Flush = Flush;
1025 ctx->Driver.RendererString = RendererString;
1027 /*===========================================================================*/
1028 /* This function will release all resources used by the DLL. Every context */
1029 /* will be clobbered by releaseing all driver desources and then freeing the */
1030 /* context memory. Most all the work is done in DestroyContext. */
1031 /*===========================================================================*/
1033 /*===========================================================================*/
1034 static BOOL TermOpenGL( HINSTANCE hInst )
1036 D3DMESACONTEXT *pTmp,
1039 /* Just incase we are still getting paint msg. */
1040 MakeCurrent( pD3DDefault );
1042 /* Walk the list until we get back to the default context. */
1043 for( pTmp = pD3DDefault->next; pTmp != pD3DDefault; pTmp = pNext )
1046 DestroyContext( pTmp );
1048 DestroyContext( pD3DDefault );
1052 /*===========================================================================*/
1053 /* This function is an internal function that will clean up all the Mesa */
1054 /* context bound to this D3D context. Also any D3D stuff that this context */
1055 /* uses will be unloaded. */
1056 /*===========================================================================*/
1057 /* RETURN: TRUE, FALSE. */
1058 /*===========================================================================*/
1059 static void DestroyContext( D3DMESACONTEXT *pContext )
1061 D3DMESACONTEXT *pTmp;
1063 /* Walk the list until we find the context before this one. */
1064 for( pTmp = pD3DDefault; pTmp && (pTmp->next != pContext); pTmp = pTmp->next )
1065 if ( pTmp == pTmp->next )
1068 /* If we never found it it must already be deleted. */
1069 if ( pTmp->next != pContext )
1072 /* Make sure we are not using this context. */
1073 if ( pContext == pD3DCurrent )
1074 MakeCurrent( pD3DDefault );
1076 /* Free the Mesa stuff. */
1077 if ( pContext->gl_visual )
1079 _mesa_destroy_visual( pContext->gl_visual );
1080 pContext->gl_visual = NULL;
1082 if ( pContext->gl_buffer )
1084 _mesa_destroy_framebuffer( pContext->gl_buffer );
1085 pContext->gl_buffer = NULL;
1087 if ( pContext->gl_ctx )
1089 _mesa_destroy_context( pContext->gl_ctx );
1090 pContext->gl_ctx = NULL;
1093 /* Now dump the D3D. */
1094 if ( pContext->pShared )
1095 TermHAL( pContext->pShared );
1097 /* Update the previous context's link. */
1098 pTmp->next = pContext->next;
1103 /*===========================================================================*/
1104 /* This function will pull the supplied context away from Win32. Basicly it*/
1105 /* will remove the hook from the window Proc. */
1107 /* TODO: might want to serialize this stuff... */
1108 /*===========================================================================*/
1109 /* RETURN: TRUE, FALSE. */
1110 /*===========================================================================*/
1111 static BOOL UnBindWindow( D3DMESACONTEXT *pContext )
1113 if ( pContext == NULL )
1116 if ( pContext == pD3DDefault )
1119 /* Make sure we always have a context bound. */
1120 if ( pContext == pD3DCurrent )
1121 pD3DCurrent = pD3DDefault;
1123 SetWindowLong( pContext->pShared->hwnd, GWL_WNDPROC, (LONG)pContext->hOldProc );
1124 pContext->hOldProc = NULL;
1128 /*===========================================================================*/
1129 /* There are two cases that allow for a faster clear when we know that the */
1130 /* whole buffer is cleared and that there is no clipping. */
1131 /*===========================================================================*/
1132 /* RETURN: the original mask with the bits cleared that represents the buffer*
1133 /* or buffers we just cleared. */
1134 /*===========================================================================*/
1135 GLbitfield ClearBuffersD3D( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height )
1137 D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
1140 if ( mask & GL_COLOR_BUFFER_BIT )
1142 dwFlags |= D3DCLEAR_TARGET;
1143 mask &= ~GL_COLOR_BUFFER_BIT;
1145 if ( mask & GL_DEPTH_BUFFER_BIT )
1147 dwFlags |= D3DCLEAR_ZBUFFER;
1148 mask &= ~GL_DEPTH_BUFFER_BIT;
1153 ClearHAL( pContext->pShared,
1158 ((pContext->aClear<<24) | (pContext->rClear<<16) | (pContext->gClear<<8) | (pContext->bClear)),
1167 /*===========================================================================*/
1168 /* TEXTURE MANAGER: ok here is how I did textures. Mesa-3.0 will keep track*/
1169 /* of all the textures for us. So this means that at anytime we can go to */
1170 /* the Mesa context and get the current texture. With this in mind this is */
1171 /* what I did. I really don't care about what textures get or are loaded */
1172 /* until I actually have to draw a tri that is textured. At this point I */
1173 /* must have the texture so I demand the texture by destorying all other */
1174 /* texture surfaces if need be and load the current one. This allows for the*/
1175 /* best preformance on low memory cards as time is not wasted loading and */
1176 /* unload textures. */
1177 /*===========================================================================*/
1183 /*===========================================================================*/
1184 /* TextureLoad will try and create a D3D surface from the supplied texture */
1185 /* object if its level 0 (first). The surface will be fully filled with the */
1187 /*===========================================================================*/
1189 /*===========================================================================*/
1190 static void TextureLoad( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint internalFormat, const struct gl_texture_image *image )
1192 D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
1194 /* TODO: only doing first LOD. */
1195 if ( (ctx->DriverCtx == NULL) || (level != 0) )
1198 CreateTMgrHAL( pContext->pShared,
1201 tObj->Image[level]->Format,
1203 tObj->Image[level]->Width,
1204 tObj->Image[level]->Height,
1206 (void *)tObj->Image[level]->Data );
1208 /*===========================================================================*/
1209 /* TextureBind make sure that the texture is on the card. Thats it. */
1210 /*===========================================================================*/
1212 /*===========================================================================*/
1213 static void TextureBind( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj )
1215 D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
1217 /* TODO: only doing first LOD. */
1218 if ( (tObj->Image[0] == NULL) || (ctx->DriverCtx == NULL) )
1221 CreateTMgrHAL( pContext->pShared,
1224 tObj->Image[0]->Format,
1226 tObj->Image[0]->Width,
1227 tObj->Image[0]->Height,
1229 (void *)tObj->Image[0]->Data );
1231 /*===========================================================================*/
1232 /* TextureSubImage will make sure that the texture being updated is updated */
1233 /* if its on the card. */
1234 /*===========================================================================*/
1236 /*===========================================================================*/
1237 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 )
1239 D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
1242 /* TODO: only doing first LOD. */
1243 if ( (ctx->DriverCtx == NULL) || (level > 0) )
1246 /* Create a dirty rectangle structure. */
1247 rect.left = xoffset;
1248 rect.right = xoffset + width;
1250 rect.bottom = yoffset + height;
1252 CreateTMgrHAL( pContext->pShared,
1255 tObj->Image[0]->Format,
1257 tObj->Image[0]->Width,
1258 tObj->Image[0]->Height,
1260 (void *)tObj->Image[0]->Data );