1 /* $Id: wmesa.c,v 1.9 2000/09/28 22:44:32 brianp Exp $ */
4 * Windows (Win32) device driver for Mesa 3.4
8 * Copyright (C) 1996- Li Wei
9 * Address : Institute of Artificial Intelligence
11 * : Xi'an Jiaotong University
12 * Email : liwei@aiar.xjtu.edu.cn
13 * Web page : http://sun.aiar.xjtu.edu.cn
15 * This file and its associations are partially borrowed from the
16 * Windows NT driver for Mesa 1.8 , written by Mark Leaming
21 #define WMESA_STEREO_C
27 #include "mesa_extend.h"
38 #pragma warning ( disable : 4100 4133 4761 )
41 // #include "profile.h"
51 #define CopyMemory memcpy
54 #if !defined(NO_STEREO)
60 #if !defined(NO_PARALLEL)
61 // #include "parallel.h"
64 struct DISPLAY_OPTIONS displayOptions
;
66 GLenum stereoCompile
= GL_FALSE
;
67 GLenum stereoShowing
= GL_FALSE
;
68 GLenum stereoBuffer
= GL_FALSE
;
69 #if !defined(NO_STEREO)
70 GLint displayList
= MAXIMUM_DISPLAY_LIST
;
72 GLint stereo_flag
= 0 ;
74 /* end of added code*/
76 static PWMC Current
= NULL
;
77 WMesaContext WC
= NULL
;
80 #define assert(ignore) ((void) 0)
82 void Mesa_Assert(void *Cond
,void *File
,unsigned Line
)
85 sprintf(Msg
,"%s %s %d",Cond
,File
,Line
);
86 MessageBox(NULL
,Msg
,"Assertion failed.",MB_OK
);
89 #define assert(e) if (!e) Mesa_Assert(#e,__FILE__,__LINE__);
92 //#define DD_GETDC (Current->hDC )
93 #define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
94 //#define DD_GETDC ((Current->db_flag) ? Current->hDCPrimary : Current->hDCBack )
97 //#define BEGINGDICALL if(Current->rgb_flag)wmFlushBits(Current);
99 //#define ENDGDICALL if(Current->rgb_flag)wmGetBits(Current);
102 //#define FLIP(Y) (Current->dither_flag? Y : Current->height-(Y)-1)
103 //#define FLIP(Y) (Current->height-(Y)-1)
106 * XXX Why only flip Y coord if single buffered???
108 #define FLIP(Y) (Current->db_flag? Y: Current->height-(Y)-1)
110 #define ENDPROFILE(PARA)
112 #define DITHER_RGB_TO_8BIT_SETUP \
113 GLubyte pixelDithered;
115 #define DITHER_RGB_TO_8BIT(red, green, blue, pixel, scanline) \
117 char unsigned redtemp, greentemp, bluetemp, paletteindex; \
118 redtemp = aDividedBy51[red] \
119 + (aModulo51[red] > aHalftone8x8[(pixel%8)*8 \
121 greentemp = aDividedBy51[(char unsigned)green] \
122 + (aModulo51[green] > aHalftone8x8[ \
123 (pixel%8)*8 + scanline%8]); \
124 bluetemp = aDividedBy51[(char unsigned)blue] \
125 + (aModulo51[blue] > aHalftone8x8[ \
126 (pixel%8)*8 +scanline%8]); \
127 paletteindex = redtemp + aTimes6[greentemp] + aTimes36[bluetemp]; \
128 pixelDithered = aWinGHalftoneTranslation[paletteindex]; \
133 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
);
134 static void DDFree( WMesaContext wc
);
135 static HRESULT
DDRestoreAll( WMesaContext wc
);
136 static void DDDeleteOffScreen(WMesaContext wc
);
137 static BOOL
DDCreateOffScreen(WMesaContext wc
);
140 static void FlushToFile(PWMC pwc
, PSTR szFile
);
142 BOOL
wmCreateBackingStore(PWMC pwc
, long lxSize
, long lySize
);
143 BOOL
wmDeleteBackingStore(PWMC pwc
);
144 void wmCreatePalette( PWMC pwdc
);
145 BOOL
wmSetDibColors(PWMC pwc
);
146 void wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
);
148 void wmCreateDIBSection(
150 PWMC pwc
, // handle of device context
151 CONST BITMAPINFO
*pbmi
, // address of structure containing bitmap size, format, and color data
152 UINT iUsage
// color data type indicator: RGB values or palette indices
156 void WMesaViewport( GLcontext
*ctx
,
157 GLint x
, GLint y
, GLsizei width
, GLsizei height
);
160 static triangle_func
choose_triangle_function( GLcontext
*ctx
);
163 static void wmSetPixelFormat( PWMC wc
, HDC hDC
)
166 wc
->cColorBits
= GetDeviceCaps(hDC
, BITSPIXEL
);
169 switch(wc
->cColorBits
){
171 if(wc
->dither_flag
!= GL_TRUE
)
172 wc
->pixelformat
= PF_INDEX8
;
174 wc
->pixelformat
= PF_DITHER8
;
177 wc
->pixelformat
= PF_5R6G5B
;
180 wc
->pixelformat
= PF_8R8G8B
;
183 wc
->pixelformat
= PF_BADFORMAT
;
188 // This function sets the color table of a DIB section
189 // to match that of the destination DC
191 BOOL
/*WINAPI*/ wmSetDibColors(PWMC pwc
)
193 RGBQUAD
*pColTab
, *pRGB
;
194 PALETTEENTRY
*pPal
, *pPE
;
199 /* Build a color table in the DIB that maps to the
200 selected palette in the DC.
202 nColors
= 1 << pwc
->cColorBits
;
203 pPal
= (PALETTEENTRY
*)malloc( nColors
* sizeof(PALETTEENTRY
));
204 memset( pPal
, 0, nColors
* sizeof(PALETTEENTRY
) );
205 GetPaletteEntries( pwc
->hGLPalette
, 0, nColors
, pPal
);
206 pColTab
= (RGBQUAD
*)malloc( nColors
* sizeof(RGBQUAD
));
207 for (i
= 0, pRGB
= pColTab
, pPE
= pPal
; i
< nColors
; i
++, pRGB
++, pPE
++) {
208 pRGB
->rgbRed
= pPE
->peRed
;
209 pRGB
->rgbGreen
= pPE
->peGreen
;
210 pRGB
->rgbBlue
= pPE
->peBlue
;
213 bRet
= SetDIBColorTable(pwc
->dib
.hDC
, 0, nColors
, pColTab
);
216 dwErr
= GetLastError();
226 // Free up the dib section that was created
228 BOOL
wmDeleteBackingStore(PWMC pwc
)
230 SelectObject(pwc
->dib
.hDC
, pwc
->hOldBitmap
);
231 DeleteDC(pwc
->dib
.hDC
);
232 DeleteObject(pwc
->hbmDIB
);
233 UnmapViewOfFile(pwc
->dib
.base
);
234 CloseHandle(pwc
->dib
.hFileMap
);
240 // This function creates the DIB section that is used for combined
243 BOOL
/*WINAPI*/ wmCreateBackingStore(PWMC pwc
, long lxSize
, long lySize
)
246 LPBITMAPINFO pbmi
= &(pwc
->bmi
);
249 pbmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
250 pbmi
->bmiHeader
.biWidth
= lxSize
;
251 pbmi
->bmiHeader
.biHeight
= -lySize
;
252 pbmi
->bmiHeader
.biPlanes
= 1;
254 pbmi
->bmiHeader
.biBitCount
= GetDeviceCaps(pwc
->hDC
, BITSPIXEL
);
256 pbmi
->bmiHeader
.biBitCount
= 8;
257 pbmi
->bmiHeader
.biCompression
= BI_RGB
;
258 pbmi
->bmiHeader
.biSizeImage
= 0;
259 pbmi
->bmiHeader
.biXPelsPerMeter
= 0;
260 pbmi
->bmiHeader
.biYPelsPerMeter
= 0;
261 pbmi
->bmiHeader
.biClrUsed
= 0;
262 pbmi
->bmiHeader
.biClrImportant
= 0;
264 iUsage
= (pbmi
->bmiHeader
.biBitCount
<= 8) ? DIB_PAL_COLORS
: DIB_RGB_COLORS
;
266 pwc
->cColorBits
= pbmi
->bmiHeader
.biBitCount
;
267 pwc
->ScanWidth
= pwc
->pitch
= lxSize
;
269 wmCreateDIBSection(hdc
, pwc
, pbmi
, iUsage
);
271 if ((iUsage
== DIB_PAL_COLORS
) && !(pwc
->hGLPalette
)) {
272 wmCreatePalette( pwc
);
273 wmSetDibColors( pwc
);
275 wmSetPixelFormat(pwc
, pwc
->hDC
);
282 // This function copies one scan line in a DIB section to another
284 BOOL WINAPI
wmSetDIBits(PWMC pwc
, UINT uiScanWidth
, UINT uiNumScans
, UINT nBypp
, UINT uiNewWidth
, LPBYTE pBits
)
287 LPBYTE pDest
= pwc
->pbPixels
;
288 DWORD dwNextScan
= uiScanWidth
;
289 DWORD dwNewScan
= uiNewWidth
;
290 DWORD dwScanWidth
= (uiScanWidth
* nBypp
);
293 // We need to round up to the nearest DWORD
294 // and multiply by the number of bytes per
297 dwNextScan
= (((dwNextScan
* nBypp
)+ 3) & ~3);
298 dwNewScan
= (((dwNewScan
* nBypp
)+ 3) & ~3);
300 for(uiScans
= 0; uiScans
< uiNumScans
; uiScans
++){
301 CopyMemory(pDest
, pBits
, dwScanWidth
);
311 BOOL
wmFlush(PWMC pwc
);
315 Modified from file osmesa.c
319 #define PIXELADDR(X,Y) ((GLubyte *)Current->pbPixels + (Current->height-Y-1)* Current->ScanWidth + (X)*nBypp)
320 #define PIXELADDR1( X, Y ) \
321 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X))
322 #define PIXELADDR2( X, Y ) \
323 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*2)
324 #define PIXELADDR4( X, Y ) \
325 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*4)
328 BYTE
DITHER_RGB_2_8BIT( int r
, int g
, int b
, int x
, int y
);
330 /* Finish all pending operations and synchronize. */
331 static void finish(GLcontext
* ctx
)
338 // We cache all gl draw routines until a flush is made
340 static void flush(GLcontext
* ctx
)
343 if((Current
->rgb_flag
/*&& !(Current->dib.fFlushed)*/&&!(Current
->db_flag
))
344 ||(!Current
->rgb_flag
))
355 * Set the color index used to clear the color buffer.
357 static void clear_index(GLcontext
* ctx
, GLuint index
)
360 Current
->clearpixel
= index
;
361 ENDPROFILE(clear_index
)
367 * Set the color used to clear the color buffer.
369 static void clear_color( GLcontext
* ctx
, GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
372 Current
->clearpixel
=RGB(r
, g
, b
);
373 ENDPROFILE(clear_color
)
379 * Clear the specified region of the color buffer using the clear color
380 * or index as specified by one of the two functions above.
382 //static void clear(GLcontext* ctx,
383 // GLboolean all,GLint x, GLint y, GLint width, GLint height )
384 // TODO: I modified this function to match the prototype in
385 // dd.h. (swansma@geocities.com)
387 static GLbitfield
clear(GLcontext
* ctx
, GLbitfield mask
,
388 GLboolean all
, GLint x
, GLint y
, GLint width
, GLint height
)
393 LPDWORD lpdw
= (LPDWORD
)Current
->pbPixels
;
394 LPWORD lpw
= (LPWORD
)Current
->pbPixels
;
395 LPBYTE lpb
= Current
->pbPixels
;
402 width
=Current
->width
;
403 height
=Current
->height
;
405 if(Current
->db_flag
==GL_TRUE
){
406 UINT nBypp
= Current
->cColorBits
/ 8;
411 /* Need rectification */
412 iSize
= Current
->width
/4;
413 bColor
= BGR8(GetRValue(Current
->clearpixel
),
414 GetGValue(Current
->clearpixel
),
415 GetBValue(Current
->clearpixel
));
416 wColor
= MAKEWORD(bColor
,bColor
);
417 dwColor
= MAKELONG(wColor
, wColor
);
420 iSize
= Current
->width
/ 2;
421 wColor
= BGR16(GetRValue(Current
->clearpixel
),
422 GetGValue(Current
->clearpixel
),
423 GetBValue(Current
->clearpixel
));
424 dwColor
= MAKELONG(wColor
, wColor
);
427 iSize
= Current
->width
;
428 dwColor
= BGR32(GetRValue(Current
->clearpixel
),
429 GetGValue(Current
->clearpixel
),
430 GetBValue(Current
->clearpixel
));
440 // This is the 24bit case
443 iSize
= Current
->width
*3/4;
444 dwColor
= BGR24(GetRValue(Current
->clearpixel
),
445 GetGValue(Current
->clearpixel
),
446 GetBValue(Current
->clearpixel
));
461 memcpy(lpb
, Current
->pbPixels
, iSize
*4);
462 lpb
+= Current
->ScanWidth
;
467 else { // For single buffer
469 HPEN Pen
=CreatePen(PS_SOLID
,1,Current
->clearpixel
);
470 HBRUSH Brush
=CreateSolidBrush(Current
->clearpixel
);
471 HPEN Old_Pen
=SelectObject(DC
,Pen
);
472 HBRUSH Old_Brush
=SelectObject(DC
,Brush
);
473 Rectangle(DC
,x
,y
,x
+width
,y
+height
);
474 SelectObject(DC
,Old_Pen
);
475 SelectObject(DC
,Old_Brush
);
485 return mask
; // TODO: I doubt this is correct. dd.h doesn't explain what this should
491 /* Set the current color index. */
492 static void set_index(GLcontext
* ctx
, GLuint index
)
495 Current
->pixel
=index
;
496 ENDPROFILE(set_index
)
501 /* Set the current RGBA color. */
502 static void set_color( GLcontext
* ctx
, GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
505 Current
->pixel
= RGB( r
, g
, b
);
506 ENDPROFILE(set_color
)
510 static void enable( GLcontext
* ctx
, GLenum pname
, GLboolean enable
)
515 if (pname
== GL_DITHER
) {
516 if(enable
== GL_FALSE
){
517 Current
->dither_flag
= GL_FALSE
;
518 if(Current
->cColorBits
== 8)
519 Current
->pixelformat
= PF_INDEX8
;
522 if (Current
->rgb_flag
&& Current
->cColorBits
== 8){
523 Current
->pixelformat
= PF_DITHER8
;
524 Current
->dither_flag
= GL_TRUE
;
527 Current
->dither_flag
= GL_FALSE
;
534 static GLboolean
set_draw_buffer( GLcontext
* ctx
, GLenum mode
)
537 /* TODO: this could be better */
538 if (mode
==GL_FRONT_LEFT
|| mode
==GL_BACK_LEFT
) {
544 ENDPROFILE(set_draw_buffer
)
548 static void set_read_buffer(GLcontext
*ctx
, GLframebuffer
*colorBuffer
,
557 /* Return characteristics of the output buffer. */
558 static void buffer_size( GLcontext
* ctx
, GLuint
*width
, GLuint
*height
)
564 GetClientRect(Current
->Window
,&CR
);
569 New_Size
=((*width
)!=Current
->width
) || ((*height
)!=Current
->height
);
572 Current
->width
=*width
;
573 Current
->height
=*height
;
574 Current
->ScanWidth
=Current
->width
;
575 if ((Current
->ScanWidth
%sizeof(long))!=0)
576 Current
->ScanWidth
+=(sizeof(long)-(Current
->ScanWidth
%sizeof(long)));
578 if (Current
->db_flag
){
580 DDDeleteOffScreen(Current
);
581 DDCreateOffScreen(Current
);
583 if (Current
->rgb_flag
==GL_TRUE
&& Current
->dither_flag
!=GL_TRUE
){
584 wmDeleteBackingStore(Current
);
585 wmCreateBackingStore(Current
, Current
->width
, Current
->height
);
590 // Resize OsmesaBuffer if in Parallel mode
591 #if !defined(NO_PARALLEL)
593 PRSizeRenderBuffer(Current
->width
, Current
->height
,Current
->ScanWidth
,
594 Current
->rgb_flag
== GL_TRUE
? Current
->pbPixels
: Current
->ScreenMem
);
597 ENDPROFILE(buffer_size
)
602 /**********************************************************************/
603 /***** Accelerated point, line, polygon rendering *****/
604 /**********************************************************************/
607 static void fast_rgb_points( GLcontext
* ctx
, GLuint first
, GLuint last
)
615 if (0 /*Current->gl_ctx->VB->MonoColor*/) {
616 /* all drawn with current color */
617 for (i
=first
;i
<=last
;i
++) {
618 if (!Current
->gl_ctx
->VB
->ClipMask
[i
]) {
620 x
= (GLint
) Current
->gl_ctx
->VB
->Win
.data
[i
][0];
621 y
= FLIP( (GLint
) Current
->gl_ctx
->VB
->Win
.data
[i
][1] );
622 wmSetPixel(pwc
, y
,x
,GetRValue(Current
->pixel
),
623 GetGValue(Current
->pixel
), GetBValue(Current
->pixel
));
628 /* draw points of different colors */
629 for (i
=first
;i
<=last
;i
++) {
630 if (!Current
->gl_ctx
->VB
->ClipMask
[i
]) {
632 unsigned long pixel
=RGB(Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][0]*255.0,
633 Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][1]*255.0,
634 Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][2]*255.0);
635 x
= (GLint
) Current
->gl_ctx
->VB
->Win
.data
[i
][0];
636 y
= FLIP( (GLint
) Current
->gl_ctx
->VB
->Win
.data
[i
][1] );
637 wmSetPixel(pwc
, y
,x
,Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][0]*255.0,
638 Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][1]*255.0,
639 Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][2]*255.0);
644 ENDPROFILE(fast_rgb_points
)
649 /* Return pointer to accerated points function */
650 extern points_func
choose_points_function( GLcontext
* ctx
)
653 if (ctx
->Point
.Size
==1.0 && !ctx
->Point
.SmoothFlag
&& ctx
->RasterMask
==0
654 && !ctx
->Texture
.ReallyEnabled
&& ctx
->Visual
->RGBAflag
) {
655 ENDPROFILE(choose_points_function
)
656 return fast_rgb_points
;
659 ENDPROFILE(choose_points_function
)
666 /* Draw a line using the color specified by Current->gl_ctx->VB->ColorPtr->data[pv] */
667 static void fast_flat_rgb_line( GLcontext
* ctx
, GLuint v0
, GLuint v1
, GLuint pv
)
676 if (0 /*Current->gl_ctx->VB->MonoColor*/) {
677 pixel
= Current
->pixel
; /* use current color */
680 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);
683 x0
= (int) Current
->gl_ctx
->VB
->Win
.data
[v0
][0];
684 y0
= FLIP( (int) Current
->gl_ctx
->VB
->Win
.data
[v0
][1] );
685 x1
= (int) Current
->gl_ctx
->VB
->Win
.data
[v1
][0];
686 y1
= FLIP( (int) Current
->gl_ctx
->VB
->Win
.data
[v1
][1] );
691 Pen
=CreatePen(PS_SOLID
,1,pixel
);
692 Old_Pen
=SelectObject(DC
,Pen
);
693 MoveToEx(DC
,x0
,y0
,NULL
);
695 SelectObject(DC
,Old_Pen
);
701 ENDPROFILE(fast_flat_rgb_line
)
706 /* Return pointer to accerated line function */
707 static line_func
choose_line_function( GLcontext
* ctx
)
710 if (ctx
->Line
.Width
==1.0 && !ctx
->Line
.SmoothFlag
&& !ctx
->Line
.StippleFlag
711 && ctx
->Light
.ShadeModel
==GL_FLAT
&& ctx
->RasterMask
==0
712 && !ctx
->Texture
.ReallyEnabled
&& Current
->rgb_flag
) {
713 ENDPROFILE(choose_line_function
)
714 return fast_flat_rgb_line
;
717 ENDPROFILE(choose_line_function
)
723 /**********************************************************************/
724 /***** Span-based pixel drawing *****/
725 /**********************************************************************/
728 /* Write a horizontal span of 32-bit color-index pixels with a boolean mask. */
729 static void write_ci32_span( const GLcontext
* ctx
,
730 GLuint n
, GLint x
, GLint y
,
731 const GLuint index
[],
732 const GLubyte mask
[] )
736 PBYTE Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
737 assert(Current
->rgb_flag
==GL_FALSE
);
741 ENDPROFILE(write_ci32_span
)
745 /* Write a horizontal span of 8-bit color-index pixels with a boolean mask. */
746 static void write_ci8_span( const GLcontext
* ctx
,
747 GLuint n
, GLint x
, GLint y
,
748 const GLubyte index
[],
749 const GLubyte mask
[] )
753 PBYTE Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
754 assert(Current
->rgb_flag
==GL_FALSE
);
758 ENDPROFILE(write_ci8_span
)
764 * Write a horizontal span of pixels with a boolean mask. The current
765 * color index is used for all pixels.
767 static void write_mono_ci_span(const GLcontext
* ctx
,
768 GLuint n
,GLint x
,GLint y
,
769 const GLubyte mask
[])
773 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
774 assert(Current
->rgb_flag
==GL_FALSE
);
777 Mem
[i
]=Current
->pixel
;
778 ENDPROFILE(write_mono_ci_span
)
782 * To improve the performance of this routine, frob the data into an actual
783 * scanline and call bitblt on the complete scan line instead of SetPixel.
786 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
787 static void write_rgba_span( const GLcontext
* ctx
, GLuint n
, GLint x
, GLint y
,
788 const GLubyte rgba
[][4], const GLubyte mask
[] )
793 if (pwc
->rgb_flag
==GL_TRUE
)
801 wmSetPixel(pwc
, y
, x
+ i
, rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
805 wmSetPixel(pwc
, y
, x
+ i
, rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
] );
812 BYTE
*Mem
=Current
->ScreenMem
+y
*Current
->ScanWidth
+x
;
817 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]));
821 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]));
824 ENDPROFILE(write_rgba_span
)
828 /* Write a horizontal span of RGB color pixels with a boolean mask. */
829 static void write_rgb_span( const GLcontext
* ctx
,
830 GLuint n
, GLint x
, GLint y
,
831 const GLubyte rgb
[][3], const GLubyte mask
[] )
836 if (pwc
->rgb_flag
==GL_TRUE
)
844 wmSetPixel(pwc
, y
, x
+ i
, rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]);
848 wmSetPixel(pwc
, y
, x
+ i
, rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
] );
855 BYTE
*Mem
=Current
->ScreenMem
+y
*Current
->ScanWidth
+x
;
860 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]));
864 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]));
867 ENDPROFILE(write_rgb_span
)
872 * Write a horizontal span of pixels with a boolean mask. The current color
873 * is used for all pixels.
875 static void write_mono_rgba_span( const GLcontext
* ctx
,
876 GLuint n
, GLint x
, GLint y
,
877 const GLubyte mask
[])
883 assert(Current
->rgb_flag
==GL_TRUE
);
885 if(Current
->rgb_flag
==GL_TRUE
){
889 wmSetPixel(pwc
,y
,x
+i
,GetRValue(Current
->pixel
), GetGValue(Current
->pixel
), GetBValue(Current
->pixel
));
894 SetPixel(DC
, y
, x
+i
, Current
->pixel
);
897 ENDPROFILE(write_mono_rgba_span
)
902 /**********************************************************************/
903 /***** Array-based pixel drawing *****/
904 /**********************************************************************/
907 /* Write an array of 32-bit index pixels with a boolean mask. */
908 static void write_ci32_pixels( const GLcontext
* ctx
,
909 GLuint n
, const GLint x
[], const GLint y
[],
910 const GLuint index
[], const GLubyte mask
[] )
914 assert(Current
->rgb_flag
==GL_FALSE
);
915 for (i
=0; i
<n
; i
++) {
917 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
];
921 ENDPROFILE(write_ci32_pixels
)
927 * Write an array of pixels with a boolean mask. The current color
928 * index is used for all pixels.
930 static void write_mono_ci_pixels( const GLcontext
* ctx
,
932 const GLint x
[], const GLint y
[],
933 const GLubyte mask
[] )
937 assert(Current
->rgb_flag
==GL_FALSE
);
938 for (i
=0; i
<n
; i
++) {
940 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
];
941 *Mem
= Current
->pixel
;
944 ENDPROFILE(write_mono_ci_pixels
)
949 /* Write an array of RGBA pixels with a boolean mask. */
950 static void write_rgba_pixels( const GLcontext
* ctx
,
951 GLuint n
, const GLint x
[], const GLint y
[],
952 const GLubyte rgba
[][4], const GLubyte mask
[] )
958 assert(Current
->rgb_flag
==GL_TRUE
);
961 wmSetPixel(pwc
, FLIP(y
[i
]),x
[i
],rgba
[i
][RCOMP
],rgba
[i
][GCOMP
],rgba
[i
][BCOMP
]);
963 ENDPROFILE(write_rgba_pixels
)
969 * Write an array of pixels with a boolean mask. The current color
970 * is used for all pixels.
972 static void write_mono_rgba_pixels( const GLcontext
* ctx
,
974 const GLint x
[], const GLint y
[],
975 const GLubyte mask
[] )
981 assert(Current
->rgb_flag
==GL_TRUE
);
984 wmSetPixel(pwc
, FLIP(y
[i
]),x
[i
],GetRValue(Current
->pixel
),
985 GetGValue(Current
->pixel
), GetBValue(Current
->pixel
));
987 ENDPROFILE(write_mono_rgba_pixels
)
992 /**********************************************************************/
993 /***** Read spans/arrays of pixels *****/
994 /**********************************************************************/
997 /* Read a horizontal span of color-index pixels. */
998 static void read_ci32_span( const GLcontext
* ctx
, GLuint n
, GLint x
, GLint y
,
1003 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
1004 assert(Current
->rgb_flag
==GL_FALSE
);
1007 ENDPROFILE(read_ci32_span
)
1013 /* Read an array of color index pixels. */
1014 static void read_ci32_pixels( const GLcontext
* ctx
,
1015 GLuint n
, const GLint x
[], const GLint y
[],
1016 GLuint indx
[], const GLubyte mask
[] )
1020 assert(Current
->rgb_flag
==GL_FALSE
);
1021 for (i
=0; i
<n
; i
++) {
1023 indx
[i
]=*(Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
]);
1026 ENDPROFILE(read_ci32_pixels
)
1031 /* Read a horizontal span of color pixels. */
1032 static void read_rgba_span( const GLcontext
* ctx
,
1033 GLuint n
, GLint x
, GLint y
,
1040 assert(Current
->rgb_flag
==GL_TRUE
);
1042 y
= Current
->height
- y
- 1;
1043 for (i
=0; i
<n
; i
++) {
1044 Color
=GetPixel(DC
,x
+i
,y
);
1045 rgba
[i
][RCOMP
] = GetRValue(Color
);
1046 rgba
[i
][GCOMP
] = GetGValue(Color
);
1047 rgba
[i
][BCOMP
] = GetBValue(Color
);
1048 rgba
[i
][ACOMP
] = 255;
1051 // Brian P. Has mentioned to comment this out.
1052 // memset(alpha,0,n*sizeof(GLubyte));
1053 ENDPROFILE(read_rgba_span
)
1057 /* Read an array of color pixels. */
1058 static void read_rgba_pixels( const GLcontext
* ctx
,
1059 GLuint n
, const GLint x
[], const GLint y
[],
1060 GLubyte rgba
[][4], const GLubyte mask
[] )
1066 assert(Current
->rgb_flag
==GL_TRUE
);
1067 for (i
=0; i
<n
; i
++) {
1069 Color
=GetPixel(DC
,x
[i
],FLIP(y
[i
]));
1070 rgba
[i
][RCOMP
] = GetRValue(Color
);
1071 rgba
[i
][GCOMP
] = GetGValue(Color
);
1072 rgba
[i
][BCOMP
] = GetBValue(Color
);
1073 rgba
[i
][ACOMP
] = 255;
1077 // Brian P. has mentioned to comment this out.
1078 // memset(alpha,0,n*sizeof(GLint));
1079 ENDPROFILE(read_rgba_pixels
)
1084 /**********************************************************************/
1085 /**********************************************************************/
1088 static const GLubyte
*get_string(GLcontext
*ctx
, GLenum name
)
1090 if (name
== GL_RENDERER
) {
1091 return (GLubyte
*) "Mesa Windows";
1100 void setup_DD_pointers( GLcontext
* ctx
)
1102 ctx
->Driver
.GetString
= get_string
;
1103 ctx
->Driver
.UpdateState
= setup_DD_pointers
;
1104 ctx
->Driver
.GetBufferSize
= buffer_size
;
1105 ctx
->Driver
.Finish
= finish
;
1106 ctx
->Driver
.Flush
= flush
;
1108 ctx
->Driver
.ClearIndex
= clear_index
;
1109 ctx
->Driver
.ClearColor
= clear_color
;
1110 ctx
->Driver
.Clear
= clear
;
1112 ctx
->Driver
.Index
= set_index
;
1113 ctx
->Driver
.Color
= set_color
;
1115 ctx
->Driver
.Enable
= enable
;
1117 ctx
->Driver
.SetDrawBuffer
= set_draw_buffer
;
1118 ctx
->Driver
.SetReadBuffer
= set_read_buffer
;
1119 ctx
->Driver
.GetBufferSize
= buffer_size
;
1121 ctx
->Driver
.PointsFunc
= choose_points_function(ctx
);
1122 ctx
->Driver
.LineFunc
= choose_line_function(ctx
);
1123 ctx
->Driver
.TriangleFunc
= choose_triangle_function( ctx
);
1125 /* Pixel/span writing functions: */
1126 ctx
->Driver
.WriteRGBASpan
= write_rgba_span
;
1127 ctx
->Driver
.WriteRGBSpan
= write_rgb_span
;
1128 ctx
->Driver
.WriteMonoRGBASpan
= write_mono_rgba_span
;
1129 ctx
->Driver
.WriteRGBAPixels
= write_rgba_pixels
;
1130 ctx
->Driver
.WriteMonoRGBAPixels
= write_mono_rgba_pixels
;
1131 ctx
->Driver
.WriteCI32Span
= write_ci32_span
;
1132 ctx
->Driver
.WriteCI8Span
= write_ci8_span
;
1133 ctx
->Driver
.WriteMonoCISpan
= write_mono_ci_span
;
1134 ctx
->Driver
.WriteCI32Pixels
= write_ci32_pixels
;
1135 ctx
->Driver
.WriteMonoCIPixels
= write_mono_ci_pixels
;
1137 ctx
->Driver
.ReadCI32Span
= read_ci32_span
;
1138 ctx
->Driver
.ReadRGBASpan
= read_rgba_span
;
1139 ctx
->Driver
.ReadCI32Pixels
= read_ci32_pixels
;
1140 ctx
->Driver
.ReadRGBAPixels
= read_rgba_pixels
;
1144 /**********************************************************************/
1145 /***** WMesa API Functions *****/
1146 /**********************************************************************/
1150 #define PAL_SIZE 256
1151 static void GetPalette(HPALETTE Pal
,RGBQUAD
*aRGB
)
1159 WORD NumberOfEntries
;
1160 PALETTEENTRY aEntries
[PAL_SIZE
];
1168 GetPaletteEntries(Pal
,0,PAL_SIZE
,Palette
.aEntries
);
1170 GetSystemPaletteEntries(hdc
,0,PAL_SIZE
,Palette
.aEntries
);
1171 if (GetSystemPaletteUse(hdc
) == SYSPAL_NOSTATIC
)
1173 for(i
= 0; i
<PAL_SIZE
; i
++)
1174 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1175 Palette
.aEntries
[255].peRed
= 255;
1176 Palette
.aEntries
[255].peGreen
= 255;
1177 Palette
.aEntries
[255].peBlue
= 255;
1178 Palette
.aEntries
[255].peFlags
= 0;
1179 Palette
.aEntries
[0].peRed
= 0;
1180 Palette
.aEntries
[0].peGreen
= 0;
1181 Palette
.aEntries
[0].peBlue
= 0;
1182 Palette
.aEntries
[0].peFlags
= 0;
1188 nStaticColors
= GetDeviceCaps(hdc
, NUMCOLORS
)/2;
1189 for (i
=0; i
<nStaticColors
; i
++)
1190 Palette
.aEntries
[i
].peFlags
= 0;
1191 nUsableColors
= PAL_SIZE
-nStaticColors
;
1192 for (; i
<nUsableColors
; i
++)
1193 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1194 for (; i
<PAL_SIZE
-nStaticColors
; i
++)
1195 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1196 for (i
=PAL_SIZE
-nStaticColors
; i
<PAL_SIZE
; i
++)
1197 Palette
.aEntries
[i
].peFlags
= 0;
1199 ReleaseDC(NULL
,hdc
);
1200 for (i
=0; i
<PAL_SIZE
; i
++)
1202 aRGB
[i
].rgbRed
=Palette
.aEntries
[i
].peRed
;
1203 aRGB
[i
].rgbGreen
=Palette
.aEntries
[i
].peGreen
;
1204 aRGB
[i
].rgbBlue
=Palette
.aEntries
[i
].peBlue
;
1205 aRGB
[i
].rgbReserved
=Palette
.aEntries
[i
].peFlags
;
1207 ENDPROFILE(GetPalette
)
1211 WMesaContext
WMesaCreateContext( HWND hWnd
, HPALETTE
* Pal
,
1217 GLboolean true_color_flag
;
1218 c
= (struct wmesa_context
* ) calloc(1,sizeof(struct wmesa_context
));
1223 c
->hDC
= GetDC(hWnd
);
1224 true_color_flag
= GetDeviceCaps(c
->hDC
, BITSPIXEL
) > 8;
1226 if(true_color_flag
) c
->rgb_flag
= rgb_flag
= GL_TRUE
;
1231 if ((true_color_flag
==GL_FALSE
) && (rgb_flag
== GL_TRUE
)){
1232 c
->dither_flag
= GL_TRUE
;
1233 c
->hPalHalfTone
= WinGCreateHalftonePalette();
1236 c
->dither_flag
= GL_FALSE
;
1238 c
->dither_flag
= GL_FALSE
;
1242 if (rgb_flag
==GL_FALSE
)
1244 c
->rgb_flag
= GL_FALSE
;
1246 c
->db_flag
= db_flag
=GL_TRUE
; // WinG requires double buffering
1247 printf("Single buffer is not supported in color index mode, setting to double buffer.\n");
1251 c
->rgb_flag
= GL_TRUE
;
1254 GetClientRect(c
->Window
,&CR
);
1256 c
->height
=CR
.bottom
;
1260 /* Double buffered */
1262 // if (c->rgb_flag==GL_TRUE && c->dither_flag != GL_TRUE )
1264 wmCreateBackingStore(c
, c
->width
, c
->height
);
1271 /* Single Buffered */
1276 if (DDInit(c
,hWnd
) == GL_FALSE
) {
1283 c
->gl_visual
= _mesa_create_visual(rgb_flag
,
1284 db_flag
, /* db_flag */
1285 GL_FALSE
, /* stereo */
1286 8,8,8,8, /* r, g, b, a bits */
1288 16, /* depth_bits */
1289 8, /* stencil_bits */
1290 16,16,16,16,/* accum_bits */
1293 if (!c
->gl_visual
) {
1297 /* allocate a new Mesa context */
1298 c
->gl_ctx
= _mesa_create_context( c
->gl_visual
, NULL
, c
, GL_TRUE
);
1301 _mesa_destroy_visual( c
->gl_visual
);
1306 c
->gl_buffer
= _mesa_create_framebuffer( c
->gl_visual
,
1307 c
->gl_visual
->DepthBits
> 0,
1308 c
->gl_visual
->StencilBits
> 0,
1309 c
->gl_visual
->AccumRedBits
> 0,
1310 c
->gl_visual
->AlphaBits
> 0 );
1311 if (!c
->gl_buffer
) {
1312 _mesa_destroy_visual( c
->gl_visual
);
1313 _mesa_destroy_context( c
->gl_ctx
);
1318 c
->gl_ctx
->Driver
.UpdateState
= setup_DD_pointers
;
1320 // setup_DD_pointers(c->gl_ctx);
1325 void WMesaDestroyContext( void )
1327 WMesaContext c
= Current
;
1328 ReleaseDC(c
->Window
,c
->hDC
);
1330 if(c
->hPalHalfTone
!= NULL
)
1331 DeleteObject(c
->hPalHalfTone
);
1332 _mesa_destroy_visual( c
->gl_visual
);
1333 _mesa_destroy_framebuffer( c
->gl_buffer
);
1334 _mesa_destroy_context( c
->gl_ctx
);
1340 wmDeleteBackingStore(c
);
1343 //Following code is added to enable parallel render
1344 // Parallel render only work in double buffer mode
1345 #if !defined(NO_PARALLEL)
1347 PRDestroyRenderBuffer();
1354 void /*APIENTRY*/ WMesaMakeCurrent( WMesaContext c
)
1362 // A little optimization
1363 // If it already is current,
1364 // don't set it again
1369 //gl_set_context( c->gl_ctx );
1370 _mesa_make_current(c
->gl_ctx
, c
->gl_buffer
);
1371 setup_DD_pointers(c
->gl_ctx
);
1373 if (Current
->gl_ctx
->Viewport
.Width
==0) {
1374 /* initialize viewport to window size */
1375 gl_Viewport( Current
->gl_ctx
,
1376 0, 0, Current
->width
, Current
->height
);
1378 if ((c
->cColorBits
<= 8 ) && (c
->rgb_flag
== GL_TRUE
)){
1379 WMesaPaletteChange(c
->hPalHalfTone
);
1385 void /*APIENTRY*/ WMesaSwapBuffers( void )
1387 HDC DC
= Current
->hDC
;
1388 if (Current
->db_flag
)
1394 void /*APIENTRY*/ WMesaPaletteChange(HPALETTE Pal
)
1397 LPPALETTEENTRY pPal
;
1398 if (Current
&& (Current
->rgb_flag
==GL_FALSE
|| Current
->dither_flag
== GL_TRUE
))
1400 pPal
= (PALETTEENTRY
*)malloc( 256 * sizeof(PALETTEENTRY
));
1402 // GetPaletteEntries( Pal, 0, 256, pPal );
1403 GetPalette( Pal
, pPal
);
1405 Current
->lpDD
->lpVtbl
->CreatePalette(Current
->lpDD
,DDPCAPS_8BIT
,
1406 pPal
, &(Current
->lpDDPal
), NULL
);
1407 if (Current
->lpDDPal
)
1408 Current
->lpDDSPrimary
->lpVtbl
->SetPalette(Current
->lpDDSPrimary
,Current
->lpDDPal
);
1410 vRet
= SetDIBColorTable(Current
->dib
.hDC
,0,256,pPal
);
1420 static unsigned char threeto8
[8] = {
1421 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
1424 static unsigned char twoto8
[4] = {
1428 static unsigned char oneto8
[2] = {
1432 static unsigned char componentFromIndex(UCHAR i
, UINT nbits
, UINT shift
)
1449 return threeto8
[val
];
1456 void /*WINAPI*/ wmCreatePalette( PWMC pwdc
)
1458 /* Create a compressed and re-expanded 3:3:2 palette */
1461 BYTE rb
, rs
, gb
, gs
, bb
, bs
;
1463 pwdc
->nColors
= 0x100;
1465 pPal
= (PLOGPALETTE
)malloc(sizeof(LOGPALETTE
) + pwdc
->nColors
* sizeof(PALETTEENTRY
));
1466 memset( pPal
, 0, sizeof(LOGPALETTE
) + pwdc
->nColors
* sizeof(PALETTEENTRY
) );
1468 pPal
->palVersion
= 0x300;
1477 if (pwdc
->db_flag
) {
1479 /* Need to make two palettes: one for the screen DC and one for the DIB. */
1480 pPal
->palNumEntries
= pwdc
->nColors
;
1481 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1482 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1483 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1484 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1485 pPal
->palPalEntry
[i
].peFlags
= 0;
1487 pwdc
->hGLPalette
= CreatePalette( pPal
);
1488 pwdc
->hPalette
= CreatePalette( pPal
);
1492 pPal
->palNumEntries
= pwdc
->nColors
;
1493 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1494 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1495 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1496 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1497 pPal
->palPalEntry
[i
].peFlags
= 0;
1499 pwdc
->hGLPalette
= CreatePalette( pPal
);
1506 void /*WINAPI*/ wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1508 if (Current
->db_flag
) {
1509 LPBYTE lpb
= pwc
->pbPixels
;
1512 UINT nBypp
= pwc
->cColorBits
>> 3;
1513 UINT nOffset
= iPixel
% nBypp
;
1515 // Move the pixel buffer pointer to the scanline that we
1518 // pwc->dib.fFlushed = FALSE;
1520 lpb
+= pwc
->ScanWidth
* iScanLine
;
1521 // Now move to the desired pixel
1522 lpb
+= iPixel
* nBypp
;
1523 lpb
= PIXELADDR(iPixel
, iScanLine
);
1524 lpdw
= (LPDWORD
)lpb
;
1528 if(pwc
->dither_flag
)
1529 *lpb
= DITHER_RGB_2_8BIT(r
,g
,b
,iScanLine
,iPixel
);
1534 *lpw
= BGR16(r
,g
,b
);
1535 else if (nBypp
== 3){
1536 *lpdw
= BGR24(r
,g
,b
);
1538 else if (nBypp
== 4)
1539 *lpdw
= BGR32(r
,g
,b
);
1542 SetPixel(Current
->hDC
, iPixel
, iScanLine
, RGB(r
,g
,b
));
1547 void /*WINAPI*/ wmCreateDIBSection(
1549 PWMC pwc
, // handle of device context
1550 CONST BITMAPINFO
*pbmi
, // address of structure containing bitmap size, format, and color data
1551 UINT iUsage
// color data type indicator: RGB values or palette indices
1556 UINT nBypp
= pwc
->cColorBits
/ 8;
1559 dwScanWidth
= (((pwc
->ScanWidth
* nBypp
)+ 3) & ~3);
1561 pwc
->ScanWidth
=pwc
->pitch
= dwScanWidth
;
1564 pwc
->ScanWidth
= 2* pwc
->pitch
;
1566 dwSize
= sizeof(BITMAPINFO
) + (dwScanWidth
* pwc
->height
);
1568 pwc
->dib
.hFileMap
= CreateFileMapping((HANDLE
)PAGE_FILE
,
1570 PAGE_READWRITE
| SEC_COMMIT
,
1575 if (!pwc
->dib
.hFileMap
)
1578 pwc
->dib
.base
= MapViewOfFile(pwc
->dib
.hFileMap
,
1579 FILE_MAP_ALL_ACCESS
,
1585 CloseHandle(pwc
->dib
.hFileMap
);
1589 // pwc->pbPixels = pwc->addrOffScreen = ((LPBYTE)pwc->dib.base) + sizeof(BITMAPINFO);
1591 // pwc->dib.hDC = CreateCompatibleDC(hDC);
1593 CopyMemory(pwc
->dib
.base
, pbmi
, sizeof(BITMAPINFO
));
1595 hic
= CreateIC("display", NULL
, NULL
, NULL
);
1596 pwc
->dib
.hDC
= CreateCompatibleDC(hic
);
1599 /* pwc->hbmDIB = CreateDIBitmap(hic,
1600 &(pwc->bmi.bmiHeader),
1606 pwc
->hbmDIB
= CreateDIBSection(hic
,
1608 (iUsage
? DIB_PAL_COLORS
: DIB_RGB_COLORS
),
1613 pwc->hbmDIB = CreateDIBSection(hic,
1620 pwc
->ScreenMem
= pwc
->addrOffScreen
= pwc
->pbPixels
;
1621 pwc
->hOldBitmap
= SelectObject(pwc
->dib
.hDC
, pwc
->hbmDIB
);
1630 // Blit memory DC to screen DC
1632 BOOL
/*WINAPI*/ wmFlush(PWMC pwc
)
1640 // Now search through the torus frames and mark used colors
1643 if (pwc
->lpDDSOffScreen
== NULL
)
1644 if(DDCreateOffScreen(pwc
) == GL_FALSE
)
1647 pwc
->lpDDSOffScreen
->lpVtbl
->Unlock(pwc
->lpDDSOffScreen
, NULL
);
1651 ddrval
= pwc
->lpDDSPrimary
->lpVtbl
->Blt( pwc
->lpDDSPrimary
,
1652 &(pwc
->rectSurface
), pwc
->lpDDSOffScreen
, &(pwc
->rectOffScreen
), 0, NULL
);
1654 if( ddrval
== DD_OK
)
1658 if( ddrval
== DDERR_SURFACELOST
)
1660 if(!DDRestoreAll(pwc
))
1665 if( ddrval
!= DDERR_WASSTILLDRAWING
)
1671 while (pwc
->lpDDSOffScreen
->lpVtbl
->Lock(pwc
->lpDDSOffScreen
,
1672 NULL
, &(pwc
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
)
1676 dwErr
= GetLastError();
1678 bRet
= BitBlt(pwc
->hDC
, 0, 0, pwc
->width
, pwc
->height
,
1679 pwc
->dib
.hDC
, 0, 0, SRCCOPY
);
1688 // The following code is added by Li Wei to enable stereo display
1690 #if !defined(NO_STEREO)
1692 void WMesaShowStereo(GLuint list
)
1695 GLbitfield mask
= GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
;
1698 // Must use double Buffer
1699 if( ! Current
-> db_flag
)
1703 glGetIntegerv(GL_MATRIX_MODE
,&matrix_mode
);
1705 // glPushMatrix(); //****
1706 WMesaViewport(Current
->gl_ctx
,0,Current
->height
/2,Current
->width
,Current
->height
/2);
1707 // Current->gl_ctx->NewState = 0;
1709 // glViewport(0,0,Current->width,Current->height/2);
1710 if(matrix_mode
!=GL_MODELVIEW
)
1711 glMatrixMode(GL_MODELVIEW
);
1713 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1715 gluLookAt(viewDistance
/2,0.0,0.0 ,
1716 viewDistance
/2,0.0,-1.0,
1718 // glTranslatef(viewDistance/2.0,0.,0.);
1719 glMultMatrixf( cm
);
1721 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
;
1726 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1728 gluLookAt(-viewDistance
/2,0.0,0.0 ,
1729 -viewDistance
/2,0.0,-1.0,
1731 // glTranslatef(-viewDistance/2.0,0.,0.);
1734 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
+ Current
->pitch
;
1736 if(matrix_mode
!=GL_MODELVIEW
)
1737 glMatrixMode(matrix_mode
);
1742 WMesaViewport(Current
->gl_ctx
,0,0,Current
->width
,Current
->height
);
1743 // Current->gl_ctx->NewState = 0;
1748 void toggleStereoMode()
1750 if(!Current
->db_flag
)
1754 if(stereoBuffer
==GL_FALSE
)
1755 #if !defined(NO_PARALLEL)
1759 Current
->ScanWidth
= Current
->pitch
*2;
1764 #if !defined(NO_PARALLEL)
1767 Current
->ScanWidth
= Current
->pitch
;
1768 Current
->pbPixels
= Current
->addrOffScreen
;
1772 /* if in stereo mode, the following function is called */
1773 void glShowStereo(GLuint list
)
1775 WMesaShowStereo(list
);
1778 #endif // End if NO_STEREO not defined
1780 #if !defined(NO_PARALLEL)
1782 void toggleParallelMode(void)
1785 parallelFlag
= GL_TRUE
;
1786 if(parallelMachine
==GL_FALSE
){
1787 PRCreateRenderBuffer( Current
->rgb_flag
? GL_RGBA
:GL_COLOR_INDEX
,
1788 Current
->cColorBits
/8,
1789 Current
->width
,Current
->height
,
1791 Current
->rgb_flag
? Current
->pbPixels
: Current
->ScreenMem
);
1792 parallelMachine
= GL_TRUE
;
1796 parallelFlag
= GL_FALSE
;
1797 if(parallelMachine
==GL_TRUE
){
1798 PRDestroyRenderBuffer();
1799 parallelMachine
=GL_FALSE
;
1800 ReadyForNextFrame
= GL_TRUE
;
1803 /***********************************************
1804 // Seems something wrong!!!!
1805 ************************************************/
1807 WMesaMakeCurrent(Current
);
1808 #if !defined(NO_STEREO)
1809 stereo_flag
= GL_FALSE
;
1814 void PRShowRenderResult(void)
1817 if(!glImageRendered())
1826 #endif //End if NO_PARALLEL not defined
1830 BYTE
DITHER_RGB_2_8BIT( int red
, int green
, int blue
, int pixel
, int scanline
)
1832 char unsigned redtemp
, greentemp
, bluetemp
, paletteindex
;
1834 //*** now, look up each value in the halftone matrix
1835 //*** using an 8x8 ordered dither.
1836 redtemp
= aDividedBy51
[red
]
1837 + (aModulo51
[red
] > aHalftone8x8
[(pixel
%8)*8
1839 greentemp
= aDividedBy51
[(char unsigned)green
]
1840 + (aModulo51
[green
] > aHalftone8x8
[
1841 (pixel
%8)*8 + scanline
%8]);
1842 bluetemp
= aDividedBy51
[(char unsigned)blue
]
1843 + (aModulo51
[blue
] > aHalftone8x8
[
1844 (pixel
%8)*8 +scanline
%8]);
1846 //*** recombine the halftoned rgb values into a palette index
1848 redtemp
+ aTimes6
[greentemp
] + aTimes36
[bluetemp
];
1850 //*** and translate through the wing halftone palette
1851 //*** translation vector to give the correct value.
1852 return aWinGHalftoneTranslation
[paletteindex
];
1859 * restore all lost objects
1861 HRESULT
DDRestoreAll( WMesaContext wc
)
1865 ddrval
= wc
->lpDDSPrimary
->lpVtbl
->Restore(wc
->lpDDSPrimary
);
1866 if( ddrval
== DD_OK
)
1868 ddrval
= wc
->lpDDSOffScreen
->lpVtbl
->Restore(wc
->lpDDSOffScreen
);
1876 * This function is called if the initialization function fails
1878 BOOL
initFail( HWND hwnd
, WMesaContext wc
)
1881 MessageBox( hwnd
, "DirectDraw Init FAILED", "", MB_OK
);
1887 static void DDDeleteOffScreen(WMesaContext wc
)
1889 if( wc
->lpDDSOffScreen
!= NULL
)
1891 wc
->lpDDSOffScreen
->lpVtbl
->Unlock(wc
->lpDDSOffScreen
,NULL
);
1892 wc
->lpDDSOffScreen
->lpVtbl
->Release(wc
->lpDDSOffScreen
);
1893 wc
->lpDDSOffScreen
= NULL
;
1898 static void DDFreePrimarySurface(WMesaContext wc
)
1900 if( wc
->lpDDSPrimary
!= NULL
)
1902 if(wc
->db_flag
== GL_FALSE
)
1903 wc
->lpDDSPrimary
->lpVtbl
->ReleaseDC(wc
->lpDDSPrimary
, wc
->hDC
);
1904 wc
->lpDDSPrimary
->lpVtbl
->Release(wc
->lpDDSPrimary
);
1905 wc
->lpDDSPrimary
= NULL
;
1909 static BOOL
DDCreatePrimarySurface(WMesaContext wc
)
1913 wc
->ddsd
.dwSize
= sizeof( wc
->ddsd
);
1914 wc
->ddsd
.dwFlags
= DDSD_CAPS
;
1915 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
1917 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
,&(wc
->ddsd
), &(wc
->lpDDSPrimary
), NULL
);
1918 if( ddrval
!= DD_OK
)
1920 return initFail(wc
->hwnd
, wc
);
1922 if(wc
->db_flag
== GL_FALSE
)
1923 wc
->lpDDSPrimary
->lpVtbl
->GetDC(wc
->lpDDSPrimary
, wc
->hDC
);
1927 static BOOL
DDCreateOffScreen(WMesaContext wc
)
1931 if(wc
->lpDD
== NULL
)
1933 GetClientRect( wc
->hwnd
, &(wc
->rectOffScreen
) );
1934 wc
->ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1935 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
1936 wc
->ddsd
.dwHeight
= wc
->rectOffScreen
.bottom
- wc
->rectOffScreen
.top
;
1937 wc
->ddsd
.dwWidth
= wc
->rectOffScreen
.right
- wc
->rectOffScreen
.left
;
1939 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
, &(wc
->ddsd
), &(wc
->lpDDSOffScreen
), NULL
);
1940 if( ddrval
!= DD_OK
)
1945 while (wc
->lpDDSOffScreen
->lpVtbl
->Lock(wc
->lpDDSOffScreen
,NULL
, &(wc
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
)
1947 // while ((ddrval = wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, &(wc->ddsd), DDLOCK_SURFACEMEMORYPTR , NULL)) != DD_OK)
1949 if(wc
->ddsd
.lpSurface
==NULL
)
1950 return initFail(wc
->hwnd
, wc
);
1952 wc
->ScreenMem
= wc
->pbPixels
= wc
->addrOffScreen
= (PBYTE
)(wc
->ddsd
.lpSurface
);
1953 wc
->ScanWidth
= wc
->pitch
= wc
->ddsd
.lPitch
;
1955 wc
->ScanWidth
= wc
->ddsd
.lPitch
*2;
1957 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
1959 ClientToScreen( wc
->hwnd
, &pt
);
1960 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
1961 wmSetPixelFormat(wc
, wc
->hDC
);
1966 * doInit - do work required for every instance of the application:
1967 * create the window, initialize data
1969 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
)
1974 LPDIRECTDRAW lpDD
; // DirectDraw object
1975 LPDIRECTDRAW2 lpDD2
;
1978 wc
->fullScreen
= displayOptions
.fullScreen
;
1979 wc
->gMode
= displayOptions
.mode
;
1981 stereo_flag
= displayOptions
.stereo
;
1982 if(wc
->db_flag
!= GL_TRUE
)
1983 stereo_flag
= GL_FALSE
;
1985 * create the main DirectDraw object
1987 ddrval
= DirectDrawCreate( NULL
, &(wc
->lpDD
), NULL
);
1988 if( ddrval
!= DD_OK
)
1990 return initFail(hwnd
,wc
);
1993 // Get exclusive mode if requested
1996 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2000 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
, DDSCL_NORMAL
);
2002 if( ddrval
!= DD_OK
)
2004 return initFail(hwnd
, wc
);
2008 /* ddrval = wc->lpDD->lpVtbl->QueryInterface(wc->lpDD, IID_IDirectDraw2,
2009 (LPVOID *)((wc->lpDD2)));
2013 return initFail(hwnd
, wc
);
2016 //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
2017 // wc->lpDD2->lpVtbl->GetMonitorFrequency(wc->lpDD, &dwFrequency);
2020 case 1: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 640, 480, displayOptions
.bpp
); break;
2021 case 2: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 800, 600, displayOptions
.bpp
); break;
2022 case 3: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1024, 768, displayOptions
.bpp
); break;
2023 case 4: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1152, 864, displayOptions
.bpp
); break;
2024 case 5: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1280, 1024, displayOptions
.bpp
); break;
2027 if( ddrval
!= DD_OK
)
2029 printf("Can't modify display mode, current mode used\n");
2030 // return initFail(hwnd , wc);
2032 //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
2034 case DDERR_INVALIDOBJECT
:
2036 case DDERR_INVALIDPARAMS
:
2038 case DDERR_UNSUPPORTEDMODE
:
2042 if(DDCreatePrimarySurface(wc
) == GL_FALSE
)
2043 return initFail(hwnd
, wc
);
2046 return DDCreateOffScreen(wc
);
2049 static void DDFree( WMesaContext wc
)
2051 if( wc
->lpDD
!= NULL
)
2053 DDFreePrimarySurface(wc
);
2054 DDDeleteOffScreen(wc
);
2055 wc
->lpDD
->lpVtbl
->Release(wc
->lpDD
);
2058 // Clean up the screen on exit
2059 RedrawWindow( NULL
, NULL
, NULL
, RDW_INVALIDATE
| RDW_ERASE
|
2065 void WMesaMove(void)
2067 WMesaContext wc
= Current
;
2069 if (Current
!= NULL
){
2070 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2072 ClientToScreen( wc
->hwnd
, &pt
);
2073 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2080 * Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable
2083 #define PACK_8B8G8R( R, G, B ) ( ((B) << 16) | ((G) << 8) | (R) )
2086 /**********************************************************************/
2087 /*** Triangle rendering ***/
2088 /**********************************************************************/
2091 * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
2093 static void smooth_8A8B8G8R_z_triangle( GLcontext
*ctx
,
2094 GLuint v0
, GLuint v1
, GLuint v2
,
2097 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2099 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
2100 #define INTERP_RGB 1
2101 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2102 #define PIXEL_TYPE GLuint
2103 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2104 #define BYTES_PER_ROW (wmesa->ScanWidth)
2105 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2107 GLint i, len = RIGHT-LEFT; \
2108 for (i=0;i<len;i++) { \
2109 GLdepth z = FixedToDepth(ffz); \
2110 if (z < zRow[i]) { \
2111 pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2112 FixedToInt(ffb) ); \
2115 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2121 #include "tritemp.h"
2125 #include "..\tritemp.h"
2127 #include "tritemp.h"
2134 * XImage, smooth, depth-buffered, PF_8R8G8B triangle.
2136 static void smooth_8R8G8B_z_triangle( GLcontext
*ctx
,
2137 GLuint v0
, GLuint v1
, GLuint v2
,
2140 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2142 #define INTERP_RGB 1
2143 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2144 #define PIXEL_TYPE GLuint
2145 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2146 #define BYTES_PER_ROW (wmesa->ScanWidth)
2147 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2149 GLint i, len = RIGHT-LEFT; \
2150 for (i=0;i<len;i++) { \
2151 GLdepth z = FixedToDepth(ffz); \
2152 if (z < zRow[i]) { \
2153 pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2154 FixedToInt(ffb) ); \
2157 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2162 #include "tritemp.h"
2166 #include "..\tritemp.h"
2168 #include "tritemp.h"
2176 * XImage, smooth, depth-buffered, PF_5R6G5B triangle.
2178 static void smooth_5R6G5B_z_triangle( GLcontext
*ctx
,
2179 GLuint v0
, GLuint v1
, GLuint v2
,
2182 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2184 #define INTERP_RGB 1
2185 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2186 #define PIXEL_TYPE GLushort
2187 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2188 #define BYTES_PER_ROW (wmesa->ScanWidth)
2189 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2191 GLint i, len = RIGHT-LEFT; \
2192 for (i=0;i<len;i++) { \
2193 GLdepth z = FixedToDepth(ffz); \
2194 if (z < zRow[i]) { \
2195 pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2196 FixedToInt(ffb) ); \
2199 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2204 #include "tritemp.h"
2208 #include "..\tritemp.h"
2210 #include "tritemp.h"
2216 * XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
2218 static void flat_8A8B8G8R_z_triangle( GLcontext
*ctx
, GLuint v0
,
2219 GLuint v1
, GLuint v2
, GLuint pv
)
2221 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2223 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2224 #define PIXEL_TYPE GLuint
2225 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2226 #define BYTES_PER_ROW (wmesa->ScanWidth)
2227 #define SETUP_CODE \
2228 unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \
2229 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2230 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2232 GLint i, len = RIGHT-LEFT; \
2233 for (i=0;i<len;i++) { \
2234 GLdepth z = FixedToDepth(ffz); \
2235 if (z < zRow[i]) { \
2243 #include "tritemp.h"
2247 #include "..\tritemp.h"
2249 #include "tritemp.h"
2256 * XImage, flat, depth-buffered, PF_8R8G8B triangle.
2258 static void flat_8R8G8B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2259 GLuint v2
, GLuint pv
)
2261 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2263 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2264 #define PIXEL_TYPE GLuint
2265 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2266 #define BYTES_PER_ROW (wmesa->ScanWidth)
2267 #define SETUP_CODE \
2268 unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \
2269 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2270 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2272 GLint i, len = RIGHT-LEFT; \
2273 for (i=0;i<len;i++) { \
2274 GLdepth z = FixedToDepth(ffz); \
2275 if (z < zRow[i]) { \
2283 #include "tritemp.h"
2287 #include "..\tritemp.h"
2289 #include "tritemp.h"
2296 * XImage, flat, depth-buffered, PF_5R6G5B triangle.
2298 static void flat_5R6G5B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2299 GLuint v2
, GLuint pv
)
2301 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2303 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2304 #define PIXEL_TYPE GLushort
2305 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2306 #define BYTES_PER_ROW (wmesa->ScanWidth)
2307 #define SETUP_CODE \
2308 unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \
2309 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2310 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2312 GLint i, len = RIGHT-LEFT; \
2313 for (i=0;i<len;i++) { \
2314 GLdepth z = FixedToDepth(ffz); \
2315 if (z < zRow[i]) { \
2323 #include "tritemp.h"
2327 #include "..\tritemp.h"
2329 #include "tritemp.h"
2336 * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
2338 static void smooth_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2339 GLuint v2
, GLuint pv
)
2341 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2342 #define INTERP_RGB 1
2343 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2344 #define PIXEL_TYPE GLuint
2345 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2346 #define BYTES_PER_ROW (wmesa->ScanWidth)
2347 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2350 PIXEL_TYPE *pixel = pRow; \
2351 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2352 *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2353 FixedToInt(ffb) ); \
2354 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2358 #include "tritemp.h"
2362 #include "..\tritemp.h"
2364 #include "tritemp.h"
2371 * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
2373 static void smooth_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2374 GLuint v2
, GLuint pv
)
2376 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2377 #define INTERP_RGB 1
2378 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2379 #define PIXEL_TYPE GLuint
2380 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2381 #define BYTES_PER_ROW (wmesa->ScanWidth)
2382 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2385 PIXEL_TYPE *pixel = pRow; \
2386 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2387 *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2388 FixedToInt(ffb) ); \
2389 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2393 #include "tritemp.h"
2397 #include "..\tritemp.h"
2399 #include "tritemp.h"
2406 * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
2408 static void smooth_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2409 GLuint v2
, GLuint pv
)
2411 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2412 #define INTERP_RGB 1
2413 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2414 #define PIXEL_TYPE GLushort
2415 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2416 #define BYTES_PER_ROW (wmesa->ScanWidth)
2417 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2420 PIXEL_TYPE *pixel = pRow; \
2421 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2422 *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2423 FixedToInt(ffb) ); \
2424 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2428 #include "tritemp.h"
2432 #include "..\tritemp.h"
2434 #include "tritemp.h"
2442 * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
2444 static void flat_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
,
2445 GLuint v1
, GLuint v2
, GLuint pv
)
2447 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2448 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2449 #define PIXEL_TYPE GLuint
2450 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2451 #define BYTES_PER_ROW (wmesa->ScanWidth)
2452 #define SETUP_CODE \
2453 unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \
2454 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2455 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2458 PIXEL_TYPE *pixel = pRow; \
2459 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2465 #include "tritemp.h"
2469 #include "..\tritemp.h"
2471 #include "tritemp.h"
2478 * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
2480 static void flat_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2481 GLuint v2
, GLuint pv
)
2483 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2484 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2485 #define PIXEL_TYPE GLuint
2486 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2487 #define BYTES_PER_ROW (wmesa->ScanWidth)
2488 #define SETUP_CODE \
2489 unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \
2490 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2491 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2494 PIXEL_TYPE *pixel = pRow; \
2495 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2500 #include "tritemp.h"
2504 #include "..\tritemp.h"
2506 #include "tritemp.h"
2513 * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
2515 static void flat_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2516 GLuint v2
, GLuint pv
)
2518 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2519 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2520 #define PIXEL_TYPE GLushort
2521 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2522 #define BYTES_PER_ROW (wmesa->ScanWidth)
2523 #define SETUP_CODE \
2524 unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \
2525 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2526 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2529 PIXEL_TYPE *pixel = pRow; \
2530 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2535 #include "tritemp.h"
2539 #include "..\tritemp.h"
2541 #include "tritemp.h"
2548 * XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
2551 static void smooth_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2552 GLuint v2
, GLuint pv
)
2554 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2556 #define INTERP_INDEX 1
2557 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2558 #define PIXEL_TYPE GLubyte
2559 #define BYTES_PER_ROW (wmesa->ScanWidth)
2560 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2562 GLint i, len = RIGHT-LEFT; \
2563 for (i=0;i<len;i++) { \
2564 GLdepth z = FixedToDepth(ffz); \
2565 if (z < zRow[i]) { \
2566 pRow[i] = FixedToInt(ffi); \
2574 #include "tritemp.h"
2578 #include "..\tritemp.h"
2580 #include "tritemp.h"
2587 * XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
2590 static void flat_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2591 GLuint v2
, GLuint pv
)
2593 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2595 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2596 #define PIXEL_TYPE GLubyte
2597 #define BYTES_PER_ROW (wmesa->ScanWidth)
2598 #define SETUP_CODE \
2599 GLuint index = VB->IndexPtr->data[pv]; \
2600 (*ctx->Driver.Index)( ctx, index );
2601 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2603 GLint i, len = RIGHT-LEFT; \
2604 for (i=0;i<len;i++) { \
2605 GLdepth z = FixedToDepth(ffz); \
2606 if (z < zRow[i]) { \
2614 #include "tritemp.h"
2618 #include "..\tritemp.h"
2620 #include "tritemp.h"
2628 * XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2631 static void smooth_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2632 GLuint v2
, GLuint pv
)
2634 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2636 #define INTERP_INDEX 1
2637 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2638 #define PIXEL_TYPE GLubyte
2639 #define BYTES_PER_ROW (wmesa->ScanWidth)
2640 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2643 PIXEL_TYPE *pixel = pRow; \
2644 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2645 *pixel = FixedToInt(ffi); \
2650 #include "tritemp.h"
2654 #include "..\tritemp.h"
2656 #include "tritemp.h"
2663 * XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2665 static void flat_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2666 GLuint v2
, GLuint pv
)
2668 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2670 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2671 #define PIXEL_TYPE GLubyte
2672 #define BYTES_PER_ROW (wmesa->ScanWidth)
2673 #define SETUP_CODE \
2674 GLuint index = VB->IndexPtr->data[pv]; \
2675 (*ctx->Driver.Index)( ctx, index );
2676 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2679 PIXEL_TYPE *pixel = pRow; \
2680 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2685 #include "tritemp.h"
2689 #include "..\tritemp.h"
2691 #include "tritemp.h"
2697 * XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
2699 static void smooth_DITHER8_z_triangle( GLcontext
*ctx
,
2700 GLuint v0
, GLuint v1
, GLuint v2
,
2703 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2704 DITHER_RGB_TO_8BIT_SETUP
2706 #define INTERP_RGB 1
2707 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2708 #define PIXEL_TYPE GLubyte
2709 #define BYTES_PER_ROW (wmesa->ScanWidth)
2710 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2712 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
2713 for (i=0;i<len;i++,xx++) { \
2714 GLdepth z = FixedToDepth(ffz); \
2715 if (z < zRow[i]) { \
2716 DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg), \
2717 FixedToInt(ffb), xx, yy); \
2718 pRow[i] = pixelDithered; \
2721 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2726 #include "tritemp.h"
2730 #include "..\tritemp.h"
2732 #include "tritemp.h"
2738 * XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
2740 static void flat_DITHER8_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2741 GLuint v2
, GLuint pv
)
2743 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2744 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 i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
2753 for (i=0;i<len;i++,xx++) { \
2754 GLdepth z = FixedToDepth(ffz); \
2755 if (z < zRow[i]) { \
2756 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \
2757 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \
2758 pRow[i] = pixelDithered; \
2765 #include "tritemp.h"
2769 #include "..\tritemp.h"
2771 #include "tritemp.h"
2777 * XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
2779 static void smooth_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2780 GLuint v2
, GLuint pv
)
2782 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2783 DITHER_RGB_TO_8BIT_SETUP
2784 #define INTERP_RGB 1
2785 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2786 #define PIXEL_TYPE GLubyte
2787 #define BYTES_PER_ROW (wmesa->ScanWidth)
2788 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2790 GLint xx, yy = FLIP(Y); \
2791 PIXEL_TYPE *pixel = pRow; \
2792 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2793 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy);\
2794 *pixel = pixelDithered; \
2795 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2799 #include "tritemp.h"
2803 #include "..\tritemp.h"
2805 #include "tritemp.h"
2811 * XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
2814 static void flat_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2815 GLuint v2
, GLuint pv
)
2817 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2818 DITHER_RGB_TO_8BIT_SETUP
2819 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2820 #define PIXEL_TYPE GLubyte
2821 #define BYTES_PER_ROW (wmesa->ScanWidth)
2823 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2825 GLint xx, yy = FLIP(Y); \
2826 PIXEL_TYPE *pixel = pRow; \
2827 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2828 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \
2829 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \
2830 *pixel = pixelDithered; \
2834 #include "tritemp.h"
2838 #include "..\tritemp.h"
2840 #include "tritemp.h"
2848 static triangle_func
choose_triangle_function( GLcontext
*ctx
)
2850 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2851 int depth
= wmesa
->cColorBits
;
2853 if (ctx
->Polygon
.SmoothFlag
) return NULL
;
2854 if (ctx
->Texture
.ReallyEnabled
) return NULL
;
2855 if (!wmesa
->db_flag
) return NULL
;
2856 /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {
2857 if ( ctx
->Light
.ShadeModel
==GL_SMOOTH
2858 && ctx
->RasterMask
==DEPTH_BIT
2859 && ctx
->Depth
.Func
==GL_LESS
2860 && ctx
->Depth
.Mask
==GL_TRUE
2861 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2862 switch (wmesa
->pixelformat
) {
2864 return smooth_8A8B8G8R_z_triangle
;
2866 return smooth_8R8G8B_z_triangle
;
2868 return smooth_5R6G5B_z_triangle
;
2870 return smooth_DITHER8_z_triangle
;
2872 return smooth_ci_z_triangle
;
2877 if ( ctx
->Light
.ShadeModel
==GL_FLAT
2878 && ctx
->RasterMask
==DEPTH_BIT
2879 && ctx
->Depth
.Func
==GL_LESS
2880 && ctx
->Depth
.Mask
==GL_TRUE
2881 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2882 switch (wmesa
->pixelformat
) {
2884 return flat_8A8B8G8R_z_triangle
;
2886 return flat_8R8G8B_z_triangle
;
2888 return flat_5R6G5B_z_triangle
;
2890 return flat_DITHER8_z_triangle
;
2892 return flat_ci_z_triangle
;
2897 if ( ctx
->RasterMask
==0 /* no depth test */
2898 && ctx
->Light
.ShadeModel
==GL_SMOOTH
2899 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2900 switch (wmesa
->pixelformat
) {
2902 return smooth_8A8B8G8R_triangle
;
2904 return smooth_8R8G8B_triangle
;
2906 return smooth_5R6G5B_triangle
;
2908 return smooth_DITHER8_triangle
;
2910 return smooth_ci_triangle
;
2916 if ( ctx
->RasterMask
==0 /* no depth test */
2917 && ctx
->Light
.ShadeModel
==GL_FLAT
2918 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2919 switch (wmesa
->pixelformat
) {
2921 return flat_8A8B8G8R_triangle
;
2923 return flat_8R8G8B_triangle
;
2925 return flat_5R6G5B_triangle
;
2927 return flat_DITHER8_triangle
;
2929 return flat_ci_triangle
;
2940 * Define a new viewport and reallocate auxillary buffers if the size of
2941 * the window (color buffer) has changed.
2943 void WMesaViewport( GLcontext
*ctx
,
2944 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2947 ctx
->Viewport
.X
= x
;
2948 ctx
->Viewport
.Width
= width
;
2949 ctx
->Viewport
.Y
= y
;
2950 ctx
->Viewport
.Height
= height
;
2952 /* compute scale and bias values */
2953 /* Pre-Keith 3.1 changes
2954 ctx->Viewport.Map.m[Sx] = (GLfloat) width / 2.0F;
2955 ctx->Viewport.Map.m[Tx] = ctx->Viewport.Sx + x;
2956 ctx->Viewport.Map.m[Sy] = (GLfloat) height / 2.0F;
2957 ctx->Viewport.Map.m[Ty] = ctx->Viewport.Sy + y;
2959 ctx
->Viewport
.WindowMap
.m
[MAT_SX
] = (GLfloat
) width
/ 2.0F
;
2960 ctx
->Viewport
.WindowMap
.m
[MAT_TX
] = ctx
->Viewport
.WindowMap
.m
[MAT_SX
] + x
;
2961 ctx
->Viewport
.WindowMap
.m
[MAT_SY
] = (GLfloat
) height
/ 2.0F
;
2962 ctx
->Viewport
.WindowMap
.m
[MAT_TY
] = ctx
->Viewport
.WindowMap
.m
[MAT_SY
] + y
;