1 /* $Id: wmesa.c,v 1.23 2001/11/01 22:44:47 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"
44 #include "texformat.h"
46 #include "array_cache/acache.h"
47 #include "swrast/swrast.h"
48 #include "swrast_setup/swrast_setup.h"
49 #include "swrast/s_context.h"
50 #include "swrast/s_depth.h"
51 #include "swrast/s_lines.h"
52 #include "swrast/s_triangle.h"
53 #include "swrast/s_trispan.h"
55 #include "tnl/t_context.h"
56 #include "tnl/t_pipeline.h"
58 /* Dither not tested for Mesa 4.0 */
68 #define CopyMemory memcpy
71 /* Stereo and parallel not tested for Mesa 4.0. */
72 #if !defined(NO_STEREO)
77 #if !defined(NO_PARALLEL)
82 /* File global varaibles */
83 struct DISPLAY_OPTIONS displayOptions
=
87 0, // full screen mode (1,2,3,4)
90 GLenum stereoCompile
= GL_FALSE
;
91 GLenum stereoShowing
= GL_FALSE
;
92 GLenum stereoBuffer
= GL_FALSE
;
93 #if !defined(NO_STEREO)
94 GLint displayList
= MAXIMUM_DISPLAY_LIST
;
96 GLint stereo_flag
= 0 ;
98 static PWMC Current
= NULL
;
99 WMesaContext WC
= NULL
;
101 #ifdef COMPILE_SETPIXEL
103 __forceinline
void wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
105 pwc
->wmSetPixel(pwc
,iScanLine
,iPixel
,r
,g
,b
);
108 void ChooseSetPixel(PWMC pwc
);
110 #endif // COMPILE_SETPIXEL
112 /* If we are double-buffering, we want to get the DC for the
113 * off-screen DIB, otherwise the DC for the window.
115 #define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
118 #define FLIP(Y) (Current->height-(Y)-1)
120 #define DITHER_RGB_TO_8BIT_SETUP \
121 GLubyte pixelDithered;
123 #define DITHER_RGB_TO_8BIT(red, green, blue, pixel, scanline) \
125 char unsigned redtemp, greentemp, bluetemp, paletteindex; \
126 redtemp = aDividedBy51[red] \
127 + (aModulo51[red] > aHalftone8x8[(pixel%8)*8 \
129 greentemp = aDividedBy51[(char unsigned)green] \
130 + (aModulo51[green] > aHalftone8x8[ \
131 (pixel%8)*8 + scanline%8]); \
132 bluetemp = aDividedBy51[(char unsigned)blue] \
133 + (aModulo51[blue] > aHalftone8x8[ \
134 (pixel%8)*8 +scanline%8]); \
135 paletteindex = redtemp + aTimes6[greentemp] + aTimes36[bluetemp];\
136 pixelDithered = aWinGHalftoneTranslation[paletteindex]; \
140 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
);
141 static void DDFree( WMesaContext wc
);
142 static HRESULT
DDRestoreAll( WMesaContext wc
);
143 static void DDDeleteOffScreen(WMesaContext wc
);
144 static BOOL
DDCreateOffScreen(WMesaContext wc
);
146 // define this to use the GDI Rectangle call to
147 // clear the back buffer. Otherwise will manually
148 // set the pixels. On an NVidia GEForce 2MX under Windows XP
149 // and DirectX 8 , defining this makes apps run much much faster
150 #define USE_GDI_TO_CLEAR 1
153 static void FlushToFile(PWMC pwc
, PSTR szFile
);
154 BOOL
wmCreateBackingStore(PWMC pwc
, long lxSize
, long lySize
);
155 BOOL
wmDeleteBackingStore(PWMC pwc
);
156 void wmCreatePalette( PWMC pwdc
);
157 BOOL
wmSetDibColors(PWMC pwc
);
158 void wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
);
159 BOOL
wmFlush(PWMC pwc
);
160 void wmCreateDIBSection(
162 PWMC pwc
, // handle of device context
163 CONST BITMAPINFO
*pbmi
, // bitmap size, format, and color data
164 UINT iUsage
// color data type indicator: RGB values or palette indices
166 void WMesaViewport( GLcontext
*ctx
,
167 GLint x
, GLint y
, GLsizei width
, GLsizei height
);
170 static void wmSetPixelFormat( PWMC wc
, HDC hDC
)
173 wc
->cColorBits
= GetDeviceCaps(hDC
, BITSPIXEL
);
176 switch(wc
->cColorBits
){
178 if(wc
->dither_flag
!= GL_TRUE
)
179 wc
->pixelformat
= PF_INDEX8
;
181 wc
->pixelformat
= PF_DITHER8
;
184 wc
->pixelformat
= PF_5R6G5B
;
187 wc
->pixelformat
= PF_8R8G8B
;
190 wc
->pixelformat
= PF_BADFORMAT
;
195 /* This function sets the color table of a DIB section
196 * to match that of the destination DC
198 BOOL
wmSetDibColors(PWMC pwc
)
200 RGBQUAD
*pColTab
, *pRGB
;
201 PALETTEENTRY
*pPal
, *pPE
;
206 /* Build a color table in the DIB that maps to the
207 * selected palette in the DC.
209 nColors
= 1 << pwc
->cColorBits
;
210 pPal
= (PALETTEENTRY
*)malloc( nColors
* sizeof(PALETTEENTRY
));
211 memset( pPal
, 0, nColors
* sizeof(PALETTEENTRY
) );
212 GetPaletteEntries( pwc
->hGLPalette
, 0, nColors
, pPal
);
213 pColTab
= (RGBQUAD
*)malloc( nColors
* sizeof(RGBQUAD
));
214 for (i
= 0, pRGB
= pColTab
, pPE
= pPal
; i
< nColors
; i
++, pRGB
++, pPE
++) {
215 pRGB
->rgbRed
= pPE
->peRed
;
216 pRGB
->rgbGreen
= pPE
->peGreen
;
217 pRGB
->rgbBlue
= pPE
->peBlue
;
220 bRet
= SetDIBColorTable(pwc
->dib
.hDC
, 0, nColors
, pColTab
);
223 dwErr
= GetLastError();
233 * Free up the dib section that was created
235 BOOL
wmDeleteBackingStore(PWMC pwc
)
237 SelectObject(pwc
->dib
.hDC
, pwc
->hOldBitmap
);
238 DeleteDC(pwc
->dib
.hDC
);
239 DeleteObject(pwc
->hbmDIB
);
240 #ifdef USE_MAPPED_FILE
241 UnmapViewOfFile(pwc
->dib
.base
);
242 CloseHandle(pwc
->dib
.hFileMap
);
249 * This function creates the DIB section that is used for combined
252 BOOL
wmCreateBackingStore(PWMC pwc
, long lxSize
, long lySize
)
255 LPBITMAPINFO pbmi
= &(pwc
->bmi
);
258 pbmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
259 pbmi
->bmiHeader
.biWidth
= lxSize
;
260 pbmi
->bmiHeader
.biHeight
= -lySize
;
261 pbmi
->bmiHeader
.biPlanes
= 1;
263 pbmi
->bmiHeader
.biBitCount
= GetDeviceCaps(pwc
->hDC
, BITSPIXEL
);
265 pbmi
->bmiHeader
.biBitCount
= 8;
266 pbmi
->bmiHeader
.biCompression
= BI_RGB
;
267 pbmi
->bmiHeader
.biSizeImage
= 0;
268 pbmi
->bmiHeader
.biXPelsPerMeter
= 0;
269 pbmi
->bmiHeader
.biYPelsPerMeter
= 0;
270 pbmi
->bmiHeader
.biClrUsed
= 0;
271 pbmi
->bmiHeader
.biClrImportant
= 0;
273 iUsage
= (pbmi
->bmiHeader
.biBitCount
<= 8) ? DIB_PAL_COLORS
: DIB_RGB_COLORS
;
275 pwc
->cColorBits
= pbmi
->bmiHeader
.biBitCount
;
276 pwc
->ScanWidth
= pwc
->pitch
= lxSize
;
278 wmCreateDIBSection(hdc
, pwc
, pbmi
, iUsage
);
280 if ((iUsage
== DIB_PAL_COLORS
) && !(pwc
->hGLPalette
)) {
281 wmCreatePalette( pwc
);
282 wmSetDibColors( pwc
);
284 wmSetPixelFormat(pwc
, pwc
->hDC
);
289 // D.R.S. 10/30/01 - this function is never referenced
291 * This function copies one scan line in a DIB section to another
293 BOOL
wmSetDIBits(PWMC pwc
, UINT uiScanWidth
, UINT uiNumScans
,
294 UINT nBypp
, UINT uiNewWidth
, LPBYTE pBits
)
297 LPBYTE pDest
= pwc
->pbPixels
;
298 DWORD dwNextScan
= uiScanWidth
;
299 DWORD dwNewScan
= uiNewWidth
;
300 DWORD dwScanWidth
= (uiScanWidth
* nBypp
);
303 * We need to round up to the nearest DWORD
304 * and multiply by the number of bytes per
307 dwNextScan
= (((dwNextScan
* nBypp
)+ 3) & ~3);
308 dwNewScan
= (((dwNewScan
* nBypp
)+ 3) & ~3);
310 for(uiScans
= 0; uiScans
< uiNumScans
; uiScans
++){
311 CopyMemory(pDest
, pBits
, dwScanWidth
);
319 #if defined(FAST_RASTERIZERS)
321 #define PIXELADDR(X,Y) \
322 ((GLubyte *)Current->pbPixels + (Current->height-Y-1)* \
323 Current->ScanWidth + (X)*nBypp)
324 #define PIXELADDR1( X, Y ) \
325 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X))
326 #define PIXELADDR2( X, Y ) \
327 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*2)
328 #define PIXELADDR4( X, Y ) \
329 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*4)
333 BYTE
DITHER_RGB_2_8BIT( int r
, int g
, int b
, int x
, int y
);
335 /* Finish all pending operations and synchronize. */
336 static void finish(GLcontext
* ctx
)
342 static void flush(GLcontext
* ctx
)
344 if((Current
->rgb_flag
&&!(Current
->db_flag
))
345 ||(!Current
->rgb_flag
))
355 * Set the color index used to clear the color buffer.
357 static void clear_index(GLcontext
* ctx
, GLuint index
)
359 Current
->clearpixel
= index
;
365 * Set the color used to clear the color buffer.
367 static void clear_color( GLcontext
* ctx
, const GLchan color
[4] )
369 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);
400 if (*colorMask
== 0xffffffff && ctx
->Color
.IndexMask
== 0xffffffff) {
401 if (mask
& DD_BACK_LEFT_BIT
) {
402 #if defined(USE_GDI_TO_CLEAR)
404 // D.R.S. 10/29/01 on my system (Pentium 4 with nvidia GeForce2 MX card,
405 // this is almose 100 times faster that the code below
407 HPEN Pen
=CreatePen(PS_SOLID
,1,Current
->clearpixel
);
408 HBRUSH Brush
=CreateSolidBrush(Current
->clearpixel
);
410 HBRUSH Old_Brush
=NULL
;
411 Current
->lpDDSOffScreen
->lpVtbl
->Unlock(Current
->lpDDSOffScreen
,NULL
);
412 Current
->lpDDSOffScreen
->lpVtbl
->GetDC(Current
->lpDDSOffScreen
,&DC
);
413 Old_Pen
=SelectObject(DC
,Pen
);
414 Old_Brush
=SelectObject(DC
,Brush
);
415 Rectangle(DC
,x
,y
,x
+width
,y
+height
);
416 SelectObject(DC
,Old_Pen
);
417 SelectObject(DC
,Old_Brush
);
420 Current
->lpDDSOffScreen
->lpVtbl
->ReleaseDC(Current
->lpDDSOffScreen
,DC
);
421 while (Current
->lpDDSOffScreen
->lpVtbl
->Lock(Current
->lpDDSOffScreen
,NULL
, &(Current
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
);
422 mask
&= ~DD_BACK_LEFT_BIT
;
426 HPEN Pen
=CreatePen(PS_SOLID
,1,Current
->clearpixel
);
427 HBRUSH Brush
=CreateSolidBrush(Current
->clearpixel
);
428 HPEN Old_Pen
=SelectObject(DC
,Pen
);
429 HBRUSH Old_Brush
=SelectObject(DC
,Brush
);
430 Rectangle(DC
,x
+Current
->rectSurface
.left
,Current
->rectSurface
.top
+y
,x
+width
+Current
->rectSurface
.left
,y
+height
+Current
->rectSurface
.top
);
431 SelectObject(DC
,Old_Pen
);
432 SelectObject(DC
,Old_Brush
);
436 mask
&= ~DD_BACK_LEFT_BIT
;
442 LPDWORD lpdw
= (LPDWORD
)Current
->pbPixels
;
443 LPWORD lpw
= (LPWORD
)Current
->pbPixels
;
444 LPBYTE lpb
= Current
->pbPixels
;
446 /* Double-buffering - clear back buffer */
447 UINT nBypp
= Current
->cColorBits
/ 8;
451 assert(Current
->db_flag
==GL_TRUE
); /* we'd better be double buffer */
453 iSize
= Current
->width
/4;
454 bColor
= BGR8(GetRValue(Current
->clearpixel
),
455 GetGValue(Current
->clearpixel
),
456 GetBValue(Current
->clearpixel
));
457 wColor
= MAKEWORD(bColor
,bColor
);
458 dwColor
= MAKELONG(wColor
, wColor
);
461 iSize
= Current
->width
/ 2;
462 wColor
= BGR16(GetRValue(Current
->clearpixel
),
463 GetGValue(Current
->clearpixel
),
464 GetBValue(Current
->clearpixel
));
465 dwColor
= MAKELONG(wColor
, wColor
);
468 iSize
= Current
->width
;
469 dwColor
= BGR32(GetRValue(Current
->clearpixel
),
470 GetGValue(Current
->clearpixel
),
471 GetBValue(Current
->clearpixel
));
481 /* This is the 24bit case */
483 iSize
= Current
->width
*3/4;
484 dwColor
= BGR24(GetRValue(Current
->clearpixel
),
485 GetGValue(Current
->clearpixel
),
486 GetBValue(Current
->clearpixel
));
500 /* copy cleared line to other lines in buffer */
502 memcpy(lpb
, Current
->pbPixels
, iSize
*4);
503 lpb
+= Current
->ScanWidth
;
507 mask
&= ~DD_BACK_LEFT_BIT
;
508 #endif // defined(USE_GDI_TO_CLEAR)
509 } /* double-buffer */
511 if (mask
& DD_FRONT_LEFT_BIT
) {
514 HPEN Pen
=CreatePen(PS_SOLID
,1,Current
->clearpixel
);
515 HBRUSH Brush
=CreateSolidBrush(Current
->clearpixel
);
516 HPEN Old_Pen
=SelectObject(DC
,Pen
);
517 HBRUSH Old_Brush
=SelectObject(DC
,Brush
);
518 Rectangle(DC
,x
+Current
->rectSurface
.left
,Current
->rectSurface
.top
+y
,x
+width
+Current
->rectSurface
.left
,y
+height
+Current
->rectSurface
.top
);
519 SelectObject(DC
,Old_Pen
);
520 SelectObject(DC
,Old_Brush
);
524 mask
&= ~DD_FRONT_LEFT_BIT
;
525 } /* single-buffer */
526 } /* if masks are all 1's */
528 /* Call swrast if there is anything left to clear (like DEPTH) */
530 _swrast_Clear( ctx
, mask
, all
, x
, y
, width
, height
);
535 static void enable( GLcontext
* ctx
, GLenum pname
, GLboolean enable
)
540 if (pname
== GL_DITHER
) {
541 if(enable
== GL_FALSE
){
542 Current
->dither_flag
= GL_FALSE
;
543 if(Current
->cColorBits
== 8)
544 Current
->pixelformat
= PF_INDEX8
;
547 if (Current
->rgb_flag
&& Current
->cColorBits
== 8){
548 Current
->pixelformat
= PF_DITHER8
;
549 Current
->dither_flag
= GL_TRUE
;
552 Current
->dither_flag
= GL_FALSE
;
557 static GLboolean
set_draw_buffer( GLcontext
* ctx
, GLenum mode
)
559 /* TODO: this could be better */
560 if (mode
==GL_FRONT_LEFT
|| mode
==GL_BACK_LEFT
) {
569 static void set_read_buffer(GLcontext
*ctx
, GLframebuffer
*colorBuffer
,
578 /* Return characteristics of the output buffer. */
579 static void buffer_size( GLcontext
* ctx
, GLuint
*width
, GLuint
*height
)
584 GetClientRect(Current
->Window
,&CR
);
589 New_Size
=((*width
)!=Current
->width
) || ((*height
)!=Current
->height
);
592 Current
->width
=*width
;
593 Current
->height
=*height
;
594 Current
->ScanWidth
=Current
->width
;
595 if ((Current
->ScanWidth
%sizeof(long))!=0)
596 Current
->ScanWidth
+=(sizeof(long)-(Current
->ScanWidth
%sizeof(long)));
598 if (Current
->db_flag
){
600 DDDeleteOffScreen(Current
);
601 DDCreateOffScreen(Current
);
603 if (Current
->rgb_flag
==GL_TRUE
&& Current
->dither_flag
!=GL_TRUE
){
604 wmDeleteBackingStore(Current
);
605 wmCreateBackingStore(Current
, Current
->width
, Current
->height
);
610 /* Resize OsmesaBuffer if in Parallel mode */
611 #if !defined(NO_PARALLEL)
613 PRSizeRenderBuffer(Current
->width
, Current
->height
,Current
->ScanWidth
,
614 Current
->rgb_flag
== GL_TRUE
? Current
->pbPixels
:
622 /**********************************************************************/
623 /***** Accelerated point, line, polygon rendering *****/
624 /**********************************************************************/
626 /* Accelerated routines are not implemented in 4.0. See OSMesa for ideas. */
628 static void fast_rgb_points( GLcontext
* ctx
, GLuint first
, GLuint last
)
632 /* Return pointer to accelerated points function */
633 extern points_func
choose_points_function( GLcontext
* ctx
)
638 static void fast_flat_rgb_line( GLcontext
* ctx
, GLuint v0
,
639 GLuint v1
, GLuint pv
)
643 static line_func
choose_line_function( GLcontext
* ctx
)
648 /**********************************************************************/
649 /***** Span-based pixel drawing *****/
650 /**********************************************************************/
653 /* Write a horizontal span of 32-bit color-index pixels with a boolean mask. */
654 static void write_ci32_span( const GLcontext
* ctx
,
655 GLuint n
, GLint x
, GLint y
,
656 const GLuint index
[],
657 const GLubyte mask
[] )
660 PBYTE Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
661 assert(Current
->rgb_flag
==GL_FALSE
);
668 /* Write a horizontal span of 8-bit color-index pixels with a boolean mask. */
669 static void write_ci8_span( const GLcontext
* ctx
,
670 GLuint n
, GLint x
, GLint y
,
671 const GLubyte index
[],
672 const GLubyte mask
[] )
675 PBYTE Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
676 assert(Current
->rgb_flag
==GL_FALSE
);
685 * Write a horizontal span of pixels with a boolean mask. The current
686 * color index is used for all pixels.
688 static void write_mono_ci_span(const GLcontext
* ctx
,
689 GLuint n
,GLint x
,GLint y
,
690 GLuint colorIndex
, const GLubyte mask
[])
693 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
694 assert(Current
->rgb_flag
==GL_FALSE
);
701 * To improve the performance of this routine, frob the data into an actual
702 * scanline and call bitblt on the complete scan line instead of SetPixel.
705 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
706 static void write_rgba_span( const GLcontext
* ctx
, GLuint n
, GLint x
, GLint y
,
707 const GLubyte rgba
[][4], const GLubyte mask
[] )
711 if (pwc
->rgb_flag
==GL_TRUE
)
719 wmSetPixel(pwc
, y
, x
+ i
,
720 rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
724 wmSetPixel(pwc
, y
, x
+ i
,
725 rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
] );
732 BYTE
*Mem
=Current
->ScreenMem
+y
*Current
->ScanWidth
+x
;
737 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,
744 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,
752 /* Write a horizontal span of RGB color pixels with a boolean mask. */
753 static void write_rgb_span( const GLcontext
* ctx
,
754 GLuint n
, GLint x
, GLint y
,
755 const GLubyte rgb
[][3], const GLubyte mask
[] )
759 if (pwc
->rgb_flag
==GL_TRUE
)
767 wmSetPixel(pwc
, y
, x
+ i
,
768 rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]);
772 wmSetPixel(pwc
, y
, x
+ i
,
773 rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
] );
780 BYTE
*Mem
=Current
->ScreenMem
+y
*Current
->ScanWidth
+x
;
785 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,
792 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,
801 * Write a horizontal span of pixels with a boolean mask. The current color
802 * is used for all pixels.
804 static void write_mono_rgba_span( const GLcontext
* ctx
,
805 GLuint n
, GLint x
, GLint y
,
806 const GLchan color
[4], const GLubyte mask
[])
810 assert(Current
->rgb_flag
==GL_TRUE
);
812 if(Current
->rgb_flag
==GL_TRUE
)
816 wmSetPixel(pwc
,y
,x
+i
,color
[RCOMP
], color
[GCOMP
], color
[BCOMP
]);
821 ULONG pixel
= RGB( color
[RCOMP
], color
[GCOMP
], color
[BCOMP
] );
824 SetPixel(DC
, y
, x
+i
, pixel
);
831 /**********************************************************************/
832 /***** Array-based pixel drawing *****/
833 /**********************************************************************/
836 /* Write an array of 32-bit index pixels with a boolean mask. */
837 static void write_ci32_pixels( const GLcontext
* ctx
,
838 GLuint n
, const GLint x
[], const GLint y
[],
839 const GLuint index
[], const GLubyte mask
[] )
842 assert(Current
->rgb_flag
==GL_FALSE
);
843 for (i
=0; i
<n
; i
++) {
845 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
];
854 * Write an array of pixels with a boolean mask. The current color
855 * index is used for all pixels.
857 static void write_mono_ci_pixels( const GLcontext
* ctx
,
859 const GLint x
[], const GLint y
[],
860 GLuint colorIndex
, const GLubyte mask
[] )
863 assert(Current
->rgb_flag
==GL_FALSE
);
864 for (i
=0; i
<n
; i
++) {
866 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
];
874 /* Write an array of RGBA pixels with a boolean mask. */
875 static void write_rgba_pixels( const GLcontext
* ctx
,
876 GLuint n
, const GLint x
[], const GLint y
[],
877 const GLubyte rgba
[][4], const GLubyte mask
[] )
882 assert(Current
->rgb_flag
==GL_TRUE
);
885 wmSetPixel(pwc
, FLIP(y
[i
]), x
[i
],
886 rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
893 * Write an array of pixels with a boolean mask. The current color
894 * is used for all pixels.
896 static void write_mono_rgba_pixels( const GLcontext
* ctx
,
898 const GLint x
[], const GLint y
[],
899 const GLchan color
[4],
900 const GLubyte mask
[] )
905 assert(Current
->rgb_flag
==GL_TRUE
);
908 wmSetPixel(pwc
, FLIP(y
[i
]),x
[i
],color
[RCOMP
],
909 color
[GCOMP
], color
[BCOMP
]);
915 /**********************************************************************/
916 /***** Read spans/arrays of pixels *****/
917 /**********************************************************************/
920 /* Read a horizontal span of color-index pixels. */
921 static void read_ci32_span( const GLcontext
* ctx
, GLuint n
, GLint x
, GLint y
,
925 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
926 assert(Current
->rgb_flag
==GL_FALSE
);
934 /* Read an array of color index pixels. */
935 static void read_ci32_pixels( const GLcontext
* ctx
,
936 GLuint n
, const GLint x
[], const GLint y
[],
937 GLuint indx
[], const GLubyte mask
[] )
940 assert(Current
->rgb_flag
==GL_FALSE
);
941 for (i
=0; i
<n
; i
++) {
943 indx
[i
]=*(Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
]);
950 /* Read a horizontal span of color pixels. */
951 static void read_rgba_span( const GLcontext
* ctx
,
952 GLuint n
, GLint x
, GLint y
,
958 assert(Current
->rgb_flag
==GL_TRUE
);
959 y
= Current
->height
- y
- 1;
960 for (i
=0; i
<n
; i
++) {
961 Color
=GetPixel(DC
,x
+i
,y
);
962 rgba
[i
][RCOMP
] = GetRValue(Color
);
963 rgba
[i
][GCOMP
] = GetGValue(Color
);
964 rgba
[i
][BCOMP
] = GetBValue(Color
);
965 rgba
[i
][ACOMP
] = 255;
971 /* Read an array of color pixels. */
972 static void read_rgba_pixels( const GLcontext
* ctx
,
973 GLuint n
, const GLint x
[], const GLint y
[],
974 GLubyte rgba
[][4], const GLubyte mask
[] )
979 assert(Current
->rgb_flag
==GL_TRUE
);
980 for (i
=0; i
<n
; i
++) {
982 GLint y2
= Current
->height
- y
[i
] - 1;
983 Color
=GetPixel(DC
,x
[i
],y2
);
984 rgba
[i
][RCOMP
] = GetRValue(Color
);
985 rgba
[i
][GCOMP
] = GetGValue(Color
);
986 rgba
[i
][BCOMP
] = GetBValue(Color
);
987 rgba
[i
][ACOMP
] = 255;
995 /**********************************************************************/
996 /**********************************************************************/
999 static const GLubyte
*get_string(GLcontext
*ctx
, GLenum name
)
1001 if (name
== GL_RENDERER
) {
1002 return (GLubyte
*) "Mesa Windows";
1009 static void wmesa_update_state( GLcontext
*ctx
, GLuint new_state
);
1011 static void SetFunctionPointers(GLcontext
*ctx
)
1013 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference( ctx
);
1014 ctx
->Driver
.GetString
= get_string
;
1015 ctx
->Driver
.UpdateState
= wmesa_update_state
;
1016 ctx
->Driver
.SetDrawBuffer
= set_draw_buffer
;
1017 ctx
->Driver
.ResizeBuffersMESA
= _swrast_alloc_buffers
;
1018 ctx
->Driver
.GetBufferSize
= buffer_size
;
1020 ctx
->Driver
.Accum
= _swrast_Accum
;
1021 ctx
->Driver
.Bitmap
= _swrast_Bitmap
;
1022 ctx
->Driver
.Clear
= clear
;
1024 ctx
->Driver
.Flush
= flush
;
1025 ctx
->Driver
.ClearIndex
= clear_index
;
1026 ctx
->Driver
.ClearColor
= clear_color
;
1027 ctx
->Driver
.Enable
= enable
;
1029 ctx
->Driver
.CopyPixels
= _swrast_CopyPixels
;
1030 ctx
->Driver
.DrawPixels
= _swrast_DrawPixels
;
1031 ctx
->Driver
.ReadPixels
= _swrast_ReadPixels
;
1033 ctx
->Driver
.ChooseTextureFormat
= _mesa_choose_tex_format
;
1034 ctx
->Driver
.TexImage1D
= _mesa_store_teximage1d
;
1035 ctx
->Driver
.TexImage2D
= _mesa_store_teximage2d
;
1036 ctx
->Driver
.TexImage3D
= _mesa_store_teximage3d
;
1037 ctx
->Driver
.TexSubImage1D
= _mesa_store_texsubimage1d
;
1038 ctx
->Driver
.TexSubImage2D
= _mesa_store_texsubimage2d
;
1039 ctx
->Driver
.TexSubImage3D
= _mesa_store_texsubimage3d
;
1040 ctx
->Driver
.TestProxyTexImage
= _mesa_test_proxy_teximage
;
1042 ctx
->Driver
.CopyTexImage1D
= _swrast_copy_teximage1d
;
1043 ctx
->Driver
.CopyTexImage2D
= _swrast_copy_teximage2d
;
1044 ctx
->Driver
.CopyTexSubImage1D
= _swrast_copy_texsubimage1d
;
1045 ctx
->Driver
.CopyTexSubImage2D
= _swrast_copy_texsubimage2d
;
1046 ctx
->Driver
.CopyTexSubImage3D
= _swrast_copy_texsubimage3d
;
1047 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1048 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1049 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1050 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;
1052 ctx
->Driver
.BaseCompressedTexFormat
= _mesa_base_compressed_texformat
;
1053 ctx
->Driver
.CompressedTextureSize
= _mesa_compressed_texture_size
;
1054 ctx
->Driver
.GetCompressedTexImage
= _mesa_get_compressed_teximage
;
1057 swdd
->SetReadBuffer
= set_read_buffer
;
1060 /* Pixel/span writing functions: */
1061 swdd
->WriteRGBASpan
= write_rgba_span
;
1062 swdd
->WriteRGBSpan
= write_rgb_span
;
1063 swdd
->WriteMonoRGBASpan
= write_mono_rgba_span
;
1064 swdd
->WriteRGBAPixels
= write_rgba_pixels
;
1065 swdd
->WriteMonoRGBAPixels
= write_mono_rgba_pixels
;
1066 swdd
->WriteCI32Span
= write_ci32_span
;
1067 swdd
->WriteCI8Span
= write_ci8_span
;
1068 swdd
->WriteMonoCISpan
= write_mono_ci_span
;
1069 swdd
->WriteCI32Pixels
= write_ci32_pixels
;
1070 swdd
->WriteMonoCIPixels
= write_mono_ci_pixels
;
1072 swdd
->ReadCI32Span
= read_ci32_span
;
1073 swdd
->ReadRGBASpan
= read_rgba_span
;
1074 swdd
->ReadCI32Pixels
= read_ci32_pixels
;
1075 swdd
->ReadRGBAPixels
= read_rgba_pixels
;
1079 static void wmesa_update_state( GLcontext
*ctx
, GLuint new_state
)
1081 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference( ctx
);
1082 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1085 * XXX these function pointers could be initialized just once during
1086 * context creation since they don't depend on any state changes.
1087 * kws - This is true - this function gets called a lot and it
1088 * would be good to minimize setting all this when not needed.
1090 #ifndef SET_FPOINTERS_ONCE
1091 SetFunctionPointers(ctx
);
1093 ctx
->Driver
.GetString
= get_string
;
1094 ctx
->Driver
.UpdateState
= wmesa_update_state
;
1095 ctx
->Driver
.SetDrawBuffer
= set_draw_buffer
;
1096 ctx
->Driver
.ResizeBuffersMESA
= _swrast_alloc_buffers
;
1097 ctx
->Driver
.GetBufferSize
= buffer_size
;
1099 ctx
->Driver
.Accum
= _swrast_Accum
;
1100 ctx
->Driver
.Bitmap
= _swrast_Bitmap
;
1101 ctx
->Driver
.Clear
= clear
;
1103 ctx
->Driver
.Flush
= flush
;
1104 ctx
->Driver
.ClearIndex
= clear_index
;
1105 ctx
->Driver
.ClearColor
= clear_color
;
1106 ctx
->Driver
.Enable
= enable
;
1108 ctx
->Driver
.CopyPixels
= _swrast_CopyPixels
;
1109 ctx
->Driver
.DrawPixels
= _swrast_DrawPixels
;
1110 ctx
->Driver
.ReadPixels
= _swrast_ReadPixels
;
1112 ctx
->Driver
.ChooseTextureFormat
= _mesa_choose_tex_format
;
1113 ctx
->Driver
.TexImage1D
= _mesa_store_teximage1d
;
1114 ctx
->Driver
.TexImage2D
= _mesa_store_teximage2d
;
1115 ctx
->Driver
.TexImage3D
= _mesa_store_teximage3d
;
1116 ctx
->Driver
.TexSubImage1D
= _mesa_store_texsubimage1d
;
1117 ctx
->Driver
.TexSubImage2D
= _mesa_store_texsubimage2d
;
1118 ctx
->Driver
.TexSubImage3D
= _mesa_store_texsubimage3d
;
1119 ctx
->Driver
.TestProxyTexImage
= _mesa_test_proxy_teximage
;
1121 ctx
->Driver
.CopyTexImage1D
= _swrast_copy_teximage1d
;
1122 ctx
->Driver
.CopyTexImage2D
= _swrast_copy_teximage2d
;
1123 ctx
->Driver
.CopyTexSubImage1D
= _swrast_copy_texsubimage1d
;
1124 ctx
->Driver
.CopyTexSubImage2D
= _swrast_copy_texsubimage2d
;
1125 ctx
->Driver
.CopyTexSubImage3D
= _swrast_copy_texsubimage3d
;
1126 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1127 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1128 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1129 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;
1131 ctx
->Driver
.BaseCompressedTexFormat
= _mesa_base_compressed_texformat
;
1132 ctx
->Driver
.CompressedTextureSize
= _mesa_compressed_texture_size
;
1133 ctx
->Driver
.GetCompressedTexImage
= _mesa_get_compressed_teximage
;
1136 swdd
->SetReadBuffer
= set_read_buffer
;
1139 /* Pixel/span writing functions: */
1140 swdd
->WriteRGBASpan
= write_rgba_span
;
1141 swdd
->WriteRGBSpan
= write_rgb_span
;
1142 swdd
->WriteMonoRGBASpan
= write_mono_rgba_span
;
1143 swdd
->WriteRGBAPixels
= write_rgba_pixels
;
1144 swdd
->WriteMonoRGBAPixels
= write_mono_rgba_pixels
;
1145 swdd
->WriteCI32Span
= write_ci32_span
;
1146 swdd
->WriteCI8Span
= write_ci8_span
;
1147 swdd
->WriteMonoCISpan
= write_mono_ci_span
;
1148 swdd
->WriteCI32Pixels
= write_ci32_pixels
;
1149 swdd
->WriteMonoCIPixels
= write_mono_ci_pixels
;
1151 swdd
->ReadCI32Span
= read_ci32_span
;
1152 swdd
->ReadRGBASpan
= read_rgba_span
;
1153 swdd
->ReadCI32Pixels
= read_ci32_pixels
;
1154 swdd
->ReadRGBAPixels
= read_rgba_pixels
;
1156 #endif // !SET_FPOINTERS_ONCE
1157 tnl
->Driver
.RunPipeline
= _tnl_run_pipeline
;
1159 _swrast_InvalidateState( ctx
, new_state
);
1160 _swsetup_InvalidateState( ctx
, new_state
);
1161 _ac_InvalidateState( ctx
, new_state
);
1162 _tnl_InvalidateState( ctx
, new_state
);
1168 /**********************************************************************/
1169 /***** WMesa API Functions *****/
1170 /**********************************************************************/
1174 #define PAL_SIZE 256
1175 static void GetPalette(HPALETTE Pal
,RGBQUAD
*aRGB
)
1182 WORD NumberOfEntries
;
1183 PALETTEENTRY aEntries
[PAL_SIZE
];
1191 GetPaletteEntries(Pal
,0,PAL_SIZE
,Palette
.aEntries
);
1193 GetSystemPaletteEntries(hdc
,0,PAL_SIZE
,Palette
.aEntries
);
1194 if (GetSystemPaletteUse(hdc
) == SYSPAL_NOSTATIC
)
1196 for(i
= 0; i
<PAL_SIZE
; i
++)
1197 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1198 Palette
.aEntries
[255].peRed
= 255;
1199 Palette
.aEntries
[255].peGreen
= 255;
1200 Palette
.aEntries
[255].peBlue
= 255;
1201 Palette
.aEntries
[255].peFlags
= 0;
1202 Palette
.aEntries
[0].peRed
= 0;
1203 Palette
.aEntries
[0].peGreen
= 0;
1204 Palette
.aEntries
[0].peBlue
= 0;
1205 Palette
.aEntries
[0].peFlags
= 0;
1211 nStaticColors
= GetDeviceCaps(hdc
, NUMCOLORS
)/2;
1212 for (i
=0; i
<nStaticColors
; i
++)
1213 Palette
.aEntries
[i
].peFlags
= 0;
1214 nUsableColors
= PAL_SIZE
-nStaticColors
;
1215 for (; i
<nUsableColors
; i
++)
1216 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1217 for (; i
<PAL_SIZE
-nStaticColors
; i
++)
1218 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1219 for (i
=PAL_SIZE
-nStaticColors
; i
<PAL_SIZE
; i
++)
1220 Palette
.aEntries
[i
].peFlags
= 0;
1222 ReleaseDC(NULL
,hdc
);
1223 for (i
=0; i
<PAL_SIZE
; i
++)
1225 aRGB
[i
].rgbRed
=Palette
.aEntries
[i
].peRed
;
1226 aRGB
[i
].rgbGreen
=Palette
.aEntries
[i
].peGreen
;
1227 aRGB
[i
].rgbBlue
=Palette
.aEntries
[i
].peBlue
;
1228 aRGB
[i
].rgbReserved
=Palette
.aEntries
[i
].peFlags
;
1233 WMesaContext
WMesaCreateContext( HWND hWnd
, HPALETTE
* Pal
,
1239 GLboolean true_color_flag
;
1240 c
= (struct wmesa_context
* ) calloc(1,sizeof(struct wmesa_context
));
1245 c
->hDC
= GetDC(hWnd
);
1246 true_color_flag
= GetDeviceCaps(c
->hDC
, BITSPIXEL
) > 8;
1248 if(true_color_flag
) c
->rgb_flag
= rgb_flag
= GL_TRUE
;
1253 if ((true_color_flag
==GL_FALSE
) && (rgb_flag
== GL_TRUE
)){
1254 c
->dither_flag
= GL_TRUE
;
1256 c
->hPalHalfTone
= WinGCreateHalftonePalette();
1258 c
->hPalHalfTone
= CreateHalftonePalette(c
->hDC
);
1262 c
->dither_flag
= GL_FALSE
;
1264 c
->dither_flag
= GL_FALSE
;
1268 if (rgb_flag
==GL_FALSE
)
1270 c
->rgb_flag
= GL_FALSE
;
1272 /* Old WinG stuff???? */
1273 c
->db_flag
= db_flag
=GL_TRUE
; /* WinG requires double buffering */
1274 printf("Single buffer is not supported in color index mode, ",
1275 "setting to double buffer.\n");
1280 c
->rgb_flag
= GL_TRUE
;
1282 GetClientRect(c
->Window
,&CR
);
1284 c
->height
=CR
.bottom
;
1288 /* Double buffered */
1291 wmCreateBackingStore(c
, c
->width
, c
->height
);
1298 /* Single Buffered */
1303 if (DDInit(c
,hWnd
) == GL_FALSE
) {
1310 c
->gl_visual
= _mesa_create_visual(rgb_flag
,
1311 db_flag
, /* db_flag */
1312 GL_FALSE
, /* stereo */
1313 8,8,8,8, /* r, g, b, a bits */
1315 16, /* depth_bits */
1316 8, /* stencil_bits */
1317 16,16,16,16,/* accum_bits */
1320 if (!c
->gl_visual
) {
1324 /* allocate a new Mesa context */
1325 c
->gl_ctx
= _mesa_create_context( c
->gl_visual
, NULL
, c
, GL_TRUE
);
1328 _mesa_destroy_visual( c
->gl_visual
);
1333 if (!_mesa_initialize_context(c
->gl_ctx
,
1336 (void *) c
, GL_TRUE
)) {
1337 _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 GL_FALSE
/* 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
);
1399 wmDeleteBackingStore(c
);
1402 #if !defined(NO_PARALLEL)
1404 PRDestroyRenderBuffer();
1409 void WMesaMakeCurrent( WMesaContext c
)
1419 wmesa_update_state(c
->gl_ctx
, 0);
1420 _mesa_make_current(c
->gl_ctx
, c
->gl_buffer
);
1422 if (Current
->gl_ctx
->Viewport
.Width
==0) {
1423 /* initialize viewport to window size */
1424 _mesa_Viewport( 0, 0, Current
->width
, Current
->height
);
1425 Current
->gl_ctx
->Scissor
.Width
= Current
->width
;
1426 Current
->gl_ctx
->Scissor
.Height
= Current
->height
;
1428 if ((c
->cColorBits
<= 8 ) && (c
->rgb_flag
== GL_TRUE
)){
1429 WMesaPaletteChange(c
->hPalHalfTone
);
1435 void WMesaSwapBuffers( void )
1437 HDC DC
= Current
->hDC
;
1438 GET_CURRENT_CONTEXT(ctx
);
1440 /* If we're swapping the buffer associated with the current context
1441 * we have to flush any pending rendering commands first.
1443 if (Current
&& Current
->gl_ctx
== ctx
)
1444 _mesa_swapbuffers(ctx
);
1446 if (Current
->db_flag
)
1452 void WMesaPaletteChange(HPALETTE Pal
)
1457 LPPALETTEENTRY pPal
;
1458 if (Current
&& (Current
->rgb_flag
==GL_FALSE
||
1459 Current
->dither_flag
== GL_TRUE
))
1461 pPal
= (PALETTEENTRY
*)malloc( 256 * sizeof(PALETTEENTRY
));
1463 GetPaletteEntries( Pal
, 0, 256, pPal
);
1465 Current
->lpDD
->lpVtbl
->CreatePalette(Current
->lpDD
,DDPCAPS_8BIT
,
1466 pPal
, &(Current
->lpDDPal
), NULL
);
1467 if (Current
->lpDDPal
)
1468 Current
->lpDDSPrimary
->lpVtbl
->SetPalette(Current
->lpDDSPrimary
,
1471 vRet
= SetDIBColorTable(Current
->dib
.hDC
, 0, 256, (RGBQUAD
*)pPal
);
1480 static unsigned char threeto8
[8] = {
1481 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
1484 static unsigned char twoto8
[4] = {
1488 static unsigned char oneto8
[2] = {
1492 static unsigned char componentFromIndex(UCHAR i
, UINT nbits
, UINT shift
)
1509 return threeto8
[val
];
1516 void wmCreatePalette( PWMC pwdc
)
1518 /* Create a compressed and re-expanded 3:3:2 palette */
1521 BYTE rb
, rs
, gb
, gs
, bb
, bs
;
1523 pwdc
->nColors
= 0x100;
1525 pPal
= (PLOGPALETTE
)malloc(sizeof(LOGPALETTE
) +
1526 pwdc
->nColors
* sizeof(PALETTEENTRY
));
1527 memset( pPal
, 0, sizeof(LOGPALETTE
) + pwdc
->nColors
* sizeof(PALETTEENTRY
) );
1529 pPal
->palVersion
= 0x300;
1538 if (pwdc
->db_flag
) {
1540 /* Need to make two palettes: one for the screen DC and one for the DIB. */
1541 pPal
->palNumEntries
= pwdc
->nColors
;
1542 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1543 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1544 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1545 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1546 pPal
->palPalEntry
[i
].peFlags
= 0;
1548 pwdc
->hGLPalette
= CreatePalette( pPal
);
1549 pwdc
->hPalette
= CreatePalette( pPal
);
1553 pPal
->palNumEntries
= pwdc
->nColors
;
1554 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1555 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1556 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1557 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1558 pPal
->palPalEntry
[i
].peFlags
= 0;
1560 pwdc
->hGLPalette
= CreatePalette( pPal
);
1569 #ifdef COMPILE_SETPIXEL
1571 wmSetPixelDefault(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1573 if (Current
->db_flag
)
1577 Current
->lpDDSOffScreen
->lpVtbl
->Unlock(Current
->lpDDSOffScreen
,NULL
);
1578 Current
->lpDDSOffScreen
->lpVtbl
->GetDC(Current
->lpDDSOffScreen
,&hdc
);
1579 SetPixelV(hdc
,iPixel
, iScanLine
, RGB(r
,g
,b
));
1580 Current
->lpDDSOffScreen
->lpVtbl
->ReleaseDC(Current
->lpDDSOffScreen
,hdc
);
1581 while (Current
->lpDDSOffScreen
->lpVtbl
->Lock(Current
->lpDDSOffScreen
,NULL
, &(Current
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
);
1583 SetPixelV(Current
->hDC
, iPixel
, iScanLine
, RGB(r
,g
,b
));
1588 SetPixelV(Current
->hDC
, iPixel
+pwc
->rectSurface
.left
, pwc
->rectSurface
.top
+iScanLine
, RGB(r
,g
,b
));
1592 wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1594 if (Current
->db_flag
)
1596 LPBYTE lpb
= pwc
->pbPixels
;
1597 UINT nBypp
= pwc
->cColorBits
>> 3;
1599 lpb
+= pwc
->ScanWidth
* iScanLine
;
1600 lpb
+= iPixel
* nBypp
;
1604 if(pwc
->dither_flag
)
1605 *lpb
= DITHER_RGB_2_8BIT(r
,g
,b
,iScanLine
,iPixel
);
1610 *((LPWORD
)lpb
) = BGR16(r
,g
,b
);
1611 else if (nBypp
== 3)
1612 *((LPDWORD
)lpb
) = BGR24(r
,g
,b
);
1613 else if (nBypp
== 4)
1614 *((LPDWORD
)lpb
) = BGR32(r
,g
,b
);
1618 SetPixel(Current
->hDC
, iPixel
, iScanLine
, RGB(r
,g
,b
));
1622 #ifdef COMPILE_SETPIXEL
1623 void wmSetPixel4(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1625 LPDWORD lpdw
= ((LPDWORD
)(pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
)) + iPixel
;
1626 *lpdw
= BGR32(r
,g
,b
);
1627 // LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel + iPixel + iPixel;
1628 // *((LPDWORD)lpb) = BGR32(r,g,b);
1631 void wmSetPixel3(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1633 LPBYTE lpb
= pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
+ iPixel
+ iPixel
+ iPixel
;
1634 *((LPDWORD
)lpb
) = BGR24(r
,g
,b
);
1637 void wmSetPixel2(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1639 LPWORD lpw
= ((LPWORD
)(pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
)) + iPixel
;
1640 *lpw
= BGR16(r
,g
,b
);
1641 // LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel;
1642 // *((LPWORD)lpb) = BGR16(r,g,b);
1645 void wmSetPixel1(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1647 LPBYTE lpb
= pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
+ iPixel
;
1651 void wmSetPixel1Dither(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1653 LPBYTE lpb
= pwc
->pbPixels
+ pwc
->ScanWidth
* iScanLine
+ iPixel
;
1654 *lpb
= DITHER_RGB_2_8BIT(r
,g
,b
,iScanLine
,iPixel
);
1658 void ChooseSetPixel(PWMC pwc
)
1660 UINT nBypp
= (pwc
) ? pwc
->cColorBits
>> 3 : 0;
1664 pwc
->wmSetPixel
= pwc
->dither_flag
? &wmSetPixel1Dither
: &wmSetPixel1
;
1667 pwc
->wmSetPixel
= &wmSetPixel2
;
1670 pwc
->wmSetPixel
= &wmSetPixel3
;
1673 pwc
->wmSetPixel
= &wmSetPixel4
;
1676 pwc
->wmSetPixel
= &wmSetPixelDefault
;
1683 void wmCreateDIBSection(
1685 PWMC pwc
, // handle of device context
1686 CONST BITMAPINFO
*pbmi
, // bitmap size, format, and color data
1687 UINT iUsage
// color data type indicator: RGB values or palette indices
1692 UINT nBypp
= pwc
->cColorBits
/ 8;
1695 dwScanWidth
= (((pwc
->ScanWidth
* nBypp
)+ 3) & ~3);
1697 pwc
->ScanWidth
=pwc
->pitch
= dwScanWidth
;
1700 pwc
->ScanWidth
= 2* pwc
->pitch
;
1702 dwSize
= sizeof(BITMAPINFO
) + (dwScanWidth
* pwc
->height
);
1703 #ifdef USE_MAPPED_FILE
1704 pwc
->dib
.hFileMap
= CreateFileMapping((HANDLE
)PAGE_FILE
,
1706 PAGE_READWRITE
| SEC_COMMIT
,
1711 if (!pwc
->dib
.hFileMap
)
1714 pwc
->dib
.base
= MapViewOfFile(pwc
->dib
.hFileMap
,
1715 FILE_MAP_ALL_ACCESS
,
1721 CloseHandle(pwc
->dib
.hFileMap
);
1726 CopyMemory(pwc
->dib
.base
, pbmi
, sizeof(BITMAPINFO
));
1727 #endif // USE_MAPPED_FILE
1729 hic
= CreateIC("display", NULL
, NULL
, NULL
);
1730 pwc
->dib
.hDC
= CreateCompatibleDC(hic
);
1732 #ifdef USE_MAPPED_FILE
1734 pwc
->hbmDIB
= CreateDIBSection(hic
,
1736 (iUsage
? DIB_PAL_COLORS
: DIB_RGB_COLORS
),
1741 pwc
->hbmDIB
= CreateDIBSection(hic
,
1743 (iUsage
? DIB_PAL_COLORS
: DIB_RGB_COLORS
),
1747 #endif // USE_MAPPED_FILE
1748 pwc
->ScreenMem
= pwc
->addrOffScreen
= pwc
->pbPixels
;
1749 pwc
->hOldBitmap
= SelectObject(pwc
->dib
.hDC
, pwc
->hbmDIB
);
1758 * Blit memory DC to screen DC
1760 BOOL
wmFlush(PWMC pwc
)
1770 if (pwc
->lpDDSOffScreen
== NULL
)
1771 if(DDCreateOffScreen(pwc
) == GL_FALSE
)
1774 pwc
->lpDDSOffScreen
->lpVtbl
->Unlock(pwc
->lpDDSOffScreen
, NULL
);
1778 ddrval
= pwc
->lpDDSPrimary
->lpVtbl
->Blt( pwc
->lpDDSPrimary
,
1779 &(pwc
->rectSurface
),
1780 pwc
->lpDDSOffScreen
,
1781 &(pwc
->rectOffScreen
),
1784 if( ddrval
== DD_OK
)
1788 if( ddrval
== DDERR_SURFACELOST
)
1790 if(!DDRestoreAll(pwc
))
1795 if( ddrval
!= DDERR_WASSTILLDRAWING
)
1801 while (pwc
->lpDDSOffScreen
->lpVtbl
->Lock(pwc
->lpDDSOffScreen
,
1802 NULL
, &(pwc
->ddsd
), 0, NULL
) ==
1803 DDERR_WASSTILLDRAWING
)
1807 dwErr
= GetLastError();
1809 bRet
= BitBlt(pwc
->hDC
, 0, 0, pwc
->width
, pwc
->height
,
1810 pwc
->dib
.hDC
, 0, 0, SRCCOPY
);
1819 /* The following code is added by Li Wei to enable stereo display */
1821 #if !defined(NO_STEREO)
1823 static void __gluMakeIdentityf(GLfloat m
[16])
1825 m
[0+4*0] = 1; m
[0+4*1] = 0; m
[0+4*2] = 0; m
[0+4*3] = 0;
1826 m
[1+4*0] = 0; m
[1+4*1] = 1; m
[1+4*2] = 0; m
[1+4*3] = 0;
1827 m
[2+4*0] = 0; m
[2+4*1] = 0; m
[2+4*2] = 1; m
[2+4*3] = 0;
1828 m
[3+4*0] = 0; m
[3+4*1] = 0; m
[3+4*2] = 0; m
[3+4*3] = 1;
1831 static void normalize(float v
[3])
1835 r
= sqrt( v
[0]*v
[0] + v
[1]*v
[1] + v
[2]*v
[2] );
1836 if (r
== 0.0) return;
1843 static void cross(float v1
[3], float v2
[3], float result
[3])
1845 result
[0] = v1
[1]*v2
[2] - v1
[2]*v2
[1];
1846 result
[1] = v1
[2]*v2
[0] - v1
[0]*v2
[2];
1847 result
[2] = v1
[0]*v2
[1] - v1
[1]*v2
[0];
1852 __gluLookAt(GLdouble eyex
, GLdouble eyey
, GLdouble eyez
, GLdouble centerx
,
1853 GLdouble centery
, GLdouble centerz
, GLdouble upx
, GLdouble upy
,
1857 float forward
[3], side
[3], up
[3];
1860 forward
[0] = centerx
- eyex
;
1861 forward
[1] = centery
- eyey
;
1862 forward
[2] = centerz
- eyez
;
1870 /* Side = forward x up */
1871 cross(forward
, up
, side
);
1874 /* Recompute up as: up = side x forward */
1875 cross(side
, forward
, up
);
1877 __gluMakeIdentityf(&m
[0][0]);
1886 m
[0][2] = -forward
[0];
1887 m
[1][2] = -forward
[1];
1888 m
[2][2] = -forward
[2];
1890 glMultMatrixf(&m
[0][0]);
1891 glTranslated(-eyex
, -eyey
, -eyez
);
1894 GLfloat viewDistance
= 1.0;
1896 void WMesaShowStereo(GLuint list
)
1899 GLbitfield mask
= GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
;
1902 /* Must use double Buffer */
1903 if( ! Current
-> db_flag
)
1907 glGetIntegerv(GL_MATRIX_MODE
,&matrix_mode
);
1909 WMesaViewport(Current
->gl_ctx
,0,Current
->height
/2,
1910 Current
->width
,Current
->height
/2);
1911 if(matrix_mode
!=GL_MODELVIEW
)
1912 glMatrixMode(GL_MODELVIEW
);
1914 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1916 __gluLookAt(viewDistance
/2,0.0,0.0 ,
1917 viewDistance
/2,0.0,-1.0,
1919 glMultMatrixf( cm
);
1921 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
;
1924 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1926 __gluLookAt(-viewDistance
/2,0.0,0.0 ,
1927 -viewDistance
/2,0.0,-1.0,
1931 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
+ Current
->pitch
;
1933 if(matrix_mode
!=GL_MODELVIEW
)
1934 glMatrixMode(matrix_mode
);
1938 WMesaViewport(Current
->gl_ctx
,0,0,Current
->width
,Current
->height
);
1942 void toggleStereoMode()
1944 if(!Current
->db_flag
)
1948 if(stereoBuffer
==GL_FALSE
)
1949 #if !defined(NO_PARALLEL)
1953 Current
->ScanWidth
= Current
->pitch
*2;
1958 #if !defined(NO_PARALLEL)
1961 Current
->ScanWidth
= Current
->pitch
;
1962 Current
->pbPixels
= Current
->addrOffScreen
;
1966 /* if in stereo mode, the following function is called */
1967 void glShowStereo(GLuint list
)
1969 WMesaShowStereo(list
);
1972 #endif /* NO_STEREO */
1974 #if !defined(NO_PARALLEL)
1976 void toggleParallelMode(void)
1979 parallelFlag
= GL_TRUE
;
1980 if(parallelMachine
==GL_FALSE
){
1981 PRCreateRenderBuffer( Current
->rgb_flag
? GL_RGBA
:GL_COLOR_INDEX
,
1982 Current
->cColorBits
/8,
1983 Current
->width
,Current
->height
,
1985 Current
->rgb_flag
? Current
->pbPixels
:
1986 Current
->ScreenMem
);
1987 parallelMachine
= GL_TRUE
;
1991 parallelFlag
= GL_FALSE
;
1992 if(parallelMachine
==GL_TRUE
){
1993 PRDestroyRenderBuffer();
1994 parallelMachine
=GL_FALSE
;
1995 ReadyForNextFrame
= GL_TRUE
;
1998 /***********************************************
1999 * Seems something wrong!!!!
2000 ************************************************/
2002 WMesaMakeCurrent(Current
);
2003 #if !defined(NO_STEREO)
2004 stereo_flag
= GL_FALSE
;
2009 void PRShowRenderResult(void)
2012 if(!glImageRendered())
2021 #endif /* NO_PARALLEL */
2023 BYTE
DITHER_RGB_2_8BIT( int red
, int green
, int blue
, int pixel
, int scanline
)
2025 char unsigned redtemp
, greentemp
, bluetemp
, paletteindex
;
2027 //*** now, look up each value in the halftone matrix
2028 //*** using an 8x8 ordered dither.
2029 redtemp
= aDividedBy51
[red
]
2030 + (aModulo51
[red
] > aHalftone8x8
[(pixel
%8)*8
2032 greentemp
= aDividedBy51
[(char unsigned)green
]
2033 + (aModulo51
[green
] > aHalftone8x8
[
2034 (pixel
%8)*8 + scanline
%8]);
2035 bluetemp
= aDividedBy51
[(char unsigned)blue
]
2036 + (aModulo51
[blue
] > aHalftone8x8
[
2037 (pixel
%8)*8 +scanline
%8]);
2039 //*** recombine the halftoned rgb values into a palette index
2041 redtemp
+ aTimes6
[greentemp
] + aTimes36
[bluetemp
];
2043 //*** and translate through the wing halftone palette
2044 //*** translation vector to give the correct value.
2045 return aWinGHalftoneTranslation
[paletteindex
];
2052 * restore all lost objects
2054 HRESULT
DDRestoreAll( WMesaContext wc
)
2058 ddrval
= wc
->lpDDSPrimary
->lpVtbl
->Restore(wc
->lpDDSPrimary
);
2059 if( ddrval
== DD_OK
)
2061 ddrval
= wc
->lpDDSOffScreen
->lpVtbl
->Restore(wc
->lpDDSOffScreen
);
2069 * This function is called if the initialization function fails
2071 BOOL
initFail( HWND hwnd
, WMesaContext wc
)
2074 MessageBox( hwnd
, "DirectDraw Init FAILED", "", MB_OK
);
2080 static void DDDeleteOffScreen(WMesaContext wc
)
2082 if( wc
->lpDDSOffScreen
!= NULL
)
2084 wc
->lpDDSOffScreen
->lpVtbl
->Unlock(wc
->lpDDSOffScreen
,NULL
);
2085 wc
->lpDDSOffScreen
->lpVtbl
->Release(wc
->lpDDSOffScreen
);
2086 wc
->lpDDSOffScreen
= NULL
;
2091 static void DDFreePrimarySurface(WMesaContext wc
)
2093 if( wc
->lpDDSPrimary
!= NULL
)
2095 if(wc
->db_flag
== GL_FALSE
)
2096 wc
->lpDDSPrimary
->lpVtbl
->ReleaseDC(wc
->lpDDSPrimary
, wc
->hDC
);
2097 wc
->lpDDSPrimary
->lpVtbl
->Release(wc
->lpDDSPrimary
);
2098 wc
->lpDDSPrimary
= NULL
;
2102 static BOOL
DDCreatePrimarySurface(WMesaContext wc
)
2106 wc
->ddsd
.dwSize
= sizeof( wc
->ddsd
);
2107 wc
->ddsd
.dwFlags
= DDSD_CAPS
;
2108 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2110 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
,&(wc
->ddsd
),
2111 &(wc
->lpDDSPrimary
), NULL
);
2112 if( ddrval
!= DD_OK
)
2114 return initFail(wc
->hwnd
, wc
);
2116 if(wc
->db_flag
== GL_FALSE
)
2117 wc
->lpDDSPrimary
->lpVtbl
->GetDC(wc
->lpDDSPrimary
, &(wc
->hDC
));
2121 static BOOL
DDCreateOffScreen(WMesaContext wc
)
2125 if(wc
->lpDD
== NULL
)
2127 GetClientRect( wc
->hwnd
, &(wc
->rectOffScreen
) );
2128 wc
->ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
2129 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
2130 wc
->ddsd
.dwHeight
= wc
->rectOffScreen
.bottom
- wc
->rectOffScreen
.top
;
2131 wc
->ddsd
.dwWidth
= wc
->rectOffScreen
.right
- wc
->rectOffScreen
.left
;
2133 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
, &(wc
->ddsd
),
2134 &(wc
->lpDDSOffScreen
), NULL
);
2135 if( ddrval
!= DD_OK
)
2140 while (wc
->lpDDSOffScreen
->lpVtbl
->Lock(wc
->lpDDSOffScreen
,NULL
,
2141 &(wc
->ddsd
), 0, NULL
) ==
2142 DDERR_WASSTILLDRAWING
)
2145 if(wc
->ddsd
.lpSurface
==NULL
)
2146 return initFail(wc
->hwnd
, wc
);
2148 wc
->ScreenMem
= wc
->pbPixels
= wc
->addrOffScreen
=
2149 (PBYTE
)(wc
->ddsd
.lpSurface
);
2150 wc
->ScanWidth
= wc
->pitch
= wc
->ddsd
.lPitch
;
2152 wc
->ScanWidth
= wc
->ddsd
.lPitch
*2;
2154 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2156 ClientToScreen( wc
->hwnd
, &pt
);
2157 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2158 wmSetPixelFormat(wc
, wc
->hDC
);
2163 struct tagWMesaContextList
2166 struct tagWMesaContextList
*next
;
2169 WMesaContextList
*head
= 0;
2171 void AddContext(WMesaContext wc
)
2173 WMesaContextList
*lst
= (WMesaContextList
*)malloc(sizeof(WMesaContextList
));
2180 WMesaContext
FindContext(HWND hWnd
)
2182 WMesaContextList
*tmp
= head
;
2185 if( tmp
->wc
->hwnd
== hWnd
)
2192 void RemoveContext(HWND hWnd
)
2194 WMesaContextList
*tmp
= head
;
2197 if( tmp
->wc
->hwnd
== hWnd
)
2199 WMesaContextList
*lst
= tmp
;
2207 if( tmp
->next
->wc
->hwnd
== hWnd
)
2209 WMesaContextList
*lst
= tmp
->next
;
2210 tmp
->next
= tmp
->next
->next
;
2218 static LRESULT CALLBACK
MyWndProc(HWND hwnd
,UINT message
,WPARAM wParam
, LPARAM lParam
)
2220 WMesaContext wc
= Current
->hwnd
== hwnd
? Current
: FindContext(hwnd
);
2223 LRESULT lret
= CallWindowProc((WNDPROC
)(wc
->oldWndProc
),hwnd
,message
,wParam
,lParam
);
2224 if( message
= WM_MOVE
)
2227 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2228 ClientToScreen( hwnd
, &pt
);
2229 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2237 * doInit - do work required for every instance of the application:
2238 * create the window, initialize data
2240 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
)
2243 // DWORD dwFrequency;
2245 // LPDIRECTDRAW lpDD; // DirectDraw object
2246 // LPDIRECTDRAW2 lpDD2;
2247 LPDIRECTDRAWCLIPPER pcClipper
= NULL
;
2249 wc
->fullScreen
= displayOptions
.fullScreen
;
2250 wc
->gMode
= displayOptions
.mode
;
2252 stereo_flag
= displayOptions
.stereo
;
2253 if(wc
->db_flag
!= GL_TRUE
)
2254 stereo_flag
= GL_FALSE
;
2256 * create the main DirectDraw object
2258 ddrval
= DirectDrawCreate( NULL
, &(wc
->lpDD
), NULL
);
2259 if( ddrval
!= DD_OK
)
2261 return initFail(hwnd
,wc
);
2264 // Get exclusive mode if requested
2267 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
,
2273 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
,
2276 if( ddrval
!= DD_OK
)
2278 return initFail(hwnd
, wc
);
2283 return initFail(hwnd
, wc
);
2289 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 640, 480,
2290 displayOptions
.bpp
);
2293 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 800, 600,
2294 displayOptions
.bpp
);
2297 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1024, 768,
2298 displayOptions
.bpp
);
2301 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1152, 864,
2302 displayOptions
.bpp
);
2305 ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1280, 1024,
2306 displayOptions
.bpp
);
2310 if( ddrval
!= DD_OK
)
2312 printf("Can't modify display mode, current mode used\n");
2315 case DDERR_INVALIDOBJECT
:
2317 case DDERR_INVALIDPARAMS
:
2319 case DDERR_UNSUPPORTEDMODE
:
2323 if(DDCreatePrimarySurface(wc
) == GL_FALSE
)
2324 return initFail(hwnd
, wc
);
2327 DDCreateOffScreen(wc
);
2329 if( FAILED( ddrval
= wc
->lpDD
->lpVtbl
->CreateClipper(wc
->lpDD
, 0, &pcClipper
, NULL
) ) )
2332 if( FAILED( ddrval
= pcClipper
->lpVtbl
->SetHWnd(pcClipper
, 0, wc
->hwnd
) ) )
2334 pcClipper
->lpVtbl
->Release(pcClipper
);
2338 if( FAILED( ddrval
= wc
->lpDDSPrimary
->lpVtbl
->SetClipper(wc
->lpDDSPrimary
, pcClipper
) ) )
2340 pcClipper
->lpVtbl
->Release(pcClipper
);
2344 // Done with clipper
2345 pcClipper
->lpVtbl
->Release(pcClipper
);
2347 // Hook the window so we can update the drawing rectangle when the window moves
2348 wc
->oldWndProc
= SetWindowLong(wc
->hwnd
,GWL_WNDPROC
,(LONG
)MyWndProc
);
2354 static void DDFree( WMesaContext wc
)
2356 RemoveContext(wc
->hwnd
);
2357 SetWindowLong(wc
->hwnd
,GWL_WNDPROC
,(LONG
)(wc
->oldWndProc
));
2359 if( wc
->lpDD
!= NULL
)
2361 DDFreePrimarySurface(wc
);
2362 DDDeleteOffScreen(wc
);
2363 wc
->lpDD
->lpVtbl
->Release(wc
->lpDD
);
2366 // Clean up the screen on exit
2367 RedrawWindow( NULL
, NULL
, NULL
, RDW_INVALIDATE
| RDW_ERASE
|
2373 void WMesaMove(void)
2375 WMesaContext wc
= Current
;
2377 if (Current
!= NULL
){
2378 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2380 ClientToScreen( wc
->hwnd
, &pt
);
2381 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2386 /************************************************
2387 * Mesa 4.0 - These triangle rasterizers are not
2388 * implemented in this version of the Windows
2389 * driver. They could be implemented for a
2390 * potential performance improvement.
2391 * See OSMesa for an example of the approach
2393 * This old code is left in this file in case
2394 * it is useful. However, it may end up looking
2395 * a lot more like the OSMesa code.
2396 ************************************************/
2399 #if defined(FAST_RASTERIZERS)
2403 * Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable
2406 #define PACK_8B8G8R( R, G, B ) ( ((B) << 16) | ((G) << 8) | (R) )
2408 /**********************************************************************/
2409 /*** Triangle rendering ***/
2410 /**********************************************************************/
2413 * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
2415 static void smooth_8A8B8G8R_z_triangle( GLcontext
*ctx
,
2416 GLuint v0
, GLuint v1
, GLuint v2
,
2419 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2421 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
2422 #define INTERP_RGB 1
2423 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2424 #define PIXEL_TYPE GLuint
2425 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2426 #define BYTES_PER_ROW (wmesa->ScanWidth)
2427 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2429 GLint i, len = RIGHT-LEFT; \
2430 for (i=0;i<len;i++) { \
2431 GLdepth z = FixedToDepth(ffz); \
2432 if (z < zRow[i]) { \
2433 pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2434 FixedToInt(ffb) ); \
2437 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2443 #include "tritemp.h"
2447 // #include "..\tritemp.h"
2449 #include "tritemp.h"
2456 * XImage, smooth, depth-buffered, PF_8R8G8B triangle.
2458 static void smooth_8R8G8B_z_triangle( GLcontext
*ctx
,
2459 GLuint v0
, GLuint v1
, GLuint v2
,
2462 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2464 #define INTERP_RGB 1
2465 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2466 #define PIXEL_TYPE GLuint
2467 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2468 #define BYTES_PER_ROW (wmesa->ScanWidth)
2469 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2471 GLint i, len = RIGHT-LEFT; \
2472 for (i=0;i<len;i++) { \
2473 GLdepth z = FixedToDepth(ffz); \
2474 if (z < zRow[i]) { \
2475 pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2476 FixedToInt(ffb) ); \
2479 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2484 #include "tritemp.h"
2488 // #include "..\tritemp.h"
2490 #include "tritemp.h"
2498 * XImage, smooth, depth-buffered, PF_5R6G5B triangle.
2500 static void smooth_5R6G5B_z_triangle( GLcontext
*ctx
,
2501 GLuint v0
, GLuint v1
, GLuint v2
,
2504 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2506 #define INTERP_RGB 1
2507 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2508 #define PIXEL_TYPE GLushort
2509 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2510 #define BYTES_PER_ROW (wmesa->ScanWidth)
2511 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2513 GLint i, len = RIGHT-LEFT; \
2514 for (i=0;i<len;i++) { \
2515 GLdepth z = FixedToDepth(ffz); \
2516 if (z < zRow[i]) { \
2517 pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2518 FixedToInt(ffb) ); \
2521 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2526 #include "tritemp.h"
2530 // #include "..\tritemp.h"
2532 #include "tritemp.h"
2538 * XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
2540 static void flat_8A8B8G8R_z_triangle( GLcontext
*ctx
, GLuint v0
,
2541 GLuint v1
, GLuint v2
, GLuint pv
)
2543 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2545 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2546 #define PIXEL_TYPE GLuint
2547 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2548 #define BYTES_PER_ROW (wmesa->ScanWidth)
2549 #define SETUP_CODE \
2550 unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \
2551 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2552 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2554 GLint i, len = RIGHT-LEFT; \
2555 for (i=0;i<len;i++) { \
2556 GLdepth z = FixedToDepth(ffz); \
2557 if (z < zRow[i]) { \
2565 #include "tritemp.h"
2569 // #include "..\tritemp.h"
2571 #include "tritemp.h"
2578 * XImage, flat, depth-buffered, PF_8R8G8B triangle.
2580 static void flat_8R8G8B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2581 GLuint v2
, GLuint pv
)
2583 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2585 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2586 #define PIXEL_TYPE GLuint
2587 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2588 #define BYTES_PER_ROW (wmesa->ScanWidth)
2589 #define SETUP_CODE \
2590 unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \
2591 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2592 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2594 GLint i, len = RIGHT-LEFT; \
2595 for (i=0;i<len;i++) { \
2596 GLdepth z = FixedToDepth(ffz); \
2597 if (z < zRow[i]) { \
2605 #include "tritemp.h"
2609 // #include "..\tritemp.h"
2611 #include "tritemp.h"
2618 * XImage, flat, depth-buffered, PF_5R6G5B triangle.
2620 static void flat_5R6G5B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2621 GLuint v2
, GLuint pv
)
2623 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2625 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2626 #define PIXEL_TYPE GLushort
2627 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2628 #define BYTES_PER_ROW (wmesa->ScanWidth)
2629 #define SETUP_CODE \
2630 unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \
2631 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2632 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2634 GLint i, len = RIGHT-LEFT; \
2635 for (i=0;i<len;i++) { \
2636 GLdepth z = FixedToDepth(ffz); \
2637 if (z < zRow[i]) { \
2645 #include "tritemp.h"
2649 // #include "..\tritemp.h"
2651 #include "tritemp.h"
2658 * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
2660 static void smooth_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2661 GLuint v2
, GLuint pv
)
2663 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2664 #define INTERP_RGB 1
2665 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2666 #define PIXEL_TYPE GLuint
2667 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2668 #define BYTES_PER_ROW (wmesa->ScanWidth)
2669 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2672 PIXEL_TYPE *pixel = pRow; \
2673 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2674 *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2675 FixedToInt(ffb) ); \
2676 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2680 #include "tritemp.h"
2684 // #include "..\tritemp.h"
2686 #include "tritemp.h"
2693 * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
2695 static void smooth_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2696 GLuint v2
, GLuint pv
)
2698 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2699 #define INTERP_RGB 1
2700 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2701 #define PIXEL_TYPE GLuint
2702 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2703 #define BYTES_PER_ROW (wmesa->ScanWidth)
2704 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2707 PIXEL_TYPE *pixel = pRow; \
2708 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2709 *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2710 FixedToInt(ffb) ); \
2711 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2715 #include "tritemp.h"
2719 // #include "..\tritemp.h"
2721 #include "tritemp.h"
2728 * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
2730 static void smooth_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2731 GLuint v2
, GLuint pv
)
2733 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2734 #define INTERP_RGB 1
2735 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2736 #define PIXEL_TYPE GLushort
2737 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2738 #define BYTES_PER_ROW (wmesa->ScanWidth)
2739 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2742 PIXEL_TYPE *pixel = pRow; \
2743 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2744 *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2745 FixedToInt(ffb) ); \
2746 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2750 #include "tritemp.h"
2754 // #include "..\tritemp.h"
2756 #include "tritemp.h"
2764 * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
2766 static void flat_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
,
2767 GLuint v1
, GLuint v2
, GLuint pv
)
2769 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2770 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2771 #define PIXEL_TYPE GLuint
2772 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2773 #define BYTES_PER_ROW (wmesa->ScanWidth)
2774 #define SETUP_CODE \
2775 unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \
2776 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2777 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2780 PIXEL_TYPE *pixel = pRow; \
2781 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2787 #include "tritemp.h"
2791 // #include "..\tritemp.h"
2793 #include "tritemp.h"
2800 * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
2802 static void flat_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2803 GLuint v2
, GLuint pv
)
2805 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2806 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2807 #define PIXEL_TYPE GLuint
2808 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2809 #define BYTES_PER_ROW (wmesa->ScanWidth)
2810 #define SETUP_CODE \
2811 unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \
2812 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2813 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2816 PIXEL_TYPE *pixel = pRow; \
2817 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2822 #include "tritemp.h"
2826 // #include "..\tritemp.h"
2828 #include "tritemp.h"
2835 * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
2837 static void flat_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2838 GLuint v2
, GLuint pv
)
2840 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2841 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2842 #define PIXEL_TYPE GLushort
2843 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2844 #define BYTES_PER_ROW (wmesa->ScanWidth)
2845 #define SETUP_CODE \
2846 unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \
2847 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2848 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2851 PIXEL_TYPE *pixel = pRow; \
2852 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2857 #include "tritemp.h"
2861 // #include "..\tritemp.h"
2863 #include "tritemp.h"
2870 * XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
2873 static void smooth_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2874 GLuint v2
, GLuint pv
)
2876 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2878 #define INTERP_INDEX 1
2879 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2880 #define PIXEL_TYPE GLubyte
2881 #define BYTES_PER_ROW (wmesa->ScanWidth)
2882 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2884 GLint i, len = RIGHT-LEFT; \
2885 for (i=0;i<len;i++) { \
2886 GLdepth z = FixedToDepth(ffz); \
2887 if (z < zRow[i]) { \
2888 pRow[i] = FixedToInt(ffi); \
2896 #include "tritemp.h"
2900 // #include "..\tritemp.h"
2902 #include "tritemp.h"
2909 * XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
2912 static void flat_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2913 GLuint v2
, GLuint pv
)
2915 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2917 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2918 #define PIXEL_TYPE GLubyte
2919 #define BYTES_PER_ROW (wmesa->ScanWidth)
2920 #define SETUP_CODE \
2921 GLuint index = VB->IndexPtr->data[pv]; \
2922 (*ctx->Driver.Index)( ctx, index );
2923 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2925 GLint i, len = RIGHT-LEFT; \
2926 for (i=0;i<len;i++) { \
2927 GLdepth z = FixedToDepth(ffz); \
2928 if (z < zRow[i]) { \
2936 #include "tritemp.h"
2940 // #include "..\tritemp.h"
2942 #include "tritemp.h"
2950 * XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2953 static void smooth_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2954 GLuint v2
, GLuint pv
)
2956 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2958 #define INTERP_INDEX 1
2959 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2960 #define PIXEL_TYPE GLubyte
2961 #define BYTES_PER_ROW (wmesa->ScanWidth)
2962 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2965 PIXEL_TYPE *pixel = pRow; \
2966 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2967 *pixel = FixedToInt(ffi); \
2972 #include "tritemp.h"
2976 // #include "..\tritemp.h"
2978 #include "tritemp.h"
2985 * XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2987 static void flat_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2988 GLuint v2
, GLuint pv
)
2990 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2992 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2993 #define PIXEL_TYPE GLubyte
2994 #define BYTES_PER_ROW (wmesa->ScanWidth)
2995 #define SETUP_CODE \
2996 GLuint index = VB->IndexPtr->data[pv]; \
2997 (*ctx->Driver.Index)( ctx, index );
2998 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3001 PIXEL_TYPE *pixel = pRow; \
3002 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
3007 #include "tritemp.h"
3011 // #include "..\tritemp.h"
3013 #include "tritemp.h"
3019 * XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
3021 static void smooth_DITHER8_z_triangle( GLcontext
*ctx
,
3022 GLuint v0
, GLuint v1
, GLuint v2
,
3025 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3026 DITHER_RGB_TO_8BIT_SETUP
3028 #define INTERP_RGB 1
3029 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3030 #define PIXEL_TYPE GLubyte
3031 #define BYTES_PER_ROW (wmesa->ScanWidth)
3032 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3034 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
3035 for (i=0;i<len;i++,xx++) { \
3036 GLdepth z = FixedToDepth(ffz); \
3037 if (z < zRow[i]) { \
3038 DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg), \
3039 FixedToInt(ffb), xx, yy); \
3040 pRow[i] = pixelDithered; \
3043 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
3048 #include "tritemp.h"
3052 // #include "..\tritemp.h"
3054 #include "tritemp.h"
3060 * XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
3062 static void flat_DITHER8_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
3063 GLuint v2
, GLuint pv
)
3065 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3066 DITHER_RGB_TO_8BIT_SETUP
3068 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3069 #define PIXEL_TYPE GLubyte
3070 #define BYTES_PER_ROW (wmesa->ScanWidth)
3072 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3074 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
3075 for (i=0;i<len;i++,xx++) { \
3076 GLdepth z = FixedToDepth(ffz); \
3077 if (z < zRow[i]) { \
3078 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \
3079 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \
3080 pRow[i] = pixelDithered; \
3087 #include "tritemp.h"
3091 // #include "..\tritemp.h"
3093 #include "tritemp.h"
3099 * XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
3101 static void smooth_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
3102 GLuint v2
, GLuint pv
)
3104 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3105 DITHER_RGB_TO_8BIT_SETUP
3106 #define INTERP_RGB 1
3107 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3108 #define PIXEL_TYPE GLubyte
3109 #define BYTES_PER_ROW (wmesa->ScanWidth)
3110 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3112 GLint xx, yy = FLIP(Y); \
3113 PIXEL_TYPE *pixel = pRow; \
3114 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
3115 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy);\
3116 *pixel = pixelDithered; \
3117 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
3121 #include "tritemp.h"
3125 // #include "..\tritemp.h"
3127 #include "tritemp.h"
3133 * XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
3136 static void flat_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
3137 GLuint v2
, GLuint pv
)
3139 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3140 DITHER_RGB_TO_8BIT_SETUP
3141 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3142 #define PIXEL_TYPE GLubyte
3143 #define BYTES_PER_ROW (wmesa->ScanWidth)
3145 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3147 GLint xx, yy = FLIP(Y); \
3148 PIXEL_TYPE *pixel = pRow; \
3149 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
3150 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \
3151 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \
3152 *pixel = pixelDithered; \
3156 #include "tritemp.h"
3160 // #include "..\tritemp.h"
3162 #include "tritemp.h"
3168 /************** END DEAD TRIANGLE CODE ***********************/
3170 static triangle_func
choose_triangle_function( GLcontext
*ctx
)
3173 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
3174 int depth
= wmesa
->cColorBits
;
3176 if (ctx
->Polygon
.SmoothFlag
) return NULL
;
3177 if (ctx
->Texture
._ReallyEnabled
) return NULL
;
3178 if (!wmesa
->db_flag
) return NULL
;
3179 /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {
3180 if ( ctx
->Light
.ShadeModel
==GL_SMOOTH
3181 && ctx
->_RasterMask
==DEPTH_BIT
3182 && ctx
->Depth
.Func
==GL_LESS
3183 && ctx
->Depth
.Mask
==GL_TRUE
3184 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
3185 switch (wmesa
->pixelformat
) {
3187 return smooth_8A8B8G8R_z_triangle
;
3189 return smooth_8R8G8B_z_triangle
;
3191 return smooth_5R6G5B_z_triangle
;
3193 return smooth_DITHER8_z_triangle
;
3195 return smooth_ci_z_triangle
;
3200 if ( ctx
->Light
.ShadeModel
==GL_FLAT
3201 && ctx
->_RasterMask
==DEPTH_BIT
3202 && ctx
->Depth
.Func
==GL_LESS
3203 && ctx
->Depth
.Mask
==GL_TRUE
3204 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
3205 switch (wmesa
->pixelformat
) {
3207 return flat_8A8B8G8R_z_triangle
;
3209 return flat_8R8G8B_z_triangle
;
3211 return flat_5R6G5B_z_triangle
;
3213 return flat_DITHER8_z_triangle
;
3215 return flat_ci_z_triangle
;
3220 if ( ctx
->_RasterMask
==0 /* no depth test */
3221 && ctx
->Light
.ShadeModel
==GL_SMOOTH
3222 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
3223 switch (wmesa
->pixelformat
) {
3225 return smooth_8A8B8G8R_triangle
;
3227 return smooth_8R8G8B_triangle
;
3229 return smooth_5R6G5B_triangle
;
3231 return smooth_DITHER8_triangle
;
3233 return smooth_ci_triangle
;
3239 if ( ctx
->_RasterMask
==0 /* no depth test */
3240 && ctx
->Light
.ShadeModel
==GL_FLAT
3241 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
3242 switch (wmesa
->pixelformat
) {
3244 return flat_8A8B8G8R_triangle
;
3246 return flat_8R8G8B_triangle
;
3248 return flat_5R6G5B_triangle
;
3250 return flat_DITHER8_triangle
;
3252 return flat_ci_triangle
;
3264 * Define a new viewport and reallocate auxillary buffers if the size of
3265 * the window (color buffer) has changed.
3267 void WMesaViewport( GLcontext
*ctx
,
3268 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
3270 assert(0); /* I don't think that this is being used. */
3273 ctx
->Viewport
.X
= x
;
3274 ctx
->Viewport
.Width
= width
;
3275 ctx
->Viewport
.Y
= y
;
3276 ctx
->Viewport
.Height
= height
;
3278 /* compute scale and bias values */
3279 /* Pre-Keith 3.1 changes
3280 ctx->Viewport.Map.m[Sx] = (GLfloat) width / 2.0F;
3281 ctx->Viewport.Map.m[Tx] = ctx->Viewport.Sx + x;
3282 ctx->Viewport.Map.m[Sy] = (GLfloat) height / 2.0F;
3283 ctx->Viewport.Map.m[Ty] = ctx->Viewport.Sy + y;
3285 ctx
->Viewport
.WindowMap
.m
[MAT_SX
] = (GLfloat
) width
/ 2.0F
;
3286 ctx
->Viewport
.WindowMap
.m
[MAT_TX
] = ctx
->Viewport
.WindowMap
.m
[MAT_SX
] + x
;
3287 ctx
->Viewport
.WindowMap
.m
[MAT_SY
] = (GLfloat
) height
/ 2.0F
;
3288 ctx
->Viewport
.WindowMap
.m
[MAT_TY
] = ctx
->Viewport
.WindowMap
.m
[MAT_SY
] + y
;