1 /* $Id: wmesaBackup.c,v 1.1 1999/08/19 00:55:42 jtg 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.1 1999/08/19 00:55:42 jtg
28 * Revision 1.1 1999/01/03 03:08:57 brianp
31 * Revision 3.1 1998/06/11 01:42:08 brianp
32 * updated for Mesa 3.0 device driver interface (but not tested)
34 * Revision 3.0 1998/06/11 01:18:25 brianp
40 #define WMESA_STEREO_C
45 #include "mesa_extend.h"
56 #pragma warning ( disable : 4133 4761 )
59 // #include "profile.h"
69 #define CopyMemory memcpy
72 #if !defined(NO_STEREO)
78 #if !defined(NO_PARALLEL)
79 // #include "parallel.h"
82 struct DISPLAY_OPTIONS displayOptions
;
84 GLenum stereoCompile
= GL_FALSE
;
85 GLenum stereoShowing
= GL_FALSE
;
86 GLenum stereoBuffer
= GL_FALSE
;
87 #if !defined(NO_STEREO)
88 GLint displayList
= MAXIMUM_DISPLAY_LIST
;
90 GLint stereo_flag
= 0 ;
92 /* end of added code*/
94 static PWMC Current
= NULL
;
95 WMesaContext WC
= NULL
;
98 #define assert(ignore) ((void) 0)
100 void Mesa_Assert(void *Cond
,void *File
,unsigned Line
)
103 sprintf(Msg
,"%s %s %d",Cond
,File
,Line
);
104 MessageBox(NULL
,Msg
,"Assertion failed.",MB_OK
);
107 #define assert(e) if (!e) Mesa_Assert(#e,__FILE__,__LINE__);
110 //#define DD_GETDC (Current->hDC )
111 #define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
112 //#define DD_GETDC ((Current->db_flag) ? Current->hDCPrimary : Current->hDCBack )
115 //#define BEGINGDICALL if(Current->rgb_flag)wmFlushBits(Current);
117 //#define ENDGDICALL if(Current->rgb_flag)wmGetBits(Current);
120 //#define FLIP(Y) (Current->dither_flag? Y : Current->height-(Y)-1)
121 //#define FLIP(Y) (Current->height-(Y)-1)
123 #define FLIP(Y) (Current->db_flag? Y: Current->height-(Y)-1)
125 #define ENDPROFILE(PARA)
127 #define DITHER_RGB_TO_8BIT_SETUP \
128 GLubyte pixelDithered;
130 #define DITHER_RGB_TO_8BIT(red, green, blue, pixel, scanline) \
132 char unsigned redtemp, greentemp, bluetemp, paletteindex; \
133 redtemp = aDividedBy51[red] \
134 + (aModulo51[red] > aHalftone8x8[(pixel%8)*8 \
136 greentemp = aDividedBy51[(char unsigned)green] \
137 + (aModulo51[green] > aHalftone8x8[ \
138 (pixel%8)*8 + scanline%8]); \
139 bluetemp = aDividedBy51[(char unsigned)blue] \
140 + (aModulo51[blue] > aHalftone8x8[ \
141 (pixel%8)*8 +scanline%8]); \
142 paletteindex = redtemp + aTimes6[greentemp] + aTimes36[bluetemp]; \
143 pixelDithered = aWinGHalftoneTranslation[paletteindex]; \
148 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
);
149 static void DDFree( WMesaContext wc
);
150 static HRESULT
DDRestoreAll( WMesaContext wc
);
151 static void DDDeleteOffScreen(WMesaContext wc
);
152 static BOOL
DDCreateOffScreen(WMesaContext wc
);
155 static void FlushToFile(PWMC pwc
, PSTR szFile
);
157 BOOL
wmCreateBackingStore(PWMC pwc
, long lxSize
, long lySize
);
158 BOOL
wmDeleteBackingStore(PWMC pwc
);
159 void wmCreatePalette( PWMC pwdc
);
160 BOOL
wmSetDibColors(PWMC pwc
);
161 void wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
);
163 void wmCreateDIBSection(
165 PWMC pwc
, // handle of device context
166 CONST BITMAPINFO
*pbmi
, // address of structure containing bitmap size, format, and color data
167 UINT iUsage
// color data type indicator: RGB values or palette indices
171 void WMesaViewport( GLcontext
*ctx
,
172 GLint x
, GLint y
, GLsizei width
, GLsizei height
);
175 static triangle_func
choose_triangle_function( GLcontext
*ctx
);
178 static void wmSetPixelFormat( PWMC wc
, HDC hDC
)
181 wc
->cColorBits
= GetDeviceCaps(hDC
, BITSPIXEL
);
184 switch(wc
->cColorBits
){
186 if(wc
->dither_flag
!= GL_TRUE
)
187 wc
->pixelformat
= PF_INDEX8
;
189 wc
->pixelformat
= PF_DITHER8
;
192 wc
->pixelformat
= PF_5R6G5B
;
195 wc
->pixelformat
= PF_8R8G8B
;
198 wc
->pixelformat
= PF_BADFORMAT
;
203 // This function sets the color table of a DIB section
204 // to match that of the destination DC
206 BOOL
/*WINAPI*/ wmSetDibColors(PWMC pwc
)
208 RGBQUAD
*pColTab
, *pRGB
;
209 PALETTEENTRY
*pPal
, *pPE
;
214 /* Build a color table in the DIB that maps to the
215 selected palette in the DC.
217 nColors
= 1 << pwc
->cColorBits
;
218 pPal
= (PALETTEENTRY
*)malloc( nColors
* sizeof(PALETTEENTRY
));
219 memset( pPal
, 0, nColors
* sizeof(PALETTEENTRY
) );
220 GetPaletteEntries( pwc
->hGLPalette
, 0, nColors
, pPal
);
221 pColTab
= (RGBQUAD
*)malloc( nColors
* sizeof(RGBQUAD
));
222 for (i
= 0, pRGB
= pColTab
, pPE
= pPal
; i
< nColors
; i
++, pRGB
++, pPE
++) {
223 pRGB
->rgbRed
= pPE
->peRed
;
224 pRGB
->rgbGreen
= pPE
->peGreen
;
225 pRGB
->rgbBlue
= pPE
->peBlue
;
228 bRet
= SetDIBColorTable(pwc
->dib
.hDC
, 0, nColors
, pColTab
);
231 dwErr
= GetLastError();
241 // Free up the dib section that was created
243 BOOL
wmDeleteBackingStore(PWMC pwc
)
245 SelectObject(pwc
->dib
.hDC
, pwc
->hOldBitmap
);
246 DeleteDC(pwc
->dib
.hDC
);
247 DeleteObject(pwc
->hbmDIB
);
248 UnmapViewOfFile(pwc
->dib
.base
);
249 CloseHandle(pwc
->dib
.hFileMap
);
255 // This function creates the DIB section that is used for combined
258 BOOL
/*WINAPI*/ wmCreateBackingStore(PWMC pwc
, long lxSize
, long lySize
)
261 LPBITMAPINFO pbmi
= &(pwc
->bmi
);
264 pbmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
265 pbmi
->bmiHeader
.biWidth
= lxSize
;
266 pbmi
->bmiHeader
.biHeight
= -lySize
;
267 pbmi
->bmiHeader
.biPlanes
= 1;
269 pbmi
->bmiHeader
.biBitCount
= GetDeviceCaps(pwc
->hDC
, BITSPIXEL
);
271 pbmi
->bmiHeader
.biBitCount
= 8;
272 pbmi
->bmiHeader
.biCompression
= BI_RGB
;
273 pbmi
->bmiHeader
.biSizeImage
= 0;
274 pbmi
->bmiHeader
.biXPelsPerMeter
= 0;
275 pbmi
->bmiHeader
.biYPelsPerMeter
= 0;
276 pbmi
->bmiHeader
.biClrUsed
= 0;
277 pbmi
->bmiHeader
.biClrImportant
= 0;
279 iUsage
= (pbmi
->bmiHeader
.biBitCount
<= 8) ? DIB_PAL_COLORS
: DIB_RGB_COLORS
;
281 pwc
->cColorBits
= pbmi
->bmiHeader
.biBitCount
;
282 pwc
->ScanWidth
= pwc
->pitch
= lxSize
;
284 wmCreateDIBSection(hdc
, pwc
, pbmi
, iUsage
);
286 if ((iUsage
== DIB_PAL_COLORS
) && !(pwc
->hGLPalette
)) {
287 wmCreatePalette( pwc
);
288 wmSetDibColors( pwc
);
290 wmSetPixelFormat(pwc
, pwc
->hDC
);
297 // This function copies one scan line in a DIB section to another
299 BOOL GLWINAPI
wmSetDIBits(PWMC pwc
, UINT uiScanWidth
, UINT uiNumScans
, UINT nBypp
, UINT uiNewWidth
, LPBYTE pBits
)
302 LPBYTE pDest
= pwc
->pbPixels
;
303 DWORD dwNextScan
= uiScanWidth
;
304 DWORD dwNewScan
= uiNewWidth
;
305 DWORD dwScanWidth
= (uiScanWidth
* nBypp
);
308 // We need to round up to the nearest DWORD
309 // and multiply by the number of bytes per
312 dwNextScan
= (((dwNextScan
* nBypp
)+ 3) & ~3);
313 dwNewScan
= (((dwNewScan
* nBypp
)+ 3) & ~3);
315 for(uiScans
= 0; uiScans
< uiNumScans
; uiScans
++){
316 CopyMemory(pDest
, pBits
, dwScanWidth
);
326 BOOL
wmFlush(PWMC pwc
);
330 Modified from file osmesa.c
334 #define PIXELADDR(X,Y) ((GLubyte *)Current->pbPixels + (Current->height-Y-1)* Current->ScanWidth + (X)*nBypp)
335 #define PIXELADDR1( X, Y ) \
336 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X))
337 #define PIXELADDR2( X, Y ) \
338 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*2)
339 #define PIXELADDR4( X, Y ) \
340 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*4)
343 BYTE
DITHER_RGB_2_8BIT( int r
, int g
, int b
, int x
, int y
);
345 /* Finish all pending operations and synchronize. */
346 static void finish(GLcontext
* ctx
)
353 // We cache all gl draw routines until a flush is made
355 static void flush(GLcontext
* ctx
)
358 if((Current
->rgb_flag
/*&& !(Current->dib.fFlushed)*/&&!(Current
->db_flag
))
359 ||(!Current
->rgb_flag
))
370 * Set the color index used to clear the color buffer.
372 static void clear_index(GLcontext
* ctx
, GLuint index
)
375 Current
->clearpixel
= index
;
376 ENDPROFILE(clear_index
)
382 * Set the color used to clear the color buffer.
384 static void clear_color( GLcontext
* ctx
, GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
387 Current
->clearpixel
=RGB(r
, g
, b
);
388 ENDPROFILE(clear_color
)
394 * Clear the specified region of the color buffer using the clear color
395 * or index as specified by one of the two functions above.
397 //static void clear(GLcontext* ctx,
398 // GLboolean all,GLint x, GLint y, GLint width, GLint height )
399 // TODO: I modified this function to match the prototype in dd.h. (swansma@geocities.com)
400 // dd.h does not explain what the return type is so I could not set this to the proper
402 static GLbitfield
clear(GLcontext
* ctx
, GLbitfield mask
,
403 GLboolean all
, GLint x
, GLint y
, GLint width
, GLint height
)
408 LPDWORD lpdw
= (LPDWORD
)Current
->pbPixels
;
409 LPWORD lpw
= (LPWORD
)Current
->pbPixels
;
410 LPBYTE lpb
= Current
->pbPixels
;
417 width
=Current
->width
;
418 height
=Current
->height
;
420 if(Current
->db_flag
==GL_TRUE
){
421 UINT nBypp
= Current
->cColorBits
/ 8;
426 /* Need rectification */
427 iSize
= Current
->width
/4;
428 bColor
= BGR8(GetRValue(Current
->clearpixel
),
429 GetGValue(Current
->clearpixel
),
430 GetBValue(Current
->clearpixel
));
431 wColor
= MAKEWORD(bColor
,bColor
);
432 dwColor
= MAKELONG(wColor
, wColor
);
435 iSize
= Current
->width
/ 2;
436 wColor
= BGR16(GetRValue(Current
->clearpixel
),
437 GetGValue(Current
->clearpixel
),
438 GetBValue(Current
->clearpixel
));
439 dwColor
= MAKELONG(wColor
, wColor
);
442 iSize
= Current
->width
;
443 dwColor
= BGR32(GetRValue(Current
->clearpixel
),
444 GetGValue(Current
->clearpixel
),
445 GetBValue(Current
->clearpixel
));
455 // This is the 24bit case
458 iSize
= Current
->width
*3/4;
459 dwColor
= BGR24(GetRValue(Current
->clearpixel
),
460 GetGValue(Current
->clearpixel
),
461 GetBValue(Current
->clearpixel
));
476 memcpy(lpb
, Current
->pbPixels
, iSize
*4);
477 lpb
+= Current
->ScanWidth
;
482 else { // For single buffer
484 HPEN Pen
=CreatePen(PS_SOLID
,1,Current
->clearpixel
);
485 HBRUSH Brush
=CreateSolidBrush(Current
->clearpixel
);
486 HPEN Old_Pen
=SelectObject(DC
,Pen
);
487 HBRUSH Old_Brush
=SelectObject(DC
,Brush
);
488 Rectangle(DC
,x
,y
,x
+width
,y
+height
);
489 SelectObject(DC
,Old_Pen
);
490 SelectObject(DC
,Old_Brush
);
500 return mask
; // TODO: I doubt this is correct. dd.h doesn't explain what this should
506 /* Set the current color index. */
507 static void set_index(GLcontext
* ctx
, GLuint index
)
510 Current
->pixel
=index
;
511 ENDPROFILE(set_index
)
516 /* Set the current RGBA color. */
517 static void set_color( GLcontext
* ctx
, GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
520 Current
->pixel
= RGB( r
, g
, b
);
521 ENDPROFILE(set_color
)
526 /* Set the index mode bitplane mask. */
527 static GLboolean
index_mask(GLcontext
* ctx
, GLuint mask
)
529 /* can't implement */
535 /* Set the RGBA drawing mask. */
536 static GLboolean
color_mask( GLcontext
* ctx
,
537 GLboolean rmask
, GLboolean gmask
,
538 GLboolean bmask
, GLboolean amask
)
540 /* can't implement */
547 * Set the pixel logic operation. Return GL_TRUE if the device driver
548 * can perform the operation, otherwise return GL_FALSE. If GL_FALSE
549 * is returned, the logic op will be done in software by Mesa.
551 GLboolean
logicop( GLcontext
* ctx
, GLenum op
)
553 /* can't implement */
558 static void dither( GLcontext
* ctx
, GLboolean enable
)
560 if(enable
== GL_FALSE
){
561 Current
->dither_flag
= GL_FALSE
;
562 if(Current
->cColorBits
== 8)
563 Current
->pixelformat
= PF_INDEX8
;
566 if (Current
->rgb_flag
&& Current
->cColorBits
== 8){
567 Current
->pixelformat
= PF_DITHER8
;
568 Current
->dither_flag
= GL_TRUE
;
571 Current
->dither_flag
= GL_FALSE
;
577 static GLboolean
set_buffer( GLcontext
* ctx
, GLenum mode
)
580 /* TODO: this could be better */
581 if (mode
==GL_FRONT
|| mode
==GL_BACK
) {
587 ENDPROFILE(set_buffer
)
592 /* Return characteristics of the output buffer. */
593 static void buffer_size( GLcontext
* ctx
, GLuint
*width
, GLuint
*height
)
599 GetClientRect(Current
->Window
,&CR
);
604 New_Size
=((*width
)!=Current
->width
) || ((*height
)!=Current
->height
);
607 Current
->width
=*width
;
608 Current
->height
=*height
;
609 Current
->ScanWidth
=Current
->width
;
610 if ((Current
->ScanWidth
%sizeof(long))!=0)
611 Current
->ScanWidth
+=(sizeof(long)-(Current
->ScanWidth
%sizeof(long)));
613 if (Current
->db_flag
){
615 DDDeleteOffScreen(Current
);
616 DDCreateOffScreen(Current
);
618 if (Current
->rgb_flag
==GL_TRUE
&& Current
->dither_flag
!=GL_TRUE
){
619 wmDeleteBackingStore(Current
);
620 wmCreateBackingStore(Current
, Current
->width
, Current
->height
);
625 // Resize OsmesaBuffer if in Parallel mode
626 #if !defined(NO_PARALLEL)
628 PRSizeRenderBuffer(Current
->width
, Current
->height
,Current
->ScanWidth
,
629 Current
->rgb_flag
== GL_TRUE
? Current
->pbPixels
: Current
->ScreenMem
);
632 ENDPROFILE(buffer_size
)
637 /**********************************************************************/
638 /***** Accelerated point, line, polygon rendering *****/
639 /**********************************************************************/
642 static void fast_rgb_points( GLcontext
* ctx
, GLuint first
, GLuint last
)
650 if (Current
->gl_ctx
->VB
->MonoColor
) {
651 /* all drawn with current color */
652 for (i
=first
;i
<=last
;i
++) {
653 if (!Current
->gl_ctx
->VB
->ClipMask
[i
]) {
655 x
= (GLint
) Current
->gl_ctx
->VB
->Win
[i
][0];
656 y
= FLIP( (GLint
) Current
->gl_ctx
->VB
->Win
[i
][1] );
657 wmSetPixel(pwc
, y
,x
,GetRValue(Current
->pixel
),
658 GetGValue(Current
->pixel
), GetBValue(Current
->pixel
));
663 /* draw points of different colors */
664 for (i
=first
;i
<=last
;i
++) {
665 if (!Current
->gl_ctx
->VB
->ClipMask
[i
]) {
667 unsigned long pixel
=RGB(Current
->gl_ctx
->VB
->Color
[i
][0]*255.0,
668 Current
->gl_ctx
->VB
->Color
[i
][1]*255.0,
669 Current
->gl_ctx
->VB
->Color
[i
][2]*255.0);
670 x
= (GLint
) Current
->gl_ctx
->VB
->Win
[i
][0];
671 y
= FLIP( (GLint
) Current
->gl_ctx
->VB
->Win
[i
][1] );
672 wmSetPixel(pwc
, y
,x
,Current
->gl_ctx
->VB
->Color
[i
][0]*255.0,
673 Current
->gl_ctx
->VB
->Color
[i
][1]*255.0,
674 Current
->gl_ctx
->VB
->Color
[i
][2]*255.0);
679 ENDPROFILE(fast_rgb_points
)
684 /* Return pointer to accerated points function */
685 extern points_func
choose_points_function( GLcontext
* ctx
)
688 if (ctx
->Point
.Size
==1.0 && !ctx
->Point
.SmoothFlag
&& ctx
->RasterMask
==0
689 && !ctx
->Texture
.Enabled
&& ctx
->Visual
->RGBAflag
) {
690 ENDPROFILE(choose_points_function
)
691 return fast_rgb_points
;
694 ENDPROFILE(choose_points_function
)
701 /* Draw a line using the color specified by Current->gl_ctx->VB->Color[pv] */
702 static void fast_flat_rgb_line( GLcontext
* ctx
, GLuint v0
, GLuint v1
, GLuint pv
)
711 if (Current
->gl_ctx
->VB
->MonoColor
) {
712 pixel
= Current
->pixel
; /* use current color */
715 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);
718 x0
= (int) Current
->gl_ctx
->VB
->Win
[v0
][0];
719 y0
= FLIP( (int) Current
->gl_ctx
->VB
->Win
[v0
][1] );
720 x1
= (int) Current
->gl_ctx
->VB
->Win
[v1
][0];
721 y1
= FLIP( (int) Current
->gl_ctx
->VB
->Win
[v1
][1] );
726 Pen
=CreatePen(PS_SOLID
,1,pixel
);
727 Old_Pen
=SelectObject(DC
,Pen
);
728 MoveToEx(DC
,x0
,y0
,NULL
);
730 SelectObject(DC
,Old_Pen
);
736 ENDPROFILE(fast_flat_rgb_line
)
741 /* Return pointer to accerated line function */
742 static line_func
choose_line_function( GLcontext
* ctx
)
745 if (ctx
->Line
.Width
==1.0 && !ctx
->Line
.SmoothFlag
&& !ctx
->Line
.StippleFlag
746 && ctx
->Light
.ShadeModel
==GL_FLAT
&& ctx
->RasterMask
==0
747 && !ctx
->Texture
.Enabled
&& Current
->rgb_flag
) {
748 ENDPROFILE(choose_line_function
)
749 return fast_flat_rgb_line
;
752 ENDPROFILE(choose_line_function
)
758 /**********************************************************************/
759 /***** Span-based pixel drawing *****/
760 /**********************************************************************/
763 /* Write a horizontal span of 32-bit color-index pixels with a boolean mask. */
764 static void write_ci32_span( const GLcontext
* ctx
,
765 GLuint n
, GLint x
, GLint y
,
766 const GLuint index
[],
767 const GLubyte mask
[] )
771 PBYTE Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
772 assert(Current
->rgb_flag
==GL_FALSE
);
776 ENDPROFILE(write_ci32_span
)
780 /* Write a horizontal span of 8-bit color-index pixels with a boolean mask. */
781 static void write_ci8_span( const GLcontext
* ctx
,
782 GLuint n
, GLint x
, GLint y
,
783 const GLubyte index
[],
784 const GLubyte mask
[] )
788 PBYTE Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
789 assert(Current
->rgb_flag
==GL_FALSE
);
793 ENDPROFILE(write_ci8_span
)
799 * Write a horizontal span of pixels with a boolean mask. The current
800 * color index is used for all pixels.
802 static void write_mono_ci_span(const GLcontext
* ctx
,
803 GLuint n
,GLint x
,GLint y
,
804 const GLubyte mask
[])
808 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
809 assert(Current
->rgb_flag
==GL_FALSE
);
812 Mem
[i
]=Current
->pixel
;
813 ENDPROFILE(write_mono_ci_span
)
817 * To improve the performance of this routine, frob the data into an actual
818 * scanline and call bitblt on the complete scan line instead of SetPixel.
821 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
822 static void write_rgba_span( const GLcontext
* ctx
, GLuint n
, GLint x
, GLint y
,
823 const GLubyte rgba
[][4], const GLubyte mask
[] )
828 if (pwc
->rgb_flag
==GL_TRUE
)
836 wmSetPixel(pwc
, y
, x
+ i
, rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
840 wmSetPixel(pwc
, y
, x
+ i
, rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
] );
847 BYTE
*Mem
=Current
->ScreenMem
+y
*Current
->ScanWidth
+x
;
852 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]));
856 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]));
859 ENDPROFILE(write_rgba_span
)
863 /* Write a horizontal span of RGB color pixels with a boolean mask. */
864 static void write_rgb_span( const GLcontext
* ctx
,
865 GLuint n
, GLint x
, GLint y
,
866 const GLubyte rgb
[][3], const GLubyte mask
[] )
871 if (pwc
->rgb_flag
==GL_TRUE
)
879 wmSetPixel(pwc
, y
, x
+ i
, rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]);
883 wmSetPixel(pwc
, y
, x
+ i
, rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
] );
890 BYTE
*Mem
=Current
->ScreenMem
+y
*Current
->ScanWidth
+x
;
895 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]));
899 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]));
902 ENDPROFILE(write_rgb_span
)
907 * Write a horizontal span of pixels with a boolean mask. The current color
908 * is used for all pixels.
910 static void write_mono_rgba_span( const GLcontext
* ctx
,
911 GLuint n
, GLint x
, GLint y
,
912 const GLubyte mask
[])
918 assert(Current
->rgb_flag
==GL_TRUE
);
920 if(Current
->rgb_flag
==GL_TRUE
){
924 wmSetPixel(pwc
,y
,x
+i
,GetRValue(Current
->pixel
), GetGValue(Current
->pixel
), GetBValue(Current
->pixel
));
929 SetPixel(DC
, y
, x
+i
, Current
->pixel
);
932 ENDPROFILE(write_mono_rgba_span
)
937 /**********************************************************************/
938 /***** Array-based pixel drawing *****/
939 /**********************************************************************/
942 /* Write an array of 32-bit index pixels with a boolean mask. */
943 static void write_ci32_pixels( const GLcontext
* ctx
,
944 GLuint n
, const GLint x
[], const GLint y
[],
945 const GLuint index
[], const GLubyte mask
[] )
949 assert(Current
->rgb_flag
==GL_FALSE
);
950 for (i
=0; i
<n
; i
++) {
952 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
];
956 ENDPROFILE(write_ci32_pixels
)
962 * Write an array of pixels with a boolean mask. The current color
963 * index is used for all pixels.
965 static void write_mono_ci_pixels( const GLcontext
* ctx
,
967 const GLint x
[], const GLint y
[],
968 const GLubyte mask
[] )
972 assert(Current
->rgb_flag
==GL_FALSE
);
973 for (i
=0; i
<n
; i
++) {
975 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
];
976 *Mem
= Current
->pixel
;
979 ENDPROFILE(write_mono_ci_pixels
)
984 /* Write an array of RGBA pixels with a boolean mask. */
985 static void write_rgba_pixels( const GLcontext
* ctx
,
986 GLuint n
, const GLint x
[], const GLint y
[],
987 const GLubyte rgba
[][4], const GLubyte mask
[] )
993 assert(Current
->rgb_flag
==GL_TRUE
);
996 wmSetPixel(pwc
, FLIP(y
[i
]),x
[i
],rgba
[i
][RCOMP
],rgba
[i
][GCOMP
],rgba
[i
][BCOMP
]);
998 ENDPROFILE(write_rgba_pixels
)
1004 * Write an array of pixels with a boolean mask. The current color
1005 * is used for all pixels.
1007 static void write_mono_rgba_pixels( const GLcontext
* ctx
,
1009 const GLint x
[], const GLint y
[],
1010 const GLubyte mask
[] )
1016 assert(Current
->rgb_flag
==GL_TRUE
);
1019 wmSetPixel(pwc
, FLIP(y
[i
]),x
[i
],GetRValue(Current
->pixel
),
1020 GetGValue(Current
->pixel
), GetBValue(Current
->pixel
));
1022 ENDPROFILE(write_mono_rgba_pixels
)
1027 /**********************************************************************/
1028 /***** Read spans/arrays of pixels *****/
1029 /**********************************************************************/
1032 /* Read a horizontal span of color-index pixels. */
1033 static void read_ci32_span( const GLcontext
* ctx
, GLuint n
, GLint x
, GLint y
,
1038 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
1039 assert(Current
->rgb_flag
==GL_FALSE
);
1042 ENDPROFILE(read_ci32_span
)
1048 /* Read an array of color index pixels. */
1049 static void read_ci32_pixels( const GLcontext
* ctx
,
1050 GLuint n
, const GLint x
[], const GLint y
[],
1051 GLuint indx
[], const GLubyte mask
[] )
1055 assert(Current
->rgb_flag
==GL_FALSE
);
1056 for (i
=0; i
<n
; i
++) {
1058 indx
[i
]=*(Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
]);
1061 ENDPROFILE(read_ci32_pixels
)
1066 /* Read a horizontal span of color pixels. */
1067 static void read_rgba_span( const GLcontext
* ctx
,
1068 GLuint n
, GLint x
, GLint y
,
1075 assert(Current
->rgb_flag
==GL_TRUE
);
1077 for (i
=0; i
<n
; i
++) {
1078 Color
=GetPixel(DC
,x
+i
,y
);
1079 rgba
[i
][RCOMP
] = GetRValue(Color
);
1080 rgba
[i
][GCOMP
] = GetGValue(Color
);
1081 rgba
[i
][BCOMP
] = GetBValue(Color
);
1082 rgba
[i
][ACOMP
] = 255;
1085 // Brian P. Has mentioned to comment this out.
1086 // memset(alpha,0,n*sizeof(GLubyte));
1087 ENDPROFILE(read_rgba_span
)
1091 /* Read an array of color pixels. */
1092 static void read_rgba_pixels( const GLcontext
* ctx
,
1093 GLuint n
, const GLint x
[], const GLint y
[],
1094 GLubyte rgba
[][4], const GLubyte mask
[] )
1100 assert(Current
->rgb_flag
==GL_TRUE
);
1101 for (i
=0; i
<n
; i
++) {
1103 Color
=GetPixel(DC
,x
[i
],FLIP(y
[i
]));
1104 rgba
[i
][RCOMP
] = GetRValue(Color
);
1105 rgba
[i
][GCOMP
] = GetGValue(Color
);
1106 rgba
[i
][BCOMP
] = GetBValue(Color
);
1107 rgba
[i
][ACOMP
] = 255;
1111 // Brian P. has mentioned to comment this out.
1112 // memset(alpha,0,n*sizeof(GLint));
1113 ENDPROFILE(read_rgba_pixels
)
1118 /**********************************************************************/
1119 /**********************************************************************/
1122 static const char *renderer_string(void)
1129 void setup_DD_pointers( GLcontext
* ctx
)
1131 ctx
->Driver
.RendererString
= renderer_string
;
1132 ctx
->Driver
.UpdateState
= setup_DD_pointers
;
1133 ctx
->Driver
.GetBufferSize
= buffer_size
;
1134 ctx
->Driver
.Finish
= finish
;
1135 ctx
->Driver
.Flush
= flush
;
1137 ctx
->Driver
.ClearIndex
= clear_index
;
1138 ctx
->Driver
.ClearColor
= clear_color
;
1139 ctx
->Driver
.Clear
= clear
;
1141 ctx
->Driver
.Index
= set_index
;
1142 ctx
->Driver
.Color
= set_color
;
1143 ctx
->Driver
.IndexMask
= index_mask
;
1144 ctx
->Driver
.ColorMask
= color_mask
;
1146 ctx
->Driver
.LogicOp
= logicop
;
1147 ctx
->Driver
.Dither
= dither
;
1149 ctx
->Driver
.SetBuffer
= set_buffer
;
1150 ctx
->Driver
.GetBufferSize
= buffer_size
;
1152 ctx
->Driver
.PointsFunc
= choose_points_function(ctx
);
1153 ctx
->Driver
.LineFunc
= choose_line_function(ctx
);
1154 ctx
->Driver
.TriangleFunc
= choose_triangle_function( ctx
);
1156 /* Pixel/span writing functions: */
1157 ctx
->Driver
.WriteRGBASpan
= write_rgba_span
;
1158 ctx
->Driver
.WriteRGBSpan
= write_rgb_span
;
1159 ctx
->Driver
.WriteMonoRGBASpan
= write_mono_rgba_span
;
1160 ctx
->Driver
.WriteRGBAPixels
= write_rgba_pixels
;
1161 ctx
->Driver
.WriteMonoRGBAPixels
= write_mono_rgba_pixels
;
1162 ctx
->Driver
.WriteCI32Span
= write_ci32_span
;
1163 ctx
->Driver
.WriteCI8Span
= write_ci8_span
;
1164 ctx
->Driver
.WriteMonoCISpan
= write_mono_ci_span
;
1165 ctx
->Driver
.WriteCI32Pixels
= write_ci32_pixels
;
1166 ctx
->Driver
.WriteMonoCIPixels
= write_mono_ci_pixels
;
1168 ctx
->Driver
.ReadCI32Span
= read_ci32_span
;
1169 ctx
->Driver
.ReadRGBASpan
= read_rgba_span
;
1170 ctx
->Driver
.ReadCI32Pixels
= read_ci32_pixels
;
1171 ctx
->Driver
.ReadRGBAPixels
= read_rgba_pixels
;
1175 /**********************************************************************/
1176 /***** WMesa API Functions *****/
1177 /**********************************************************************/
1181 #define PAL_SIZE 256
1182 static void GetPalette(HPALETTE Pal
,RGBQUAD
*aRGB
)
1190 WORD NumberOfEntries
;
1191 PALETTEENTRY aEntries
[PAL_SIZE
];
1199 GetPaletteEntries(Pal
,0,PAL_SIZE
,Palette
.aEntries
);
1201 GetSystemPaletteEntries(hdc
,0,PAL_SIZE
,Palette
.aEntries
);
1202 if (GetSystemPaletteUse(hdc
) == SYSPAL_NOSTATIC
)
1204 for(i
= 0; i
<PAL_SIZE
; i
++)
1205 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1206 Palette
.aEntries
[255].peRed
= 255;
1207 Palette
.aEntries
[255].peGreen
= 255;
1208 Palette
.aEntries
[255].peBlue
= 255;
1209 Palette
.aEntries
[255].peFlags
= 0;
1210 Palette
.aEntries
[0].peRed
= 0;
1211 Palette
.aEntries
[0].peGreen
= 0;
1212 Palette
.aEntries
[0].peBlue
= 0;
1213 Palette
.aEntries
[0].peFlags
= 0;
1219 nStaticColors
= GetDeviceCaps(hdc
, NUMCOLORS
)/2;
1220 for (i
=0; i
<nStaticColors
; i
++)
1221 Palette
.aEntries
[i
].peFlags
= 0;
1222 nUsableColors
= PAL_SIZE
-nStaticColors
;
1223 for (; i
<nUsableColors
; i
++)
1224 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1225 for (; i
<PAL_SIZE
-nStaticColors
; i
++)
1226 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1227 for (i
=PAL_SIZE
-nStaticColors
; i
<PAL_SIZE
; i
++)
1228 Palette
.aEntries
[i
].peFlags
= 0;
1230 ReleaseDC(NULL
,hdc
);
1231 for (i
=0; i
<PAL_SIZE
; i
++)
1233 aRGB
[i
].rgbRed
=Palette
.aEntries
[i
].peRed
;
1234 aRGB
[i
].rgbGreen
=Palette
.aEntries
[i
].peGreen
;
1235 aRGB
[i
].rgbBlue
=Palette
.aEntries
[i
].peBlue
;
1236 aRGB
[i
].rgbReserved
=Palette
.aEntries
[i
].peFlags
;
1238 ENDPROFILE(GetPalette
)
1242 WMesaContext
WMesaCreateContext( HWND hWnd
,
1249 GLboolean true_color_flag
;
1250 c
= (struct wmesa_context
* ) calloc(1,sizeof(struct wmesa_context
));
1255 c
->hDC
= GetDC(hWnd
);
1256 true_color_flag
= GetDeviceCaps(c
->hDC
, BITSPIXEL
) > 8;
1258 if(true_color_flag
) c
->rgb_flag
= rgb_flag
= GL_TRUE
;
1263 if ((true_color_flag
==GL_FALSE
) && (rgb_flag
== GL_TRUE
)){
1264 c
->dither_flag
= GL_TRUE
;
1265 c
->hPalHalfTone
= WinGCreateHalftonePalette();
1268 c
->dither_flag
= GL_FALSE
;
1270 c
->dither_flag
= GL_FALSE
;
1274 if (rgb_flag
==GL_FALSE
)
1276 c
->rgb_flag
= GL_FALSE
;
1278 c
->db_flag
= db_flag
=GL_TRUE
; // WinG requires double buffering
1279 printf("Single buffer is not supported in color index mode, setting to double buffer.\n");
1283 c
->rgb_flag
= GL_TRUE
;
1286 GetClientRect(c
->Window
,&CR
);
1288 c
->height
=CR
.bottom
;
1292 /* Double buffered */
1294 // if (c->rgb_flag==GL_TRUE && c->dither_flag != GL_TRUE )
1296 wmCreateBackingStore(c
, c
->width
, c
->height
);
1303 /* Single Buffered */
1308 if (DDInit(c
,hWnd
) == GL_FALSE
) {
1315 c
->gl_visual
= gl_create_visual(rgb_flag
,
1316 GL_FALSE
, /* software alpha */
1317 db_flag
, /* db_flag */
1318 GL_FALSE
, /* stereo */
1319 16, /* depth_bits */
1320 8, /* stencil_bits */
1323 8,8,8,8 ); /* r, g, b, a bits */
1325 if (!c
->gl_visual
) {
1329 /* allocate a new Mesa context */
1330 c
->gl_ctx
= gl_create_context( c
->gl_visual
, NULL
, c
, GL_TRUE
);
1333 gl_destroy_visual( c
->gl_visual
);
1338 c
->gl_buffer
= gl_create_framebuffer( c
->gl_visual
);
1339 if (!c
->gl_buffer
) {
1340 gl_destroy_visual( c
->gl_visual
);
1341 gl_destroy_context( c
->gl_ctx
);
1346 c
->gl_ctx
->Driver
.UpdateState
= setup_DD_pointers
;
1348 // setup_DD_pointers(c->gl_ctx);
1353 void WMesaDestroyContext( void )
1355 WMesaContext c
= Current
;
1356 ReleaseDC(c
->Window
,c
->hDC
);
1358 if(c
->hPalHalfTone
!= NULL
)
1359 DeleteObject(c
->hPalHalfTone
);
1360 gl_destroy_visual( c
->gl_visual
);
1361 gl_destroy_framebuffer( c
->gl_buffer
);
1362 gl_destroy_context( c
->gl_ctx
);
1368 wmDeleteBackingStore(c
);
1371 //Following code is added to enable parallel render
1372 // Parallel render only work in double buffer mode
1373 #if !defined(NO_PARALLEL)
1375 PRDestroyRenderBuffer();
1380 void WMesaMakeCurrent( WMesaContext c
)
1388 // A little optimization
1389 // If it already is current,
1390 // don't set it again
1395 //gl_set_context( c->gl_ctx );
1396 gl_make_current(c
->gl_ctx
, c
->gl_buffer
);
1397 setup_DD_pointers(c
->gl_ctx
);
1399 if (Current
->gl_ctx
->Viewport
.Width
==0) {
1400 /* initialize viewport to window size */
1401 gl_Viewport( Current
->gl_ctx
,
1402 0, 0, Current
->width
, Current
->height
);
1404 if ((c
->cColorBits
<= 8 ) && (c
->rgb_flag
== GL_TRUE
)){
1405 WMesaPaletteChange(c
->hPalHalfTone
);
1409 void WMesaSwapBuffers( void )
1411 HDC DC
= Current
->hDC
;
1412 if (Current
->db_flag
)
1416 void WMesaPaletteChange(HPALETTE Pal
)
1419 LPPALETTEENTRY pPal
;
1420 if (Current
&& (Current
->rgb_flag
==GL_FALSE
|| Current
->dither_flag
== GL_TRUE
))
1422 pPal
= (PALETTEENTRY
*)malloc( 256 * sizeof(PALETTEENTRY
));
1424 // GetPaletteEntries( Pal, 0, 256, pPal );
1425 GetPalette( Pal
, pPal
);
1427 Current
->lpDD
->lpVtbl
->CreatePalette(Current
->lpDD
,DDPCAPS_8BIT
,
1428 pPal
, &(Current
->lpDDPal
), NULL
);
1429 if (Current
->lpDDPal
)
1430 Current
->lpDDSPrimary
->lpVtbl
->SetPalette(Current
->lpDDSPrimary
,Current
->lpDDPal
);
1432 vRet
= SetDIBColorTable(Current
->dib
.hDC
,0,256,pPal
);
1439 static unsigned char threeto8
[8] = {
1440 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
1443 static unsigned char twoto8
[4] = {
1447 static unsigned char oneto8
[2] = {
1451 static unsigned char componentFromIndex(UCHAR i
, UINT nbits
, UINT shift
)
1468 return threeto8
[val
];
1475 void wmCreatePalette( PWMC pwdc
)
1477 /* Create a compressed and re-expanded 3:3:2 palette */
1480 BYTE rb
, rs
, gb
, gs
, bb
, bs
;
1482 pwdc
->nColors
= 0x100;
1484 pPal
= (PLOGPALETTE
)malloc(sizeof(LOGPALETTE
) + pwdc
->nColors
* sizeof(PALETTEENTRY
));
1485 memset( pPal
, 0, sizeof(LOGPALETTE
) + pwdc
->nColors
* sizeof(PALETTEENTRY
) );
1487 pPal
->palVersion
= 0x300;
1496 if (pwdc
->db_flag
) {
1498 /* Need to make two palettes: one for the screen DC and one for the DIB. */
1499 pPal
->palNumEntries
= pwdc
->nColors
;
1500 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1501 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1502 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1503 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1504 pPal
->palPalEntry
[i
].peFlags
= 0;
1506 pwdc
->hGLPalette
= CreatePalette( pPal
);
1507 pwdc
->hPalette
= CreatePalette( pPal
);
1511 pPal
->palNumEntries
= pwdc
->nColors
;
1512 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1513 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1514 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1515 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1516 pPal
->palPalEntry
[i
].peFlags
= 0;
1518 pwdc
->hGLPalette
= CreatePalette( pPal
);
1525 void wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1527 if(Current
->db_flag
){
1528 LPBYTE lpb
= pwc
->pbPixels
;
1531 UINT nBypp
= pwc
->cColorBits
/ 8;
1532 UINT nOffset
= iPixel
% nBypp
;
1534 // Move the pixel buffer pointer to the scanline that we
1537 // pwc->dib.fFlushed = FALSE;
1539 lpb
+= pwc
->ScanWidth
* iScanLine
;
1540 // Now move to the desired pixel
1541 lpb
+= iPixel
* nBypp
;
1542 lpb
= PIXELADDR(iPixel
, iScanLine
);
1543 lpdw
= (LPDWORD
)lpb
;
1547 if(pwc
->dither_flag
)
1548 *lpb
= DITHER_RGB_2_8BIT(r
,g
,b
,iScanLine
,iPixel
);
1553 *lpw
= BGR16(r
,g
,b
);
1554 else if (nBypp
== 3){
1555 *lpdw
= BGR24(r
,g
,b
);
1557 else if (nBypp
== 4)
1558 *lpdw
= BGR32(r
,g
,b
);
1562 SetPixel(DC
, iPixel
, iScanLine
, RGB(r
,g
,b
));
1567 void wmCreateDIBSection( HDC hDC
,
1568 PWMC pwc
, // handle of device context
1569 CONST BITMAPINFO
*pbmi
, // address of structure containing bitmap size, format, and color data
1570 UINT iUsage
// color data type indicator: RGB values or palette indices
1575 UINT nBypp
= pwc
->cColorBits
/ 8;
1578 dwScanWidth
= (((pwc
->ScanWidth
* nBypp
)+ 3) & ~3);
1580 pwc
->ScanWidth
=pwc
->pitch
= dwScanWidth
;
1583 pwc
->ScanWidth
= 2* pwc
->pitch
;
1585 dwSize
= sizeof(BITMAPINFO
) + (dwScanWidth
* pwc
->height
);
1587 pwc
->dib
.hFileMap
= CreateFileMapping((HANDLE
)PAGE_FILE
,
1589 PAGE_READWRITE
| SEC_COMMIT
,
1594 if (!pwc
->dib
.hFileMap
)
1597 pwc
->dib
.base
= MapViewOfFile(pwc
->dib
.hFileMap
,
1598 FILE_MAP_ALL_ACCESS
,
1604 CloseHandle(pwc
->dib
.hFileMap
);
1608 // pwc->pbPixels = pwc->addrOffScreen = ((LPBYTE)pwc->dib.base) + sizeof(BITMAPINFO);
1610 // pwc->dib.hDC = CreateCompatibleDC(hDC);
1612 CopyMemory(pwc
->dib
.base
, pbmi
, sizeof(BITMAPINFO
));
1614 hic
= CreateIC("display", NULL
, NULL
, NULL
);
1615 pwc
->dib
.hDC
= CreateCompatibleDC(hic
);
1618 /* pwc->hbmDIB = CreateDIBitmap(hic,
1619 &(pwc->bmi.bmiHeader),
1625 pwc
->hbmDIB
= CreateDIBSection(hic
,
1627 (iUsage
? DIB_PAL_COLORS
: DIB_RGB_COLORS
),
1632 pwc->hbmDIB = CreateDIBSection(hic,
1639 pwc
->ScreenMem
= pwc
->addrOffScreen
= pwc
->pbPixels
;
1640 pwc
->hOldBitmap
= SelectObject(pwc
->dib
.hDC
, pwc
->hbmDIB
);
1649 // Blit memory DC to screen DC
1651 BOOL
wmFlush(PWMC pwc
)
1659 // Now search through the torus frames and mark used colors
1662 if (pwc
->lpDDSOffScreen
== NULL
)
1663 if(DDCreateOffScreen(pwc
) == GL_FALSE
)
1666 pwc
->lpDDSOffScreen
->lpVtbl
->Unlock(pwc
->lpDDSOffScreen
, NULL
);
1670 ddrval
= pwc
->lpDDSPrimary
->lpVtbl
->Blt( pwc
->lpDDSPrimary
,
1671 &(pwc
->rectSurface
), pwc
->lpDDSOffScreen
, &(pwc
->rectOffScreen
), 0, NULL
);
1673 if( ddrval
== DD_OK
)
1677 if( ddrval
== DDERR_SURFACELOST
)
1679 if(!DDRestoreAll(pwc
))
1684 if( ddrval
!= DDERR_WASSTILLDRAWING
)
1690 while (pwc
->lpDDSOffScreen
->lpVtbl
->Lock(pwc
->lpDDSOffScreen
,
1691 NULL
, &(pwc
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
)
1695 dwErr
= GetLastError();
1697 bRet
= BitBlt(pwc
->hDC
, 0, 0, pwc
->width
, pwc
->height
,
1698 pwc
->dib
.hDC
, 0, 0, SRCCOPY
);
1706 // The following code is added by Li Wei to enable stereo display
1708 #if !defined(NO_STEREO)
1710 void WMesaShowStereo(GLuint list
)
1713 GLbitfield mask
= GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
;
1716 // Must use double Buffer
1717 if( ! Current
-> db_flag
)
1721 glGetIntegerv(GL_MATRIX_MODE
,&matrix_mode
);
1723 // glPushMatrix(); //****
1724 WMesaViewport(Current
->gl_ctx
,0,Current
->height
/2,Current
->width
,Current
->height
/2);
1725 // Current->gl_ctx->NewState = 0;
1727 // glViewport(0,0,Current->width,Current->height/2);
1728 if(matrix_mode
!=GL_MODELVIEW
)
1729 glMatrixMode(GL_MODELVIEW
);
1731 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1733 gluLookAt(viewDistance
/2,0.0,0.0 ,
1734 viewDistance
/2,0.0,-1.0,
1736 // glTranslatef(viewDistance/2.0,0.,0.);
1737 glMultMatrixf( cm
);
1739 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
;
1744 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1746 gluLookAt(-viewDistance
/2,0.0,0.0 ,
1747 -viewDistance
/2,0.0,-1.0,
1749 // glTranslatef(-viewDistance/2.0,0.,0.);
1752 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
+ Current
->pitch
;
1754 if(matrix_mode
!=GL_MODELVIEW
)
1755 glMatrixMode(matrix_mode
);
1760 WMesaViewport(Current
->gl_ctx
,0,0,Current
->width
,Current
->height
);
1761 // Current->gl_ctx->NewState = 0;
1766 void toggleStereoMode()
1768 if(!Current
->db_flag
)
1772 if(stereoBuffer
==GL_FALSE
)
1773 #if !defined(NO_PARALLEL)
1777 Current
->ScanWidth
= Current
->pitch
*2;
1782 #if !defined(NO_PARALLEL)
1785 Current
->ScanWidth
= Current
->pitch
;
1786 Current
->pbPixels
= Current
->addrOffScreen
;
1790 /* if in stereo mode, the following function is called */
1791 void glShowStereo(GLuint list
)
1793 WMesaShowStereo(list
);
1796 #endif // End if NO_STEREO not defined
1798 #if !defined(NO_PARALLEL)
1800 void toggleParallelMode(void)
1803 parallelFlag
= GL_TRUE
;
1804 if(parallelMachine
==GL_FALSE
){
1805 PRCreateRenderBuffer( Current
->rgb_flag
? GL_RGBA
:GL_COLOR_INDEX
,
1806 Current
->cColorBits
/8,
1807 Current
->width
,Current
->height
,
1809 Current
->rgb_flag
? Current
->pbPixels
: Current
->ScreenMem
);
1810 parallelMachine
= GL_TRUE
;
1814 parallelFlag
= GL_FALSE
;
1815 if(parallelMachine
==GL_TRUE
){
1816 PRDestroyRenderBuffer();
1817 parallelMachine
=GL_FALSE
;
1818 ReadyForNextFrame
= GL_TRUE
;
1821 /***********************************************
1822 // Seems something wrong!!!!
1823 ************************************************/
1825 WMesaMakeCurrent(Current
);
1826 #if !defined(NO_STEREO)
1827 stereo_flag
= GL_FALSE
;
1832 void PRShowRenderResult(void)
1835 if(!glImageRendered())
1844 #endif //End if NO_PARALLEL not defined
1848 BYTE
DITHER_RGB_2_8BIT( int red
, int green
, int blue
, int pixel
, int scanline
)
1850 char unsigned redtemp
, greentemp
, bluetemp
, paletteindex
;
1852 //*** now, look up each value in the halftone matrix
1853 //*** using an 8x8 ordered dither.
1854 redtemp
= aDividedBy51
[red
]
1855 + (aModulo51
[red
] > aHalftone8x8
[(pixel
%8)*8
1857 greentemp
= aDividedBy51
[(char unsigned)green
]
1858 + (aModulo51
[green
] > aHalftone8x8
[
1859 (pixel
%8)*8 + scanline
%8]);
1860 bluetemp
= aDividedBy51
[(char unsigned)blue
]
1861 + (aModulo51
[blue
] > aHalftone8x8
[
1862 (pixel
%8)*8 +scanline
%8]);
1864 //*** recombine the halftoned rgb values into a palette index
1866 redtemp
+ aTimes6
[greentemp
] + aTimes36
[bluetemp
];
1868 //*** and translate through the wing halftone palette
1869 //*** translation vector to give the correct value.
1870 return aWinGHalftoneTranslation
[paletteindex
];
1877 * restore all lost objects
1879 static HRESULT
DDRestoreAll( WMesaContext wc
)
1883 ddrval
= wc
->lpDDSPrimary
->lpVtbl
->Restore(wc
->lpDDSPrimary
);
1884 if( ddrval
== DD_OK
)
1886 ddrval
= wc
->lpDDSOffScreen
->lpVtbl
->Restore(wc
->lpDDSOffScreen
);
1894 * This function is called if the initialization function fails
1896 static BOOL
initFail( HWND hwnd
, WMesaContext wc
)
1899 MessageBox( hwnd
, "DirectDraw Init FAILED", "", MB_OK
);
1905 static void DDDeleteOffScreen(WMesaContext wc
)
1907 if( wc
->lpDDSOffScreen
!= NULL
)
1909 wc
->lpDDSOffScreen
->lpVtbl
->Unlock(wc
->lpDDSOffScreen
,NULL
);
1910 wc
->lpDDSOffScreen
->lpVtbl
->Release(wc
->lpDDSOffScreen
);
1911 wc
->lpDDSOffScreen
= NULL
;
1916 static void DDFreePrimarySurface(WMesaContext wc
)
1918 if( wc
->lpDDSPrimary
!= NULL
)
1920 if(wc
->db_flag
== GL_FALSE
)
1921 wc
->lpDDSPrimary
->lpVtbl
->ReleaseDC(wc
->lpDDSPrimary
, wc
->hDC
);
1922 wc
->lpDDSPrimary
->lpVtbl
->Release(wc
->lpDDSPrimary
);
1923 wc
->lpDDSPrimary
= NULL
;
1927 static BOOL
DDCreatePrimarySurface(WMesaContext wc
)
1931 wc
->ddsd
.dwSize
= sizeof( wc
->ddsd
);
1932 wc
->ddsd
.dwFlags
= DDSD_CAPS
;
1933 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
1935 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
,&(wc
->ddsd
), &(wc
->lpDDSPrimary
), NULL
);
1936 if( ddrval
!= DD_OK
)
1938 return initFail(wc
->hwnd
, wc
);
1940 if(wc
->db_flag
== GL_FALSE
)
1941 wc
->lpDDSPrimary
->lpVtbl
->GetDC(wc
->lpDDSPrimary
, wc
->hDC
);
1945 static BOOL
DDCreateOffScreen(WMesaContext wc
)
1949 if(wc
->lpDD
== NULL
)
1951 GetClientRect( wc
->hwnd
, &(wc
->rectOffScreen
) );
1952 wc
->ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1953 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
1954 wc
->ddsd
.dwHeight
= wc
->rectOffScreen
.bottom
- wc
->rectOffScreen
.top
;
1955 wc
->ddsd
.dwWidth
= wc
->rectOffScreen
.right
- wc
->rectOffScreen
.left
;
1957 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
, &(wc
->ddsd
), &(wc
->lpDDSOffScreen
), NULL
);
1958 if( ddrval
!= DD_OK
)
1963 while (wc
->lpDDSOffScreen
->lpVtbl
->Lock(wc
->lpDDSOffScreen
,NULL
, &(wc
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
)
1965 // while ((ddrval = wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, &(wc->ddsd), DDLOCK_SURFACEMEMORYPTR , NULL)) != DD_OK)
1967 if(wc
->ddsd
.lpSurface
==NULL
)
1968 return initFail(wc
->hwnd
, wc
);
1970 wc
->ScreenMem
= wc
->pbPixels
= wc
->addrOffScreen
= (PBYTE
)(wc
->ddsd
.lpSurface
);
1971 wc
->ScanWidth
= wc
->pitch
= wc
->ddsd
.lPitch
;
1973 wc
->ScanWidth
= wc
->ddsd
.lPitch
*2;
1975 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
1977 ClientToScreen( wc
->hwnd
, &pt
);
1978 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
1979 wmSetPixelFormat(wc
, wc
->hDC
);
1984 * doInit - do work required for every instance of the application:
1985 * create the window, initialize data
1987 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
)
1992 LPDIRECTDRAW lpDD
; // DirectDraw object
1993 LPDIRECTDRAW2 lpDD2
;
1996 wc
->fullScreen
= displayOptions
.fullScreen
;
1997 wc
->gMode
= displayOptions
.mode
;
1999 stereo_flag
= displayOptions
.stereo
;
2000 if(wc
->db_flag
!= GL_TRUE
)
2001 stereo_flag
= GL_FALSE
;
2003 * create the main DirectDraw object
2005 ddrval
= DirectDrawCreate( NULL
, &(wc
->lpDD
), NULL
);
2006 if( ddrval
!= DD_OK
)
2008 return initFail(hwnd
,wc
);
2011 // Get exclusive mode if requested
2014 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2018 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
, DDSCL_NORMAL
);
2020 if( ddrval
!= DD_OK
)
2022 return initFail(hwnd
, wc
);
2026 /* ddrval = wc->lpDD->lpVtbl->QueryInterface(wc->lpDD, IID_IDirectDraw2,
2027 (LPVOID *)((wc->lpDD2)));
2031 return initFail(hwnd
, wc
);
2034 //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
2035 // wc->lpDD2->lpVtbl->GetMonitorFrequency(wc->lpDD, &dwFrequency);
2038 case 1: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 640, 480, displayOptions
.bpp
); break;
2039 case 2: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 800, 600, displayOptions
.bpp
); break;
2040 case 3: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1024, 768, displayOptions
.bpp
); break;
2041 case 4: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1152, 864, displayOptions
.bpp
); break;
2042 case 5: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1280, 1024, displayOptions
.bpp
); break;
2045 if( ddrval
!= DD_OK
)
2047 printf("Can't modify display mode, current mode used\n");
2048 // return initFail(hwnd , wc);
2050 //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
2052 case DDERR_INVALIDOBJECT
:
2054 case DDERR_INVALIDPARAMS
:
2056 case DDERR_UNSUPPORTEDMODE
:
2060 if(DDCreatePrimarySurface(wc
) == GL_FALSE
)
2061 return initFail(hwnd
, wc
);
2064 return DDCreateOffScreen(wc
);
2067 static void DDFree( WMesaContext wc
)
2069 if( wc
->lpDD
!= NULL
)
2071 DDFreePrimarySurface(wc
);
2072 DDDeleteOffScreen(wc
);
2073 wc
->lpDD
->lpVtbl
->Release(wc
->lpDD
);
2076 // Clean up the screen on exit
2077 RedrawWindow( NULL
, NULL
, NULL
, RDW_INVALIDATE
| RDW_ERASE
|
2083 void WMesaMove(void)
2085 WMesaContext wc
= Current
;
2087 if (Current
!= NULL
){
2088 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2090 ClientToScreen( wc
->hwnd
, &pt
);
2091 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2098 * Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable
2101 #define PACK_8B8G8R( R, G, B ) ( ((B) << 16) | ((G) << 8) | (R) )
2104 /**********************************************************************/
2105 /*** Triangle rendering ***/
2106 /**********************************************************************/
2109 * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
2111 static void smooth_8A8B8G8R_z_triangle( GLcontext
*ctx
,
2112 GLuint v0
, GLuint v1
, GLuint v2
,
2115 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2117 #define INTERP_RGB 1
2118 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2119 #define PIXEL_TYPE GLuint
2120 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2121 #define BYTES_PER_ROW (wmesa->ScanWidth)
2122 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2124 GLint i, len = RIGHT-LEFT; \
2125 for (i=0;i<len;i++) { \
2126 GLdepth z = FixedToDepth(ffz); \
2127 if (z < zRow[i]) { \
2128 pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2129 FixedToInt(ffb) ); \
2132 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2137 #include "..\tritemp.h"
2139 #include "tritemp.h"
2145 * XImage, smooth, depth-buffered, PF_8R8G8B triangle.
2147 static void smooth_8R8G8B_z_triangle( GLcontext
*ctx
,
2148 GLuint v0
, GLuint v1
, GLuint v2
,
2151 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2153 #define INTERP_RGB 1
2154 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2155 #define PIXEL_TYPE GLuint
2156 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2157 #define BYTES_PER_ROW (wmesa->ScanWidth)
2158 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2160 GLint i, len = RIGHT-LEFT; \
2161 for (i=0;i<len;i++) { \
2162 GLdepth z = FixedToDepth(ffz); \
2163 if (z < zRow[i]) { \
2164 pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2165 FixedToInt(ffb) ); \
2168 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2173 #include "..\tritemp.h"
2175 #include "tritemp.h"
2182 * XImage, smooth, depth-buffered, PF_5R6G5B triangle.
2184 static void smooth_5R6G5B_z_triangle( GLcontext
*ctx
,
2185 GLuint v0
, GLuint v1
, GLuint v2
,
2188 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2190 #define INTERP_RGB 1
2191 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2192 #define PIXEL_TYPE GLushort
2193 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2194 #define BYTES_PER_ROW (wmesa->ScanWidth)
2195 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2197 GLint i, len = RIGHT-LEFT; \
2198 for (i=0;i<len;i++) { \
2199 GLdepth z = FixedToDepth(ffz); \
2200 if (z < zRow[i]) { \
2201 pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2202 FixedToInt(ffb) ); \
2205 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2210 #include "..\tritemp.h"
2212 #include "tritemp.h"
2217 * XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
2219 static void flat_8A8B8G8R_z_triangle( GLcontext
*ctx
, GLuint v0
,
2220 GLuint v1
, GLuint v2
, GLuint pv
)
2222 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2224 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2225 #define PIXEL_TYPE GLuint
2226 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2227 #define BYTES_PER_ROW (wmesa->ScanWidth)
2228 #define SETUP_CODE \
2229 unsigned long p = PACK_8B8G8R( VB->Color[pv][0], \
2230 VB->Color[pv][1], VB->Color[pv][2] );
2231 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2233 GLint i, len = RIGHT-LEFT; \
2234 for (i=0;i<len;i++) { \
2235 GLdepth z = FixedToDepth(ffz); \
2236 if (z < zRow[i]) { \
2244 #include "..\tritemp.h"
2246 #include "tritemp.h"
2252 * XImage, flat, depth-buffered, PF_8R8G8B triangle.
2254 static void flat_8R8G8B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2255 GLuint v2
, GLuint pv
)
2257 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2259 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2260 #define PIXEL_TYPE GLuint
2261 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2262 #define BYTES_PER_ROW (wmesa->ScanWidth)
2263 #define SETUP_CODE \
2264 unsigned long p = PACK_8R8G8B( VB->Color[pv][0], \
2265 VB->Color[pv][1], VB->Color[pv][2] );
2266 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2268 GLint i, len = RIGHT-LEFT; \
2269 for (i=0;i<len;i++) { \
2270 GLdepth z = FixedToDepth(ffz); \
2271 if (z < zRow[i]) { \
2279 #include "..\tritemp.h"
2281 #include "tritemp.h"
2287 * XImage, flat, depth-buffered, PF_5R6G5B triangle.
2289 static void flat_5R6G5B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2290 GLuint v2
, GLuint pv
)
2292 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2294 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2295 #define PIXEL_TYPE GLushort
2296 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2297 #define BYTES_PER_ROW (wmesa->ScanWidth)
2298 #define SETUP_CODE \
2299 unsigned long p = PACK_5R6G5B( VB->Color[pv][0], \
2300 VB->Color[pv][1], VB->Color[pv][2] );
2301 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2303 GLint i, len = RIGHT-LEFT; \
2304 for (i=0;i<len;i++) { \
2305 GLdepth z = FixedToDepth(ffz); \
2306 if (z < zRow[i]) { \
2314 #include "..\tritemp.h"
2316 #include "tritemp.h"
2322 * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
2324 static void smooth_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2325 GLuint v2
, GLuint pv
)
2327 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2328 #define INTERP_RGB 1
2329 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2330 #define PIXEL_TYPE GLuint
2331 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2332 #define BYTES_PER_ROW (wmesa->ScanWidth)
2333 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2336 PIXEL_TYPE *pixel = pRow; \
2337 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2338 *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2339 FixedToInt(ffb) ); \
2340 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2344 #include "..\tritemp.h"
2346 #include "tritemp.h"
2352 * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
2354 static void smooth_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2355 GLuint v2
, GLuint pv
)
2357 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2358 #define INTERP_RGB 1
2359 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2360 #define PIXEL_TYPE GLuint
2361 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2362 #define BYTES_PER_ROW (wmesa->ScanWidth)
2363 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2366 PIXEL_TYPE *pixel = pRow; \
2367 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2368 *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2369 FixedToInt(ffb) ); \
2370 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2374 #include "..\tritemp.h"
2376 #include "tritemp.h"
2382 * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
2384 static void smooth_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2385 GLuint v2
, GLuint pv
)
2387 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2388 #define INTERP_RGB 1
2389 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2390 #define PIXEL_TYPE GLushort
2391 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2392 #define BYTES_PER_ROW (wmesa->ScanWidth)
2393 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2396 PIXEL_TYPE *pixel = pRow; \
2397 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2398 *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2399 FixedToInt(ffb) ); \
2400 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2404 #include "..\tritemp.h"
2406 #include "tritemp.h"
2413 * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
2415 static void flat_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
,
2416 GLuint v1
, GLuint v2
, GLuint pv
)
2418 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2419 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2420 #define PIXEL_TYPE GLuint
2421 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2422 #define BYTES_PER_ROW (wmesa->ScanWidth)
2423 #define SETUP_CODE \
2424 unsigned long p = PACK_8B8G8R( VB->Color[pv][0], \
2425 VB->Color[pv][1], VB->Color[pv][2] );
2426 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2429 PIXEL_TYPE *pixel = pRow; \
2430 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2435 #include "..\tritemp.h"
2437 #include "tritemp.h"
2443 * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
2445 static void flat_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2446 GLuint v2
, GLuint pv
)
2448 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2449 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2450 #define PIXEL_TYPE GLuint
2451 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2452 #define BYTES_PER_ROW (wmesa->ScanWidth)
2453 #define SETUP_CODE \
2454 unsigned long p = PACK_8R8G8B( VB->Color[pv][0], \
2455 VB->Color[pv][1], VB->Color[pv][2] );
2456 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2459 PIXEL_TYPE *pixel = pRow; \
2460 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2465 #include "..\tritemp.h"
2467 #include "tritemp.h"
2473 * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
2475 static void flat_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2476 GLuint v2
, GLuint pv
)
2478 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2479 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2480 #define PIXEL_TYPE GLushort
2481 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2482 #define BYTES_PER_ROW (wmesa->ScanWidth)
2483 #define SETUP_CODE \
2484 unsigned long p = PACK_5R6G5B( VB->Color[pv][0], \
2485 VB->Color[pv][1], VB->Color[pv][2] );
2486 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2489 PIXEL_TYPE *pixel = pRow; \
2490 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2495 #include "..\tritemp.h"
2497 #include "tritemp.h"
2503 * XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
2506 static void smooth_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2507 GLuint v2
, GLuint pv
)
2509 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2511 #define INTERP_INDEX 1
2512 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2513 #define PIXEL_TYPE GLubyte
2514 #define BYTES_PER_ROW (wmesa->ScanWidth)
2515 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2517 GLint i, len = RIGHT-LEFT; \
2518 for (i=0;i<len;i++) { \
2519 GLdepth z = FixedToDepth(ffz); \
2520 if (z < zRow[i]) { \
2521 pRow[i] = FixedToInt(ffi); \
2530 #include "..\tritemp.h"
2532 #include "tritemp.h"
2538 * XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
2541 static void flat_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2542 GLuint v2
, GLuint pv
)
2544 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2546 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2547 #define PIXEL_TYPE GLubyte
2548 #define BYTES_PER_ROW (wmesa->ScanWidth)
2549 #define SETUP_CODE \
2550 GLuint index = VB->Index[pv]; \
2551 if (!VB->MonoColor) { \
2552 /* set the color index */ \
2553 (*ctx->Driver.Index)( ctx, index ); \
2555 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2557 GLint i, len = RIGHT-LEFT; \
2558 for (i=0;i<len;i++) { \
2559 GLdepth z = FixedToDepth(ffz); \
2560 if (z < zRow[i]) { \
2568 #include "..\tritemp.h"
2570 #include "tritemp.h"
2577 * XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2580 static void smooth_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2581 GLuint v2
, GLuint pv
)
2583 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2585 #define INTERP_INDEX 1
2586 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2587 #define PIXEL_TYPE GLubyte
2588 #define BYTES_PER_ROW (wmesa->ScanWidth)
2589 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2592 PIXEL_TYPE *pixel = pRow; \
2593 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2594 *pixel = FixedToInt(ffi); \
2599 #include "..\tritemp.h"
2601 #include "tritemp.h"
2607 * XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2609 static void flat_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2610 GLuint v2
, GLuint pv
)
2612 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2614 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2615 #define PIXEL_TYPE GLubyte
2616 #define BYTES_PER_ROW (wmesa->ScanWidth)
2617 #define SETUP_CODE \
2618 GLuint index = VB->Index[pv]; \
2619 if (!VB->MonoColor) { \
2620 /* set the color index */ \
2621 (*ctx->Driver.Index)( ctx, index ); \
2623 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2626 PIXEL_TYPE *pixel = pRow; \
2627 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2632 #include "..\tritemp.h"
2634 #include "tritemp.h"
2639 * XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
2641 static void smooth_DITHER8_z_triangle( GLcontext
*ctx
,
2642 GLuint v0
, GLuint v1
, GLuint v2
,
2645 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2646 DITHER_RGB_TO_8BIT_SETUP
2648 #define INTERP_RGB 1
2649 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2650 #define PIXEL_TYPE GLubyte
2651 #define BYTES_PER_ROW (wmesa->ScanWidth)
2652 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2654 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
2655 for (i=0;i<len;i++,xx++) { \
2656 GLdepth z = FixedToDepth(ffz); \
2657 if (z < zRow[i]) { \
2658 DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg), \
2659 FixedToInt(ffb), xx, yy); \
2660 pRow[i] = pixelDithered; \
2663 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2668 #include "..\tritemp.h"
2670 #include "tritemp.h"
2675 * XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
2677 static void flat_DITHER8_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2678 GLuint v2
, GLuint pv
)
2680 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2681 DITHER_RGB_TO_8BIT_SETUP
2683 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2684 #define PIXEL_TYPE GLubyte
2685 #define BYTES_PER_ROW (wmesa->ScanWidth)
2687 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2689 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
2690 for (i=0;i<len;i++,xx++) { \
2691 GLdepth z = FixedToDepth(ffz); \
2692 if (z < zRow[i]) { \
2693 DITHER_RGB_TO_8BIT( VB->Color[pv][0], \
2694 VB->Color[pv][1], VB->Color[pv][2], xx, yy); \
2695 pRow[i] = pixelDithered; \
2702 #include "..\tritemp.h"
2704 #include "tritemp.h"
2709 * XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
2711 static void smooth_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2712 GLuint v2
, GLuint pv
)
2714 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2715 DITHER_RGB_TO_8BIT_SETUP
2716 #define INTERP_RGB 1
2717 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2718 #define PIXEL_TYPE GLubyte
2719 #define BYTES_PER_ROW (wmesa->ScanWidth)
2720 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2722 GLint xx, yy = FLIP(Y); \
2723 PIXEL_TYPE *pixel = pRow; \
2724 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2725 DITHER_RGB_TO_8BIT( VB->Color[pv][0], VB->Color[pv][1], VB->Color[pv][2], xx, yy);\
2726 *pixel = pixelDithered; \
2727 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2731 #include "..\tritemp.h"
2733 #include "tritemp.h"
2738 * XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
2741 static void flat_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2742 GLuint v2
, GLuint pv
)
2744 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2745 DITHER_RGB_TO_8BIT_SETUP
2746 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2747 #define PIXEL_TYPE GLubyte
2748 #define BYTES_PER_ROW (wmesa->ScanWidth)
2750 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2752 GLint xx, yy = FLIP(Y); \
2753 PIXEL_TYPE *pixel = pRow; \
2754 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2755 DITHER_RGB_TO_8BIT( VB->Color[pv][0], \
2756 VB->Color[pv][1], VB->Color[pv][2], xx, yy); \
2757 *pixel = pixelDithered; \
2761 #include "..\tritemp.h"
2763 #include "tritemp.h"
2770 static triangle_func
choose_triangle_function( GLcontext
*ctx
)
2772 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2773 int depth
= wmesa
->cColorBits
;
2775 if (ctx
->Polygon
.SmoothFlag
) return NULL
;
2776 if (ctx
->Texture
.Enabled
) return NULL
;
2777 if (!wmesa
->db_flag
) return NULL
;
2778 /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {
2779 if ( ctx
->Light
.ShadeModel
==GL_SMOOTH
2780 && ctx
->RasterMask
==DEPTH_BIT
2781 && ctx
->Depth
.Func
==GL_LESS
2782 && ctx
->Depth
.Mask
==GL_TRUE
2783 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2784 switch (wmesa
->pixelformat
) {
2786 return smooth_8A8B8G8R_z_triangle
;
2788 return smooth_8R8G8B_z_triangle
;
2790 return smooth_5R6G5B_z_triangle
;
2792 return smooth_DITHER8_z_triangle
;
2794 return smooth_ci_z_triangle
;
2799 if ( ctx
->Light
.ShadeModel
==GL_FLAT
2800 && ctx
->RasterMask
==DEPTH_BIT
2801 && ctx
->Depth
.Func
==GL_LESS
2802 && ctx
->Depth
.Mask
==GL_TRUE
2803 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2804 switch (wmesa
->pixelformat
) {
2806 return flat_8A8B8G8R_z_triangle
;
2808 return flat_8R8G8B_z_triangle
;
2810 return flat_5R6G5B_z_triangle
;
2812 return flat_DITHER8_z_triangle
;
2814 return flat_ci_z_triangle
;
2819 if ( ctx
->RasterMask
==0 /* no depth test */
2820 && ctx
->Light
.ShadeModel
==GL_SMOOTH
2821 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2822 switch (wmesa
->pixelformat
) {
2824 return smooth_8A8B8G8R_triangle
;
2826 return smooth_8R8G8B_triangle
;
2828 return smooth_5R6G5B_triangle
;
2830 return smooth_DITHER8_triangle
;
2832 return smooth_ci_triangle
;
2838 if ( ctx
->RasterMask
==0 /* no depth test */
2839 && ctx
->Light
.ShadeModel
==GL_FLAT
2840 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2841 switch (wmesa
->pixelformat
) {
2843 return flat_8A8B8G8R_triangle
;
2845 return flat_8R8G8B_triangle
;
2847 return flat_5R6G5B_triangle
;
2849 return flat_DITHER8_triangle
;
2851 return flat_ci_triangle
;
2862 * Define a new viewport and reallocate auxillary buffers if the size of
2863 * the window (color buffer) has changed.
2865 void WMesaViewport( GLcontext
*ctx
,
2866 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2869 ctx
->Viewport
.X
= x
;
2870 ctx
->Viewport
.Width
= width
;
2871 ctx
->Viewport
.Y
= y
;
2872 ctx
->Viewport
.Height
= height
;
2874 /* compute scale and bias values */
2875 ctx
->Viewport
.Sx
= (GLfloat
) width
/ 2.0F
;
2876 ctx
->Viewport
.Tx
= ctx
->Viewport
.Sx
+ x
;
2877 ctx
->Viewport
.Sy
= (GLfloat
) height
/ 2.0F
;
2878 ctx
->Viewport
.Ty
= ctx
->Viewport
.Sy
+ y
;