1 /* $Id: wmesa.c,v 1.35 2002/09/12 17:05:55 kschultz 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
.CopyTexImage1D
= _swrast_copy_teximage1d
;
1049 ctx
->Driver
.CopyTexImage2D
= _swrast_copy_teximage2d
;
1050 ctx
->Driver
.CopyTexSubImage1D
= _swrast_copy_texsubimage1d
;
1051 ctx
->Driver
.CopyTexSubImage2D
= _swrast_copy_texsubimage2d
;
1052 ctx
->Driver
.CopyTexSubImage3D
= _swrast_copy_texsubimage3d
;
1053 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1054 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1055 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1056 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;
1058 ctx
->Driver
.BaseCompressedTexFormat
= _mesa_base_compressed_texformat
;
1059 ctx
->Driver
.CompressedTextureSize
= _mesa_compressed_texture_size
;
1060 ctx
->Driver
.GetCompressedTexImage
= _mesa_get_compressed_teximage
;
1063 swdd
->SetBuffer
= set_buffer
;
1066 /* Pixel/span writing functions: */
1067 swdd
->WriteRGBASpan
= write_rgba_span
;
1068 swdd
->WriteRGBSpan
= write_rgb_span
;
1069 swdd
->WriteMonoRGBASpan
= write_mono_rgba_span
;
1070 swdd
->WriteRGBAPixels
= write_rgba_pixels
;
1071 swdd
->WriteMonoRGBAPixels
= write_mono_rgba_pixels
;
1072 swdd
->WriteCI32Span
= write_ci32_span
;
1073 swdd
->WriteCI8Span
= write_ci8_span
;
1074 swdd
->WriteMonoCISpan
= write_mono_ci_span
;
1075 swdd
->WriteCI32Pixels
= write_ci32_pixels
;
1076 swdd
->WriteMonoCIPixels
= write_mono_ci_pixels
;
1078 swdd
->ReadCI32Span
= read_ci32_span
;
1079 swdd
->ReadRGBASpan
= read_rgba_span
;
1080 swdd
->ReadCI32Pixels
= read_ci32_pixels
;
1081 swdd
->ReadRGBAPixels
= read_rgba_pixels
;
1085 static void wmesa_update_state( GLcontext
*ctx
, GLuint new_state
)
1087 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference( ctx
);
1088 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1091 * XXX these function pointers could be initialized just once during
1092 * context creation since they don't depend on any state changes.
1093 * kws - This is true - this function gets called a lot and it
1094 * would be good to minimize setting all this when not needed.
1096 #ifndef SET_FPOINTERS_ONCE
1097 SetFunctionPointers(ctx
);
1099 ctx
->Driver
.GetString
= get_string
;
1100 ctx
->Driver
.UpdateState
= wmesa_update_state
;
1101 ctx
->Driver
.ResizeBuffers
= _swrast_alloc_buffers
;
1102 ctx
->Driver
.GetBufferSize
= buffer_size
;
1104 ctx
->Driver
.Accum
= _swrast_Accum
;
1105 ctx
->Driver
.Bitmap
= _swrast_Bitmap
;
1106 ctx
->Driver
.Clear
= clear
;
1108 ctx
->Driver
.Flush
= flush
;
1109 ctx
->Driver
.ClearIndex
= clear_index
;
1110 ctx
->Driver
.ClearColor
= clear_color
;
1111 ctx
->Driver
.Enable
= enable
;
1113 ctx
->Driver
.CopyPixels
= _swrast_CopyPixels
;
1114 ctx
->Driver
.DrawPixels
= _swrast_DrawPixels
;
1115 ctx
->Driver
.ReadPixels
= _swrast_ReadPixels
;
1117 ctx
->Driver
.ChooseTextureFormat
= _mesa_choose_tex_format
;
1118 ctx
->Driver
.TexImage1D
= _mesa_store_teximage1d
;
1119 ctx
->Driver
.TexImage2D
= _mesa_store_teximage2d
;
1120 ctx
->Driver
.TexImage3D
= _mesa_store_teximage3d
;
1121 ctx
->Driver
.TexSubImage1D
= _mesa_store_texsubimage1d
;
1122 ctx
->Driver
.TexSubImage2D
= _mesa_store_texsubimage2d
;
1123 ctx
->Driver
.TexSubImage3D
= _mesa_store_texsubimage3d
;
1124 ctx
->Driver
.TestProxyTexImage
= _mesa_test_proxy_teximage
;
1126 ctx
->Driver
.CopyTexImage1D
= _swrast_copy_teximage1d
;
1127 ctx
->Driver
.CopyTexImage2D
= _swrast_copy_teximage2d
;
1128 ctx
->Driver
.CopyTexSubImage1D
= _swrast_copy_texsubimage1d
;
1129 ctx
->Driver
.CopyTexSubImage2D
= _swrast_copy_texsubimage2d
;
1130 ctx
->Driver
.CopyTexSubImage3D
= _swrast_copy_texsubimage3d
;
1131 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1132 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1133 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1134 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;
1136 ctx
->Driver
.BaseCompressedTexFormat
= _mesa_base_compressed_texformat
;
1137 ctx
->Driver
.CompressedTextureSize
= _mesa_compressed_texture_size
;
1138 ctx
->Driver
.GetCompressedTexImage
= _mesa_get_compressed_teximage
;
1140 swdd
->SetBuffer
= set_buffer
;
1142 /* Pixel/span writing functions: */
1143 swdd
->WriteRGBASpan
= write_rgba_span
;
1144 swdd
->WriteRGBSpan
= write_rgb_span
;
1145 swdd
->WriteMonoRGBASpan
= write_mono_rgba_span
;
1146 swdd
->WriteRGBAPixels
= write_rgba_pixels
;
1147 swdd
->WriteMonoRGBAPixels
= write_mono_rgba_pixels
;
1148 swdd
->WriteCI32Span
= write_ci32_span
;
1149 swdd
->WriteCI8Span
= write_ci8_span
;
1150 swdd
->WriteMonoCISpan
= write_mono_ci_span
;
1151 swdd
->WriteCI32Pixels
= write_ci32_pixels
;
1152 swdd
->WriteMonoCIPixels
= write_mono_ci_pixels
;
1154 swdd
->ReadCI32Span
= read_ci32_span
;
1155 swdd
->ReadRGBASpan
= read_rgba_span
;
1156 swdd
->ReadCI32Pixels
= read_ci32_pixels
;
1157 swdd
->ReadRGBAPixels
= read_rgba_pixels
;
1159 #endif // !SET_FPOINTERS_ONCE
1160 tnl
->Driver
.RunPipeline
= _tnl_run_pipeline
;
1162 _swrast_InvalidateState( ctx
, new_state
);
1163 _swsetup_InvalidateState( ctx
, new_state
);
1164 _ac_InvalidateState( ctx
, new_state
);
1165 _tnl_InvalidateState( ctx
, new_state
);
1171 /**********************************************************************/
1172 /***** WMesa API Functions *****/
1173 /**********************************************************************/
1177 #define PAL_SIZE 256
1178 static void GetPalette(HPALETTE Pal
,RGBQUAD
*aRGB
)
1185 WORD NumberOfEntries
;
1186 PALETTEENTRY aEntries
[PAL_SIZE
];
1194 GetPaletteEntries(Pal
,0,PAL_SIZE
,Palette
.aEntries
);
1196 GetSystemPaletteEntries(hdc
,0,PAL_SIZE
,Palette
.aEntries
);
1197 if (GetSystemPaletteUse(hdc
) == SYSPAL_NOSTATIC
)
1199 for(i
= 0; i
<PAL_SIZE
; i
++)
1200 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1201 Palette
.aEntries
[255].peRed
= 255;
1202 Palette
.aEntries
[255].peGreen
= 255;
1203 Palette
.aEntries
[255].peBlue
= 255;
1204 Palette
.aEntries
[255].peFlags
= 0;
1205 Palette
.aEntries
[0].peRed
= 0;
1206 Palette
.aEntries
[0].peGreen
= 0;
1207 Palette
.aEntries
[0].peBlue
= 0;
1208 Palette
.aEntries
[0].peFlags
= 0;
1214 nStaticColors
= GetDeviceCaps(hdc
, NUMCOLORS
)/2;
1215 for (i
=0; i
<nStaticColors
; i
++)
1216 Palette
.aEntries
[i
].peFlags
= 0;
1217 nUsableColors
= PAL_SIZE
-nStaticColors
;
1218 for (; i
<nUsableColors
; i
++)
1219 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1220 for (; i
<PAL_SIZE
-nStaticColors
; i
++)
1221 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1222 for (i
=PAL_SIZE
-nStaticColors
; i
<PAL_SIZE
; i
++)
1223 Palette
.aEntries
[i
].peFlags
= 0;
1225 ReleaseDC(NULL
,hdc
);
1226 for (i
=0; i
<PAL_SIZE
; i
++)
1228 aRGB
[i
].rgbRed
=Palette
.aEntries
[i
].peRed
;
1229 aRGB
[i
].rgbGreen
=Palette
.aEntries
[i
].peGreen
;
1230 aRGB
[i
].rgbBlue
=Palette
.aEntries
[i
].peBlue
;
1231 aRGB
[i
].rgbReserved
=Palette
.aEntries
[i
].peFlags
;
1236 WMesaContext
WMesaCreateContext( HWND hWnd
, HPALETTE
* Pal
,
1239 GLboolean alpha_flag
)
1243 GLboolean true_color_flag
;
1244 __GLimports imports
;
1246 c
= (struct wmesa_context
* ) calloc(1,sizeof(struct wmesa_context
));
1251 c
->hDC
= GetDC(hWnd
);
1252 true_color_flag
= GetDeviceCaps(c
->hDC
, BITSPIXEL
) > 8;
1254 if(true_color_flag
) c
->rgb_flag
= rgb_flag
= GL_TRUE
;
1259 if ((true_color_flag
==GL_FALSE
) && (rgb_flag
== GL_TRUE
)){
1260 c
->dither_flag
= GL_TRUE
;
1262 c
->hPalHalfTone
= WinGCreateHalftonePalette();
1264 c
->hPalHalfTone
= CreateHalftonePalette(c
->hDC
);
1268 c
->dither_flag
= GL_FALSE
;
1270 c
->dither_flag
= GL_FALSE
;
1274 if (rgb_flag
==GL_FALSE
)
1276 c
->rgb_flag
= GL_FALSE
;
1278 /* Old WinG stuff???? */
1279 c
->db_flag
= db_flag
=GL_TRUE
; /* WinG requires double buffering */
1280 printf("Single buffer is not supported in color index mode, ",
1281 "setting to double buffer.\n");
1286 c
->rgb_flag
= GL_TRUE
;
1288 GetClientRect(c
->Window
,&CR
);
1290 c
->height
=CR
.bottom
;
1294 /* Double buffered */
1297 wmCreateBackingStore(c
, c
->width
, c
->height
);
1304 /* Single Buffered */
1309 if (DDInit(c
,hWnd
) == GL_FALSE
) {
1316 c
->gl_visual
= _mesa_create_visual(rgb_flag
,
1317 db_flag
, /* db_flag */
1318 GL_FALSE
, /* stereo */
1319 8,8,8, /* r, g, b bits */
1320 alpha_flag
? 8 : 0, /* alpha bits */
1322 16, /* depth_bits */
1323 8, /* stencil_bits */
1324 16,16,16,/* accum_bits */
1325 alpha_flag
? 16 : 0, /* alpha accum */
1328 if (!c
->gl_visual
) {
1332 _mesa_init_default_imports( &imports
, (void *) c
);
1334 /* allocate a new Mesa context */
1335 c
->gl_ctx
= _mesa_create_context( c
->gl_visual
, NULL
, &imports
);
1338 _mesa_destroy_visual( c
->gl_visual
);
1343 _mesa_enable_sw_extensions(c
->gl_ctx
);
1344 _mesa_enable_1_3_extensions(c
->gl_ctx
);
1346 c
->gl_buffer
= _mesa_create_framebuffer( c
->gl_visual
,
1347 c
->gl_visual
->depthBits
> 0,
1348 c
->gl_visual
->stencilBits
> 0,
1349 c
->gl_visual
->accumRedBits
> 0,
1350 alpha_flag
/* s/w alpha */ );
1351 if (!c
->gl_buffer
) {
1352 _mesa_destroy_visual( c
->gl_visual
);
1353 _mesa_free_context_data( c
->gl_ctx
);
1358 /* Initialize the software rasterizer and helper modules.
1361 GLcontext
*ctx
= c
->gl_ctx
;
1362 _swrast_CreateContext( ctx
);
1363 _ac_CreateContext( ctx
);
1364 _tnl_CreateContext( ctx
);
1365 _swsetup_CreateContext( ctx
);
1367 #ifdef SET_FPOINTERS_ONCE
1368 SetFunctionPointers(ctx
);
1369 #endif // SET_FPOINTERS_ONCE
1370 _swsetup_Wakeup( ctx
);
1372 #ifdef COMPILE_SETPIXEL
1378 void WMesaDestroyContext( void )
1380 WMesaContext c
= Current
;
1381 ReleaseDC(c
->Window
,c
->hDC
);
1383 if(c
->hPalHalfTone
!= NULL
)
1384 DeleteObject(c
->hPalHalfTone
);
1386 _swsetup_DestroyContext( c
->gl_ctx
);
1387 _tnl_DestroyContext( c
->gl_ctx
);
1388 _ac_DestroyContext( c
->gl_ctx
);
1389 _swrast_DestroyContext( c
->gl_ctx
);
1391 _mesa_destroy_visual( c
->gl_visual
);
1392 _mesa_destroy_framebuffer( c
->gl_buffer
);
1393 _mesa_free_context_data( c
->gl_ctx
);
1394 free( (void *) c
->gl_ctx
);
1400 wmDeleteBackingStore(c
);
1403 #if !defined(NO_PARALLEL)
1405 PRDestroyRenderBuffer();
1408 // Destroyed context no longer valid
1409 WMesaMakeCurrent( NULL
);
1413 void WMesaMakeCurrent( WMesaContext c
)
1424 wmesa_update_state(c
->gl_ctx
, 0);
1425 _mesa_make_current(c
->gl_ctx
, c
->gl_buffer
);
1426 if (Current
->gl_ctx
->Viewport
.Width
==0) {
1427 /* initialize viewport to window size */
1428 _mesa_Viewport( 0, 0, Current
->width
, Current
->height
);
1429 Current
->gl_ctx
->Scissor
.Width
= Current
->width
;
1430 Current
->gl_ctx
->Scissor
.Height
= Current
->height
;
1432 if ((c
->cColorBits
<= 8 ) && (c
->rgb_flag
== GL_TRUE
)){
1433 WMesaPaletteChange(c
->hPalHalfTone
);
1439 void WMesaSwapBuffers( void )
1441 HDC DC
= Current
->hDC
;
1442 GET_CURRENT_CONTEXT(ctx
);
1444 /* If we're swapping the buffer associated with the current context
1445 * we have to flush any pending rendering commands first.
1447 if (Current
&& Current
->gl_ctx
== ctx
)
1448 _mesa_swapbuffers(ctx
);
1450 if (Current
->db_flag
)
1456 void WMesaPaletteChange(HPALETTE Pal
)
1461 LPPALETTEENTRY pPal
;
1462 if (Current
&& (Current
->rgb_flag
==GL_FALSE
||
1463 Current
->dither_flag
== GL_TRUE
))
1465 pPal
= (PALETTEENTRY
*)malloc( 256 * sizeof(PALETTEENTRY
));
1467 GetPaletteEntries( Pal
, 0, 256, pPal
);
1469 Current
->lpDD
->lpVtbl
->CreatePalette(Current
->lpDD
,DDPCAPS_8BIT
,
1470 pPal
, &(Current
->lpDDPal
), NULL
);
1471 if (Current
->lpDDPal
)
1472 Current
->lpDDSPrimary
->lpVtbl
->SetPalette(Current
->lpDDSPrimary
,
1475 vRet
= SetDIBColorTable(Current
->dib
.hDC
, 0, 256, (RGBQUAD
*)pPal
);
1484 static unsigned char threeto8
[8] = {
1485 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
1488 static unsigned char twoto8
[4] = {
1492 static unsigned char oneto8
[2] = {
1496 static unsigned char componentFromIndex(UCHAR i
, UINT nbits
, UINT shift
)
1513 return threeto8
[val
];
1520 void wmCreatePalette( PWMC pwdc
)
1522 /* Create a compressed and re-expanded 3:3:2 palette */
1525 BYTE rb
, rs
, gb
, gs
, bb
, bs
;
1527 pwdc
->nColors
= 0x100;
1529 pPal
= (PLOGPALETTE
)malloc(sizeof(LOGPALETTE
) +
1530 pwdc
->nColors
* sizeof(PALETTEENTRY
));
1531 memset( pPal
, 0, sizeof(LOGPALETTE
) + pwdc
->nColors
* sizeof(PALETTEENTRY
) );
1533 pPal
->palVersion
= 0x300;
1542 if (pwdc
->db_flag
) {
1544 /* Need to make two palettes: one for the screen DC and one for the DIB. */
1545 pPal
->palNumEntries
= pwdc
->nColors
;
1546 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1547 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1548 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1549 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1550 pPal
->palPalEntry
[i
].peFlags
= 0;
1552 pwdc
->hGLPalette
= CreatePalette( pPal
);
1553 pwdc
->hPalette
= CreatePalette( pPal
);
1557 pPal
->palNumEntries
= pwdc
->nColors
;
1558 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1559 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1560 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1561 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1562 pPal
->palPalEntry
[i
].peFlags
= 0;
1564 pwdc
->hGLPalette
= CreatePalette( pPal
);
1573 #ifdef COMPILE_SETPIXEL
1575 wmSetPixelDefault(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1577 if (Current
->db_flag
)
1581 Current
->lpDDSOffScreen
->lpVtbl
->Unlock(Current
->lpDDSOffScreen
,NULL
);
1582 Current
->lpDDSOffScreen
->lpVtbl
->GetDC(Current
->lpDDSOffScreen
,&hdc
);
1583 SetPixelV(hdc
,iPixel
, iScanLine
, RGB(r
,g
,b
));
1584 Current
->lpDDSOffScreen
->lpVtbl
->ReleaseDC(Current
->lpDDSOffScreen
,hdc
);
1585 while (Current
->lpDDSOffScreen
->lpVtbl
->Lock(Current
->lpDDSOffScreen
,NULL
, &(Current
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
);
1587 SetPixelV(Current
->hDC
, iPixel
, iScanLine
, RGB(r
,g
,b
));
1592 SetPixelV(Current
->hDC
, iPixel
+pwc
->rectSurface
.left
, pwc
->rectSurface
.top
+iScanLine
, RGB(r
,g
,b
));
1596 wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1598 if (Current
->db_flag
)
1600 LPBYTE lpb
= pwc
->pbPixels
;
1601 UINT nBypp
= pwc
->cColorBits
>> 3;
1603 lpb
+= pwc
->ScanWidth
* iScanLine
;
1604 lpb
+= iPixel
* nBypp
;
1608 if(pwc
->dither_flag
)
1609 *lpb
= DITHER_RGB_2_8BIT(r
,g
,b
,iScanLine
,iPixel
);
1614 *((LPWORD
)lpb
) = BGR16(r
,g
,b
);
1615 else if (nBypp
== 3)
1621 else if (nBypp
== 4)
1622 *((LPDWORD
)lpb
) = BGR32(r
,g
,b
);
1626 SetPixel(Current
->hDC
, iPixel
, iScanLine
, RGB(r
,g
,b
));
1630 #ifdef COMPILE_SETPIXEL
1631 void wmSetPixel4(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1633 LPDWORD lpdw
= ((LPDWORD
)(pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
)) + iPixel
;
1634 *lpdw
= BGR32(r
,g
,b
);
1635 // LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel + iPixel + iPixel;
1636 // *((LPDWORD)lpb) = BGR32(r,g,b);
1639 void wmSetPixel3(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1641 LPBYTE lpb
= pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
+ iPixel
+ iPixel
+ iPixel
;
1647 void wmSetPixel2(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1649 LPWORD lpw
= ((LPWORD
)(pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
)) + iPixel
;
1650 *lpw
= BGR16(r
,g
,b
);
1651 // LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel;
1652 // *((LPWORD)lpb) = BGR16(r,g,b);
1655 void wmSetPixel1(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1657 LPBYTE lpb
= pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
+ iPixel
;
1661 void wmSetPixel1Dither(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1663 LPBYTE lpb
= pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
+ iPixel
;
1664 *lpb
= DITHER_RGB_2_8BIT(r
,g
,b
,iScanLine
,iPixel
);
1668 void ChooseSetPixel(PWMC pwc
)
1670 UINT nBypp
= (pwc
) ? pwc
->cColorBits
>> 3 : 0;
1674 pwc
->wmSetPixel
= pwc
->dither_flag
? &wmSetPixel1Dither
: &wmSetPixel1
;
1677 pwc
->wmSetPixel
= &wmSetPixel2
;
1680 pwc
->wmSetPixel
= &wmSetPixel3
;
1683 pwc
->wmSetPixel
= &wmSetPixel4
;
1686 pwc
->wmSetPixel
= &wmSetPixelDefault
;
1693 void wmCreateDIBSection(
1695 PWMC pwc
, // handle of device context
1696 CONST BITMAPINFO
*pbmi
, // bitmap size, format, and color data
1697 UINT iUsage
// color data type indicator: RGB values or palette indices
1702 UINT nBypp
= pwc
->cColorBits
/ 8;
1705 dwScanWidth
= (((pwc
->ScanWidth
* nBypp
)+ 3) & ~3);
1707 pwc
->ScanWidth
=pwc
->pitch
= dwScanWidth
;
1710 pwc
->ScanWidth
= 2* pwc
->pitch
;
1712 dwSize
= sizeof(BITMAPINFO
) + (dwScanWidth
* pwc
->height
);
1713 #ifdef USE_MAPPED_FILE
1714 pwc
->dib
.hFileMap
= CreateFileMapping((HANDLE
)PAGE_FILE
,
1716 PAGE_READWRITE
| SEC_COMMIT
,
1721 if (!pwc
->dib
.hFileMap
)
1724 pwc
->dib
.base
= MapViewOfFile(pwc
->dib
.hFileMap
,
1725 FILE_MAP_ALL_ACCESS
,
1731 CloseHandle(pwc
->dib
.hFileMap
);
1736 CopyMemory(pwc
->dib
.base
, pbmi
, sizeof(BITMAPINFO
));
1737 #endif // USE_MAPPED_FILE
1739 hic
= CreateIC("display", NULL
, NULL
, NULL
);
1740 pwc
->dib
.hDC
= CreateCompatibleDC(hic
);
1742 #ifdef USE_MAPPED_FILE
1744 pwc
->hbmDIB
= CreateDIBSection(hic
,
1746 (iUsage
? DIB_PAL_COLORS
: DIB_RGB_COLORS
),
1751 pwc
->hbmDIB
= CreateDIBSection(hic
,
1753 (iUsage
? DIB_PAL_COLORS
: DIB_RGB_COLORS
),
1757 #endif // USE_MAPPED_FILE
1758 pwc
->ScreenMem
= pwc
->addrOffScreen
= pwc
->pbPixels
;
1759 pwc
->hOldBitmap
= SelectObject(pwc
->dib
.hDC
, pwc
->hbmDIB
);
1768 * Blit memory DC to screen DC
1770 BOOL
wmFlush(PWMC pwc
)
1780 if (pwc
->lpDDSOffScreen
== NULL
)
1781 if(DDCreateOffScreen(pwc
) == GL_FALSE
)
1784 pwc
->lpDDSOffScreen
->lpVtbl
->Unlock(pwc
->lpDDSOffScreen
, NULL
);
1788 ddrval
= pwc
->lpDDSPrimary
->lpVtbl
->Blt( pwc
->lpDDSPrimary
,
1789 &(pwc
->rectSurface
),
1790 pwc
->lpDDSOffScreen
,
1791 &(pwc
->rectOffScreen
),
1794 if( ddrval
== DD_OK
)
1798 if( ddrval
== DDERR_SURFACELOST
)
1800 if(!DDRestoreAll(pwc
))
1805 if( ddrval
!= DDERR_WASSTILLDRAWING
)
1811 while (pwc
->lpDDSOffScreen
->lpVtbl
->Lock(pwc
->lpDDSOffScreen
,
1812 NULL
, &(pwc
->ddsd
), 0, NULL
) ==
1813 DDERR_WASSTILLDRAWING
)
1817 dwErr
= GetLastError();
1819 bRet
= BitBlt(pwc
->hDC
, 0, 0, pwc
->width
, pwc
->height
,
1820 pwc
->dib
.hDC
, 0, 0, SRCCOPY
);
1829 /* The following code is added by Li Wei to enable stereo display */
1831 #if !defined(NO_STEREO)
1833 static void __gluMakeIdentityf(GLfloat m
[16])
1835 m
[0+4*0] = 1; m
[0+4*1] = 0; m
[0+4*2] = 0; m
[0+4*3] = 0;
1836 m
[1+4*0] = 0; m
[1+4*1] = 1; m
[1+4*2] = 0; m
[1+4*3] = 0;
1837 m
[2+4*0] = 0; m
[2+4*1] = 0; m
[2+4*2] = 1; m
[2+4*3] = 0;
1838 m
[3+4*0] = 0; m
[3+4*1] = 0; m
[3+4*2] = 0; m
[3+4*3] = 1;
1841 static void normalize(float v
[3])
1845 r
= sqrt( v
[0]*v
[0] + v
[1]*v
[1] + v
[2]*v
[2] );
1846 if (r
== 0.0) return;
1853 static void cross(float v1
[3], float v2
[3], float result
[3])
1855 result
[0] = v1
[1]*v2
[2] - v1
[2]*v2
[1];
1856 result
[1] = v1
[2]*v2
[0] - v1
[0]*v2
[2];
1857 result
[2] = v1
[0]*v2
[1] - v1
[1]*v2
[0];
1862 __gluLookAt(GLdouble eyex
, GLdouble eyey
, GLdouble eyez
, GLdouble centerx
,
1863 GLdouble centery
, GLdouble centerz
, GLdouble upx
, GLdouble upy
,
1867 float forward
[3], side
[3], up
[3];
1870 forward
[0] = centerx
- eyex
;
1871 forward
[1] = centery
- eyey
;
1872 forward
[2] = centerz
- eyez
;
1880 /* Side = forward x up */
1881 cross(forward
, up
, side
);
1884 /* Recompute up as: up = side x forward */
1885 cross(side
, forward
, up
);
1887 __gluMakeIdentityf(&m
[0][0]);
1896 m
[0][2] = -forward
[0];
1897 m
[1][2] = -forward
[1];
1898 m
[2][2] = -forward
[2];
1900 glMultMatrixf(&m
[0][0]);
1901 glTranslated(-eyex
, -eyey
, -eyez
);
1904 GLfloat viewDistance
= 1.0;
1906 void WMesaShowStereo(GLuint list
)
1909 GLbitfield mask
= GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
;
1912 /* Must use double Buffer */
1913 if( ! Current
-> db_flag
)
1917 glGetIntegerv(GL_MATRIX_MODE
,&matrix_mode
);
1919 WMesaViewport(Current
->gl_ctx
,0,Current
->height
/2,
1920 Current
->width
,Current
->height
/2);
1921 if(matrix_mode
!=GL_MODELVIEW
)
1922 glMatrixMode(GL_MODELVIEW
);
1924 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1926 __gluLookAt(viewDistance
/2,0.0,0.0 ,
1927 viewDistance
/2,0.0,-1.0,
1929 glMultMatrixf( cm
);
1931 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
;
1934 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1936 __gluLookAt(-viewDistance
/2,0.0,0.0 ,
1937 -viewDistance
/2,0.0,-1.0,
1941 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
+ Current
->pitch
;
1943 if(matrix_mode
!=GL_MODELVIEW
)
1944 glMatrixMode(matrix_mode
);
1948 WMesaViewport(Current
->gl_ctx
,0,0,Current
->width
,Current
->height
);
1952 void toggleStereoMode()
1954 if(!Current
->db_flag
)
1958 if(stereoBuffer
==GL_FALSE
)
1959 #if !defined(NO_PARALLEL)
1963 Current
->ScanWidth
= Current
->pitch
*2;
1968 #if !defined(NO_PARALLEL)
1971 Current
->ScanWidth
= Current
->pitch
;
1972 Current
->pbPixels
= Current
->addrOffScreen
;
1976 /* if in stereo mode, the following function is called */
1977 void glShowStereo(GLuint list
)
1979 WMesaShowStereo(list
);
1982 #endif /* NO_STEREO */
1984 #if !defined(NO_PARALLEL)
1986 void toggleParallelMode(void)
1989 parallelFlag
= GL_TRUE
;
1990 if(parallelMachine
==GL_FALSE
){
1991 PRCreateRenderBuffer( Current
->rgb_flag
? GL_RGBA
:GL_COLOR_INDEX
,
1992 Current
->cColorBits
/8,
1993 Current
->width
,Current
->height
,
1995 Current
->rgb_flag
? Current
->pbPixels
:
1996 Current
->ScreenMem
);
1997 parallelMachine
= GL_TRUE
;
2001 parallelFlag
= GL_FALSE
;
2002 if(parallelMachine
==GL_TRUE
){
2003 PRDestroyRenderBuffer();
2004 parallelMachine
=GL_FALSE
;
2005 ReadyForNextFrame
= GL_TRUE
;
2008 /***********************************************
2009 * Seems something wrong!!!!
2010 ************************************************/
2012 WMesaMakeCurrent(Current
);
2013 #if !defined(NO_STEREO)
2014 stereo_flag
= GL_FALSE
;
2019 void PRShowRenderResult(void)
2022 if(!glImageRendered())
2031 #endif /* NO_PARALLEL */
2033 BYTE
DITHER_RGB_2_8BIT( int red
, int green
, int blue
, int pixel
, int scanline
)
2035 char unsigned redtemp
, greentemp
, bluetemp
, paletteindex
;
2037 //*** now, look up each value in the halftone matrix
2038 //*** using an 8x8 ordered dither.
2039 redtemp
= aDividedBy51
[red
]
2040 + (aModulo51
[red
] > aHalftone8x8
[(pixel
%8)*8
2042 greentemp
= aDividedBy51
[(char unsigned)green
]
2043 + (aModulo51
[green
] > aHalftone8x8
[
2044 (pixel
%8)*8 + scanline
%8]);
2045 bluetemp
= aDividedBy51
[(char unsigned)blue
]
2046 + (aModulo51
[blue
] > aHalftone8x8
[
2047 (pixel
%8)*8 +scanline
%8]);
2049 //*** recombine the halftoned rgb values into a palette index
2051 redtemp
+ aTimes6
[greentemp
] + aTimes36
[bluetemp
];
2053 //*** and translate through the wing halftone palette
2054 //*** translation vector to give the correct value.
2055 return aWinGHalftoneTranslation
[paletteindex
];
2062 * restore all lost objects
2064 HRESULT
DDRestoreAll( WMesaContext wc
)
2068 ddrval
= wc
->lpDDSPrimary
->lpVtbl
->Restore(wc
->lpDDSPrimary
);
2069 if( ddrval
== DD_OK
)
2071 ddrval
= wc
->lpDDSOffScreen
->lpVtbl
->Restore(wc
->lpDDSOffScreen
);
2079 * This function is called if the initialization function fails
2081 BOOL
initFail( HWND hwnd
, WMesaContext wc
)
2084 MessageBox( hwnd
, "DirectDraw Init FAILED", "", MB_OK
);
2090 static void DDDeleteOffScreen(WMesaContext wc
)
2092 if( wc
->lpDDSOffScreen
!= NULL
)
2094 wc
->lpDDSOffScreen
->lpVtbl
->Unlock(wc
->lpDDSOffScreen
,NULL
);
2095 wc
->lpDDSOffScreen
->lpVtbl
->Release(wc
->lpDDSOffScreen
);
2096 wc
->lpDDSOffScreen
= NULL
;
2101 static void DDFreePrimarySurface(WMesaContext wc
)
2103 if( wc
->lpDDSPrimary
!= NULL
)
2105 if(wc
->db_flag
== GL_FALSE
)
2106 wc
->lpDDSPrimary
->lpVtbl
->ReleaseDC(wc
->lpDDSPrimary
, wc
->hDC
);
2107 wc
->lpDDSPrimary
->lpVtbl
->Release(wc
->lpDDSPrimary
);
2108 wc
->lpDDSPrimary
= NULL
;
2112 static BOOL
DDCreatePrimarySurface(WMesaContext wc
)
2116 wc
->ddsd
.dwSize
= sizeof( wc
->ddsd
);
2117 wc
->ddsd
.dwFlags
= DDSD_CAPS
;
2118 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2120 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
,&(wc
->ddsd
),
2121 &(wc
->lpDDSPrimary
), NULL
);
2122 if( ddrval
!= DD_OK
)
2124 return initFail(wc
->hwnd
, wc
);
2126 if(wc
->db_flag
== GL_FALSE
)
2127 wc
->lpDDSPrimary
->lpVtbl
->GetDC(wc
->lpDDSPrimary
, &(wc
->hDC
));
2131 static BOOL
DDCreateOffScreen(WMesaContext wc
)
2135 if(wc
->lpDD
== NULL
)
2137 GetClientRect( wc
->hwnd
, &(wc
->rectOffScreen
) );
2138 wc
->ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
2139 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
2140 wc
->ddsd
.dwHeight
= wc
->rectOffScreen
.bottom
- wc
->rectOffScreen
.top
;
2141 wc
->ddsd
.dwWidth
= wc
->rectOffScreen
.right
- wc
->rectOffScreen
.left
;
2143 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
, &(wc
->ddsd
),
2144 &(wc
->lpDDSOffScreen
), NULL
);
2145 if( ddrval
!= DD_OK
)
2150 while (wc
->lpDDSOffScreen
->lpVtbl
->Lock(wc
->lpDDSOffScreen
,NULL
,
2151 &(wc
->ddsd
), 0, NULL
) ==
2152 DDERR_WASSTILLDRAWING
)
2155 if(wc
->ddsd
.lpSurface
==NULL
)
2156 return initFail(wc
->hwnd
, wc
);
2158 wc
->ScreenMem
= wc
->pbPixels
= wc
->addrOffScreen
=
2159 (PBYTE
)(wc
->ddsd
.lpSurface
);
2160 wc
->ScanWidth
= wc
->pitch
= wc
->ddsd
.lPitch
;
2162 wc
->ScanWidth
= wc
->ddsd
.lPitch
*2;
2164 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2166 ClientToScreen( wc
->hwnd
, &pt
);
2167 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2168 wmSetPixelFormat(wc
, wc
->hDC
);
2173 struct tagWMesaContextList
2176 struct tagWMesaContextList
*next
;
2179 WMesaContextList
*head
= 0;
2181 void AddContext(WMesaContext wc
)
2183 WMesaContextList
*lst
= (WMesaContextList
*)malloc(sizeof(WMesaContextList
));
2190 WMesaContext
FindContext(HWND hWnd
)
2192 WMesaContextList
*tmp
= head
;
2195 if( tmp
->wc
->hwnd
== hWnd
)
2202 void RemoveContext(HWND hWnd
)
2204 WMesaContextList
*tmp
= head
;
2207 if( tmp
->wc
->hwnd
== hWnd
)
2209 WMesaContextList
*lst
= tmp
;
2217 if( tmp
->next
->wc
->hwnd
== hWnd
)
2219 WMesaContextList
*lst
= tmp
->next
;
2220 tmp
->next
= tmp
->next
->next
;
2228 static LRESULT CALLBACK
MyWndProc(HWND hwnd
,UINT message
,WPARAM wParam
, LPARAM lParam
)
2230 WMesaContext wc
= Current
->hwnd
== hwnd
? Current
: FindContext(hwnd
);
2233 LRESULT lret
= CallWindowProc((WNDPROC
)(wc
->oldWndProc
),hwnd
,message
,wParam
,lParam
);
2234 if( message
= WM_MOVE
)
2237 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2238 ClientToScreen( hwnd
, &pt
);
2239 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2247 * doInit - do work required for every instance of the application:
2248 * create the window, initialize data
2250 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
)
2253 // DWORD dwFrequency;
2255 // LPDIRECTDRAW lpDD; // DirectDraw object
2256 // LPDIRECTDRAW2 lpDD2;
2257 LPDIRECTDRAWCLIPPER pcClipper
= NULL
;
2259 wc
->fullScreen
= displayOptions
.fullScreen
;
2260 wc
->gMode
= displayOptions
.mode
;
2262 stereo_flag
= displayOptions
.stereo
;
2263 if(wc
->db_flag
!= GL_TRUE
)
2264 stereo_flag
= GL_FALSE
;
2266 * create the main DirectDraw object
2268 ddrval
= DirectDrawCreate( NULL
, &(wc
->lpDD
), NULL
);
2269 if( ddrval
!= DD_OK
)
2271 return initFail(hwnd
,wc
);
2274 // Get exclusive mode if requested
2277 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
,
2283 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
,
2286 if( ddrval
!= DD_OK
)
2288 return initFail(hwnd
, wc
);
2293 return initFail(hwnd
, wc
);
2299 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 640, 480,
2300 displayOptions
.bpp
);
2303 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 800, 600,
2304 displayOptions
.bpp
);
2307 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1024, 768,
2308 displayOptions
.bpp
);
2311 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1152, 864,
2312 displayOptions
.bpp
);
2315 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1280, 1024,
2316 displayOptions
.bpp
);
2320 if( ddrval
!= DD_OK
)
2322 printf("Can't modify display mode, current mode used\n");
2325 case DDERR_INVALIDOBJECT
:
2327 case DDERR_INVALIDPARAMS
:
2329 case DDERR_UNSUPPORTEDMODE
:
2333 if(DDCreatePrimarySurface(wc
) == GL_FALSE
)
2334 return initFail(hwnd
, wc
);
2337 DDCreateOffScreen(wc
);
2339 if( FAILED( ddrval
= wc
->lpDD
->lpVtbl
->CreateClipper(wc
->lpDD
, 0, &pcClipper
, NULL
) ) )
2342 if( FAILED( ddrval
= pcClipper
->lpVtbl
->SetHWnd(pcClipper
, 0, wc
->hwnd
) ) )
2344 pcClipper
->lpVtbl
->Release(pcClipper
);
2348 if( FAILED( ddrval
= wc
->lpDDSPrimary
->lpVtbl
->SetClipper(wc
->lpDDSPrimary
, pcClipper
) ) )
2350 pcClipper
->lpVtbl
->Release(pcClipper
);
2354 // Done with clipper
2355 pcClipper
->lpVtbl
->Release(pcClipper
);
2357 // Hook the window so we can update the drawing rectangle when the window moves
2358 wc
->oldWndProc
= SetWindowLong(wc
->hwnd
,GWL_WNDPROC
,(LONG
)MyWndProc
);
2364 static void DDFree( WMesaContext wc
)
2366 RemoveContext(wc
->hwnd
);
2367 SetWindowLong(wc
->hwnd
,GWL_WNDPROC
,(LONG
)(wc
->oldWndProc
));
2369 if( wc
->lpDD
!= NULL
)
2371 DDFreePrimarySurface(wc
);
2372 DDDeleteOffScreen(wc
);
2373 wc
->lpDD
->lpVtbl
->Release(wc
->lpDD
);
2376 // Clean up the screen on exit
2377 RedrawWindow( NULL
, NULL
, NULL
, RDW_INVALIDATE
| RDW_ERASE
|
2383 void WMesaMove(void)
2385 WMesaContext wc
= Current
;
2387 if (Current
!= NULL
){
2388 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2390 ClientToScreen( wc
->hwnd
, &pt
);
2391 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2396 /************************************************
2397 * Mesa 4.0 - These triangle rasterizers are not
2398 * implemented in this version of the Windows
2399 * driver. They could be implemented for a
2400 * potential performance improvement.
2401 * See OSMesa for an example of the approach
2403 * This old code is left in this file in case
2404 * it is useful. However, it may end up looking
2405 * a lot more like the OSMesa code.
2406 ************************************************/
2409 #if defined(FAST_RASTERIZERS)
2413 * Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable
2416 #define PACK_8B8G8R( R, G, B ) ( ((B) << 16) | ((G) << 8) | (R) )
2418 /**********************************************************************/
2419 /*** Triangle rendering ***/
2420 /**********************************************************************/
2423 * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
2425 static void smooth_8A8B8G8R_z_triangle( GLcontext
*ctx
,
2426 GLuint v0
, GLuint v1
, GLuint v2
,
2429 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2431 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
2432 #define INTERP_RGB 1
2433 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2434 #define PIXEL_TYPE GLuint
2435 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2436 #define BYTES_PER_ROW (wmesa->ScanWidth)
2437 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2439 GLint i, len = RIGHT-LEFT; \
2440 for (i=0;i<len;i++) { \
2441 GLdepth z = FixedToDepth(ffz); \
2442 if (z < zRow[i]) { \
2443 pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2444 FixedToInt(ffb) ); \
2447 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2453 #include "tritemp.h"
2457 // #include "..\tritemp.h"
2459 #include "tritemp.h"
2466 * XImage, smooth, depth-buffered, PF_8R8G8B triangle.
2468 static void smooth_8R8G8B_z_triangle( GLcontext
*ctx
,
2469 GLuint v0
, GLuint v1
, GLuint v2
,
2472 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2474 #define INTERP_RGB 1
2475 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2476 #define PIXEL_TYPE GLuint
2477 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2478 #define BYTES_PER_ROW (wmesa->ScanWidth)
2479 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2481 GLint i, len = RIGHT-LEFT; \
2482 for (i=0;i<len;i++) { \
2483 GLdepth z = FixedToDepth(ffz); \
2484 if (z < zRow[i]) { \
2485 pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2486 FixedToInt(ffb) ); \
2489 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2494 #include "tritemp.h"
2498 // #include "..\tritemp.h"
2500 #include "tritemp.h"
2508 * XImage, smooth, depth-buffered, PF_5R6G5B triangle.
2510 static void smooth_5R6G5B_z_triangle( GLcontext
*ctx
,
2511 GLuint v0
, GLuint v1
, GLuint v2
,
2514 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2516 #define INTERP_RGB 1
2517 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2518 #define PIXEL_TYPE GLushort
2519 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2520 #define BYTES_PER_ROW (wmesa->ScanWidth)
2521 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2523 GLint i, len = RIGHT-LEFT; \
2524 for (i=0;i<len;i++) { \
2525 GLdepth z = FixedToDepth(ffz); \
2526 if (z < zRow[i]) { \
2527 pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2528 FixedToInt(ffb) ); \
2531 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2536 #include "tritemp.h"
2540 // #include "..\tritemp.h"
2542 #include "tritemp.h"
2548 * XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
2550 static void flat_8A8B8G8R_z_triangle( GLcontext
*ctx
, GLuint v0
,
2551 GLuint v1
, GLuint v2
, GLuint pv
)
2553 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2555 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2556 #define PIXEL_TYPE GLuint
2557 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2558 #define BYTES_PER_ROW (wmesa->ScanWidth)
2559 #define SETUP_CODE \
2560 unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \
2561 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2562 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2564 GLint i, len = RIGHT-LEFT; \
2565 for (i=0;i<len;i++) { \
2566 GLdepth z = FixedToDepth(ffz); \
2567 if (z < zRow[i]) { \
2575 #include "tritemp.h"
2579 // #include "..\tritemp.h"
2581 #include "tritemp.h"
2588 * XImage, flat, depth-buffered, PF_8R8G8B triangle.
2590 static void flat_8R8G8B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2591 GLuint v2
, GLuint pv
)
2593 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2595 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2596 #define PIXEL_TYPE GLuint
2597 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2598 #define BYTES_PER_ROW (wmesa->ScanWidth)
2599 #define SETUP_CODE \
2600 unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \
2601 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2602 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2604 GLint i, len = RIGHT-LEFT; \
2605 for (i=0;i<len;i++) { \
2606 GLdepth z = FixedToDepth(ffz); \
2607 if (z < zRow[i]) { \
2615 #include "tritemp.h"
2619 // #include "..\tritemp.h"
2621 #include "tritemp.h"
2628 * XImage, flat, depth-buffered, PF_5R6G5B triangle.
2630 static void flat_5R6G5B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2631 GLuint v2
, GLuint pv
)
2633 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2635 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2636 #define PIXEL_TYPE GLushort
2637 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2638 #define BYTES_PER_ROW (wmesa->ScanWidth)
2639 #define SETUP_CODE \
2640 unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \
2641 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2642 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2644 GLint i, len = RIGHT-LEFT; \
2645 for (i=0;i<len;i++) { \
2646 GLdepth z = FixedToDepth(ffz); \
2647 if (z < zRow[i]) { \
2655 #include "tritemp.h"
2659 // #include "..\tritemp.h"
2661 #include "tritemp.h"
2668 * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
2670 static void smooth_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2671 GLuint v2
, GLuint pv
)
2673 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2674 #define INTERP_RGB 1
2675 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2676 #define PIXEL_TYPE GLuint
2677 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2678 #define BYTES_PER_ROW (wmesa->ScanWidth)
2679 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2682 PIXEL_TYPE *pixel = pRow; \
2683 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2684 *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2685 FixedToInt(ffb) ); \
2686 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2690 #include "tritemp.h"
2694 // #include "..\tritemp.h"
2696 #include "tritemp.h"
2703 * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
2705 static void smooth_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2706 GLuint v2
, GLuint pv
)
2708 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2709 #define INTERP_RGB 1
2710 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2711 #define PIXEL_TYPE GLuint
2712 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2713 #define BYTES_PER_ROW (wmesa->ScanWidth)
2714 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2717 PIXEL_TYPE *pixel = pRow; \
2718 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2719 *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2720 FixedToInt(ffb) ); \
2721 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2725 #include "tritemp.h"
2729 // #include "..\tritemp.h"
2731 #include "tritemp.h"
2738 * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
2740 static void smooth_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2741 GLuint v2
, GLuint pv
)
2743 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2744 #define INTERP_RGB 1
2745 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2746 #define PIXEL_TYPE GLushort
2747 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2748 #define BYTES_PER_ROW (wmesa->ScanWidth)
2749 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2752 PIXEL_TYPE *pixel = pRow; \
2753 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2754 *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2755 FixedToInt(ffb) ); \
2756 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2760 #include "tritemp.h"
2764 // #include "..\tritemp.h"
2766 #include "tritemp.h"
2774 * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
2776 static void flat_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
,
2777 GLuint v1
, GLuint v2
, GLuint pv
)
2779 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2780 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2781 #define PIXEL_TYPE GLuint
2782 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2783 #define BYTES_PER_ROW (wmesa->ScanWidth)
2784 #define SETUP_CODE \
2785 unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \
2786 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2787 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2790 PIXEL_TYPE *pixel = pRow; \
2791 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2797 #include "tritemp.h"
2801 // #include "..\tritemp.h"
2803 #include "tritemp.h"
2810 * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
2812 static void flat_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2813 GLuint v2
, GLuint pv
)
2815 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2816 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2817 #define PIXEL_TYPE GLuint
2818 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2819 #define BYTES_PER_ROW (wmesa->ScanWidth)
2820 #define SETUP_CODE \
2821 unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \
2822 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2823 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2826 PIXEL_TYPE *pixel = pRow; \
2827 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2832 #include "tritemp.h"
2836 // #include "..\tritemp.h"
2838 #include "tritemp.h"
2845 * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
2847 static void flat_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2848 GLuint v2
, GLuint pv
)
2850 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2851 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2852 #define PIXEL_TYPE GLushort
2853 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2854 #define BYTES_PER_ROW (wmesa->ScanWidth)
2855 #define SETUP_CODE \
2856 unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \
2857 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2858 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2861 PIXEL_TYPE *pixel = pRow; \
2862 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2867 #include "tritemp.h"
2871 // #include "..\tritemp.h"
2873 #include "tritemp.h"
2880 * XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
2883 static void smooth_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2884 GLuint v2
, GLuint pv
)
2886 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2888 #define INTERP_INDEX 1
2889 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2890 #define PIXEL_TYPE GLubyte
2891 #define BYTES_PER_ROW (wmesa->ScanWidth)
2892 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2894 GLint i, len = RIGHT-LEFT; \
2895 for (i=0;i<len;i++) { \
2896 GLdepth z = FixedToDepth(ffz); \
2897 if (z < zRow[i]) { \
2898 pRow[i] = FixedToInt(ffi); \
2906 #include "tritemp.h"
2910 // #include "..\tritemp.h"
2912 #include "tritemp.h"
2919 * XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
2922 static void flat_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2923 GLuint v2
, GLuint pv
)
2925 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2927 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2928 #define PIXEL_TYPE GLubyte
2929 #define BYTES_PER_ROW (wmesa->ScanWidth)
2930 #define SETUP_CODE \
2931 GLuint index = VB->IndexPtr->data[pv]; \
2932 (*ctx->Driver.Index)( ctx, index );
2933 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2935 GLint i, len = RIGHT-LEFT; \
2936 for (i=0;i<len;i++) { \
2937 GLdepth z = FixedToDepth(ffz); \
2938 if (z < zRow[i]) { \
2946 #include "tritemp.h"
2950 // #include "..\tritemp.h"
2952 #include "tritemp.h"
2960 * XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2963 static void smooth_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2964 GLuint v2
, GLuint pv
)
2966 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2968 #define INTERP_INDEX 1
2969 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2970 #define PIXEL_TYPE GLubyte
2971 #define BYTES_PER_ROW (wmesa->ScanWidth)
2972 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2975 PIXEL_TYPE *pixel = pRow; \
2976 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2977 *pixel = FixedToInt(ffi); \
2982 #include "tritemp.h"
2986 // #include "..\tritemp.h"
2988 #include "tritemp.h"
2995 * XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2997 static void flat_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2998 GLuint v2
, GLuint pv
)
3000 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3002 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3003 #define PIXEL_TYPE GLubyte
3004 #define BYTES_PER_ROW (wmesa->ScanWidth)
3005 #define SETUP_CODE \
3006 GLuint index = VB->IndexPtr->data[pv]; \
3007 (*ctx->Driver.Index)( ctx, index );
3008 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3011 PIXEL_TYPE *pixel = pRow; \
3012 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
3017 #include "tritemp.h"
3021 // #include "..\tritemp.h"
3023 #include "tritemp.h"
3029 * XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
3031 static void smooth_DITHER8_z_triangle( GLcontext
*ctx
,
3032 GLuint v0
, GLuint v1
, GLuint v2
,
3035 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3036 DITHER_RGB_TO_8BIT_SETUP
3038 #define INTERP_RGB 1
3039 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3040 #define PIXEL_TYPE GLubyte
3041 #define BYTES_PER_ROW (wmesa->ScanWidth)
3042 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3044 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
3045 for (i=0;i<len;i++,xx++) { \
3046 GLdepth z = FixedToDepth(ffz); \
3047 if (z < zRow[i]) { \
3048 DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg), \
3049 FixedToInt(ffb), xx, yy); \
3050 pRow[i] = pixelDithered; \
3053 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
3058 #include "tritemp.h"
3062 // #include "..\tritemp.h"
3064 #include "tritemp.h"
3070 * XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
3072 static void flat_DITHER8_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
3073 GLuint v2
, GLuint pv
)
3075 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3076 DITHER_RGB_TO_8BIT_SETUP
3078 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3079 #define PIXEL_TYPE GLubyte
3080 #define BYTES_PER_ROW (wmesa->ScanWidth)
3082 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3084 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
3085 for (i=0;i<len;i++,xx++) { \
3086 GLdepth z = FixedToDepth(ffz); \
3087 if (z < zRow[i]) { \
3088 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \
3089 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \
3090 pRow[i] = pixelDithered; \
3097 #include "tritemp.h"
3101 // #include "..\tritemp.h"
3103 #include "tritemp.h"
3109 * XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
3111 static void smooth_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
3112 GLuint v2
, GLuint pv
)
3114 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3115 DITHER_RGB_TO_8BIT_SETUP
3116 #define INTERP_RGB 1
3117 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3118 #define PIXEL_TYPE GLubyte
3119 #define BYTES_PER_ROW (wmesa->ScanWidth)
3120 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3122 GLint xx, yy = FLIP(Y); \
3123 PIXEL_TYPE *pixel = pRow; \
3124 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
3125 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy);\
3126 *pixel = pixelDithered; \
3127 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
3131 #include "tritemp.h"
3135 // #include "..\tritemp.h"
3137 #include "tritemp.h"
3143 * XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
3146 static void flat_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
3147 GLuint v2
, GLuint pv
)
3149 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3150 DITHER_RGB_TO_8BIT_SETUP
3151 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3152 #define PIXEL_TYPE GLubyte
3153 #define BYTES_PER_ROW (wmesa->ScanWidth)
3155 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3157 GLint xx, yy = FLIP(Y); \
3158 PIXEL_TYPE *pixel = pRow; \
3159 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
3160 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \
3161 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \
3162 *pixel = pixelDithered; \
3166 #include "tritemp.h"
3170 // #include "..\tritemp.h"
3172 #include "tritemp.h"
3178 /************** END DEAD TRIANGLE CODE ***********************/
3180 static triangle_func
choose_triangle_function( GLcontext
*ctx
)
3183 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3184 int depth
= wmesa
->cColorBits
;
3186 if (ctx
->Polygon
.SmoothFlag
) return NULL
;
3187 if (ctx
->Texture
._EnabledUnits
) return NULL
;
3188 if (!wmesa
->db_flag
) return NULL
;
3189 if (ctx
->swrast
->_RasterMask
& MULTI_DRAW_BIT
) return NULL
;
3191 /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {
3192 if ( ctx
->Light
.ShadeModel
==GL_SMOOTH
3193 && ctx
->_RasterMask
==DEPTH_BIT
3194 && ctx
->Depth
.Func
==GL_LESS
3195 && ctx
->Depth
.Mask
==GL_TRUE
3196 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
3197 switch (wmesa
->pixelformat
) {
3199 return smooth_8A8B8G8R_z_triangle
;
3201 return smooth_8R8G8B_z_triangle
;
3203 return smooth_5R6G5B_z_triangle
;
3205 return smooth_DITHER8_z_triangle
;
3207 return smooth_ci_z_triangle
;
3212 if ( ctx
->Light
.ShadeModel
==GL_FLAT
3213 && ctx
->_RasterMask
==DEPTH_BIT
3214 && ctx
->Depth
.Func
==GL_LESS
3215 && ctx
->Depth
.Mask
==GL_TRUE
3216 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
3217 switch (wmesa
->pixelformat
) {
3219 return flat_8A8B8G8R_z_triangle
;
3221 return flat_8R8G8B_z_triangle
;
3223 return flat_5R6G5B_z_triangle
;
3225 return flat_DITHER8_z_triangle
;
3227 return flat_ci_z_triangle
;
3232 if ( ctx
->_RasterMask
==0 /* no depth test */
3233 && ctx
->Light
.ShadeModel
==GL_SMOOTH
3234 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
3235 switch (wmesa
->pixelformat
) {
3237 return smooth_8A8B8G8R_triangle
;
3239 return smooth_8R8G8B_triangle
;
3241 return smooth_5R6G5B_triangle
;
3243 return smooth_DITHER8_triangle
;
3245 return smooth_ci_triangle
;
3251 if ( ctx
->_RasterMask
==0 /* no depth test */
3252 && ctx
->Light
.ShadeModel
==GL_FLAT
3253 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
3254 switch (wmesa
->pixelformat
) {
3256 return flat_8A8B8G8R_triangle
;
3258 return flat_8R8G8B_triangle
;
3260 return flat_5R6G5B_triangle
;
3262 return flat_DITHER8_triangle
;
3264 return flat_ci_triangle
;
3276 * Define a new viewport and reallocate auxillary buffers if the size of
3277 * the window (color buffer) has changed.
3279 void WMesaViewport( GLcontext
*ctx
,
3280 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
3282 assert(0); /* I don't think that this is being used. */
3285 ctx
->Viewport
.X
= x
;
3286 ctx
->Viewport
.Width
= width
;
3287 ctx
->Viewport
.Y
= y
;
3288 ctx
->Viewport
.Height
= height
;
3290 /* compute scale and bias values */
3291 /* Pre-Keith 3.1 changes
3292 ctx->Viewport.Map.m[Sx] = (GLfloat) width / 2.0F;
3293 ctx->Viewport.Map.m[Tx] = ctx->Viewport.Sx + x;
3294 ctx->Viewport.Map.m[Sy] = (GLfloat) height / 2.0F;
3295 ctx->Viewport.Map.m[Ty] = ctx->Viewport.Sy + y;
3297 ctx
->Viewport
.WindowMap
.m
[MAT_SX
] = (GLfloat
) width
/ 2.0F
;
3298 ctx
->Viewport
.WindowMap
.m
[MAT_TX
] = ctx
->Viewport
.WindowMap
.m
[MAT_SX
] + x
;
3299 ctx
->Viewport
.WindowMap
.m
[MAT_SY
] = (GLfloat
) height
/ 2.0F
;
3300 ctx
->Viewport
.WindowMap
.m
[MAT_TY
] = ctx
->Viewport
.WindowMap
.m
[MAT_SY
] + y
;