3 * Windows (Win32) device driver for Mesa 3.4
7 * Copyright (C) 1996- Li Wei
8 * Address : Institute of Artificial Intelligence
10 * : Xi'an Jiaotong University
11 * Email : liwei@aiar.xjtu.edu.cn
12 * Web page : http://sun.aiar.xjtu.edu.cn
14 * This file and its associations are partially borrowed from the
15 * Windows NT driver for Mesa 1.8 , written by Mark Leaming
18 * Updated for Mesa 4.0 by Karl Schultz (kschultz@sourceforge.net)
22 #pragma auto_inline(on)
23 #pragma inline_depth(255)
24 #pragma inline_recursion(on)
29 //#include "mesa_extend.h"
37 #include "extensions.h"
42 #include "texformat.h"
45 #include "array_cache/acache.h"
46 #include "swrast/swrast.h"
47 #include "swrast_setup/swrast_setup.h"
48 #include "swrast/s_context.h"
49 #include "swrast/s_depth.h"
50 #include "swrast/s_lines.h"
51 #include "swrast/s_triangle.h"
52 #include "swrast/s_trispan.h"
54 #include "tnl/t_context.h"
55 #include "tnl/t_pipeline.h"
56 #include "drivers/common/driverfuncs.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( struct dd_function_table
*functions
)
1037 functions
->GetString
= get_string
;
1038 functions
->UpdateState
= wmesa_update_state
;
1039 functions
->ResizeBuffers
= _swrast_alloc_buffers
;
1040 functions
->GetBufferSize
= buffer_size
;
1042 functions
->Clear
= clear
;
1044 functions
->Flush
= flush
;
1045 functions
->ClearIndex
= clear_index
;
1046 functions
->ClearColor
= clear_color
;
1047 functions
->Enable
= enable
;
1051 static void SetSWrastPointers(GLcontext
*ctx
)
1053 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference( ctx
);
1054 swdd
->SetBuffer
= set_buffer
;
1056 /* Pixel/span writing functions: */
1057 swdd
->WriteRGBASpan
= write_rgba_span
;
1058 swdd
->WriteRGBSpan
= write_rgb_span
;
1059 swdd
->WriteMonoRGBASpan
= write_mono_rgba_span
;
1060 swdd
->WriteRGBAPixels
= write_rgba_pixels
;
1061 swdd
->WriteMonoRGBAPixels
= write_mono_rgba_pixels
;
1062 swdd
->WriteCI32Span
= write_ci32_span
;
1063 swdd
->WriteCI8Span
= write_ci8_span
;
1064 swdd
->WriteMonoCISpan
= write_mono_ci_span
;
1065 swdd
->WriteCI32Pixels
= write_ci32_pixels
;
1066 swdd
->WriteMonoCIPixels
= write_mono_ci_pixels
;
1068 swdd
->ReadCI32Span
= read_ci32_span
;
1069 swdd
->ReadRGBASpan
= read_rgba_span
;
1070 swdd
->ReadCI32Pixels
= read_ci32_pixels
;
1071 swdd
->ReadRGBAPixels
= read_rgba_pixels
;
1075 static void wmesa_update_state( GLcontext
*ctx
, GLuint new_state
)
1077 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference( ctx
);
1078 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1081 * XXX these function pointers could be initialized just once during
1082 * context creation since they don't depend on any state changes.
1083 * kws - This is true - this function gets called a lot and it
1084 * would be good to minimize setting all this when not needed.
1086 #ifndef SET_FPOINTERS_ONCE
1087 SetFunctionPointers(&ctx
->Driver
);
1088 SetSWrastPointers(ctx
);
1090 ctx
->Driver
.GetString
= get_string
;
1091 ctx
->Driver
.UpdateState
= wmesa_update_state
;
1092 ctx
->Driver
.ResizeBuffers
= _swrast_alloc_buffers
;
1093 ctx
->Driver
.GetBufferSize
= buffer_size
;
1095 ctx
->Driver
.Accum
= _swrast_Accum
;
1096 ctx
->Driver
.Bitmap
= _swrast_Bitmap
;
1097 ctx
->Driver
.Clear
= clear
;
1099 ctx
->Driver
.Flush
= flush
;
1100 ctx
->Driver
.ClearIndex
= clear_index
;
1101 ctx
->Driver
.ClearColor
= clear_color
;
1102 ctx
->Driver
.Enable
= enable
;
1104 ctx
->Driver
.CopyPixels
= _swrast_CopyPixels
;
1105 ctx
->Driver
.DrawPixels
= _swrast_DrawPixels
;
1106 ctx
->Driver
.ReadPixels
= _swrast_ReadPixels
;
1108 ctx
->Driver
.ChooseTextureFormat
= _mesa_choose_tex_format
;
1109 ctx
->Driver
.TexImage1D
= _mesa_store_teximage1d
;
1110 ctx
->Driver
.TexImage2D
= _mesa_store_teximage2d
;
1111 ctx
->Driver
.TexImage3D
= _mesa_store_teximage3d
;
1112 ctx
->Driver
.TexSubImage1D
= _mesa_store_texsubimage1d
;
1113 ctx
->Driver
.TexSubImage2D
= _mesa_store_texsubimage2d
;
1114 ctx
->Driver
.TexSubImage3D
= _mesa_store_texsubimage3d
;
1115 ctx
->Driver
.TestProxyTexImage
= _mesa_test_proxy_teximage
;
1117 ctx
->Driver
.CompressedTexImage1D
= _mesa_store_compressed_teximage1d
;
1118 ctx
->Driver
.CompressedTexImage2D
= _mesa_store_compressed_teximage2d
;
1119 ctx
->Driver
.CompressedTexImage3D
= _mesa_store_compressed_teximage3d
;
1120 ctx
->Driver
.CompressedTexSubImage1D
= _mesa_store_compressed_texsubimage1d
;
1121 ctx
->Driver
.CompressedTexSubImage2D
= _mesa_store_compressed_texsubimage2d
;
1122 ctx
->Driver
.CompressedTexSubImage3D
= _mesa_store_compressed_texsubimage3d
;
1124 ctx
->Driver
.CopyTexImage1D
= _swrast_copy_teximage1d
;
1125 ctx
->Driver
.CopyTexImage2D
= _swrast_copy_teximage2d
;
1126 ctx
->Driver
.CopyTexSubImage1D
= _swrast_copy_texsubimage1d
;
1127 ctx
->Driver
.CopyTexSubImage2D
= _swrast_copy_texsubimage2d
;
1128 ctx
->Driver
.CopyTexSubImage3D
= _swrast_copy_texsubimage3d
;
1129 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1130 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1131 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1132 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;
1134 swdd
->SetBuffer
= set_buffer
;
1136 /* Pixel/span writing functions: */
1137 swdd
->WriteRGBASpan
= write_rgba_span
;
1138 swdd
->WriteRGBSpan
= write_rgb_span
;
1139 swdd
->WriteMonoRGBASpan
= write_mono_rgba_span
;
1140 swdd
->WriteRGBAPixels
= write_rgba_pixels
;
1141 swdd
->WriteMonoRGBAPixels
= write_mono_rgba_pixels
;
1142 swdd
->WriteCI32Span
= write_ci32_span
;
1143 swdd
->WriteCI8Span
= write_ci8_span
;
1144 swdd
->WriteMonoCISpan
= write_mono_ci_span
;
1145 swdd
->WriteCI32Pixels
= write_ci32_pixels
;
1146 swdd
->WriteMonoCIPixels
= write_mono_ci_pixels
;
1148 swdd
->ReadCI32Span
= read_ci32_span
;
1149 swdd
->ReadRGBASpan
= read_rgba_span
;
1150 swdd
->ReadCI32Pixels
= read_ci32_pixels
;
1151 swdd
->ReadRGBAPixels
= read_rgba_pixels
;
1153 #endif // !SET_FPOINTERS_ONCE
1154 tnl
->Driver
.RunPipeline
= _tnl_run_pipeline
;
1156 _swrast_InvalidateState( ctx
, new_state
);
1157 _swsetup_InvalidateState( ctx
, new_state
);
1158 _ac_InvalidateState( ctx
, new_state
);
1159 _tnl_InvalidateState( ctx
, new_state
);
1165 /**********************************************************************/
1166 /***** WMesa API Functions *****/
1167 /**********************************************************************/
1171 #define PAL_SIZE 256
1172 static void GetPalette(HPALETTE Pal
,RGBQUAD
*aRGB
)
1179 WORD NumberOfEntries
;
1180 PALETTEENTRY aEntries
[PAL_SIZE
];
1188 GetPaletteEntries(Pal
,0,PAL_SIZE
,Palette
.aEntries
);
1190 GetSystemPaletteEntries(hdc
,0,PAL_SIZE
,Palette
.aEntries
);
1191 if (GetSystemPaletteUse(hdc
) == SYSPAL_NOSTATIC
)
1193 for(i
= 0; i
<PAL_SIZE
; i
++)
1194 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1195 Palette
.aEntries
[255].peRed
= 255;
1196 Palette
.aEntries
[255].peGreen
= 255;
1197 Palette
.aEntries
[255].peBlue
= 255;
1198 Palette
.aEntries
[255].peFlags
= 0;
1199 Palette
.aEntries
[0].peRed
= 0;
1200 Palette
.aEntries
[0].peGreen
= 0;
1201 Palette
.aEntries
[0].peBlue
= 0;
1202 Palette
.aEntries
[0].peFlags
= 0;
1208 nStaticColors
= GetDeviceCaps(hdc
, NUMCOLORS
)/2;
1209 for (i
=0; i
<nStaticColors
; i
++)
1210 Palette
.aEntries
[i
].peFlags
= 0;
1211 nUsableColors
= PAL_SIZE
-nStaticColors
;
1212 for (; i
<nUsableColors
; i
++)
1213 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1214 for (; i
<PAL_SIZE
-nStaticColors
; i
++)
1215 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1216 for (i
=PAL_SIZE
-nStaticColors
; i
<PAL_SIZE
; i
++)
1217 Palette
.aEntries
[i
].peFlags
= 0;
1219 ReleaseDC(NULL
,hdc
);
1220 for (i
=0; i
<PAL_SIZE
; i
++)
1222 aRGB
[i
].rgbRed
=Palette
.aEntries
[i
].peRed
;
1223 aRGB
[i
].rgbGreen
=Palette
.aEntries
[i
].peGreen
;
1224 aRGB
[i
].rgbBlue
=Palette
.aEntries
[i
].peBlue
;
1225 aRGB
[i
].rgbReserved
=Palette
.aEntries
[i
].peFlags
;
1230 WMesaContext
WMesaCreateContext( HWND hWnd
, HPALETTE
* Pal
,
1233 GLboolean alpha_flag
)
1237 GLboolean true_color_flag
;
1238 struct dd_function_table functions
;
1240 c
= (struct wmesa_context
* ) calloc(1,sizeof(struct wmesa_context
));
1245 c
->hDC
= GetDC(hWnd
);
1246 true_color_flag
= GetDeviceCaps(c
->hDC
, BITSPIXEL
) > 8;
1248 if(true_color_flag
) c
->rgb_flag
= rgb_flag
= GL_TRUE
;
1253 if ((true_color_flag
==GL_FALSE
) && (rgb_flag
== GL_TRUE
)){
1254 c
->dither_flag
= GL_TRUE
;
1256 c
->hPalHalfTone
= WinGCreateHalftonePalette();
1258 c
->hPalHalfTone
= CreateHalftonePalette(c
->hDC
);
1262 c
->dither_flag
= GL_FALSE
;
1264 c
->dither_flag
= GL_FALSE
;
1268 if (rgb_flag
==GL_FALSE
)
1270 c
->rgb_flag
= GL_FALSE
;
1272 /* Old WinG stuff???? */
1273 c
->db_flag
= db_flag
=GL_TRUE
; /* WinG requires double buffering */
1274 printf("Single buffer is not supported in color index mode, ",
1275 "setting to double buffer.\n");
1280 c
->rgb_flag
= GL_TRUE
;
1282 GetClientRect(c
->Window
,&CR
);
1284 c
->height
=CR
.bottom
;
1288 /* Double buffered */
1291 wmCreateBackingStore(c
, c
->width
, c
->height
);
1298 /* Single Buffered */
1303 if (DDInit(c
,hWnd
) == GL_FALSE
) {
1310 c
->gl_visual
= _mesa_create_visual(rgb_flag
,
1311 db_flag
, /* db_flag */
1312 GL_FALSE
, /* stereo */
1313 8,8,8, /* r, g, b bits */
1314 alpha_flag
? 8 : 0, /* alpha bits */
1316 16, /* depth_bits */
1317 8, /* stencil_bits */
1318 16,16,16,/* accum_bits */
1319 alpha_flag
? 16 : 0, /* alpha accum */
1322 if (!c
->gl_visual
) {
1326 _mesa_init_driver_functions(&functions
);
1327 SetFunctionPointers(&functions
);
1329 /* allocate a new Mesa context */
1330 c
->gl_ctx
= _mesa_create_context( c
->gl_visual
, NULL
,
1331 &functions
, (void *) c
);
1334 _mesa_destroy_visual( c
->gl_visual
);
1339 _mesa_enable_sw_extensions(c
->gl_ctx
);
1340 _mesa_enable_1_3_extensions(c
->gl_ctx
);
1341 _mesa_enable_1_4_extensions(c
->gl_ctx
);
1343 c
->gl_buffer
= _mesa_create_framebuffer( c
->gl_visual
,
1344 c
->gl_visual
->depthBits
> 0,
1345 c
->gl_visual
->stencilBits
> 0,
1346 c
->gl_visual
->accumRedBits
> 0,
1347 alpha_flag
/* s/w alpha */ );
1348 if (!c
->gl_buffer
) {
1349 _mesa_destroy_visual( c
->gl_visual
);
1350 _mesa_free_context_data( c
->gl_ctx
);
1355 /* Initialize the software rasterizer and helper modules.
1358 GLcontext
*ctx
= c
->gl_ctx
;
1359 _swrast_CreateContext( ctx
);
1360 _ac_CreateContext( ctx
);
1361 _tnl_CreateContext( ctx
);
1362 _swsetup_CreateContext( ctx
);
1364 #ifdef SET_FPOINTERS_ONCE
1365 /*SetFunctionPointers(ctx);*/
1366 SetSWrastPointers(ctx
);
1367 #endif // SET_FPOINTERS_ONCE
1368 _swsetup_Wakeup( ctx
);
1370 #ifdef COMPILE_SETPIXEL
1376 void WMesaDestroyContext( void )
1378 WMesaContext c
= Current
;
1379 ReleaseDC(c
->Window
,c
->hDC
);
1381 if(c
->hPalHalfTone
!= NULL
)
1382 DeleteObject(c
->hPalHalfTone
);
1384 _swsetup_DestroyContext( c
->gl_ctx
);
1385 _tnl_DestroyContext( c
->gl_ctx
);
1386 _ac_DestroyContext( c
->gl_ctx
);
1387 _swrast_DestroyContext( c
->gl_ctx
);
1389 _mesa_destroy_visual( c
->gl_visual
);
1390 _mesa_destroy_framebuffer( c
->gl_buffer
);
1391 _mesa_free_context_data( c
->gl_ctx
);
1392 free( (void *) c
->gl_ctx
);
1398 wmDeleteBackingStore(c
);
1401 #if !defined(NO_PARALLEL)
1403 PRDestroyRenderBuffer();
1406 // Destroyed context no longer valid
1407 WMesaMakeCurrent( NULL
);
1411 void WMesaMakeCurrent( WMesaContext c
)
1422 wmesa_update_state(c
->gl_ctx
, 0);
1423 _mesa_make_current(c
->gl_ctx
, c
->gl_buffer
);
1424 if (Current
->gl_ctx
->Viewport
.Width
==0) {
1425 /* initialize viewport to window size */
1426 _mesa_Viewport( 0, 0, Current
->width
, Current
->height
);
1427 Current
->gl_ctx
->Scissor
.Width
= Current
->width
;
1428 Current
->gl_ctx
->Scissor
.Height
= Current
->height
;
1430 if ((c
->cColorBits
<= 8 ) && (c
->rgb_flag
== GL_TRUE
)){
1431 WMesaPaletteChange(c
->hPalHalfTone
);
1437 void WMesaSwapBuffers( void )
1439 HDC DC
= Current
->hDC
;
1440 GET_CURRENT_CONTEXT(ctx
);
1442 /* If we're swapping the buffer associated with the current context
1443 * we have to flush any pending rendering commands first.
1445 if (Current
&& Current
->gl_ctx
== ctx
)
1446 _mesa_notifySwapBuffers(ctx
);
1448 if (Current
->db_flag
)
1454 void WMesaPaletteChange(HPALETTE Pal
)
1459 LPPALETTEENTRY pPal
;
1460 if (Current
&& (Current
->rgb_flag
==GL_FALSE
||
1461 Current
->dither_flag
== GL_TRUE
))
1463 pPal
= (PALETTEENTRY
*)malloc( 256 * sizeof(PALETTEENTRY
));
1465 GetPaletteEntries( Pal
, 0, 256, pPal
);
1467 Current
->lpDD
->lpVtbl
->CreatePalette(Current
->lpDD
,DDPCAPS_8BIT
,
1468 pPal
, &(Current
->lpDDPal
), NULL
);
1469 if (Current
->lpDDPal
)
1470 Current
->lpDDSPrimary
->lpVtbl
->SetPalette(Current
->lpDDSPrimary
,
1473 vRet
= SetDIBColorTable(Current
->dib
.hDC
, 0, 256, (RGBQUAD
*)pPal
);
1482 static unsigned char threeto8
[8] = {
1483 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
1486 static unsigned char twoto8
[4] = {
1490 static unsigned char oneto8
[2] = {
1494 static unsigned char componentFromIndex(UCHAR i
, UINT nbits
, UINT shift
)
1511 return threeto8
[val
];
1518 void wmCreatePalette( PWMC pwdc
)
1520 /* Create a compressed and re-expanded 3:3:2 palette */
1523 BYTE rb
, rs
, gb
, gs
, bb
, bs
;
1525 pwdc
->nColors
= 0x100;
1527 pPal
= (PLOGPALETTE
)malloc(sizeof(LOGPALETTE
) +
1528 pwdc
->nColors
* sizeof(PALETTEENTRY
));
1529 memset( pPal
, 0, sizeof(LOGPALETTE
) + pwdc
->nColors
* sizeof(PALETTEENTRY
) );
1531 pPal
->palVersion
= 0x300;
1540 if (pwdc
->db_flag
) {
1542 /* Need to make two palettes: one for the screen DC and one for the DIB. */
1543 pPal
->palNumEntries
= pwdc
->nColors
;
1544 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1545 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1546 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1547 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1548 pPal
->palPalEntry
[i
].peFlags
= 0;
1550 pwdc
->hGLPalette
= CreatePalette( pPal
);
1551 pwdc
->hPalette
= CreatePalette( pPal
);
1555 pPal
->palNumEntries
= pwdc
->nColors
;
1556 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1557 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1558 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1559 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1560 pPal
->palPalEntry
[i
].peFlags
= 0;
1562 pwdc
->hGLPalette
= CreatePalette( pPal
);
1571 #ifdef COMPILE_SETPIXEL
1573 wmSetPixelDefault(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1575 if (Current
->db_flag
)
1579 Current
->lpDDSOffScreen
->lpVtbl
->Unlock(Current
->lpDDSOffScreen
,NULL
);
1580 Current
->lpDDSOffScreen
->lpVtbl
->GetDC(Current
->lpDDSOffScreen
,&hdc
);
1581 SetPixelV(hdc
,iPixel
, iScanLine
, RGB(r
,g
,b
));
1582 Current
->lpDDSOffScreen
->lpVtbl
->ReleaseDC(Current
->lpDDSOffScreen
,hdc
);
1583 while (Current
->lpDDSOffScreen
->lpVtbl
->Lock(Current
->lpDDSOffScreen
,NULL
, &(Current
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
);
1585 SetPixelV(Current
->hDC
, iPixel
, iScanLine
, RGB(r
,g
,b
));
1590 SetPixelV(Current
->hDC
, iPixel
+pwc
->rectSurface
.left
, pwc
->rectSurface
.top
+iScanLine
, RGB(r
,g
,b
));
1594 wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1596 if (Current
->db_flag
)
1598 LPBYTE lpb
= pwc
->pbPixels
;
1599 UINT nBypp
= pwc
->cColorBits
>> 3;
1601 lpb
+= pwc
->ScanWidth
* iScanLine
;
1602 lpb
+= iPixel
* nBypp
;
1606 if(pwc
->dither_flag
)
1607 *lpb
= DITHER_RGB_2_8BIT(r
,g
,b
,iScanLine
,iPixel
);
1612 *((LPWORD
)lpb
) = BGR16(r
,g
,b
);
1613 else if (nBypp
== 3)
1619 else if (nBypp
== 4)
1620 *((LPDWORD
)lpb
) = BGR32(r
,g
,b
);
1624 SetPixel(Current
->hDC
, iPixel
, iScanLine
, RGB(r
,g
,b
));
1628 #ifdef COMPILE_SETPIXEL
1629 void wmSetPixel4(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1631 LPDWORD lpdw
= ((LPDWORD
)(pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
)) + iPixel
;
1632 *lpdw
= BGR32(r
,g
,b
);
1633 // LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel + iPixel + iPixel;
1634 // *((LPDWORD)lpb) = BGR32(r,g,b);
1637 void wmSetPixel3(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1639 LPBYTE lpb
= pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
+ iPixel
+ iPixel
+ iPixel
;
1645 void wmSetPixel2(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1647 LPWORD lpw
= ((LPWORD
)(pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
)) + iPixel
;
1648 *lpw
= BGR16(r
,g
,b
);
1649 // LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel;
1650 // *((LPWORD)lpb) = BGR16(r,g,b);
1653 void wmSetPixel1(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1655 LPBYTE lpb
= pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
+ iPixel
;
1659 void wmSetPixel1Dither(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1661 LPBYTE lpb
= pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
+ iPixel
;
1662 *lpb
= DITHER_RGB_2_8BIT(r
,g
,b
,iScanLine
,iPixel
);
1666 void ChooseSetPixel(PWMC pwc
)
1668 UINT nBypp
= (pwc
) ? pwc
->cColorBits
>> 3 : 0;
1672 pwc
->wmSetPixel
= pwc
->dither_flag
? &wmSetPixel1Dither
: &wmSetPixel1
;
1675 pwc
->wmSetPixel
= &wmSetPixel2
;
1678 pwc
->wmSetPixel
= &wmSetPixel3
;
1681 pwc
->wmSetPixel
= &wmSetPixel4
;
1684 pwc
->wmSetPixel
= &wmSetPixelDefault
;
1691 void wmCreateDIBSection(
1693 PWMC pwc
, // handle of device context
1694 CONST BITMAPINFO
*pbmi
, // bitmap size, format, and color data
1695 UINT iUsage
// color data type indicator: RGB values or palette indices
1700 UINT nBypp
= pwc
->cColorBits
/ 8;
1703 dwScanWidth
= (((pwc
->ScanWidth
* nBypp
)+ 3) & ~3);
1705 pwc
->ScanWidth
=pwc
->pitch
= dwScanWidth
;
1708 pwc
->ScanWidth
= 2* pwc
->pitch
;
1710 dwSize
= sizeof(BITMAPINFO
) + (dwScanWidth
* pwc
->height
);
1711 #ifdef USE_MAPPED_FILE
1712 pwc
->dib
.hFileMap
= CreateFileMapping((HANDLE
)PAGE_FILE
,
1714 PAGE_READWRITE
| SEC_COMMIT
,
1719 if (!pwc
->dib
.hFileMap
)
1722 pwc
->dib
.base
= MapViewOfFile(pwc
->dib
.hFileMap
,
1723 FILE_MAP_ALL_ACCESS
,
1729 CloseHandle(pwc
->dib
.hFileMap
);
1734 CopyMemory(pwc
->dib
.base
, pbmi
, sizeof(BITMAPINFO
));
1735 #endif // USE_MAPPED_FILE
1737 hic
= CreateIC("display", NULL
, NULL
, NULL
);
1738 pwc
->dib
.hDC
= CreateCompatibleDC(hic
);
1740 #ifdef USE_MAPPED_FILE
1742 pwc
->hbmDIB
= CreateDIBSection(hic
,
1744 (iUsage
? DIB_PAL_COLORS
: DIB_RGB_COLORS
),
1749 pwc
->hbmDIB
= CreateDIBSection(hic
,
1751 (iUsage
? DIB_PAL_COLORS
: DIB_RGB_COLORS
),
1755 #endif // USE_MAPPED_FILE
1756 pwc
->ScreenMem
= pwc
->addrOffScreen
= pwc
->pbPixels
;
1757 pwc
->hOldBitmap
= SelectObject(pwc
->dib
.hDC
, pwc
->hbmDIB
);
1766 * Blit memory DC to screen DC
1768 BOOL
wmFlush(PWMC pwc
)
1778 if (pwc
->lpDDSOffScreen
== NULL
)
1779 if(DDCreateOffScreen(pwc
) == GL_FALSE
)
1782 pwc
->lpDDSOffScreen
->lpVtbl
->Unlock(pwc
->lpDDSOffScreen
, NULL
);
1786 ddrval
= pwc
->lpDDSPrimary
->lpVtbl
->Blt( pwc
->lpDDSPrimary
,
1787 &(pwc
->rectSurface
),
1788 pwc
->lpDDSOffScreen
,
1789 &(pwc
->rectOffScreen
),
1792 if( ddrval
== DD_OK
)
1796 if( ddrval
== DDERR_SURFACELOST
)
1798 if(!DDRestoreAll(pwc
))
1803 if( ddrval
!= DDERR_WASSTILLDRAWING
)
1809 while (pwc
->lpDDSOffScreen
->lpVtbl
->Lock(pwc
->lpDDSOffScreen
,
1810 NULL
, &(pwc
->ddsd
), 0, NULL
) ==
1811 DDERR_WASSTILLDRAWING
)
1815 dwErr
= GetLastError();
1817 bRet
= BitBlt(pwc
->hDC
, 0, 0, pwc
->width
, pwc
->height
,
1818 pwc
->dib
.hDC
, 0, 0, SRCCOPY
);
1827 /* The following code is added by Li Wei to enable stereo display */
1829 #if !defined(NO_STEREO)
1831 static void __gluMakeIdentityf(GLfloat m
[16])
1833 m
[0+4*0] = 1; m
[0+4*1] = 0; m
[0+4*2] = 0; m
[0+4*3] = 0;
1834 m
[1+4*0] = 0; m
[1+4*1] = 1; m
[1+4*2] = 0; m
[1+4*3] = 0;
1835 m
[2+4*0] = 0; m
[2+4*1] = 0; m
[2+4*2] = 1; m
[2+4*3] = 0;
1836 m
[3+4*0] = 0; m
[3+4*1] = 0; m
[3+4*2] = 0; m
[3+4*3] = 1;
1839 static void normalize(float v
[3])
1843 r
= sqrt( v
[0]*v
[0] + v
[1]*v
[1] + v
[2]*v
[2] );
1844 if (r
== 0.0) return;
1851 static void cross(float v1
[3], float v2
[3], float result
[3])
1853 result
[0] = v1
[1]*v2
[2] - v1
[2]*v2
[1];
1854 result
[1] = v1
[2]*v2
[0] - v1
[0]*v2
[2];
1855 result
[2] = v1
[0]*v2
[1] - v1
[1]*v2
[0];
1860 __gluLookAt(GLdouble eyex
, GLdouble eyey
, GLdouble eyez
, GLdouble centerx
,
1861 GLdouble centery
, GLdouble centerz
, GLdouble upx
, GLdouble upy
,
1865 float forward
[3], side
[3], up
[3];
1868 forward
[0] = centerx
- eyex
;
1869 forward
[1] = centery
- eyey
;
1870 forward
[2] = centerz
- eyez
;
1878 /* Side = forward x up */
1879 cross(forward
, up
, side
);
1882 /* Recompute up as: up = side x forward */
1883 cross(side
, forward
, up
);
1885 __gluMakeIdentityf(&m
[0][0]);
1894 m
[0][2] = -forward
[0];
1895 m
[1][2] = -forward
[1];
1896 m
[2][2] = -forward
[2];
1898 glMultMatrixf(&m
[0][0]);
1899 glTranslated(-eyex
, -eyey
, -eyez
);
1902 GLfloat viewDistance
= 1.0;
1904 void WMesaShowStereo(GLuint list
)
1907 GLbitfield mask
= GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
;
1910 /* Must use double Buffer */
1911 if( ! Current
-> db_flag
)
1915 glGetIntegerv(GL_MATRIX_MODE
,&matrix_mode
);
1917 WMesaViewport(Current
->gl_ctx
,0,Current
->height
/2,
1918 Current
->width
,Current
->height
/2);
1919 if(matrix_mode
!=GL_MODELVIEW
)
1920 glMatrixMode(GL_MODELVIEW
);
1922 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1924 __gluLookAt(viewDistance
/2,0.0,0.0 ,
1925 viewDistance
/2,0.0,-1.0,
1927 glMultMatrixf( cm
);
1929 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
;
1932 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1934 __gluLookAt(-viewDistance
/2,0.0,0.0 ,
1935 -viewDistance
/2,0.0,-1.0,
1939 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
+ Current
->pitch
;
1941 if(matrix_mode
!=GL_MODELVIEW
)
1942 glMatrixMode(matrix_mode
);
1946 WMesaViewport(Current
->gl_ctx
,0,0,Current
->width
,Current
->height
);
1950 void toggleStereoMode()
1952 if(!Current
->db_flag
)
1956 if(stereoBuffer
==GL_FALSE
)
1957 #if !defined(NO_PARALLEL)
1961 Current
->ScanWidth
= Current
->pitch
*2;
1966 #if !defined(NO_PARALLEL)
1969 Current
->ScanWidth
= Current
->pitch
;
1970 Current
->pbPixels
= Current
->addrOffScreen
;
1974 /* if in stereo mode, the following function is called */
1975 void glShowStereo(GLuint list
)
1977 WMesaShowStereo(list
);
1980 #endif /* NO_STEREO */
1982 #if !defined(NO_PARALLEL)
1984 void toggleParallelMode(void)
1987 parallelFlag
= GL_TRUE
;
1988 if(parallelMachine
==GL_FALSE
){
1989 PRCreateRenderBuffer( Current
->rgb_flag
? GL_RGBA
:GL_COLOR_INDEX
,
1990 Current
->cColorBits
/8,
1991 Current
->width
,Current
->height
,
1993 Current
->rgb_flag
? Current
->pbPixels
:
1994 Current
->ScreenMem
);
1995 parallelMachine
= GL_TRUE
;
1999 parallelFlag
= GL_FALSE
;
2000 if(parallelMachine
==GL_TRUE
){
2001 PRDestroyRenderBuffer();
2002 parallelMachine
=GL_FALSE
;
2003 ReadyForNextFrame
= GL_TRUE
;
2006 /***********************************************
2007 * Seems something wrong!!!!
2008 ************************************************/
2010 WMesaMakeCurrent(Current
);
2011 #if !defined(NO_STEREO)
2012 stereo_flag
= GL_FALSE
;
2017 void PRShowRenderResult(void)
2020 if(!glImageRendered())
2029 #endif /* NO_PARALLEL */
2031 BYTE
DITHER_RGB_2_8BIT( int red
, int green
, int blue
, int pixel
, int scanline
)
2033 char unsigned redtemp
, greentemp
, bluetemp
, paletteindex
;
2035 //*** now, look up each value in the halftone matrix
2036 //*** using an 8x8 ordered dither.
2037 redtemp
= aDividedBy51
[red
]
2038 + (aModulo51
[red
] > aHalftone8x8
[(pixel
%8)*8
2040 greentemp
= aDividedBy51
[(char unsigned)green
]
2041 + (aModulo51
[green
] > aHalftone8x8
[
2042 (pixel
%8)*8 + scanline
%8]);
2043 bluetemp
= aDividedBy51
[(char unsigned)blue
]
2044 + (aModulo51
[blue
] > aHalftone8x8
[
2045 (pixel
%8)*8 +scanline
%8]);
2047 //*** recombine the halftoned rgb values into a palette index
2049 redtemp
+ aTimes6
[greentemp
] + aTimes36
[bluetemp
];
2051 //*** and translate through the wing halftone palette
2052 //*** translation vector to give the correct value.
2053 return aWinGHalftoneTranslation
[paletteindex
];
2060 * restore all lost objects
2062 HRESULT
DDRestoreAll( WMesaContext wc
)
2066 ddrval
= wc
->lpDDSPrimary
->lpVtbl
->Restore(wc
->lpDDSPrimary
);
2067 if( ddrval
== DD_OK
)
2069 ddrval
= wc
->lpDDSOffScreen
->lpVtbl
->Restore(wc
->lpDDSOffScreen
);
2077 * This function is called if the initialization function fails
2079 BOOL
initFail( HWND hwnd
, WMesaContext wc
)
2082 MessageBox( hwnd
, "DirectDraw Init FAILED", "", MB_OK
);
2088 static void DDDeleteOffScreen(WMesaContext wc
)
2090 if( wc
->lpDDSOffScreen
!= NULL
)
2092 wc
->lpDDSOffScreen
->lpVtbl
->Unlock(wc
->lpDDSOffScreen
,NULL
);
2093 wc
->lpDDSOffScreen
->lpVtbl
->Release(wc
->lpDDSOffScreen
);
2094 wc
->lpDDSOffScreen
= NULL
;
2099 static void DDFreePrimarySurface(WMesaContext wc
)
2101 if( wc
->lpDDSPrimary
!= NULL
)
2103 if(wc
->db_flag
== GL_FALSE
)
2104 wc
->lpDDSPrimary
->lpVtbl
->ReleaseDC(wc
->lpDDSPrimary
, wc
->hDC
);
2105 wc
->lpDDSPrimary
->lpVtbl
->Release(wc
->lpDDSPrimary
);
2106 wc
->lpDDSPrimary
= NULL
;
2110 static BOOL
DDCreatePrimarySurface(WMesaContext wc
)
2114 wc
->ddsd
.dwSize
= sizeof( wc
->ddsd
);
2115 wc
->ddsd
.dwFlags
= DDSD_CAPS
;
2116 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2118 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
,&(wc
->ddsd
),
2119 &(wc
->lpDDSPrimary
), NULL
);
2120 if( ddrval
!= DD_OK
)
2122 return initFail(wc
->hwnd
, wc
);
2124 if(wc
->db_flag
== GL_FALSE
)
2125 wc
->lpDDSPrimary
->lpVtbl
->GetDC(wc
->lpDDSPrimary
, &(wc
->hDC
));
2129 static BOOL
DDCreateOffScreen(WMesaContext wc
)
2133 if(wc
->lpDD
== NULL
)
2135 GetClientRect( wc
->hwnd
, &(wc
->rectOffScreen
) );
2136 wc
->ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
2137 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
2138 wc
->ddsd
.dwHeight
= wc
->rectOffScreen
.bottom
- wc
->rectOffScreen
.top
;
2139 wc
->ddsd
.dwWidth
= wc
->rectOffScreen
.right
- wc
->rectOffScreen
.left
;
2141 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
, &(wc
->ddsd
),
2142 &(wc
->lpDDSOffScreen
), NULL
);
2143 if( ddrval
!= DD_OK
)
2148 while (wc
->lpDDSOffScreen
->lpVtbl
->Lock(wc
->lpDDSOffScreen
,NULL
,
2149 &(wc
->ddsd
), 0, NULL
) ==
2150 DDERR_WASSTILLDRAWING
)
2153 if(wc
->ddsd
.lpSurface
==NULL
)
2154 return initFail(wc
->hwnd
, wc
);
2156 wc
->ScreenMem
= wc
->pbPixels
= wc
->addrOffScreen
=
2157 (PBYTE
)(wc
->ddsd
.lpSurface
);
2158 wc
->ScanWidth
= wc
->pitch
= wc
->ddsd
.lPitch
;
2160 wc
->ScanWidth
= wc
->ddsd
.lPitch
*2;
2162 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2164 ClientToScreen( wc
->hwnd
, &pt
);
2165 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2166 wmSetPixelFormat(wc
, wc
->hDC
);
2171 struct tagWMesaContextList
2174 struct tagWMesaContextList
*next
;
2177 WMesaContextList
*head
= 0;
2179 void AddContext(WMesaContext wc
)
2181 WMesaContextList
*lst
= (WMesaContextList
*)malloc(sizeof(WMesaContextList
));
2188 WMesaContext
FindContext(HWND hWnd
)
2190 WMesaContextList
*tmp
= head
;
2193 if( tmp
->wc
->hwnd
== hWnd
)
2200 void RemoveContext(HWND hWnd
)
2202 WMesaContextList
*tmp
= head
;
2205 if( tmp
->wc
->hwnd
== hWnd
)
2207 WMesaContextList
*lst
= tmp
;
2215 if( tmp
->next
->wc
->hwnd
== hWnd
)
2217 WMesaContextList
*lst
= tmp
->next
;
2218 tmp
->next
= tmp
->next
->next
;
2226 static LRESULT CALLBACK
MyWndProc(HWND hwnd
,UINT message
,WPARAM wParam
, LPARAM lParam
)
2230 if (Current
==0 || Current
->hwnd
!= hwnd
)
2231 wc
=FindContext(hwnd
);
2238 LRESULT lret
= CallWindowProc((WNDPROC
)(wc
->oldWndProc
),hwnd
,message
,wParam
,lParam
);
2239 if( message
= WM_MOVE
)
2242 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2243 ClientToScreen( hwnd
, &pt
);
2244 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2252 * doInit - do work required for every instance of the application:
2253 * create the window, initialize data
2255 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
)
2258 // DWORD dwFrequency;
2260 // LPDIRECTDRAW lpDD; // DirectDraw object
2261 // LPDIRECTDRAW2 lpDD2;
2262 LPDIRECTDRAWCLIPPER pcClipper
= NULL
;
2264 wc
->fullScreen
= displayOptions
.fullScreen
;
2265 wc
->gMode
= displayOptions
.mode
;
2267 stereo_flag
= displayOptions
.stereo
;
2268 if(wc
->db_flag
!= GL_TRUE
)
2269 stereo_flag
= GL_FALSE
;
2271 * create the main DirectDraw object
2273 ddrval
= DirectDrawCreate( NULL
, &(wc
->lpDD
), NULL
);
2274 if( ddrval
!= DD_OK
)
2276 return initFail(hwnd
,wc
);
2279 // Get exclusive mode if requested
2282 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
,
2288 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
,
2291 if( ddrval
!= DD_OK
)
2293 return initFail(hwnd
, wc
);
2298 return initFail(hwnd
, wc
);
2304 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 640, 480,
2305 displayOptions
.bpp
);
2308 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 800, 600,
2309 displayOptions
.bpp
);
2312 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1024, 768,
2313 displayOptions
.bpp
);
2316 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1152, 864,
2317 displayOptions
.bpp
);
2320 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1280, 1024,
2321 displayOptions
.bpp
);
2325 if( ddrval
!= DD_OK
)
2327 printf("Can't modify display mode, current mode used\n");
2330 case DDERR_INVALIDOBJECT
:
2332 case DDERR_INVALIDPARAMS
:
2334 case DDERR_UNSUPPORTEDMODE
:
2338 if(DDCreatePrimarySurface(wc
) == GL_FALSE
)
2339 return initFail(hwnd
, wc
);
2342 DDCreateOffScreen(wc
);
2344 if( FAILED( ddrval
= wc
->lpDD
->lpVtbl
->CreateClipper(wc
->lpDD
, 0, &pcClipper
, NULL
) ) )
2347 if( FAILED( ddrval
= pcClipper
->lpVtbl
->SetHWnd(pcClipper
, 0, wc
->hwnd
) ) )
2349 pcClipper
->lpVtbl
->Release(pcClipper
);
2353 if( FAILED( ddrval
= wc
->lpDDSPrimary
->lpVtbl
->SetClipper(wc
->lpDDSPrimary
, pcClipper
) ) )
2355 pcClipper
->lpVtbl
->Release(pcClipper
);
2359 // Done with clipper
2360 pcClipper
->lpVtbl
->Release(pcClipper
);
2362 // Hook the window so we can update the drawing rectangle when the window moves
2363 wc
->oldWndProc
= SetWindowLong(wc
->hwnd
,GWL_WNDPROC
,(LONG
)MyWndProc
);
2369 static void DDFree( WMesaContext wc
)
2371 RemoveContext(wc
->hwnd
);
2372 SetWindowLong(wc
->hwnd
,GWL_WNDPROC
,(LONG
)(wc
->oldWndProc
));
2374 if( wc
->lpDD
!= NULL
)
2376 DDFreePrimarySurface(wc
);
2377 DDDeleteOffScreen(wc
);
2378 wc
->lpDD
->lpVtbl
->Release(wc
->lpDD
);
2381 // Clean up the screen on exit
2382 RedrawWindow( NULL
, NULL
, NULL
, RDW_INVALIDATE
| RDW_ERASE
|
2388 void WMesaMove(void)
2390 WMesaContext wc
= Current
;
2392 if (Current
!= NULL
){
2393 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2395 ClientToScreen( wc
->hwnd
, &pt
);
2396 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2401 /************************************************
2402 * Mesa 4.0 - These triangle rasterizers are not
2403 * implemented in this version of the Windows
2404 * driver. They could be implemented for a
2405 * potential performance improvement.
2406 * See OSMesa for an example of the approach
2408 * This old code is left in this file in case
2409 * it is useful. However, it may end up looking
2410 * a lot more like the OSMesa code.
2411 ************************************************/
2414 #if defined(FAST_RASTERIZERS)
2418 * Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable
2421 #define PACK_8B8G8R( R, G, B ) ( ((B) << 16) | ((G) << 8) | (R) )
2423 /**********************************************************************/
2424 /*** Triangle rendering ***/
2425 /**********************************************************************/
2428 * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
2430 static void smooth_8A8B8G8R_z_triangle( GLcontext
*ctx
,
2431 GLuint v0
, GLuint v1
, GLuint v2
,
2434 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2436 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
2437 #define INTERP_RGB 1
2438 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2439 #define PIXEL_TYPE GLuint
2440 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2441 #define BYTES_PER_ROW (wmesa->ScanWidth)
2442 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2444 GLint i, len = RIGHT-LEFT; \
2445 for (i=0;i<len;i++) { \
2446 GLdepth z = FixedToDepth(ffz); \
2447 if (z < zRow[i]) { \
2448 pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2449 FixedToInt(ffb) ); \
2452 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2458 #include "tritemp.h"
2462 // #include "..\tritemp.h"
2464 #include "tritemp.h"
2471 * XImage, smooth, depth-buffered, PF_8R8G8B triangle.
2473 static void smooth_8R8G8B_z_triangle( GLcontext
*ctx
,
2474 GLuint v0
, GLuint v1
, GLuint v2
,
2477 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2479 #define INTERP_RGB 1
2480 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2481 #define PIXEL_TYPE GLuint
2482 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2483 #define BYTES_PER_ROW (wmesa->ScanWidth)
2484 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2486 GLint i, len = RIGHT-LEFT; \
2487 for (i=0;i<len;i++) { \
2488 GLdepth z = FixedToDepth(ffz); \
2489 if (z < zRow[i]) { \
2490 pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2491 FixedToInt(ffb) ); \
2494 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2499 #include "tritemp.h"
2503 // #include "..\tritemp.h"
2505 #include "tritemp.h"
2513 * XImage, smooth, depth-buffered, PF_5R6G5B triangle.
2515 static void smooth_5R6G5B_z_triangle( GLcontext
*ctx
,
2516 GLuint v0
, GLuint v1
, GLuint v2
,
2519 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2521 #define INTERP_RGB 1
2522 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2523 #define PIXEL_TYPE GLushort
2524 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2525 #define BYTES_PER_ROW (wmesa->ScanWidth)
2526 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2528 GLint i, len = RIGHT-LEFT; \
2529 for (i=0;i<len;i++) { \
2530 GLdepth z = FixedToDepth(ffz); \
2531 if (z < zRow[i]) { \
2532 pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2533 FixedToInt(ffb) ); \
2536 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2541 #include "tritemp.h"
2545 // #include "..\tritemp.h"
2547 #include "tritemp.h"
2553 * XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
2555 static void flat_8A8B8G8R_z_triangle( GLcontext
*ctx
, GLuint v0
,
2556 GLuint v1
, GLuint v2
, GLuint pv
)
2558 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2560 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2561 #define PIXEL_TYPE GLuint
2562 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2563 #define BYTES_PER_ROW (wmesa->ScanWidth)
2564 #define SETUP_CODE \
2565 unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \
2566 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2567 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2569 GLint i, len = RIGHT-LEFT; \
2570 for (i=0;i<len;i++) { \
2571 GLdepth z = FixedToDepth(ffz); \
2572 if (z < zRow[i]) { \
2580 #include "tritemp.h"
2584 // #include "..\tritemp.h"
2586 #include "tritemp.h"
2593 * XImage, flat, depth-buffered, PF_8R8G8B triangle.
2595 static void flat_8R8G8B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2596 GLuint v2
, GLuint pv
)
2598 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2600 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2601 #define PIXEL_TYPE GLuint
2602 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2603 #define BYTES_PER_ROW (wmesa->ScanWidth)
2604 #define SETUP_CODE \
2605 unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \
2606 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2607 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2609 GLint i, len = RIGHT-LEFT; \
2610 for (i=0;i<len;i++) { \
2611 GLdepth z = FixedToDepth(ffz); \
2612 if (z < zRow[i]) { \
2620 #include "tritemp.h"
2624 // #include "..\tritemp.h"
2626 #include "tritemp.h"
2633 * XImage, flat, depth-buffered, PF_5R6G5B triangle.
2635 static void flat_5R6G5B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2636 GLuint v2
, GLuint pv
)
2638 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2640 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2641 #define PIXEL_TYPE GLushort
2642 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2643 #define BYTES_PER_ROW (wmesa->ScanWidth)
2644 #define SETUP_CODE \
2645 unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \
2646 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2647 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2649 GLint i, len = RIGHT-LEFT; \
2650 for (i=0;i<len;i++) { \
2651 GLdepth z = FixedToDepth(ffz); \
2652 if (z < zRow[i]) { \
2660 #include "tritemp.h"
2664 // #include "..\tritemp.h"
2666 #include "tritemp.h"
2673 * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
2675 static void smooth_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2676 GLuint v2
, GLuint pv
)
2678 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2679 #define INTERP_RGB 1
2680 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2681 #define PIXEL_TYPE GLuint
2682 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2683 #define BYTES_PER_ROW (wmesa->ScanWidth)
2684 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2687 PIXEL_TYPE *pixel = pRow; \
2688 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2689 *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2690 FixedToInt(ffb) ); \
2691 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2695 #include "tritemp.h"
2699 // #include "..\tritemp.h"
2701 #include "tritemp.h"
2708 * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
2710 static void smooth_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2711 GLuint v2
, GLuint pv
)
2713 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2714 #define INTERP_RGB 1
2715 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2716 #define PIXEL_TYPE GLuint
2717 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2718 #define BYTES_PER_ROW (wmesa->ScanWidth)
2719 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2722 PIXEL_TYPE *pixel = pRow; \
2723 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2724 *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2725 FixedToInt(ffb) ); \
2726 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2730 #include "tritemp.h"
2734 // #include "..\tritemp.h"
2736 #include "tritemp.h"
2743 * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
2745 static void smooth_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2746 GLuint v2
, GLuint pv
)
2748 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2749 #define INTERP_RGB 1
2750 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2751 #define PIXEL_TYPE GLushort
2752 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2753 #define BYTES_PER_ROW (wmesa->ScanWidth)
2754 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2757 PIXEL_TYPE *pixel = pRow; \
2758 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2759 *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2760 FixedToInt(ffb) ); \
2761 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2765 #include "tritemp.h"
2769 // #include "..\tritemp.h"
2771 #include "tritemp.h"
2779 * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
2781 static void flat_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
,
2782 GLuint v1
, GLuint v2
, GLuint pv
)
2784 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2785 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2786 #define PIXEL_TYPE GLuint
2787 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2788 #define BYTES_PER_ROW (wmesa->ScanWidth)
2789 #define SETUP_CODE \
2790 unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \
2791 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2792 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2795 PIXEL_TYPE *pixel = pRow; \
2796 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2802 #include "tritemp.h"
2806 // #include "..\tritemp.h"
2808 #include "tritemp.h"
2815 * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
2817 static void flat_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2818 GLuint v2
, GLuint pv
)
2820 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2821 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2822 #define PIXEL_TYPE GLuint
2823 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2824 #define BYTES_PER_ROW (wmesa->ScanWidth)
2825 #define SETUP_CODE \
2826 unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \
2827 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2828 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2831 PIXEL_TYPE *pixel = pRow; \
2832 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2837 #include "tritemp.h"
2841 // #include "..\tritemp.h"
2843 #include "tritemp.h"
2850 * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
2852 static void flat_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2853 GLuint v2
, GLuint pv
)
2855 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2856 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2857 #define PIXEL_TYPE GLushort
2858 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2859 #define BYTES_PER_ROW (wmesa->ScanWidth)
2860 #define SETUP_CODE \
2861 unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \
2862 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2863 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2866 PIXEL_TYPE *pixel = pRow; \
2867 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2872 #include "tritemp.h"
2876 // #include "..\tritemp.h"
2878 #include "tritemp.h"
2885 * XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
2888 static void smooth_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2889 GLuint v2
, GLuint pv
)
2891 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2893 #define INTERP_INDEX 1
2894 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2895 #define PIXEL_TYPE GLubyte
2896 #define BYTES_PER_ROW (wmesa->ScanWidth)
2897 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2899 GLint i, len = RIGHT-LEFT; \
2900 for (i=0;i<len;i++) { \
2901 GLdepth z = FixedToDepth(ffz); \
2902 if (z < zRow[i]) { \
2903 pRow[i] = FixedToInt(ffi); \
2911 #include "tritemp.h"
2915 // #include "..\tritemp.h"
2917 #include "tritemp.h"
2924 * XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
2927 static void flat_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2928 GLuint v2
, GLuint pv
)
2930 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2932 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2933 #define PIXEL_TYPE GLubyte
2934 #define BYTES_PER_ROW (wmesa->ScanWidth)
2935 #define SETUP_CODE \
2936 GLuint index = VB->IndexPtr->data[pv]; \
2937 (*ctx->Driver.Index)( ctx, index );
2938 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2940 GLint i, len = RIGHT-LEFT; \
2941 for (i=0;i<len;i++) { \
2942 GLdepth z = FixedToDepth(ffz); \
2943 if (z < zRow[i]) { \
2951 #include "tritemp.h"
2955 // #include "..\tritemp.h"
2957 #include "tritemp.h"
2965 * XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2968 static void smooth_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2969 GLuint v2
, GLuint pv
)
2971 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2973 #define INTERP_INDEX 1
2974 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2975 #define PIXEL_TYPE GLubyte
2976 #define BYTES_PER_ROW (wmesa->ScanWidth)
2977 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2980 PIXEL_TYPE *pixel = pRow; \
2981 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2982 *pixel = FixedToInt(ffi); \
2987 #include "tritemp.h"
2991 // #include "..\tritemp.h"
2993 #include "tritemp.h"
3000 * XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
3002 static void flat_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
3003 GLuint v2
, GLuint pv
)
3005 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3007 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3008 #define PIXEL_TYPE GLubyte
3009 #define BYTES_PER_ROW (wmesa->ScanWidth)
3010 #define SETUP_CODE \
3011 GLuint index = VB->IndexPtr->data[pv]; \
3012 (*ctx->Driver.Index)( ctx, index );
3013 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3016 PIXEL_TYPE *pixel = pRow; \
3017 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
3022 #include "tritemp.h"
3026 // #include "..\tritemp.h"
3028 #include "tritemp.h"
3034 * XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
3036 static void smooth_DITHER8_z_triangle( GLcontext
*ctx
,
3037 GLuint v0
, GLuint v1
, GLuint v2
,
3040 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3041 DITHER_RGB_TO_8BIT_SETUP
3043 #define INTERP_RGB 1
3044 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3045 #define PIXEL_TYPE GLubyte
3046 #define BYTES_PER_ROW (wmesa->ScanWidth)
3047 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3049 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
3050 for (i=0;i<len;i++,xx++) { \
3051 GLdepth z = FixedToDepth(ffz); \
3052 if (z < zRow[i]) { \
3053 DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg), \
3054 FixedToInt(ffb), xx, yy); \
3055 pRow[i] = pixelDithered; \
3058 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
3063 #include "tritemp.h"
3067 // #include "..\tritemp.h"
3069 #include "tritemp.h"
3075 * XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
3077 static void flat_DITHER8_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
3078 GLuint v2
, GLuint pv
)
3080 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3081 DITHER_RGB_TO_8BIT_SETUP
3083 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3084 #define PIXEL_TYPE GLubyte
3085 #define BYTES_PER_ROW (wmesa->ScanWidth)
3087 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3089 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
3090 for (i=0;i<len;i++,xx++) { \
3091 GLdepth z = FixedToDepth(ffz); \
3092 if (z < zRow[i]) { \
3093 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \
3094 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \
3095 pRow[i] = pixelDithered; \
3102 #include "tritemp.h"
3106 // #include "..\tritemp.h"
3108 #include "tritemp.h"
3114 * XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
3116 static void smooth_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
3117 GLuint v2
, GLuint pv
)
3119 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3120 DITHER_RGB_TO_8BIT_SETUP
3121 #define INTERP_RGB 1
3122 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3123 #define PIXEL_TYPE GLubyte
3124 #define BYTES_PER_ROW (wmesa->ScanWidth)
3125 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3127 GLint xx, yy = FLIP(Y); \
3128 PIXEL_TYPE *pixel = pRow; \
3129 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
3130 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy);\
3131 *pixel = pixelDithered; \
3132 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
3136 #include "tritemp.h"
3140 // #include "..\tritemp.h"
3142 #include "tritemp.h"
3148 * XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
3151 static void flat_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
3152 GLuint v2
, GLuint pv
)
3154 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3155 DITHER_RGB_TO_8BIT_SETUP
3156 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3157 #define PIXEL_TYPE GLubyte
3158 #define BYTES_PER_ROW (wmesa->ScanWidth)
3160 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3162 GLint xx, yy = FLIP(Y); \
3163 PIXEL_TYPE *pixel = pRow; \
3164 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
3165 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \
3166 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \
3167 *pixel = pixelDithered; \
3171 #include "tritemp.h"
3175 // #include "..\tritemp.h"
3177 #include "tritemp.h"
3183 /************** END DEAD TRIANGLE CODE ***********************/
3185 static triangle_func
choose_triangle_function( GLcontext
*ctx
)
3188 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3189 int depth
= wmesa
->cColorBits
;
3191 if (ctx
->Polygon
.SmoothFlag
) return NULL
;
3192 if (ctx
->Texture
._EnabledUnits
) return NULL
;
3193 if (!wmesa
->db_flag
) return NULL
;
3194 if (ctx
->swrast
->_RasterMask
& MULTI_DRAW_BIT
) return NULL
;
3196 /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {
3197 if ( ctx
->Light
.ShadeModel
==GL_SMOOTH
3198 && ctx
->_RasterMask
==DEPTH_BIT
3199 && ctx
->Depth
.Func
==GL_LESS
3200 && ctx
->Depth
.Mask
==GL_TRUE
3201 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
3202 switch (wmesa
->pixelformat
) {
3204 return smooth_8A8B8G8R_z_triangle
;
3206 return smooth_8R8G8B_z_triangle
;
3208 return smooth_5R6G5B_z_triangle
;
3210 return smooth_DITHER8_z_triangle
;
3212 return smooth_ci_z_triangle
;
3217 if ( ctx
->Light
.ShadeModel
==GL_FLAT
3218 && ctx
->_RasterMask
==DEPTH_BIT
3219 && ctx
->Depth
.Func
==GL_LESS
3220 && ctx
->Depth
.Mask
==GL_TRUE
3221 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
3222 switch (wmesa
->pixelformat
) {
3224 return flat_8A8B8G8R_z_triangle
;
3226 return flat_8R8G8B_z_triangle
;
3228 return flat_5R6G5B_z_triangle
;
3230 return flat_DITHER8_z_triangle
;
3232 return flat_ci_z_triangle
;
3237 if ( ctx
->_RasterMask
==0 /* no depth test */
3238 && ctx
->Light
.ShadeModel
==GL_SMOOTH
3239 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
3240 switch (wmesa
->pixelformat
) {
3242 return smooth_8A8B8G8R_triangle
;
3244 return smooth_8R8G8B_triangle
;
3246 return smooth_5R6G5B_triangle
;
3248 return smooth_DITHER8_triangle
;
3250 return smooth_ci_triangle
;
3256 if ( ctx
->_RasterMask
==0 /* no depth test */
3257 && ctx
->Light
.ShadeModel
==GL_FLAT
3258 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
3259 switch (wmesa
->pixelformat
) {
3261 return flat_8A8B8G8R_triangle
;
3263 return flat_8R8G8B_triangle
;
3265 return flat_5R6G5B_triangle
;
3267 return flat_DITHER8_triangle
;
3269 return flat_ci_triangle
;
3281 * Define a new viewport and reallocate auxillary buffers if the size of
3282 * the window (color buffer) has changed.
3284 void WMesaViewport( GLcontext
*ctx
,
3285 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
3287 assert(0); /* I don't think that this is being used. */
3290 ctx
->Viewport
.X
= x
;
3291 ctx
->Viewport
.Width
= width
;
3292 ctx
->Viewport
.Y
= y
;
3293 ctx
->Viewport
.Height
= height
;
3295 /* compute scale and bias values */
3296 /* Pre-Keith 3.1 changes
3297 ctx->Viewport.Map.m[Sx] = (GLfloat) width / 2.0F;
3298 ctx->Viewport.Map.m[Tx] = ctx->Viewport.Sx + x;
3299 ctx->Viewport.Map.m[Sy] = (GLfloat) height / 2.0F;
3300 ctx->Viewport.Map.m[Ty] = ctx->Viewport.Sy + y;
3302 ctx
->Viewport
.WindowMap
.m
[MAT_SX
] = (GLfloat
) width
/ 2.0F
;
3303 ctx
->Viewport
.WindowMap
.m
[MAT_TX
] = ctx
->Viewport
.WindowMap
.m
[MAT_SX
] + x
;
3304 ctx
->Viewport
.WindowMap
.m
[MAT_SY
] = (GLfloat
) height
/ 2.0F
;
3305 ctx
->Viewport
.WindowMap
.m
[MAT_TY
] = ctx
->Viewport
.WindowMap
.m
[MAT_SY
] + y
;