1 /* $Id: wmesa.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
25 * Revision 1.1 1999/08/19 00:55:42 jtg
28 * Revision 3.10 1999/06/15 01:35:06 brianp
29 * small change to wmSetPixel() from TWILMOT@cpr.fr
31 * Revision 3.9 1999/05/11 19:06:01 brianp
32 * fixed a few VB->Index bugs (mikec@ensoniq.com)
34 * Revision 3.8 1999/05/08 15:15:23 brianp
35 * various updates from mikec@ensoniq.com
37 * Revision 3.7 1999/04/01 01:27:34 brianp
38 * always flip Y coord in read_rgba_span()
40 * Revision 3.6 1999/03/28 21:17:27 brianp
41 * updated SetBuffer driver function
43 * Revision 3.5 1999/03/16 01:36:42 brianp
44 * patched dither() to check if Current is NULL, per xzhou@nyx.net
46 * Revision 3.4 1999/02/25 14:12:33 keithw
49 * Revision 3.3 1999/01/03 03:08:57 brianp
52 * Revision 3.2 1998/08/29 00:26:01
53 * updated for Mesa 3.0 to accomodate EGCS-Mingw32 build
55 * Revision 3.1 1998/06/11 01:42:08 brianp
56 * updated for Mesa 3.0 device driver interface (but not tested)
58 * Revision 3.0 1998/06/11 01:18:25 brianp
64 #define WMESA_STEREO_C
70 #include "mesa_extend.h"
81 #pragma warning ( disable : 4133 4761 )
84 // #include "profile.h"
94 #define CopyMemory memcpy
97 #if !defined(NO_STEREO)
103 #if !defined(NO_PARALLEL)
104 // #include "parallel.h"
107 struct DISPLAY_OPTIONS displayOptions
;
109 GLenum stereoCompile
= GL_FALSE
;
110 GLenum stereoShowing
= GL_FALSE
;
111 GLenum stereoBuffer
= GL_FALSE
;
112 #if !defined(NO_STEREO)
113 GLint displayList
= MAXIMUM_DISPLAY_LIST
;
115 GLint stereo_flag
= 0 ;
117 /* end of added code*/
119 static PWMC Current
= NULL
;
120 WMesaContext WC
= NULL
;
123 #define assert(ignore) ((void) 0)
125 void Mesa_Assert(void *Cond
,void *File
,unsigned Line
)
128 sprintf(Msg
,"%s %s %d",Cond
,File
,Line
);
129 MessageBox(NULL
,Msg
,"Assertion failed.",MB_OK
);
132 #define assert(e) if (!e) Mesa_Assert(#e,__FILE__,__LINE__);
135 //#define DD_GETDC (Current->hDC )
136 #define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
137 //#define DD_GETDC ((Current->db_flag) ? Current->hDCPrimary : Current->hDCBack )
140 //#define BEGINGDICALL if(Current->rgb_flag)wmFlushBits(Current);
142 //#define ENDGDICALL if(Current->rgb_flag)wmGetBits(Current);
145 //#define FLIP(Y) (Current->dither_flag? Y : Current->height-(Y)-1)
146 //#define FLIP(Y) (Current->height-(Y)-1)
149 * XXX Why only flip Y coord if single buffered???
151 #define FLIP(Y) (Current->db_flag? Y: Current->height-(Y)-1)
153 #define ENDPROFILE(PARA)
155 #define DITHER_RGB_TO_8BIT_SETUP \
156 GLubyte pixelDithered;
158 #define DITHER_RGB_TO_8BIT(red, green, blue, pixel, scanline) \
160 char unsigned redtemp, greentemp, bluetemp, paletteindex; \
161 redtemp = aDividedBy51[red] \
162 + (aModulo51[red] > aHalftone8x8[(pixel%8)*8 \
164 greentemp = aDividedBy51[(char unsigned)green] \
165 + (aModulo51[green] > aHalftone8x8[ \
166 (pixel%8)*8 + scanline%8]); \
167 bluetemp = aDividedBy51[(char unsigned)blue] \
168 + (aModulo51[blue] > aHalftone8x8[ \
169 (pixel%8)*8 +scanline%8]); \
170 paletteindex = redtemp + aTimes6[greentemp] + aTimes36[bluetemp]; \
171 pixelDithered = aWinGHalftoneTranslation[paletteindex]; \
176 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
);
177 static void DDFree( WMesaContext wc
);
178 static HRESULT
DDRestoreAll( WMesaContext wc
);
179 static void DDDeleteOffScreen(WMesaContext wc
);
180 static BOOL
DDCreateOffScreen(WMesaContext wc
);
183 static void FlushToFile(PWMC pwc
, PSTR szFile
);
185 BOOL
wmCreateBackingStore(PWMC pwc
, long lxSize
, long lySize
);
186 BOOL
wmDeleteBackingStore(PWMC pwc
);
187 void wmCreatePalette( PWMC pwdc
);
188 BOOL
wmSetDibColors(PWMC pwc
);
189 void wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
);
191 void wmCreateDIBSection(
193 PWMC pwc
, // handle of device context
194 CONST BITMAPINFO
*pbmi
, // address of structure containing bitmap size, format, and color data
195 UINT iUsage
// color data type indicator: RGB values or palette indices
199 void WMesaViewport( GLcontext
*ctx
,
200 GLint x
, GLint y
, GLsizei width
, GLsizei height
);
203 static triangle_func
choose_triangle_function( GLcontext
*ctx
);
206 static void wmSetPixelFormat( PWMC wc
, HDC hDC
)
209 wc
->cColorBits
= GetDeviceCaps(hDC
, BITSPIXEL
);
212 switch(wc
->cColorBits
){
214 if(wc
->dither_flag
!= GL_TRUE
)
215 wc
->pixelformat
= PF_INDEX8
;
217 wc
->pixelformat
= PF_DITHER8
;
220 wc
->pixelformat
= PF_5R6G5B
;
223 wc
->pixelformat
= PF_8R8G8B
;
226 wc
->pixelformat
= PF_BADFORMAT
;
231 // This function sets the color table of a DIB section
232 // to match that of the destination DC
234 BOOL
/*WINAPI*/ wmSetDibColors(PWMC pwc
)
236 RGBQUAD
*pColTab
, *pRGB
;
237 PALETTEENTRY
*pPal
, *pPE
;
242 /* Build a color table in the DIB that maps to the
243 selected palette in the DC.
245 nColors
= 1 << pwc
->cColorBits
;
246 pPal
= (PALETTEENTRY
*)malloc( nColors
* sizeof(PALETTEENTRY
));
247 memset( pPal
, 0, nColors
* sizeof(PALETTEENTRY
) );
248 GetPaletteEntries( pwc
->hGLPalette
, 0, nColors
, pPal
);
249 pColTab
= (RGBQUAD
*)malloc( nColors
* sizeof(RGBQUAD
));
250 for (i
= 0, pRGB
= pColTab
, pPE
= pPal
; i
< nColors
; i
++, pRGB
++, pPE
++) {
251 pRGB
->rgbRed
= pPE
->peRed
;
252 pRGB
->rgbGreen
= pPE
->peGreen
;
253 pRGB
->rgbBlue
= pPE
->peBlue
;
256 bRet
= SetDIBColorTable(pwc
->dib
.hDC
, 0, nColors
, pColTab
);
259 dwErr
= GetLastError();
269 // Free up the dib section that was created
271 BOOL
wmDeleteBackingStore(PWMC pwc
)
273 SelectObject(pwc
->dib
.hDC
, pwc
->hOldBitmap
);
274 DeleteDC(pwc
->dib
.hDC
);
275 DeleteObject(pwc
->hbmDIB
);
276 UnmapViewOfFile(pwc
->dib
.base
);
277 CloseHandle(pwc
->dib
.hFileMap
);
283 // This function creates the DIB section that is used for combined
286 BOOL
/*WINAPI*/ wmCreateBackingStore(PWMC pwc
, long lxSize
, long lySize
)
289 LPBITMAPINFO pbmi
= &(pwc
->bmi
);
292 pbmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
293 pbmi
->bmiHeader
.biWidth
= lxSize
;
294 pbmi
->bmiHeader
.biHeight
= -lySize
;
295 pbmi
->bmiHeader
.biPlanes
= 1;
297 pbmi
->bmiHeader
.biBitCount
= GetDeviceCaps(pwc
->hDC
, BITSPIXEL
);
299 pbmi
->bmiHeader
.biBitCount
= 8;
300 pbmi
->bmiHeader
.biCompression
= BI_RGB
;
301 pbmi
->bmiHeader
.biSizeImage
= 0;
302 pbmi
->bmiHeader
.biXPelsPerMeter
= 0;
303 pbmi
->bmiHeader
.biYPelsPerMeter
= 0;
304 pbmi
->bmiHeader
.biClrUsed
= 0;
305 pbmi
->bmiHeader
.biClrImportant
= 0;
307 iUsage
= (pbmi
->bmiHeader
.biBitCount
<= 8) ? DIB_PAL_COLORS
: DIB_RGB_COLORS
;
309 pwc
->cColorBits
= pbmi
->bmiHeader
.biBitCount
;
310 pwc
->ScanWidth
= pwc
->pitch
= lxSize
;
312 wmCreateDIBSection(hdc
, pwc
, pbmi
, iUsage
);
314 if ((iUsage
== DIB_PAL_COLORS
) && !(pwc
->hGLPalette
)) {
315 wmCreatePalette( pwc
);
316 wmSetDibColors( pwc
);
318 wmSetPixelFormat(pwc
, pwc
->hDC
);
325 // This function copies one scan line in a DIB section to another
327 BOOL WINAPI
wmSetDIBits(PWMC pwc
, UINT uiScanWidth
, UINT uiNumScans
, UINT nBypp
, UINT uiNewWidth
, LPBYTE pBits
)
330 LPBYTE pDest
= pwc
->pbPixels
;
331 DWORD dwNextScan
= uiScanWidth
;
332 DWORD dwNewScan
= uiNewWidth
;
333 DWORD dwScanWidth
= (uiScanWidth
* nBypp
);
336 // We need to round up to the nearest DWORD
337 // and multiply by the number of bytes per
340 dwNextScan
= (((dwNextScan
* nBypp
)+ 3) & ~3);
341 dwNewScan
= (((dwNewScan
* nBypp
)+ 3) & ~3);
343 for(uiScans
= 0; uiScans
< uiNumScans
; uiScans
++){
344 CopyMemory(pDest
, pBits
, dwScanWidth
);
354 BOOL
wmFlush(PWMC pwc
);
358 Modified from file osmesa.c
362 #define PIXELADDR(X,Y) ((GLubyte *)Current->pbPixels + (Current->height-Y-1)* Current->ScanWidth + (X)*nBypp)
363 #define PIXELADDR1( X, Y ) \
364 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X))
365 #define PIXELADDR2( X, Y ) \
366 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*2)
367 #define PIXELADDR4( X, Y ) \
368 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*4)
371 BYTE
DITHER_RGB_2_8BIT( int r
, int g
, int b
, int x
, int y
);
373 /* Finish all pending operations and synchronize. */
374 static void finish(GLcontext
* ctx
)
381 // We cache all gl draw routines until a flush is made
383 static void flush(GLcontext
* ctx
)
386 if((Current
->rgb_flag
/*&& !(Current->dib.fFlushed)*/&&!(Current
->db_flag
))
387 ||(!Current
->rgb_flag
))
398 * Set the color index used to clear the color buffer.
400 static void clear_index(GLcontext
* ctx
, GLuint index
)
403 Current
->clearpixel
= index
;
404 ENDPROFILE(clear_index
)
410 * Set the color used to clear the color buffer.
412 static void clear_color( GLcontext
* ctx
, GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
415 Current
->clearpixel
=RGB(r
, g
, b
);
416 ENDPROFILE(clear_color
)
422 * Clear the specified region of the color buffer using the clear color
423 * or index as specified by one of the two functions above.
425 //static void clear(GLcontext* ctx,
426 // GLboolean all,GLint x, GLint y, GLint width, GLint height )
427 // TODO: I modified this function to match the prototype in dd.h. (swansma@geocities.com)
428 // dd.h does not explain what the return type is so I could not set this to the proper
430 static GLbitfield
clear(GLcontext
* ctx
, GLbitfield mask
,
431 GLboolean all
, GLint x
, GLint y
, GLint width
, GLint height
)
436 LPDWORD lpdw
= (LPDWORD
)Current
->pbPixels
;
437 LPWORD lpw
= (LPWORD
)Current
->pbPixels
;
438 LPBYTE lpb
= Current
->pbPixels
;
445 width
=Current
->width
;
446 height
=Current
->height
;
448 if(Current
->db_flag
==GL_TRUE
){
449 UINT nBypp
= Current
->cColorBits
/ 8;
454 /* Need rectification */
455 iSize
= Current
->width
/4;
456 bColor
= BGR8(GetRValue(Current
->clearpixel
),
457 GetGValue(Current
->clearpixel
),
458 GetBValue(Current
->clearpixel
));
459 wColor
= MAKEWORD(bColor
,bColor
);
460 dwColor
= MAKELONG(wColor
, wColor
);
463 iSize
= Current
->width
/ 2;
464 wColor
= BGR16(GetRValue(Current
->clearpixel
),
465 GetGValue(Current
->clearpixel
),
466 GetBValue(Current
->clearpixel
));
467 dwColor
= MAKELONG(wColor
, wColor
);
470 iSize
= Current
->width
;
471 dwColor
= BGR32(GetRValue(Current
->clearpixel
),
472 GetGValue(Current
->clearpixel
),
473 GetBValue(Current
->clearpixel
));
483 // This is the 24bit case
486 iSize
= Current
->width
*3/4;
487 dwColor
= BGR24(GetRValue(Current
->clearpixel
),
488 GetGValue(Current
->clearpixel
),
489 GetBValue(Current
->clearpixel
));
504 memcpy(lpb
, Current
->pbPixels
, iSize
*4);
505 lpb
+= Current
->ScanWidth
;
510 else { // For single buffer
512 HPEN Pen
=CreatePen(PS_SOLID
,1,Current
->clearpixel
);
513 HBRUSH Brush
=CreateSolidBrush(Current
->clearpixel
);
514 HPEN Old_Pen
=SelectObject(DC
,Pen
);
515 HBRUSH Old_Brush
=SelectObject(DC
,Brush
);
516 Rectangle(DC
,x
,y
,x
+width
,y
+height
);
517 SelectObject(DC
,Old_Pen
);
518 SelectObject(DC
,Old_Brush
);
528 return mask
; // TODO: I doubt this is correct. dd.h doesn't explain what this should
534 /* Set the current color index. */
535 static void set_index(GLcontext
* ctx
, GLuint index
)
538 Current
->pixel
=index
;
539 ENDPROFILE(set_index
)
544 /* Set the current RGBA color. */
545 static void set_color( GLcontext
* ctx
, GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
548 Current
->pixel
= RGB( r
, g
, b
);
549 ENDPROFILE(set_color
)
554 /* Set the index mode bitplane mask. */
555 static GLboolean
index_mask(GLcontext
* ctx
, GLuint mask
)
557 /* can't implement */
563 /* Set the RGBA drawing mask. */
564 static GLboolean
color_mask( GLcontext
* ctx
,
565 GLboolean rmask
, GLboolean gmask
,
566 GLboolean bmask
, GLboolean amask
)
568 /* can't implement */
575 * Set the pixel logic operation. Return GL_TRUE if the device driver
576 * can perform the operation, otherwise return GL_FALSE. If GL_FALSE
577 * is returned, the logic op will be done in software by Mesa.
579 GLboolean
logicop( GLcontext
* ctx
, GLenum op
)
581 /* can't implement */
586 static void dither( GLcontext
* ctx
, GLboolean enable
)
591 if(enable
== GL_FALSE
){
592 Current
->dither_flag
= GL_FALSE
;
593 if(Current
->cColorBits
== 8)
594 Current
->pixelformat
= PF_INDEX8
;
597 if (Current
->rgb_flag
&& Current
->cColorBits
== 8){
598 Current
->pixelformat
= PF_DITHER8
;
599 Current
->dither_flag
= GL_TRUE
;
602 Current
->dither_flag
= GL_FALSE
;
608 static GLboolean
set_buffer( GLcontext
* ctx
, GLenum mode
)
611 /* TODO: this could be better */
612 if (mode
==GL_FRONT_LEFT
|| mode
==GL_BACK_LEFT
) {
618 ENDPROFILE(set_buffer
)
623 /* Return characteristics of the output buffer. */
624 static void buffer_size( GLcontext
* ctx
, GLuint
*width
, GLuint
*height
)
630 GetClientRect(Current
->Window
,&CR
);
635 New_Size
=((*width
)!=Current
->width
) || ((*height
)!=Current
->height
);
638 Current
->width
=*width
;
639 Current
->height
=*height
;
640 Current
->ScanWidth
=Current
->width
;
641 if ((Current
->ScanWidth
%sizeof(long))!=0)
642 Current
->ScanWidth
+=(sizeof(long)-(Current
->ScanWidth
%sizeof(long)));
644 if (Current
->db_flag
){
646 DDDeleteOffScreen(Current
);
647 DDCreateOffScreen(Current
);
649 if (Current
->rgb_flag
==GL_TRUE
&& Current
->dither_flag
!=GL_TRUE
){
650 wmDeleteBackingStore(Current
);
651 wmCreateBackingStore(Current
, Current
->width
, Current
->height
);
656 // Resize OsmesaBuffer if in Parallel mode
657 #if !defined(NO_PARALLEL)
659 PRSizeRenderBuffer(Current
->width
, Current
->height
,Current
->ScanWidth
,
660 Current
->rgb_flag
== GL_TRUE
? Current
->pbPixels
: Current
->ScreenMem
);
663 ENDPROFILE(buffer_size
)
668 /**********************************************************************/
669 /***** Accelerated point, line, polygon rendering *****/
670 /**********************************************************************/
673 static void fast_rgb_points( GLcontext
* ctx
, GLuint first
, GLuint last
)
681 if (0 /*Current->gl_ctx->VB->MonoColor*/) {
682 /* all drawn with current color */
683 for (i
=first
;i
<=last
;i
++) {
684 if (!Current
->gl_ctx
->VB
->ClipMask
[i
]) {
686 x
= (GLint
) Current
->gl_ctx
->VB
->Win
.data
[i
][0];
687 y
= FLIP( (GLint
) Current
->gl_ctx
->VB
->Win
.data
[i
][1] );
688 wmSetPixel(pwc
, y
,x
,GetRValue(Current
->pixel
),
689 GetGValue(Current
->pixel
), GetBValue(Current
->pixel
));
694 /* draw points of different colors */
695 for (i
=first
;i
<=last
;i
++) {
696 if (!Current
->gl_ctx
->VB
->ClipMask
[i
]) {
698 unsigned long pixel
=RGB(Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][0]*255.0,
699 Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][1]*255.0,
700 Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][2]*255.0);
701 x
= (GLint
) Current
->gl_ctx
->VB
->Win
.data
[i
][0];
702 y
= FLIP( (GLint
) Current
->gl_ctx
->VB
->Win
.data
[i
][1] );
703 wmSetPixel(pwc
, y
,x
,Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][0]*255.0,
704 Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][1]*255.0,
705 Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][2]*255.0);
710 ENDPROFILE(fast_rgb_points
)
715 /* Return pointer to accerated points function */
716 extern points_func
choose_points_function( GLcontext
* ctx
)
719 if (ctx
->Point
.Size
==1.0 && !ctx
->Point
.SmoothFlag
&& ctx
->RasterMask
==0
720 && !ctx
->Texture
.Enabled
&& ctx
->Visual
->RGBAflag
) {
721 ENDPROFILE(choose_points_function
)
722 return fast_rgb_points
;
725 ENDPROFILE(choose_points_function
)
732 /* Draw a line using the color specified by Current->gl_ctx->VB->ColorPtr->data[pv] */
733 static void fast_flat_rgb_line( GLcontext
* ctx
, GLuint v0
, GLuint v1
, GLuint pv
)
742 if (0 /*Current->gl_ctx->VB->MonoColor*/) {
743 pixel
= Current
->pixel
; /* use current color */
746 pixel
= RGB(Current
->gl_ctx
->VB
->ColorPtr
->data
[pv
][0]*255.0, Current
->gl_ctx
->VB
->ColorPtr
->data
[pv
][1]*255.0, Current
->gl_ctx
->VB
->ColorPtr
->data
[pv
][2]*255.0);
749 x0
= (int) Current
->gl_ctx
->VB
->Win
.data
[v0
][0];
750 y0
= FLIP( (int) Current
->gl_ctx
->VB
->Win
.data
[v0
][1] );
751 x1
= (int) Current
->gl_ctx
->VB
->Win
.data
[v1
][0];
752 y1
= FLIP( (int) Current
->gl_ctx
->VB
->Win
.data
[v1
][1] );
757 Pen
=CreatePen(PS_SOLID
,1,pixel
);
758 Old_Pen
=SelectObject(DC
,Pen
);
759 MoveToEx(DC
,x0
,y0
,NULL
);
761 SelectObject(DC
,Old_Pen
);
767 ENDPROFILE(fast_flat_rgb_line
)
772 /* Return pointer to accerated line function */
773 static line_func
choose_line_function( GLcontext
* ctx
)
776 if (ctx
->Line
.Width
==1.0 && !ctx
->Line
.SmoothFlag
&& !ctx
->Line
.StippleFlag
777 && ctx
->Light
.ShadeModel
==GL_FLAT
&& ctx
->RasterMask
==0
778 && !ctx
->Texture
.Enabled
&& Current
->rgb_flag
) {
779 ENDPROFILE(choose_line_function
)
780 return fast_flat_rgb_line
;
783 ENDPROFILE(choose_line_function
)
789 /**********************************************************************/
790 /***** Span-based pixel drawing *****/
791 /**********************************************************************/
794 /* Write a horizontal span of 32-bit color-index pixels with a boolean mask. */
795 static void write_ci32_span( const GLcontext
* ctx
,
796 GLuint n
, GLint x
, GLint y
,
797 const GLuint index
[],
798 const GLubyte mask
[] )
802 PBYTE Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
803 assert(Current
->rgb_flag
==GL_FALSE
);
807 ENDPROFILE(write_ci32_span
)
811 /* Write a horizontal span of 8-bit color-index pixels with a boolean mask. */
812 static void write_ci8_span( const GLcontext
* ctx
,
813 GLuint n
, GLint x
, GLint y
,
814 const GLubyte index
[],
815 const GLubyte mask
[] )
819 PBYTE Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
820 assert(Current
->rgb_flag
==GL_FALSE
);
824 ENDPROFILE(write_ci8_span
)
830 * Write a horizontal span of pixels with a boolean mask. The current
831 * color index is used for all pixels.
833 static void write_mono_ci_span(const GLcontext
* ctx
,
834 GLuint n
,GLint x
,GLint y
,
835 const GLubyte mask
[])
839 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
840 assert(Current
->rgb_flag
==GL_FALSE
);
843 Mem
[i
]=Current
->pixel
;
844 ENDPROFILE(write_mono_ci_span
)
848 * To improve the performance of this routine, frob the data into an actual
849 * scanline and call bitblt on the complete scan line instead of SetPixel.
852 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
853 static void write_rgba_span( const GLcontext
* ctx
, GLuint n
, GLint x
, GLint y
,
854 const GLubyte rgba
[][4], const GLubyte mask
[] )
859 if (pwc
->rgb_flag
==GL_TRUE
)
867 wmSetPixel(pwc
, y
, x
+ i
, rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
871 wmSetPixel(pwc
, y
, x
+ i
, rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
] );
878 BYTE
*Mem
=Current
->ScreenMem
+y
*Current
->ScanWidth
+x
;
883 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]));
887 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]));
890 ENDPROFILE(write_rgba_span
)
894 /* Write a horizontal span of RGB color pixels with a boolean mask. */
895 static void write_rgb_span( const GLcontext
* ctx
,
896 GLuint n
, GLint x
, GLint y
,
897 const GLubyte rgb
[][3], const GLubyte mask
[] )
902 if (pwc
->rgb_flag
==GL_TRUE
)
910 wmSetPixel(pwc
, y
, x
+ i
, rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]);
914 wmSetPixel(pwc
, y
, x
+ i
, rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
] );
921 BYTE
*Mem
=Current
->ScreenMem
+y
*Current
->ScanWidth
+x
;
926 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]));
930 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]));
933 ENDPROFILE(write_rgb_span
)
938 * Write a horizontal span of pixels with a boolean mask. The current color
939 * is used for all pixels.
941 static void write_mono_rgba_span( const GLcontext
* ctx
,
942 GLuint n
, GLint x
, GLint y
,
943 const GLubyte mask
[])
949 assert(Current
->rgb_flag
==GL_TRUE
);
951 if(Current
->rgb_flag
==GL_TRUE
){
955 wmSetPixel(pwc
,y
,x
+i
,GetRValue(Current
->pixel
), GetGValue(Current
->pixel
), GetBValue(Current
->pixel
));
960 SetPixel(DC
, y
, x
+i
, Current
->pixel
);
963 ENDPROFILE(write_mono_rgba_span
)
968 /**********************************************************************/
969 /***** Array-based pixel drawing *****/
970 /**********************************************************************/
973 /* Write an array of 32-bit index pixels with a boolean mask. */
974 static void write_ci32_pixels( const GLcontext
* ctx
,
975 GLuint n
, const GLint x
[], const GLint y
[],
976 const GLuint index
[], const GLubyte mask
[] )
980 assert(Current
->rgb_flag
==GL_FALSE
);
981 for (i
=0; i
<n
; i
++) {
983 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
];
987 ENDPROFILE(write_ci32_pixels
)
993 * Write an array of pixels with a boolean mask. The current color
994 * index is used for all pixels.
996 static void write_mono_ci_pixels( const GLcontext
* ctx
,
998 const GLint x
[], const GLint y
[],
999 const GLubyte mask
[] )
1003 assert(Current
->rgb_flag
==GL_FALSE
);
1004 for (i
=0; i
<n
; i
++) {
1006 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
];
1007 *Mem
= Current
->pixel
;
1010 ENDPROFILE(write_mono_ci_pixels
)
1015 /* Write an array of RGBA pixels with a boolean mask. */
1016 static void write_rgba_pixels( const GLcontext
* ctx
,
1017 GLuint n
, const GLint x
[], const GLint y
[],
1018 const GLubyte rgba
[][4], const GLubyte mask
[] )
1024 assert(Current
->rgb_flag
==GL_TRUE
);
1027 wmSetPixel(pwc
, FLIP(y
[i
]),x
[i
],rgba
[i
][RCOMP
],rgba
[i
][GCOMP
],rgba
[i
][BCOMP
]);
1029 ENDPROFILE(write_rgba_pixels
)
1035 * Write an array of pixels with a boolean mask. The current color
1036 * is used for all pixels.
1038 static void write_mono_rgba_pixels( const GLcontext
* ctx
,
1040 const GLint x
[], const GLint y
[],
1041 const GLubyte mask
[] )
1047 assert(Current
->rgb_flag
==GL_TRUE
);
1050 wmSetPixel(pwc
, FLIP(y
[i
]),x
[i
],GetRValue(Current
->pixel
),
1051 GetGValue(Current
->pixel
), GetBValue(Current
->pixel
));
1053 ENDPROFILE(write_mono_rgba_pixels
)
1058 /**********************************************************************/
1059 /***** Read spans/arrays of pixels *****/
1060 /**********************************************************************/
1063 /* Read a horizontal span of color-index pixels. */
1064 static void read_ci32_span( const GLcontext
* ctx
, GLuint n
, GLint x
, GLint y
,
1069 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
1070 assert(Current
->rgb_flag
==GL_FALSE
);
1073 ENDPROFILE(read_ci32_span
)
1079 /* Read an array of color index pixels. */
1080 static void read_ci32_pixels( const GLcontext
* ctx
,
1081 GLuint n
, const GLint x
[], const GLint y
[],
1082 GLuint indx
[], const GLubyte mask
[] )
1086 assert(Current
->rgb_flag
==GL_FALSE
);
1087 for (i
=0; i
<n
; i
++) {
1089 indx
[i
]=*(Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
]);
1092 ENDPROFILE(read_ci32_pixels
)
1097 /* Read a horizontal span of color pixels. */
1098 static void read_rgba_span( const GLcontext
* ctx
,
1099 GLuint n
, GLint x
, GLint y
,
1106 assert(Current
->rgb_flag
==GL_TRUE
);
1108 y
= Current
->height
- y
- 1;
1109 for (i
=0; i
<n
; i
++) {
1110 Color
=GetPixel(DC
,x
+i
,y
);
1111 rgba
[i
][RCOMP
] = GetRValue(Color
);
1112 rgba
[i
][GCOMP
] = GetGValue(Color
);
1113 rgba
[i
][BCOMP
] = GetBValue(Color
);
1114 rgba
[i
][ACOMP
] = 255;
1117 // Brian P. Has mentioned to comment this out.
1118 // memset(alpha,0,n*sizeof(GLubyte));
1119 ENDPROFILE(read_rgba_span
)
1123 /* Read an array of color pixels. */
1124 static void read_rgba_pixels( const GLcontext
* ctx
,
1125 GLuint n
, const GLint x
[], const GLint y
[],
1126 GLubyte rgba
[][4], const GLubyte mask
[] )
1132 assert(Current
->rgb_flag
==GL_TRUE
);
1133 for (i
=0; i
<n
; i
++) {
1135 Color
=GetPixel(DC
,x
[i
],FLIP(y
[i
]));
1136 rgba
[i
][RCOMP
] = GetRValue(Color
);
1137 rgba
[i
][GCOMP
] = GetGValue(Color
);
1138 rgba
[i
][BCOMP
] = GetBValue(Color
);
1139 rgba
[i
][ACOMP
] = 255;
1143 // Brian P. has mentioned to comment this out.
1144 // memset(alpha,0,n*sizeof(GLint));
1145 ENDPROFILE(read_rgba_pixels
)
1150 /**********************************************************************/
1151 /**********************************************************************/
1154 static const char *renderer_string(void)
1161 void setup_DD_pointers( GLcontext
* ctx
)
1163 ctx
->Driver
.RendererString
= renderer_string
;
1164 ctx
->Driver
.UpdateState
= setup_DD_pointers
;
1165 ctx
->Driver
.GetBufferSize
= buffer_size
;
1166 ctx
->Driver
.Finish
= finish
;
1167 ctx
->Driver
.Flush
= flush
;
1169 ctx
->Driver
.ClearIndex
= clear_index
;
1170 ctx
->Driver
.ClearColor
= clear_color
;
1171 ctx
->Driver
.Clear
= clear
;
1173 ctx
->Driver
.Index
= set_index
;
1174 ctx
->Driver
.Color
= set_color
;
1175 ctx
->Driver
.IndexMask
= index_mask
;
1176 ctx
->Driver
.ColorMask
= color_mask
;
1178 ctx
->Driver
.LogicOp
= logicop
;
1179 ctx
->Driver
.Dither
= dither
;
1181 ctx
->Driver
.SetBuffer
= set_buffer
;
1182 ctx
->Driver
.GetBufferSize
= buffer_size
;
1184 ctx
->Driver
.PointsFunc
= choose_points_function(ctx
);
1185 ctx
->Driver
.LineFunc
= choose_line_function(ctx
);
1186 ctx
->Driver
.TriangleFunc
= choose_triangle_function( ctx
);
1188 /* Pixel/span writing functions: */
1189 ctx
->Driver
.WriteRGBASpan
= write_rgba_span
;
1190 ctx
->Driver
.WriteRGBSpan
= write_rgb_span
;
1191 ctx
->Driver
.WriteMonoRGBASpan
= write_mono_rgba_span
;
1192 ctx
->Driver
.WriteRGBAPixels
= write_rgba_pixels
;
1193 ctx
->Driver
.WriteMonoRGBAPixels
= write_mono_rgba_pixels
;
1194 ctx
->Driver
.WriteCI32Span
= write_ci32_span
;
1195 ctx
->Driver
.WriteCI8Span
= write_ci8_span
;
1196 ctx
->Driver
.WriteMonoCISpan
= write_mono_ci_span
;
1197 ctx
->Driver
.WriteCI32Pixels
= write_ci32_pixels
;
1198 ctx
->Driver
.WriteMonoCIPixels
= write_mono_ci_pixels
;
1200 ctx
->Driver
.ReadCI32Span
= read_ci32_span
;
1201 ctx
->Driver
.ReadRGBASpan
= read_rgba_span
;
1202 ctx
->Driver
.ReadCI32Pixels
= read_ci32_pixels
;
1203 ctx
->Driver
.ReadRGBAPixels
= read_rgba_pixels
;
1207 /**********************************************************************/
1208 /***** WMesa API Functions *****/
1209 /**********************************************************************/
1213 #define PAL_SIZE 256
1214 static void GetPalette(HPALETTE Pal
,RGBQUAD
*aRGB
)
1222 WORD NumberOfEntries
;
1223 PALETTEENTRY aEntries
[PAL_SIZE
];
1231 GetPaletteEntries(Pal
,0,PAL_SIZE
,Palette
.aEntries
);
1233 GetSystemPaletteEntries(hdc
,0,PAL_SIZE
,Palette
.aEntries
);
1234 if (GetSystemPaletteUse(hdc
) == SYSPAL_NOSTATIC
)
1236 for(i
= 0; i
<PAL_SIZE
; i
++)
1237 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1238 Palette
.aEntries
[255].peRed
= 255;
1239 Palette
.aEntries
[255].peGreen
= 255;
1240 Palette
.aEntries
[255].peBlue
= 255;
1241 Palette
.aEntries
[255].peFlags
= 0;
1242 Palette
.aEntries
[0].peRed
= 0;
1243 Palette
.aEntries
[0].peGreen
= 0;
1244 Palette
.aEntries
[0].peBlue
= 0;
1245 Palette
.aEntries
[0].peFlags
= 0;
1251 nStaticColors
= GetDeviceCaps(hdc
, NUMCOLORS
)/2;
1252 for (i
=0; i
<nStaticColors
; i
++)
1253 Palette
.aEntries
[i
].peFlags
= 0;
1254 nUsableColors
= PAL_SIZE
-nStaticColors
;
1255 for (; i
<nUsableColors
; i
++)
1256 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1257 for (; i
<PAL_SIZE
-nStaticColors
; i
++)
1258 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1259 for (i
=PAL_SIZE
-nStaticColors
; i
<PAL_SIZE
; i
++)
1260 Palette
.aEntries
[i
].peFlags
= 0;
1262 ReleaseDC(NULL
,hdc
);
1263 for (i
=0; i
<PAL_SIZE
; i
++)
1265 aRGB
[i
].rgbRed
=Palette
.aEntries
[i
].peRed
;
1266 aRGB
[i
].rgbGreen
=Palette
.aEntries
[i
].peGreen
;
1267 aRGB
[i
].rgbBlue
=Palette
.aEntries
[i
].peBlue
;
1268 aRGB
[i
].rgbReserved
=Palette
.aEntries
[i
].peFlags
;
1270 ENDPROFILE(GetPalette
)
1274 WMesaContext
WMesaCreateContext( HWND hWnd
, HPALETTE
* Pal
,
1280 GLboolean true_color_flag
;
1281 c
= (struct wmesa_context
* ) calloc(1,sizeof(struct wmesa_context
));
1286 c
->hDC
= GetDC(hWnd
);
1287 true_color_flag
= GetDeviceCaps(c
->hDC
, BITSPIXEL
) > 8;
1289 if(true_color_flag
) c
->rgb_flag
= rgb_flag
= GL_TRUE
;
1294 if ((true_color_flag
==GL_FALSE
) && (rgb_flag
== GL_TRUE
)){
1295 c
->dither_flag
= GL_TRUE
;
1296 c
->hPalHalfTone
= WinGCreateHalftonePalette();
1299 c
->dither_flag
= GL_FALSE
;
1301 c
->dither_flag
= GL_FALSE
;
1305 if (rgb_flag
==GL_FALSE
)
1307 c
->rgb_flag
= GL_FALSE
;
1309 c
->db_flag
= db_flag
=GL_TRUE
; // WinG requires double buffering
1310 printf("Single buffer is not supported in color index mode, setting to double buffer.\n");
1314 c
->rgb_flag
= GL_TRUE
;
1317 GetClientRect(c
->Window
,&CR
);
1319 c
->height
=CR
.bottom
;
1323 /* Double buffered */
1325 // if (c->rgb_flag==GL_TRUE && c->dither_flag != GL_TRUE )
1327 wmCreateBackingStore(c
, c
->width
, c
->height
);
1334 /* Single Buffered */
1339 if (DDInit(c
,hWnd
) == GL_FALSE
) {
1346 c
->gl_visual
= gl_create_visual(rgb_flag
,
1347 GL_FALSE
, /* software alpha */
1348 db_flag
, /* db_flag */
1349 GL_FALSE
, /* stereo */
1350 16, /* depth_bits */
1351 8, /* stencil_bits */
1354 8,8,8,8 ); /* r, g, b, a bits */
1356 if (!c
->gl_visual
) {
1360 /* allocate a new Mesa context */
1361 c
->gl_ctx
= gl_create_context( c
->gl_visual
, NULL
, c
, GL_TRUE
);
1364 gl_destroy_visual( c
->gl_visual
);
1369 c
->gl_buffer
= gl_create_framebuffer( c
->gl_visual
);
1370 if (!c
->gl_buffer
) {
1371 gl_destroy_visual( c
->gl_visual
);
1372 gl_destroy_context( c
->gl_ctx
);
1377 c
->gl_ctx
->Driver
.UpdateState
= setup_DD_pointers
;
1379 // setup_DD_pointers(c->gl_ctx);
1384 void WMesaDestroyContext( void )
1386 WMesaContext c
= Current
;
1387 ReleaseDC(c
->Window
,c
->hDC
);
1389 if(c
->hPalHalfTone
!= NULL
)
1390 DeleteObject(c
->hPalHalfTone
);
1391 gl_destroy_visual( c
->gl_visual
);
1392 gl_destroy_framebuffer( c
->gl_buffer
);
1393 gl_destroy_context( c
->gl_ctx
);
1399 wmDeleteBackingStore(c
);
1402 //Following code is added to enable parallel render
1403 // Parallel render only work in double buffer mode
1404 #if !defined(NO_PARALLEL)
1406 PRDestroyRenderBuffer();
1413 void /*APIENTRY*/ WMesaMakeCurrent( WMesaContext c
)
1421 // A little optimization
1422 // If it already is current,
1423 // don't set it again
1428 //gl_set_context( c->gl_ctx );
1429 gl_make_current(c
->gl_ctx
, c
->gl_buffer
);
1430 setup_DD_pointers(c
->gl_ctx
);
1432 if (Current
->gl_ctx
->Viewport
.Width
==0) {
1433 /* initialize viewport to window size */
1434 gl_Viewport( Current
->gl_ctx
,
1435 0, 0, Current
->width
, Current
->height
);
1437 if ((c
->cColorBits
<= 8 ) && (c
->rgb_flag
== GL_TRUE
)){
1438 WMesaPaletteChange(c
->hPalHalfTone
);
1444 void /*APIENTRY*/ WMesaSwapBuffers( void )
1446 HDC DC
= Current
->hDC
;
1447 if (Current
->db_flag
)
1453 void /*APIENTRY*/ WMesaPaletteChange(HPALETTE Pal
)
1456 LPPALETTEENTRY pPal
;
1457 if (Current
&& (Current
->rgb_flag
==GL_FALSE
|| Current
->dither_flag
== GL_TRUE
))
1459 pPal
= (PALETTEENTRY
*)malloc( 256 * sizeof(PALETTEENTRY
));
1461 // GetPaletteEntries( Pal, 0, 256, pPal );
1462 GetPalette( Pal
, pPal
);
1464 Current
->lpDD
->lpVtbl
->CreatePalette(Current
->lpDD
,DDPCAPS_8BIT
,
1465 pPal
, &(Current
->lpDDPal
), NULL
);
1466 if (Current
->lpDDPal
)
1467 Current
->lpDDSPrimary
->lpVtbl
->SetPalette(Current
->lpDDSPrimary
,Current
->lpDDPal
);
1469 vRet
= SetDIBColorTable(Current
->dib
.hDC
,0,256,pPal
);
1479 static unsigned char threeto8
[8] = {
1480 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
1483 static unsigned char twoto8
[4] = {
1487 static unsigned char oneto8
[2] = {
1491 static unsigned char componentFromIndex(UCHAR i
, UINT nbits
, UINT shift
)
1508 return threeto8
[val
];
1515 void /*WINAPI*/ wmCreatePalette( PWMC pwdc
)
1517 /* Create a compressed and re-expanded 3:3:2 palette */
1520 BYTE rb
, rs
, gb
, gs
, bb
, bs
;
1522 pwdc
->nColors
= 0x100;
1524 pPal
= (PLOGPALETTE
)malloc(sizeof(LOGPALETTE
) + pwdc
->nColors
* sizeof(PALETTEENTRY
));
1525 memset( pPal
, 0, sizeof(LOGPALETTE
) + pwdc
->nColors
* sizeof(PALETTEENTRY
) );
1527 pPal
->palVersion
= 0x300;
1536 if (pwdc
->db_flag
) {
1538 /* Need to make two palettes: one for the screen DC and one for the DIB. */
1539 pPal
->palNumEntries
= pwdc
->nColors
;
1540 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1541 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1542 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1543 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1544 pPal
->palPalEntry
[i
].peFlags
= 0;
1546 pwdc
->hGLPalette
= CreatePalette( pPal
);
1547 pwdc
->hPalette
= CreatePalette( pPal
);
1551 pPal
->palNumEntries
= pwdc
->nColors
;
1552 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1553 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1554 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1555 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1556 pPal
->palPalEntry
[i
].peFlags
= 0;
1558 pwdc
->hGLPalette
= CreatePalette( pPal
);
1565 void /*WINAPI*/ wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1567 if (Current
->db_flag
) {
1568 LPBYTE lpb
= pwc
->pbPixels
;
1571 UINT nBypp
= pwc
->cColorBits
>> 3;
1572 UINT nOffset
= iPixel
% nBypp
;
1574 // Move the pixel buffer pointer to the scanline that we
1577 // pwc->dib.fFlushed = FALSE;
1579 lpb
+= pwc
->ScanWidth
* iScanLine
;
1580 // Now move to the desired pixel
1581 lpb
+= iPixel
* nBypp
;
1582 lpb
= PIXELADDR(iPixel
, iScanLine
);
1583 lpdw
= (LPDWORD
)lpb
;
1587 if(pwc
->dither_flag
)
1588 *lpb
= DITHER_RGB_2_8BIT(r
,g
,b
,iScanLine
,iPixel
);
1593 *lpw
= BGR16(r
,g
,b
);
1594 else if (nBypp
== 3){
1595 *lpdw
= BGR24(r
,g
,b
);
1597 else if (nBypp
== 4)
1598 *lpdw
= BGR32(r
,g
,b
);
1601 SetPixel(Current
->hDC
, iPixel
, iScanLine
, RGB(r
,g
,b
));
1606 void /*WINAPI*/ wmCreateDIBSection(
1608 PWMC pwc
, // handle of device context
1609 CONST BITMAPINFO
*pbmi
, // address of structure containing bitmap size, format, and color data
1610 UINT iUsage
// color data type indicator: RGB values or palette indices
1615 UINT nBypp
= pwc
->cColorBits
/ 8;
1618 dwScanWidth
= (((pwc
->ScanWidth
* nBypp
)+ 3) & ~3);
1620 pwc
->ScanWidth
=pwc
->pitch
= dwScanWidth
;
1623 pwc
->ScanWidth
= 2* pwc
->pitch
;
1625 dwSize
= sizeof(BITMAPINFO
) + (dwScanWidth
* pwc
->height
);
1627 pwc
->dib
.hFileMap
= CreateFileMapping((HANDLE
)PAGE_FILE
,
1629 PAGE_READWRITE
| SEC_COMMIT
,
1634 if (!pwc
->dib
.hFileMap
)
1637 pwc
->dib
.base
= MapViewOfFile(pwc
->dib
.hFileMap
,
1638 FILE_MAP_ALL_ACCESS
,
1644 CloseHandle(pwc
->dib
.hFileMap
);
1648 // pwc->pbPixels = pwc->addrOffScreen = ((LPBYTE)pwc->dib.base) + sizeof(BITMAPINFO);
1650 // pwc->dib.hDC = CreateCompatibleDC(hDC);
1652 CopyMemory(pwc
->dib
.base
, pbmi
, sizeof(BITMAPINFO
));
1654 hic
= CreateIC("display", NULL
, NULL
, NULL
);
1655 pwc
->dib
.hDC
= CreateCompatibleDC(hic
);
1658 /* pwc->hbmDIB = CreateDIBitmap(hic,
1659 &(pwc->bmi.bmiHeader),
1665 pwc
->hbmDIB
= CreateDIBSection(hic
,
1667 (iUsage
? DIB_PAL_COLORS
: DIB_RGB_COLORS
),
1672 pwc->hbmDIB = CreateDIBSection(hic,
1679 pwc
->ScreenMem
= pwc
->addrOffScreen
= pwc
->pbPixels
;
1680 pwc
->hOldBitmap
= SelectObject(pwc
->dib
.hDC
, pwc
->hbmDIB
);
1689 // Blit memory DC to screen DC
1691 BOOL
/*WINAPI*/ wmFlush(PWMC pwc
)
1699 // Now search through the torus frames and mark used colors
1702 if (pwc
->lpDDSOffScreen
== NULL
)
1703 if(DDCreateOffScreen(pwc
) == GL_FALSE
)
1706 pwc
->lpDDSOffScreen
->lpVtbl
->Unlock(pwc
->lpDDSOffScreen
, NULL
);
1710 ddrval
= pwc
->lpDDSPrimary
->lpVtbl
->Blt( pwc
->lpDDSPrimary
,
1711 &(pwc
->rectSurface
), pwc
->lpDDSOffScreen
, &(pwc
->rectOffScreen
), 0, NULL
);
1713 if( ddrval
== DD_OK
)
1717 if( ddrval
== DDERR_SURFACELOST
)
1719 if(!DDRestoreAll(pwc
))
1724 if( ddrval
!= DDERR_WASSTILLDRAWING
)
1730 while (pwc
->lpDDSOffScreen
->lpVtbl
->Lock(pwc
->lpDDSOffScreen
,
1731 NULL
, &(pwc
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
)
1735 dwErr
= GetLastError();
1737 bRet
= BitBlt(pwc
->hDC
, 0, 0, pwc
->width
, pwc
->height
,
1738 pwc
->dib
.hDC
, 0, 0, SRCCOPY
);
1747 // The following code is added by Li Wei to enable stereo display
1749 #if !defined(NO_STEREO)
1751 void WMesaShowStereo(GLuint list
)
1754 GLbitfield mask
= GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
;
1757 // Must use double Buffer
1758 if( ! Current
-> db_flag
)
1762 glGetIntegerv(GL_MATRIX_MODE
,&matrix_mode
);
1764 // glPushMatrix(); //****
1765 WMesaViewport(Current
->gl_ctx
,0,Current
->height
/2,Current
->width
,Current
->height
/2);
1766 // Current->gl_ctx->NewState = 0;
1768 // glViewport(0,0,Current->width,Current->height/2);
1769 if(matrix_mode
!=GL_MODELVIEW
)
1770 glMatrixMode(GL_MODELVIEW
);
1772 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1774 gluLookAt(viewDistance
/2,0.0,0.0 ,
1775 viewDistance
/2,0.0,-1.0,
1777 // glTranslatef(viewDistance/2.0,0.,0.);
1778 glMultMatrixf( cm
);
1780 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
;
1785 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1787 gluLookAt(-viewDistance
/2,0.0,0.0 ,
1788 -viewDistance
/2,0.0,-1.0,
1790 // glTranslatef(-viewDistance/2.0,0.,0.);
1793 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
+ Current
->pitch
;
1795 if(matrix_mode
!=GL_MODELVIEW
)
1796 glMatrixMode(matrix_mode
);
1801 WMesaViewport(Current
->gl_ctx
,0,0,Current
->width
,Current
->height
);
1802 // Current->gl_ctx->NewState = 0;
1807 void toggleStereoMode()
1809 if(!Current
->db_flag
)
1813 if(stereoBuffer
==GL_FALSE
)
1814 #if !defined(NO_PARALLEL)
1818 Current
->ScanWidth
= Current
->pitch
*2;
1823 #if !defined(NO_PARALLEL)
1826 Current
->ScanWidth
= Current
->pitch
;
1827 Current
->pbPixels
= Current
->addrOffScreen
;
1831 /* if in stereo mode, the following function is called */
1832 void glShowStereo(GLuint list
)
1834 WMesaShowStereo(list
);
1837 #endif // End if NO_STEREO not defined
1839 #if !defined(NO_PARALLEL)
1841 void toggleParallelMode(void)
1844 parallelFlag
= GL_TRUE
;
1845 if(parallelMachine
==GL_FALSE
){
1846 PRCreateRenderBuffer( Current
->rgb_flag
? GL_RGBA
:GL_COLOR_INDEX
,
1847 Current
->cColorBits
/8,
1848 Current
->width
,Current
->height
,
1850 Current
->rgb_flag
? Current
->pbPixels
: Current
->ScreenMem
);
1851 parallelMachine
= GL_TRUE
;
1855 parallelFlag
= GL_FALSE
;
1856 if(parallelMachine
==GL_TRUE
){
1857 PRDestroyRenderBuffer();
1858 parallelMachine
=GL_FALSE
;
1859 ReadyForNextFrame
= GL_TRUE
;
1862 /***********************************************
1863 // Seems something wrong!!!!
1864 ************************************************/
1866 WMesaMakeCurrent(Current
);
1867 #if !defined(NO_STEREO)
1868 stereo_flag
= GL_FALSE
;
1873 void PRShowRenderResult(void)
1876 if(!glImageRendered())
1885 #endif //End if NO_PARALLEL not defined
1889 BYTE
DITHER_RGB_2_8BIT( int red
, int green
, int blue
, int pixel
, int scanline
)
1891 char unsigned redtemp
, greentemp
, bluetemp
, paletteindex
;
1893 //*** now, look up each value in the halftone matrix
1894 //*** using an 8x8 ordered dither.
1895 redtemp
= aDividedBy51
[red
]
1896 + (aModulo51
[red
] > aHalftone8x8
[(pixel
%8)*8
1898 greentemp
= aDividedBy51
[(char unsigned)green
]
1899 + (aModulo51
[green
] > aHalftone8x8
[
1900 (pixel
%8)*8 + scanline
%8]);
1901 bluetemp
= aDividedBy51
[(char unsigned)blue
]
1902 + (aModulo51
[blue
] > aHalftone8x8
[
1903 (pixel
%8)*8 +scanline
%8]);
1905 //*** recombine the halftoned rgb values into a palette index
1907 redtemp
+ aTimes6
[greentemp
] + aTimes36
[bluetemp
];
1909 //*** and translate through the wing halftone palette
1910 //*** translation vector to give the correct value.
1911 return aWinGHalftoneTranslation
[paletteindex
];
1918 * restore all lost objects
1920 HRESULT
DDRestoreAll( WMesaContext wc
)
1924 ddrval
= wc
->lpDDSPrimary
->lpVtbl
->Restore(wc
->lpDDSPrimary
);
1925 if( ddrval
== DD_OK
)
1927 ddrval
= wc
->lpDDSOffScreen
->lpVtbl
->Restore(wc
->lpDDSOffScreen
);
1935 * This function is called if the initialization function fails
1937 BOOL
initFail( HWND hwnd
, WMesaContext wc
)
1940 MessageBox( hwnd
, "DirectDraw Init FAILED", "", MB_OK
);
1946 static void DDDeleteOffScreen(WMesaContext wc
)
1948 if( wc
->lpDDSOffScreen
!= NULL
)
1950 wc
->lpDDSOffScreen
->lpVtbl
->Unlock(wc
->lpDDSOffScreen
,NULL
);
1951 wc
->lpDDSOffScreen
->lpVtbl
->Release(wc
->lpDDSOffScreen
);
1952 wc
->lpDDSOffScreen
= NULL
;
1957 static void DDFreePrimarySurface(WMesaContext wc
)
1959 if( wc
->lpDDSPrimary
!= NULL
)
1961 if(wc
->db_flag
== GL_FALSE
)
1962 wc
->lpDDSPrimary
->lpVtbl
->ReleaseDC(wc
->lpDDSPrimary
, wc
->hDC
);
1963 wc
->lpDDSPrimary
->lpVtbl
->Release(wc
->lpDDSPrimary
);
1964 wc
->lpDDSPrimary
= NULL
;
1968 static BOOL
DDCreatePrimarySurface(WMesaContext wc
)
1972 wc
->ddsd
.dwSize
= sizeof( wc
->ddsd
);
1973 wc
->ddsd
.dwFlags
= DDSD_CAPS
;
1974 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
1976 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
,&(wc
->ddsd
), &(wc
->lpDDSPrimary
), NULL
);
1977 if( ddrval
!= DD_OK
)
1979 return initFail(wc
->hwnd
, wc
);
1981 if(wc
->db_flag
== GL_FALSE
)
1982 wc
->lpDDSPrimary
->lpVtbl
->GetDC(wc
->lpDDSPrimary
, wc
->hDC
);
1986 static BOOL
DDCreateOffScreen(WMesaContext wc
)
1990 if(wc
->lpDD
== NULL
)
1992 GetClientRect( wc
->hwnd
, &(wc
->rectOffScreen
) );
1993 wc
->ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1994 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
1995 wc
->ddsd
.dwHeight
= wc
->rectOffScreen
.bottom
- wc
->rectOffScreen
.top
;
1996 wc
->ddsd
.dwWidth
= wc
->rectOffScreen
.right
- wc
->rectOffScreen
.left
;
1998 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
, &(wc
->ddsd
), &(wc
->lpDDSOffScreen
), NULL
);
1999 if( ddrval
!= DD_OK
)
2004 while (wc
->lpDDSOffScreen
->lpVtbl
->Lock(wc
->lpDDSOffScreen
,NULL
, &(wc
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
)
2006 // while ((ddrval = wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, &(wc->ddsd), DDLOCK_SURFACEMEMORYPTR , NULL)) != DD_OK)
2008 if(wc
->ddsd
.lpSurface
==NULL
)
2009 return initFail(wc
->hwnd
, wc
);
2011 wc
->ScreenMem
= wc
->pbPixels
= wc
->addrOffScreen
= (PBYTE
)(wc
->ddsd
.lpSurface
);
2012 wc
->ScanWidth
= wc
->pitch
= wc
->ddsd
.lPitch
;
2014 wc
->ScanWidth
= wc
->ddsd
.lPitch
*2;
2016 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2018 ClientToScreen( wc
->hwnd
, &pt
);
2019 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2020 wmSetPixelFormat(wc
, wc
->hDC
);
2025 * doInit - do work required for every instance of the application:
2026 * create the window, initialize data
2028 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
)
2033 LPDIRECTDRAW lpDD
; // DirectDraw object
2034 LPDIRECTDRAW2 lpDD2
;
2037 wc
->fullScreen
= displayOptions
.fullScreen
;
2038 wc
->gMode
= displayOptions
.mode
;
2040 stereo_flag
= displayOptions
.stereo
;
2041 if(wc
->db_flag
!= GL_TRUE
)
2042 stereo_flag
= GL_FALSE
;
2044 * create the main DirectDraw object
2046 ddrval
= DirectDrawCreate( NULL
, &(wc
->lpDD
), NULL
);
2047 if( ddrval
!= DD_OK
)
2049 return initFail(hwnd
,wc
);
2052 // Get exclusive mode if requested
2055 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2059 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
, DDSCL_NORMAL
);
2061 if( ddrval
!= DD_OK
)
2063 return initFail(hwnd
, wc
);
2067 /* ddrval = wc->lpDD->lpVtbl->QueryInterface(wc->lpDD, IID_IDirectDraw2,
2068 (LPVOID *)((wc->lpDD2)));
2072 return initFail(hwnd
, wc
);
2075 //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
2076 // wc->lpDD2->lpVtbl->GetMonitorFrequency(wc->lpDD, &dwFrequency);
2079 case 1: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 640, 480, displayOptions
.bpp
); break;
2080 case 2: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 800, 600, displayOptions
.bpp
); break;
2081 case 3: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1024, 768, displayOptions
.bpp
); break;
2082 case 4: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1152, 864, displayOptions
.bpp
); break;
2083 case 5: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1280, 1024, displayOptions
.bpp
); break;
2086 if( ddrval
!= DD_OK
)
2088 printf("Can't modify display mode, current mode used\n");
2089 // return initFail(hwnd , wc);
2091 //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
2093 case DDERR_INVALIDOBJECT
:
2095 case DDERR_INVALIDPARAMS
:
2097 case DDERR_UNSUPPORTEDMODE
:
2101 if(DDCreatePrimarySurface(wc
) == GL_FALSE
)
2102 return initFail(hwnd
, wc
);
2105 return DDCreateOffScreen(wc
);
2108 static void DDFree( WMesaContext wc
)
2110 if( wc
->lpDD
!= NULL
)
2112 DDFreePrimarySurface(wc
);
2113 DDDeleteOffScreen(wc
);
2114 wc
->lpDD
->lpVtbl
->Release(wc
->lpDD
);
2117 // Clean up the screen on exit
2118 RedrawWindow( NULL
, NULL
, NULL
, RDW_INVALIDATE
| RDW_ERASE
|
2124 void WMesaMove(void)
2126 WMesaContext wc
= Current
;
2128 if (Current
!= NULL
){
2129 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2131 ClientToScreen( wc
->hwnd
, &pt
);
2132 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2139 * Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable
2142 #define PACK_8B8G8R( R, G, B ) ( ((B) << 16) | ((G) << 8) | (R) )
2145 /**********************************************************************/
2146 /*** Triangle rendering ***/
2147 /**********************************************************************/
2150 * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
2152 static void smooth_8A8B8G8R_z_triangle( GLcontext
*ctx
,
2153 GLuint v0
, GLuint v1
, GLuint v2
,
2156 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2158 #define INTERP_RGB 1
2159 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2160 #define PIXEL_TYPE GLuint
2161 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2162 #define BYTES_PER_ROW (wmesa->ScanWidth)
2163 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2165 GLint i, len = RIGHT-LEFT; \
2166 for (i=0;i<len;i++) { \
2167 GLdepth z = FixedToDepth(ffz); \
2168 if (z < zRow[i]) { \
2169 pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2170 FixedToInt(ffb) ); \
2173 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2179 #include "tritemp.h"
2183 #include "..\tritemp.h"
2185 #include "tritemp.h"
2192 * XImage, smooth, depth-buffered, PF_8R8G8B triangle.
2194 static void smooth_8R8G8B_z_triangle( GLcontext
*ctx
,
2195 GLuint v0
, GLuint v1
, GLuint v2
,
2198 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2200 #define INTERP_RGB 1
2201 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2202 #define PIXEL_TYPE GLuint
2203 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2204 #define BYTES_PER_ROW (wmesa->ScanWidth)
2205 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2207 GLint i, len = RIGHT-LEFT; \
2208 for (i=0;i<len;i++) { \
2209 GLdepth z = FixedToDepth(ffz); \
2210 if (z < zRow[i]) { \
2211 pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2212 FixedToInt(ffb) ); \
2215 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2220 #include "tritemp.h"
2224 #include "..\tritemp.h"
2226 #include "tritemp.h"
2234 * XImage, smooth, depth-buffered, PF_5R6G5B triangle.
2236 static void smooth_5R6G5B_z_triangle( GLcontext
*ctx
,
2237 GLuint v0
, GLuint v1
, GLuint v2
,
2240 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2242 #define INTERP_RGB 1
2243 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2244 #define PIXEL_TYPE GLushort
2245 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2246 #define BYTES_PER_ROW (wmesa->ScanWidth)
2247 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2249 GLint i, len = RIGHT-LEFT; \
2250 for (i=0;i<len;i++) { \
2251 GLdepth z = FixedToDepth(ffz); \
2252 if (z < zRow[i]) { \
2253 pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2254 FixedToInt(ffb) ); \
2257 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2262 #include "tritemp.h"
2266 #include "..\tritemp.h"
2268 #include "tritemp.h"
2274 * XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
2276 static void flat_8A8B8G8R_z_triangle( GLcontext
*ctx
, GLuint v0
,
2277 GLuint v1
, GLuint v2
, GLuint pv
)
2279 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2281 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2282 #define PIXEL_TYPE GLuint
2283 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2284 #define BYTES_PER_ROW (wmesa->ScanWidth)
2285 #define SETUP_CODE \
2286 unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \
2287 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2288 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2290 GLint i, len = RIGHT-LEFT; \
2291 for (i=0;i<len;i++) { \
2292 GLdepth z = FixedToDepth(ffz); \
2293 if (z < zRow[i]) { \
2301 #include "tritemp.h"
2305 #include "..\tritemp.h"
2307 #include "tritemp.h"
2314 * XImage, flat, depth-buffered, PF_8R8G8B triangle.
2316 static void flat_8R8G8B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2317 GLuint v2
, GLuint pv
)
2319 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2321 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2322 #define PIXEL_TYPE GLuint
2323 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2324 #define BYTES_PER_ROW (wmesa->ScanWidth)
2325 #define SETUP_CODE \
2326 unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \
2327 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2328 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2330 GLint i, len = RIGHT-LEFT; \
2331 for (i=0;i<len;i++) { \
2332 GLdepth z = FixedToDepth(ffz); \
2333 if (z < zRow[i]) { \
2341 #include "tritemp.h"
2345 #include "..\tritemp.h"
2347 #include "tritemp.h"
2354 * XImage, flat, depth-buffered, PF_5R6G5B triangle.
2356 static void flat_5R6G5B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2357 GLuint v2
, GLuint pv
)
2359 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2361 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2362 #define PIXEL_TYPE GLushort
2363 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2364 #define BYTES_PER_ROW (wmesa->ScanWidth)
2365 #define SETUP_CODE \
2366 unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \
2367 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2368 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2370 GLint i, len = RIGHT-LEFT; \
2371 for (i=0;i<len;i++) { \
2372 GLdepth z = FixedToDepth(ffz); \
2373 if (z < zRow[i]) { \
2381 #include "tritemp.h"
2385 #include "..\tritemp.h"
2387 #include "tritemp.h"
2394 * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
2396 static void smooth_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2397 GLuint v2
, GLuint pv
)
2399 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2400 #define INTERP_RGB 1
2401 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2402 #define PIXEL_TYPE GLuint
2403 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2404 #define BYTES_PER_ROW (wmesa->ScanWidth)
2405 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2408 PIXEL_TYPE *pixel = pRow; \
2409 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2410 *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2411 FixedToInt(ffb) ); \
2412 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2416 #include "tritemp.h"
2420 #include "..\tritemp.h"
2422 #include "tritemp.h"
2429 * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
2431 static void smooth_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2432 GLuint v2
, GLuint pv
)
2434 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2435 #define INTERP_RGB 1
2436 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2437 #define PIXEL_TYPE GLuint
2438 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2439 #define BYTES_PER_ROW (wmesa->ScanWidth)
2440 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2443 PIXEL_TYPE *pixel = pRow; \
2444 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2445 *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2446 FixedToInt(ffb) ); \
2447 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2451 #include "tritemp.h"
2455 #include "..\tritemp.h"
2457 #include "tritemp.h"
2464 * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
2466 static void smooth_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2467 GLuint v2
, GLuint pv
)
2469 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2470 #define INTERP_RGB 1
2471 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2472 #define PIXEL_TYPE GLushort
2473 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2474 #define BYTES_PER_ROW (wmesa->ScanWidth)
2475 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2478 PIXEL_TYPE *pixel = pRow; \
2479 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2480 *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2481 FixedToInt(ffb) ); \
2482 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2486 #include "tritemp.h"
2490 #include "..\tritemp.h"
2492 #include "tritemp.h"
2500 * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
2502 static void flat_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
,
2503 GLuint v1
, GLuint v2
, GLuint pv
)
2505 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2506 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2507 #define PIXEL_TYPE GLuint
2508 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2509 #define BYTES_PER_ROW (wmesa->ScanWidth)
2510 #define SETUP_CODE \
2511 unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \
2512 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2513 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2516 PIXEL_TYPE *pixel = pRow; \
2517 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2523 #include "tritemp.h"
2527 #include "..\tritemp.h"
2529 #include "tritemp.h"
2536 * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
2538 static void flat_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2539 GLuint v2
, GLuint pv
)
2541 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2542 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2543 #define PIXEL_TYPE GLuint
2544 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2545 #define BYTES_PER_ROW (wmesa->ScanWidth)
2546 #define SETUP_CODE \
2547 unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \
2548 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2549 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2552 PIXEL_TYPE *pixel = pRow; \
2553 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2558 #include "tritemp.h"
2562 #include "..\tritemp.h"
2564 #include "tritemp.h"
2571 * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
2573 static void flat_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2574 GLuint v2
, GLuint pv
)
2576 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2577 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2578 #define PIXEL_TYPE GLushort
2579 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2580 #define BYTES_PER_ROW (wmesa->ScanWidth)
2581 #define SETUP_CODE \
2582 unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \
2583 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2584 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2587 PIXEL_TYPE *pixel = pRow; \
2588 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2593 #include "tritemp.h"
2597 #include "..\tritemp.h"
2599 #include "tritemp.h"
2606 * XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
2609 static void smooth_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2610 GLuint v2
, GLuint pv
)
2612 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2614 #define INTERP_INDEX 1
2615 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2616 #define PIXEL_TYPE GLubyte
2617 #define BYTES_PER_ROW (wmesa->ScanWidth)
2618 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2620 GLint i, len = RIGHT-LEFT; \
2621 for (i=0;i<len;i++) { \
2622 GLdepth z = FixedToDepth(ffz); \
2623 if (z < zRow[i]) { \
2624 pRow[i] = FixedToInt(ffi); \
2632 #include "tritemp.h"
2636 #include "..\tritemp.h"
2638 #include "tritemp.h"
2645 * XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
2648 static void flat_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2649 GLuint v2
, GLuint pv
)
2651 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2653 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2654 #define PIXEL_TYPE GLubyte
2655 #define BYTES_PER_ROW (wmesa->ScanWidth)
2656 #define SETUP_CODE \
2657 GLuint index = VB->IndexPtr->data[pv]; \
2658 (*ctx->Driver.Index)( ctx, index );
2659 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2661 GLint i, len = RIGHT-LEFT; \
2662 for (i=0;i<len;i++) { \
2663 GLdepth z = FixedToDepth(ffz); \
2664 if (z < zRow[i]) { \
2672 #include "tritemp.h"
2676 #include "..\tritemp.h"
2678 #include "tritemp.h"
2686 * XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2689 static void smooth_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2690 GLuint v2
, GLuint pv
)
2692 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2694 #define INTERP_INDEX 1
2695 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2696 #define PIXEL_TYPE GLubyte
2697 #define BYTES_PER_ROW (wmesa->ScanWidth)
2698 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2701 PIXEL_TYPE *pixel = pRow; \
2702 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2703 *pixel = FixedToInt(ffi); \
2708 #include "tritemp.h"
2712 #include "..\tritemp.h"
2714 #include "tritemp.h"
2721 * XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2723 static void flat_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2724 GLuint v2
, GLuint pv
)
2726 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2728 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2729 #define PIXEL_TYPE GLubyte
2730 #define BYTES_PER_ROW (wmesa->ScanWidth)
2731 #define SETUP_CODE \
2732 GLuint index = VB->IndexPtr->data[pv]; \
2733 (*ctx->Driver.Index)( ctx, index );
2734 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2737 PIXEL_TYPE *pixel = pRow; \
2738 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2743 #include "tritemp.h"
2747 #include "..\tritemp.h"
2749 #include "tritemp.h"
2755 * XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
2757 static void smooth_DITHER8_z_triangle( GLcontext
*ctx
,
2758 GLuint v0
, GLuint v1
, GLuint v2
,
2761 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2762 DITHER_RGB_TO_8BIT_SETUP
2764 #define INTERP_RGB 1
2765 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2766 #define PIXEL_TYPE GLubyte
2767 #define BYTES_PER_ROW (wmesa->ScanWidth)
2768 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2770 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
2771 for (i=0;i<len;i++,xx++) { \
2772 GLdepth z = FixedToDepth(ffz); \
2773 if (z < zRow[i]) { \
2774 DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg), \
2775 FixedToInt(ffb), xx, yy); \
2776 pRow[i] = pixelDithered; \
2779 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2784 #include "tritemp.h"
2788 #include "..\tritemp.h"
2790 #include "tritemp.h"
2796 * XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
2798 static void flat_DITHER8_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2799 GLuint v2
, GLuint pv
)
2801 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2802 DITHER_RGB_TO_8BIT_SETUP
2804 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2805 #define PIXEL_TYPE GLubyte
2806 #define BYTES_PER_ROW (wmesa->ScanWidth)
2808 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2810 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
2811 for (i=0;i<len;i++,xx++) { \
2812 GLdepth z = FixedToDepth(ffz); \
2813 if (z < zRow[i]) { \
2814 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \
2815 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \
2816 pRow[i] = pixelDithered; \
2823 #include "tritemp.h"
2827 #include "..\tritemp.h"
2829 #include "tritemp.h"
2835 * XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
2837 static void smooth_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2838 GLuint v2
, GLuint pv
)
2840 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2841 DITHER_RGB_TO_8BIT_SETUP
2842 #define INTERP_RGB 1
2843 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2844 #define PIXEL_TYPE GLubyte
2845 #define BYTES_PER_ROW (wmesa->ScanWidth)
2846 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2848 GLint xx, yy = FLIP(Y); \
2849 PIXEL_TYPE *pixel = pRow; \
2850 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2851 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy);\
2852 *pixel = pixelDithered; \
2853 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2857 #include "tritemp.h"
2861 #include "..\tritemp.h"
2863 #include "tritemp.h"
2869 * XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
2872 static void flat_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2873 GLuint v2
, GLuint pv
)
2875 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2876 DITHER_RGB_TO_8BIT_SETUP
2877 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2878 #define PIXEL_TYPE GLubyte
2879 #define BYTES_PER_ROW (wmesa->ScanWidth)
2881 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2883 GLint xx, yy = FLIP(Y); \
2884 PIXEL_TYPE *pixel = pRow; \
2885 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2886 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \
2887 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \
2888 *pixel = pixelDithered; \
2892 #include "tritemp.h"
2896 #include "..\tritemp.h"
2898 #include "tritemp.h"
2906 static triangle_func
choose_triangle_function( GLcontext
*ctx
)
2908 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2909 int depth
= wmesa
->cColorBits
;
2911 if (ctx
->Polygon
.SmoothFlag
) return NULL
;
2912 if (ctx
->Texture
.Enabled
) return NULL
;
2913 if (!wmesa
->db_flag
) return NULL
;
2914 /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {
2915 if ( ctx
->Light
.ShadeModel
==GL_SMOOTH
2916 && ctx
->RasterMask
==DEPTH_BIT
2917 && ctx
->Depth
.Func
==GL_LESS
2918 && ctx
->Depth
.Mask
==GL_TRUE
2919 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2920 switch (wmesa
->pixelformat
) {
2922 return smooth_8A8B8G8R_z_triangle
;
2924 return smooth_8R8G8B_z_triangle
;
2926 return smooth_5R6G5B_z_triangle
;
2928 return smooth_DITHER8_z_triangle
;
2930 return smooth_ci_z_triangle
;
2935 if ( ctx
->Light
.ShadeModel
==GL_FLAT
2936 && ctx
->RasterMask
==DEPTH_BIT
2937 && ctx
->Depth
.Func
==GL_LESS
2938 && ctx
->Depth
.Mask
==GL_TRUE
2939 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2940 switch (wmesa
->pixelformat
) {
2942 return flat_8A8B8G8R_z_triangle
;
2944 return flat_8R8G8B_z_triangle
;
2946 return flat_5R6G5B_z_triangle
;
2948 return flat_DITHER8_z_triangle
;
2950 return flat_ci_z_triangle
;
2955 if ( ctx
->RasterMask
==0 /* no depth test */
2956 && ctx
->Light
.ShadeModel
==GL_SMOOTH
2957 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2958 switch (wmesa
->pixelformat
) {
2960 return smooth_8A8B8G8R_triangle
;
2962 return smooth_8R8G8B_triangle
;
2964 return smooth_5R6G5B_triangle
;
2966 return smooth_DITHER8_triangle
;
2968 return smooth_ci_triangle
;
2974 if ( ctx
->RasterMask
==0 /* no depth test */
2975 && ctx
->Light
.ShadeModel
==GL_FLAT
2976 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2977 switch (wmesa
->pixelformat
) {
2979 return flat_8A8B8G8R_triangle
;
2981 return flat_8R8G8B_triangle
;
2983 return flat_5R6G5B_triangle
;
2985 return flat_DITHER8_triangle
;
2987 return flat_ci_triangle
;
2998 * Define a new viewport and reallocate auxillary buffers if the size of
2999 * the window (color buffer) has changed.
3001 void WMesaViewport( GLcontext
*ctx
,
3002 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
3005 ctx
->Viewport
.X
= x
;
3006 ctx
->Viewport
.Width
= width
;
3007 ctx
->Viewport
.Y
= y
;
3008 ctx
->Viewport
.Height
= height
;
3010 /* compute scale and bias values */
3011 /* Pre-Keith 3.1 changes
3012 ctx->Viewport.Map.m[Sx] = (GLfloat) width / 2.0F;
3013 ctx->Viewport.Map.m[Tx] = ctx->Viewport.Sx + x;
3014 ctx->Viewport.Map.m[Sy] = (GLfloat) height / 2.0F;
3015 ctx->Viewport.Map.m[Ty] = ctx->Viewport.Sy + y;
3017 ctx
->Viewport
.WindowMap
.m
[MAT_SX
] = (GLfloat
) width
/ 2.0F
;
3018 ctx
->Viewport
.WindowMap
.m
[MAT_TX
] = ctx
->Viewport
.WindowMap
.m
[MAT_SX
] + x
;
3019 ctx
->Viewport
.WindowMap
.m
[MAT_SY
] = (GLfloat
) height
/ 2.0F
;
3020 ctx
->Viewport
.WindowMap
.m
[MAT_TY
] = ctx
->Viewport
.WindowMap
.m
[MAT_SY
] + y
;