1 /* $Id: wmesa.c,v 1.36 2002/09/27 02:45:39 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"
45 #include "texformat.h"
47 #include "array_cache/acache.h"
48 #include "swrast/swrast.h"
49 #include "swrast_setup/swrast_setup.h"
50 #include "swrast/s_context.h"
51 #include "swrast/s_depth.h"
52 #include "swrast/s_lines.h"
53 #include "swrast/s_triangle.h"
54 #include "swrast/s_trispan.h"
56 #include "tnl/t_context.h"
57 #include "tnl/t_pipeline.h"
59 /* Dither not tested for Mesa 4.0 */
69 #define CopyMemory memcpy
72 /* Stereo and parallel not tested for Mesa 4.0. */
73 #if !defined(NO_STEREO)
78 #if !defined(NO_PARALLEL)
83 /* File global varaibles */
84 struct DISPLAY_OPTIONS displayOptions
=
88 0, // full screen mode (1,2,3,4)
91 GLenum stereoCompile
= GL_FALSE
;
92 GLenum stereoShowing
= GL_FALSE
;
93 GLenum stereoBuffer
= GL_FALSE
;
94 #if !defined(NO_STEREO)
95 GLint displayList
= MAXIMUM_DISPLAY_LIST
;
97 GLint stereo_flag
= 0 ;
99 static PWMC Current
= NULL
;
100 WMesaContext WC
= NULL
;
102 #ifdef COMPILE_SETPIXEL
104 __forceinline
void wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
106 pwc
->wmSetPixel(pwc
,iScanLine
,iPixel
,r
,g
,b
);
109 void ChooseSetPixel(PWMC pwc
);
111 #endif // COMPILE_SETPIXEL
113 /* If we are double-buffering, we want to get the DC for the
114 * off-screen DIB, otherwise the DC for the window.
116 #define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
119 #define FLIP(Y) (Current->height-(Y)-1)
121 #define DITHER_RGB_TO_8BIT_SETUP \
122 GLubyte pixelDithered;
124 #define DITHER_RGB_TO_8BIT(red, green, blue, pixel, scanline) \
126 char unsigned redtemp, greentemp, bluetemp, paletteindex; \
127 redtemp = aDividedBy51[red] \
128 + (aModulo51[red] > aHalftone8x8[(pixel%8)*8 \
130 greentemp = aDividedBy51[(char unsigned)green] \
131 + (aModulo51[green] > aHalftone8x8[ \
132 (pixel%8)*8 + scanline%8]); \
133 bluetemp = aDividedBy51[(char unsigned)blue] \
134 + (aModulo51[blue] > aHalftone8x8[ \
135 (pixel%8)*8 +scanline%8]); \
136 paletteindex = redtemp + aTimes6[greentemp] + aTimes36[bluetemp];\
137 pixelDithered = aWinGHalftoneTranslation[paletteindex]; \
141 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
);
142 static void DDFree( WMesaContext wc
);
143 static HRESULT
DDRestoreAll( WMesaContext wc
);
144 static void DDDeleteOffScreen(WMesaContext wc
);
145 static BOOL
DDCreateOffScreen(WMesaContext wc
);
147 // define this to use the GDI Rectangle call to
148 // clear the back buffer. Otherwise will manually
149 // set the pixels. On an NVidia GEForce 2MX under Windows XP
150 // and DirectX 8 , defining this makes apps run much much faster
151 #define USE_GDI_TO_CLEAR 1
154 static void FlushToFile(PWMC pwc
, PSTR szFile
);
155 BOOL
wmCreateBackingStore(PWMC pwc
, long lxSize
, long lySize
);
156 BOOL
wmDeleteBackingStore(PWMC pwc
);
157 void wmCreatePalette( PWMC pwdc
);
158 BOOL
wmSetDibColors(PWMC pwc
);
159 void wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
);
160 BOOL
wmFlush(PWMC pwc
);
161 void wmCreateDIBSection(
163 PWMC pwc
, // handle of device context
164 CONST BITMAPINFO
*pbmi
, // bitmap size, format, and color data
165 UINT iUsage
// color data type indicator: RGB values or palette indices
167 void WMesaViewport( GLcontext
*ctx
,
168 GLint x
, GLint y
, GLsizei width
, GLsizei height
);
171 static void wmSetPixelFormat( PWMC wc
, HDC hDC
)
174 wc
->cColorBits
= GetDeviceCaps(hDC
, BITSPIXEL
);
177 switch(wc
->cColorBits
){
179 if(wc
->dither_flag
!= GL_TRUE
)
180 wc
->pixelformat
= PF_INDEX8
;
182 wc
->pixelformat
= PF_DITHER8
;
185 wc
->pixelformat
= PF_5R6G5B
;
188 wc
->pixelformat
= PF_8R8G8B
;
191 wc
->pixelformat
= PF_BADFORMAT
;
196 /* This function sets the color table of a DIB section
197 * to match that of the destination DC
199 BOOL
wmSetDibColors(PWMC pwc
)
201 RGBQUAD
*pColTab
, *pRGB
;
202 PALETTEENTRY
*pPal
, *pPE
;
207 /* Build a color table in the DIB that maps to the
208 * selected palette in the DC.
210 nColors
= 1 << pwc
->cColorBits
;
211 pPal
= (PALETTEENTRY
*)malloc( nColors
* sizeof(PALETTEENTRY
));
212 memset( pPal
, 0, nColors
* sizeof(PALETTEENTRY
) );
213 GetPaletteEntries( pwc
->hGLPalette
, 0, nColors
, pPal
);
214 pColTab
= (RGBQUAD
*)malloc( nColors
* sizeof(RGBQUAD
));
215 for (i
= 0, pRGB
= pColTab
, pPE
= pPal
; i
< nColors
; i
++, pRGB
++, pPE
++) {
216 pRGB
->rgbRed
= pPE
->peRed
;
217 pRGB
->rgbGreen
= pPE
->peGreen
;
218 pRGB
->rgbBlue
= pPE
->peBlue
;
221 bRet
= SetDIBColorTable(pwc
->dib
.hDC
, 0, nColors
, pColTab
);
224 dwErr
= GetLastError();
234 * Free up the dib section that was created
236 BOOL
wmDeleteBackingStore(PWMC pwc
)
238 SelectObject(pwc
->dib
.hDC
, pwc
->hOldBitmap
);
239 DeleteDC(pwc
->dib
.hDC
);
240 DeleteObject(pwc
->hbmDIB
);
241 #ifdef USE_MAPPED_FILE
242 UnmapViewOfFile(pwc
->dib
.base
);
243 CloseHandle(pwc
->dib
.hFileMap
);
250 * This function creates the DIB section that is used for combined
253 BOOL
wmCreateBackingStore(PWMC pwc
, long lxSize
, long lySize
)
256 LPBITMAPINFO pbmi
= &(pwc
->bmi
);
259 pbmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
260 pbmi
->bmiHeader
.biWidth
= lxSize
;
261 pbmi
->bmiHeader
.biHeight
= -lySize
;
262 pbmi
->bmiHeader
.biPlanes
= 1;
264 pbmi
->bmiHeader
.biBitCount
= GetDeviceCaps(pwc
->hDC
, BITSPIXEL
);
266 pbmi
->bmiHeader
.biBitCount
= 8;
267 pbmi
->bmiHeader
.biCompression
= BI_RGB
;
268 pbmi
->bmiHeader
.biSizeImage
= 0;
269 pbmi
->bmiHeader
.biXPelsPerMeter
= 0;
270 pbmi
->bmiHeader
.biYPelsPerMeter
= 0;
271 pbmi
->bmiHeader
.biClrUsed
= 0;
272 pbmi
->bmiHeader
.biClrImportant
= 0;
274 iUsage
= (pbmi
->bmiHeader
.biBitCount
<= 8) ? DIB_PAL_COLORS
: DIB_RGB_COLORS
;
276 pwc
->cColorBits
= pbmi
->bmiHeader
.biBitCount
;
277 pwc
->ScanWidth
= pwc
->pitch
= lxSize
;
279 wmCreateDIBSection(hdc
, pwc
, pbmi
, iUsage
);
281 if ((iUsage
== DIB_PAL_COLORS
) && !(pwc
->hGLPalette
)) {
282 wmCreatePalette( pwc
);
283 wmSetDibColors( pwc
);
285 wmSetPixelFormat(pwc
, pwc
->hDC
);
290 // D.R.S. 10/30/01 - this function is never referenced
292 * This function copies one scan line in a DIB section to another
294 BOOL
wmSetDIBits(PWMC pwc
, UINT uiScanWidth
, UINT uiNumScans
,
295 UINT nBypp
, UINT uiNewWidth
, LPBYTE pBits
)
298 LPBYTE pDest
= pwc
->pbPixels
;
299 DWORD dwNextScan
= uiScanWidth
;
300 DWORD dwNewScan
= uiNewWidth
;
301 DWORD dwScanWidth
= (uiScanWidth
* nBypp
);
304 * We need to round up to the nearest DWORD
305 * and multiply by the number of bytes per
308 dwNextScan
= (((dwNextScan
* nBypp
)+ 3) & ~3);
309 dwNewScan
= (((dwNewScan
* nBypp
)+ 3) & ~3);
311 for(uiScans
= 0; uiScans
< uiNumScans
; uiScans
++){
312 CopyMemory(pDest
, pBits
, dwScanWidth
);
320 #if defined(FAST_RASTERIZERS)
322 #define PIXELADDR(X,Y) \
323 ((GLubyte *)Current->pbPixels + (Current->height-Y-1)* \
324 Current->ScanWidth + (X)*nBypp)
325 #define PIXELADDR1( X, Y ) \
326 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X))
327 #define PIXELADDR2( X, Y ) \
328 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*2)
329 #define PIXELADDR4( X, Y ) \
330 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*4)
334 BYTE
DITHER_RGB_2_8BIT( int r
, int g
, int b
, int x
, int y
);
336 /* Finish all pending operations and synchronize. */
337 static void finish(GLcontext
* ctx
)
343 static void flush(GLcontext
* ctx
)
345 if((Current
->rgb_flag
&&!(Current
->db_flag
))
346 ||(!Current
->rgb_flag
))
356 * Set the color index used to clear the color buffer.
358 static void clear_index(GLcontext
* ctx
, GLuint index
)
360 Current
->clearpixel
= index
;
366 * Set the color used to clear the color buffer.
368 static void clear_color( GLcontext
* ctx
, const GLchan color
[4] )
370 Current
->clearpixel
= RGB(color
[0], color
[1], color
[2]);
375 * Clear the specified region of the color buffer using the clear color
376 * or index as specified by one of the two functions above.
378 * This procedure clears either the front and/or the back COLOR buffers.
379 * Only the "left" buffer is cleared since we are not stereo.
380 * Clearing of the other non-color buffers is left to the swrast.
381 * We also only clear the color buffers if the color masks are all 1's.
382 * Otherwise, we let swrast do it.
385 static clear(GLcontext
* ctx
, GLbitfield mask
,
386 GLboolean all
, GLint x
, GLint y
, GLint width
, GLint height
)
388 const GLuint
*colorMask
= (GLuint
*) &ctx
->Color
.ColorMask
;
392 width
=Current
->width
;
393 height
=Current
->height
;
397 /* sanity check - can't have right(stereo) buffers */
398 assert((mask
& (DD_FRONT_RIGHT_BIT
| DD_BACK_RIGHT_BIT
)) == 0);
401 if ((mask
& (DD_FRONT_LEFT_BIT
| DD_BACK_RIGHT_BIT
)) &&
402 ctx
->DrawBuffer
->UseSoftwareAlphaBuffers
&&
403 ctx
->Color
.ColorMask
[ACOMP
]) {
404 _mesa_clear_alpha_buffers( ctx
);
407 if (*colorMask
== 0xffffffff && ctx
->Color
.IndexMask
== 0xffffffff) {
408 if (mask
& DD_BACK_LEFT_BIT
) {
409 #if defined(USE_GDI_TO_CLEAR)
411 // D.R.S. 10/29/01 on my system (Pentium 4 with nvidia GeForce2 MX card,
412 // this is almose 100 times faster that the code below
414 HPEN Pen
=CreatePen(PS_SOLID
,1,Current
->clearpixel
);
415 HBRUSH Brush
=CreateSolidBrush(Current
->clearpixel
);
417 HBRUSH Old_Brush
=NULL
;
418 Current
->lpDDSOffScreen
->lpVtbl
->Unlock(Current
->lpDDSOffScreen
,NULL
);
419 Current
->lpDDSOffScreen
->lpVtbl
->GetDC(Current
->lpDDSOffScreen
,&DC
);
420 Old_Pen
=SelectObject(DC
,Pen
);
421 Old_Brush
=SelectObject(DC
,Brush
);
422 Rectangle(DC
,x
,y
,x
+width
,y
+height
);
423 SelectObject(DC
,Old_Pen
);
424 SelectObject(DC
,Old_Brush
);
427 Current
->lpDDSOffScreen
->lpVtbl
->ReleaseDC(Current
->lpDDSOffScreen
,DC
);
428 while (Current
->lpDDSOffScreen
->lpVtbl
->Lock(Current
->lpDDSOffScreen
,NULL
, &(Current
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
);
430 mask
&= ~DD_BACK_LEFT_BIT
;
434 HPEN Pen
=CreatePen(PS_SOLID
,1,Current
->clearpixel
);
435 HBRUSH Brush
=CreateSolidBrush(Current
->clearpixel
);
436 HPEN Old_Pen
=SelectObject(DC
,Pen
);
437 HBRUSH Old_Brush
=SelectObject(DC
,Brush
);
438 Rectangle(DC
,x
+Current
->rectSurface
.left
,Current
->rectSurface
.top
+y
,x
+width
+Current
->rectSurface
.left
,y
+height
+Current
->rectSurface
.top
);
440 SelectObject(DC
,Old_Pen
);
441 SelectObject(DC
,Old_Brush
);
445 mask
&= ~DD_BACK_LEFT_BIT
;
451 LPDWORD lpdw
= (LPDWORD
)Current
->pbPixels
;
452 LPWORD lpw
= (LPWORD
)Current
->pbPixels
;
453 LPBYTE lpb
= Current
->pbPixels
;
455 /* Double-buffering - clear back buffer */
456 UINT nBypp
= Current
->cColorBits
/ 8;
462 assert(Current
->db_flag
==GL_TRUE
); /* we'd better be double buffer */
464 iSize
= Current
->width
/4;
465 bColor
= BGR8(GetRValue(Current
->clearpixel
),
466 GetGValue(Current
->clearpixel
),
467 GetBValue(Current
->clearpixel
));
468 wColor
= MAKEWORD(bColor
,bColor
);
469 dwColor
= MAKELONG(wColor
, wColor
);
472 iSize
= Current
->width
/ 2;
473 wColor
= BGR16(GetRValue(Current
->clearpixel
),
474 GetGValue(Current
->clearpixel
),
475 GetBValue(Current
->clearpixel
));
476 dwColor
= MAKELONG(wColor
, wColor
);
480 r
= GetRValue(Current
->clearpixel
);
481 g
= GetGValue(Current
->clearpixel
);
482 b
= GetBValue(Current
->clearpixel
);
483 iSize
= Current
->width
;
490 lpb
= Current
->pbPixels
+ Current
->ScanWidth
;
494 iSize
= Current
->width
;
495 dwColor
= BGR32(GetRValue(Current
->clearpixel
),
496 GetGValue(Current
->clearpixel
),
497 GetBValue(Current
->clearpixel
));
515 /* copy cleared line to other lines in buffer */
517 memcpy(lpb
, Current
->pbPixels
, iSize
*mult
);
518 lpb
+= Current
->ScanWidth
;
522 mask
&= ~DD_BACK_LEFT_BIT
;
523 #endif // defined(USE_GDI_TO_CLEAR)
524 } /* double-buffer */
526 if (mask
& DD_FRONT_LEFT_BIT
) {
529 HPEN Pen
=CreatePen(PS_SOLID
,1,Current
->clearpixel
);
530 HBRUSH Brush
=CreateSolidBrush(Current
->clearpixel
);
531 HPEN Old_Pen
=SelectObject(DC
,Pen
);
532 HBRUSH Old_Brush
=SelectObject(DC
,Brush
);
533 Rectangle(DC
,x
+Current
->rectSurface
.left
,Current
->rectSurface
.top
+y
,x
+width
+Current
->rectSurface
.left
,y
+height
+Current
->rectSurface
.top
);
535 SelectObject(DC
,Old_Pen
);
536 SelectObject(DC
,Old_Brush
);
540 mask
&= ~DD_FRONT_LEFT_BIT
;
541 } /* single-buffer */
542 } /* if masks are all 1's */
544 /* Call swrast if there is anything left to clear (like DEPTH) */
546 _swrast_Clear( ctx
, mask
, all
, x
, y
, width
, height
);
550 static void enable( GLcontext
* ctx
, GLenum pname
, GLboolean enable
)
555 if (pname
== GL_DITHER
) {
556 if(enable
== GL_FALSE
){
557 Current
->dither_flag
= GL_FALSE
;
558 if(Current
->cColorBits
== 8)
559 Current
->pixelformat
= PF_INDEX8
;
562 if (Current
->rgb_flag
&& Current
->cColorBits
== 8){
563 Current
->pixelformat
= PF_DITHER8
;
564 Current
->dither_flag
= GL_TRUE
;
567 Current
->dither_flag
= GL_FALSE
;
574 static void set_buffer(GLcontext
*ctx
, GLframebuffer
*colorBuffer
,
577 /* XXX todo - examine buffer and set read/write pointers */
583 /* Return characteristics of the output buffer. */
584 static void buffer_size( GLframebuffer
*buffer
, GLuint
*width
, GLuint
*height
)
586 GET_CURRENT_CONTEXT(ctx
);
590 GetClientRect(Current
->Window
,&CR
);
595 New_Size
=((*width
)!=Current
->width
) || ((*height
)!=Current
->height
);
598 Current
->width
=*width
;
599 Current
->height
=*height
;
600 Current
->ScanWidth
=Current
->width
;
601 if ((Current
->ScanWidth
%sizeof(long))!=0)
602 Current
->ScanWidth
+=(sizeof(long)-(Current
->ScanWidth
%sizeof(long)));
604 if (Current
->db_flag
){
606 DDDeleteOffScreen(Current
);
607 DDCreateOffScreen(Current
);
609 if (Current
->rgb_flag
==GL_TRUE
&& Current
->dither_flag
!=GL_TRUE
){
610 wmDeleteBackingStore(Current
);
611 wmCreateBackingStore(Current
, Current
->width
, Current
->height
);
616 /* Resize OsmesaBuffer if in Parallel mode */
617 #if !defined(NO_PARALLEL)
619 PRSizeRenderBuffer(Current
->width
, Current
->height
,Current
->ScanWidth
,
620 Current
->rgb_flag
== GL_TRUE
? Current
->pbPixels
:
628 /**********************************************************************/
629 /***** Accelerated point, line, polygon rendering *****/
630 /**********************************************************************/
632 /* Accelerated routines are not implemented in 4.0. See OSMesa for ideas. */
634 static void fast_rgb_points( GLcontext
* ctx
, GLuint first
, GLuint last
)
638 /* Return pointer to accelerated points function */
639 extern points_func
choose_points_function( GLcontext
* ctx
)
644 static void fast_flat_rgb_line( GLcontext
* ctx
, GLuint v0
,
645 GLuint v1
, GLuint pv
)
649 static line_func
choose_line_function( GLcontext
* ctx
)
654 /**********************************************************************/
655 /***** Span-based pixel drawing *****/
656 /**********************************************************************/
659 /* Write a horizontal span of 32-bit color-index pixels with a boolean mask. */
660 static void write_ci32_span( const GLcontext
* ctx
,
661 GLuint n
, GLint x
, GLint y
,
662 const GLuint index
[],
663 const GLubyte mask
[] )
666 PBYTE Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
667 assert(Current
->rgb_flag
==GL_FALSE
);
674 /* Write a horizontal span of 8-bit color-index pixels with a boolean mask. */
675 static void write_ci8_span( const GLcontext
* ctx
,
676 GLuint n
, GLint x
, GLint y
,
677 const GLubyte index
[],
678 const GLubyte mask
[] )
681 PBYTE Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
682 assert(Current
->rgb_flag
==GL_FALSE
);
691 * Write a horizontal span of pixels with a boolean mask. The current
692 * color index is used for all pixels.
694 static void write_mono_ci_span(const GLcontext
* ctx
,
695 GLuint n
,GLint x
,GLint y
,
696 GLuint colorIndex
, const GLubyte mask
[])
699 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
700 assert(Current
->rgb_flag
==GL_FALSE
);
707 * To improve the performance of this routine, frob the data into an actual
708 * scanline and call bitblt on the complete scan line instead of SetPixel.
711 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
712 static void write_rgba_span( const GLcontext
* ctx
, GLuint n
, GLint x
, GLint y
,
713 const GLubyte rgba
[][4], const GLubyte mask
[] )
717 if (pwc
->rgb_flag
==GL_TRUE
)
725 wmSetPixel(pwc
, y
, x
+ i
,
726 rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
730 wmSetPixel(pwc
, y
, x
+ i
,
731 rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
] );
738 BYTE
*Mem
=Current
->ScreenMem
+y
*Current
->ScanWidth
+x
;
743 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,
750 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,
758 /* Write a horizontal span of RGB color pixels with a boolean mask. */
759 static void write_rgb_span( const GLcontext
* ctx
,
760 GLuint n
, GLint x
, GLint y
,
761 const GLubyte rgb
[][3], const GLubyte mask
[] )
765 if (pwc
->rgb_flag
==GL_TRUE
)
773 wmSetPixel(pwc
, y
, x
+ i
,
774 rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]);
778 wmSetPixel(pwc
, y
, x
+ i
,
779 rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
] );
786 BYTE
*Mem
=Current
->ScreenMem
+y
*Current
->ScanWidth
+x
;
791 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,
798 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,
807 * Write a horizontal span of pixels with a boolean mask. The current color
808 * is used for all pixels.
810 static void write_mono_rgba_span( const GLcontext
* ctx
,
811 GLuint n
, GLint x
, GLint y
,
812 const GLchan color
[4], const GLubyte mask
[])
816 assert(Current
->rgb_flag
==GL_TRUE
);
818 if(Current
->rgb_flag
==GL_TRUE
)
822 wmSetPixel(pwc
,y
,x
+i
,color
[RCOMP
], color
[GCOMP
], color
[BCOMP
]);
827 ULONG pixel
= RGB( color
[RCOMP
], color
[GCOMP
], color
[BCOMP
] );
830 SetPixel(DC
, y
, x
+i
, pixel
);
837 /**********************************************************************/
838 /***** Array-based pixel drawing *****/
839 /**********************************************************************/
842 /* Write an array of 32-bit index pixels with a boolean mask. */
843 static void write_ci32_pixels( const GLcontext
* ctx
,
844 GLuint n
, const GLint x
[], const GLint y
[],
845 const GLuint index
[], const GLubyte mask
[] )
848 assert(Current
->rgb_flag
==GL_FALSE
);
849 for (i
=0; i
<n
; i
++) {
851 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
];
860 * Write an array of pixels with a boolean mask. The current color
861 * index is used for all pixels.
863 static void write_mono_ci_pixels( const GLcontext
* ctx
,
865 const GLint x
[], const GLint y
[],
866 GLuint colorIndex
, const GLubyte mask
[] )
869 assert(Current
->rgb_flag
==GL_FALSE
);
870 for (i
=0; i
<n
; i
++) {
872 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
];
880 /* Write an array of RGBA pixels with a boolean mask. */
881 static void write_rgba_pixels( const GLcontext
* ctx
,
882 GLuint n
, const GLint x
[], const GLint y
[],
883 const GLubyte rgba
[][4], const GLubyte mask
[] )
888 assert(Current
->rgb_flag
==GL_TRUE
);
891 wmSetPixel(pwc
, FLIP(y
[i
]), x
[i
],
892 rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
899 * Write an array of pixels with a boolean mask. The current color
900 * is used for all pixels.
902 static void write_mono_rgba_pixels( const GLcontext
* ctx
,
904 const GLint x
[], const GLint y
[],
905 const GLchan color
[4],
906 const GLubyte mask
[] )
911 assert(Current
->rgb_flag
==GL_TRUE
);
914 wmSetPixel(pwc
, FLIP(y
[i
]),x
[i
],color
[RCOMP
],
915 color
[GCOMP
], color
[BCOMP
]);
921 /**********************************************************************/
922 /***** Read spans/arrays of pixels *****/
923 /**********************************************************************/
926 /* Read a horizontal span of color-index pixels. */
927 static void read_ci32_span( const GLcontext
* ctx
, GLuint n
, GLint x
, GLint y
,
931 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
932 assert(Current
->rgb_flag
==GL_FALSE
);
940 /* Read an array of color index pixels. */
941 static void read_ci32_pixels( const GLcontext
* ctx
,
942 GLuint n
, const GLint x
[], const GLint y
[],
943 GLuint indx
[], const GLubyte mask
[] )
946 assert(Current
->rgb_flag
==GL_FALSE
);
947 for (i
=0; i
<n
; i
++) {
949 indx
[i
]=*(Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
]);
956 /* Read a horizontal span of color pixels. */
957 static void read_rgba_span( const GLcontext
* ctx
,
958 GLuint n
, GLint x
, GLint y
,
964 assert(Current
->rgb_flag
==GL_TRUE
);
965 y
= Current
->height
- y
- 1;
966 for (i
=0; i
<n
; i
++) {
967 Color
=GetPixel(DC
,x
+i
,y
);
968 rgba
[i
][RCOMP
] = GetRValue(Color
);
969 rgba
[i
][GCOMP
] = GetGValue(Color
);
970 rgba
[i
][BCOMP
] = GetBValue(Color
);
971 rgba
[i
][ACOMP
] = 255;
977 /* Read an array of color pixels. */
978 static void read_rgba_pixels( const GLcontext
* ctx
,
979 GLuint n
, const GLint x
[], const GLint y
[],
980 GLubyte rgba
[][4], const GLubyte mask
[] )
985 assert(Current
->rgb_flag
==GL_TRUE
);
986 for (i
=0; i
<n
; i
++) {
988 GLint y2
= Current
->height
- y
[i
] - 1;
989 Color
=GetPixel(DC
,x
[i
],y2
);
990 rgba
[i
][RCOMP
] = GetRValue(Color
);
991 rgba
[i
][GCOMP
] = GetGValue(Color
);
992 rgba
[i
][BCOMP
] = GetBValue(Color
);
993 rgba
[i
][ACOMP
] = 255;
1001 /**********************************************************************/
1002 /**********************************************************************/
1005 static const GLubyte
*get_string(GLcontext
*ctx
, GLenum name
)
1007 if (name
== GL_RENDERER
) {
1008 return (GLubyte
*) "Mesa Windows";
1015 static void wmesa_update_state( GLcontext
*ctx
, GLuint new_state
);
1017 static void SetFunctionPointers(GLcontext
*ctx
)
1019 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference( ctx
);
1020 ctx
->Driver
.GetString
= get_string
;
1021 ctx
->Driver
.UpdateState
= wmesa_update_state
;
1022 ctx
->Driver
.ResizeBuffers
= _swrast_alloc_buffers
;
1023 ctx
->Driver
.GetBufferSize
= buffer_size
;
1025 ctx
->Driver
.Accum
= _swrast_Accum
;
1026 ctx
->Driver
.Bitmap
= _swrast_Bitmap
;
1027 ctx
->Driver
.Clear
= clear
;
1029 ctx
->Driver
.Flush
= flush
;
1030 ctx
->Driver
.ClearIndex
= clear_index
;
1031 ctx
->Driver
.ClearColor
= clear_color
;
1032 ctx
->Driver
.Enable
= enable
;
1034 ctx
->Driver
.CopyPixels
= _swrast_CopyPixels
;
1035 ctx
->Driver
.DrawPixels
= _swrast_DrawPixels
;
1036 ctx
->Driver
.ReadPixels
= _swrast_ReadPixels
;
1037 ctx
->Driver
.DrawBuffer
= _swrast_DrawBuffer
;
1039 ctx
->Driver
.ChooseTextureFormat
= _mesa_choose_tex_format
;
1040 ctx
->Driver
.TexImage1D
= _mesa_store_teximage1d
;
1041 ctx
->Driver
.TexImage2D
= _mesa_store_teximage2d
;
1042 ctx
->Driver
.TexImage3D
= _mesa_store_teximage3d
;
1043 ctx
->Driver
.TexSubImage1D
= _mesa_store_texsubimage1d
;
1044 ctx
->Driver
.TexSubImage2D
= _mesa_store_texsubimage2d
;
1045 ctx
->Driver
.TexSubImage3D
= _mesa_store_texsubimage3d
;
1046 ctx
->Driver
.TestProxyTexImage
= _mesa_test_proxy_teximage
;
1048 ctx
->Driver
.CompressedTexImage1D
= _mesa_store_compressed_teximage1d
;
1049 ctx
->Driver
.CompressedTexImage2D
= _mesa_store_compressed_teximage2d
;
1050 ctx
->Driver
.CompressedTexImage3D
= _mesa_store_compressed_teximage3d
;
1051 ctx
->Driver
.CompressedTexSubImage1D
= _mesa_store_compressed_texsubimage1d
;
1052 ctx
->Driver
.CompressedTexSubImage2D
= _mesa_store_compressed_texsubimage2d
;
1053 ctx
->Driver
.CompressedTexSubImage3D
= _mesa_store_compressed_texsubimage3d
;
1055 ctx
->Driver
.CopyTexImage1D
= _swrast_copy_teximage1d
;
1056 ctx
->Driver
.CopyTexImage2D
= _swrast_copy_teximage2d
;
1057 ctx
->Driver
.CopyTexSubImage1D
= _swrast_copy_texsubimage1d
;
1058 ctx
->Driver
.CopyTexSubImage2D
= _swrast_copy_texsubimage2d
;
1059 ctx
->Driver
.CopyTexSubImage3D
= _swrast_copy_texsubimage3d
;
1060 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1061 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1062 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1063 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;
1065 swdd
->SetBuffer
= set_buffer
;
1067 /* Pixel/span writing functions: */
1068 swdd
->WriteRGBASpan
= write_rgba_span
;
1069 swdd
->WriteRGBSpan
= write_rgb_span
;
1070 swdd
->WriteMonoRGBASpan
= write_mono_rgba_span
;
1071 swdd
->WriteRGBAPixels
= write_rgba_pixels
;
1072 swdd
->WriteMonoRGBAPixels
= write_mono_rgba_pixels
;
1073 swdd
->WriteCI32Span
= write_ci32_span
;
1074 swdd
->WriteCI8Span
= write_ci8_span
;
1075 swdd
->WriteMonoCISpan
= write_mono_ci_span
;
1076 swdd
->WriteCI32Pixels
= write_ci32_pixels
;
1077 swdd
->WriteMonoCIPixels
= write_mono_ci_pixels
;
1079 swdd
->ReadCI32Span
= read_ci32_span
;
1080 swdd
->ReadRGBASpan
= read_rgba_span
;
1081 swdd
->ReadCI32Pixels
= read_ci32_pixels
;
1082 swdd
->ReadRGBAPixels
= read_rgba_pixels
;
1086 static void wmesa_update_state( GLcontext
*ctx
, GLuint new_state
)
1088 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference( ctx
);
1089 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1092 * XXX these function pointers could be initialized just once during
1093 * context creation since they don't depend on any state changes.
1094 * kws - This is true - this function gets called a lot and it
1095 * would be good to minimize setting all this when not needed.
1097 #ifndef SET_FPOINTERS_ONCE
1098 SetFunctionPointers(ctx
);
1100 ctx
->Driver
.GetString
= get_string
;
1101 ctx
->Driver
.UpdateState
= wmesa_update_state
;
1102 ctx
->Driver
.ResizeBuffers
= _swrast_alloc_buffers
;
1103 ctx
->Driver
.GetBufferSize
= buffer_size
;
1105 ctx
->Driver
.Accum
= _swrast_Accum
;
1106 ctx
->Driver
.Bitmap
= _swrast_Bitmap
;
1107 ctx
->Driver
.Clear
= clear
;
1109 ctx
->Driver
.Flush
= flush
;
1110 ctx
->Driver
.ClearIndex
= clear_index
;
1111 ctx
->Driver
.ClearColor
= clear_color
;
1112 ctx
->Driver
.Enable
= enable
;
1114 ctx
->Driver
.CopyPixels
= _swrast_CopyPixels
;
1115 ctx
->Driver
.DrawPixels
= _swrast_DrawPixels
;
1116 ctx
->Driver
.ReadPixels
= _swrast_ReadPixels
;
1118 ctx
->Driver
.ChooseTextureFormat
= _mesa_choose_tex_format
;
1119 ctx
->Driver
.TexImage1D
= _mesa_store_teximage1d
;
1120 ctx
->Driver
.TexImage2D
= _mesa_store_teximage2d
;
1121 ctx
->Driver
.TexImage3D
= _mesa_store_teximage3d
;
1122 ctx
->Driver
.TexSubImage1D
= _mesa_store_texsubimage1d
;
1123 ctx
->Driver
.TexSubImage2D
= _mesa_store_texsubimage2d
;
1124 ctx
->Driver
.TexSubImage3D
= _mesa_store_texsubimage3d
;
1125 ctx
->Driver
.TestProxyTexImage
= _mesa_test_proxy_teximage
;
1127 ctx
->Driver
.CompressedTexImage1D
= _mesa_store_compressed_teximage1d
;
1128 ctx
->Driver
.CompressedTexImage2D
= _mesa_store_compressed_teximage2d
;
1129 ctx
->Driver
.CompressedTexImage3D
= _mesa_store_compressed_teximage3d
;
1130 ctx
->Driver
.CompressedTexSubImage1D
= _mesa_store_compressed_texsubimage1d
;
1131 ctx
->Driver
.CompressedTexSubImage2D
= _mesa_store_compressed_texsubimage2d
;
1132 ctx
->Driver
.CompressedTexSubImage3D
= _mesa_store_compressed_texsubimage3d
;
1134 ctx
->Driver
.CopyTexImage1D
= _swrast_copy_teximage1d
;
1135 ctx
->Driver
.CopyTexImage2D
= _swrast_copy_teximage2d
;
1136 ctx
->Driver
.CopyTexSubImage1D
= _swrast_copy_texsubimage1d
;
1137 ctx
->Driver
.CopyTexSubImage2D
= _swrast_copy_texsubimage2d
;
1138 ctx
->Driver
.CopyTexSubImage3D
= _swrast_copy_texsubimage3d
;
1139 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1140 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1141 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1142 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;
1144 swdd
->SetBuffer
= set_buffer
;
1146 /* Pixel/span writing functions: */
1147 swdd
->WriteRGBASpan
= write_rgba_span
;
1148 swdd
->WriteRGBSpan
= write_rgb_span
;
1149 swdd
->WriteMonoRGBASpan
= write_mono_rgba_span
;
1150 swdd
->WriteRGBAPixels
= write_rgba_pixels
;
1151 swdd
->WriteMonoRGBAPixels
= write_mono_rgba_pixels
;
1152 swdd
->WriteCI32Span
= write_ci32_span
;
1153 swdd
->WriteCI8Span
= write_ci8_span
;
1154 swdd
->WriteMonoCISpan
= write_mono_ci_span
;
1155 swdd
->WriteCI32Pixels
= write_ci32_pixels
;
1156 swdd
->WriteMonoCIPixels
= write_mono_ci_pixels
;
1158 swdd
->ReadCI32Span
= read_ci32_span
;
1159 swdd
->ReadRGBASpan
= read_rgba_span
;
1160 swdd
->ReadCI32Pixels
= read_ci32_pixels
;
1161 swdd
->ReadRGBAPixels
= read_rgba_pixels
;
1163 #endif // !SET_FPOINTERS_ONCE
1164 tnl
->Driver
.RunPipeline
= _tnl_run_pipeline
;
1166 _swrast_InvalidateState( ctx
, new_state
);
1167 _swsetup_InvalidateState( ctx
, new_state
);
1168 _ac_InvalidateState( ctx
, new_state
);
1169 _tnl_InvalidateState( ctx
, new_state
);
1175 /**********************************************************************/
1176 /***** WMesa API Functions *****/
1177 /**********************************************************************/
1181 #define PAL_SIZE 256
1182 static void GetPalette(HPALETTE Pal
,RGBQUAD
*aRGB
)
1189 WORD NumberOfEntries
;
1190 PALETTEENTRY aEntries
[PAL_SIZE
];
1198 GetPaletteEntries(Pal
,0,PAL_SIZE
,Palette
.aEntries
);
1200 GetSystemPaletteEntries(hdc
,0,PAL_SIZE
,Palette
.aEntries
);
1201 if (GetSystemPaletteUse(hdc
) == SYSPAL_NOSTATIC
)
1203 for(i
= 0; i
<PAL_SIZE
; i
++)
1204 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1205 Palette
.aEntries
[255].peRed
= 255;
1206 Palette
.aEntries
[255].peGreen
= 255;
1207 Palette
.aEntries
[255].peBlue
= 255;
1208 Palette
.aEntries
[255].peFlags
= 0;
1209 Palette
.aEntries
[0].peRed
= 0;
1210 Palette
.aEntries
[0].peGreen
= 0;
1211 Palette
.aEntries
[0].peBlue
= 0;
1212 Palette
.aEntries
[0].peFlags
= 0;
1218 nStaticColors
= GetDeviceCaps(hdc
, NUMCOLORS
)/2;
1219 for (i
=0; i
<nStaticColors
; i
++)
1220 Palette
.aEntries
[i
].peFlags
= 0;
1221 nUsableColors
= PAL_SIZE
-nStaticColors
;
1222 for (; i
<nUsableColors
; i
++)
1223 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1224 for (; i
<PAL_SIZE
-nStaticColors
; i
++)
1225 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1226 for (i
=PAL_SIZE
-nStaticColors
; i
<PAL_SIZE
; i
++)
1227 Palette
.aEntries
[i
].peFlags
= 0;
1229 ReleaseDC(NULL
,hdc
);
1230 for (i
=0; i
<PAL_SIZE
; i
++)
1232 aRGB
[i
].rgbRed
=Palette
.aEntries
[i
].peRed
;
1233 aRGB
[i
].rgbGreen
=Palette
.aEntries
[i
].peGreen
;
1234 aRGB
[i
].rgbBlue
=Palette
.aEntries
[i
].peBlue
;
1235 aRGB
[i
].rgbReserved
=Palette
.aEntries
[i
].peFlags
;
1240 WMesaContext
WMesaCreateContext( HWND hWnd
, HPALETTE
* Pal
,
1243 GLboolean alpha_flag
)
1247 GLboolean true_color_flag
;
1248 __GLimports imports
;
1250 c
= (struct wmesa_context
* ) calloc(1,sizeof(struct wmesa_context
));
1255 c
->hDC
= GetDC(hWnd
);
1256 true_color_flag
= GetDeviceCaps(c
->hDC
, BITSPIXEL
) > 8;
1258 if(true_color_flag
) c
->rgb_flag
= rgb_flag
= GL_TRUE
;
1263 if ((true_color_flag
==GL_FALSE
) && (rgb_flag
== GL_TRUE
)){
1264 c
->dither_flag
= GL_TRUE
;
1266 c
->hPalHalfTone
= WinGCreateHalftonePalette();
1268 c
->hPalHalfTone
= CreateHalftonePalette(c
->hDC
);
1272 c
->dither_flag
= GL_FALSE
;
1274 c
->dither_flag
= GL_FALSE
;
1278 if (rgb_flag
==GL_FALSE
)
1280 c
->rgb_flag
= GL_FALSE
;
1282 /* Old WinG stuff???? */
1283 c
->db_flag
= db_flag
=GL_TRUE
; /* WinG requires double buffering */
1284 printf("Single buffer is not supported in color index mode, ",
1285 "setting to double buffer.\n");
1290 c
->rgb_flag
= GL_TRUE
;
1292 GetClientRect(c
->Window
,&CR
);
1294 c
->height
=CR
.bottom
;
1298 /* Double buffered */
1301 wmCreateBackingStore(c
, c
->width
, c
->height
);
1308 /* Single Buffered */
1313 if (DDInit(c
,hWnd
) == GL_FALSE
) {
1320 c
->gl_visual
= _mesa_create_visual(rgb_flag
,
1321 db_flag
, /* db_flag */
1322 GL_FALSE
, /* stereo */
1323 8,8,8, /* r, g, b bits */
1324 alpha_flag
? 8 : 0, /* alpha bits */
1326 16, /* depth_bits */
1327 8, /* stencil_bits */
1328 16,16,16,/* accum_bits */
1329 alpha_flag
? 16 : 0, /* alpha accum */
1332 if (!c
->gl_visual
) {
1336 _mesa_init_default_imports( &imports
, (void *) c
);
1338 /* allocate a new Mesa context */
1339 c
->gl_ctx
= _mesa_create_context( c
->gl_visual
, NULL
, &imports
);
1342 _mesa_destroy_visual( c
->gl_visual
);
1347 _mesa_enable_sw_extensions(c
->gl_ctx
);
1348 _mesa_enable_1_3_extensions(c
->gl_ctx
);
1350 c
->gl_buffer
= _mesa_create_framebuffer( c
->gl_visual
,
1351 c
->gl_visual
->depthBits
> 0,
1352 c
->gl_visual
->stencilBits
> 0,
1353 c
->gl_visual
->accumRedBits
> 0,
1354 alpha_flag
/* s/w alpha */ );
1355 if (!c
->gl_buffer
) {
1356 _mesa_destroy_visual( c
->gl_visual
);
1357 _mesa_free_context_data( c
->gl_ctx
);
1362 /* Initialize the software rasterizer and helper modules.
1365 GLcontext
*ctx
= c
->gl_ctx
;
1366 _swrast_CreateContext( ctx
);
1367 _ac_CreateContext( ctx
);
1368 _tnl_CreateContext( ctx
);
1369 _swsetup_CreateContext( ctx
);
1371 #ifdef SET_FPOINTERS_ONCE
1372 SetFunctionPointers(ctx
);
1373 #endif // SET_FPOINTERS_ONCE
1374 _swsetup_Wakeup( ctx
);
1376 #ifdef COMPILE_SETPIXEL
1382 void WMesaDestroyContext( void )
1384 WMesaContext c
= Current
;
1385 ReleaseDC(c
->Window
,c
->hDC
);
1387 if(c
->hPalHalfTone
!= NULL
)
1388 DeleteObject(c
->hPalHalfTone
);
1390 _swsetup_DestroyContext( c
->gl_ctx
);
1391 _tnl_DestroyContext( c
->gl_ctx
);
1392 _ac_DestroyContext( c
->gl_ctx
);
1393 _swrast_DestroyContext( c
->gl_ctx
);
1395 _mesa_destroy_visual( c
->gl_visual
);
1396 _mesa_destroy_framebuffer( c
->gl_buffer
);
1397 _mesa_free_context_data( c
->gl_ctx
);
1398 free( (void *) c
->gl_ctx
);
1404 wmDeleteBackingStore(c
);
1407 #if !defined(NO_PARALLEL)
1409 PRDestroyRenderBuffer();
1412 // Destroyed context no longer valid
1413 WMesaMakeCurrent( NULL
);
1417 void WMesaMakeCurrent( WMesaContext c
)
1428 wmesa_update_state(c
->gl_ctx
, 0);
1429 _mesa_make_current(c
->gl_ctx
, c
->gl_buffer
);
1430 if (Current
->gl_ctx
->Viewport
.Width
==0) {
1431 /* initialize viewport to window size */
1432 _mesa_Viewport( 0, 0, Current
->width
, Current
->height
);
1433 Current
->gl_ctx
->Scissor
.Width
= Current
->width
;
1434 Current
->gl_ctx
->Scissor
.Height
= Current
->height
;
1436 if ((c
->cColorBits
<= 8 ) && (c
->rgb_flag
== GL_TRUE
)){
1437 WMesaPaletteChange(c
->hPalHalfTone
);
1443 void WMesaSwapBuffers( void )
1445 HDC DC
= Current
->hDC
;
1446 GET_CURRENT_CONTEXT(ctx
);
1448 /* If we're swapping the buffer associated with the current context
1449 * we have to flush any pending rendering commands first.
1451 if (Current
&& Current
->gl_ctx
== ctx
)
1452 _mesa_swapbuffers(ctx
);
1454 if (Current
->db_flag
)
1460 void WMesaPaletteChange(HPALETTE Pal
)
1465 LPPALETTEENTRY pPal
;
1466 if (Current
&& (Current
->rgb_flag
==GL_FALSE
||
1467 Current
->dither_flag
== GL_TRUE
))
1469 pPal
= (PALETTEENTRY
*)malloc( 256 * sizeof(PALETTEENTRY
));
1471 GetPaletteEntries( Pal
, 0, 256, pPal
);
1473 Current
->lpDD
->lpVtbl
->CreatePalette(Current
->lpDD
,DDPCAPS_8BIT
,
1474 pPal
, &(Current
->lpDDPal
), NULL
);
1475 if (Current
->lpDDPal
)
1476 Current
->lpDDSPrimary
->lpVtbl
->SetPalette(Current
->lpDDSPrimary
,
1479 vRet
= SetDIBColorTable(Current
->dib
.hDC
, 0, 256, (RGBQUAD
*)pPal
);
1488 static unsigned char threeto8
[8] = {
1489 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
1492 static unsigned char twoto8
[4] = {
1496 static unsigned char oneto8
[2] = {
1500 static unsigned char componentFromIndex(UCHAR i
, UINT nbits
, UINT shift
)
1517 return threeto8
[val
];
1524 void wmCreatePalette( PWMC pwdc
)
1526 /* Create a compressed and re-expanded 3:3:2 palette */
1529 BYTE rb
, rs
, gb
, gs
, bb
, bs
;
1531 pwdc
->nColors
= 0x100;
1533 pPal
= (PLOGPALETTE
)malloc(sizeof(LOGPALETTE
) +
1534 pwdc
->nColors
* sizeof(PALETTEENTRY
));
1535 memset( pPal
, 0, sizeof(LOGPALETTE
) + pwdc
->nColors
* sizeof(PALETTEENTRY
) );
1537 pPal
->palVersion
= 0x300;
1546 if (pwdc
->db_flag
) {
1548 /* Need to make two palettes: one for the screen DC and one for the DIB. */
1549 pPal
->palNumEntries
= pwdc
->nColors
;
1550 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1551 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1552 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1553 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1554 pPal
->palPalEntry
[i
].peFlags
= 0;
1556 pwdc
->hGLPalette
= CreatePalette( pPal
);
1557 pwdc
->hPalette
= CreatePalette( pPal
);
1561 pPal
->palNumEntries
= pwdc
->nColors
;
1562 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1563 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1564 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1565 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1566 pPal
->palPalEntry
[i
].peFlags
= 0;
1568 pwdc
->hGLPalette
= CreatePalette( pPal
);
1577 #ifdef COMPILE_SETPIXEL
1579 wmSetPixelDefault(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1581 if (Current
->db_flag
)
1585 Current
->lpDDSOffScreen
->lpVtbl
->Unlock(Current
->lpDDSOffScreen
,NULL
);
1586 Current
->lpDDSOffScreen
->lpVtbl
->GetDC(Current
->lpDDSOffScreen
,&hdc
);
1587 SetPixelV(hdc
,iPixel
, iScanLine
, RGB(r
,g
,b
));
1588 Current
->lpDDSOffScreen
->lpVtbl
->ReleaseDC(Current
->lpDDSOffScreen
,hdc
);
1589 while (Current
->lpDDSOffScreen
->lpVtbl
->Lock(Current
->lpDDSOffScreen
,NULL
, &(Current
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
);
1591 SetPixelV(Current
->hDC
, iPixel
, iScanLine
, RGB(r
,g
,b
));
1596 SetPixelV(Current
->hDC
, iPixel
+pwc
->rectSurface
.left
, pwc
->rectSurface
.top
+iScanLine
, RGB(r
,g
,b
));
1600 wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1602 if (Current
->db_flag
)
1604 LPBYTE lpb
= pwc
->pbPixels
;
1605 UINT nBypp
= pwc
->cColorBits
>> 3;
1607 lpb
+= pwc
->ScanWidth
* iScanLine
;
1608 lpb
+= iPixel
* nBypp
;
1612 if(pwc
->dither_flag
)
1613 *lpb
= DITHER_RGB_2_8BIT(r
,g
,b
,iScanLine
,iPixel
);
1618 *((LPWORD
)lpb
) = BGR16(r
,g
,b
);
1619 else if (nBypp
== 3)
1625 else if (nBypp
== 4)
1626 *((LPDWORD
)lpb
) = BGR32(r
,g
,b
);
1630 SetPixel(Current
->hDC
, iPixel
, iScanLine
, RGB(r
,g
,b
));
1634 #ifdef COMPILE_SETPIXEL
1635 void wmSetPixel4(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1637 LPDWORD lpdw
= ((LPDWORD
)(pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
)) + iPixel
;
1638 *lpdw
= BGR32(r
,g
,b
);
1639 // LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel + iPixel + iPixel;
1640 // *((LPDWORD)lpb) = BGR32(r,g,b);
1643 void wmSetPixel3(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1645 LPBYTE lpb
= pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
+ iPixel
+ iPixel
+ iPixel
;
1651 void wmSetPixel2(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1653 LPWORD lpw
= ((LPWORD
)(pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
)) + iPixel
;
1654 *lpw
= BGR16(r
,g
,b
);
1655 // LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel;
1656 // *((LPWORD)lpb) = BGR16(r,g,b);
1659 void wmSetPixel1(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1661 LPBYTE lpb
= pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
+ iPixel
;
1665 void wmSetPixel1Dither(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1667 LPBYTE lpb
= pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
+ iPixel
;
1668 *lpb
= DITHER_RGB_2_8BIT(r
,g
,b
,iScanLine
,iPixel
);
1672 void ChooseSetPixel(PWMC pwc
)
1674 UINT nBypp
= (pwc
) ? pwc
->cColorBits
>> 3 : 0;
1678 pwc
->wmSetPixel
= pwc
->dither_flag
? &wmSetPixel1Dither
: &wmSetPixel1
;
1681 pwc
->wmSetPixel
= &wmSetPixel2
;
1684 pwc
->wmSetPixel
= &wmSetPixel3
;
1687 pwc
->wmSetPixel
= &wmSetPixel4
;
1690 pwc
->wmSetPixel
= &wmSetPixelDefault
;
1697 void wmCreateDIBSection(
1699 PWMC pwc
, // handle of device context
1700 CONST BITMAPINFO
*pbmi
, // bitmap size, format, and color data
1701 UINT iUsage
// color data type indicator: RGB values or palette indices
1706 UINT nBypp
= pwc
->cColorBits
/ 8;
1709 dwScanWidth
= (((pwc
->ScanWidth
* nBypp
)+ 3) & ~3);
1711 pwc
->ScanWidth
=pwc
->pitch
= dwScanWidth
;
1714 pwc
->ScanWidth
= 2* pwc
->pitch
;
1716 dwSize
= sizeof(BITMAPINFO
) + (dwScanWidth
* pwc
->height
);
1717 #ifdef USE_MAPPED_FILE
1718 pwc
->dib
.hFileMap
= CreateFileMapping((HANDLE
)PAGE_FILE
,
1720 PAGE_READWRITE
| SEC_COMMIT
,
1725 if (!pwc
->dib
.hFileMap
)
1728 pwc
->dib
.base
= MapViewOfFile(pwc
->dib
.hFileMap
,
1729 FILE_MAP_ALL_ACCESS
,
1735 CloseHandle(pwc
->dib
.hFileMap
);
1740 CopyMemory(pwc
->dib
.base
, pbmi
, sizeof(BITMAPINFO
));
1741 #endif // USE_MAPPED_FILE
1743 hic
= CreateIC("display", NULL
, NULL
, NULL
);
1744 pwc
->dib
.hDC
= CreateCompatibleDC(hic
);
1746 #ifdef USE_MAPPED_FILE
1748 pwc
->hbmDIB
= CreateDIBSection(hic
,
1750 (iUsage
? DIB_PAL_COLORS
: DIB_RGB_COLORS
),
1755 pwc
->hbmDIB
= CreateDIBSection(hic
,
1757 (iUsage
? DIB_PAL_COLORS
: DIB_RGB_COLORS
),
1761 #endif // USE_MAPPED_FILE
1762 pwc
->ScreenMem
= pwc
->addrOffScreen
= pwc
->pbPixels
;
1763 pwc
->hOldBitmap
= SelectObject(pwc
->dib
.hDC
, pwc
->hbmDIB
);
1772 * Blit memory DC to screen DC
1774 BOOL
wmFlush(PWMC pwc
)
1784 if (pwc
->lpDDSOffScreen
== NULL
)
1785 if(DDCreateOffScreen(pwc
) == GL_FALSE
)
1788 pwc
->lpDDSOffScreen
->lpVtbl
->Unlock(pwc
->lpDDSOffScreen
, NULL
);
1792 ddrval
= pwc
->lpDDSPrimary
->lpVtbl
->Blt( pwc
->lpDDSPrimary
,
1793 &(pwc
->rectSurface
),
1794 pwc
->lpDDSOffScreen
,
1795 &(pwc
->rectOffScreen
),
1798 if( ddrval
== DD_OK
)
1802 if( ddrval
== DDERR_SURFACELOST
)
1804 if(!DDRestoreAll(pwc
))
1809 if( ddrval
!= DDERR_WASSTILLDRAWING
)
1815 while (pwc
->lpDDSOffScreen
->lpVtbl
->Lock(pwc
->lpDDSOffScreen
,
1816 NULL
, &(pwc
->ddsd
), 0, NULL
) ==
1817 DDERR_WASSTILLDRAWING
)
1821 dwErr
= GetLastError();
1823 bRet
= BitBlt(pwc
->hDC
, 0, 0, pwc
->width
, pwc
->height
,
1824 pwc
->dib
.hDC
, 0, 0, SRCCOPY
);
1833 /* The following code is added by Li Wei to enable stereo display */
1835 #if !defined(NO_STEREO)
1837 static void __gluMakeIdentityf(GLfloat m
[16])
1839 m
[0+4*0] = 1; m
[0+4*1] = 0; m
[0+4*2] = 0; m
[0+4*3] = 0;
1840 m
[1+4*0] = 0; m
[1+4*1] = 1; m
[1+4*2] = 0; m
[1+4*3] = 0;
1841 m
[2+4*0] = 0; m
[2+4*1] = 0; m
[2+4*2] = 1; m
[2+4*3] = 0;
1842 m
[3+4*0] = 0; m
[3+4*1] = 0; m
[3+4*2] = 0; m
[3+4*3] = 1;
1845 static void normalize(float v
[3])
1849 r
= sqrt( v
[0]*v
[0] + v
[1]*v
[1] + v
[2]*v
[2] );
1850 if (r
== 0.0) return;
1857 static void cross(float v1
[3], float v2
[3], float result
[3])
1859 result
[0] = v1
[1]*v2
[2] - v1
[2]*v2
[1];
1860 result
[1] = v1
[2]*v2
[0] - v1
[0]*v2
[2];
1861 result
[2] = v1
[0]*v2
[1] - v1
[1]*v2
[0];
1866 __gluLookAt(GLdouble eyex
, GLdouble eyey
, GLdouble eyez
, GLdouble centerx
,
1867 GLdouble centery
, GLdouble centerz
, GLdouble upx
, GLdouble upy
,
1871 float forward
[3], side
[3], up
[3];
1874 forward
[0] = centerx
- eyex
;
1875 forward
[1] = centery
- eyey
;
1876 forward
[2] = centerz
- eyez
;
1884 /* Side = forward x up */
1885 cross(forward
, up
, side
);
1888 /* Recompute up as: up = side x forward */
1889 cross(side
, forward
, up
);
1891 __gluMakeIdentityf(&m
[0][0]);
1900 m
[0][2] = -forward
[0];
1901 m
[1][2] = -forward
[1];
1902 m
[2][2] = -forward
[2];
1904 glMultMatrixf(&m
[0][0]);
1905 glTranslated(-eyex
, -eyey
, -eyez
);
1908 GLfloat viewDistance
= 1.0;
1910 void WMesaShowStereo(GLuint list
)
1913 GLbitfield mask
= GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
;
1916 /* Must use double Buffer */
1917 if( ! Current
-> db_flag
)
1921 glGetIntegerv(GL_MATRIX_MODE
,&matrix_mode
);
1923 WMesaViewport(Current
->gl_ctx
,0,Current
->height
/2,
1924 Current
->width
,Current
->height
/2);
1925 if(matrix_mode
!=GL_MODELVIEW
)
1926 glMatrixMode(GL_MODELVIEW
);
1928 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1930 __gluLookAt(viewDistance
/2,0.0,0.0 ,
1931 viewDistance
/2,0.0,-1.0,
1933 glMultMatrixf( cm
);
1935 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
;
1938 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1940 __gluLookAt(-viewDistance
/2,0.0,0.0 ,
1941 -viewDistance
/2,0.0,-1.0,
1945 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
+ Current
->pitch
;
1947 if(matrix_mode
!=GL_MODELVIEW
)
1948 glMatrixMode(matrix_mode
);
1952 WMesaViewport(Current
->gl_ctx
,0,0,Current
->width
,Current
->height
);
1956 void toggleStereoMode()
1958 if(!Current
->db_flag
)
1962 if(stereoBuffer
==GL_FALSE
)
1963 #if !defined(NO_PARALLEL)
1967 Current
->ScanWidth
= Current
->pitch
*2;
1972 #if !defined(NO_PARALLEL)
1975 Current
->ScanWidth
= Current
->pitch
;
1976 Current
->pbPixels
= Current
->addrOffScreen
;
1980 /* if in stereo mode, the following function is called */
1981 void glShowStereo(GLuint list
)
1983 WMesaShowStereo(list
);
1986 #endif /* NO_STEREO */
1988 #if !defined(NO_PARALLEL)
1990 void toggleParallelMode(void)
1993 parallelFlag
= GL_TRUE
;
1994 if(parallelMachine
==GL_FALSE
){
1995 PRCreateRenderBuffer( Current
->rgb_flag
? GL_RGBA
:GL_COLOR_INDEX
,
1996 Current
->cColorBits
/8,
1997 Current
->width
,Current
->height
,
1999 Current
->rgb_flag
? Current
->pbPixels
:
2000 Current
->ScreenMem
);
2001 parallelMachine
= GL_TRUE
;
2005 parallelFlag
= GL_FALSE
;
2006 if(parallelMachine
==GL_TRUE
){
2007 PRDestroyRenderBuffer();
2008 parallelMachine
=GL_FALSE
;
2009 ReadyForNextFrame
= GL_TRUE
;
2012 /***********************************************
2013 * Seems something wrong!!!!
2014 ************************************************/
2016 WMesaMakeCurrent(Current
);
2017 #if !defined(NO_STEREO)
2018 stereo_flag
= GL_FALSE
;
2023 void PRShowRenderResult(void)
2026 if(!glImageRendered())
2035 #endif /* NO_PARALLEL */
2037 BYTE
DITHER_RGB_2_8BIT( int red
, int green
, int blue
, int pixel
, int scanline
)
2039 char unsigned redtemp
, greentemp
, bluetemp
, paletteindex
;
2041 //*** now, look up each value in the halftone matrix
2042 //*** using an 8x8 ordered dither.
2043 redtemp
= aDividedBy51
[red
]
2044 + (aModulo51
[red
] > aHalftone8x8
[(pixel
%8)*8
2046 greentemp
= aDividedBy51
[(char unsigned)green
]
2047 + (aModulo51
[green
] > aHalftone8x8
[
2048 (pixel
%8)*8 + scanline
%8]);
2049 bluetemp
= aDividedBy51
[(char unsigned)blue
]
2050 + (aModulo51
[blue
] > aHalftone8x8
[
2051 (pixel
%8)*8 +scanline
%8]);
2053 //*** recombine the halftoned rgb values into a palette index
2055 redtemp
+ aTimes6
[greentemp
] + aTimes36
[bluetemp
];
2057 //*** and translate through the wing halftone palette
2058 //*** translation vector to give the correct value.
2059 return aWinGHalftoneTranslation
[paletteindex
];
2066 * restore all lost objects
2068 HRESULT
DDRestoreAll( WMesaContext wc
)
2072 ddrval
= wc
->lpDDSPrimary
->lpVtbl
->Restore(wc
->lpDDSPrimary
);
2073 if( ddrval
== DD_OK
)
2075 ddrval
= wc
->lpDDSOffScreen
->lpVtbl
->Restore(wc
->lpDDSOffScreen
);
2083 * This function is called if the initialization function fails
2085 BOOL
initFail( HWND hwnd
, WMesaContext wc
)
2088 MessageBox( hwnd
, "DirectDraw Init FAILED", "", MB_OK
);
2094 static void DDDeleteOffScreen(WMesaContext wc
)
2096 if( wc
->lpDDSOffScreen
!= NULL
)
2098 wc
->lpDDSOffScreen
->lpVtbl
->Unlock(wc
->lpDDSOffScreen
,NULL
);
2099 wc
->lpDDSOffScreen
->lpVtbl
->Release(wc
->lpDDSOffScreen
);
2100 wc
->lpDDSOffScreen
= NULL
;
2105 static void DDFreePrimarySurface(WMesaContext wc
)
2107 if( wc
->lpDDSPrimary
!= NULL
)
2109 if(wc
->db_flag
== GL_FALSE
)
2110 wc
->lpDDSPrimary
->lpVtbl
->ReleaseDC(wc
->lpDDSPrimary
, wc
->hDC
);
2111 wc
->lpDDSPrimary
->lpVtbl
->Release(wc
->lpDDSPrimary
);
2112 wc
->lpDDSPrimary
= NULL
;
2116 static BOOL
DDCreatePrimarySurface(WMesaContext wc
)
2120 wc
->ddsd
.dwSize
= sizeof( wc
->ddsd
);
2121 wc
->ddsd
.dwFlags
= DDSD_CAPS
;
2122 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2124 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
,&(wc
->ddsd
),
2125 &(wc
->lpDDSPrimary
), NULL
);
2126 if( ddrval
!= DD_OK
)
2128 return initFail(wc
->hwnd
, wc
);
2130 if(wc
->db_flag
== GL_FALSE
)
2131 wc
->lpDDSPrimary
->lpVtbl
->GetDC(wc
->lpDDSPrimary
, &(wc
->hDC
));
2135 static BOOL
DDCreateOffScreen(WMesaContext wc
)
2139 if(wc
->lpDD
== NULL
)
2141 GetClientRect( wc
->hwnd
, &(wc
->rectOffScreen
) );
2142 wc
->ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
2143 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
2144 wc
->ddsd
.dwHeight
= wc
->rectOffScreen
.bottom
- wc
->rectOffScreen
.top
;
2145 wc
->ddsd
.dwWidth
= wc
->rectOffScreen
.right
- wc
->rectOffScreen
.left
;
2147 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
, &(wc
->ddsd
),
2148 &(wc
->lpDDSOffScreen
), NULL
);
2149 if( ddrval
!= DD_OK
)
2154 while (wc
->lpDDSOffScreen
->lpVtbl
->Lock(wc
->lpDDSOffScreen
,NULL
,
2155 &(wc
->ddsd
), 0, NULL
) ==
2156 DDERR_WASSTILLDRAWING
)
2159 if(wc
->ddsd
.lpSurface
==NULL
)
2160 return initFail(wc
->hwnd
, wc
);
2162 wc
->ScreenMem
= wc
->pbPixels
= wc
->addrOffScreen
=
2163 (PBYTE
)(wc
->ddsd
.lpSurface
);
2164 wc
->ScanWidth
= wc
->pitch
= wc
->ddsd
.lPitch
;
2166 wc
->ScanWidth
= wc
->ddsd
.lPitch
*2;
2168 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2170 ClientToScreen( wc
->hwnd
, &pt
);
2171 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2172 wmSetPixelFormat(wc
, wc
->hDC
);
2177 struct tagWMesaContextList
2180 struct tagWMesaContextList
*next
;
2183 WMesaContextList
*head
= 0;
2185 void AddContext(WMesaContext wc
)
2187 WMesaContextList
*lst
= (WMesaContextList
*)malloc(sizeof(WMesaContextList
));
2194 WMesaContext
FindContext(HWND hWnd
)
2196 WMesaContextList
*tmp
= head
;
2199 if( tmp
->wc
->hwnd
== hWnd
)
2206 void RemoveContext(HWND hWnd
)
2208 WMesaContextList
*tmp
= head
;
2211 if( tmp
->wc
->hwnd
== hWnd
)
2213 WMesaContextList
*lst
= tmp
;
2221 if( tmp
->next
->wc
->hwnd
== hWnd
)
2223 WMesaContextList
*lst
= tmp
->next
;
2224 tmp
->next
= tmp
->next
->next
;
2232 static LRESULT CALLBACK
MyWndProc(HWND hwnd
,UINT message
,WPARAM wParam
, LPARAM lParam
)
2234 WMesaContext wc
= Current
->hwnd
== hwnd
? Current
: FindContext(hwnd
);
2237 LRESULT lret
= CallWindowProc((WNDPROC
)(wc
->oldWndProc
),hwnd
,message
,wParam
,lParam
);
2238 if( message
= WM_MOVE
)
2241 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2242 ClientToScreen( hwnd
, &pt
);
2243 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2251 * doInit - do work required for every instance of the application:
2252 * create the window, initialize data
2254 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
)
2257 // DWORD dwFrequency;
2259 // LPDIRECTDRAW lpDD; // DirectDraw object
2260 // LPDIRECTDRAW2 lpDD2;
2261 LPDIRECTDRAWCLIPPER pcClipper
= NULL
;
2263 wc
->fullScreen
= displayOptions
.fullScreen
;
2264 wc
->gMode
= displayOptions
.mode
;
2266 stereo_flag
= displayOptions
.stereo
;
2267 if(wc
->db_flag
!= GL_TRUE
)
2268 stereo_flag
= GL_FALSE
;
2270 * create the main DirectDraw object
2272 ddrval
= DirectDrawCreate( NULL
, &(wc
->lpDD
), NULL
);
2273 if( ddrval
!= DD_OK
)
2275 return initFail(hwnd
,wc
);
2278 // Get exclusive mode if requested
2281 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
,
2287 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
,
2290 if( ddrval
!= DD_OK
)
2292 return initFail(hwnd
, wc
);
2297 return initFail(hwnd
, wc
);
2303 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 640, 480,
2304 displayOptions
.bpp
);
2307 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 800, 600,
2308 displayOptions
.bpp
);
2311 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1024, 768,
2312 displayOptions
.bpp
);
2315 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1152, 864,
2316 displayOptions
.bpp
);
2319 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1280, 1024,
2320 displayOptions
.bpp
);
2324 if( ddrval
!= DD_OK
)
2326 printf("Can't modify display mode, current mode used\n");
2329 case DDERR_INVALIDOBJECT
:
2331 case DDERR_INVALIDPARAMS
:
2333 case DDERR_UNSUPPORTEDMODE
:
2337 if(DDCreatePrimarySurface(wc
) == GL_FALSE
)
2338 return initFail(hwnd
, wc
);
2341 DDCreateOffScreen(wc
);
2343 if( FAILED( ddrval
= wc
->lpDD
->lpVtbl
->CreateClipper(wc
->lpDD
, 0, &pcClipper
, NULL
) ) )
2346 if( FAILED( ddrval
= pcClipper
->lpVtbl
->SetHWnd(pcClipper
, 0, wc
->hwnd
) ) )
2348 pcClipper
->lpVtbl
->Release(pcClipper
);
2352 if( FAILED( ddrval
= wc
->lpDDSPrimary
->lpVtbl
->SetClipper(wc
->lpDDSPrimary
, pcClipper
) ) )
2354 pcClipper
->lpVtbl
->Release(pcClipper
);
2358 // Done with clipper
2359 pcClipper
->lpVtbl
->Release(pcClipper
);
2361 // Hook the window so we can update the drawing rectangle when the window moves
2362 wc
->oldWndProc
= SetWindowLong(wc
->hwnd
,GWL_WNDPROC
,(LONG
)MyWndProc
);
2368 static void DDFree( WMesaContext wc
)
2370 RemoveContext(wc
->hwnd
);
2371 SetWindowLong(wc
->hwnd
,GWL_WNDPROC
,(LONG
)(wc
->oldWndProc
));
2373 if( wc
->lpDD
!= NULL
)
2375 DDFreePrimarySurface(wc
);
2376 DDDeleteOffScreen(wc
);
2377 wc
->lpDD
->lpVtbl
->Release(wc
->lpDD
);
2380 // Clean up the screen on exit
2381 RedrawWindow( NULL
, NULL
, NULL
, RDW_INVALIDATE
| RDW_ERASE
|
2387 void WMesaMove(void)
2389 WMesaContext wc
= Current
;
2391 if (Current
!= NULL
){
2392 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2394 ClientToScreen( wc
->hwnd
, &pt
);
2395 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2400 /************************************************
2401 * Mesa 4.0 - These triangle rasterizers are not
2402 * implemented in this version of the Windows
2403 * driver. They could be implemented for a
2404 * potential performance improvement.
2405 * See OSMesa for an example of the approach
2407 * This old code is left in this file in case
2408 * it is useful. However, it may end up looking
2409 * a lot more like the OSMesa code.
2410 ************************************************/
2413 #if defined(FAST_RASTERIZERS)
2417 * Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable
2420 #define PACK_8B8G8R( R, G, B ) ( ((B) << 16) | ((G) << 8) | (R) )
2422 /**********************************************************************/
2423 /*** Triangle rendering ***/
2424 /**********************************************************************/
2427 * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
2429 static void smooth_8A8B8G8R_z_triangle( GLcontext
*ctx
,
2430 GLuint v0
, GLuint v1
, GLuint v2
,
2433 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2435 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
2436 #define INTERP_RGB 1
2437 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2438 #define PIXEL_TYPE GLuint
2439 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2440 #define BYTES_PER_ROW (wmesa->ScanWidth)
2441 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2443 GLint i, len = RIGHT-LEFT; \
2444 for (i=0;i<len;i++) { \
2445 GLdepth z = FixedToDepth(ffz); \
2446 if (z < zRow[i]) { \
2447 pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2448 FixedToInt(ffb) ); \
2451 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2457 #include "tritemp.h"
2461 // #include "..\tritemp.h"
2463 #include "tritemp.h"
2470 * XImage, smooth, depth-buffered, PF_8R8G8B triangle.
2472 static void smooth_8R8G8B_z_triangle( GLcontext
*ctx
,
2473 GLuint v0
, GLuint v1
, GLuint v2
,
2476 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2478 #define INTERP_RGB 1
2479 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2480 #define PIXEL_TYPE GLuint
2481 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2482 #define BYTES_PER_ROW (wmesa->ScanWidth)
2483 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2485 GLint i, len = RIGHT-LEFT; \
2486 for (i=0;i<len;i++) { \
2487 GLdepth z = FixedToDepth(ffz); \
2488 if (z < zRow[i]) { \
2489 pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2490 FixedToInt(ffb) ); \
2493 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2498 #include "tritemp.h"
2502 // #include "..\tritemp.h"
2504 #include "tritemp.h"
2512 * XImage, smooth, depth-buffered, PF_5R6G5B triangle.
2514 static void smooth_5R6G5B_z_triangle( GLcontext
*ctx
,
2515 GLuint v0
, GLuint v1
, GLuint v2
,
2518 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2520 #define INTERP_RGB 1
2521 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2522 #define PIXEL_TYPE GLushort
2523 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2524 #define BYTES_PER_ROW (wmesa->ScanWidth)
2525 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2527 GLint i, len = RIGHT-LEFT; \
2528 for (i=0;i<len;i++) { \
2529 GLdepth z = FixedToDepth(ffz); \
2530 if (z < zRow[i]) { \
2531 pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2532 FixedToInt(ffb) ); \
2535 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2540 #include "tritemp.h"
2544 // #include "..\tritemp.h"
2546 #include "tritemp.h"
2552 * XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
2554 static void flat_8A8B8G8R_z_triangle( GLcontext
*ctx
, GLuint v0
,
2555 GLuint v1
, GLuint v2
, GLuint pv
)
2557 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2559 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2560 #define PIXEL_TYPE GLuint
2561 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2562 #define BYTES_PER_ROW (wmesa->ScanWidth)
2563 #define SETUP_CODE \
2564 unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \
2565 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2566 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2568 GLint i, len = RIGHT-LEFT; \
2569 for (i=0;i<len;i++) { \
2570 GLdepth z = FixedToDepth(ffz); \
2571 if (z < zRow[i]) { \
2579 #include "tritemp.h"
2583 // #include "..\tritemp.h"
2585 #include "tritemp.h"
2592 * XImage, flat, depth-buffered, PF_8R8G8B triangle.
2594 static void flat_8R8G8B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2595 GLuint v2
, GLuint pv
)
2597 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2599 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2600 #define PIXEL_TYPE GLuint
2601 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2602 #define BYTES_PER_ROW (wmesa->ScanWidth)
2603 #define SETUP_CODE \
2604 unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \
2605 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2606 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2608 GLint i, len = RIGHT-LEFT; \
2609 for (i=0;i<len;i++) { \
2610 GLdepth z = FixedToDepth(ffz); \
2611 if (z < zRow[i]) { \
2619 #include "tritemp.h"
2623 // #include "..\tritemp.h"
2625 #include "tritemp.h"
2632 * XImage, flat, depth-buffered, PF_5R6G5B triangle.
2634 static void flat_5R6G5B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2635 GLuint v2
, GLuint pv
)
2637 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2639 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2640 #define PIXEL_TYPE GLushort
2641 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2642 #define BYTES_PER_ROW (wmesa->ScanWidth)
2643 #define SETUP_CODE \
2644 unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \
2645 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2646 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2648 GLint i, len = RIGHT-LEFT; \
2649 for (i=0;i<len;i++) { \
2650 GLdepth z = FixedToDepth(ffz); \
2651 if (z < zRow[i]) { \
2659 #include "tritemp.h"
2663 // #include "..\tritemp.h"
2665 #include "tritemp.h"
2672 * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
2674 static void smooth_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2675 GLuint v2
, GLuint pv
)
2677 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2678 #define INTERP_RGB 1
2679 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2680 #define PIXEL_TYPE GLuint
2681 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2682 #define BYTES_PER_ROW (wmesa->ScanWidth)
2683 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2686 PIXEL_TYPE *pixel = pRow; \
2687 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2688 *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2689 FixedToInt(ffb) ); \
2690 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2694 #include "tritemp.h"
2698 // #include "..\tritemp.h"
2700 #include "tritemp.h"
2707 * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
2709 static void smooth_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2710 GLuint v2
, GLuint pv
)
2712 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2713 #define INTERP_RGB 1
2714 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2715 #define PIXEL_TYPE GLuint
2716 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2717 #define BYTES_PER_ROW (wmesa->ScanWidth)
2718 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2721 PIXEL_TYPE *pixel = pRow; \
2722 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2723 *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2724 FixedToInt(ffb) ); \
2725 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2729 #include "tritemp.h"
2733 // #include "..\tritemp.h"
2735 #include "tritemp.h"
2742 * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
2744 static void smooth_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2745 GLuint v2
, GLuint pv
)
2747 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2748 #define INTERP_RGB 1
2749 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2750 #define PIXEL_TYPE GLushort
2751 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2752 #define BYTES_PER_ROW (wmesa->ScanWidth)
2753 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2756 PIXEL_TYPE *pixel = pRow; \
2757 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2758 *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2759 FixedToInt(ffb) ); \
2760 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2764 #include "tritemp.h"
2768 // #include "..\tritemp.h"
2770 #include "tritemp.h"
2778 * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
2780 static void flat_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
,
2781 GLuint v1
, GLuint v2
, GLuint pv
)
2783 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2784 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2785 #define PIXEL_TYPE GLuint
2786 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2787 #define BYTES_PER_ROW (wmesa->ScanWidth)
2788 #define SETUP_CODE \
2789 unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \
2790 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2791 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2794 PIXEL_TYPE *pixel = pRow; \
2795 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2801 #include "tritemp.h"
2805 // #include "..\tritemp.h"
2807 #include "tritemp.h"
2814 * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
2816 static void flat_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2817 GLuint v2
, GLuint pv
)
2819 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2820 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2821 #define PIXEL_TYPE GLuint
2822 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2823 #define BYTES_PER_ROW (wmesa->ScanWidth)
2824 #define SETUP_CODE \
2825 unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \
2826 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2827 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2830 PIXEL_TYPE *pixel = pRow; \
2831 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2836 #include "tritemp.h"
2840 // #include "..\tritemp.h"
2842 #include "tritemp.h"
2849 * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
2851 static void flat_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2852 GLuint v2
, GLuint pv
)
2854 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2855 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2856 #define PIXEL_TYPE GLushort
2857 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2858 #define BYTES_PER_ROW (wmesa->ScanWidth)
2859 #define SETUP_CODE \
2860 unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \
2861 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2862 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2865 PIXEL_TYPE *pixel = pRow; \
2866 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2871 #include "tritemp.h"
2875 // #include "..\tritemp.h"
2877 #include "tritemp.h"
2884 * XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
2887 static void smooth_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2888 GLuint v2
, GLuint pv
)
2890 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2892 #define INTERP_INDEX 1
2893 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2894 #define PIXEL_TYPE GLubyte
2895 #define BYTES_PER_ROW (wmesa->ScanWidth)
2896 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2898 GLint i, len = RIGHT-LEFT; \
2899 for (i=0;i<len;i++) { \
2900 GLdepth z = FixedToDepth(ffz); \
2901 if (z < zRow[i]) { \
2902 pRow[i] = FixedToInt(ffi); \
2910 #include "tritemp.h"
2914 // #include "..\tritemp.h"
2916 #include "tritemp.h"
2923 * XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
2926 static void flat_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2927 GLuint v2
, GLuint pv
)
2929 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2931 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2932 #define PIXEL_TYPE GLubyte
2933 #define BYTES_PER_ROW (wmesa->ScanWidth)
2934 #define SETUP_CODE \
2935 GLuint index = VB->IndexPtr->data[pv]; \
2936 (*ctx->Driver.Index)( ctx, index );
2937 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2939 GLint i, len = RIGHT-LEFT; \
2940 for (i=0;i<len;i++) { \
2941 GLdepth z = FixedToDepth(ffz); \
2942 if (z < zRow[i]) { \
2950 #include "tritemp.h"
2954 // #include "..\tritemp.h"
2956 #include "tritemp.h"
2964 * XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2967 static void smooth_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2968 GLuint v2
, GLuint pv
)
2970 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2972 #define INTERP_INDEX 1
2973 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2974 #define PIXEL_TYPE GLubyte
2975 #define BYTES_PER_ROW (wmesa->ScanWidth)
2976 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2979 PIXEL_TYPE *pixel = pRow; \
2980 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2981 *pixel = FixedToInt(ffi); \
2986 #include "tritemp.h"
2990 // #include "..\tritemp.h"
2992 #include "tritemp.h"
2999 * XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
3001 static void flat_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
3002 GLuint v2
, GLuint pv
)
3004 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3006 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3007 #define PIXEL_TYPE GLubyte
3008 #define BYTES_PER_ROW (wmesa->ScanWidth)
3009 #define SETUP_CODE \
3010 GLuint index = VB->IndexPtr->data[pv]; \
3011 (*ctx->Driver.Index)( ctx, index );
3012 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3015 PIXEL_TYPE *pixel = pRow; \
3016 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
3021 #include "tritemp.h"
3025 // #include "..\tritemp.h"
3027 #include "tritemp.h"
3033 * XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
3035 static void smooth_DITHER8_z_triangle( GLcontext
*ctx
,
3036 GLuint v0
, GLuint v1
, GLuint v2
,
3039 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3040 DITHER_RGB_TO_8BIT_SETUP
3042 #define INTERP_RGB 1
3043 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3044 #define PIXEL_TYPE GLubyte
3045 #define BYTES_PER_ROW (wmesa->ScanWidth)
3046 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3048 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
3049 for (i=0;i<len;i++,xx++) { \
3050 GLdepth z = FixedToDepth(ffz); \
3051 if (z < zRow[i]) { \
3052 DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg), \
3053 FixedToInt(ffb), xx, yy); \
3054 pRow[i] = pixelDithered; \
3057 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
3062 #include "tritemp.h"
3066 // #include "..\tritemp.h"
3068 #include "tritemp.h"
3074 * XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
3076 static void flat_DITHER8_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
3077 GLuint v2
, GLuint pv
)
3079 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3080 DITHER_RGB_TO_8BIT_SETUP
3082 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3083 #define PIXEL_TYPE GLubyte
3084 #define BYTES_PER_ROW (wmesa->ScanWidth)
3086 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3088 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
3089 for (i=0;i<len;i++,xx++) { \
3090 GLdepth z = FixedToDepth(ffz); \
3091 if (z < zRow[i]) { \
3092 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \
3093 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \
3094 pRow[i] = pixelDithered; \
3101 #include "tritemp.h"
3105 // #include "..\tritemp.h"
3107 #include "tritemp.h"
3113 * XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
3115 static void smooth_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
3116 GLuint v2
, GLuint pv
)
3118 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3119 DITHER_RGB_TO_8BIT_SETUP
3120 #define INTERP_RGB 1
3121 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3122 #define PIXEL_TYPE GLubyte
3123 #define BYTES_PER_ROW (wmesa->ScanWidth)
3124 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3126 GLint xx, yy = FLIP(Y); \
3127 PIXEL_TYPE *pixel = pRow; \
3128 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
3129 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy);\
3130 *pixel = pixelDithered; \
3131 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
3135 #include "tritemp.h"
3139 // #include "..\tritemp.h"
3141 #include "tritemp.h"
3147 * XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
3150 static void flat_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
3151 GLuint v2
, GLuint pv
)
3153 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3154 DITHER_RGB_TO_8BIT_SETUP
3155 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3156 #define PIXEL_TYPE GLubyte
3157 #define BYTES_PER_ROW (wmesa->ScanWidth)
3159 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3161 GLint xx, yy = FLIP(Y); \
3162 PIXEL_TYPE *pixel = pRow; \
3163 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
3164 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \
3165 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \
3166 *pixel = pixelDithered; \
3170 #include "tritemp.h"
3174 // #include "..\tritemp.h"
3176 #include "tritemp.h"
3182 /************** END DEAD TRIANGLE CODE ***********************/
3184 static triangle_func
choose_triangle_function( GLcontext
*ctx
)
3187 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3188 int depth
= wmesa
->cColorBits
;
3190 if (ctx
->Polygon
.SmoothFlag
) return NULL
;
3191 if (ctx
->Texture
._EnabledUnits
) return NULL
;
3192 if (!wmesa
->db_flag
) return NULL
;
3193 if (ctx
->swrast
->_RasterMask
& MULTI_DRAW_BIT
) return NULL
;
3195 /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {
3196 if ( ctx
->Light
.ShadeModel
==GL_SMOOTH
3197 && ctx
->_RasterMask
==DEPTH_BIT
3198 && ctx
->Depth
.Func
==GL_LESS
3199 && ctx
->Depth
.Mask
==GL_TRUE
3200 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
3201 switch (wmesa
->pixelformat
) {
3203 return smooth_8A8B8G8R_z_triangle
;
3205 return smooth_8R8G8B_z_triangle
;
3207 return smooth_5R6G5B_z_triangle
;
3209 return smooth_DITHER8_z_triangle
;
3211 return smooth_ci_z_triangle
;
3216 if ( ctx
->Light
.ShadeModel
==GL_FLAT
3217 && ctx
->_RasterMask
==DEPTH_BIT
3218 && ctx
->Depth
.Func
==GL_LESS
3219 && ctx
->Depth
.Mask
==GL_TRUE
3220 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
3221 switch (wmesa
->pixelformat
) {
3223 return flat_8A8B8G8R_z_triangle
;
3225 return flat_8R8G8B_z_triangle
;
3227 return flat_5R6G5B_z_triangle
;
3229 return flat_DITHER8_z_triangle
;
3231 return flat_ci_z_triangle
;
3236 if ( ctx
->_RasterMask
==0 /* no depth test */
3237 && ctx
->Light
.ShadeModel
==GL_SMOOTH
3238 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
3239 switch (wmesa
->pixelformat
) {
3241 return smooth_8A8B8G8R_triangle
;
3243 return smooth_8R8G8B_triangle
;
3245 return smooth_5R6G5B_triangle
;
3247 return smooth_DITHER8_triangle
;
3249 return smooth_ci_triangle
;
3255 if ( ctx
->_RasterMask
==0 /* no depth test */
3256 && ctx
->Light
.ShadeModel
==GL_FLAT
3257 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
3258 switch (wmesa
->pixelformat
) {
3260 return flat_8A8B8G8R_triangle
;
3262 return flat_8R8G8B_triangle
;
3264 return flat_5R6G5B_triangle
;
3266 return flat_DITHER8_triangle
;
3268 return flat_ci_triangle
;
3280 * Define a new viewport and reallocate auxillary buffers if the size of
3281 * the window (color buffer) has changed.
3283 void WMesaViewport( GLcontext
*ctx
,
3284 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
3286 assert(0); /* I don't think that this is being used. */
3289 ctx
->Viewport
.X
= x
;
3290 ctx
->Viewport
.Width
= width
;
3291 ctx
->Viewport
.Y
= y
;
3292 ctx
->Viewport
.Height
= height
;
3294 /* compute scale and bias values */
3295 /* Pre-Keith 3.1 changes
3296 ctx->Viewport.Map.m[Sx] = (GLfloat) width / 2.0F;
3297 ctx->Viewport.Map.m[Tx] = ctx->Viewport.Sx + x;
3298 ctx->Viewport.Map.m[Sy] = (GLfloat) height / 2.0F;
3299 ctx->Viewport.Map.m[Ty] = ctx->Viewport.Sy + y;
3301 ctx
->Viewport
.WindowMap
.m
[MAT_SX
] = (GLfloat
) width
/ 2.0F
;
3302 ctx
->Viewport
.WindowMap
.m
[MAT_TX
] = ctx
->Viewport
.WindowMap
.m
[MAT_SX
] + x
;
3303 ctx
->Viewport
.WindowMap
.m
[MAT_SY
] = (GLfloat
) height
/ 2.0F
;
3304 ctx
->Viewport
.WindowMap
.m
[MAT_TY
] = ctx
->Viewport
.WindowMap
.m
[MAT_SY
] + y
;