1 /* $Id: wmesa.c,v 1.14 2001/03/03 20:33:29 brianp Exp $ */
4 * Windows (Win32) device driver for Mesa 3.4
8 * Copyright (C) 1996- Li Wei
9 * Address : Institute of Artificial Intelligence
11 * : Xi'an Jiaotong University
12 * Email : liwei@aiar.xjtu.edu.cn
13 * Web page : http://sun.aiar.xjtu.edu.cn
15 * This file and its associations are partially borrowed from the
16 * Windows NT driver for Mesa 1.8 , written by Mark Leaming
21 #define WMESA_STEREO_C
27 #include "mesa_extend.h"
38 #pragma warning ( disable : 4100 4133 4761 )
41 // #include "profile.h"
51 #define CopyMemory memcpy
54 #if !defined(NO_STEREO)
60 #if !defined(NO_PARALLEL)
61 // #include "parallel.h"
64 struct DISPLAY_OPTIONS displayOptions
;
66 GLenum stereoCompile
= GL_FALSE
;
67 GLenum stereoShowing
= GL_FALSE
;
68 GLenum stereoBuffer
= GL_FALSE
;
69 #if !defined(NO_STEREO)
70 GLint displayList
= MAXIMUM_DISPLAY_LIST
;
72 GLint stereo_flag
= 0 ;
74 /* end of added code*/
76 static PWMC Current
= NULL
;
77 WMesaContext WC
= NULL
;
80 #define assert(ignore) ((void) 0)
82 void Mesa_Assert(void *Cond
,void *File
,unsigned Line
)
85 sprintf(Msg
,"%s %s %d",Cond
,File
,Line
);
86 MessageBox(NULL
,Msg
,"Assertion failed.",MB_OK
);
89 #define assert(e) if (!e) Mesa_Assert(#e,__FILE__,__LINE__);
92 //#define DD_GETDC (Current->hDC )
93 #define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
94 //#define DD_GETDC ((Current->db_flag) ? Current->hDCPrimary : Current->hDCBack )
97 //#define BEGINGDICALL if(Current->rgb_flag)wmFlushBits(Current);
99 //#define ENDGDICALL if(Current->rgb_flag)wmGetBits(Current);
102 //#define FLIP(Y) (Current->dither_flag? Y : Current->height-(Y)-1)
103 //#define FLIP(Y) (Current->height-(Y)-1)
106 * XXX Why only flip Y coord if single buffered???
108 #define FLIP(Y) (Current->db_flag? Y: Current->height-(Y)-1)
110 #define ENDPROFILE(PARA)
112 #define DITHER_RGB_TO_8BIT_SETUP \
113 GLubyte pixelDithered;
115 #define DITHER_RGB_TO_8BIT(red, green, blue, pixel, scanline) \
117 char unsigned redtemp, greentemp, bluetemp, paletteindex; \
118 redtemp = aDividedBy51[red] \
119 + (aModulo51[red] > aHalftone8x8[(pixel%8)*8 \
121 greentemp = aDividedBy51[(char unsigned)green] \
122 + (aModulo51[green] > aHalftone8x8[ \
123 (pixel%8)*8 + scanline%8]); \
124 bluetemp = aDividedBy51[(char unsigned)blue] \
125 + (aModulo51[blue] > aHalftone8x8[ \
126 (pixel%8)*8 +scanline%8]); \
127 paletteindex = redtemp + aTimes6[greentemp] + aTimes36[bluetemp]; \
128 pixelDithered = aWinGHalftoneTranslation[paletteindex]; \
133 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
);
134 static void DDFree( WMesaContext wc
);
135 static HRESULT
DDRestoreAll( WMesaContext wc
);
136 static void DDDeleteOffScreen(WMesaContext wc
);
137 static BOOL
DDCreateOffScreen(WMesaContext wc
);
140 static void FlushToFile(PWMC pwc
, PSTR szFile
);
142 BOOL
wmCreateBackingStore(PWMC pwc
, long lxSize
, long lySize
);
143 BOOL
wmDeleteBackingStore(PWMC pwc
);
144 void wmCreatePalette( PWMC pwdc
);
145 BOOL
wmSetDibColors(PWMC pwc
);
146 void wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
);
148 void wmCreateDIBSection(
150 PWMC pwc
, // handle of device context
151 CONST BITMAPINFO
*pbmi
, // address of structure containing bitmap size, format, and color data
152 UINT iUsage
// color data type indicator: RGB values or palette indices
156 void WMesaViewport( GLcontext
*ctx
,
157 GLint x
, GLint y
, GLsizei width
, GLsizei height
);
160 static triangle_func
choose_triangle_function( GLcontext
*ctx
);
163 static void wmSetPixelFormat( PWMC wc
, HDC hDC
)
166 wc
->cColorBits
= GetDeviceCaps(hDC
, BITSPIXEL
);
169 switch(wc
->cColorBits
){
171 if(wc
->dither_flag
!= GL_TRUE
)
172 wc
->pixelformat
= PF_INDEX8
;
174 wc
->pixelformat
= PF_DITHER8
;
177 wc
->pixelformat
= PF_5R6G5B
;
180 wc
->pixelformat
= PF_8R8G8B
;
183 wc
->pixelformat
= PF_BADFORMAT
;
188 // This function sets the color table of a DIB section
189 // to match that of the destination DC
191 BOOL
/*WINAPI*/ wmSetDibColors(PWMC pwc
)
193 RGBQUAD
*pColTab
, *pRGB
;
194 PALETTEENTRY
*pPal
, *pPE
;
199 /* Build a color table in the DIB that maps to the
200 selected palette in the DC.
202 nColors
= 1 << pwc
->cColorBits
;
203 pPal
= (PALETTEENTRY
*)malloc( nColors
* sizeof(PALETTEENTRY
));
204 memset( pPal
, 0, nColors
* sizeof(PALETTEENTRY
) );
205 GetPaletteEntries( pwc
->hGLPalette
, 0, nColors
, pPal
);
206 pColTab
= (RGBQUAD
*)malloc( nColors
* sizeof(RGBQUAD
));
207 for (i
= 0, pRGB
= pColTab
, pPE
= pPal
; i
< nColors
; i
++, pRGB
++, pPE
++) {
208 pRGB
->rgbRed
= pPE
->peRed
;
209 pRGB
->rgbGreen
= pPE
->peGreen
;
210 pRGB
->rgbBlue
= pPE
->peBlue
;
213 bRet
= SetDIBColorTable(pwc
->dib
.hDC
, 0, nColors
, pColTab
);
216 dwErr
= GetLastError();
226 // Free up the dib section that was created
228 BOOL
wmDeleteBackingStore(PWMC pwc
)
230 SelectObject(pwc
->dib
.hDC
, pwc
->hOldBitmap
);
231 DeleteDC(pwc
->dib
.hDC
);
232 DeleteObject(pwc
->hbmDIB
);
233 UnmapViewOfFile(pwc
->dib
.base
);
234 CloseHandle(pwc
->dib
.hFileMap
);
240 // This function creates the DIB section that is used for combined
243 BOOL
/*WINAPI*/ wmCreateBackingStore(PWMC pwc
, long lxSize
, long lySize
)
246 LPBITMAPINFO pbmi
= &(pwc
->bmi
);
249 pbmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
250 pbmi
->bmiHeader
.biWidth
= lxSize
;
251 pbmi
->bmiHeader
.biHeight
= -lySize
;
252 pbmi
->bmiHeader
.biPlanes
= 1;
254 pbmi
->bmiHeader
.biBitCount
= GetDeviceCaps(pwc
->hDC
, BITSPIXEL
);
256 pbmi
->bmiHeader
.biBitCount
= 8;
257 pbmi
->bmiHeader
.biCompression
= BI_RGB
;
258 pbmi
->bmiHeader
.biSizeImage
= 0;
259 pbmi
->bmiHeader
.biXPelsPerMeter
= 0;
260 pbmi
->bmiHeader
.biYPelsPerMeter
= 0;
261 pbmi
->bmiHeader
.biClrUsed
= 0;
262 pbmi
->bmiHeader
.biClrImportant
= 0;
264 iUsage
= (pbmi
->bmiHeader
.biBitCount
<= 8) ? DIB_PAL_COLORS
: DIB_RGB_COLORS
;
266 pwc
->cColorBits
= pbmi
->bmiHeader
.biBitCount
;
267 pwc
->ScanWidth
= pwc
->pitch
= lxSize
;
269 wmCreateDIBSection(hdc
, pwc
, pbmi
, iUsage
);
271 if ((iUsage
== DIB_PAL_COLORS
) && !(pwc
->hGLPalette
)) {
272 wmCreatePalette( pwc
);
273 wmSetDibColors( pwc
);
275 wmSetPixelFormat(pwc
, pwc
->hDC
);
282 // This function copies one scan line in a DIB section to another
284 BOOL WINAPI
wmSetDIBits(PWMC pwc
, UINT uiScanWidth
, UINT uiNumScans
, UINT nBypp
, UINT uiNewWidth
, LPBYTE pBits
)
287 LPBYTE pDest
= pwc
->pbPixels
;
288 DWORD dwNextScan
= uiScanWidth
;
289 DWORD dwNewScan
= uiNewWidth
;
290 DWORD dwScanWidth
= (uiScanWidth
* nBypp
);
293 // We need to round up to the nearest DWORD
294 // and multiply by the number of bytes per
297 dwNextScan
= (((dwNextScan
* nBypp
)+ 3) & ~3);
298 dwNewScan
= (((dwNewScan
* nBypp
)+ 3) & ~3);
300 for(uiScans
= 0; uiScans
< uiNumScans
; uiScans
++){
301 CopyMemory(pDest
, pBits
, dwScanWidth
);
311 BOOL
wmFlush(PWMC pwc
);
315 Modified from file osmesa.c
319 #define PIXELADDR(X,Y) ((GLubyte *)Current->pbPixels + (Current->height-Y-1)* Current->ScanWidth + (X)*nBypp)
320 #define PIXELADDR1( X, Y ) \
321 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X))
322 #define PIXELADDR2( X, Y ) \
323 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*2)
324 #define PIXELADDR4( X, Y ) \
325 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*4)
328 BYTE
DITHER_RGB_2_8BIT( int r
, int g
, int b
, int x
, int y
);
330 /* Finish all pending operations and synchronize. */
331 static void finish(GLcontext
* ctx
)
338 // We cache all gl draw routines until a flush is made
340 static void flush(GLcontext
* ctx
)
343 if((Current
->rgb_flag
/*&& !(Current->dib.fFlushed)*/&&!(Current
->db_flag
))
344 ||(!Current
->rgb_flag
))
355 * Set the color index used to clear the color buffer.
357 static void clear_index(GLcontext
* ctx
, GLuint index
)
360 Current
->clearpixel
= index
;
361 ENDPROFILE(clear_index
)
367 * Set the color used to clear the color buffer.
369 static void clear_color( GLcontext
* ctx
, const GLchan color
[4] )
372 Current
->clearpixel
= RGB(color
[0], color
[1], color
[2]);
373 ENDPROFILE(clear_color
)
379 * Clear the specified region of the color buffer using the clear color
380 * or index as specified by one of the two functions above.
382 //static void clear(GLcontext* ctx,
383 // GLboolean all,GLint x, GLint y, GLint width, GLint height )
384 // TODO: I modified this function to match the prototype in
385 // dd.h. (swansma@geocities.com)
387 static GLbitfield
clear(GLcontext
* ctx
, GLbitfield mask
,
388 GLboolean all
, GLint x
, GLint y
, GLint width
, GLint height
)
393 LPDWORD lpdw
= (LPDWORD
)Current
->pbPixels
;
394 LPWORD lpw
= (LPWORD
)Current
->pbPixels
;
395 LPBYTE lpb
= Current
->pbPixels
;
402 width
=Current
->width
;
403 height
=Current
->height
;
405 if(Current
->db_flag
==GL_TRUE
){
406 UINT nBypp
= Current
->cColorBits
/ 8;
411 /* Need rectification */
412 iSize
= Current
->width
/4;
413 bColor
= BGR8(GetRValue(Current
->clearpixel
),
414 GetGValue(Current
->clearpixel
),
415 GetBValue(Current
->clearpixel
));
416 wColor
= MAKEWORD(bColor
,bColor
);
417 dwColor
= MAKELONG(wColor
, wColor
);
420 iSize
= Current
->width
/ 2;
421 wColor
= BGR16(GetRValue(Current
->clearpixel
),
422 GetGValue(Current
->clearpixel
),
423 GetBValue(Current
->clearpixel
));
424 dwColor
= MAKELONG(wColor
, wColor
);
427 iSize
= Current
->width
;
428 dwColor
= BGR32(GetRValue(Current
->clearpixel
),
429 GetGValue(Current
->clearpixel
),
430 GetBValue(Current
->clearpixel
));
440 // This is the 24bit case
443 iSize
= Current
->width
*3/4;
444 dwColor
= BGR24(GetRValue(Current
->clearpixel
),
445 GetGValue(Current
->clearpixel
),
446 GetBValue(Current
->clearpixel
));
461 memcpy(lpb
, Current
->pbPixels
, iSize
*4);
462 lpb
+= Current
->ScanWidth
;
467 else { // For single buffer
469 HPEN Pen
=CreatePen(PS_SOLID
,1,Current
->clearpixel
);
470 HBRUSH Brush
=CreateSolidBrush(Current
->clearpixel
);
471 HPEN Old_Pen
=SelectObject(DC
,Pen
);
472 HBRUSH Old_Brush
=SelectObject(DC
,Brush
);
473 Rectangle(DC
,x
,y
,x
+width
,y
+height
);
474 SelectObject(DC
,Old_Pen
);
475 SelectObject(DC
,Old_Brush
);
485 return mask
; // TODO: I doubt this is correct. dd.h doesn't explain what this should
491 static void enable( GLcontext
* ctx
, GLenum pname
, GLboolean enable
)
496 if (pname
== GL_DITHER
) {
497 if(enable
== GL_FALSE
){
498 Current
->dither_flag
= GL_FALSE
;
499 if(Current
->cColorBits
== 8)
500 Current
->pixelformat
= PF_INDEX8
;
503 if (Current
->rgb_flag
&& Current
->cColorBits
== 8){
504 Current
->pixelformat
= PF_DITHER8
;
505 Current
->dither_flag
= GL_TRUE
;
508 Current
->dither_flag
= GL_FALSE
;
515 static GLboolean
set_draw_buffer( GLcontext
* ctx
, GLenum mode
)
518 /* TODO: this could be better */
519 if (mode
==GL_FRONT_LEFT
|| mode
==GL_BACK_LEFT
) {
525 ENDPROFILE(set_draw_buffer
)
529 static void set_read_buffer(GLcontext
*ctx
, GLframebuffer
*colorBuffer
,
538 /* Return characteristics of the output buffer. */
539 static void buffer_size( GLcontext
* ctx
, GLuint
*width
, GLuint
*height
)
545 GetClientRect(Current
->Window
,&CR
);
550 New_Size
=((*width
)!=Current
->width
) || ((*height
)!=Current
->height
);
553 Current
->width
=*width
;
554 Current
->height
=*height
;
555 Current
->ScanWidth
=Current
->width
;
556 if ((Current
->ScanWidth
%sizeof(long))!=0)
557 Current
->ScanWidth
+=(sizeof(long)-(Current
->ScanWidth
%sizeof(long)));
559 if (Current
->db_flag
){
561 DDDeleteOffScreen(Current
);
562 DDCreateOffScreen(Current
);
564 if (Current
->rgb_flag
==GL_TRUE
&& Current
->dither_flag
!=GL_TRUE
){
565 wmDeleteBackingStore(Current
);
566 wmCreateBackingStore(Current
, Current
->width
, Current
->height
);
571 // Resize OsmesaBuffer if in Parallel mode
572 #if !defined(NO_PARALLEL)
574 PRSizeRenderBuffer(Current
->width
, Current
->height
,Current
->ScanWidth
,
575 Current
->rgb_flag
== GL_TRUE
? Current
->pbPixels
: Current
->ScreenMem
);
578 ENDPROFILE(buffer_size
)
583 /**********************************************************************/
584 /***** Accelerated point, line, polygon rendering *****/
585 /**********************************************************************/
588 static void fast_rgb_points( GLcontext
* ctx
, GLuint first
, GLuint last
)
596 if (0 /*Current->gl_ctx->VB->MonoColor*/) {
597 /* all drawn with current color */
598 for (i
=first
;i
<=last
;i
++) {
599 if (!Current
->gl_ctx
->VB
->ClipMask
[i
]) {
601 x
= (GLint
) Current
->gl_ctx
->VB
->Win
.data
[i
][0];
602 y
= FLIP( (GLint
) Current
->gl_ctx
->VB
->Win
.data
[i
][1] );
603 wmSetPixel(pwc
, y
,x
,GetRValue(Current
->pixel
),
604 GetGValue(Current
->pixel
), GetBValue(Current
->pixel
));
609 /* draw points of different colors */
610 for (i
=first
;i
<=last
;i
++) {
611 if (!Current
->gl_ctx
->VB
->ClipMask
[i
]) {
613 unsigned long pixel
=RGB(Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][0]*255.0,
614 Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][1]*255.0,
615 Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][2]*255.0);
616 x
= (GLint
) Current
->gl_ctx
->VB
->Win
.data
[i
][0];
617 y
= FLIP( (GLint
) Current
->gl_ctx
->VB
->Win
.data
[i
][1] );
618 wmSetPixel(pwc
, y
,x
,Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][0]*255.0,
619 Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][1]*255.0,
620 Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][2]*255.0);
625 ENDPROFILE(fast_rgb_points
)
630 /* Return pointer to accerated points function */
631 extern points_func
choose_points_function( GLcontext
* ctx
)
634 if (ctx
->Point
.Size
==1.0 && !ctx
->Point
.SmoothFlag
&& ctx
->_RasterMask
==0
635 && !ctx
->Texture
._ReallyEnabled
&& ctx
->Visual
->RGBAflag
) {
636 ENDPROFILE(choose_points_function
)
637 return fast_rgb_points
;
640 ENDPROFILE(choose_points_function
)
647 /* Draw a line using the color specified by Current->gl_ctx->VB->ColorPtr->data[pv] */
648 static void fast_flat_rgb_line( GLcontext
* ctx
, GLuint v0
, GLuint v1
, GLuint pv
)
657 if (0 /*Current->gl_ctx->VB->MonoColor*/) {
658 pixel
= Current
->pixel
; /* use current color */
661 pixel
= RGB(Current
->gl_ctx
->VB
->ColorPtr
->data
[pv
][0]*255.0, Current
->gl_ctx
->VB
->ColorPtr
->data
[pv
][1]*255.0, Current
->gl_ctx
->VB
->ColorPtr
->data
[pv
][2]*255.0);
664 x0
= (int) Current
->gl_ctx
->VB
->Win
.data
[v0
][0];
665 y0
= FLIP( (int) Current
->gl_ctx
->VB
->Win
.data
[v0
][1] );
666 x1
= (int) Current
->gl_ctx
->VB
->Win
.data
[v1
][0];
667 y1
= FLIP( (int) Current
->gl_ctx
->VB
->Win
.data
[v1
][1] );
672 Pen
=CreatePen(PS_SOLID
,1,pixel
);
673 Old_Pen
=SelectObject(DC
,Pen
);
674 MoveToEx(DC
,x0
,y0
,NULL
);
676 SelectObject(DC
,Old_Pen
);
682 ENDPROFILE(fast_flat_rgb_line
)
687 /* Return pointer to accerated line function */
688 static line_func
choose_line_function( GLcontext
* ctx
)
691 if (ctx
->Line
.Width
==1.0 && !ctx
->Line
.SmoothFlag
&& !ctx
->Line
.StippleFlag
692 && ctx
->Light
.ShadeModel
==GL_FLAT
&& ctx
->_RasterMask
==0
693 && !ctx
->Texture
._ReallyEnabled
&& Current
->rgb_flag
) {
694 ENDPROFILE(choose_line_function
)
695 return fast_flat_rgb_line
;
698 ENDPROFILE(choose_line_function
)
704 /**********************************************************************/
705 /***** Span-based pixel drawing *****/
706 /**********************************************************************/
709 /* Write a horizontal span of 32-bit color-index pixels with a boolean mask. */
710 static void write_ci32_span( const GLcontext
* ctx
,
711 GLuint n
, GLint x
, GLint y
,
712 const GLuint index
[],
713 const GLubyte mask
[] )
717 PBYTE Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
718 assert(Current
->rgb_flag
==GL_FALSE
);
722 ENDPROFILE(write_ci32_span
)
726 /* Write a horizontal span of 8-bit color-index pixels with a boolean mask. */
727 static void write_ci8_span( const GLcontext
* ctx
,
728 GLuint n
, GLint x
, GLint y
,
729 const GLubyte index
[],
730 const GLubyte mask
[] )
734 PBYTE Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
735 assert(Current
->rgb_flag
==GL_FALSE
);
739 ENDPROFILE(write_ci8_span
)
745 * Write a horizontal span of pixels with a boolean mask. The current
746 * color index is used for all pixels.
748 static void write_mono_ci_span(const GLcontext
* ctx
,
749 GLuint n
,GLint x
,GLint y
,
750 GLuint colorIndex
, const GLubyte mask
[])
754 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
755 assert(Current
->rgb_flag
==GL_FALSE
);
759 ENDPROFILE(write_mono_ci_span
)
763 * To improve the performance of this routine, frob the data into an actual
764 * scanline and call bitblt on the complete scan line instead of SetPixel.
767 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
768 static void write_rgba_span( const GLcontext
* ctx
, GLuint n
, GLint x
, GLint y
,
769 const GLubyte rgba
[][4], const GLubyte mask
[] )
774 if (pwc
->rgb_flag
==GL_TRUE
)
782 wmSetPixel(pwc
, y
, x
+ i
, rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
786 wmSetPixel(pwc
, y
, x
+ i
, rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
] );
793 BYTE
*Mem
=Current
->ScreenMem
+y
*Current
->ScanWidth
+x
;
798 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]));
802 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]));
805 ENDPROFILE(write_rgba_span
)
809 /* Write a horizontal span of RGB color pixels with a boolean mask. */
810 static void write_rgb_span( const GLcontext
* ctx
,
811 GLuint n
, GLint x
, GLint y
,
812 const GLubyte rgb
[][3], const GLubyte mask
[] )
817 if (pwc
->rgb_flag
==GL_TRUE
)
825 wmSetPixel(pwc
, y
, x
+ i
, rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]);
829 wmSetPixel(pwc
, y
, x
+ i
, rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
] );
836 BYTE
*Mem
=Current
->ScreenMem
+y
*Current
->ScanWidth
+x
;
841 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]));
845 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]));
848 ENDPROFILE(write_rgb_span
)
853 * Write a horizontal span of pixels with a boolean mask. The current color
854 * is used for all pixels.
856 static void write_mono_rgba_span( const GLcontext
* ctx
,
857 GLuint n
, GLint x
, GLint y
,
858 const GLchan color
[4], const GLubyte mask
[])
860 ULONG pixel
= RGB( color
[RCOMP
], color
[GCOMP
], color
[BCOMP
] );
865 assert(Current
->rgb_flag
==GL_TRUE
);
867 if(Current
->rgb_flag
==GL_TRUE
){
871 wmSetPixel(pwc
,y
,x
+i
,color
[RCOMP
], color
[GCOMP
], color
[BCOMP
]);
876 SetPixel(DC
, y
, x
+i
, pixel
);
879 ENDPROFILE(write_mono_rgba_span
)
884 /**********************************************************************/
885 /***** Array-based pixel drawing *****/
886 /**********************************************************************/
889 /* Write an array of 32-bit index pixels with a boolean mask. */
890 static void write_ci32_pixels( const GLcontext
* ctx
,
891 GLuint n
, const GLint x
[], const GLint y
[],
892 const GLuint index
[], const GLubyte mask
[] )
896 assert(Current
->rgb_flag
==GL_FALSE
);
897 for (i
=0; i
<n
; i
++) {
899 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
];
903 ENDPROFILE(write_ci32_pixels
)
909 * Write an array of pixels with a boolean mask. The current color
910 * index is used for all pixels.
912 static void write_mono_ci_pixels( const GLcontext
* ctx
,
914 const GLint x
[], const GLint y
[],
915 GLuint colorIndex
, const GLubyte mask
[] )
919 assert(Current
->rgb_flag
==GL_FALSE
);
920 for (i
=0; i
<n
; i
++) {
922 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
];
926 ENDPROFILE(write_mono_ci_pixels
)
931 /* Write an array of RGBA pixels with a boolean mask. */
932 static void write_rgba_pixels( const GLcontext
* ctx
,
933 GLuint n
, const GLint x
[], const GLint y
[],
934 const GLubyte rgba
[][4], const GLubyte mask
[] )
940 assert(Current
->rgb_flag
==GL_TRUE
);
943 wmSetPixel(pwc
, FLIP(y
[i
]), x
[i
],
944 rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
946 ENDPROFILE(write_rgba_pixels
)
952 * Write an array of pixels with a boolean mask. The current color
953 * is used for all pixels.
955 static void write_mono_rgba_pixels( const GLcontext
* ctx
,
957 const GLint x
[], const GLint y
[],
958 const GLchan color
[4],
959 const GLubyte mask
[] )
965 assert(Current
->rgb_flag
==GL_TRUE
);
968 wmSetPixel(pwc
, FLIP(y
[i
]),x
[i
],color
[RCOMP
],
969 color
[GCOMP
], color
[BCOMP
]);
971 ENDPROFILE(write_mono_rgba_pixels
)
976 /**********************************************************************/
977 /***** Read spans/arrays of pixels *****/
978 /**********************************************************************/
981 /* Read a horizontal span of color-index pixels. */
982 static void read_ci32_span( const GLcontext
* ctx
, GLuint n
, GLint x
, GLint y
,
987 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
988 assert(Current
->rgb_flag
==GL_FALSE
);
991 ENDPROFILE(read_ci32_span
)
997 /* Read an array of color index pixels. */
998 static void read_ci32_pixels( const GLcontext
* ctx
,
999 GLuint n
, const GLint x
[], const GLint y
[],
1000 GLuint indx
[], const GLubyte mask
[] )
1004 assert(Current
->rgb_flag
==GL_FALSE
);
1005 for (i
=0; i
<n
; i
++) {
1007 indx
[i
]=*(Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
]);
1010 ENDPROFILE(read_ci32_pixels
)
1015 /* Read a horizontal span of color pixels. */
1016 static void read_rgba_span( const GLcontext
* ctx
,
1017 GLuint n
, GLint x
, GLint y
,
1024 assert(Current
->rgb_flag
==GL_TRUE
);
1026 y
= Current
->height
- y
- 1;
1027 for (i
=0; i
<n
; i
++) {
1028 Color
=GetPixel(DC
,x
+i
,y
);
1029 rgba
[i
][RCOMP
] = GetRValue(Color
);
1030 rgba
[i
][GCOMP
] = GetGValue(Color
);
1031 rgba
[i
][BCOMP
] = GetBValue(Color
);
1032 rgba
[i
][ACOMP
] = 255;
1035 // Brian P. Has mentioned to comment this out.
1036 // memset(alpha,0,n*sizeof(GLubyte));
1037 ENDPROFILE(read_rgba_span
)
1041 /* Read an array of color pixels. */
1042 static void read_rgba_pixels( const GLcontext
* ctx
,
1043 GLuint n
, const GLint x
[], const GLint y
[],
1044 GLubyte rgba
[][4], const GLubyte mask
[] )
1050 assert(Current
->rgb_flag
==GL_TRUE
);
1051 for (i
=0; i
<n
; i
++) {
1053 Color
=GetPixel(DC
,x
[i
],FLIP(y
[i
]));
1054 rgba
[i
][RCOMP
] = GetRValue(Color
);
1055 rgba
[i
][GCOMP
] = GetGValue(Color
);
1056 rgba
[i
][BCOMP
] = GetBValue(Color
);
1057 rgba
[i
][ACOMP
] = 255;
1061 // Brian P. has mentioned to comment this out.
1062 // memset(alpha,0,n*sizeof(GLint));
1063 ENDPROFILE(read_rgba_pixels
)
1068 /**********************************************************************/
1069 /**********************************************************************/
1072 static const GLubyte
*get_string(GLcontext
*ctx
, GLenum name
)
1074 if (name
== GL_RENDERER
) {
1075 return (GLubyte
*) "Mesa Windows";
1084 void setup_DD_pointers( GLcontext
* ctx
)
1086 ctx
->Driver
.GetString
= get_string
;
1087 ctx
->Driver
.UpdateState
= setup_DD_pointers
;
1088 ctx
->Driver
.GetBufferSize
= buffer_size
;
1089 ctx
->Driver
.Finish
= finish
;
1090 ctx
->Driver
.Flush
= flush
;
1092 ctx
->Driver
.ClearIndex
= clear_index
;
1093 ctx
->Driver
.ClearColor
= clear_color
;
1094 ctx
->Driver
.Clear
= clear
;
1096 ctx
->Driver
.Enable
= enable
;
1098 ctx
->Driver
.SetDrawBuffer
= set_draw_buffer
;
1099 ctx
->Driver
.SetReadBuffer
= set_read_buffer
;
1100 ctx
->Driver
.GetBufferSize
= buffer_size
;
1102 ctx
->Driver
.PointsFunc
= choose_points_function(ctx
);
1103 ctx
->Driver
.LineFunc
= choose_line_function(ctx
);
1104 ctx
->Driver
.TriangleFunc
= choose_triangle_function( ctx
);
1106 /* Pixel/span writing functions: */
1107 ctx
->Driver
.WriteRGBASpan
= write_rgba_span
;
1108 ctx
->Driver
.WriteRGBSpan
= write_rgb_span
;
1109 ctx
->Driver
.WriteMonoRGBASpan
= write_mono_rgba_span
;
1110 ctx
->Driver
.WriteRGBAPixels
= write_rgba_pixels
;
1111 ctx
->Driver
.WriteMonoRGBAPixels
= write_mono_rgba_pixels
;
1112 ctx
->Driver
.WriteCI32Span
= write_ci32_span
;
1113 ctx
->Driver
.WriteCI8Span
= write_ci8_span
;
1114 ctx
->Driver
.WriteMonoCISpan
= write_mono_ci_span
;
1115 ctx
->Driver
.WriteCI32Pixels
= write_ci32_pixels
;
1116 ctx
->Driver
.WriteMonoCIPixels
= write_mono_ci_pixels
;
1118 ctx
->Driver
.ReadCI32Span
= read_ci32_span
;
1119 ctx
->Driver
.ReadRGBASpan
= read_rgba_span
;
1120 ctx
->Driver
.ReadCI32Pixels
= read_ci32_pixels
;
1121 ctx
->Driver
.ReadRGBAPixels
= read_rgba_pixels
;
1125 /**********************************************************************/
1126 /***** WMesa API Functions *****/
1127 /**********************************************************************/
1131 #define PAL_SIZE 256
1132 static void GetPalette(HPALETTE Pal
,RGBQUAD
*aRGB
)
1140 WORD NumberOfEntries
;
1141 PALETTEENTRY aEntries
[PAL_SIZE
];
1149 GetPaletteEntries(Pal
,0,PAL_SIZE
,Palette
.aEntries
);
1151 GetSystemPaletteEntries(hdc
,0,PAL_SIZE
,Palette
.aEntries
);
1152 if (GetSystemPaletteUse(hdc
) == SYSPAL_NOSTATIC
)
1154 for(i
= 0; i
<PAL_SIZE
; i
++)
1155 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1156 Palette
.aEntries
[255].peRed
= 255;
1157 Palette
.aEntries
[255].peGreen
= 255;
1158 Palette
.aEntries
[255].peBlue
= 255;
1159 Palette
.aEntries
[255].peFlags
= 0;
1160 Palette
.aEntries
[0].peRed
= 0;
1161 Palette
.aEntries
[0].peGreen
= 0;
1162 Palette
.aEntries
[0].peBlue
= 0;
1163 Palette
.aEntries
[0].peFlags
= 0;
1169 nStaticColors
= GetDeviceCaps(hdc
, NUMCOLORS
)/2;
1170 for (i
=0; i
<nStaticColors
; i
++)
1171 Palette
.aEntries
[i
].peFlags
= 0;
1172 nUsableColors
= PAL_SIZE
-nStaticColors
;
1173 for (; i
<nUsableColors
; i
++)
1174 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1175 for (; i
<PAL_SIZE
-nStaticColors
; i
++)
1176 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1177 for (i
=PAL_SIZE
-nStaticColors
; i
<PAL_SIZE
; i
++)
1178 Palette
.aEntries
[i
].peFlags
= 0;
1180 ReleaseDC(NULL
,hdc
);
1181 for (i
=0; i
<PAL_SIZE
; i
++)
1183 aRGB
[i
].rgbRed
=Palette
.aEntries
[i
].peRed
;
1184 aRGB
[i
].rgbGreen
=Palette
.aEntries
[i
].peGreen
;
1185 aRGB
[i
].rgbBlue
=Palette
.aEntries
[i
].peBlue
;
1186 aRGB
[i
].rgbReserved
=Palette
.aEntries
[i
].peFlags
;
1188 ENDPROFILE(GetPalette
)
1192 WMesaContext
WMesaCreateContext( HWND hWnd
, HPALETTE
* Pal
,
1198 GLboolean true_color_flag
;
1199 c
= (struct wmesa_context
* ) calloc(1,sizeof(struct wmesa_context
));
1204 c
->hDC
= GetDC(hWnd
);
1205 true_color_flag
= GetDeviceCaps(c
->hDC
, BITSPIXEL
) > 8;
1207 if(true_color_flag
) c
->rgb_flag
= rgb_flag
= GL_TRUE
;
1212 if ((true_color_flag
==GL_FALSE
) && (rgb_flag
== GL_TRUE
)){
1213 c
->dither_flag
= GL_TRUE
;
1214 c
->hPalHalfTone
= WinGCreateHalftonePalette();
1217 c
->dither_flag
= GL_FALSE
;
1219 c
->dither_flag
= GL_FALSE
;
1223 if (rgb_flag
==GL_FALSE
)
1225 c
->rgb_flag
= GL_FALSE
;
1227 c
->db_flag
= db_flag
=GL_TRUE
; // WinG requires double buffering
1228 printf("Single buffer is not supported in color index mode, setting to double buffer.\n");
1232 c
->rgb_flag
= GL_TRUE
;
1235 GetClientRect(c
->Window
,&CR
);
1237 c
->height
=CR
.bottom
;
1241 /* Double buffered */
1243 // if (c->rgb_flag==GL_TRUE && c->dither_flag != GL_TRUE )
1245 wmCreateBackingStore(c
, c
->width
, c
->height
);
1252 /* Single Buffered */
1257 if (DDInit(c
,hWnd
) == GL_FALSE
) {
1264 c
->gl_visual
= _mesa_create_visual(rgb_flag
,
1265 db_flag
, /* db_flag */
1266 GL_FALSE
, /* stereo */
1267 8,8,8,8, /* r, g, b, a bits */
1269 16, /* depth_bits */
1270 8, /* stencil_bits */
1271 16,16,16,16,/* accum_bits */
1274 if (!c
->gl_visual
) {
1278 /* allocate a new Mesa context */
1279 c
->gl_ctx
= _mesa_create_context( c
->gl_visual
, NULL
, c
, GL_TRUE
);
1282 _mesa_destroy_visual( c
->gl_visual
);
1287 _mesa_enable_sw_extensions(c
->gl_ctx
);
1289 c
->gl_buffer
= _mesa_create_framebuffer( c
->gl_visual
,
1290 c
->gl_visual
->DepthBits
> 0,
1291 c
->gl_visual
->StencilBits
> 0,
1292 c
->gl_visual
->AccumRedBits
> 0,
1293 c
->gl_visual
->AlphaBits
> 0 );
1294 if (!c
->gl_buffer
) {
1295 _mesa_destroy_visual( c
->gl_visual
);
1296 _mesa_destroy_context( c
->gl_ctx
);
1301 c
->gl_ctx
->Driver
.UpdateState
= setup_DD_pointers
;
1303 // setup_DD_pointers(c->gl_ctx);
1308 void WMesaDestroyContext( void )
1310 WMesaContext c
= Current
;
1311 ReleaseDC(c
->Window
,c
->hDC
);
1313 if(c
->hPalHalfTone
!= NULL
)
1314 DeleteObject(c
->hPalHalfTone
);
1315 _mesa_destroy_visual( c
->gl_visual
);
1316 _mesa_destroy_framebuffer( c
->gl_buffer
);
1317 _mesa_destroy_context( c
->gl_ctx
);
1323 wmDeleteBackingStore(c
);
1326 //Following code is added to enable parallel render
1327 // Parallel render only work in double buffer mode
1328 #if !defined(NO_PARALLEL)
1330 PRDestroyRenderBuffer();
1337 void /*APIENTRY*/ WMesaMakeCurrent( WMesaContext c
)
1345 // A little optimization
1346 // If it already is current,
1347 // don't set it again
1352 //gl_set_context( c->gl_ctx );
1353 _mesa_make_current(c
->gl_ctx
, c
->gl_buffer
);
1354 setup_DD_pointers(c
->gl_ctx
);
1356 if (Current
->gl_ctx
->Viewport
.Width
==0) {
1357 /* initialize viewport to window size */
1358 _mesa_set_viewport( Current
->gl_ctx
,
1359 0, 0, Current
->width
, Current
->height
);
1361 if ((c
->cColorBits
<= 8 ) && (c
->rgb_flag
== GL_TRUE
)){
1362 WMesaPaletteChange(c
->hPalHalfTone
);
1368 void /*APIENTRY*/ WMesaSwapBuffers( void )
1370 HDC DC
= Current
->hDC
;
1371 if (Current
->db_flag
)
1377 void /*APIENTRY*/ WMesaPaletteChange(HPALETTE Pal
)
1380 LPPALETTEENTRY pPal
;
1381 if (Current
&& (Current
->rgb_flag
==GL_FALSE
|| Current
->dither_flag
== GL_TRUE
))
1383 pPal
= (PALETTEENTRY
*)malloc( 256 * sizeof(PALETTEENTRY
));
1385 // GetPaletteEntries( Pal, 0, 256, pPal );
1386 GetPalette( Pal
, pPal
);
1388 Current
->lpDD
->lpVtbl
->CreatePalette(Current
->lpDD
,DDPCAPS_8BIT
,
1389 pPal
, &(Current
->lpDDPal
), NULL
);
1390 if (Current
->lpDDPal
)
1391 Current
->lpDDSPrimary
->lpVtbl
->SetPalette(Current
->lpDDSPrimary
,Current
->lpDDPal
);
1393 vRet
= SetDIBColorTable(Current
->dib
.hDC
,0,256,pPal
);
1403 static unsigned char threeto8
[8] = {
1404 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
1407 static unsigned char twoto8
[4] = {
1411 static unsigned char oneto8
[2] = {
1415 static unsigned char componentFromIndex(UCHAR i
, UINT nbits
, UINT shift
)
1432 return threeto8
[val
];
1439 void /*WINAPI*/ wmCreatePalette( PWMC pwdc
)
1441 /* Create a compressed and re-expanded 3:3:2 palette */
1444 BYTE rb
, rs
, gb
, gs
, bb
, bs
;
1446 pwdc
->nColors
= 0x100;
1448 pPal
= (PLOGPALETTE
)malloc(sizeof(LOGPALETTE
) + pwdc
->nColors
* sizeof(PALETTEENTRY
));
1449 memset( pPal
, 0, sizeof(LOGPALETTE
) + pwdc
->nColors
* sizeof(PALETTEENTRY
) );
1451 pPal
->palVersion
= 0x300;
1460 if (pwdc
->db_flag
) {
1462 /* Need to make two palettes: one for the screen DC and one for the DIB. */
1463 pPal
->palNumEntries
= pwdc
->nColors
;
1464 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1465 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1466 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1467 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1468 pPal
->palPalEntry
[i
].peFlags
= 0;
1470 pwdc
->hGLPalette
= CreatePalette( pPal
);
1471 pwdc
->hPalette
= CreatePalette( pPal
);
1475 pPal
->palNumEntries
= pwdc
->nColors
;
1476 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1477 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1478 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1479 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1480 pPal
->palPalEntry
[i
].peFlags
= 0;
1482 pwdc
->hGLPalette
= CreatePalette( pPal
);
1489 void /*WINAPI*/ wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1491 if (Current
->db_flag
) {
1492 LPBYTE lpb
= pwc
->pbPixels
;
1495 UINT nBypp
= pwc
->cColorBits
>> 3;
1496 UINT nOffset
= iPixel
% nBypp
;
1498 // Move the pixel buffer pointer to the scanline that we
1501 // pwc->dib.fFlushed = FALSE;
1503 lpb
+= pwc
->ScanWidth
* iScanLine
;
1504 // Now move to the desired pixel
1505 lpb
+= iPixel
* nBypp
;
1506 lpb
= PIXELADDR(iPixel
, iScanLine
);
1507 lpdw
= (LPDWORD
)lpb
;
1511 if(pwc
->dither_flag
)
1512 *lpb
= DITHER_RGB_2_8BIT(r
,g
,b
,iScanLine
,iPixel
);
1517 *lpw
= BGR16(r
,g
,b
);
1518 else if (nBypp
== 3){
1519 *lpdw
= BGR24(r
,g
,b
);
1521 else if (nBypp
== 4)
1522 *lpdw
= BGR32(r
,g
,b
);
1525 SetPixel(Current
->hDC
, iPixel
, iScanLine
, RGB(r
,g
,b
));
1530 void /*WINAPI*/ wmCreateDIBSection(
1532 PWMC pwc
, // handle of device context
1533 CONST BITMAPINFO
*pbmi
, // address of structure containing bitmap size, format, and color data
1534 UINT iUsage
// color data type indicator: RGB values or palette indices
1539 UINT nBypp
= pwc
->cColorBits
/ 8;
1542 dwScanWidth
= (((pwc
->ScanWidth
* nBypp
)+ 3) & ~3);
1544 pwc
->ScanWidth
=pwc
->pitch
= dwScanWidth
;
1547 pwc
->ScanWidth
= 2* pwc
->pitch
;
1549 dwSize
= sizeof(BITMAPINFO
) + (dwScanWidth
* pwc
->height
);
1551 pwc
->dib
.hFileMap
= CreateFileMapping((HANDLE
)PAGE_FILE
,
1553 PAGE_READWRITE
| SEC_COMMIT
,
1558 if (!pwc
->dib
.hFileMap
)
1561 pwc
->dib
.base
= MapViewOfFile(pwc
->dib
.hFileMap
,
1562 FILE_MAP_ALL_ACCESS
,
1568 CloseHandle(pwc
->dib
.hFileMap
);
1572 // pwc->pbPixels = pwc->addrOffScreen = ((LPBYTE)pwc->dib.base) + sizeof(BITMAPINFO);
1574 // pwc->dib.hDC = CreateCompatibleDC(hDC);
1576 CopyMemory(pwc
->dib
.base
, pbmi
, sizeof(BITMAPINFO
));
1578 hic
= CreateIC("display", NULL
, NULL
, NULL
);
1579 pwc
->dib
.hDC
= CreateCompatibleDC(hic
);
1582 /* pwc->hbmDIB = CreateDIBitmap(hic,
1583 &(pwc->bmi.bmiHeader),
1589 pwc
->hbmDIB
= CreateDIBSection(hic
,
1591 (iUsage
? DIB_PAL_COLORS
: DIB_RGB_COLORS
),
1596 pwc->hbmDIB = CreateDIBSection(hic,
1603 pwc
->ScreenMem
= pwc
->addrOffScreen
= pwc
->pbPixels
;
1604 pwc
->hOldBitmap
= SelectObject(pwc
->dib
.hDC
, pwc
->hbmDIB
);
1613 // Blit memory DC to screen DC
1615 BOOL
/*WINAPI*/ wmFlush(PWMC pwc
)
1623 // Now search through the torus frames and mark used colors
1626 if (pwc
->lpDDSOffScreen
== NULL
)
1627 if(DDCreateOffScreen(pwc
) == GL_FALSE
)
1630 pwc
->lpDDSOffScreen
->lpVtbl
->Unlock(pwc
->lpDDSOffScreen
, NULL
);
1634 ddrval
= pwc
->lpDDSPrimary
->lpVtbl
->Blt( pwc
->lpDDSPrimary
,
1635 &(pwc
->rectSurface
), pwc
->lpDDSOffScreen
, &(pwc
->rectOffScreen
), 0, NULL
);
1637 if( ddrval
== DD_OK
)
1641 if( ddrval
== DDERR_SURFACELOST
)
1643 if(!DDRestoreAll(pwc
))
1648 if( ddrval
!= DDERR_WASSTILLDRAWING
)
1654 while (pwc
->lpDDSOffScreen
->lpVtbl
->Lock(pwc
->lpDDSOffScreen
,
1655 NULL
, &(pwc
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
)
1659 dwErr
= GetLastError();
1661 bRet
= BitBlt(pwc
->hDC
, 0, 0, pwc
->width
, pwc
->height
,
1662 pwc
->dib
.hDC
, 0, 0, SRCCOPY
);
1671 // The following code is added by Li Wei to enable stereo display
1673 #if !defined(NO_STEREO)
1675 void WMesaShowStereo(GLuint list
)
1678 GLbitfield mask
= GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
;
1681 // Must use double Buffer
1682 if( ! Current
-> db_flag
)
1686 glGetIntegerv(GL_MATRIX_MODE
,&matrix_mode
);
1688 // glPushMatrix(); //****
1689 WMesaViewport(Current
->gl_ctx
,0,Current
->height
/2,Current
->width
,Current
->height
/2);
1690 // Current->gl_ctx->NewState = 0;
1692 // glViewport(0,0,Current->width,Current->height/2);
1693 if(matrix_mode
!=GL_MODELVIEW
)
1694 glMatrixMode(GL_MODELVIEW
);
1696 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1698 gluLookAt(viewDistance
/2,0.0,0.0 ,
1699 viewDistance
/2,0.0,-1.0,
1701 // glTranslatef(viewDistance/2.0,0.,0.);
1702 glMultMatrixf( cm
);
1704 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
;
1709 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1711 gluLookAt(-viewDistance
/2,0.0,0.0 ,
1712 -viewDistance
/2,0.0,-1.0,
1714 // glTranslatef(-viewDistance/2.0,0.,0.);
1717 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
+ Current
->pitch
;
1719 if(matrix_mode
!=GL_MODELVIEW
)
1720 glMatrixMode(matrix_mode
);
1725 WMesaViewport(Current
->gl_ctx
,0,0,Current
->width
,Current
->height
);
1726 // Current->gl_ctx->NewState = 0;
1731 void toggleStereoMode()
1733 if(!Current
->db_flag
)
1737 if(stereoBuffer
==GL_FALSE
)
1738 #if !defined(NO_PARALLEL)
1742 Current
->ScanWidth
= Current
->pitch
*2;
1747 #if !defined(NO_PARALLEL)
1750 Current
->ScanWidth
= Current
->pitch
;
1751 Current
->pbPixels
= Current
->addrOffScreen
;
1755 /* if in stereo mode, the following function is called */
1756 void glShowStereo(GLuint list
)
1758 WMesaShowStereo(list
);
1761 #endif // End if NO_STEREO not defined
1763 #if !defined(NO_PARALLEL)
1765 void toggleParallelMode(void)
1768 parallelFlag
= GL_TRUE
;
1769 if(parallelMachine
==GL_FALSE
){
1770 PRCreateRenderBuffer( Current
->rgb_flag
? GL_RGBA
:GL_COLOR_INDEX
,
1771 Current
->cColorBits
/8,
1772 Current
->width
,Current
->height
,
1774 Current
->rgb_flag
? Current
->pbPixels
: Current
->ScreenMem
);
1775 parallelMachine
= GL_TRUE
;
1779 parallelFlag
= GL_FALSE
;
1780 if(parallelMachine
==GL_TRUE
){
1781 PRDestroyRenderBuffer();
1782 parallelMachine
=GL_FALSE
;
1783 ReadyForNextFrame
= GL_TRUE
;
1786 /***********************************************
1787 // Seems something wrong!!!!
1788 ************************************************/
1790 WMesaMakeCurrent(Current
);
1791 #if !defined(NO_STEREO)
1792 stereo_flag
= GL_FALSE
;
1797 void PRShowRenderResult(void)
1800 if(!glImageRendered())
1809 #endif //End if NO_PARALLEL not defined
1813 BYTE
DITHER_RGB_2_8BIT( int red
, int green
, int blue
, int pixel
, int scanline
)
1815 char unsigned redtemp
, greentemp
, bluetemp
, paletteindex
;
1817 //*** now, look up each value in the halftone matrix
1818 //*** using an 8x8 ordered dither.
1819 redtemp
= aDividedBy51
[red
]
1820 + (aModulo51
[red
] > aHalftone8x8
[(pixel
%8)*8
1822 greentemp
= aDividedBy51
[(char unsigned)green
]
1823 + (aModulo51
[green
] > aHalftone8x8
[
1824 (pixel
%8)*8 + scanline
%8]);
1825 bluetemp
= aDividedBy51
[(char unsigned)blue
]
1826 + (aModulo51
[blue
] > aHalftone8x8
[
1827 (pixel
%8)*8 +scanline
%8]);
1829 //*** recombine the halftoned rgb values into a palette index
1831 redtemp
+ aTimes6
[greentemp
] + aTimes36
[bluetemp
];
1833 //*** and translate through the wing halftone palette
1834 //*** translation vector to give the correct value.
1835 return aWinGHalftoneTranslation
[paletteindex
];
1842 * restore all lost objects
1844 HRESULT
DDRestoreAll( WMesaContext wc
)
1848 ddrval
= wc
->lpDDSPrimary
->lpVtbl
->Restore(wc
->lpDDSPrimary
);
1849 if( ddrval
== DD_OK
)
1851 ddrval
= wc
->lpDDSOffScreen
->lpVtbl
->Restore(wc
->lpDDSOffScreen
);
1859 * This function is called if the initialization function fails
1861 BOOL
initFail( HWND hwnd
, WMesaContext wc
)
1864 MessageBox( hwnd
, "DirectDraw Init FAILED", "", MB_OK
);
1870 static void DDDeleteOffScreen(WMesaContext wc
)
1872 if( wc
->lpDDSOffScreen
!= NULL
)
1874 wc
->lpDDSOffScreen
->lpVtbl
->Unlock(wc
->lpDDSOffScreen
,NULL
);
1875 wc
->lpDDSOffScreen
->lpVtbl
->Release(wc
->lpDDSOffScreen
);
1876 wc
->lpDDSOffScreen
= NULL
;
1881 static void DDFreePrimarySurface(WMesaContext wc
)
1883 if( wc
->lpDDSPrimary
!= NULL
)
1885 if(wc
->db_flag
== GL_FALSE
)
1886 wc
->lpDDSPrimary
->lpVtbl
->ReleaseDC(wc
->lpDDSPrimary
, wc
->hDC
);
1887 wc
->lpDDSPrimary
->lpVtbl
->Release(wc
->lpDDSPrimary
);
1888 wc
->lpDDSPrimary
= NULL
;
1892 static BOOL
DDCreatePrimarySurface(WMesaContext wc
)
1896 wc
->ddsd
.dwSize
= sizeof( wc
->ddsd
);
1897 wc
->ddsd
.dwFlags
= DDSD_CAPS
;
1898 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
1900 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
,&(wc
->ddsd
), &(wc
->lpDDSPrimary
), NULL
);
1901 if( ddrval
!= DD_OK
)
1903 return initFail(wc
->hwnd
, wc
);
1905 if(wc
->db_flag
== GL_FALSE
)
1906 wc
->lpDDSPrimary
->lpVtbl
->GetDC(wc
->lpDDSPrimary
, wc
->hDC
);
1910 static BOOL
DDCreateOffScreen(WMesaContext wc
)
1914 if(wc
->lpDD
== NULL
)
1916 GetClientRect( wc
->hwnd
, &(wc
->rectOffScreen
) );
1917 wc
->ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1918 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
1919 wc
->ddsd
.dwHeight
= wc
->rectOffScreen
.bottom
- wc
->rectOffScreen
.top
;
1920 wc
->ddsd
.dwWidth
= wc
->rectOffScreen
.right
- wc
->rectOffScreen
.left
;
1922 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
, &(wc
->ddsd
), &(wc
->lpDDSOffScreen
), NULL
);
1923 if( ddrval
!= DD_OK
)
1928 while (wc
->lpDDSOffScreen
->lpVtbl
->Lock(wc
->lpDDSOffScreen
,NULL
, &(wc
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
)
1930 // while ((ddrval = wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, &(wc->ddsd), DDLOCK_SURFACEMEMORYPTR , NULL)) != DD_OK)
1932 if(wc
->ddsd
.lpSurface
==NULL
)
1933 return initFail(wc
->hwnd
, wc
);
1935 wc
->ScreenMem
= wc
->pbPixels
= wc
->addrOffScreen
= (PBYTE
)(wc
->ddsd
.lpSurface
);
1936 wc
->ScanWidth
= wc
->pitch
= wc
->ddsd
.lPitch
;
1938 wc
->ScanWidth
= wc
->ddsd
.lPitch
*2;
1940 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
1942 ClientToScreen( wc
->hwnd
, &pt
);
1943 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
1944 wmSetPixelFormat(wc
, wc
->hDC
);
1949 * doInit - do work required for every instance of the application:
1950 * create the window, initialize data
1952 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
)
1957 LPDIRECTDRAW lpDD
; // DirectDraw object
1958 LPDIRECTDRAW2 lpDD2
;
1961 wc
->fullScreen
= displayOptions
.fullScreen
;
1962 wc
->gMode
= displayOptions
.mode
;
1964 stereo_flag
= displayOptions
.stereo
;
1965 if(wc
->db_flag
!= GL_TRUE
)
1966 stereo_flag
= GL_FALSE
;
1968 * create the main DirectDraw object
1970 ddrval
= DirectDrawCreate( NULL
, &(wc
->lpDD
), NULL
);
1971 if( ddrval
!= DD_OK
)
1973 return initFail(hwnd
,wc
);
1976 // Get exclusive mode if requested
1979 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1983 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
, DDSCL_NORMAL
);
1985 if( ddrval
!= DD_OK
)
1987 return initFail(hwnd
, wc
);
1991 /* ddrval = wc->lpDD->lpVtbl->QueryInterface(wc->lpDD, IID_IDirectDraw2,
1992 (LPVOID *)((wc->lpDD2)));
1996 return initFail(hwnd
, wc
);
1999 //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
2000 // wc->lpDD2->lpVtbl->GetMonitorFrequency(wc->lpDD, &dwFrequency);
2003 case 1: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 640, 480, displayOptions
.bpp
); break;
2004 case 2: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 800, 600, displayOptions
.bpp
); break;
2005 case 3: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1024, 768, displayOptions
.bpp
); break;
2006 case 4: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1152, 864, displayOptions
.bpp
); break;
2007 case 5: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1280, 1024, displayOptions
.bpp
); break;
2010 if( ddrval
!= DD_OK
)
2012 printf("Can't modify display mode, current mode used\n");
2013 // return initFail(hwnd , wc);
2015 //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
2017 case DDERR_INVALIDOBJECT
:
2019 case DDERR_INVALIDPARAMS
:
2021 case DDERR_UNSUPPORTEDMODE
:
2025 if(DDCreatePrimarySurface(wc
) == GL_FALSE
)
2026 return initFail(hwnd
, wc
);
2029 return DDCreateOffScreen(wc
);
2032 static void DDFree( WMesaContext wc
)
2034 if( wc
->lpDD
!= NULL
)
2036 DDFreePrimarySurface(wc
);
2037 DDDeleteOffScreen(wc
);
2038 wc
->lpDD
->lpVtbl
->Release(wc
->lpDD
);
2041 // Clean up the screen on exit
2042 RedrawWindow( NULL
, NULL
, NULL
, RDW_INVALIDATE
| RDW_ERASE
|
2048 void WMesaMove(void)
2050 WMesaContext wc
= Current
;
2052 if (Current
!= NULL
){
2053 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2055 ClientToScreen( wc
->hwnd
, &pt
);
2056 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2063 * Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable
2066 #define PACK_8B8G8R( R, G, B ) ( ((B) << 16) | ((G) << 8) | (R) )
2069 /**********************************************************************/
2070 /*** Triangle rendering ***/
2071 /**********************************************************************/
2074 * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
2076 static void smooth_8A8B8G8R_z_triangle( GLcontext
*ctx
,
2077 GLuint v0
, GLuint v1
, GLuint v2
,
2080 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2082 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
2083 #define INTERP_RGB 1
2084 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2085 #define PIXEL_TYPE GLuint
2086 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2087 #define BYTES_PER_ROW (wmesa->ScanWidth)
2088 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2090 GLint i, len = RIGHT-LEFT; \
2091 for (i=0;i<len;i++) { \
2092 GLdepth z = FixedToDepth(ffz); \
2093 if (z < zRow[i]) { \
2094 pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2095 FixedToInt(ffb) ); \
2098 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2104 #include "tritemp.h"
2108 #include "..\tritemp.h"
2110 #include "tritemp.h"
2117 * XImage, smooth, depth-buffered, PF_8R8G8B triangle.
2119 static void smooth_8R8G8B_z_triangle( GLcontext
*ctx
,
2120 GLuint v0
, GLuint v1
, GLuint v2
,
2123 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2125 #define INTERP_RGB 1
2126 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2127 #define PIXEL_TYPE GLuint
2128 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2129 #define BYTES_PER_ROW (wmesa->ScanWidth)
2130 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2132 GLint i, len = RIGHT-LEFT; \
2133 for (i=0;i<len;i++) { \
2134 GLdepth z = FixedToDepth(ffz); \
2135 if (z < zRow[i]) { \
2136 pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2137 FixedToInt(ffb) ); \
2140 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2145 #include "tritemp.h"
2149 #include "..\tritemp.h"
2151 #include "tritemp.h"
2159 * XImage, smooth, depth-buffered, PF_5R6G5B triangle.
2161 static void smooth_5R6G5B_z_triangle( GLcontext
*ctx
,
2162 GLuint v0
, GLuint v1
, GLuint v2
,
2165 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2167 #define INTERP_RGB 1
2168 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2169 #define PIXEL_TYPE GLushort
2170 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2171 #define BYTES_PER_ROW (wmesa->ScanWidth)
2172 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2174 GLint i, len = RIGHT-LEFT; \
2175 for (i=0;i<len;i++) { \
2176 GLdepth z = FixedToDepth(ffz); \
2177 if (z < zRow[i]) { \
2178 pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2179 FixedToInt(ffb) ); \
2182 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2187 #include "tritemp.h"
2191 #include "..\tritemp.h"
2193 #include "tritemp.h"
2199 * XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
2201 static void flat_8A8B8G8R_z_triangle( GLcontext
*ctx
, GLuint v0
,
2202 GLuint v1
, GLuint v2
, GLuint pv
)
2204 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2206 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2207 #define PIXEL_TYPE GLuint
2208 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2209 #define BYTES_PER_ROW (wmesa->ScanWidth)
2210 #define SETUP_CODE \
2211 unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \
2212 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2213 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2215 GLint i, len = RIGHT-LEFT; \
2216 for (i=0;i<len;i++) { \
2217 GLdepth z = FixedToDepth(ffz); \
2218 if (z < zRow[i]) { \
2226 #include "tritemp.h"
2230 #include "..\tritemp.h"
2232 #include "tritemp.h"
2239 * XImage, flat, depth-buffered, PF_8R8G8B triangle.
2241 static void flat_8R8G8B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2242 GLuint v2
, GLuint pv
)
2244 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2246 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2247 #define PIXEL_TYPE GLuint
2248 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2249 #define BYTES_PER_ROW (wmesa->ScanWidth)
2250 #define SETUP_CODE \
2251 unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \
2252 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2253 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2255 GLint i, len = RIGHT-LEFT; \
2256 for (i=0;i<len;i++) { \
2257 GLdepth z = FixedToDepth(ffz); \
2258 if (z < zRow[i]) { \
2266 #include "tritemp.h"
2270 #include "..\tritemp.h"
2272 #include "tritemp.h"
2279 * XImage, flat, depth-buffered, PF_5R6G5B triangle.
2281 static void flat_5R6G5B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2282 GLuint v2
, GLuint pv
)
2284 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2286 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2287 #define PIXEL_TYPE GLushort
2288 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2289 #define BYTES_PER_ROW (wmesa->ScanWidth)
2290 #define SETUP_CODE \
2291 unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \
2292 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2293 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2295 GLint i, len = RIGHT-LEFT; \
2296 for (i=0;i<len;i++) { \
2297 GLdepth z = FixedToDepth(ffz); \
2298 if (z < zRow[i]) { \
2306 #include "tritemp.h"
2310 #include "..\tritemp.h"
2312 #include "tritemp.h"
2319 * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
2321 static void smooth_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2322 GLuint v2
, GLuint pv
)
2324 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2325 #define INTERP_RGB 1
2326 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2327 #define PIXEL_TYPE GLuint
2328 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2329 #define BYTES_PER_ROW (wmesa->ScanWidth)
2330 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2333 PIXEL_TYPE *pixel = pRow; \
2334 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2335 *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2336 FixedToInt(ffb) ); \
2337 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2341 #include "tritemp.h"
2345 #include "..\tritemp.h"
2347 #include "tritemp.h"
2354 * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
2356 static void smooth_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2357 GLuint v2
, GLuint pv
)
2359 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2360 #define INTERP_RGB 1
2361 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2362 #define PIXEL_TYPE GLuint
2363 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2364 #define BYTES_PER_ROW (wmesa->ScanWidth)
2365 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2368 PIXEL_TYPE *pixel = pRow; \
2369 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2370 *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2371 FixedToInt(ffb) ); \
2372 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2376 #include "tritemp.h"
2380 #include "..\tritemp.h"
2382 #include "tritemp.h"
2389 * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
2391 static void smooth_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2392 GLuint v2
, GLuint pv
)
2394 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2395 #define INTERP_RGB 1
2396 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2397 #define PIXEL_TYPE GLushort
2398 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2399 #define BYTES_PER_ROW (wmesa->ScanWidth)
2400 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2403 PIXEL_TYPE *pixel = pRow; \
2404 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2405 *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2406 FixedToInt(ffb) ); \
2407 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2411 #include "tritemp.h"
2415 #include "..\tritemp.h"
2417 #include "tritemp.h"
2425 * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
2427 static void flat_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
,
2428 GLuint v1
, GLuint v2
, GLuint pv
)
2430 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2431 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2432 #define PIXEL_TYPE GLuint
2433 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2434 #define BYTES_PER_ROW (wmesa->ScanWidth)
2435 #define SETUP_CODE \
2436 unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \
2437 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2438 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2441 PIXEL_TYPE *pixel = pRow; \
2442 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2448 #include "tritemp.h"
2452 #include "..\tritemp.h"
2454 #include "tritemp.h"
2461 * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
2463 static void flat_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2464 GLuint v2
, GLuint pv
)
2466 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2467 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2468 #define PIXEL_TYPE GLuint
2469 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2470 #define BYTES_PER_ROW (wmesa->ScanWidth)
2471 #define SETUP_CODE \
2472 unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \
2473 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2474 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2477 PIXEL_TYPE *pixel = pRow; \
2478 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2483 #include "tritemp.h"
2487 #include "..\tritemp.h"
2489 #include "tritemp.h"
2496 * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
2498 static void flat_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2499 GLuint v2
, GLuint pv
)
2501 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2502 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2503 #define PIXEL_TYPE GLushort
2504 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2505 #define BYTES_PER_ROW (wmesa->ScanWidth)
2506 #define SETUP_CODE \
2507 unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \
2508 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2509 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2512 PIXEL_TYPE *pixel = pRow; \
2513 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2518 #include "tritemp.h"
2522 #include "..\tritemp.h"
2524 #include "tritemp.h"
2531 * XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
2534 static void smooth_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2535 GLuint v2
, GLuint pv
)
2537 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2539 #define INTERP_INDEX 1
2540 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2541 #define PIXEL_TYPE GLubyte
2542 #define BYTES_PER_ROW (wmesa->ScanWidth)
2543 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2545 GLint i, len = RIGHT-LEFT; \
2546 for (i=0;i<len;i++) { \
2547 GLdepth z = FixedToDepth(ffz); \
2548 if (z < zRow[i]) { \
2549 pRow[i] = FixedToInt(ffi); \
2557 #include "tritemp.h"
2561 #include "..\tritemp.h"
2563 #include "tritemp.h"
2570 * XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
2573 static void flat_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2574 GLuint v2
, GLuint pv
)
2576 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2578 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2579 #define PIXEL_TYPE GLubyte
2580 #define BYTES_PER_ROW (wmesa->ScanWidth)
2581 #define SETUP_CODE \
2582 GLuint index = VB->IndexPtr->data[pv]; \
2583 (*ctx->Driver.Index)( ctx, index );
2584 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2586 GLint i, len = RIGHT-LEFT; \
2587 for (i=0;i<len;i++) { \
2588 GLdepth z = FixedToDepth(ffz); \
2589 if (z < zRow[i]) { \
2597 #include "tritemp.h"
2601 #include "..\tritemp.h"
2603 #include "tritemp.h"
2611 * XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2614 static void smooth_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2615 GLuint v2
, GLuint pv
)
2617 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2619 #define INTERP_INDEX 1
2620 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2621 #define PIXEL_TYPE GLubyte
2622 #define BYTES_PER_ROW (wmesa->ScanWidth)
2623 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2626 PIXEL_TYPE *pixel = pRow; \
2627 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2628 *pixel = FixedToInt(ffi); \
2633 #include "tritemp.h"
2637 #include "..\tritemp.h"
2639 #include "tritemp.h"
2646 * XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2648 static void flat_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2649 GLuint v2
, GLuint pv
)
2651 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2653 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2654 #define PIXEL_TYPE GLubyte
2655 #define BYTES_PER_ROW (wmesa->ScanWidth)
2656 #define SETUP_CODE \
2657 GLuint index = VB->IndexPtr->data[pv]; \
2658 (*ctx->Driver.Index)( ctx, index );
2659 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2662 PIXEL_TYPE *pixel = pRow; \
2663 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2668 #include "tritemp.h"
2672 #include "..\tritemp.h"
2674 #include "tritemp.h"
2680 * XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
2682 static void smooth_DITHER8_z_triangle( GLcontext
*ctx
,
2683 GLuint v0
, GLuint v1
, GLuint v2
,
2686 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2687 DITHER_RGB_TO_8BIT_SETUP
2689 #define INTERP_RGB 1
2690 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2691 #define PIXEL_TYPE GLubyte
2692 #define BYTES_PER_ROW (wmesa->ScanWidth)
2693 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2695 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
2696 for (i=0;i<len;i++,xx++) { \
2697 GLdepth z = FixedToDepth(ffz); \
2698 if (z < zRow[i]) { \
2699 DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg), \
2700 FixedToInt(ffb), xx, yy); \
2701 pRow[i] = pixelDithered; \
2704 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2709 #include "tritemp.h"
2713 #include "..\tritemp.h"
2715 #include "tritemp.h"
2721 * XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
2723 static void flat_DITHER8_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2724 GLuint v2
, GLuint pv
)
2726 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2727 DITHER_RGB_TO_8BIT_SETUP
2729 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2730 #define PIXEL_TYPE GLubyte
2731 #define BYTES_PER_ROW (wmesa->ScanWidth)
2733 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2735 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
2736 for (i=0;i<len;i++,xx++) { \
2737 GLdepth z = FixedToDepth(ffz); \
2738 if (z < zRow[i]) { \
2739 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \
2740 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \
2741 pRow[i] = pixelDithered; \
2748 #include "tritemp.h"
2752 #include "..\tritemp.h"
2754 #include "tritemp.h"
2760 * XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
2762 static void smooth_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2763 GLuint v2
, GLuint pv
)
2765 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2766 DITHER_RGB_TO_8BIT_SETUP
2767 #define INTERP_RGB 1
2768 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2769 #define PIXEL_TYPE GLubyte
2770 #define BYTES_PER_ROW (wmesa->ScanWidth)
2771 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2773 GLint xx, yy = FLIP(Y); \
2774 PIXEL_TYPE *pixel = pRow; \
2775 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2776 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy);\
2777 *pixel = pixelDithered; \
2778 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2782 #include "tritemp.h"
2786 #include "..\tritemp.h"
2788 #include "tritemp.h"
2794 * XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
2797 static void flat_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2798 GLuint v2
, GLuint pv
)
2800 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2801 DITHER_RGB_TO_8BIT_SETUP
2802 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2803 #define PIXEL_TYPE GLubyte
2804 #define BYTES_PER_ROW (wmesa->ScanWidth)
2806 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2808 GLint xx, yy = FLIP(Y); \
2809 PIXEL_TYPE *pixel = pRow; \
2810 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2811 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \
2812 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \
2813 *pixel = pixelDithered; \
2817 #include "tritemp.h"
2821 #include "..\tritemp.h"
2823 #include "tritemp.h"
2831 static triangle_func
choose_triangle_function( GLcontext
*ctx
)
2833 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2834 int depth
= wmesa
->cColorBits
;
2836 if (ctx
->Polygon
.SmoothFlag
) return NULL
;
2837 if (ctx
->Texture
._ReallyEnabled
) return NULL
;
2838 if (!wmesa
->db_flag
) return NULL
;
2839 /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {
2840 if ( ctx
->Light
.ShadeModel
==GL_SMOOTH
2841 && ctx
->_RasterMask
==DEPTH_BIT
2842 && ctx
->Depth
.Func
==GL_LESS
2843 && ctx
->Depth
.Mask
==GL_TRUE
2844 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2845 switch (wmesa
->pixelformat
) {
2847 return smooth_8A8B8G8R_z_triangle
;
2849 return smooth_8R8G8B_z_triangle
;
2851 return smooth_5R6G5B_z_triangle
;
2853 return smooth_DITHER8_z_triangle
;
2855 return smooth_ci_z_triangle
;
2860 if ( ctx
->Light
.ShadeModel
==GL_FLAT
2861 && ctx
->_RasterMask
==DEPTH_BIT
2862 && ctx
->Depth
.Func
==GL_LESS
2863 && ctx
->Depth
.Mask
==GL_TRUE
2864 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2865 switch (wmesa
->pixelformat
) {
2867 return flat_8A8B8G8R_z_triangle
;
2869 return flat_8R8G8B_z_triangle
;
2871 return flat_5R6G5B_z_triangle
;
2873 return flat_DITHER8_z_triangle
;
2875 return flat_ci_z_triangle
;
2880 if ( ctx
->_RasterMask
==0 /* no depth test */
2881 && ctx
->Light
.ShadeModel
==GL_SMOOTH
2882 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2883 switch (wmesa
->pixelformat
) {
2885 return smooth_8A8B8G8R_triangle
;
2887 return smooth_8R8G8B_triangle
;
2889 return smooth_5R6G5B_triangle
;
2891 return smooth_DITHER8_triangle
;
2893 return smooth_ci_triangle
;
2899 if ( ctx
->_RasterMask
==0 /* no depth test */
2900 && ctx
->Light
.ShadeModel
==GL_FLAT
2901 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2902 switch (wmesa
->pixelformat
) {
2904 return flat_8A8B8G8R_triangle
;
2906 return flat_8R8G8B_triangle
;
2908 return flat_5R6G5B_triangle
;
2910 return flat_DITHER8_triangle
;
2912 return flat_ci_triangle
;
2923 * Define a new viewport and reallocate auxillary buffers if the size of
2924 * the window (color buffer) has changed.
2926 void WMesaViewport( GLcontext
*ctx
,
2927 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2930 ctx
->Viewport
.X
= x
;
2931 ctx
->Viewport
.Width
= width
;
2932 ctx
->Viewport
.Y
= y
;
2933 ctx
->Viewport
.Height
= height
;
2935 /* compute scale and bias values */
2936 /* Pre-Keith 3.1 changes
2937 ctx->Viewport.Map.m[Sx] = (GLfloat) width / 2.0F;
2938 ctx->Viewport.Map.m[Tx] = ctx->Viewport.Sx + x;
2939 ctx->Viewport.Map.m[Sy] = (GLfloat) height / 2.0F;
2940 ctx->Viewport.Map.m[Ty] = ctx->Viewport.Sy + y;
2942 ctx
->Viewport
.WindowMap
.m
[MAT_SX
] = (GLfloat
) width
/ 2.0F
;
2943 ctx
->Viewport
.WindowMap
.m
[MAT_TX
] = ctx
->Viewport
.WindowMap
.m
[MAT_SX
] + x
;
2944 ctx
->Viewport
.WindowMap
.m
[MAT_SY
] = (GLfloat
) height
/ 2.0F
;
2945 ctx
->Viewport
.WindowMap
.m
[MAT_TY
] = ctx
->Viewport
.WindowMap
.m
[MAT_SY
] + y
;