1 /* $Id: wmesaBackup.c,v 1.2 2000/11/05 18:41:00 keithw Exp $ */
7 * Display driver for Mesa 2.3 under
8 * Windows95 and WindowsNT
10 * Copyright (C) 1996- Li Wei
11 * Address : Institute of Artificial Intelligence
13 * : Xi'an Jiaotong University
14 * Email : liwei@aiar.xjtu.edu.cn
15 * Web page : http://sun.aiar.xjtu.edu.cn
17 * This file and its associations are partially borrowed from the
18 * Windows NT driver for Mesa 1.8 , written by Mark Leaming
24 * $Log: wmesaBackup.c,v $
25 * Revision 1.2 2000/11/05 18:41:00 keithw
26 * - Changes for new software rasterizer modules
27 * - Remove support for choosing software fallbacks from core code
28 * - Remove partial fallback code from vbrender.c -- drivers are now
29 * expected to be able to find a triangle/quad function for every state,
30 * even if they have to use _swsetup_Triangle or _swsetup_Quad.
31 * - Marked derived variables in the GLcontext struct with a leading
34 * Revision 1.1.1.1 1999/08/19 00:55:42 jtg
37 * Revision 1.1 1999/01/03 03:08:57 brianp
40 * Revision 3.1 1998/06/11 01:42:08 brianp
41 * updated for Mesa 3.0 device driver interface (but not tested)
43 * Revision 3.0 1998/06/11 01:18:25 brianp
49 #define WMESA_STEREO_C
54 #include "mesa_extend.h"
65 #pragma warning ( disable : 4133 4761 )
68 // #include "profile.h"
78 #define CopyMemory memcpy
81 #if !defined(NO_STEREO)
87 #if !defined(NO_PARALLEL)
88 // #include "parallel.h"
91 struct DISPLAY_OPTIONS displayOptions
;
93 GLenum stereoCompile
= GL_FALSE
;
94 GLenum stereoShowing
= GL_FALSE
;
95 GLenum stereoBuffer
= GL_FALSE
;
96 #if !defined(NO_STEREO)
97 GLint displayList
= MAXIMUM_DISPLAY_LIST
;
99 GLint stereo_flag
= 0 ;
101 /* end of added code*/
103 static PWMC Current
= NULL
;
104 WMesaContext WC
= NULL
;
107 #define assert(ignore) ((void) 0)
109 void Mesa_Assert(void *Cond
,void *File
,unsigned Line
)
112 sprintf(Msg
,"%s %s %d",Cond
,File
,Line
);
113 MessageBox(NULL
,Msg
,"Assertion failed.",MB_OK
);
116 #define assert(e) if (!e) Mesa_Assert(#e,__FILE__,__LINE__);
119 //#define DD_GETDC (Current->hDC )
120 #define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
121 //#define DD_GETDC ((Current->db_flag) ? Current->hDCPrimary : Current->hDCBack )
124 //#define BEGINGDICALL if(Current->rgb_flag)wmFlushBits(Current);
126 //#define ENDGDICALL if(Current->rgb_flag)wmGetBits(Current);
129 //#define FLIP(Y) (Current->dither_flag? Y : Current->height-(Y)-1)
130 //#define FLIP(Y) (Current->height-(Y)-1)
132 #define FLIP(Y) (Current->db_flag? Y: Current->height-(Y)-1)
134 #define ENDPROFILE(PARA)
136 #define DITHER_RGB_TO_8BIT_SETUP \
137 GLubyte pixelDithered;
139 #define DITHER_RGB_TO_8BIT(red, green, blue, pixel, scanline) \
141 char unsigned redtemp, greentemp, bluetemp, paletteindex; \
142 redtemp = aDividedBy51[red] \
143 + (aModulo51[red] > aHalftone8x8[(pixel%8)*8 \
145 greentemp = aDividedBy51[(char unsigned)green] \
146 + (aModulo51[green] > aHalftone8x8[ \
147 (pixel%8)*8 + scanline%8]); \
148 bluetemp = aDividedBy51[(char unsigned)blue] \
149 + (aModulo51[blue] > aHalftone8x8[ \
150 (pixel%8)*8 +scanline%8]); \
151 paletteindex = redtemp + aTimes6[greentemp] + aTimes36[bluetemp]; \
152 pixelDithered = aWinGHalftoneTranslation[paletteindex]; \
157 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
);
158 static void DDFree( WMesaContext wc
);
159 static HRESULT
DDRestoreAll( WMesaContext wc
);
160 static void DDDeleteOffScreen(WMesaContext wc
);
161 static BOOL
DDCreateOffScreen(WMesaContext wc
);
164 static void FlushToFile(PWMC pwc
, PSTR szFile
);
166 BOOL
wmCreateBackingStore(PWMC pwc
, long lxSize
, long lySize
);
167 BOOL
wmDeleteBackingStore(PWMC pwc
);
168 void wmCreatePalette( PWMC pwdc
);
169 BOOL
wmSetDibColors(PWMC pwc
);
170 void wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
);
172 void wmCreateDIBSection(
174 PWMC pwc
, // handle of device context
175 CONST BITMAPINFO
*pbmi
, // address of structure containing bitmap size, format, and color data
176 UINT iUsage
// color data type indicator: RGB values or palette indices
180 void WMesaViewport( GLcontext
*ctx
,
181 GLint x
, GLint y
, GLsizei width
, GLsizei height
);
184 static triangle_func
choose_triangle_function( GLcontext
*ctx
);
187 static void wmSetPixelFormat( PWMC wc
, HDC hDC
)
190 wc
->cColorBits
= GetDeviceCaps(hDC
, BITSPIXEL
);
193 switch(wc
->cColorBits
){
195 if(wc
->dither_flag
!= GL_TRUE
)
196 wc
->pixelformat
= PF_INDEX8
;
198 wc
->pixelformat
= PF_DITHER8
;
201 wc
->pixelformat
= PF_5R6G5B
;
204 wc
->pixelformat
= PF_8R8G8B
;
207 wc
->pixelformat
= PF_BADFORMAT
;
212 // This function sets the color table of a DIB section
213 // to match that of the destination DC
215 BOOL
/*WINAPI*/ wmSetDibColors(PWMC pwc
)
217 RGBQUAD
*pColTab
, *pRGB
;
218 PALETTEENTRY
*pPal
, *pPE
;
223 /* Build a color table in the DIB that maps to the
224 selected palette in the DC.
226 nColors
= 1 << pwc
->cColorBits
;
227 pPal
= (PALETTEENTRY
*)malloc( nColors
* sizeof(PALETTEENTRY
));
228 memset( pPal
, 0, nColors
* sizeof(PALETTEENTRY
) );
229 GetPaletteEntries( pwc
->hGLPalette
, 0, nColors
, pPal
);
230 pColTab
= (RGBQUAD
*)malloc( nColors
* sizeof(RGBQUAD
));
231 for (i
= 0, pRGB
= pColTab
, pPE
= pPal
; i
< nColors
; i
++, pRGB
++, pPE
++) {
232 pRGB
->rgbRed
= pPE
->peRed
;
233 pRGB
->rgbGreen
= pPE
->peGreen
;
234 pRGB
->rgbBlue
= pPE
->peBlue
;
237 bRet
= SetDIBColorTable(pwc
->dib
.hDC
, 0, nColors
, pColTab
);
240 dwErr
= GetLastError();
250 // Free up the dib section that was created
252 BOOL
wmDeleteBackingStore(PWMC pwc
)
254 SelectObject(pwc
->dib
.hDC
, pwc
->hOldBitmap
);
255 DeleteDC(pwc
->dib
.hDC
);
256 DeleteObject(pwc
->hbmDIB
);
257 UnmapViewOfFile(pwc
->dib
.base
);
258 CloseHandle(pwc
->dib
.hFileMap
);
264 // This function creates the DIB section that is used for combined
267 BOOL
/*WINAPI*/ wmCreateBackingStore(PWMC pwc
, long lxSize
, long lySize
)
270 LPBITMAPINFO pbmi
= &(pwc
->bmi
);
273 pbmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
274 pbmi
->bmiHeader
.biWidth
= lxSize
;
275 pbmi
->bmiHeader
.biHeight
= -lySize
;
276 pbmi
->bmiHeader
.biPlanes
= 1;
278 pbmi
->bmiHeader
.biBitCount
= GetDeviceCaps(pwc
->hDC
, BITSPIXEL
);
280 pbmi
->bmiHeader
.biBitCount
= 8;
281 pbmi
->bmiHeader
.biCompression
= BI_RGB
;
282 pbmi
->bmiHeader
.biSizeImage
= 0;
283 pbmi
->bmiHeader
.biXPelsPerMeter
= 0;
284 pbmi
->bmiHeader
.biYPelsPerMeter
= 0;
285 pbmi
->bmiHeader
.biClrUsed
= 0;
286 pbmi
->bmiHeader
.biClrImportant
= 0;
288 iUsage
= (pbmi
->bmiHeader
.biBitCount
<= 8) ? DIB_PAL_COLORS
: DIB_RGB_COLORS
;
290 pwc
->cColorBits
= pbmi
->bmiHeader
.biBitCount
;
291 pwc
->ScanWidth
= pwc
->pitch
= lxSize
;
293 wmCreateDIBSection(hdc
, pwc
, pbmi
, iUsage
);
295 if ((iUsage
== DIB_PAL_COLORS
) && !(pwc
->hGLPalette
)) {
296 wmCreatePalette( pwc
);
297 wmSetDibColors( pwc
);
299 wmSetPixelFormat(pwc
, pwc
->hDC
);
306 // This function copies one scan line in a DIB section to another
308 BOOL GLWINAPI
wmSetDIBits(PWMC pwc
, UINT uiScanWidth
, UINT uiNumScans
, UINT nBypp
, UINT uiNewWidth
, LPBYTE pBits
)
311 LPBYTE pDest
= pwc
->pbPixels
;
312 DWORD dwNextScan
= uiScanWidth
;
313 DWORD dwNewScan
= uiNewWidth
;
314 DWORD dwScanWidth
= (uiScanWidth
* nBypp
);
317 // We need to round up to the nearest DWORD
318 // and multiply by the number of bytes per
321 dwNextScan
= (((dwNextScan
* nBypp
)+ 3) & ~3);
322 dwNewScan
= (((dwNewScan
* nBypp
)+ 3) & ~3);
324 for(uiScans
= 0; uiScans
< uiNumScans
; uiScans
++){
325 CopyMemory(pDest
, pBits
, dwScanWidth
);
335 BOOL
wmFlush(PWMC pwc
);
339 Modified from file osmesa.c
343 #define PIXELADDR(X,Y) ((GLubyte *)Current->pbPixels + (Current->height-Y-1)* Current->ScanWidth + (X)*nBypp)
344 #define PIXELADDR1( X, Y ) \
345 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X))
346 #define PIXELADDR2( X, Y ) \
347 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*2)
348 #define PIXELADDR4( X, Y ) \
349 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*4)
352 BYTE
DITHER_RGB_2_8BIT( int r
, int g
, int b
, int x
, int y
);
354 /* Finish all pending operations and synchronize. */
355 static void finish(GLcontext
* ctx
)
362 // We cache all gl draw routines until a flush is made
364 static void flush(GLcontext
* ctx
)
367 if((Current
->rgb_flag
/*&& !(Current->dib.fFlushed)*/&&!(Current
->db_flag
))
368 ||(!Current
->rgb_flag
))
379 * Set the color index used to clear the color buffer.
381 static void clear_index(GLcontext
* ctx
, GLuint index
)
384 Current
->clearpixel
= index
;
385 ENDPROFILE(clear_index
)
391 * Set the color used to clear the color buffer.
393 static void clear_color( GLcontext
* ctx
, GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
396 Current
->clearpixel
=RGB(r
, g
, b
);
397 ENDPROFILE(clear_color
)
403 * Clear the specified region of the color buffer using the clear color
404 * or index as specified by one of the two functions above.
406 //static void clear(GLcontext* ctx,
407 // GLboolean all,GLint x, GLint y, GLint width, GLint height )
408 // TODO: I modified this function to match the prototype in dd.h. (swansma@geocities.com)
409 // dd.h does not explain what the return type is so I could not set this to the proper
411 static GLbitfield
clear(GLcontext
* ctx
, GLbitfield mask
,
412 GLboolean all
, GLint x
, GLint y
, GLint width
, GLint height
)
417 LPDWORD lpdw
= (LPDWORD
)Current
->pbPixels
;
418 LPWORD lpw
= (LPWORD
)Current
->pbPixels
;
419 LPBYTE lpb
= Current
->pbPixels
;
426 width
=Current
->width
;
427 height
=Current
->height
;
429 if(Current
->db_flag
==GL_TRUE
){
430 UINT nBypp
= Current
->cColorBits
/ 8;
435 /* Need rectification */
436 iSize
= Current
->width
/4;
437 bColor
= BGR8(GetRValue(Current
->clearpixel
),
438 GetGValue(Current
->clearpixel
),
439 GetBValue(Current
->clearpixel
));
440 wColor
= MAKEWORD(bColor
,bColor
);
441 dwColor
= MAKELONG(wColor
, wColor
);
444 iSize
= Current
->width
/ 2;
445 wColor
= BGR16(GetRValue(Current
->clearpixel
),
446 GetGValue(Current
->clearpixel
),
447 GetBValue(Current
->clearpixel
));
448 dwColor
= MAKELONG(wColor
, wColor
);
451 iSize
= Current
->width
;
452 dwColor
= BGR32(GetRValue(Current
->clearpixel
),
453 GetGValue(Current
->clearpixel
),
454 GetBValue(Current
->clearpixel
));
464 // This is the 24bit case
467 iSize
= Current
->width
*3/4;
468 dwColor
= BGR24(GetRValue(Current
->clearpixel
),
469 GetGValue(Current
->clearpixel
),
470 GetBValue(Current
->clearpixel
));
485 memcpy(lpb
, Current
->pbPixels
, iSize
*4);
486 lpb
+= Current
->ScanWidth
;
491 else { // For single buffer
493 HPEN Pen
=CreatePen(PS_SOLID
,1,Current
->clearpixel
);
494 HBRUSH Brush
=CreateSolidBrush(Current
->clearpixel
);
495 HPEN Old_Pen
=SelectObject(DC
,Pen
);
496 HBRUSH Old_Brush
=SelectObject(DC
,Brush
);
497 Rectangle(DC
,x
,y
,x
+width
,y
+height
);
498 SelectObject(DC
,Old_Pen
);
499 SelectObject(DC
,Old_Brush
);
509 return mask
; // TODO: I doubt this is correct. dd.h doesn't explain what this should
515 /* Set the current color index. */
516 static void set_index(GLcontext
* ctx
, GLuint index
)
519 Current
->pixel
=index
;
520 ENDPROFILE(set_index
)
525 /* Set the current RGBA color. */
526 static void set_color( GLcontext
* ctx
, GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
529 Current
->pixel
= RGB( r
, g
, b
);
530 ENDPROFILE(set_color
)
535 /* Set the index mode bitplane mask. */
536 static GLboolean
index_mask(GLcontext
* ctx
, GLuint mask
)
538 /* can't implement */
544 /* Set the RGBA drawing mask. */
545 static GLboolean
color_mask( GLcontext
* ctx
,
546 GLboolean rmask
, GLboolean gmask
,
547 GLboolean bmask
, GLboolean amask
)
549 /* can't implement */
556 * Set the pixel logic operation. Return GL_TRUE if the device driver
557 * can perform the operation, otherwise return GL_FALSE. If GL_FALSE
558 * is returned, the logic op will be done in software by Mesa.
560 GLboolean
logicop( GLcontext
* ctx
, GLenum op
)
562 /* can't implement */
567 static void dither( GLcontext
* ctx
, GLboolean enable
)
569 if(enable
== GL_FALSE
){
570 Current
->dither_flag
= GL_FALSE
;
571 if(Current
->cColorBits
== 8)
572 Current
->pixelformat
= PF_INDEX8
;
575 if (Current
->rgb_flag
&& Current
->cColorBits
== 8){
576 Current
->pixelformat
= PF_DITHER8
;
577 Current
->dither_flag
= GL_TRUE
;
580 Current
->dither_flag
= GL_FALSE
;
586 static GLboolean
set_buffer( GLcontext
* ctx
, GLenum mode
)
589 /* TODO: this could be better */
590 if (mode
==GL_FRONT
|| mode
==GL_BACK
) {
596 ENDPROFILE(set_buffer
)
601 /* Return characteristics of the output buffer. */
602 static void buffer_size( GLcontext
* ctx
, GLuint
*width
, GLuint
*height
)
608 GetClientRect(Current
->Window
,&CR
);
613 New_Size
=((*width
)!=Current
->width
) || ((*height
)!=Current
->height
);
616 Current
->width
=*width
;
617 Current
->height
=*height
;
618 Current
->ScanWidth
=Current
->width
;
619 if ((Current
->ScanWidth
%sizeof(long))!=0)
620 Current
->ScanWidth
+=(sizeof(long)-(Current
->ScanWidth
%sizeof(long)));
622 if (Current
->db_flag
){
624 DDDeleteOffScreen(Current
);
625 DDCreateOffScreen(Current
);
627 if (Current
->rgb_flag
==GL_TRUE
&& Current
->dither_flag
!=GL_TRUE
){
628 wmDeleteBackingStore(Current
);
629 wmCreateBackingStore(Current
, Current
->width
, Current
->height
);
634 // Resize OsmesaBuffer if in Parallel mode
635 #if !defined(NO_PARALLEL)
637 PRSizeRenderBuffer(Current
->width
, Current
->height
,Current
->ScanWidth
,
638 Current
->rgb_flag
== GL_TRUE
? Current
->pbPixels
: Current
->ScreenMem
);
641 ENDPROFILE(buffer_size
)
646 /**********************************************************************/
647 /***** Accelerated point, line, polygon rendering *****/
648 /**********************************************************************/
651 static void fast_rgb_points( GLcontext
* ctx
, GLuint first
, GLuint last
)
659 if (Current
->gl_ctx
->VB
->MonoColor
) {
660 /* all drawn with current color */
661 for (i
=first
;i
<=last
;i
++) {
662 if (!Current
->gl_ctx
->VB
->ClipMask
[i
]) {
664 x
= (GLint
) Current
->gl_ctx
->VB
->Win
[i
][0];
665 y
= FLIP( (GLint
) Current
->gl_ctx
->VB
->Win
[i
][1] );
666 wmSetPixel(pwc
, y
,x
,GetRValue(Current
->pixel
),
667 GetGValue(Current
->pixel
), GetBValue(Current
->pixel
));
672 /* draw points of different colors */
673 for (i
=first
;i
<=last
;i
++) {
674 if (!Current
->gl_ctx
->VB
->ClipMask
[i
]) {
676 unsigned long pixel
=RGB(Current
->gl_ctx
->VB
->Color
[i
][0]*255.0,
677 Current
->gl_ctx
->VB
->Color
[i
][1]*255.0,
678 Current
->gl_ctx
->VB
->Color
[i
][2]*255.0);
679 x
= (GLint
) Current
->gl_ctx
->VB
->Win
[i
][0];
680 y
= FLIP( (GLint
) Current
->gl_ctx
->VB
->Win
[i
][1] );
681 wmSetPixel(pwc
, y
,x
,Current
->gl_ctx
->VB
->Color
[i
][0]*255.0,
682 Current
->gl_ctx
->VB
->Color
[i
][1]*255.0,
683 Current
->gl_ctx
->VB
->Color
[i
][2]*255.0);
688 ENDPROFILE(fast_rgb_points
)
693 /* Return pointer to accerated points function */
694 extern points_func
choose_points_function( GLcontext
* ctx
)
697 if (ctx
->Point
.Size
==1.0 && !ctx
->Point
.SmoothFlag
&& ctx
->_RasterMask
==0
698 && !ctx
->Texture
.Enabled
&& ctx
->Visual
->RGBAflag
) {
699 ENDPROFILE(choose_points_function
)
700 return fast_rgb_points
;
703 ENDPROFILE(choose_points_function
)
710 /* Draw a line using the color specified by Current->gl_ctx->VB->Color[pv] */
711 static void fast_flat_rgb_line( GLcontext
* ctx
, GLuint v0
, GLuint v1
, GLuint pv
)
720 if (Current
->gl_ctx
->VB
->MonoColor
) {
721 pixel
= Current
->pixel
; /* use current color */
724 pixel
= RGB(Current
->gl_ctx
->VB
->Color
[pv
][0]*255.0, Current
->gl_ctx
->VB
->Color
[pv
][1]*255.0, Current
->gl_ctx
->VB
->Color
[pv
][2]*255.0);
727 x0
= (int) Current
->gl_ctx
->VB
->Win
[v0
][0];
728 y0
= FLIP( (int) Current
->gl_ctx
->VB
->Win
[v0
][1] );
729 x1
= (int) Current
->gl_ctx
->VB
->Win
[v1
][0];
730 y1
= FLIP( (int) Current
->gl_ctx
->VB
->Win
[v1
][1] );
735 Pen
=CreatePen(PS_SOLID
,1,pixel
);
736 Old_Pen
=SelectObject(DC
,Pen
);
737 MoveToEx(DC
,x0
,y0
,NULL
);
739 SelectObject(DC
,Old_Pen
);
745 ENDPROFILE(fast_flat_rgb_line
)
750 /* Return pointer to accerated line function */
751 static line_func
choose_line_function( GLcontext
* ctx
)
754 if (ctx
->Line
.Width
==1.0 && !ctx
->Line
.SmoothFlag
&& !ctx
->Line
.StippleFlag
755 && ctx
->Light
.ShadeModel
==GL_FLAT
&& ctx
->_RasterMask
==0
756 && !ctx
->Texture
.Enabled
&& Current
->rgb_flag
) {
757 ENDPROFILE(choose_line_function
)
758 return fast_flat_rgb_line
;
761 ENDPROFILE(choose_line_function
)
767 /**********************************************************************/
768 /***** Span-based pixel drawing *****/
769 /**********************************************************************/
772 /* Write a horizontal span of 32-bit color-index pixels with a boolean mask. */
773 static void write_ci32_span( const GLcontext
* ctx
,
774 GLuint n
, GLint x
, GLint y
,
775 const GLuint index
[],
776 const GLubyte mask
[] )
780 PBYTE Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
781 assert(Current
->rgb_flag
==GL_FALSE
);
785 ENDPROFILE(write_ci32_span
)
789 /* Write a horizontal span of 8-bit color-index pixels with a boolean mask. */
790 static void write_ci8_span( const GLcontext
* ctx
,
791 GLuint n
, GLint x
, GLint y
,
792 const GLubyte index
[],
793 const GLubyte mask
[] )
797 PBYTE Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
798 assert(Current
->rgb_flag
==GL_FALSE
);
802 ENDPROFILE(write_ci8_span
)
808 * Write a horizontal span of pixels with a boolean mask. The current
809 * color index is used for all pixels.
811 static void write_mono_ci_span(const GLcontext
* ctx
,
812 GLuint n
,GLint x
,GLint y
,
813 const GLubyte mask
[])
817 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
818 assert(Current
->rgb_flag
==GL_FALSE
);
821 Mem
[i
]=Current
->pixel
;
822 ENDPROFILE(write_mono_ci_span
)
826 * To improve the performance of this routine, frob the data into an actual
827 * scanline and call bitblt on the complete scan line instead of SetPixel.
830 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
831 static void write_rgba_span( const GLcontext
* ctx
, GLuint n
, GLint x
, GLint y
,
832 const GLubyte rgba
[][4], const GLubyte mask
[] )
837 if (pwc
->rgb_flag
==GL_TRUE
)
845 wmSetPixel(pwc
, y
, x
+ i
, rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
849 wmSetPixel(pwc
, y
, x
+ i
, rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
] );
856 BYTE
*Mem
=Current
->ScreenMem
+y
*Current
->ScanWidth
+x
;
861 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]));
865 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]));
868 ENDPROFILE(write_rgba_span
)
872 /* Write a horizontal span of RGB color pixels with a boolean mask. */
873 static void write_rgb_span( const GLcontext
* ctx
,
874 GLuint n
, GLint x
, GLint y
,
875 const GLubyte rgb
[][3], const GLubyte mask
[] )
880 if (pwc
->rgb_flag
==GL_TRUE
)
888 wmSetPixel(pwc
, y
, x
+ i
, rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]);
892 wmSetPixel(pwc
, y
, x
+ i
, rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
] );
899 BYTE
*Mem
=Current
->ScreenMem
+y
*Current
->ScanWidth
+x
;
904 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]));
908 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]));
911 ENDPROFILE(write_rgb_span
)
916 * Write a horizontal span of pixels with a boolean mask. The current color
917 * is used for all pixels.
919 static void write_mono_rgba_span( const GLcontext
* ctx
,
920 GLuint n
, GLint x
, GLint y
,
921 const GLubyte mask
[])
927 assert(Current
->rgb_flag
==GL_TRUE
);
929 if(Current
->rgb_flag
==GL_TRUE
){
933 wmSetPixel(pwc
,y
,x
+i
,GetRValue(Current
->pixel
), GetGValue(Current
->pixel
), GetBValue(Current
->pixel
));
938 SetPixel(DC
, y
, x
+i
, Current
->pixel
);
941 ENDPROFILE(write_mono_rgba_span
)
946 /**********************************************************************/
947 /***** Array-based pixel drawing *****/
948 /**********************************************************************/
951 /* Write an array of 32-bit index pixels with a boolean mask. */
952 static void write_ci32_pixels( const GLcontext
* ctx
,
953 GLuint n
, const GLint x
[], const GLint y
[],
954 const GLuint index
[], const GLubyte mask
[] )
958 assert(Current
->rgb_flag
==GL_FALSE
);
959 for (i
=0; i
<n
; i
++) {
961 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
];
965 ENDPROFILE(write_ci32_pixels
)
971 * Write an array of pixels with a boolean mask. The current color
972 * index is used for all pixels.
974 static void write_mono_ci_pixels( const GLcontext
* ctx
,
976 const GLint x
[], const GLint y
[],
977 const GLubyte mask
[] )
981 assert(Current
->rgb_flag
==GL_FALSE
);
982 for (i
=0; i
<n
; i
++) {
984 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
];
985 *Mem
= Current
->pixel
;
988 ENDPROFILE(write_mono_ci_pixels
)
993 /* Write an array of RGBA pixels with a boolean mask. */
994 static void write_rgba_pixels( const GLcontext
* ctx
,
995 GLuint n
, const GLint x
[], const GLint y
[],
996 const GLubyte rgba
[][4], const GLubyte mask
[] )
1002 assert(Current
->rgb_flag
==GL_TRUE
);
1005 wmSetPixel(pwc
, FLIP(y
[i
]),x
[i
],rgba
[i
][RCOMP
],rgba
[i
][GCOMP
],rgba
[i
][BCOMP
]);
1007 ENDPROFILE(write_rgba_pixels
)
1013 * Write an array of pixels with a boolean mask. The current color
1014 * is used for all pixels.
1016 static void write_mono_rgba_pixels( const GLcontext
* ctx
,
1018 const GLint x
[], const GLint y
[],
1019 const GLubyte mask
[] )
1025 assert(Current
->rgb_flag
==GL_TRUE
);
1028 wmSetPixel(pwc
, FLIP(y
[i
]),x
[i
],GetRValue(Current
->pixel
),
1029 GetGValue(Current
->pixel
), GetBValue(Current
->pixel
));
1031 ENDPROFILE(write_mono_rgba_pixels
)
1036 /**********************************************************************/
1037 /***** Read spans/arrays of pixels *****/
1038 /**********************************************************************/
1041 /* Read a horizontal span of color-index pixels. */
1042 static void read_ci32_span( const GLcontext
* ctx
, GLuint n
, GLint x
, GLint y
,
1047 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
1048 assert(Current
->rgb_flag
==GL_FALSE
);
1051 ENDPROFILE(read_ci32_span
)
1057 /* Read an array of color index pixels. */
1058 static void read_ci32_pixels( const GLcontext
* ctx
,
1059 GLuint n
, const GLint x
[], const GLint y
[],
1060 GLuint indx
[], const GLubyte mask
[] )
1064 assert(Current
->rgb_flag
==GL_FALSE
);
1065 for (i
=0; i
<n
; i
++) {
1067 indx
[i
]=*(Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
]);
1070 ENDPROFILE(read_ci32_pixels
)
1075 /* Read a horizontal span of color pixels. */
1076 static void read_rgba_span( const GLcontext
* ctx
,
1077 GLuint n
, GLint x
, GLint y
,
1084 assert(Current
->rgb_flag
==GL_TRUE
);
1086 for (i
=0; i
<n
; i
++) {
1087 Color
=GetPixel(DC
,x
+i
,y
);
1088 rgba
[i
][RCOMP
] = GetRValue(Color
);
1089 rgba
[i
][GCOMP
] = GetGValue(Color
);
1090 rgba
[i
][BCOMP
] = GetBValue(Color
);
1091 rgba
[i
][ACOMP
] = 255;
1094 // Brian P. Has mentioned to comment this out.
1095 // memset(alpha,0,n*sizeof(GLubyte));
1096 ENDPROFILE(read_rgba_span
)
1100 /* Read an array of color pixels. */
1101 static void read_rgba_pixels( const GLcontext
* ctx
,
1102 GLuint n
, const GLint x
[], const GLint y
[],
1103 GLubyte rgba
[][4], const GLubyte mask
[] )
1109 assert(Current
->rgb_flag
==GL_TRUE
);
1110 for (i
=0; i
<n
; i
++) {
1112 Color
=GetPixel(DC
,x
[i
],FLIP(y
[i
]));
1113 rgba
[i
][RCOMP
] = GetRValue(Color
);
1114 rgba
[i
][GCOMP
] = GetGValue(Color
);
1115 rgba
[i
][BCOMP
] = GetBValue(Color
);
1116 rgba
[i
][ACOMP
] = 255;
1120 // Brian P. has mentioned to comment this out.
1121 // memset(alpha,0,n*sizeof(GLint));
1122 ENDPROFILE(read_rgba_pixels
)
1127 /**********************************************************************/
1128 /**********************************************************************/
1131 static const char *renderer_string(void)
1138 void setup_DD_pointers( GLcontext
* ctx
)
1140 ctx
->Driver
.RendererString
= renderer_string
;
1141 ctx
->Driver
.UpdateState
= setup_DD_pointers
;
1142 ctx
->Driver
.GetBufferSize
= buffer_size
;
1143 ctx
->Driver
.Finish
= finish
;
1144 ctx
->Driver
.Flush
= flush
;
1146 ctx
->Driver
.ClearIndex
= clear_index
;
1147 ctx
->Driver
.ClearColor
= clear_color
;
1148 ctx
->Driver
.Clear
= clear
;
1150 ctx
->Driver
.Index
= set_index
;
1151 ctx
->Driver
.Color
= set_color
;
1152 ctx
->Driver
.IndexMask
= index_mask
;
1153 ctx
->Driver
.ColorMask
= color_mask
;
1155 ctx
->Driver
.LogicOp
= logicop
;
1156 ctx
->Driver
.Dither
= dither
;
1158 ctx
->Driver
.SetBuffer
= set_buffer
;
1159 ctx
->Driver
.GetBufferSize
= buffer_size
;
1161 ctx
->Driver
.PointsFunc
= choose_points_function(ctx
);
1162 ctx
->Driver
.LineFunc
= choose_line_function(ctx
);
1163 ctx
->Driver
.TriangleFunc
= choose_triangle_function( ctx
);
1165 /* Pixel/span writing functions: */
1166 ctx
->Driver
.WriteRGBASpan
= write_rgba_span
;
1167 ctx
->Driver
.WriteRGBSpan
= write_rgb_span
;
1168 ctx
->Driver
.WriteMonoRGBASpan
= write_mono_rgba_span
;
1169 ctx
->Driver
.WriteRGBAPixels
= write_rgba_pixels
;
1170 ctx
->Driver
.WriteMonoRGBAPixels
= write_mono_rgba_pixels
;
1171 ctx
->Driver
.WriteCI32Span
= write_ci32_span
;
1172 ctx
->Driver
.WriteCI8Span
= write_ci8_span
;
1173 ctx
->Driver
.WriteMonoCISpan
= write_mono_ci_span
;
1174 ctx
->Driver
.WriteCI32Pixels
= write_ci32_pixels
;
1175 ctx
->Driver
.WriteMonoCIPixels
= write_mono_ci_pixels
;
1177 ctx
->Driver
.ReadCI32Span
= read_ci32_span
;
1178 ctx
->Driver
.ReadRGBASpan
= read_rgba_span
;
1179 ctx
->Driver
.ReadCI32Pixels
= read_ci32_pixels
;
1180 ctx
->Driver
.ReadRGBAPixels
= read_rgba_pixels
;
1184 /**********************************************************************/
1185 /***** WMesa API Functions *****/
1186 /**********************************************************************/
1190 #define PAL_SIZE 256
1191 static void GetPalette(HPALETTE Pal
,RGBQUAD
*aRGB
)
1199 WORD NumberOfEntries
;
1200 PALETTEENTRY aEntries
[PAL_SIZE
];
1208 GetPaletteEntries(Pal
,0,PAL_SIZE
,Palette
.aEntries
);
1210 GetSystemPaletteEntries(hdc
,0,PAL_SIZE
,Palette
.aEntries
);
1211 if (GetSystemPaletteUse(hdc
) == SYSPAL_NOSTATIC
)
1213 for(i
= 0; i
<PAL_SIZE
; i
++)
1214 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1215 Palette
.aEntries
[255].peRed
= 255;
1216 Palette
.aEntries
[255].peGreen
= 255;
1217 Palette
.aEntries
[255].peBlue
= 255;
1218 Palette
.aEntries
[255].peFlags
= 0;
1219 Palette
.aEntries
[0].peRed
= 0;
1220 Palette
.aEntries
[0].peGreen
= 0;
1221 Palette
.aEntries
[0].peBlue
= 0;
1222 Palette
.aEntries
[0].peFlags
= 0;
1228 nStaticColors
= GetDeviceCaps(hdc
, NUMCOLORS
)/2;
1229 for (i
=0; i
<nStaticColors
; i
++)
1230 Palette
.aEntries
[i
].peFlags
= 0;
1231 nUsableColors
= PAL_SIZE
-nStaticColors
;
1232 for (; i
<nUsableColors
; i
++)
1233 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1234 for (; i
<PAL_SIZE
-nStaticColors
; i
++)
1235 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1236 for (i
=PAL_SIZE
-nStaticColors
; i
<PAL_SIZE
; i
++)
1237 Palette
.aEntries
[i
].peFlags
= 0;
1239 ReleaseDC(NULL
,hdc
);
1240 for (i
=0; i
<PAL_SIZE
; i
++)
1242 aRGB
[i
].rgbRed
=Palette
.aEntries
[i
].peRed
;
1243 aRGB
[i
].rgbGreen
=Palette
.aEntries
[i
].peGreen
;
1244 aRGB
[i
].rgbBlue
=Palette
.aEntries
[i
].peBlue
;
1245 aRGB
[i
].rgbReserved
=Palette
.aEntries
[i
].peFlags
;
1247 ENDPROFILE(GetPalette
)
1251 WMesaContext
WMesaCreateContext( HWND hWnd
,
1258 GLboolean true_color_flag
;
1259 c
= (struct wmesa_context
* ) calloc(1,sizeof(struct wmesa_context
));
1264 c
->hDC
= GetDC(hWnd
);
1265 true_color_flag
= GetDeviceCaps(c
->hDC
, BITSPIXEL
) > 8;
1267 if(true_color_flag
) c
->rgb_flag
= rgb_flag
= GL_TRUE
;
1272 if ((true_color_flag
==GL_FALSE
) && (rgb_flag
== GL_TRUE
)){
1273 c
->dither_flag
= GL_TRUE
;
1274 c
->hPalHalfTone
= WinGCreateHalftonePalette();
1277 c
->dither_flag
= GL_FALSE
;
1279 c
->dither_flag
= GL_FALSE
;
1283 if (rgb_flag
==GL_FALSE
)
1285 c
->rgb_flag
= GL_FALSE
;
1287 c
->db_flag
= db_flag
=GL_TRUE
; // WinG requires double buffering
1288 printf("Single buffer is not supported in color index mode, setting to double buffer.\n");
1292 c
->rgb_flag
= GL_TRUE
;
1295 GetClientRect(c
->Window
,&CR
);
1297 c
->height
=CR
.bottom
;
1301 /* Double buffered */
1303 // if (c->rgb_flag==GL_TRUE && c->dither_flag != GL_TRUE )
1305 wmCreateBackingStore(c
, c
->width
, c
->height
);
1312 /* Single Buffered */
1317 if (DDInit(c
,hWnd
) == GL_FALSE
) {
1324 c
->gl_visual
= gl_create_visual(rgb_flag
,
1325 GL_FALSE
, /* software alpha */
1326 db_flag
, /* db_flag */
1327 GL_FALSE
, /* stereo */
1328 16, /* depth_bits */
1329 8, /* stencil_bits */
1332 8,8,8,8 ); /* r, g, b, a bits */
1334 if (!c
->gl_visual
) {
1338 /* allocate a new Mesa context */
1339 c
->gl_ctx
= gl_create_context( c
->gl_visual
, NULL
, c
, GL_TRUE
);
1342 gl_destroy_visual( c
->gl_visual
);
1347 c
->gl_buffer
= gl_create_framebuffer( c
->gl_visual
);
1348 if (!c
->gl_buffer
) {
1349 gl_destroy_visual( c
->gl_visual
);
1350 gl_destroy_context( c
->gl_ctx
);
1355 c
->gl_ctx
->Driver
.UpdateState
= setup_DD_pointers
;
1357 // setup_DD_pointers(c->gl_ctx);
1362 void WMesaDestroyContext( void )
1364 WMesaContext c
= Current
;
1365 ReleaseDC(c
->Window
,c
->hDC
);
1367 if(c
->hPalHalfTone
!= NULL
)
1368 DeleteObject(c
->hPalHalfTone
);
1369 gl_destroy_visual( c
->gl_visual
);
1370 gl_destroy_framebuffer( c
->gl_buffer
);
1371 gl_destroy_context( c
->gl_ctx
);
1377 wmDeleteBackingStore(c
);
1380 //Following code is added to enable parallel render
1381 // Parallel render only work in double buffer mode
1382 #if !defined(NO_PARALLEL)
1384 PRDestroyRenderBuffer();
1389 void WMesaMakeCurrent( WMesaContext c
)
1397 // A little optimization
1398 // If it already is current,
1399 // don't set it again
1404 //gl_set_context( c->gl_ctx );
1405 gl_make_current(c
->gl_ctx
, c
->gl_buffer
);
1406 setup_DD_pointers(c
->gl_ctx
);
1408 if (Current
->gl_ctx
->Viewport
.Width
==0) {
1409 /* initialize viewport to window size */
1410 gl_Viewport( Current
->gl_ctx
,
1411 0, 0, Current
->width
, Current
->height
);
1413 if ((c
->cColorBits
<= 8 ) && (c
->rgb_flag
== GL_TRUE
)){
1414 WMesaPaletteChange(c
->hPalHalfTone
);
1418 void WMesaSwapBuffers( void )
1420 HDC DC
= Current
->hDC
;
1421 if (Current
->db_flag
)
1425 void WMesaPaletteChange(HPALETTE Pal
)
1428 LPPALETTEENTRY pPal
;
1429 if (Current
&& (Current
->rgb_flag
==GL_FALSE
|| Current
->dither_flag
== GL_TRUE
))
1431 pPal
= (PALETTEENTRY
*)malloc( 256 * sizeof(PALETTEENTRY
));
1433 // GetPaletteEntries( Pal, 0, 256, pPal );
1434 GetPalette( Pal
, pPal
);
1436 Current
->lpDD
->lpVtbl
->CreatePalette(Current
->lpDD
,DDPCAPS_8BIT
,
1437 pPal
, &(Current
->lpDDPal
), NULL
);
1438 if (Current
->lpDDPal
)
1439 Current
->lpDDSPrimary
->lpVtbl
->SetPalette(Current
->lpDDSPrimary
,Current
->lpDDPal
);
1441 vRet
= SetDIBColorTable(Current
->dib
.hDC
,0,256,pPal
);
1448 static unsigned char threeto8
[8] = {
1449 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
1452 static unsigned char twoto8
[4] = {
1456 static unsigned char oneto8
[2] = {
1460 static unsigned char componentFromIndex(UCHAR i
, UINT nbits
, UINT shift
)
1477 return threeto8
[val
];
1484 void wmCreatePalette( PWMC pwdc
)
1486 /* Create a compressed and re-expanded 3:3:2 palette */
1489 BYTE rb
, rs
, gb
, gs
, bb
, bs
;
1491 pwdc
->nColors
= 0x100;
1493 pPal
= (PLOGPALETTE
)malloc(sizeof(LOGPALETTE
) + pwdc
->nColors
* sizeof(PALETTEENTRY
));
1494 memset( pPal
, 0, sizeof(LOGPALETTE
) + pwdc
->nColors
* sizeof(PALETTEENTRY
) );
1496 pPal
->palVersion
= 0x300;
1505 if (pwdc
->db_flag
) {
1507 /* Need to make two palettes: one for the screen DC and one for the DIB. */
1508 pPal
->palNumEntries
= pwdc
->nColors
;
1509 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1510 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1511 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1512 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1513 pPal
->palPalEntry
[i
].peFlags
= 0;
1515 pwdc
->hGLPalette
= CreatePalette( pPal
);
1516 pwdc
->hPalette
= CreatePalette( pPal
);
1520 pPal
->palNumEntries
= pwdc
->nColors
;
1521 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1522 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1523 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1524 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1525 pPal
->palPalEntry
[i
].peFlags
= 0;
1527 pwdc
->hGLPalette
= CreatePalette( pPal
);
1534 void wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1536 if(Current
->db_flag
){
1537 LPBYTE lpb
= pwc
->pbPixels
;
1540 UINT nBypp
= pwc
->cColorBits
/ 8;
1541 UINT nOffset
= iPixel
% nBypp
;
1543 // Move the pixel buffer pointer to the scanline that we
1546 // pwc->dib.fFlushed = FALSE;
1548 lpb
+= pwc
->ScanWidth
* iScanLine
;
1549 // Now move to the desired pixel
1550 lpb
+= iPixel
* nBypp
;
1551 lpb
= PIXELADDR(iPixel
, iScanLine
);
1552 lpdw
= (LPDWORD
)lpb
;
1556 if(pwc
->dither_flag
)
1557 *lpb
= DITHER_RGB_2_8BIT(r
,g
,b
,iScanLine
,iPixel
);
1562 *lpw
= BGR16(r
,g
,b
);
1563 else if (nBypp
== 3){
1564 *lpdw
= BGR24(r
,g
,b
);
1566 else if (nBypp
== 4)
1567 *lpdw
= BGR32(r
,g
,b
);
1571 SetPixel(DC
, iPixel
, iScanLine
, RGB(r
,g
,b
));
1576 void wmCreateDIBSection( HDC hDC
,
1577 PWMC pwc
, // handle of device context
1578 CONST BITMAPINFO
*pbmi
, // address of structure containing bitmap size, format, and color data
1579 UINT iUsage
// color data type indicator: RGB values or palette indices
1584 UINT nBypp
= pwc
->cColorBits
/ 8;
1587 dwScanWidth
= (((pwc
->ScanWidth
* nBypp
)+ 3) & ~3);
1589 pwc
->ScanWidth
=pwc
->pitch
= dwScanWidth
;
1592 pwc
->ScanWidth
= 2* pwc
->pitch
;
1594 dwSize
= sizeof(BITMAPINFO
) + (dwScanWidth
* pwc
->height
);
1596 pwc
->dib
.hFileMap
= CreateFileMapping((HANDLE
)PAGE_FILE
,
1598 PAGE_READWRITE
| SEC_COMMIT
,
1603 if (!pwc
->dib
.hFileMap
)
1606 pwc
->dib
.base
= MapViewOfFile(pwc
->dib
.hFileMap
,
1607 FILE_MAP_ALL_ACCESS
,
1613 CloseHandle(pwc
->dib
.hFileMap
);
1617 // pwc->pbPixels = pwc->addrOffScreen = ((LPBYTE)pwc->dib.base) + sizeof(BITMAPINFO);
1619 // pwc->dib.hDC = CreateCompatibleDC(hDC);
1621 CopyMemory(pwc
->dib
.base
, pbmi
, sizeof(BITMAPINFO
));
1623 hic
= CreateIC("display", NULL
, NULL
, NULL
);
1624 pwc
->dib
.hDC
= CreateCompatibleDC(hic
);
1627 /* pwc->hbmDIB = CreateDIBitmap(hic,
1628 &(pwc->bmi.bmiHeader),
1634 pwc
->hbmDIB
= CreateDIBSection(hic
,
1636 (iUsage
? DIB_PAL_COLORS
: DIB_RGB_COLORS
),
1641 pwc->hbmDIB = CreateDIBSection(hic,
1648 pwc
->ScreenMem
= pwc
->addrOffScreen
= pwc
->pbPixels
;
1649 pwc
->hOldBitmap
= SelectObject(pwc
->dib
.hDC
, pwc
->hbmDIB
);
1658 // Blit memory DC to screen DC
1660 BOOL
wmFlush(PWMC pwc
)
1668 // Now search through the torus frames and mark used colors
1671 if (pwc
->lpDDSOffScreen
== NULL
)
1672 if(DDCreateOffScreen(pwc
) == GL_FALSE
)
1675 pwc
->lpDDSOffScreen
->lpVtbl
->Unlock(pwc
->lpDDSOffScreen
, NULL
);
1679 ddrval
= pwc
->lpDDSPrimary
->lpVtbl
->Blt( pwc
->lpDDSPrimary
,
1680 &(pwc
->rectSurface
), pwc
->lpDDSOffScreen
, &(pwc
->rectOffScreen
), 0, NULL
);
1682 if( ddrval
== DD_OK
)
1686 if( ddrval
== DDERR_SURFACELOST
)
1688 if(!DDRestoreAll(pwc
))
1693 if( ddrval
!= DDERR_WASSTILLDRAWING
)
1699 while (pwc
->lpDDSOffScreen
->lpVtbl
->Lock(pwc
->lpDDSOffScreen
,
1700 NULL
, &(pwc
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
)
1704 dwErr
= GetLastError();
1706 bRet
= BitBlt(pwc
->hDC
, 0, 0, pwc
->width
, pwc
->height
,
1707 pwc
->dib
.hDC
, 0, 0, SRCCOPY
);
1715 // The following code is added by Li Wei to enable stereo display
1717 #if !defined(NO_STEREO)
1719 void WMesaShowStereo(GLuint list
)
1722 GLbitfield mask
= GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
;
1725 // Must use double Buffer
1726 if( ! Current
-> db_flag
)
1730 glGetIntegerv(GL_MATRIX_MODE
,&matrix_mode
);
1732 // glPushMatrix(); //****
1733 WMesaViewport(Current
->gl_ctx
,0,Current
->height
/2,Current
->width
,Current
->height
/2);
1734 // Current->gl_ctx->NewState = 0;
1736 // glViewport(0,0,Current->width,Current->height/2);
1737 if(matrix_mode
!=GL_MODELVIEW
)
1738 glMatrixMode(GL_MODELVIEW
);
1740 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1742 gluLookAt(viewDistance
/2,0.0,0.0 ,
1743 viewDistance
/2,0.0,-1.0,
1745 // glTranslatef(viewDistance/2.0,0.,0.);
1746 glMultMatrixf( cm
);
1748 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
;
1753 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1755 gluLookAt(-viewDistance
/2,0.0,0.0 ,
1756 -viewDistance
/2,0.0,-1.0,
1758 // glTranslatef(-viewDistance/2.0,0.,0.);
1761 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
+ Current
->pitch
;
1763 if(matrix_mode
!=GL_MODELVIEW
)
1764 glMatrixMode(matrix_mode
);
1769 WMesaViewport(Current
->gl_ctx
,0,0,Current
->width
,Current
->height
);
1770 // Current->gl_ctx->NewState = 0;
1775 void toggleStereoMode()
1777 if(!Current
->db_flag
)
1781 if(stereoBuffer
==GL_FALSE
)
1782 #if !defined(NO_PARALLEL)
1786 Current
->ScanWidth
= Current
->pitch
*2;
1791 #if !defined(NO_PARALLEL)
1794 Current
->ScanWidth
= Current
->pitch
;
1795 Current
->pbPixels
= Current
->addrOffScreen
;
1799 /* if in stereo mode, the following function is called */
1800 void glShowStereo(GLuint list
)
1802 WMesaShowStereo(list
);
1805 #endif // End if NO_STEREO not defined
1807 #if !defined(NO_PARALLEL)
1809 void toggleParallelMode(void)
1812 parallelFlag
= GL_TRUE
;
1813 if(parallelMachine
==GL_FALSE
){
1814 PRCreateRenderBuffer( Current
->rgb_flag
? GL_RGBA
:GL_COLOR_INDEX
,
1815 Current
->cColorBits
/8,
1816 Current
->width
,Current
->height
,
1818 Current
->rgb_flag
? Current
->pbPixels
: Current
->ScreenMem
);
1819 parallelMachine
= GL_TRUE
;
1823 parallelFlag
= GL_FALSE
;
1824 if(parallelMachine
==GL_TRUE
){
1825 PRDestroyRenderBuffer();
1826 parallelMachine
=GL_FALSE
;
1827 ReadyForNextFrame
= GL_TRUE
;
1830 /***********************************************
1831 // Seems something wrong!!!!
1832 ************************************************/
1834 WMesaMakeCurrent(Current
);
1835 #if !defined(NO_STEREO)
1836 stereo_flag
= GL_FALSE
;
1841 void PRShowRenderResult(void)
1844 if(!glImageRendered())
1853 #endif //End if NO_PARALLEL not defined
1857 BYTE
DITHER_RGB_2_8BIT( int red
, int green
, int blue
, int pixel
, int scanline
)
1859 char unsigned redtemp
, greentemp
, bluetemp
, paletteindex
;
1861 //*** now, look up each value in the halftone matrix
1862 //*** using an 8x8 ordered dither.
1863 redtemp
= aDividedBy51
[red
]
1864 + (aModulo51
[red
] > aHalftone8x8
[(pixel
%8)*8
1866 greentemp
= aDividedBy51
[(char unsigned)green
]
1867 + (aModulo51
[green
] > aHalftone8x8
[
1868 (pixel
%8)*8 + scanline
%8]);
1869 bluetemp
= aDividedBy51
[(char unsigned)blue
]
1870 + (aModulo51
[blue
] > aHalftone8x8
[
1871 (pixel
%8)*8 +scanline
%8]);
1873 //*** recombine the halftoned rgb values into a palette index
1875 redtemp
+ aTimes6
[greentemp
] + aTimes36
[bluetemp
];
1877 //*** and translate through the wing halftone palette
1878 //*** translation vector to give the correct value.
1879 return aWinGHalftoneTranslation
[paletteindex
];
1886 * restore all lost objects
1888 static HRESULT
DDRestoreAll( WMesaContext wc
)
1892 ddrval
= wc
->lpDDSPrimary
->lpVtbl
->Restore(wc
->lpDDSPrimary
);
1893 if( ddrval
== DD_OK
)
1895 ddrval
= wc
->lpDDSOffScreen
->lpVtbl
->Restore(wc
->lpDDSOffScreen
);
1903 * This function is called if the initialization function fails
1905 static BOOL
initFail( HWND hwnd
, WMesaContext wc
)
1908 MessageBox( hwnd
, "DirectDraw Init FAILED", "", MB_OK
);
1914 static void DDDeleteOffScreen(WMesaContext wc
)
1916 if( wc
->lpDDSOffScreen
!= NULL
)
1918 wc
->lpDDSOffScreen
->lpVtbl
->Unlock(wc
->lpDDSOffScreen
,NULL
);
1919 wc
->lpDDSOffScreen
->lpVtbl
->Release(wc
->lpDDSOffScreen
);
1920 wc
->lpDDSOffScreen
= NULL
;
1925 static void DDFreePrimarySurface(WMesaContext wc
)
1927 if( wc
->lpDDSPrimary
!= NULL
)
1929 if(wc
->db_flag
== GL_FALSE
)
1930 wc
->lpDDSPrimary
->lpVtbl
->ReleaseDC(wc
->lpDDSPrimary
, wc
->hDC
);
1931 wc
->lpDDSPrimary
->lpVtbl
->Release(wc
->lpDDSPrimary
);
1932 wc
->lpDDSPrimary
= NULL
;
1936 static BOOL
DDCreatePrimarySurface(WMesaContext wc
)
1940 wc
->ddsd
.dwSize
= sizeof( wc
->ddsd
);
1941 wc
->ddsd
.dwFlags
= DDSD_CAPS
;
1942 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
1944 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
,&(wc
->ddsd
), &(wc
->lpDDSPrimary
), NULL
);
1945 if( ddrval
!= DD_OK
)
1947 return initFail(wc
->hwnd
, wc
);
1949 if(wc
->db_flag
== GL_FALSE
)
1950 wc
->lpDDSPrimary
->lpVtbl
->GetDC(wc
->lpDDSPrimary
, wc
->hDC
);
1954 static BOOL
DDCreateOffScreen(WMesaContext wc
)
1958 if(wc
->lpDD
== NULL
)
1960 GetClientRect( wc
->hwnd
, &(wc
->rectOffScreen
) );
1961 wc
->ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1962 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
1963 wc
->ddsd
.dwHeight
= wc
->rectOffScreen
.bottom
- wc
->rectOffScreen
.top
;
1964 wc
->ddsd
.dwWidth
= wc
->rectOffScreen
.right
- wc
->rectOffScreen
.left
;
1966 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
, &(wc
->ddsd
), &(wc
->lpDDSOffScreen
), NULL
);
1967 if( ddrval
!= DD_OK
)
1972 while (wc
->lpDDSOffScreen
->lpVtbl
->Lock(wc
->lpDDSOffScreen
,NULL
, &(wc
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
)
1974 // while ((ddrval = wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, &(wc->ddsd), DDLOCK_SURFACEMEMORYPTR , NULL)) != DD_OK)
1976 if(wc
->ddsd
.lpSurface
==NULL
)
1977 return initFail(wc
->hwnd
, wc
);
1979 wc
->ScreenMem
= wc
->pbPixels
= wc
->addrOffScreen
= (PBYTE
)(wc
->ddsd
.lpSurface
);
1980 wc
->ScanWidth
= wc
->pitch
= wc
->ddsd
.lPitch
;
1982 wc
->ScanWidth
= wc
->ddsd
.lPitch
*2;
1984 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
1986 ClientToScreen( wc
->hwnd
, &pt
);
1987 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
1988 wmSetPixelFormat(wc
, wc
->hDC
);
1993 * doInit - do work required for every instance of the application:
1994 * create the window, initialize data
1996 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
)
2001 LPDIRECTDRAW lpDD
; // DirectDraw object
2002 LPDIRECTDRAW2 lpDD2
;
2005 wc
->fullScreen
= displayOptions
.fullScreen
;
2006 wc
->gMode
= displayOptions
.mode
;
2008 stereo_flag
= displayOptions
.stereo
;
2009 if(wc
->db_flag
!= GL_TRUE
)
2010 stereo_flag
= GL_FALSE
;
2012 * create the main DirectDraw object
2014 ddrval
= DirectDrawCreate( NULL
, &(wc
->lpDD
), NULL
);
2015 if( ddrval
!= DD_OK
)
2017 return initFail(hwnd
,wc
);
2020 // Get exclusive mode if requested
2023 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2027 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
, DDSCL_NORMAL
);
2029 if( ddrval
!= DD_OK
)
2031 return initFail(hwnd
, wc
);
2035 /* ddrval = wc->lpDD->lpVtbl->QueryInterface(wc->lpDD, IID_IDirectDraw2,
2036 (LPVOID *)((wc->lpDD2)));
2040 return initFail(hwnd
, wc
);
2043 //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
2044 // wc->lpDD2->lpVtbl->GetMonitorFrequency(wc->lpDD, &dwFrequency);
2047 case 1: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 640, 480, displayOptions
.bpp
); break;
2048 case 2: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 800, 600, displayOptions
.bpp
); break;
2049 case 3: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1024, 768, displayOptions
.bpp
); break;
2050 case 4: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1152, 864, displayOptions
.bpp
); break;
2051 case 5: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1280, 1024, displayOptions
.bpp
); break;
2054 if( ddrval
!= DD_OK
)
2056 printf("Can't modify display mode, current mode used\n");
2057 // return initFail(hwnd , wc);
2059 //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
2061 case DDERR_INVALIDOBJECT
:
2063 case DDERR_INVALIDPARAMS
:
2065 case DDERR_UNSUPPORTEDMODE
:
2069 if(DDCreatePrimarySurface(wc
) == GL_FALSE
)
2070 return initFail(hwnd
, wc
);
2073 return DDCreateOffScreen(wc
);
2076 static void DDFree( WMesaContext wc
)
2078 if( wc
->lpDD
!= NULL
)
2080 DDFreePrimarySurface(wc
);
2081 DDDeleteOffScreen(wc
);
2082 wc
->lpDD
->lpVtbl
->Release(wc
->lpDD
);
2085 // Clean up the screen on exit
2086 RedrawWindow( NULL
, NULL
, NULL
, RDW_INVALIDATE
| RDW_ERASE
|
2092 void WMesaMove(void)
2094 WMesaContext wc
= Current
;
2096 if (Current
!= NULL
){
2097 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2099 ClientToScreen( wc
->hwnd
, &pt
);
2100 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2107 * Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable
2110 #define PACK_8B8G8R( R, G, B ) ( ((B) << 16) | ((G) << 8) | (R) )
2113 /**********************************************************************/
2114 /*** Triangle rendering ***/
2115 /**********************************************************************/
2118 * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
2120 static void smooth_8A8B8G8R_z_triangle( GLcontext
*ctx
,
2121 GLuint v0
, GLuint v1
, GLuint v2
,
2124 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2126 #define INTERP_RGB 1
2127 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2128 #define PIXEL_TYPE GLuint
2129 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2130 #define BYTES_PER_ROW (wmesa->ScanWidth)
2131 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2133 GLint i, len = RIGHT-LEFT; \
2134 for (i=0;i<len;i++) { \
2135 GLdepth z = FixedToDepth(ffz); \
2136 if (z < zRow[i]) { \
2137 pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2138 FixedToInt(ffb) ); \
2141 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2146 #include "..\tritemp.h"
2148 #include "tritemp.h"
2154 * XImage, smooth, depth-buffered, PF_8R8G8B triangle.
2156 static void smooth_8R8G8B_z_triangle( GLcontext
*ctx
,
2157 GLuint v0
, GLuint v1
, GLuint v2
,
2160 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2162 #define INTERP_RGB 1
2163 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2164 #define PIXEL_TYPE GLuint
2165 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2166 #define BYTES_PER_ROW (wmesa->ScanWidth)
2167 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2169 GLint i, len = RIGHT-LEFT; \
2170 for (i=0;i<len;i++) { \
2171 GLdepth z = FixedToDepth(ffz); \
2172 if (z < zRow[i]) { \
2173 pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2174 FixedToInt(ffb) ); \
2177 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2182 #include "..\tritemp.h"
2184 #include "tritemp.h"
2191 * XImage, smooth, depth-buffered, PF_5R6G5B triangle.
2193 static void smooth_5R6G5B_z_triangle( GLcontext
*ctx
,
2194 GLuint v0
, GLuint v1
, GLuint v2
,
2197 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2199 #define INTERP_RGB 1
2200 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2201 #define PIXEL_TYPE GLushort
2202 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2203 #define BYTES_PER_ROW (wmesa->ScanWidth)
2204 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2206 GLint i, len = RIGHT-LEFT; \
2207 for (i=0;i<len;i++) { \
2208 GLdepth z = FixedToDepth(ffz); \
2209 if (z < zRow[i]) { \
2210 pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2211 FixedToInt(ffb) ); \
2214 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2219 #include "..\tritemp.h"
2221 #include "tritemp.h"
2226 * XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
2228 static void flat_8A8B8G8R_z_triangle( GLcontext
*ctx
, GLuint v0
,
2229 GLuint v1
, GLuint v2
, GLuint pv
)
2231 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2233 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2234 #define PIXEL_TYPE GLuint
2235 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2236 #define BYTES_PER_ROW (wmesa->ScanWidth)
2237 #define SETUP_CODE \
2238 unsigned long p = PACK_8B8G8R( VB->Color[pv][0], \
2239 VB->Color[pv][1], VB->Color[pv][2] );
2240 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2242 GLint i, len = RIGHT-LEFT; \
2243 for (i=0;i<len;i++) { \
2244 GLdepth z = FixedToDepth(ffz); \
2245 if (z < zRow[i]) { \
2253 #include "..\tritemp.h"
2255 #include "tritemp.h"
2261 * XImage, flat, depth-buffered, PF_8R8G8B triangle.
2263 static void flat_8R8G8B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2264 GLuint v2
, GLuint pv
)
2266 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2268 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2269 #define PIXEL_TYPE GLuint
2270 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2271 #define BYTES_PER_ROW (wmesa->ScanWidth)
2272 #define SETUP_CODE \
2273 unsigned long p = PACK_8R8G8B( VB->Color[pv][0], \
2274 VB->Color[pv][1], VB->Color[pv][2] );
2275 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2277 GLint i, len = RIGHT-LEFT; \
2278 for (i=0;i<len;i++) { \
2279 GLdepth z = FixedToDepth(ffz); \
2280 if (z < zRow[i]) { \
2288 #include "..\tritemp.h"
2290 #include "tritemp.h"
2296 * XImage, flat, depth-buffered, PF_5R6G5B triangle.
2298 static void flat_5R6G5B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2299 GLuint v2
, GLuint pv
)
2301 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2303 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2304 #define PIXEL_TYPE GLushort
2305 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2306 #define BYTES_PER_ROW (wmesa->ScanWidth)
2307 #define SETUP_CODE \
2308 unsigned long p = PACK_5R6G5B( VB->Color[pv][0], \
2309 VB->Color[pv][1], VB->Color[pv][2] );
2310 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2312 GLint i, len = RIGHT-LEFT; \
2313 for (i=0;i<len;i++) { \
2314 GLdepth z = FixedToDepth(ffz); \
2315 if (z < zRow[i]) { \
2323 #include "..\tritemp.h"
2325 #include "tritemp.h"
2331 * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
2333 static void smooth_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2334 GLuint v2
, GLuint pv
)
2336 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2337 #define INTERP_RGB 1
2338 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2339 #define PIXEL_TYPE GLuint
2340 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2341 #define BYTES_PER_ROW (wmesa->ScanWidth)
2342 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2345 PIXEL_TYPE *pixel = pRow; \
2346 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2347 *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2348 FixedToInt(ffb) ); \
2349 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2353 #include "..\tritemp.h"
2355 #include "tritemp.h"
2361 * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
2363 static void smooth_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2364 GLuint v2
, GLuint pv
)
2366 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2367 #define INTERP_RGB 1
2368 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2369 #define PIXEL_TYPE GLuint
2370 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2371 #define BYTES_PER_ROW (wmesa->ScanWidth)
2372 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2375 PIXEL_TYPE *pixel = pRow; \
2376 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2377 *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2378 FixedToInt(ffb) ); \
2379 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2383 #include "..\tritemp.h"
2385 #include "tritemp.h"
2391 * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
2393 static void smooth_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2394 GLuint v2
, GLuint pv
)
2396 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2397 #define INTERP_RGB 1
2398 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2399 #define PIXEL_TYPE GLushort
2400 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2401 #define BYTES_PER_ROW (wmesa->ScanWidth)
2402 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2405 PIXEL_TYPE *pixel = pRow; \
2406 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2407 *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2408 FixedToInt(ffb) ); \
2409 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2413 #include "..\tritemp.h"
2415 #include "tritemp.h"
2422 * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
2424 static void flat_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
,
2425 GLuint v1
, GLuint v2
, GLuint pv
)
2427 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2428 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2429 #define PIXEL_TYPE GLuint
2430 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2431 #define BYTES_PER_ROW (wmesa->ScanWidth)
2432 #define SETUP_CODE \
2433 unsigned long p = PACK_8B8G8R( VB->Color[pv][0], \
2434 VB->Color[pv][1], VB->Color[pv][2] );
2435 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2438 PIXEL_TYPE *pixel = pRow; \
2439 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2444 #include "..\tritemp.h"
2446 #include "tritemp.h"
2452 * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
2454 static void flat_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2455 GLuint v2
, GLuint pv
)
2457 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2458 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2459 #define PIXEL_TYPE GLuint
2460 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2461 #define BYTES_PER_ROW (wmesa->ScanWidth)
2462 #define SETUP_CODE \
2463 unsigned long p = PACK_8R8G8B( VB->Color[pv][0], \
2464 VB->Color[pv][1], VB->Color[pv][2] );
2465 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2468 PIXEL_TYPE *pixel = pRow; \
2469 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2474 #include "..\tritemp.h"
2476 #include "tritemp.h"
2482 * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
2484 static void flat_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2485 GLuint v2
, GLuint pv
)
2487 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2488 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2489 #define PIXEL_TYPE GLushort
2490 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2491 #define BYTES_PER_ROW (wmesa->ScanWidth)
2492 #define SETUP_CODE \
2493 unsigned long p = PACK_5R6G5B( VB->Color[pv][0], \
2494 VB->Color[pv][1], VB->Color[pv][2] );
2495 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2498 PIXEL_TYPE *pixel = pRow; \
2499 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2504 #include "..\tritemp.h"
2506 #include "tritemp.h"
2512 * XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
2515 static void smooth_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2516 GLuint v2
, GLuint pv
)
2518 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2520 #define INTERP_INDEX 1
2521 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2522 #define PIXEL_TYPE GLubyte
2523 #define BYTES_PER_ROW (wmesa->ScanWidth)
2524 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2526 GLint i, len = RIGHT-LEFT; \
2527 for (i=0;i<len;i++) { \
2528 GLdepth z = FixedToDepth(ffz); \
2529 if (z < zRow[i]) { \
2530 pRow[i] = FixedToInt(ffi); \
2539 #include "..\tritemp.h"
2541 #include "tritemp.h"
2547 * XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
2550 static void flat_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2551 GLuint v2
, GLuint pv
)
2553 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2555 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2556 #define PIXEL_TYPE GLubyte
2557 #define BYTES_PER_ROW (wmesa->ScanWidth)
2558 #define SETUP_CODE \
2559 GLuint index = VB->Index[pv]; \
2560 if (!VB->MonoColor) { \
2561 /* set the color index */ \
2562 (*ctx->Driver.Index)( ctx, index ); \
2564 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2566 GLint i, len = RIGHT-LEFT; \
2567 for (i=0;i<len;i++) { \
2568 GLdepth z = FixedToDepth(ffz); \
2569 if (z < zRow[i]) { \
2577 #include "..\tritemp.h"
2579 #include "tritemp.h"
2586 * XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2589 static void smooth_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2590 GLuint v2
, GLuint pv
)
2592 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2594 #define INTERP_INDEX 1
2595 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2596 #define PIXEL_TYPE GLubyte
2597 #define BYTES_PER_ROW (wmesa->ScanWidth)
2598 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2601 PIXEL_TYPE *pixel = pRow; \
2602 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2603 *pixel = FixedToInt(ffi); \
2608 #include "..\tritemp.h"
2610 #include "tritemp.h"
2616 * XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2618 static void flat_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2619 GLuint v2
, GLuint pv
)
2621 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2623 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2624 #define PIXEL_TYPE GLubyte
2625 #define BYTES_PER_ROW (wmesa->ScanWidth)
2626 #define SETUP_CODE \
2627 GLuint index = VB->Index[pv]; \
2628 if (!VB->MonoColor) { \
2629 /* set the color index */ \
2630 (*ctx->Driver.Index)( ctx, index ); \
2632 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2635 PIXEL_TYPE *pixel = pRow; \
2636 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2641 #include "..\tritemp.h"
2643 #include "tritemp.h"
2648 * XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
2650 static void smooth_DITHER8_z_triangle( GLcontext
*ctx
,
2651 GLuint v0
, GLuint v1
, GLuint v2
,
2654 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2655 DITHER_RGB_TO_8BIT_SETUP
2657 #define INTERP_RGB 1
2658 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2659 #define PIXEL_TYPE GLubyte
2660 #define BYTES_PER_ROW (wmesa->ScanWidth)
2661 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2663 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
2664 for (i=0;i<len;i++,xx++) { \
2665 GLdepth z = FixedToDepth(ffz); \
2666 if (z < zRow[i]) { \
2667 DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg), \
2668 FixedToInt(ffb), xx, yy); \
2669 pRow[i] = pixelDithered; \
2672 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2677 #include "..\tritemp.h"
2679 #include "tritemp.h"
2684 * XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
2686 static void flat_DITHER8_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2687 GLuint v2
, GLuint pv
)
2689 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2690 DITHER_RGB_TO_8BIT_SETUP
2692 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2693 #define PIXEL_TYPE GLubyte
2694 #define BYTES_PER_ROW (wmesa->ScanWidth)
2696 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2698 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
2699 for (i=0;i<len;i++,xx++) { \
2700 GLdepth z = FixedToDepth(ffz); \
2701 if (z < zRow[i]) { \
2702 DITHER_RGB_TO_8BIT( VB->Color[pv][0], \
2703 VB->Color[pv][1], VB->Color[pv][2], xx, yy); \
2704 pRow[i] = pixelDithered; \
2711 #include "..\tritemp.h"
2713 #include "tritemp.h"
2718 * XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
2720 static void smooth_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2721 GLuint v2
, GLuint pv
)
2723 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2724 DITHER_RGB_TO_8BIT_SETUP
2725 #define INTERP_RGB 1
2726 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2727 #define PIXEL_TYPE GLubyte
2728 #define BYTES_PER_ROW (wmesa->ScanWidth)
2729 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2731 GLint xx, yy = FLIP(Y); \
2732 PIXEL_TYPE *pixel = pRow; \
2733 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2734 DITHER_RGB_TO_8BIT( VB->Color[pv][0], VB->Color[pv][1], VB->Color[pv][2], xx, yy);\
2735 *pixel = pixelDithered; \
2736 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2740 #include "..\tritemp.h"
2742 #include "tritemp.h"
2747 * XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
2750 static void flat_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2751 GLuint v2
, GLuint pv
)
2753 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2754 DITHER_RGB_TO_8BIT_SETUP
2755 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2756 #define PIXEL_TYPE GLubyte
2757 #define BYTES_PER_ROW (wmesa->ScanWidth)
2759 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2761 GLint xx, yy = FLIP(Y); \
2762 PIXEL_TYPE *pixel = pRow; \
2763 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2764 DITHER_RGB_TO_8BIT( VB->Color[pv][0], \
2765 VB->Color[pv][1], VB->Color[pv][2], xx, yy); \
2766 *pixel = pixelDithered; \
2770 #include "..\tritemp.h"
2772 #include "tritemp.h"
2779 static triangle_func
choose_triangle_function( GLcontext
*ctx
)
2781 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2782 int depth
= wmesa
->cColorBits
;
2784 if (ctx
->Polygon
.SmoothFlag
) return NULL
;
2785 if (ctx
->Texture
.Enabled
) return NULL
;
2786 if (!wmesa
->db_flag
) return NULL
;
2787 /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {
2788 if ( ctx
->Light
.ShadeModel
==GL_SMOOTH
2789 && ctx
->_RasterMask
==DEPTH_BIT
2790 && ctx
->Depth
.Func
==GL_LESS
2791 && ctx
->Depth
.Mask
==GL_TRUE
2792 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2793 switch (wmesa
->pixelformat
) {
2795 return smooth_8A8B8G8R_z_triangle
;
2797 return smooth_8R8G8B_z_triangle
;
2799 return smooth_5R6G5B_z_triangle
;
2801 return smooth_DITHER8_z_triangle
;
2803 return smooth_ci_z_triangle
;
2808 if ( ctx
->Light
.ShadeModel
==GL_FLAT
2809 && ctx
->_RasterMask
==DEPTH_BIT
2810 && ctx
->Depth
.Func
==GL_LESS
2811 && ctx
->Depth
.Mask
==GL_TRUE
2812 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2813 switch (wmesa
->pixelformat
) {
2815 return flat_8A8B8G8R_z_triangle
;
2817 return flat_8R8G8B_z_triangle
;
2819 return flat_5R6G5B_z_triangle
;
2821 return flat_DITHER8_z_triangle
;
2823 return flat_ci_z_triangle
;
2828 if ( ctx
->_RasterMask
==0 /* no depth test */
2829 && ctx
->Light
.ShadeModel
==GL_SMOOTH
2830 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2831 switch (wmesa
->pixelformat
) {
2833 return smooth_8A8B8G8R_triangle
;
2835 return smooth_8R8G8B_triangle
;
2837 return smooth_5R6G5B_triangle
;
2839 return smooth_DITHER8_triangle
;
2841 return smooth_ci_triangle
;
2847 if ( ctx
->_RasterMask
==0 /* no depth test */
2848 && ctx
->Light
.ShadeModel
==GL_FLAT
2849 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2850 switch (wmesa
->pixelformat
) {
2852 return flat_8A8B8G8R_triangle
;
2854 return flat_8R8G8B_triangle
;
2856 return flat_5R6G5B_triangle
;
2858 return flat_DITHER8_triangle
;
2860 return flat_ci_triangle
;
2871 * Define a new viewport and reallocate auxillary buffers if the size of
2872 * the window (color buffer) has changed.
2874 void WMesaViewport( GLcontext
*ctx
,
2875 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2878 ctx
->Viewport
.X
= x
;
2879 ctx
->Viewport
.Width
= width
;
2880 ctx
->Viewport
.Y
= y
;
2881 ctx
->Viewport
.Height
= height
;
2883 /* compute scale and bias values */
2884 ctx
->Viewport
.Sx
= (GLfloat
) width
/ 2.0F
;
2885 ctx
->Viewport
.Tx
= ctx
->Viewport
.Sx
+ x
;
2886 ctx
->Viewport
.Sy
= (GLfloat
) height
/ 2.0F
;
2887 ctx
->Viewport
.Ty
= ctx
->Viewport
.Sy
+ y
;