1 /* $Id: wmesa.c,v 1.2 2003/11/04 23:37:53 brianp Exp $ */
4 * Windows (Win32) device driver for Mesa 3.4
8 * Copyright (C) 1996- Li Wei
9 * Address : Institute of Artificial Intelligence
11 * : Xi'an Jiaotong University
12 * Email : liwei@aiar.xjtu.edu.cn
13 * Web page : http://sun.aiar.xjtu.edu.cn
15 * This file and its associations are partially borrowed from the
16 * Windows NT driver for Mesa 1.8 , written by Mark Leaming
19 * Updated for Mesa 4.0 by Karl Schultz (kschultz@sourceforge.net)
23 #pragma auto_inline(on)
24 #pragma inline_depth(255)
25 #pragma inline_recursion(on)
30 //#include "mesa_extend.h"
38 #include "extensions.h"
43 #include "texformat.h"
46 #include "array_cache/acache.h"
47 #include "swrast/swrast.h"
48 #include "swrast_setup/swrast_setup.h"
49 #include "swrast/s_context.h"
50 #include "swrast/s_depth.h"
51 #include "swrast/s_lines.h"
52 #include "swrast/s_triangle.h"
53 #include "swrast/s_trispan.h"
55 #include "tnl/t_context.h"
56 #include "tnl/t_pipeline.h"
58 /* Dither not tested for Mesa 4.0 */
68 #define CopyMemory memcpy
71 /* Stereo and parallel not tested for Mesa 4.0. */
73 #if !defined(NO_STEREO)
79 #if !defined(NO_PARALLEL)
84 /* File global varaibles */
85 struct DISPLAY_OPTIONS
{
92 struct DISPLAY_OPTIONS displayOptions
=
96 0, // full screen mode (1,2,3,4)
99 GLenum stereoCompile
= GL_FALSE
;
100 GLenum stereoShowing
= GL_FALSE
;
101 GLenum stereoBuffer
= GL_FALSE
;
102 #if !defined(NO_STEREO)
103 GLint displayList
= MAXIMUM_DISPLAY_LIST
;
105 GLint stereo_flag
= 0 ;
107 static PWMC Current
= NULL
;
108 WMesaContext WC
= NULL
;
110 #ifdef COMPILE_SETPIXEL
112 #if defined(_MSC_VER) && _MSC_VER >= 1200
113 #define FORCEINLINE __forceinline
115 #define FORCEINLINE __inline
118 FORCEINLINE
void wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
120 pwc
->wmSetPixel(pwc
,iScanLine
,iPixel
,r
,g
,b
);
123 void ChooseSetPixel(PWMC pwc
);
125 #endif // COMPILE_SETPIXEL
127 /* If we are double-buffering, we want to get the DC for the
128 * off-screen DIB, otherwise the DC for the window.
130 #define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
133 #define FLIP(Y) (Current->height-(Y)-1)
135 #define DITHER_RGB_TO_8BIT_SETUP \
136 GLubyte pixelDithered;
138 #define DITHER_RGB_TO_8BIT(red, green, blue, pixel, scanline) \
140 char unsigned redtemp, greentemp, bluetemp, paletteindex; \
141 redtemp = aDividedBy51[red] \
142 + (aModulo51[red] > aHalftone8x8[(pixel%8)*8 \
144 greentemp = aDividedBy51[(char unsigned)green] \
145 + (aModulo51[green] > aHalftone8x8[ \
146 (pixel%8)*8 + scanline%8]); \
147 bluetemp = aDividedBy51[(char unsigned)blue] \
148 + (aModulo51[blue] > aHalftone8x8[ \
149 (pixel%8)*8 +scanline%8]); \
150 paletteindex = redtemp + aTimes6[greentemp] + aTimes36[bluetemp];\
151 pixelDithered = aWinGHalftoneTranslation[paletteindex]; \
155 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
);
156 static void DDFree( WMesaContext wc
);
157 static HRESULT
DDRestoreAll( WMesaContext wc
);
158 static void DDDeleteOffScreen(WMesaContext wc
);
159 static BOOL
DDCreateOffScreen(WMesaContext wc
);
161 // define this to use the GDI Rectangle call to
162 // clear the back buffer. Otherwise will manually
163 // set the pixels. On an NVidia GEForce 2MX under Windows XP
164 // and DirectX 8 , defining this makes apps run much much faster
165 #define USE_GDI_TO_CLEAR 1
168 static void FlushToFile(PWMC pwc
, PSTR szFile
);
169 BOOL
wmCreateBackingStore(PWMC pwc
, long lxSize
, long lySize
);
170 BOOL
wmDeleteBackingStore(PWMC pwc
);
171 void wmCreatePalette( PWMC pwdc
);
172 BOOL
wmSetDibColors(PWMC pwc
);
173 void wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
);
174 BOOL
wmFlush(PWMC pwc
);
175 void wmCreateDIBSection(
177 PWMC pwc
, // handle of device context
178 CONST BITMAPINFO
*pbmi
, // bitmap size, format, and color data
179 UINT iUsage
// color data type indicator: RGB values or palette indices
181 void WMesaViewport( GLcontext
*ctx
,
182 GLint x
, GLint y
, GLsizei width
, GLsizei height
);
185 static void wmSetPixelFormat( PWMC wc
, HDC hDC
)
188 wc
->cColorBits
= GetDeviceCaps(hDC
, BITSPIXEL
);
191 switch(wc
->cColorBits
){
193 if(wc
->dither_flag
!= GL_TRUE
)
194 wc
->pixelformat
= PF_INDEX8
;
196 wc
->pixelformat
= PF_DITHER8
;
199 wc
->pixelformat
= PF_5R6G5B
;
202 wc
->pixelformat
= PF_8R8G8B
;
205 wc
->pixelformat
= PF_BADFORMAT
;
210 /* This function sets the color table of a DIB section
211 * to match that of the destination DC
213 BOOL
wmSetDibColors(PWMC pwc
)
215 RGBQUAD
*pColTab
, *pRGB
;
216 PALETTEENTRY
*pPal
, *pPE
;
221 /* Build a color table in the DIB that maps to the
222 * selected palette in the DC.
224 nColors
= 1 << pwc
->cColorBits
;
225 pPal
= (PALETTEENTRY
*)malloc( nColors
* sizeof(PALETTEENTRY
));
226 memset( pPal
, 0, nColors
* sizeof(PALETTEENTRY
) );
227 GetPaletteEntries( pwc
->hGLPalette
, 0, nColors
, pPal
);
228 pColTab
= (RGBQUAD
*)malloc( nColors
* sizeof(RGBQUAD
));
229 for (i
= 0, pRGB
= pColTab
, pPE
= pPal
; i
< nColors
; i
++, pRGB
++, pPE
++) {
230 pRGB
->rgbRed
= pPE
->peRed
;
231 pRGB
->rgbGreen
= pPE
->peGreen
;
232 pRGB
->rgbBlue
= pPE
->peBlue
;
235 bRet
= SetDIBColorTable(pwc
->dib
.hDC
, 0, nColors
, pColTab
);
238 dwErr
= GetLastError();
248 * Free up the dib section that was created
250 BOOL
wmDeleteBackingStore(PWMC pwc
)
252 SelectObject(pwc
->dib
.hDC
, pwc
->hOldBitmap
);
253 DeleteDC(pwc
->dib
.hDC
);
254 DeleteObject(pwc
->hbmDIB
);
255 #ifdef USE_MAPPED_FILE
256 UnmapViewOfFile(pwc
->dib
.base
);
257 CloseHandle(pwc
->dib
.hFileMap
);
264 * This function creates the DIB section that is used for combined
267 BOOL
wmCreateBackingStore(PWMC pwc
, long lxSize
, long lySize
)
270 LPBITMAPINFO pbmi
= &(pwc
->bmi
);
273 pbmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
274 pbmi
->bmiHeader
.biWidth
= lxSize
;
275 pbmi
->bmiHeader
.biHeight
= -lySize
;
276 pbmi
->bmiHeader
.biPlanes
= 1;
278 pbmi
->bmiHeader
.biBitCount
= GetDeviceCaps(pwc
->hDC
, BITSPIXEL
);
280 pbmi
->bmiHeader
.biBitCount
= 8;
281 pbmi
->bmiHeader
.biCompression
= BI_RGB
;
282 pbmi
->bmiHeader
.biSizeImage
= 0;
283 pbmi
->bmiHeader
.biXPelsPerMeter
= 0;
284 pbmi
->bmiHeader
.biYPelsPerMeter
= 0;
285 pbmi
->bmiHeader
.biClrUsed
= 0;
286 pbmi
->bmiHeader
.biClrImportant
= 0;
288 iUsage
= (pbmi
->bmiHeader
.biBitCount
<= 8) ? DIB_PAL_COLORS
: DIB_RGB_COLORS
;
290 pwc
->cColorBits
= pbmi
->bmiHeader
.biBitCount
;
291 pwc
->ScanWidth
= pwc
->pitch
= lxSize
;
293 wmCreateDIBSection(hdc
, pwc
, pbmi
, iUsage
);
295 if ((iUsage
== DIB_PAL_COLORS
) && !(pwc
->hGLPalette
)) {
296 wmCreatePalette( pwc
);
297 wmSetDibColors( pwc
);
299 wmSetPixelFormat(pwc
, pwc
->hDC
);
304 // D.R.S. 10/30/01 - this function is never referenced
306 * This function copies one scan line in a DIB section to another
308 BOOL
wmSetDIBits(PWMC pwc
, UINT uiScanWidth
, UINT uiNumScans
,
309 UINT nBypp
, UINT uiNewWidth
, LPBYTE pBits
)
312 LPBYTE pDest
= pwc
->pbPixels
;
313 DWORD dwNextScan
= uiScanWidth
;
314 DWORD dwNewScan
= uiNewWidth
;
315 DWORD dwScanWidth
= (uiScanWidth
* nBypp
);
318 * We need to round up to the nearest DWORD
319 * and multiply by the number of bytes per
322 dwNextScan
= (((dwNextScan
* nBypp
)+ 3) & ~3);
323 dwNewScan
= (((dwNewScan
* nBypp
)+ 3) & ~3);
325 for(uiScans
= 0; uiScans
< uiNumScans
; uiScans
++){
326 CopyMemory(pDest
, pBits
, dwScanWidth
);
334 #if defined(FAST_RASTERIZERS)
336 #define PIXELADDR(X,Y) \
337 ((GLubyte *)Current->pbPixels + (Current->height-Y-1)* \
338 Current->ScanWidth + (X)*nBypp)
339 #define PIXELADDR1( X, Y ) \
340 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X))
341 #define PIXELADDR2( X, Y ) \
342 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*2)
343 #define PIXELADDR4( X, Y ) \
344 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*4)
348 BYTE
DITHER_RGB_2_8BIT( int r
, int g
, int b
, int x
, int y
);
350 /* Finish all pending operations and synchronize. */
351 static void finish(GLcontext
* ctx
)
357 static void flush(GLcontext
* ctx
)
359 if((Current
->rgb_flag
&&!(Current
->db_flag
))
360 ||(!Current
->rgb_flag
))
370 * Set the color index used to clear the color buffer.
372 static void clear_index(GLcontext
* ctx
, GLuint index
)
374 Current
->clearpixel
= index
;
380 * Set the color used to clear the color buffer.
382 static void clear_color( GLcontext
* ctx
, const GLfloat color
[4] )
385 CLAMPED_FLOAT_TO_UBYTE(col
[0], color
[0]);
386 CLAMPED_FLOAT_TO_UBYTE(col
[1], color
[1]);
387 CLAMPED_FLOAT_TO_UBYTE(col
[2], color
[2]);
388 Current
->clearpixel
= RGB(col
[0], col
[1], col
[2]);
393 * Clear the specified region of the color buffer using the clear color
394 * or index as specified by one of the two functions above.
396 * This procedure clears either the front and/or the back COLOR buffers.
397 * Only the "left" buffer is cleared since we are not stereo.
398 * Clearing of the other non-color buffers is left to the swrast.
399 * We also only clear the color buffers if the color masks are all 1's.
400 * Otherwise, we let swrast do it.
403 static clear(GLcontext
* ctx
, GLbitfield mask
,
404 GLboolean all
, GLint x
, GLint y
, GLint width
, GLint height
)
406 const GLuint
*colorMask
= (GLuint
*) &ctx
->Color
.ColorMask
;
410 width
=Current
->width
;
411 height
=Current
->height
;
415 /* sanity check - can't have right(stereo) buffers */
416 assert((mask
& (DD_FRONT_RIGHT_BIT
| DD_BACK_RIGHT_BIT
)) == 0);
419 if ((mask
& (DD_FRONT_LEFT_BIT
| DD_BACK_LEFT_BIT
)) &&
420 ctx
->DrawBuffer
->UseSoftwareAlphaBuffers
&&
421 ctx
->Color
.ColorMask
[ACOMP
]) {
422 _swrast_clear_alpha_buffers( ctx
);
425 if (*colorMask
== 0xffffffff && ctx
->Color
.IndexMask
== 0xffffffff) {
426 if (mask
& DD_BACK_LEFT_BIT
) {
427 #if defined(USE_GDI_TO_CLEAR)
429 // D.R.S. 10/29/01 on my system (Pentium 4 with nvidia GeForce2 MX card,
430 // this is almose 100 times faster that the code below
432 HPEN Pen
=CreatePen(PS_SOLID
,1,Current
->clearpixel
);
433 HBRUSH Brush
=CreateSolidBrush(Current
->clearpixel
);
435 HBRUSH Old_Brush
=NULL
;
436 Current
->lpDDSOffScreen
->lpVtbl
->Unlock(Current
->lpDDSOffScreen
,NULL
);
437 Current
->lpDDSOffScreen
->lpVtbl
->GetDC(Current
->lpDDSOffScreen
,&DC
);
438 Old_Pen
=SelectObject(DC
,Pen
);
439 Old_Brush
=SelectObject(DC
,Brush
);
440 Rectangle(DC
,x
,y
,x
+width
,y
+height
);
441 SelectObject(DC
,Old_Pen
);
442 SelectObject(DC
,Old_Brush
);
445 Current
->lpDDSOffScreen
->lpVtbl
->ReleaseDC(Current
->lpDDSOffScreen
,DC
);
446 while (Current
->lpDDSOffScreen
->lpVtbl
->Lock(Current
->lpDDSOffScreen
,NULL
, &(Current
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
);
448 mask
&= ~DD_BACK_LEFT_BIT
;
452 HPEN Pen
=CreatePen(PS_SOLID
,1,Current
->clearpixel
);
453 HBRUSH Brush
=CreateSolidBrush(Current
->clearpixel
);
454 HPEN Old_Pen
=SelectObject(DC
,Pen
);
455 HBRUSH Old_Brush
=SelectObject(DC
,Brush
);
456 Rectangle(DC
,x
+Current
->rectSurface
.left
,Current
->rectSurface
.top
+y
,x
+width
+Current
->rectSurface
.left
,y
+height
+Current
->rectSurface
.top
);
458 SelectObject(DC
,Old_Pen
);
459 SelectObject(DC
,Old_Brush
);
463 mask
&= ~DD_BACK_LEFT_BIT
;
469 LPDWORD lpdw
= (LPDWORD
)Current
->pbPixels
;
470 LPWORD lpw
= (LPWORD
)Current
->pbPixels
;
471 LPBYTE lpb
= Current
->pbPixels
;
473 /* Double-buffering - clear back buffer */
474 UINT nBypp
= Current
->cColorBits
/ 8;
480 assert(Current
->db_flag
==GL_TRUE
); /* we'd better be double buffer */
482 iSize
= Current
->width
/4;
483 bColor
= BGR8(GetRValue(Current
->clearpixel
),
484 GetGValue(Current
->clearpixel
),
485 GetBValue(Current
->clearpixel
));
486 wColor
= MAKEWORD(bColor
,bColor
);
487 dwColor
= MAKELONG(wColor
, wColor
);
490 iSize
= Current
->width
/ 2;
491 wColor
= BGR16(GetRValue(Current
->clearpixel
),
492 GetGValue(Current
->clearpixel
),
493 GetBValue(Current
->clearpixel
));
494 dwColor
= MAKELONG(wColor
, wColor
);
498 r
= GetRValue(Current
->clearpixel
);
499 g
= GetGValue(Current
->clearpixel
);
500 b
= GetBValue(Current
->clearpixel
);
501 iSize
= Current
->width
;
508 lpb
= Current
->pbPixels
+ Current
->ScanWidth
;
512 iSize
= Current
->width
;
513 dwColor
= BGR32(GetRValue(Current
->clearpixel
),
514 GetGValue(Current
->clearpixel
),
515 GetBValue(Current
->clearpixel
));
533 /* copy cleared line to other lines in buffer */
535 memcpy(lpb
, Current
->pbPixels
, iSize
*mult
);
536 lpb
+= Current
->ScanWidth
;
540 mask
&= ~DD_BACK_LEFT_BIT
;
541 #endif // defined(USE_GDI_TO_CLEAR)
542 } /* double-buffer */
544 if (mask
& DD_FRONT_LEFT_BIT
) {
547 HPEN Pen
=CreatePen(PS_SOLID
,1,Current
->clearpixel
);
548 HBRUSH Brush
=CreateSolidBrush(Current
->clearpixel
);
549 HPEN Old_Pen
=SelectObject(DC
,Pen
);
550 HBRUSH Old_Brush
=SelectObject(DC
,Brush
);
551 Rectangle(DC
,x
+Current
->rectSurface
.left
,Current
->rectSurface
.top
+y
,x
+width
+Current
->rectSurface
.left
,y
+height
+Current
->rectSurface
.top
);
553 SelectObject(DC
,Old_Pen
);
554 SelectObject(DC
,Old_Brush
);
558 mask
&= ~DD_FRONT_LEFT_BIT
;
559 } /* single-buffer */
560 } /* if masks are all 1's */
562 /* Call swrast if there is anything left to clear (like DEPTH) */
564 _swrast_Clear( ctx
, mask
, all
, x
, y
, width
, height
);
568 static void enable( GLcontext
* ctx
, GLenum pname
, GLboolean enable
)
573 if (pname
== GL_DITHER
) {
574 if(enable
== GL_FALSE
){
575 Current
->dither_flag
= GL_FALSE
;
576 if(Current
->cColorBits
== 8)
577 Current
->pixelformat
= PF_INDEX8
;
580 if (Current
->rgb_flag
&& Current
->cColorBits
== 8){
581 Current
->pixelformat
= PF_DITHER8
;
582 Current
->dither_flag
= GL_TRUE
;
585 Current
->dither_flag
= GL_FALSE
;
592 static void set_buffer(GLcontext
*ctx
, GLframebuffer
*colorBuffer
,
595 /* XXX todo - examine bufferBit and set read/write pointers */
601 /* Return characteristics of the output buffer. */
602 static void buffer_size( GLframebuffer
*buffer
, GLuint
*width
, GLuint
*height
)
604 GET_CURRENT_CONTEXT(ctx
);
608 GetClientRect(Current
->Window
,&CR
);
613 New_Size
=((*width
)!=Current
->width
) || ((*height
)!=Current
->height
);
616 Current
->width
=*width
;
617 Current
->height
=*height
;
618 Current
->ScanWidth
=Current
->width
;
619 if ((Current
->ScanWidth
%sizeof(long))!=0)
620 Current
->ScanWidth
+=(sizeof(long)-(Current
->ScanWidth
%sizeof(long)));
622 if (Current
->db_flag
){
624 DDDeleteOffScreen(Current
);
625 DDCreateOffScreen(Current
);
627 if (Current
->rgb_flag
==GL_TRUE
&& Current
->dither_flag
!=GL_TRUE
){
628 wmDeleteBackingStore(Current
);
629 wmCreateBackingStore(Current
, Current
->width
, Current
->height
);
634 /* Resize OsmesaBuffer if in Parallel mode */
635 #if !defined(NO_PARALLEL)
637 PRSizeRenderBuffer(Current
->width
, Current
->height
,Current
->ScanWidth
,
638 Current
->rgb_flag
== GL_TRUE
? Current
->pbPixels
:
646 /**********************************************************************/
647 /***** Accelerated point, line, polygon rendering *****/
648 /**********************************************************************/
650 /* Accelerated routines are not implemented in 4.0. See OSMesa for ideas. */
652 static void fast_rgb_points( GLcontext
* ctx
, GLuint first
, GLuint last
)
656 /* Return pointer to accelerated points function */
657 extern points_func
choose_points_function( GLcontext
* ctx
)
662 static void fast_flat_rgb_line( GLcontext
* ctx
, GLuint v0
,
663 GLuint v1
, GLuint pv
)
667 static line_func
choose_line_function( GLcontext
* ctx
)
672 /**********************************************************************/
673 /***** Span-based pixel drawing *****/
674 /**********************************************************************/
677 /* Write a horizontal span of 32-bit color-index pixels with a boolean mask. */
678 static void write_ci32_span( const GLcontext
* ctx
,
679 GLuint n
, GLint x
, GLint y
,
680 const GLuint index
[],
681 const GLubyte mask
[] )
684 PBYTE Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
685 assert(Current
->rgb_flag
==GL_FALSE
);
692 /* Write a horizontal span of 8-bit color-index pixels with a boolean mask. */
693 static void write_ci8_span( const GLcontext
* ctx
,
694 GLuint n
, GLint x
, GLint y
,
695 const GLubyte index
[],
696 const GLubyte mask
[] )
699 PBYTE Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
700 assert(Current
->rgb_flag
==GL_FALSE
);
709 * Write a horizontal span of pixels with a boolean mask. The current
710 * color index is used for all pixels.
712 static void write_mono_ci_span(const GLcontext
* ctx
,
713 GLuint n
,GLint x
,GLint y
,
714 GLuint colorIndex
, const GLubyte mask
[])
717 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
718 assert(Current
->rgb_flag
==GL_FALSE
);
725 * To improve the performance of this routine, frob the data into an actual
726 * scanline and call bitblt on the complete scan line instead of SetPixel.
729 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
730 static void write_rgba_span( const GLcontext
* ctx
, GLuint n
, GLint x
, GLint y
,
731 const GLubyte rgba
[][4], const GLubyte mask
[] )
735 if (pwc
->rgb_flag
==GL_TRUE
)
743 wmSetPixel(pwc
, y
, x
+ i
,
744 rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
748 wmSetPixel(pwc
, y
, x
+ i
,
749 rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
] );
756 BYTE
*Mem
=Current
->ScreenMem
+y
*Current
->ScanWidth
+x
;
761 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,
768 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,
776 /* Write a horizontal span of RGB color pixels with a boolean mask. */
777 static void write_rgb_span( const GLcontext
* ctx
,
778 GLuint n
, GLint x
, GLint y
,
779 const GLubyte rgb
[][3], const GLubyte mask
[] )
783 if (pwc
->rgb_flag
==GL_TRUE
)
791 wmSetPixel(pwc
, y
, x
+ i
,
792 rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]);
796 wmSetPixel(pwc
, y
, x
+ i
,
797 rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
] );
804 BYTE
*Mem
=Current
->ScreenMem
+y
*Current
->ScanWidth
+x
;
809 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,
816 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,
825 * Write a horizontal span of pixels with a boolean mask. The current color
826 * is used for all pixels.
828 static void write_mono_rgba_span( const GLcontext
* ctx
,
829 GLuint n
, GLint x
, GLint y
,
830 const GLchan color
[4], const GLubyte mask
[])
834 assert(Current
->rgb_flag
==GL_TRUE
);
836 if(Current
->rgb_flag
==GL_TRUE
)
840 wmSetPixel(pwc
,y
,x
+i
,color
[RCOMP
], color
[GCOMP
], color
[BCOMP
]);
845 ULONG pixel
= RGB( color
[RCOMP
], color
[GCOMP
], color
[BCOMP
] );
848 SetPixel(DC
, y
, x
+i
, pixel
);
855 /**********************************************************************/
856 /***** Array-based pixel drawing *****/
857 /**********************************************************************/
860 /* Write an array of 32-bit index pixels with a boolean mask. */
861 static void write_ci32_pixels( const GLcontext
* ctx
,
862 GLuint n
, const GLint x
[], const GLint y
[],
863 const GLuint index
[], const GLubyte mask
[] )
866 assert(Current
->rgb_flag
==GL_FALSE
);
867 for (i
=0; i
<n
; i
++) {
869 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
];
878 * Write an array of pixels with a boolean mask. The current color
879 * index is used for all pixels.
881 static void write_mono_ci_pixels( const GLcontext
* ctx
,
883 const GLint x
[], const GLint y
[],
884 GLuint colorIndex
, const GLubyte mask
[] )
887 assert(Current
->rgb_flag
==GL_FALSE
);
888 for (i
=0; i
<n
; i
++) {
890 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
];
898 /* Write an array of RGBA pixels with a boolean mask. */
899 static void write_rgba_pixels( const GLcontext
* ctx
,
900 GLuint n
, const GLint x
[], const GLint y
[],
901 const GLubyte rgba
[][4], const GLubyte mask
[] )
906 assert(Current
->rgb_flag
==GL_TRUE
);
909 wmSetPixel(pwc
, FLIP(y
[i
]), x
[i
],
910 rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
917 * Write an array of pixels with a boolean mask. The current color
918 * is used for all pixels.
920 static void write_mono_rgba_pixels( const GLcontext
* ctx
,
922 const GLint x
[], const GLint y
[],
923 const GLchan color
[4],
924 const GLubyte mask
[] )
929 assert(Current
->rgb_flag
==GL_TRUE
);
932 wmSetPixel(pwc
, FLIP(y
[i
]),x
[i
],color
[RCOMP
],
933 color
[GCOMP
], color
[BCOMP
]);
939 /**********************************************************************/
940 /***** Read spans/arrays of pixels *****/
941 /**********************************************************************/
944 /* Read a horizontal span of color-index pixels. */
945 static void read_ci32_span( const GLcontext
* ctx
, GLuint n
, GLint x
, GLint y
,
949 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
950 assert(Current
->rgb_flag
==GL_FALSE
);
958 /* Read an array of color index pixels. */
959 static void read_ci32_pixels( const GLcontext
* ctx
,
960 GLuint n
, const GLint x
[], const GLint y
[],
961 GLuint indx
[], const GLubyte mask
[] )
964 assert(Current
->rgb_flag
==GL_FALSE
);
965 for (i
=0; i
<n
; i
++) {
967 indx
[i
]=*(Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
]);
974 /* Read a horizontal span of color pixels. */
975 static void read_rgba_span( const GLcontext
* ctx
,
976 GLuint n
, GLint x
, GLint y
,
982 assert(Current
->rgb_flag
==GL_TRUE
);
983 y
= Current
->height
- y
- 1;
984 for (i
=0; i
<n
; i
++) {
985 Color
=GetPixel(DC
,x
+i
,y
);
986 rgba
[i
][RCOMP
] = GetRValue(Color
);
987 rgba
[i
][GCOMP
] = GetGValue(Color
);
988 rgba
[i
][BCOMP
] = GetBValue(Color
);
989 rgba
[i
][ACOMP
] = 255;
995 /* Read an array of color pixels. */
996 static void read_rgba_pixels( const GLcontext
* ctx
,
997 GLuint n
, const GLint x
[], const GLint y
[],
998 GLubyte rgba
[][4], const GLubyte mask
[] )
1003 assert(Current
->rgb_flag
==GL_TRUE
);
1004 for (i
=0; i
<n
; i
++) {
1006 GLint y2
= Current
->height
- y
[i
] - 1;
1007 Color
=GetPixel(DC
,x
[i
],y2
);
1008 rgba
[i
][RCOMP
] = GetRValue(Color
);
1009 rgba
[i
][GCOMP
] = GetGValue(Color
);
1010 rgba
[i
][BCOMP
] = GetBValue(Color
);
1011 rgba
[i
][ACOMP
] = 255;
1019 /**********************************************************************/
1020 /**********************************************************************/
1023 static const GLubyte
*get_string(GLcontext
*ctx
, GLenum name
)
1025 if (name
== GL_RENDERER
) {
1026 return (GLubyte
*) "Mesa Windows";
1033 static void wmesa_update_state( GLcontext
*ctx
, GLuint new_state
);
1035 static void SetFunctionPointers(GLcontext
*ctx
)
1037 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference( ctx
);
1038 ctx
->Driver
.GetString
= get_string
;
1039 ctx
->Driver
.UpdateState
= wmesa_update_state
;
1040 ctx
->Driver
.ResizeBuffers
= _swrast_alloc_buffers
;
1041 ctx
->Driver
.GetBufferSize
= buffer_size
;
1043 ctx
->Driver
.Accum
= _swrast_Accum
;
1044 ctx
->Driver
.Bitmap
= _swrast_Bitmap
;
1045 ctx
->Driver
.Clear
= clear
;
1047 ctx
->Driver
.Flush
= flush
;
1048 ctx
->Driver
.ClearIndex
= clear_index
;
1049 ctx
->Driver
.ClearColor
= clear_color
;
1050 ctx
->Driver
.Enable
= enable
;
1052 ctx
->Driver
.CopyPixels
= _swrast_CopyPixels
;
1053 ctx
->Driver
.DrawPixels
= _swrast_DrawPixels
;
1054 ctx
->Driver
.ReadPixels
= _swrast_ReadPixels
;
1055 ctx
->Driver
.DrawBuffer
= _swrast_DrawBuffer
;
1057 ctx
->Driver
.ChooseTextureFormat
= _mesa_choose_tex_format
;
1058 ctx
->Driver
.TexImage1D
= _mesa_store_teximage1d
;
1059 ctx
->Driver
.TexImage2D
= _mesa_store_teximage2d
;
1060 ctx
->Driver
.TexImage3D
= _mesa_store_teximage3d
;
1061 ctx
->Driver
.TexSubImage1D
= _mesa_store_texsubimage1d
;
1062 ctx
->Driver
.TexSubImage2D
= _mesa_store_texsubimage2d
;
1063 ctx
->Driver
.TexSubImage3D
= _mesa_store_texsubimage3d
;
1064 ctx
->Driver
.TestProxyTexImage
= _mesa_test_proxy_teximage
;
1066 ctx
->Driver
.CompressedTexImage1D
= _mesa_store_compressed_teximage1d
;
1067 ctx
->Driver
.CompressedTexImage2D
= _mesa_store_compressed_teximage2d
;
1068 ctx
->Driver
.CompressedTexImage3D
= _mesa_store_compressed_teximage3d
;
1069 ctx
->Driver
.CompressedTexSubImage1D
= _mesa_store_compressed_texsubimage1d
;
1070 ctx
->Driver
.CompressedTexSubImage2D
= _mesa_store_compressed_texsubimage2d
;
1071 ctx
->Driver
.CompressedTexSubImage3D
= _mesa_store_compressed_texsubimage3d
;
1073 ctx
->Driver
.CopyTexImage1D
= _swrast_copy_teximage1d
;
1074 ctx
->Driver
.CopyTexImage2D
= _swrast_copy_teximage2d
;
1075 ctx
->Driver
.CopyTexSubImage1D
= _swrast_copy_texsubimage1d
;
1076 ctx
->Driver
.CopyTexSubImage2D
= _swrast_copy_texsubimage2d
;
1077 ctx
->Driver
.CopyTexSubImage3D
= _swrast_copy_texsubimage3d
;
1078 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1079 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1080 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1081 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;
1083 swdd
->SetBuffer
= set_buffer
;
1085 /* Pixel/span writing functions: */
1086 swdd
->WriteRGBASpan
= write_rgba_span
;
1087 swdd
->WriteRGBSpan
= write_rgb_span
;
1088 swdd
->WriteMonoRGBASpan
= write_mono_rgba_span
;
1089 swdd
->WriteRGBAPixels
= write_rgba_pixels
;
1090 swdd
->WriteMonoRGBAPixels
= write_mono_rgba_pixels
;
1091 swdd
->WriteCI32Span
= write_ci32_span
;
1092 swdd
->WriteCI8Span
= write_ci8_span
;
1093 swdd
->WriteMonoCISpan
= write_mono_ci_span
;
1094 swdd
->WriteCI32Pixels
= write_ci32_pixels
;
1095 swdd
->WriteMonoCIPixels
= write_mono_ci_pixels
;
1097 swdd
->ReadCI32Span
= read_ci32_span
;
1098 swdd
->ReadRGBASpan
= read_rgba_span
;
1099 swdd
->ReadCI32Pixels
= read_ci32_pixels
;
1100 swdd
->ReadRGBAPixels
= read_rgba_pixels
;
1104 static void wmesa_update_state( GLcontext
*ctx
, GLuint new_state
)
1106 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference( ctx
);
1107 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1110 * XXX these function pointers could be initialized just once during
1111 * context creation since they don't depend on any state changes.
1112 * kws - This is true - this function gets called a lot and it
1113 * would be good to minimize setting all this when not needed.
1115 #ifndef SET_FPOINTERS_ONCE
1116 SetFunctionPointers(ctx
);
1118 ctx
->Driver
.GetString
= get_string
;
1119 ctx
->Driver
.UpdateState
= wmesa_update_state
;
1120 ctx
->Driver
.ResizeBuffers
= _swrast_alloc_buffers
;
1121 ctx
->Driver
.GetBufferSize
= buffer_size
;
1123 ctx
->Driver
.Accum
= _swrast_Accum
;
1124 ctx
->Driver
.Bitmap
= _swrast_Bitmap
;
1125 ctx
->Driver
.Clear
= clear
;
1127 ctx
->Driver
.Flush
= flush
;
1128 ctx
->Driver
.ClearIndex
= clear_index
;
1129 ctx
->Driver
.ClearColor
= clear_color
;
1130 ctx
->Driver
.Enable
= enable
;
1132 ctx
->Driver
.CopyPixels
= _swrast_CopyPixels
;
1133 ctx
->Driver
.DrawPixels
= _swrast_DrawPixels
;
1134 ctx
->Driver
.ReadPixels
= _swrast_ReadPixels
;
1136 ctx
->Driver
.ChooseTextureFormat
= _mesa_choose_tex_format
;
1137 ctx
->Driver
.TexImage1D
= _mesa_store_teximage1d
;
1138 ctx
->Driver
.TexImage2D
= _mesa_store_teximage2d
;
1139 ctx
->Driver
.TexImage3D
= _mesa_store_teximage3d
;
1140 ctx
->Driver
.TexSubImage1D
= _mesa_store_texsubimage1d
;
1141 ctx
->Driver
.TexSubImage2D
= _mesa_store_texsubimage2d
;
1142 ctx
->Driver
.TexSubImage3D
= _mesa_store_texsubimage3d
;
1143 ctx
->Driver
.TestProxyTexImage
= _mesa_test_proxy_teximage
;
1145 ctx
->Driver
.CompressedTexImage1D
= _mesa_store_compressed_teximage1d
;
1146 ctx
->Driver
.CompressedTexImage2D
= _mesa_store_compressed_teximage2d
;
1147 ctx
->Driver
.CompressedTexImage3D
= _mesa_store_compressed_teximage3d
;
1148 ctx
->Driver
.CompressedTexSubImage1D
= _mesa_store_compressed_texsubimage1d
;
1149 ctx
->Driver
.CompressedTexSubImage2D
= _mesa_store_compressed_texsubimage2d
;
1150 ctx
->Driver
.CompressedTexSubImage3D
= _mesa_store_compressed_texsubimage3d
;
1152 ctx
->Driver
.CopyTexImage1D
= _swrast_copy_teximage1d
;
1153 ctx
->Driver
.CopyTexImage2D
= _swrast_copy_teximage2d
;
1154 ctx
->Driver
.CopyTexSubImage1D
= _swrast_copy_texsubimage1d
;
1155 ctx
->Driver
.CopyTexSubImage2D
= _swrast_copy_texsubimage2d
;
1156 ctx
->Driver
.CopyTexSubImage3D
= _swrast_copy_texsubimage3d
;
1157 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1158 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1159 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1160 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;
1162 swdd
->SetBuffer
= set_buffer
;
1164 /* Pixel/span writing functions: */
1165 swdd
->WriteRGBASpan
= write_rgba_span
;
1166 swdd
->WriteRGBSpan
= write_rgb_span
;
1167 swdd
->WriteMonoRGBASpan
= write_mono_rgba_span
;
1168 swdd
->WriteRGBAPixels
= write_rgba_pixels
;
1169 swdd
->WriteMonoRGBAPixels
= write_mono_rgba_pixels
;
1170 swdd
->WriteCI32Span
= write_ci32_span
;
1171 swdd
->WriteCI8Span
= write_ci8_span
;
1172 swdd
->WriteMonoCISpan
= write_mono_ci_span
;
1173 swdd
->WriteCI32Pixels
= write_ci32_pixels
;
1174 swdd
->WriteMonoCIPixels
= write_mono_ci_pixels
;
1176 swdd
->ReadCI32Span
= read_ci32_span
;
1177 swdd
->ReadRGBASpan
= read_rgba_span
;
1178 swdd
->ReadCI32Pixels
= read_ci32_pixels
;
1179 swdd
->ReadRGBAPixels
= read_rgba_pixels
;
1181 #endif // !SET_FPOINTERS_ONCE
1182 tnl
->Driver
.RunPipeline
= _tnl_run_pipeline
;
1184 _swrast_InvalidateState( ctx
, new_state
);
1185 _swsetup_InvalidateState( ctx
, new_state
);
1186 _ac_InvalidateState( ctx
, new_state
);
1187 _tnl_InvalidateState( ctx
, new_state
);
1193 /**********************************************************************/
1194 /***** WMesa API Functions *****/
1195 /**********************************************************************/
1199 #define PAL_SIZE 256
1200 static void GetPalette(HPALETTE Pal
,RGBQUAD
*aRGB
)
1207 WORD NumberOfEntries
;
1208 PALETTEENTRY aEntries
[PAL_SIZE
];
1216 GetPaletteEntries(Pal
,0,PAL_SIZE
,Palette
.aEntries
);
1218 GetSystemPaletteEntries(hdc
,0,PAL_SIZE
,Palette
.aEntries
);
1219 if (GetSystemPaletteUse(hdc
) == SYSPAL_NOSTATIC
)
1221 for(i
= 0; i
<PAL_SIZE
; i
++)
1222 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1223 Palette
.aEntries
[255].peRed
= 255;
1224 Palette
.aEntries
[255].peGreen
= 255;
1225 Palette
.aEntries
[255].peBlue
= 255;
1226 Palette
.aEntries
[255].peFlags
= 0;
1227 Palette
.aEntries
[0].peRed
= 0;
1228 Palette
.aEntries
[0].peGreen
= 0;
1229 Palette
.aEntries
[0].peBlue
= 0;
1230 Palette
.aEntries
[0].peFlags
= 0;
1236 nStaticColors
= GetDeviceCaps(hdc
, NUMCOLORS
)/2;
1237 for (i
=0; i
<nStaticColors
; i
++)
1238 Palette
.aEntries
[i
].peFlags
= 0;
1239 nUsableColors
= PAL_SIZE
-nStaticColors
;
1240 for (; i
<nUsableColors
; i
++)
1241 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1242 for (; i
<PAL_SIZE
-nStaticColors
; i
++)
1243 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1244 for (i
=PAL_SIZE
-nStaticColors
; i
<PAL_SIZE
; i
++)
1245 Palette
.aEntries
[i
].peFlags
= 0;
1247 ReleaseDC(NULL
,hdc
);
1248 for (i
=0; i
<PAL_SIZE
; i
++)
1250 aRGB
[i
].rgbRed
=Palette
.aEntries
[i
].peRed
;
1251 aRGB
[i
].rgbGreen
=Palette
.aEntries
[i
].peGreen
;
1252 aRGB
[i
].rgbBlue
=Palette
.aEntries
[i
].peBlue
;
1253 aRGB
[i
].rgbReserved
=Palette
.aEntries
[i
].peFlags
;
1258 WMesaContext
WMesaCreateContext( HWND hWnd
, HPALETTE
* Pal
,
1261 GLboolean alpha_flag
)
1265 GLboolean true_color_flag
;
1267 c
= (struct wmesa_context
* ) calloc(1,sizeof(struct wmesa_context
));
1272 c
->hDC
= GetDC(hWnd
);
1273 true_color_flag
= GetDeviceCaps(c
->hDC
, BITSPIXEL
) > 8;
1275 if(true_color_flag
) c
->rgb_flag
= rgb_flag
= GL_TRUE
;
1280 if ((true_color_flag
==GL_FALSE
) && (rgb_flag
== GL_TRUE
)){
1281 c
->dither_flag
= GL_TRUE
;
1283 c
->hPalHalfTone
= WinGCreateHalftonePalette();
1285 c
->hPalHalfTone
= CreateHalftonePalette(c
->hDC
);
1289 c
->dither_flag
= GL_FALSE
;
1291 c
->dither_flag
= GL_FALSE
;
1295 if (rgb_flag
==GL_FALSE
)
1297 c
->rgb_flag
= GL_FALSE
;
1299 /* Old WinG stuff???? */
1300 c
->db_flag
= db_flag
=GL_TRUE
; /* WinG requires double buffering */
1301 printf("Single buffer is not supported in color index mode, ",
1302 "setting to double buffer.\n");
1307 c
->rgb_flag
= GL_TRUE
;
1309 GetClientRect(c
->Window
,&CR
);
1311 c
->height
=CR
.bottom
;
1315 /* Double buffered */
1318 wmCreateBackingStore(c
, c
->width
, c
->height
);
1325 /* Single Buffered */
1330 if (DDInit(c
,hWnd
) == GL_FALSE
) {
1337 c
->gl_visual
= _mesa_create_visual(rgb_flag
,
1338 db_flag
, /* db_flag */
1339 GL_FALSE
, /* stereo */
1340 8,8,8, /* r, g, b bits */
1341 alpha_flag
? 8 : 0, /* alpha bits */
1343 16, /* depth_bits */
1344 8, /* stencil_bits */
1345 16,16,16,/* accum_bits */
1346 alpha_flag
? 16 : 0, /* alpha accum */
1349 if (!c
->gl_visual
) {
1353 /* allocate a new Mesa context */
1354 c
->gl_ctx
= _mesa_create_context( c
->gl_visual
, NULL
, (void *) c
, GL_FALSE
);
1357 _mesa_destroy_visual( c
->gl_visual
);
1362 _mesa_enable_sw_extensions(c
->gl_ctx
);
1363 _mesa_enable_1_3_extensions(c
->gl_ctx
);
1364 _mesa_enable_1_4_extensions(c
->gl_ctx
);
1366 c
->gl_buffer
= _mesa_create_framebuffer( c
->gl_visual
,
1367 c
->gl_visual
->depthBits
> 0,
1368 c
->gl_visual
->stencilBits
> 0,
1369 c
->gl_visual
->accumRedBits
> 0,
1370 alpha_flag
/* s/w alpha */ );
1371 if (!c
->gl_buffer
) {
1372 _mesa_destroy_visual( c
->gl_visual
);
1373 _mesa_free_context_data( c
->gl_ctx
);
1378 /* Initialize the software rasterizer and helper modules.
1381 GLcontext
*ctx
= c
->gl_ctx
;
1382 _swrast_CreateContext( ctx
);
1383 _ac_CreateContext( ctx
);
1384 _tnl_CreateContext( ctx
);
1385 _swsetup_CreateContext( ctx
);
1387 #ifdef SET_FPOINTERS_ONCE
1388 SetFunctionPointers(ctx
);
1389 #endif // SET_FPOINTERS_ONCE
1390 _swsetup_Wakeup( ctx
);
1392 #ifdef COMPILE_SETPIXEL
1398 void WMesaDestroyContext( void )
1400 WMesaContext c
= Current
;
1401 ReleaseDC(c
->Window
,c
->hDC
);
1403 if(c
->hPalHalfTone
!= NULL
)
1404 DeleteObject(c
->hPalHalfTone
);
1406 _swsetup_DestroyContext( c
->gl_ctx
);
1407 _tnl_DestroyContext( c
->gl_ctx
);
1408 _ac_DestroyContext( c
->gl_ctx
);
1409 _swrast_DestroyContext( c
->gl_ctx
);
1411 _mesa_destroy_visual( c
->gl_visual
);
1412 _mesa_destroy_framebuffer( c
->gl_buffer
);
1413 _mesa_free_context_data( c
->gl_ctx
);
1414 free( (void *) c
->gl_ctx
);
1420 wmDeleteBackingStore(c
);
1423 #if !defined(NO_PARALLEL)
1425 PRDestroyRenderBuffer();
1428 // Destroyed context no longer valid
1429 WMesaMakeCurrent( NULL
);
1433 void WMesaMakeCurrent( WMesaContext c
)
1444 wmesa_update_state(c
->gl_ctx
, 0);
1445 _mesa_make_current(c
->gl_ctx
, c
->gl_buffer
);
1446 if (Current
->gl_ctx
->Viewport
.Width
==0) {
1447 /* initialize viewport to window size */
1448 _mesa_Viewport( 0, 0, Current
->width
, Current
->height
);
1449 Current
->gl_ctx
->Scissor
.Width
= Current
->width
;
1450 Current
->gl_ctx
->Scissor
.Height
= Current
->height
;
1452 if ((c
->cColorBits
<= 8 ) && (c
->rgb_flag
== GL_TRUE
)){
1453 WMesaPaletteChange(c
->hPalHalfTone
);
1459 void WMesaSwapBuffers( void )
1461 HDC DC
= Current
->hDC
;
1462 GET_CURRENT_CONTEXT(ctx
);
1464 /* If we're swapping the buffer associated with the current context
1465 * we have to flush any pending rendering commands first.
1467 if (Current
&& Current
->gl_ctx
== ctx
)
1468 _mesa_notifySwapBuffers(ctx
);
1470 if (Current
->db_flag
)
1476 void WMesaPaletteChange(HPALETTE Pal
)
1481 LPPALETTEENTRY pPal
;
1482 if (Current
&& (Current
->rgb_flag
==GL_FALSE
||
1483 Current
->dither_flag
== GL_TRUE
))
1485 pPal
= (PALETTEENTRY
*)malloc( 256 * sizeof(PALETTEENTRY
));
1487 GetPaletteEntries( Pal
, 0, 256, pPal
);
1489 Current
->lpDD
->lpVtbl
->CreatePalette(Current
->lpDD
,DDPCAPS_8BIT
,
1490 pPal
, &(Current
->lpDDPal
), NULL
);
1491 if (Current
->lpDDPal
)
1492 Current
->lpDDSPrimary
->lpVtbl
->SetPalette(Current
->lpDDSPrimary
,
1495 vRet
= SetDIBColorTable(Current
->dib
.hDC
, 0, 256, (RGBQUAD
*)pPal
);
1504 static unsigned char threeto8
[8] = {
1505 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
1508 static unsigned char twoto8
[4] = {
1512 static unsigned char oneto8
[2] = {
1516 static unsigned char componentFromIndex(UCHAR i
, UINT nbits
, UINT shift
)
1533 return threeto8
[val
];
1540 void wmCreatePalette( PWMC pwdc
)
1542 /* Create a compressed and re-expanded 3:3:2 palette */
1545 BYTE rb
, rs
, gb
, gs
, bb
, bs
;
1547 pwdc
->nColors
= 0x100;
1549 pPal
= (PLOGPALETTE
)malloc(sizeof(LOGPALETTE
) +
1550 pwdc
->nColors
* sizeof(PALETTEENTRY
));
1551 memset( pPal
, 0, sizeof(LOGPALETTE
) + pwdc
->nColors
* sizeof(PALETTEENTRY
) );
1553 pPal
->palVersion
= 0x300;
1562 if (pwdc
->db_flag
) {
1564 /* Need to make two palettes: one for the screen DC and one for the DIB. */
1565 pPal
->palNumEntries
= pwdc
->nColors
;
1566 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1567 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1568 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1569 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1570 pPal
->palPalEntry
[i
].peFlags
= 0;
1572 pwdc
->hGLPalette
= CreatePalette( pPal
);
1573 pwdc
->hPalette
= CreatePalette( pPal
);
1577 pPal
->palNumEntries
= pwdc
->nColors
;
1578 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1579 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1580 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1581 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1582 pPal
->palPalEntry
[i
].peFlags
= 0;
1584 pwdc
->hGLPalette
= CreatePalette( pPal
);
1593 #ifdef COMPILE_SETPIXEL
1595 wmSetPixelDefault(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1597 if (Current
->db_flag
)
1601 Current
->lpDDSOffScreen
->lpVtbl
->Unlock(Current
->lpDDSOffScreen
,NULL
);
1602 Current
->lpDDSOffScreen
->lpVtbl
->GetDC(Current
->lpDDSOffScreen
,&hdc
);
1603 SetPixelV(hdc
,iPixel
, iScanLine
, RGB(r
,g
,b
));
1604 Current
->lpDDSOffScreen
->lpVtbl
->ReleaseDC(Current
->lpDDSOffScreen
,hdc
);
1605 while (Current
->lpDDSOffScreen
->lpVtbl
->Lock(Current
->lpDDSOffScreen
,NULL
, &(Current
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
);
1607 SetPixelV(Current
->hDC
, iPixel
, iScanLine
, RGB(r
,g
,b
));
1612 SetPixelV(Current
->hDC
, iPixel
+pwc
->rectSurface
.left
, pwc
->rectSurface
.top
+iScanLine
, RGB(r
,g
,b
));
1616 wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1618 if (Current
->db_flag
)
1620 LPBYTE lpb
= pwc
->pbPixels
;
1621 UINT nBypp
= pwc
->cColorBits
>> 3;
1623 lpb
+= pwc
->ScanWidth
* iScanLine
;
1624 lpb
+= iPixel
* nBypp
;
1628 if(pwc
->dither_flag
)
1629 *lpb
= DITHER_RGB_2_8BIT(r
,g
,b
,iScanLine
,iPixel
);
1634 *((LPWORD
)lpb
) = BGR16(r
,g
,b
);
1635 else if (nBypp
== 3)
1641 else if (nBypp
== 4)
1642 *((LPDWORD
)lpb
) = BGR32(r
,g
,b
);
1646 SetPixel(Current
->hDC
, iPixel
, iScanLine
, RGB(r
,g
,b
));
1650 #ifdef COMPILE_SETPIXEL
1651 void wmSetPixel4(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1653 LPDWORD lpdw
= ((LPDWORD
)(pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
)) + iPixel
;
1654 *lpdw
= BGR32(r
,g
,b
);
1655 // LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel + iPixel + iPixel;
1656 // *((LPDWORD)lpb) = BGR32(r,g,b);
1659 void wmSetPixel3(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1661 LPBYTE lpb
= pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
+ iPixel
+ iPixel
+ iPixel
;
1667 void wmSetPixel2(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1669 LPWORD lpw
= ((LPWORD
)(pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
)) + iPixel
;
1670 *lpw
= BGR16(r
,g
,b
);
1671 // LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel;
1672 // *((LPWORD)lpb) = BGR16(r,g,b);
1675 void wmSetPixel1(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1677 LPBYTE lpb
= pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
+ iPixel
;
1681 void wmSetPixel1Dither(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1683 LPBYTE lpb
= pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
+ iPixel
;
1684 *lpb
= DITHER_RGB_2_8BIT(r
,g
,b
,iScanLine
,iPixel
);
1688 void ChooseSetPixel(PWMC pwc
)
1690 UINT nBypp
= (pwc
) ? pwc
->cColorBits
>> 3 : 0;
1694 pwc
->wmSetPixel
= pwc
->dither_flag
? &wmSetPixel1Dither
: &wmSetPixel1
;
1697 pwc
->wmSetPixel
= &wmSetPixel2
;
1700 pwc
->wmSetPixel
= &wmSetPixel3
;
1703 pwc
->wmSetPixel
= &wmSetPixel4
;
1706 pwc
->wmSetPixel
= &wmSetPixelDefault
;
1713 void wmCreateDIBSection(
1715 PWMC pwc
, // handle of device context
1716 CONST BITMAPINFO
*pbmi
, // bitmap size, format, and color data
1717 UINT iUsage
// color data type indicator: RGB values or palette indices
1722 UINT nBypp
= pwc
->cColorBits
/ 8;
1725 dwScanWidth
= (((pwc
->ScanWidth
* nBypp
)+ 3) & ~3);
1727 pwc
->ScanWidth
=pwc
->pitch
= dwScanWidth
;
1730 pwc
->ScanWidth
= 2* pwc
->pitch
;
1732 dwSize
= sizeof(BITMAPINFO
) + (dwScanWidth
* pwc
->height
);
1733 #ifdef USE_MAPPED_FILE
1734 pwc
->dib
.hFileMap
= CreateFileMapping((HANDLE
)PAGE_FILE
,
1736 PAGE_READWRITE
| SEC_COMMIT
,
1741 if (!pwc
->dib
.hFileMap
)
1744 pwc
->dib
.base
= MapViewOfFile(pwc
->dib
.hFileMap
,
1745 FILE_MAP_ALL_ACCESS
,
1751 CloseHandle(pwc
->dib
.hFileMap
);
1756 CopyMemory(pwc
->dib
.base
, pbmi
, sizeof(BITMAPINFO
));
1757 #endif // USE_MAPPED_FILE
1759 hic
= CreateIC("display", NULL
, NULL
, NULL
);
1760 pwc
->dib
.hDC
= CreateCompatibleDC(hic
);
1762 #ifdef USE_MAPPED_FILE
1764 pwc
->hbmDIB
= CreateDIBSection(hic
,
1766 (iUsage
? DIB_PAL_COLORS
: DIB_RGB_COLORS
),
1771 pwc
->hbmDIB
= CreateDIBSection(hic
,
1773 (iUsage
? DIB_PAL_COLORS
: DIB_RGB_COLORS
),
1777 #endif // USE_MAPPED_FILE
1778 pwc
->ScreenMem
= pwc
->addrOffScreen
= pwc
->pbPixels
;
1779 pwc
->hOldBitmap
= SelectObject(pwc
->dib
.hDC
, pwc
->hbmDIB
);
1788 * Blit memory DC to screen DC
1790 BOOL
wmFlush(PWMC pwc
)
1800 if (pwc
->lpDDSOffScreen
== NULL
)
1801 if(DDCreateOffScreen(pwc
) == GL_FALSE
)
1804 pwc
->lpDDSOffScreen
->lpVtbl
->Unlock(pwc
->lpDDSOffScreen
, NULL
);
1808 ddrval
= pwc
->lpDDSPrimary
->lpVtbl
->Blt( pwc
->lpDDSPrimary
,
1809 &(pwc
->rectSurface
),
1810 pwc
->lpDDSOffScreen
,
1811 &(pwc
->rectOffScreen
),
1814 if( ddrval
== DD_OK
)
1818 if( ddrval
== DDERR_SURFACELOST
)
1820 if(!DDRestoreAll(pwc
))
1825 if( ddrval
!= DDERR_WASSTILLDRAWING
)
1831 while (pwc
->lpDDSOffScreen
->lpVtbl
->Lock(pwc
->lpDDSOffScreen
,
1832 NULL
, &(pwc
->ddsd
), 0, NULL
) ==
1833 DDERR_WASSTILLDRAWING
)
1837 dwErr
= GetLastError();
1839 bRet
= BitBlt(pwc
->hDC
, 0, 0, pwc
->width
, pwc
->height
,
1840 pwc
->dib
.hDC
, 0, 0, SRCCOPY
);
1849 /* The following code is added by Li Wei to enable stereo display */
1851 #if !defined(NO_STEREO)
1853 static void __gluMakeIdentityf(GLfloat m
[16])
1855 m
[0+4*0] = 1; m
[0+4*1] = 0; m
[0+4*2] = 0; m
[0+4*3] = 0;
1856 m
[1+4*0] = 0; m
[1+4*1] = 1; m
[1+4*2] = 0; m
[1+4*3] = 0;
1857 m
[2+4*0] = 0; m
[2+4*1] = 0; m
[2+4*2] = 1; m
[2+4*3] = 0;
1858 m
[3+4*0] = 0; m
[3+4*1] = 0; m
[3+4*2] = 0; m
[3+4*3] = 1;
1861 static void normalize(float v
[3])
1865 r
= sqrt( v
[0]*v
[0] + v
[1]*v
[1] + v
[2]*v
[2] );
1866 if (r
== 0.0) return;
1873 static void cross(float v1
[3], float v2
[3], float result
[3])
1875 result
[0] = v1
[1]*v2
[2] - v1
[2]*v2
[1];
1876 result
[1] = v1
[2]*v2
[0] - v1
[0]*v2
[2];
1877 result
[2] = v1
[0]*v2
[1] - v1
[1]*v2
[0];
1882 __gluLookAt(GLdouble eyex
, GLdouble eyey
, GLdouble eyez
, GLdouble centerx
,
1883 GLdouble centery
, GLdouble centerz
, GLdouble upx
, GLdouble upy
,
1887 float forward
[3], side
[3], up
[3];
1890 forward
[0] = centerx
- eyex
;
1891 forward
[1] = centery
- eyey
;
1892 forward
[2] = centerz
- eyez
;
1900 /* Side = forward x up */
1901 cross(forward
, up
, side
);
1904 /* Recompute up as: up = side x forward */
1905 cross(side
, forward
, up
);
1907 __gluMakeIdentityf(&m
[0][0]);
1916 m
[0][2] = -forward
[0];
1917 m
[1][2] = -forward
[1];
1918 m
[2][2] = -forward
[2];
1920 glMultMatrixf(&m
[0][0]);
1921 glTranslated(-eyex
, -eyey
, -eyez
);
1924 GLfloat viewDistance
= 1.0;
1926 void WMesaShowStereo(GLuint list
)
1929 GLbitfield mask
= GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
;
1932 /* Must use double Buffer */
1933 if( ! Current
-> db_flag
)
1937 glGetIntegerv(GL_MATRIX_MODE
,&matrix_mode
);
1939 WMesaViewport(Current
->gl_ctx
,0,Current
->height
/2,
1940 Current
->width
,Current
->height
/2);
1941 if(matrix_mode
!=GL_MODELVIEW
)
1942 glMatrixMode(GL_MODELVIEW
);
1944 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1946 __gluLookAt(viewDistance
/2,0.0,0.0 ,
1947 viewDistance
/2,0.0,-1.0,
1949 glMultMatrixf( cm
);
1951 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
;
1954 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1956 __gluLookAt(-viewDistance
/2,0.0,0.0 ,
1957 -viewDistance
/2,0.0,-1.0,
1961 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
+ Current
->pitch
;
1963 if(matrix_mode
!=GL_MODELVIEW
)
1964 glMatrixMode(matrix_mode
);
1968 WMesaViewport(Current
->gl_ctx
,0,0,Current
->width
,Current
->height
);
1972 void toggleStereoMode()
1974 if(!Current
->db_flag
)
1978 if(stereoBuffer
==GL_FALSE
)
1979 #if !defined(NO_PARALLEL)
1983 Current
->ScanWidth
= Current
->pitch
*2;
1988 #if !defined(NO_PARALLEL)
1991 Current
->ScanWidth
= Current
->pitch
;
1992 Current
->pbPixels
= Current
->addrOffScreen
;
1996 /* if in stereo mode, the following function is called */
1997 void glShowStereo(GLuint list
)
1999 WMesaShowStereo(list
);
2002 #endif /* NO_STEREO */
2004 #if !defined(NO_PARALLEL)
2006 void toggleParallelMode(void)
2009 parallelFlag
= GL_TRUE
;
2010 if(parallelMachine
==GL_FALSE
){
2011 PRCreateRenderBuffer( Current
->rgb_flag
? GL_RGBA
:GL_COLOR_INDEX
,
2012 Current
->cColorBits
/8,
2013 Current
->width
,Current
->height
,
2015 Current
->rgb_flag
? Current
->pbPixels
:
2016 Current
->ScreenMem
);
2017 parallelMachine
= GL_TRUE
;
2021 parallelFlag
= GL_FALSE
;
2022 if(parallelMachine
==GL_TRUE
){
2023 PRDestroyRenderBuffer();
2024 parallelMachine
=GL_FALSE
;
2025 ReadyForNextFrame
= GL_TRUE
;
2028 /***********************************************
2029 * Seems something wrong!!!!
2030 ************************************************/
2032 WMesaMakeCurrent(Current
);
2033 #if !defined(NO_STEREO)
2034 stereo_flag
= GL_FALSE
;
2039 void PRShowRenderResult(void)
2042 if(!glImageRendered())
2051 #endif /* NO_PARALLEL */
2053 BYTE
DITHER_RGB_2_8BIT( int red
, int green
, int blue
, int pixel
, int scanline
)
2055 char unsigned redtemp
, greentemp
, bluetemp
, paletteindex
;
2057 //*** now, look up each value in the halftone matrix
2058 //*** using an 8x8 ordered dither.
2059 redtemp
= aDividedBy51
[red
]
2060 + (aModulo51
[red
] > aHalftone8x8
[(pixel
%8)*8
2062 greentemp
= aDividedBy51
[(char unsigned)green
]
2063 + (aModulo51
[green
] > aHalftone8x8
[
2064 (pixel
%8)*8 + scanline
%8]);
2065 bluetemp
= aDividedBy51
[(char unsigned)blue
]
2066 + (aModulo51
[blue
] > aHalftone8x8
[
2067 (pixel
%8)*8 +scanline
%8]);
2069 //*** recombine the halftoned rgb values into a palette index
2071 redtemp
+ aTimes6
[greentemp
] + aTimes36
[bluetemp
];
2073 //*** and translate through the wing halftone palette
2074 //*** translation vector to give the correct value.
2075 return aWinGHalftoneTranslation
[paletteindex
];
2082 * restore all lost objects
2084 HRESULT
DDRestoreAll( WMesaContext wc
)
2088 ddrval
= wc
->lpDDSPrimary
->lpVtbl
->Restore(wc
->lpDDSPrimary
);
2089 if( ddrval
== DD_OK
)
2091 ddrval
= wc
->lpDDSOffScreen
->lpVtbl
->Restore(wc
->lpDDSOffScreen
);
2099 * This function is called if the initialization function fails
2101 BOOL
initFail( HWND hwnd
, WMesaContext wc
)
2104 MessageBox( hwnd
, "DirectDraw Init FAILED", "", MB_OK
);
2110 static void DDDeleteOffScreen(WMesaContext wc
)
2112 if( wc
->lpDDSOffScreen
!= NULL
)
2114 wc
->lpDDSOffScreen
->lpVtbl
->Unlock(wc
->lpDDSOffScreen
,NULL
);
2115 wc
->lpDDSOffScreen
->lpVtbl
->Release(wc
->lpDDSOffScreen
);
2116 wc
->lpDDSOffScreen
= NULL
;
2121 static void DDFreePrimarySurface(WMesaContext wc
)
2123 if( wc
->lpDDSPrimary
!= NULL
)
2125 if(wc
->db_flag
== GL_FALSE
)
2126 wc
->lpDDSPrimary
->lpVtbl
->ReleaseDC(wc
->lpDDSPrimary
, wc
->hDC
);
2127 wc
->lpDDSPrimary
->lpVtbl
->Release(wc
->lpDDSPrimary
);
2128 wc
->lpDDSPrimary
= NULL
;
2132 static BOOL
DDCreatePrimarySurface(WMesaContext wc
)
2136 wc
->ddsd
.dwSize
= sizeof( wc
->ddsd
);
2137 wc
->ddsd
.dwFlags
= DDSD_CAPS
;
2138 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2140 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
,&(wc
->ddsd
),
2141 &(wc
->lpDDSPrimary
), NULL
);
2142 if( ddrval
!= DD_OK
)
2144 return initFail(wc
->hwnd
, wc
);
2146 if(wc
->db_flag
== GL_FALSE
)
2147 wc
->lpDDSPrimary
->lpVtbl
->GetDC(wc
->lpDDSPrimary
, &(wc
->hDC
));
2151 static BOOL
DDCreateOffScreen(WMesaContext wc
)
2155 if(wc
->lpDD
== NULL
)
2157 GetClientRect( wc
->hwnd
, &(wc
->rectOffScreen
) );
2158 wc
->ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
2159 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
2160 wc
->ddsd
.dwHeight
= wc
->rectOffScreen
.bottom
- wc
->rectOffScreen
.top
;
2161 wc
->ddsd
.dwWidth
= wc
->rectOffScreen
.right
- wc
->rectOffScreen
.left
;
2163 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
, &(wc
->ddsd
),
2164 &(wc
->lpDDSOffScreen
), NULL
);
2165 if( ddrval
!= DD_OK
)
2170 while (wc
->lpDDSOffScreen
->lpVtbl
->Lock(wc
->lpDDSOffScreen
,NULL
,
2171 &(wc
->ddsd
), 0, NULL
) ==
2172 DDERR_WASSTILLDRAWING
)
2175 if(wc
->ddsd
.lpSurface
==NULL
)
2176 return initFail(wc
->hwnd
, wc
);
2178 wc
->ScreenMem
= wc
->pbPixels
= wc
->addrOffScreen
=
2179 (PBYTE
)(wc
->ddsd
.lpSurface
);
2180 wc
->ScanWidth
= wc
->pitch
= wc
->ddsd
.lPitch
;
2182 wc
->ScanWidth
= wc
->ddsd
.lPitch
*2;
2184 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2186 ClientToScreen( wc
->hwnd
, &pt
);
2187 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2188 wmSetPixelFormat(wc
, wc
->hDC
);
2193 struct tagWMesaContextList
2196 struct tagWMesaContextList
*next
;
2199 WMesaContextList
*head
= 0;
2201 void AddContext(WMesaContext wc
)
2203 WMesaContextList
*lst
= (WMesaContextList
*)malloc(sizeof(WMesaContextList
));
2210 WMesaContext
FindContext(HWND hWnd
)
2212 WMesaContextList
*tmp
= head
;
2215 if( tmp
->wc
->hwnd
== hWnd
)
2222 void RemoveContext(HWND hWnd
)
2224 WMesaContextList
*tmp
= head
;
2227 if( tmp
->wc
->hwnd
== hWnd
)
2229 WMesaContextList
*lst
= tmp
;
2237 if( tmp
->next
->wc
->hwnd
== hWnd
)
2239 WMesaContextList
*lst
= tmp
->next
;
2240 tmp
->next
= tmp
->next
->next
;
2248 static LRESULT CALLBACK
MyWndProc(HWND hwnd
,UINT message
,WPARAM wParam
, LPARAM lParam
)
2252 if (Current
==0 || Current
->hwnd
!= hwnd
)
2253 wc
=FindContext(hwnd
);
2260 LRESULT lret
= CallWindowProc((WNDPROC
)(wc
->oldWndProc
),hwnd
,message
,wParam
,lParam
);
2261 if( message
= WM_MOVE
)
2264 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2265 ClientToScreen( hwnd
, &pt
);
2266 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2274 * doInit - do work required for every instance of the application:
2275 * create the window, initialize data
2277 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
)
2280 // DWORD dwFrequency;
2282 // LPDIRECTDRAW lpDD; // DirectDraw object
2283 // LPDIRECTDRAW2 lpDD2;
2284 LPDIRECTDRAWCLIPPER pcClipper
= NULL
;
2286 wc
->fullScreen
= displayOptions
.fullScreen
;
2287 wc
->gMode
= displayOptions
.mode
;
2289 stereo_flag
= displayOptions
.stereo
;
2290 if(wc
->db_flag
!= GL_TRUE
)
2291 stereo_flag
= GL_FALSE
;
2293 * create the main DirectDraw object
2295 ddrval
= DirectDrawCreate( NULL
, &(wc
->lpDD
), NULL
);
2296 if( ddrval
!= DD_OK
)
2298 return initFail(hwnd
,wc
);
2301 // Get exclusive mode if requested
2304 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
,
2310 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
,
2313 if( ddrval
!= DD_OK
)
2315 return initFail(hwnd
, wc
);
2320 return initFail(hwnd
, wc
);
2326 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 640, 480,
2327 displayOptions
.bpp
);
2330 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 800, 600,
2331 displayOptions
.bpp
);
2334 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1024, 768,
2335 displayOptions
.bpp
);
2338 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1152, 864,
2339 displayOptions
.bpp
);
2342 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1280, 1024,
2343 displayOptions
.bpp
);
2347 if( ddrval
!= DD_OK
)
2349 printf("Can't modify display mode, current mode used\n");
2352 case DDERR_INVALIDOBJECT
:
2354 case DDERR_INVALIDPARAMS
:
2356 case DDERR_UNSUPPORTEDMODE
:
2360 if(DDCreatePrimarySurface(wc
) == GL_FALSE
)
2361 return initFail(hwnd
, wc
);
2364 DDCreateOffScreen(wc
);
2366 if( FAILED( ddrval
= wc
->lpDD
->lpVtbl
->CreateClipper(wc
->lpDD
, 0, &pcClipper
, NULL
) ) )
2369 if( FAILED( ddrval
= pcClipper
->lpVtbl
->SetHWnd(pcClipper
, 0, wc
->hwnd
) ) )
2371 pcClipper
->lpVtbl
->Release(pcClipper
);
2375 if( FAILED( ddrval
= wc
->lpDDSPrimary
->lpVtbl
->SetClipper(wc
->lpDDSPrimary
, pcClipper
) ) )
2377 pcClipper
->lpVtbl
->Release(pcClipper
);
2381 // Done with clipper
2382 pcClipper
->lpVtbl
->Release(pcClipper
);
2384 // Hook the window so we can update the drawing rectangle when the window moves
2385 wc
->oldWndProc
= SetWindowLong(wc
->hwnd
,GWL_WNDPROC
,(LONG
)MyWndProc
);
2391 static void DDFree( WMesaContext wc
)
2393 RemoveContext(wc
->hwnd
);
2394 SetWindowLong(wc
->hwnd
,GWL_WNDPROC
,(LONG
)(wc
->oldWndProc
));
2396 if( wc
->lpDD
!= NULL
)
2398 DDFreePrimarySurface(wc
);
2399 DDDeleteOffScreen(wc
);
2400 wc
->lpDD
->lpVtbl
->Release(wc
->lpDD
);
2403 // Clean up the screen on exit
2404 RedrawWindow( NULL
, NULL
, NULL
, RDW_INVALIDATE
| RDW_ERASE
|
2410 void WMesaMove(void)
2412 WMesaContext wc
= Current
;
2414 if (Current
!= NULL
){
2415 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2417 ClientToScreen( wc
->hwnd
, &pt
);
2418 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2423 /************************************************
2424 * Mesa 4.0 - These triangle rasterizers are not
2425 * implemented in this version of the Windows
2426 * driver. They could be implemented for a
2427 * potential performance improvement.
2428 * See OSMesa for an example of the approach
2430 * This old code is left in this file in case
2431 * it is useful. However, it may end up looking
2432 * a lot more like the OSMesa code.
2433 ************************************************/
2436 #if defined(FAST_RASTERIZERS)
2440 * Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable
2443 #define PACK_8B8G8R( R, G, B ) ( ((B) << 16) | ((G) << 8) | (R) )
2445 /**********************************************************************/
2446 /*** Triangle rendering ***/
2447 /**********************************************************************/
2450 * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
2452 static void smooth_8A8B8G8R_z_triangle( GLcontext
*ctx
,
2453 GLuint v0
, GLuint v1
, GLuint v2
,
2456 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2458 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
2459 #define INTERP_RGB 1
2460 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2461 #define PIXEL_TYPE GLuint
2462 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2463 #define BYTES_PER_ROW (wmesa->ScanWidth)
2464 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2466 GLint i, len = RIGHT-LEFT; \
2467 for (i=0;i<len;i++) { \
2468 GLdepth z = FixedToDepth(ffz); \
2469 if (z < zRow[i]) { \
2470 pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2471 FixedToInt(ffb) ); \
2474 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2480 #include "tritemp.h"
2484 // #include "..\tritemp.h"
2486 #include "tritemp.h"
2493 * XImage, smooth, depth-buffered, PF_8R8G8B triangle.
2495 static void smooth_8R8G8B_z_triangle( GLcontext
*ctx
,
2496 GLuint v0
, GLuint v1
, GLuint v2
,
2499 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2501 #define INTERP_RGB 1
2502 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2503 #define PIXEL_TYPE GLuint
2504 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2505 #define BYTES_PER_ROW (wmesa->ScanWidth)
2506 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2508 GLint i, len = RIGHT-LEFT; \
2509 for (i=0;i<len;i++) { \
2510 GLdepth z = FixedToDepth(ffz); \
2511 if (z < zRow[i]) { \
2512 pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2513 FixedToInt(ffb) ); \
2516 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2521 #include "tritemp.h"
2525 // #include "..\tritemp.h"
2527 #include "tritemp.h"
2535 * XImage, smooth, depth-buffered, PF_5R6G5B triangle.
2537 static void smooth_5R6G5B_z_triangle( GLcontext
*ctx
,
2538 GLuint v0
, GLuint v1
, GLuint v2
,
2541 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2543 #define INTERP_RGB 1
2544 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2545 #define PIXEL_TYPE GLushort
2546 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2547 #define BYTES_PER_ROW (wmesa->ScanWidth)
2548 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2550 GLint i, len = RIGHT-LEFT; \
2551 for (i=0;i<len;i++) { \
2552 GLdepth z = FixedToDepth(ffz); \
2553 if (z < zRow[i]) { \
2554 pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2555 FixedToInt(ffb) ); \
2558 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2563 #include "tritemp.h"
2567 // #include "..\tritemp.h"
2569 #include "tritemp.h"
2575 * XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
2577 static void flat_8A8B8G8R_z_triangle( GLcontext
*ctx
, GLuint v0
,
2578 GLuint v1
, GLuint v2
, GLuint pv
)
2580 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2582 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2583 #define PIXEL_TYPE GLuint
2584 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2585 #define BYTES_PER_ROW (wmesa->ScanWidth)
2586 #define SETUP_CODE \
2587 unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \
2588 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2589 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2591 GLint i, len = RIGHT-LEFT; \
2592 for (i=0;i<len;i++) { \
2593 GLdepth z = FixedToDepth(ffz); \
2594 if (z < zRow[i]) { \
2602 #include "tritemp.h"
2606 // #include "..\tritemp.h"
2608 #include "tritemp.h"
2615 * XImage, flat, depth-buffered, PF_8R8G8B triangle.
2617 static void flat_8R8G8B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2618 GLuint v2
, GLuint pv
)
2620 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2622 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2623 #define PIXEL_TYPE GLuint
2624 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2625 #define BYTES_PER_ROW (wmesa->ScanWidth)
2626 #define SETUP_CODE \
2627 unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \
2628 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2629 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2631 GLint i, len = RIGHT-LEFT; \
2632 for (i=0;i<len;i++) { \
2633 GLdepth z = FixedToDepth(ffz); \
2634 if (z < zRow[i]) { \
2642 #include "tritemp.h"
2646 // #include "..\tritemp.h"
2648 #include "tritemp.h"
2655 * XImage, flat, depth-buffered, PF_5R6G5B triangle.
2657 static void flat_5R6G5B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2658 GLuint v2
, GLuint pv
)
2660 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2662 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2663 #define PIXEL_TYPE GLushort
2664 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2665 #define BYTES_PER_ROW (wmesa->ScanWidth)
2666 #define SETUP_CODE \
2667 unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \
2668 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2669 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2671 GLint i, len = RIGHT-LEFT; \
2672 for (i=0;i<len;i++) { \
2673 GLdepth z = FixedToDepth(ffz); \
2674 if (z < zRow[i]) { \
2682 #include "tritemp.h"
2686 // #include "..\tritemp.h"
2688 #include "tritemp.h"
2695 * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
2697 static void smooth_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2698 GLuint v2
, GLuint pv
)
2700 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2701 #define INTERP_RGB 1
2702 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2703 #define PIXEL_TYPE GLuint
2704 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2705 #define BYTES_PER_ROW (wmesa->ScanWidth)
2706 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2709 PIXEL_TYPE *pixel = pRow; \
2710 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2711 *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2712 FixedToInt(ffb) ); \
2713 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2717 #include "tritemp.h"
2721 // #include "..\tritemp.h"
2723 #include "tritemp.h"
2730 * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
2732 static void smooth_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2733 GLuint v2
, GLuint pv
)
2735 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2736 #define INTERP_RGB 1
2737 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2738 #define PIXEL_TYPE GLuint
2739 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2740 #define BYTES_PER_ROW (wmesa->ScanWidth)
2741 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2744 PIXEL_TYPE *pixel = pRow; \
2745 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2746 *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2747 FixedToInt(ffb) ); \
2748 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2752 #include "tritemp.h"
2756 // #include "..\tritemp.h"
2758 #include "tritemp.h"
2765 * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
2767 static void smooth_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2768 GLuint v2
, GLuint pv
)
2770 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2771 #define INTERP_RGB 1
2772 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2773 #define PIXEL_TYPE GLushort
2774 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2775 #define BYTES_PER_ROW (wmesa->ScanWidth)
2776 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2779 PIXEL_TYPE *pixel = pRow; \
2780 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2781 *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2782 FixedToInt(ffb) ); \
2783 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2787 #include "tritemp.h"
2791 // #include "..\tritemp.h"
2793 #include "tritemp.h"
2801 * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
2803 static void flat_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
,
2804 GLuint v1
, GLuint v2
, GLuint pv
)
2806 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2807 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2808 #define PIXEL_TYPE GLuint
2809 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2810 #define BYTES_PER_ROW (wmesa->ScanWidth)
2811 #define SETUP_CODE \
2812 unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \
2813 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2814 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2817 PIXEL_TYPE *pixel = pRow; \
2818 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2824 #include "tritemp.h"
2828 // #include "..\tritemp.h"
2830 #include "tritemp.h"
2837 * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
2839 static void flat_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2840 GLuint v2
, GLuint pv
)
2842 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2843 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2844 #define PIXEL_TYPE GLuint
2845 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2846 #define BYTES_PER_ROW (wmesa->ScanWidth)
2847 #define SETUP_CODE \
2848 unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \
2849 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2850 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2853 PIXEL_TYPE *pixel = pRow; \
2854 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2859 #include "tritemp.h"
2863 // #include "..\tritemp.h"
2865 #include "tritemp.h"
2872 * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
2874 static void flat_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2875 GLuint v2
, GLuint pv
)
2877 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2878 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2879 #define PIXEL_TYPE GLushort
2880 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2881 #define BYTES_PER_ROW (wmesa->ScanWidth)
2882 #define SETUP_CODE \
2883 unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \
2884 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2885 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2888 PIXEL_TYPE *pixel = pRow; \
2889 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2894 #include "tritemp.h"
2898 // #include "..\tritemp.h"
2900 #include "tritemp.h"
2907 * XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
2910 static void smooth_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2911 GLuint v2
, GLuint pv
)
2913 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2915 #define INTERP_INDEX 1
2916 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2917 #define PIXEL_TYPE GLubyte
2918 #define BYTES_PER_ROW (wmesa->ScanWidth)
2919 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2921 GLint i, len = RIGHT-LEFT; \
2922 for (i=0;i<len;i++) { \
2923 GLdepth z = FixedToDepth(ffz); \
2924 if (z < zRow[i]) { \
2925 pRow[i] = FixedToInt(ffi); \
2933 #include "tritemp.h"
2937 // #include "..\tritemp.h"
2939 #include "tritemp.h"
2946 * XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
2949 static void flat_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2950 GLuint v2
, GLuint pv
)
2952 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2954 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2955 #define PIXEL_TYPE GLubyte
2956 #define BYTES_PER_ROW (wmesa->ScanWidth)
2957 #define SETUP_CODE \
2958 GLuint index = VB->IndexPtr->data[pv]; \
2959 (*ctx->Driver.Index)( ctx, index );
2960 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2962 GLint i, len = RIGHT-LEFT; \
2963 for (i=0;i<len;i++) { \
2964 GLdepth z = FixedToDepth(ffz); \
2965 if (z < zRow[i]) { \
2973 #include "tritemp.h"
2977 // #include "..\tritemp.h"
2979 #include "tritemp.h"
2987 * XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2990 static void smooth_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2991 GLuint v2
, GLuint pv
)
2993 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2995 #define INTERP_INDEX 1
2996 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2997 #define PIXEL_TYPE GLubyte
2998 #define BYTES_PER_ROW (wmesa->ScanWidth)
2999 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3002 PIXEL_TYPE *pixel = pRow; \
3003 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
3004 *pixel = FixedToInt(ffi); \
3009 #include "tritemp.h"
3013 // #include "..\tritemp.h"
3015 #include "tritemp.h"
3022 * XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
3024 static void flat_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
3025 GLuint v2
, GLuint pv
)
3027 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3029 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3030 #define PIXEL_TYPE GLubyte
3031 #define BYTES_PER_ROW (wmesa->ScanWidth)
3032 #define SETUP_CODE \
3033 GLuint index = VB->IndexPtr->data[pv]; \
3034 (*ctx->Driver.Index)( ctx, index );
3035 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3038 PIXEL_TYPE *pixel = pRow; \
3039 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
3044 #include "tritemp.h"
3048 // #include "..\tritemp.h"
3050 #include "tritemp.h"
3056 * XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
3058 static void smooth_DITHER8_z_triangle( GLcontext
*ctx
,
3059 GLuint v0
, GLuint v1
, GLuint v2
,
3062 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3063 DITHER_RGB_TO_8BIT_SETUP
3065 #define INTERP_RGB 1
3066 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3067 #define PIXEL_TYPE GLubyte
3068 #define BYTES_PER_ROW (wmesa->ScanWidth)
3069 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3071 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
3072 for (i=0;i<len;i++,xx++) { \
3073 GLdepth z = FixedToDepth(ffz); \
3074 if (z < zRow[i]) { \
3075 DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg), \
3076 FixedToInt(ffb), xx, yy); \
3077 pRow[i] = pixelDithered; \
3080 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
3085 #include "tritemp.h"
3089 // #include "..\tritemp.h"
3091 #include "tritemp.h"
3097 * XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
3099 static void flat_DITHER8_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
3100 GLuint v2
, GLuint pv
)
3102 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3103 DITHER_RGB_TO_8BIT_SETUP
3105 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3106 #define PIXEL_TYPE GLubyte
3107 #define BYTES_PER_ROW (wmesa->ScanWidth)
3109 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3111 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
3112 for (i=0;i<len;i++,xx++) { \
3113 GLdepth z = FixedToDepth(ffz); \
3114 if (z < zRow[i]) { \
3115 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \
3116 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \
3117 pRow[i] = pixelDithered; \
3124 #include "tritemp.h"
3128 // #include "..\tritemp.h"
3130 #include "tritemp.h"
3136 * XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
3138 static void smooth_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
3139 GLuint v2
, GLuint pv
)
3141 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3142 DITHER_RGB_TO_8BIT_SETUP
3143 #define INTERP_RGB 1
3144 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3145 #define PIXEL_TYPE GLubyte
3146 #define BYTES_PER_ROW (wmesa->ScanWidth)
3147 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3149 GLint xx, yy = FLIP(Y); \
3150 PIXEL_TYPE *pixel = pRow; \
3151 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
3152 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy);\
3153 *pixel = pixelDithered; \
3154 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
3158 #include "tritemp.h"
3162 // #include "..\tritemp.h"
3164 #include "tritemp.h"
3170 * XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
3173 static void flat_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
3174 GLuint v2
, GLuint pv
)
3176 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3177 DITHER_RGB_TO_8BIT_SETUP
3178 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3179 #define PIXEL_TYPE GLubyte
3180 #define BYTES_PER_ROW (wmesa->ScanWidth)
3182 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3184 GLint xx, yy = FLIP(Y); \
3185 PIXEL_TYPE *pixel = pRow; \
3186 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
3187 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \
3188 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \
3189 *pixel = pixelDithered; \
3193 #include "tritemp.h"
3197 // #include "..\tritemp.h"
3199 #include "tritemp.h"
3205 /************** END DEAD TRIANGLE CODE ***********************/
3207 static triangle_func
choose_triangle_function( GLcontext
*ctx
)
3210 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3211 int depth
= wmesa
->cColorBits
;
3213 if (ctx
->Polygon
.SmoothFlag
) return NULL
;
3214 if (ctx
->Texture
._EnabledUnits
) return NULL
;
3215 if (!wmesa
->db_flag
) return NULL
;
3216 if (ctx
->swrast
->_RasterMask
& MULTI_DRAW_BIT
) return NULL
;
3218 /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {
3219 if ( ctx
->Light
.ShadeModel
==GL_SMOOTH
3220 && ctx
->_RasterMask
==DEPTH_BIT
3221 && ctx
->Depth
.Func
==GL_LESS
3222 && ctx
->Depth
.Mask
==GL_TRUE
3223 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
3224 switch (wmesa
->pixelformat
) {
3226 return smooth_8A8B8G8R_z_triangle
;
3228 return smooth_8R8G8B_z_triangle
;
3230 return smooth_5R6G5B_z_triangle
;
3232 return smooth_DITHER8_z_triangle
;
3234 return smooth_ci_z_triangle
;
3239 if ( ctx
->Light
.ShadeModel
==GL_FLAT
3240 && ctx
->_RasterMask
==DEPTH_BIT
3241 && ctx
->Depth
.Func
==GL_LESS
3242 && ctx
->Depth
.Mask
==GL_TRUE
3243 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
3244 switch (wmesa
->pixelformat
) {
3246 return flat_8A8B8G8R_z_triangle
;
3248 return flat_8R8G8B_z_triangle
;
3250 return flat_5R6G5B_z_triangle
;
3252 return flat_DITHER8_z_triangle
;
3254 return flat_ci_z_triangle
;
3259 if ( ctx
->_RasterMask
==0 /* no depth test */
3260 && ctx
->Light
.ShadeModel
==GL_SMOOTH
3261 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
3262 switch (wmesa
->pixelformat
) {
3264 return smooth_8A8B8G8R_triangle
;
3266 return smooth_8R8G8B_triangle
;
3268 return smooth_5R6G5B_triangle
;
3270 return smooth_DITHER8_triangle
;
3272 return smooth_ci_triangle
;
3278 if ( ctx
->_RasterMask
==0 /* no depth test */
3279 && ctx
->Light
.ShadeModel
==GL_FLAT
3280 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
3281 switch (wmesa
->pixelformat
) {
3283 return flat_8A8B8G8R_triangle
;
3285 return flat_8R8G8B_triangle
;
3287 return flat_5R6G5B_triangle
;
3289 return flat_DITHER8_triangle
;
3291 return flat_ci_triangle
;
3303 * Define a new viewport and reallocate auxillary buffers if the size of
3304 * the window (color buffer) has changed.
3306 void WMesaViewport( GLcontext
*ctx
,
3307 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
3309 assert(0); /* I don't think that this is being used. */
3312 ctx
->Viewport
.X
= x
;
3313 ctx
->Viewport
.Width
= width
;
3314 ctx
->Viewport
.Y
= y
;
3315 ctx
->Viewport
.Height
= height
;
3317 /* compute scale and bias values */
3318 /* Pre-Keith 3.1 changes
3319 ctx->Viewport.Map.m[Sx] = (GLfloat) width / 2.0F;
3320 ctx->Viewport.Map.m[Tx] = ctx->Viewport.Sx + x;
3321 ctx->Viewport.Map.m[Sy] = (GLfloat) height / 2.0F;
3322 ctx->Viewport.Map.m[Ty] = ctx->Viewport.Sy + y;
3324 ctx
->Viewport
.WindowMap
.m
[MAT_SX
] = (GLfloat
) width
/ 2.0F
;
3325 ctx
->Viewport
.WindowMap
.m
[MAT_TX
] = ctx
->Viewport
.WindowMap
.m
[MAT_SX
] + x
;
3326 ctx
->Viewport
.WindowMap
.m
[MAT_SY
] = (GLfloat
) height
/ 2.0F
;
3327 ctx
->Viewport
.WindowMap
.m
[MAT_TY
] = ctx
->Viewport
.WindowMap
.m
[MAT_SY
] + y
;