1 /* $Id: wmesaBackup.c,v 1.3 2001/03/03 20:33:29 brianp Exp $ */
7 * Display driver for Mesa 2.3 under
8 * Windows95 and WindowsNT
10 * Copyright (C) 1996- Li Wei
11 * Address : Institute of Artificial Intelligence
13 * : Xi'an Jiaotong University
14 * Email : liwei@aiar.xjtu.edu.cn
15 * Web page : http://sun.aiar.xjtu.edu.cn
17 * This file and its associations are partially borrowed from the
18 * Windows NT driver for Mesa 1.8 , written by Mark Leaming
24 * $Log: wmesaBackup.c,v $
25 * Revision 1.3 2001/03/03 20:33:29 brianp
26 * lots of gl_*() to _mesa_*() namespace clean-up
28 * Revision 1.2 2000/11/05 18:41:00 keithw
29 * - Changes for new software rasterizer modules
30 * - Remove support for choosing software fallbacks from core code
31 * - Remove partial fallback code from vbrender.c -- drivers are now
32 * expected to be able to find a triangle/quad function for every state,
33 * even if they have to use _swsetup_Triangle or _swsetup_Quad.
34 * - Marked derived variables in the GLcontext struct with a leading
37 * Revision 1.1.1.1 1999/08/19 00:55:42 jtg
40 * Revision 1.1 1999/01/03 03:08:57 brianp
43 * Revision 3.1 1998/06/11 01:42:08 brianp
44 * updated for Mesa 3.0 device driver interface (but not tested)
46 * Revision 3.0 1998/06/11 01:18:25 brianp
52 #define WMESA_STEREO_C
57 #include "mesa_extend.h"
68 #pragma warning ( disable : 4133 4761 )
71 // #include "profile.h"
81 #define CopyMemory memcpy
84 #if !defined(NO_STEREO)
90 #if !defined(NO_PARALLEL)
91 // #include "parallel.h"
94 struct DISPLAY_OPTIONS displayOptions
;
96 GLenum stereoCompile
= GL_FALSE
;
97 GLenum stereoShowing
= GL_FALSE
;
98 GLenum stereoBuffer
= GL_FALSE
;
99 #if !defined(NO_STEREO)
100 GLint displayList
= MAXIMUM_DISPLAY_LIST
;
102 GLint stereo_flag
= 0 ;
104 /* end of added code*/
106 static PWMC Current
= NULL
;
107 WMesaContext WC
= NULL
;
110 #define assert(ignore) ((void) 0)
112 void Mesa_Assert(void *Cond
,void *File
,unsigned Line
)
115 sprintf(Msg
,"%s %s %d",Cond
,File
,Line
);
116 MessageBox(NULL
,Msg
,"Assertion failed.",MB_OK
);
119 #define assert(e) if (!e) Mesa_Assert(#e,__FILE__,__LINE__);
122 //#define DD_GETDC (Current->hDC )
123 #define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
124 //#define DD_GETDC ((Current->db_flag) ? Current->hDCPrimary : Current->hDCBack )
127 //#define BEGINGDICALL if(Current->rgb_flag)wmFlushBits(Current);
129 //#define ENDGDICALL if(Current->rgb_flag)wmGetBits(Current);
132 //#define FLIP(Y) (Current->dither_flag? Y : Current->height-(Y)-1)
133 //#define FLIP(Y) (Current->height-(Y)-1)
135 #define FLIP(Y) (Current->db_flag? Y: Current->height-(Y)-1)
137 #define ENDPROFILE(PARA)
139 #define DITHER_RGB_TO_8BIT_SETUP \
140 GLubyte pixelDithered;
142 #define DITHER_RGB_TO_8BIT(red, green, blue, pixel, scanline) \
144 char unsigned redtemp, greentemp, bluetemp, paletteindex; \
145 redtemp = aDividedBy51[red] \
146 + (aModulo51[red] > aHalftone8x8[(pixel%8)*8 \
148 greentemp = aDividedBy51[(char unsigned)green] \
149 + (aModulo51[green] > aHalftone8x8[ \
150 (pixel%8)*8 + scanline%8]); \
151 bluetemp = aDividedBy51[(char unsigned)blue] \
152 + (aModulo51[blue] > aHalftone8x8[ \
153 (pixel%8)*8 +scanline%8]); \
154 paletteindex = redtemp + aTimes6[greentemp] + aTimes36[bluetemp]; \
155 pixelDithered = aWinGHalftoneTranslation[paletteindex]; \
160 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
);
161 static void DDFree( WMesaContext wc
);
162 static HRESULT
DDRestoreAll( WMesaContext wc
);
163 static void DDDeleteOffScreen(WMesaContext wc
);
164 static BOOL
DDCreateOffScreen(WMesaContext wc
);
167 static void FlushToFile(PWMC pwc
, PSTR szFile
);
169 BOOL
wmCreateBackingStore(PWMC pwc
, long lxSize
, long lySize
);
170 BOOL
wmDeleteBackingStore(PWMC pwc
);
171 void wmCreatePalette( PWMC pwdc
);
172 BOOL
wmSetDibColors(PWMC pwc
);
173 void wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
);
175 void wmCreateDIBSection(
177 PWMC pwc
, // handle of device context
178 CONST BITMAPINFO
*pbmi
, // address of structure containing bitmap size, format, and color data
179 UINT iUsage
// color data type indicator: RGB values or palette indices
183 void WMesaViewport( GLcontext
*ctx
,
184 GLint x
, GLint y
, GLsizei width
, GLsizei height
);
187 static triangle_func
choose_triangle_function( GLcontext
*ctx
);
190 static void wmSetPixelFormat( PWMC wc
, HDC hDC
)
193 wc
->cColorBits
= GetDeviceCaps(hDC
, BITSPIXEL
);
196 switch(wc
->cColorBits
){
198 if(wc
->dither_flag
!= GL_TRUE
)
199 wc
->pixelformat
= PF_INDEX8
;
201 wc
->pixelformat
= PF_DITHER8
;
204 wc
->pixelformat
= PF_5R6G5B
;
207 wc
->pixelformat
= PF_8R8G8B
;
210 wc
->pixelformat
= PF_BADFORMAT
;
215 // This function sets the color table of a DIB section
216 // to match that of the destination DC
218 BOOL
/*WINAPI*/ wmSetDibColors(PWMC pwc
)
220 RGBQUAD
*pColTab
, *pRGB
;
221 PALETTEENTRY
*pPal
, *pPE
;
226 /* Build a color table in the DIB that maps to the
227 selected palette in the DC.
229 nColors
= 1 << pwc
->cColorBits
;
230 pPal
= (PALETTEENTRY
*)malloc( nColors
* sizeof(PALETTEENTRY
));
231 memset( pPal
, 0, nColors
* sizeof(PALETTEENTRY
) );
232 GetPaletteEntries( pwc
->hGLPalette
, 0, nColors
, pPal
);
233 pColTab
= (RGBQUAD
*)malloc( nColors
* sizeof(RGBQUAD
));
234 for (i
= 0, pRGB
= pColTab
, pPE
= pPal
; i
< nColors
; i
++, pRGB
++, pPE
++) {
235 pRGB
->rgbRed
= pPE
->peRed
;
236 pRGB
->rgbGreen
= pPE
->peGreen
;
237 pRGB
->rgbBlue
= pPE
->peBlue
;
240 bRet
= SetDIBColorTable(pwc
->dib
.hDC
, 0, nColors
, pColTab
);
243 dwErr
= GetLastError();
253 // Free up the dib section that was created
255 BOOL
wmDeleteBackingStore(PWMC pwc
)
257 SelectObject(pwc
->dib
.hDC
, pwc
->hOldBitmap
);
258 DeleteDC(pwc
->dib
.hDC
);
259 DeleteObject(pwc
->hbmDIB
);
260 UnmapViewOfFile(pwc
->dib
.base
);
261 CloseHandle(pwc
->dib
.hFileMap
);
267 // This function creates the DIB section that is used for combined
270 BOOL
/*WINAPI*/ wmCreateBackingStore(PWMC pwc
, long lxSize
, long lySize
)
273 LPBITMAPINFO pbmi
= &(pwc
->bmi
);
276 pbmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
277 pbmi
->bmiHeader
.biWidth
= lxSize
;
278 pbmi
->bmiHeader
.biHeight
= -lySize
;
279 pbmi
->bmiHeader
.biPlanes
= 1;
281 pbmi
->bmiHeader
.biBitCount
= GetDeviceCaps(pwc
->hDC
, BITSPIXEL
);
283 pbmi
->bmiHeader
.biBitCount
= 8;
284 pbmi
->bmiHeader
.biCompression
= BI_RGB
;
285 pbmi
->bmiHeader
.biSizeImage
= 0;
286 pbmi
->bmiHeader
.biXPelsPerMeter
= 0;
287 pbmi
->bmiHeader
.biYPelsPerMeter
= 0;
288 pbmi
->bmiHeader
.biClrUsed
= 0;
289 pbmi
->bmiHeader
.biClrImportant
= 0;
291 iUsage
= (pbmi
->bmiHeader
.biBitCount
<= 8) ? DIB_PAL_COLORS
: DIB_RGB_COLORS
;
293 pwc
->cColorBits
= pbmi
->bmiHeader
.biBitCount
;
294 pwc
->ScanWidth
= pwc
->pitch
= lxSize
;
296 wmCreateDIBSection(hdc
, pwc
, pbmi
, iUsage
);
298 if ((iUsage
== DIB_PAL_COLORS
) && !(pwc
->hGLPalette
)) {
299 wmCreatePalette( pwc
);
300 wmSetDibColors( pwc
);
302 wmSetPixelFormat(pwc
, pwc
->hDC
);
309 // This function copies one scan line in a DIB section to another
311 BOOL GLWINAPI
wmSetDIBits(PWMC pwc
, UINT uiScanWidth
, UINT uiNumScans
, UINT nBypp
, UINT uiNewWidth
, LPBYTE pBits
)
314 LPBYTE pDest
= pwc
->pbPixels
;
315 DWORD dwNextScan
= uiScanWidth
;
316 DWORD dwNewScan
= uiNewWidth
;
317 DWORD dwScanWidth
= (uiScanWidth
* nBypp
);
320 // We need to round up to the nearest DWORD
321 // and multiply by the number of bytes per
324 dwNextScan
= (((dwNextScan
* nBypp
)+ 3) & ~3);
325 dwNewScan
= (((dwNewScan
* nBypp
)+ 3) & ~3);
327 for(uiScans
= 0; uiScans
< uiNumScans
; uiScans
++){
328 CopyMemory(pDest
, pBits
, dwScanWidth
);
338 BOOL
wmFlush(PWMC pwc
);
342 Modified from file osmesa.c
346 #define PIXELADDR(X,Y) ((GLubyte *)Current->pbPixels + (Current->height-Y-1)* Current->ScanWidth + (X)*nBypp)
347 #define PIXELADDR1( X, Y ) \
348 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X))
349 #define PIXELADDR2( X, Y ) \
350 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*2)
351 #define PIXELADDR4( X, Y ) \
352 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*4)
355 BYTE
DITHER_RGB_2_8BIT( int r
, int g
, int b
, int x
, int y
);
357 /* Finish all pending operations and synchronize. */
358 static void finish(GLcontext
* ctx
)
365 // We cache all gl draw routines until a flush is made
367 static void flush(GLcontext
* ctx
)
370 if((Current
->rgb_flag
/*&& !(Current->dib.fFlushed)*/&&!(Current
->db_flag
))
371 ||(!Current
->rgb_flag
))
382 * Set the color index used to clear the color buffer.
384 static void clear_index(GLcontext
* ctx
, GLuint index
)
387 Current
->clearpixel
= index
;
388 ENDPROFILE(clear_index
)
394 * Set the color used to clear the color buffer.
396 static void clear_color( GLcontext
* ctx
, GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
399 Current
->clearpixel
=RGB(r
, g
, b
);
400 ENDPROFILE(clear_color
)
406 * Clear the specified region of the color buffer using the clear color
407 * or index as specified by one of the two functions above.
409 //static void clear(GLcontext* ctx,
410 // GLboolean all,GLint x, GLint y, GLint width, GLint height )
411 // TODO: I modified this function to match the prototype in dd.h. (swansma@geocities.com)
412 // dd.h does not explain what the return type is so I could not set this to the proper
414 static GLbitfield
clear(GLcontext
* ctx
, GLbitfield mask
,
415 GLboolean all
, GLint x
, GLint y
, GLint width
, GLint height
)
420 LPDWORD lpdw
= (LPDWORD
)Current
->pbPixels
;
421 LPWORD lpw
= (LPWORD
)Current
->pbPixels
;
422 LPBYTE lpb
= Current
->pbPixels
;
429 width
=Current
->width
;
430 height
=Current
->height
;
432 if(Current
->db_flag
==GL_TRUE
){
433 UINT nBypp
= Current
->cColorBits
/ 8;
438 /* Need rectification */
439 iSize
= Current
->width
/4;
440 bColor
= BGR8(GetRValue(Current
->clearpixel
),
441 GetGValue(Current
->clearpixel
),
442 GetBValue(Current
->clearpixel
));
443 wColor
= MAKEWORD(bColor
,bColor
);
444 dwColor
= MAKELONG(wColor
, wColor
);
447 iSize
= Current
->width
/ 2;
448 wColor
= BGR16(GetRValue(Current
->clearpixel
),
449 GetGValue(Current
->clearpixel
),
450 GetBValue(Current
->clearpixel
));
451 dwColor
= MAKELONG(wColor
, wColor
);
454 iSize
= Current
->width
;
455 dwColor
= BGR32(GetRValue(Current
->clearpixel
),
456 GetGValue(Current
->clearpixel
),
457 GetBValue(Current
->clearpixel
));
467 // This is the 24bit case
470 iSize
= Current
->width
*3/4;
471 dwColor
= BGR24(GetRValue(Current
->clearpixel
),
472 GetGValue(Current
->clearpixel
),
473 GetBValue(Current
->clearpixel
));
488 memcpy(lpb
, Current
->pbPixels
, iSize
*4);
489 lpb
+= Current
->ScanWidth
;
494 else { // For single buffer
496 HPEN Pen
=CreatePen(PS_SOLID
,1,Current
->clearpixel
);
497 HBRUSH Brush
=CreateSolidBrush(Current
->clearpixel
);
498 HPEN Old_Pen
=SelectObject(DC
,Pen
);
499 HBRUSH Old_Brush
=SelectObject(DC
,Brush
);
500 Rectangle(DC
,x
,y
,x
+width
,y
+height
);
501 SelectObject(DC
,Old_Pen
);
502 SelectObject(DC
,Old_Brush
);
512 return mask
; // TODO: I doubt this is correct. dd.h doesn't explain what this should
518 /* Set the current color index. */
519 static void set_index(GLcontext
* ctx
, GLuint index
)
522 Current
->pixel
=index
;
523 ENDPROFILE(set_index
)
528 /* Set the current RGBA color. */
529 static void set_color( GLcontext
* ctx
, GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
532 Current
->pixel
= RGB( r
, g
, b
);
533 ENDPROFILE(set_color
)
538 /* Set the index mode bitplane mask. */
539 static GLboolean
index_mask(GLcontext
* ctx
, GLuint mask
)
541 /* can't implement */
547 /* Set the RGBA drawing mask. */
548 static GLboolean
color_mask( GLcontext
* ctx
,
549 GLboolean rmask
, GLboolean gmask
,
550 GLboolean bmask
, GLboolean amask
)
552 /* can't implement */
559 * Set the pixel logic operation. Return GL_TRUE if the device driver
560 * can perform the operation, otherwise return GL_FALSE. If GL_FALSE
561 * is returned, the logic op will be done in software by Mesa.
563 GLboolean
logicop( GLcontext
* ctx
, GLenum op
)
565 /* can't implement */
570 static void dither( GLcontext
* ctx
, GLboolean enable
)
572 if(enable
== GL_FALSE
){
573 Current
->dither_flag
= GL_FALSE
;
574 if(Current
->cColorBits
== 8)
575 Current
->pixelformat
= PF_INDEX8
;
578 if (Current
->rgb_flag
&& Current
->cColorBits
== 8){
579 Current
->pixelformat
= PF_DITHER8
;
580 Current
->dither_flag
= GL_TRUE
;
583 Current
->dither_flag
= GL_FALSE
;
589 static GLboolean
set_buffer( GLcontext
* ctx
, GLenum mode
)
592 /* TODO: this could be better */
593 if (mode
==GL_FRONT
|| mode
==GL_BACK
) {
599 ENDPROFILE(set_buffer
)
604 /* Return characteristics of the output buffer. */
605 static void buffer_size( GLcontext
* ctx
, GLuint
*width
, GLuint
*height
)
611 GetClientRect(Current
->Window
,&CR
);
616 New_Size
=((*width
)!=Current
->width
) || ((*height
)!=Current
->height
);
619 Current
->width
=*width
;
620 Current
->height
=*height
;
621 Current
->ScanWidth
=Current
->width
;
622 if ((Current
->ScanWidth
%sizeof(long))!=0)
623 Current
->ScanWidth
+=(sizeof(long)-(Current
->ScanWidth
%sizeof(long)));
625 if (Current
->db_flag
){
627 DDDeleteOffScreen(Current
);
628 DDCreateOffScreen(Current
);
630 if (Current
->rgb_flag
==GL_TRUE
&& Current
->dither_flag
!=GL_TRUE
){
631 wmDeleteBackingStore(Current
);
632 wmCreateBackingStore(Current
, Current
->width
, Current
->height
);
637 // Resize OsmesaBuffer if in Parallel mode
638 #if !defined(NO_PARALLEL)
640 PRSizeRenderBuffer(Current
->width
, Current
->height
,Current
->ScanWidth
,
641 Current
->rgb_flag
== GL_TRUE
? Current
->pbPixels
: Current
->ScreenMem
);
644 ENDPROFILE(buffer_size
)
649 /**********************************************************************/
650 /***** Accelerated point, line, polygon rendering *****/
651 /**********************************************************************/
654 static void fast_rgb_points( GLcontext
* ctx
, GLuint first
, GLuint last
)
662 if (Current
->gl_ctx
->VB
->MonoColor
) {
663 /* all drawn with current color */
664 for (i
=first
;i
<=last
;i
++) {
665 if (!Current
->gl_ctx
->VB
->ClipMask
[i
]) {
667 x
= (GLint
) Current
->gl_ctx
->VB
->Win
[i
][0];
668 y
= FLIP( (GLint
) Current
->gl_ctx
->VB
->Win
[i
][1] );
669 wmSetPixel(pwc
, y
,x
,GetRValue(Current
->pixel
),
670 GetGValue(Current
->pixel
), GetBValue(Current
->pixel
));
675 /* draw points of different colors */
676 for (i
=first
;i
<=last
;i
++) {
677 if (!Current
->gl_ctx
->VB
->ClipMask
[i
]) {
679 unsigned long pixel
=RGB(Current
->gl_ctx
->VB
->Color
[i
][0]*255.0,
680 Current
->gl_ctx
->VB
->Color
[i
][1]*255.0,
681 Current
->gl_ctx
->VB
->Color
[i
][2]*255.0);
682 x
= (GLint
) Current
->gl_ctx
->VB
->Win
[i
][0];
683 y
= FLIP( (GLint
) Current
->gl_ctx
->VB
->Win
[i
][1] );
684 wmSetPixel(pwc
, y
,x
,Current
->gl_ctx
->VB
->Color
[i
][0]*255.0,
685 Current
->gl_ctx
->VB
->Color
[i
][1]*255.0,
686 Current
->gl_ctx
->VB
->Color
[i
][2]*255.0);
691 ENDPROFILE(fast_rgb_points
)
696 /* Return pointer to accerated points function */
697 extern points_func
choose_points_function( GLcontext
* ctx
)
700 if (ctx
->Point
.Size
==1.0 && !ctx
->Point
.SmoothFlag
&& ctx
->_RasterMask
==0
701 && !ctx
->Texture
.Enabled
&& ctx
->Visual
->RGBAflag
) {
702 ENDPROFILE(choose_points_function
)
703 return fast_rgb_points
;
706 ENDPROFILE(choose_points_function
)
713 /* Draw a line using the color specified by Current->gl_ctx->VB->Color[pv] */
714 static void fast_flat_rgb_line( GLcontext
* ctx
, GLuint v0
, GLuint v1
, GLuint pv
)
723 if (Current
->gl_ctx
->VB
->MonoColor
) {
724 pixel
= Current
->pixel
; /* use current color */
727 pixel
= RGB(Current
->gl_ctx
->VB
->Color
[pv
][0]*255.0, Current
->gl_ctx
->VB
->Color
[pv
][1]*255.0, Current
->gl_ctx
->VB
->Color
[pv
][2]*255.0);
730 x0
= (int) Current
->gl_ctx
->VB
->Win
[v0
][0];
731 y0
= FLIP( (int) Current
->gl_ctx
->VB
->Win
[v0
][1] );
732 x1
= (int) Current
->gl_ctx
->VB
->Win
[v1
][0];
733 y1
= FLIP( (int) Current
->gl_ctx
->VB
->Win
[v1
][1] );
738 Pen
=CreatePen(PS_SOLID
,1,pixel
);
739 Old_Pen
=SelectObject(DC
,Pen
);
740 MoveToEx(DC
,x0
,y0
,NULL
);
742 SelectObject(DC
,Old_Pen
);
748 ENDPROFILE(fast_flat_rgb_line
)
753 /* Return pointer to accerated line function */
754 static line_func
choose_line_function( GLcontext
* ctx
)
757 if (ctx
->Line
.Width
==1.0 && !ctx
->Line
.SmoothFlag
&& !ctx
->Line
.StippleFlag
758 && ctx
->Light
.ShadeModel
==GL_FLAT
&& ctx
->_RasterMask
==0
759 && !ctx
->Texture
.Enabled
&& Current
->rgb_flag
) {
760 ENDPROFILE(choose_line_function
)
761 return fast_flat_rgb_line
;
764 ENDPROFILE(choose_line_function
)
770 /**********************************************************************/
771 /***** Span-based pixel drawing *****/
772 /**********************************************************************/
775 /* Write a horizontal span of 32-bit color-index pixels with a boolean mask. */
776 static void write_ci32_span( const GLcontext
* ctx
,
777 GLuint n
, GLint x
, GLint y
,
778 const GLuint index
[],
779 const GLubyte mask
[] )
783 PBYTE Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
784 assert(Current
->rgb_flag
==GL_FALSE
);
788 ENDPROFILE(write_ci32_span
)
792 /* Write a horizontal span of 8-bit color-index pixels with a boolean mask. */
793 static void write_ci8_span( const GLcontext
* ctx
,
794 GLuint n
, GLint x
, GLint y
,
795 const GLubyte index
[],
796 const GLubyte mask
[] )
800 PBYTE Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
801 assert(Current
->rgb_flag
==GL_FALSE
);
805 ENDPROFILE(write_ci8_span
)
811 * Write a horizontal span of pixels with a boolean mask. The current
812 * color index is used for all pixels.
814 static void write_mono_ci_span(const GLcontext
* ctx
,
815 GLuint n
,GLint x
,GLint y
,
816 const GLubyte mask
[])
820 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
821 assert(Current
->rgb_flag
==GL_FALSE
);
824 Mem
[i
]=Current
->pixel
;
825 ENDPROFILE(write_mono_ci_span
)
829 * To improve the performance of this routine, frob the data into an actual
830 * scanline and call bitblt on the complete scan line instead of SetPixel.
833 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
834 static void write_rgba_span( const GLcontext
* ctx
, GLuint n
, GLint x
, GLint y
,
835 const GLubyte rgba
[][4], const GLubyte mask
[] )
840 if (pwc
->rgb_flag
==GL_TRUE
)
848 wmSetPixel(pwc
, y
, x
+ i
, rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
852 wmSetPixel(pwc
, y
, x
+ i
, rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
] );
859 BYTE
*Mem
=Current
->ScreenMem
+y
*Current
->ScanWidth
+x
;
864 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]));
868 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]));
871 ENDPROFILE(write_rgba_span
)
875 /* Write a horizontal span of RGB color pixels with a boolean mask. */
876 static void write_rgb_span( const GLcontext
* ctx
,
877 GLuint n
, GLint x
, GLint y
,
878 const GLubyte rgb
[][3], const GLubyte mask
[] )
883 if (pwc
->rgb_flag
==GL_TRUE
)
891 wmSetPixel(pwc
, y
, x
+ i
, rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]);
895 wmSetPixel(pwc
, y
, x
+ i
, rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
] );
902 BYTE
*Mem
=Current
->ScreenMem
+y
*Current
->ScanWidth
+x
;
907 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]));
911 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]));
914 ENDPROFILE(write_rgb_span
)
919 * Write a horizontal span of pixels with a boolean mask. The current color
920 * is used for all pixels.
922 static void write_mono_rgba_span( const GLcontext
* ctx
,
923 GLuint n
, GLint x
, GLint y
,
924 const GLubyte mask
[])
930 assert(Current
->rgb_flag
==GL_TRUE
);
932 if(Current
->rgb_flag
==GL_TRUE
){
936 wmSetPixel(pwc
,y
,x
+i
,GetRValue(Current
->pixel
), GetGValue(Current
->pixel
), GetBValue(Current
->pixel
));
941 SetPixel(DC
, y
, x
+i
, Current
->pixel
);
944 ENDPROFILE(write_mono_rgba_span
)
949 /**********************************************************************/
950 /***** Array-based pixel drawing *****/
951 /**********************************************************************/
954 /* Write an array of 32-bit index pixels with a boolean mask. */
955 static void write_ci32_pixels( const GLcontext
* ctx
,
956 GLuint n
, const GLint x
[], const GLint y
[],
957 const GLuint index
[], const GLubyte mask
[] )
961 assert(Current
->rgb_flag
==GL_FALSE
);
962 for (i
=0; i
<n
; i
++) {
964 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
];
968 ENDPROFILE(write_ci32_pixels
)
974 * Write an array of pixels with a boolean mask. The current color
975 * index is used for all pixels.
977 static void write_mono_ci_pixels( const GLcontext
* ctx
,
979 const GLint x
[], const GLint y
[],
980 const GLubyte mask
[] )
984 assert(Current
->rgb_flag
==GL_FALSE
);
985 for (i
=0; i
<n
; i
++) {
987 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
];
988 *Mem
= Current
->pixel
;
991 ENDPROFILE(write_mono_ci_pixels
)
996 /* Write an array of RGBA pixels with a boolean mask. */
997 static void write_rgba_pixels( const GLcontext
* ctx
,
998 GLuint n
, const GLint x
[], const GLint y
[],
999 const GLubyte rgba
[][4], const GLubyte mask
[] )
1005 assert(Current
->rgb_flag
==GL_TRUE
);
1008 wmSetPixel(pwc
, FLIP(y
[i
]),x
[i
],rgba
[i
][RCOMP
],rgba
[i
][GCOMP
],rgba
[i
][BCOMP
]);
1010 ENDPROFILE(write_rgba_pixels
)
1016 * Write an array of pixels with a boolean mask. The current color
1017 * is used for all pixels.
1019 static void write_mono_rgba_pixels( const GLcontext
* ctx
,
1021 const GLint x
[], const GLint y
[],
1022 const GLubyte mask
[] )
1028 assert(Current
->rgb_flag
==GL_TRUE
);
1031 wmSetPixel(pwc
, FLIP(y
[i
]),x
[i
],GetRValue(Current
->pixel
),
1032 GetGValue(Current
->pixel
), GetBValue(Current
->pixel
));
1034 ENDPROFILE(write_mono_rgba_pixels
)
1039 /**********************************************************************/
1040 /***** Read spans/arrays of pixels *****/
1041 /**********************************************************************/
1044 /* Read a horizontal span of color-index pixels. */
1045 static void read_ci32_span( const GLcontext
* ctx
, GLuint n
, GLint x
, GLint y
,
1050 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
1051 assert(Current
->rgb_flag
==GL_FALSE
);
1054 ENDPROFILE(read_ci32_span
)
1060 /* Read an array of color index pixels. */
1061 static void read_ci32_pixels( const GLcontext
* ctx
,
1062 GLuint n
, const GLint x
[], const GLint y
[],
1063 GLuint indx
[], const GLubyte mask
[] )
1067 assert(Current
->rgb_flag
==GL_FALSE
);
1068 for (i
=0; i
<n
; i
++) {
1070 indx
[i
]=*(Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
]);
1073 ENDPROFILE(read_ci32_pixels
)
1078 /* Read a horizontal span of color pixels. */
1079 static void read_rgba_span( const GLcontext
* ctx
,
1080 GLuint n
, GLint x
, GLint y
,
1087 assert(Current
->rgb_flag
==GL_TRUE
);
1089 for (i
=0; i
<n
; i
++) {
1090 Color
=GetPixel(DC
,x
+i
,y
);
1091 rgba
[i
][RCOMP
] = GetRValue(Color
);
1092 rgba
[i
][GCOMP
] = GetGValue(Color
);
1093 rgba
[i
][BCOMP
] = GetBValue(Color
);
1094 rgba
[i
][ACOMP
] = 255;
1097 // Brian P. Has mentioned to comment this out.
1098 // memset(alpha,0,n*sizeof(GLubyte));
1099 ENDPROFILE(read_rgba_span
)
1103 /* Read an array of color pixels. */
1104 static void read_rgba_pixels( const GLcontext
* ctx
,
1105 GLuint n
, const GLint x
[], const GLint y
[],
1106 GLubyte rgba
[][4], const GLubyte mask
[] )
1112 assert(Current
->rgb_flag
==GL_TRUE
);
1113 for (i
=0; i
<n
; i
++) {
1115 Color
=GetPixel(DC
,x
[i
],FLIP(y
[i
]));
1116 rgba
[i
][RCOMP
] = GetRValue(Color
);
1117 rgba
[i
][GCOMP
] = GetGValue(Color
);
1118 rgba
[i
][BCOMP
] = GetBValue(Color
);
1119 rgba
[i
][ACOMP
] = 255;
1123 // Brian P. has mentioned to comment this out.
1124 // memset(alpha,0,n*sizeof(GLint));
1125 ENDPROFILE(read_rgba_pixels
)
1130 /**********************************************************************/
1131 /**********************************************************************/
1134 static const char *renderer_string(void)
1141 void setup_DD_pointers( GLcontext
* ctx
)
1143 ctx
->Driver
.RendererString
= renderer_string
;
1144 ctx
->Driver
.UpdateState
= setup_DD_pointers
;
1145 ctx
->Driver
.GetBufferSize
= buffer_size
;
1146 ctx
->Driver
.Finish
= finish
;
1147 ctx
->Driver
.Flush
= flush
;
1149 ctx
->Driver
.ClearIndex
= clear_index
;
1150 ctx
->Driver
.ClearColor
= clear_color
;
1151 ctx
->Driver
.Clear
= clear
;
1153 ctx
->Driver
.Index
= set_index
;
1154 ctx
->Driver
.Color
= set_color
;
1155 ctx
->Driver
.IndexMask
= index_mask
;
1156 ctx
->Driver
.ColorMask
= color_mask
;
1158 ctx
->Driver
.LogicOp
= logicop
;
1159 ctx
->Driver
.Dither
= dither
;
1161 ctx
->Driver
.SetBuffer
= set_buffer
;
1162 ctx
->Driver
.GetBufferSize
= buffer_size
;
1164 ctx
->Driver
.PointsFunc
= choose_points_function(ctx
);
1165 ctx
->Driver
.LineFunc
= choose_line_function(ctx
);
1166 ctx
->Driver
.TriangleFunc
= choose_triangle_function( ctx
);
1168 /* Pixel/span writing functions: */
1169 ctx
->Driver
.WriteRGBASpan
= write_rgba_span
;
1170 ctx
->Driver
.WriteRGBSpan
= write_rgb_span
;
1171 ctx
->Driver
.WriteMonoRGBASpan
= write_mono_rgba_span
;
1172 ctx
->Driver
.WriteRGBAPixels
= write_rgba_pixels
;
1173 ctx
->Driver
.WriteMonoRGBAPixels
= write_mono_rgba_pixels
;
1174 ctx
->Driver
.WriteCI32Span
= write_ci32_span
;
1175 ctx
->Driver
.WriteCI8Span
= write_ci8_span
;
1176 ctx
->Driver
.WriteMonoCISpan
= write_mono_ci_span
;
1177 ctx
->Driver
.WriteCI32Pixels
= write_ci32_pixels
;
1178 ctx
->Driver
.WriteMonoCIPixels
= write_mono_ci_pixels
;
1180 ctx
->Driver
.ReadCI32Span
= read_ci32_span
;
1181 ctx
->Driver
.ReadRGBASpan
= read_rgba_span
;
1182 ctx
->Driver
.ReadCI32Pixels
= read_ci32_pixels
;
1183 ctx
->Driver
.ReadRGBAPixels
= read_rgba_pixels
;
1187 /**********************************************************************/
1188 /***** WMesa API Functions *****/
1189 /**********************************************************************/
1193 #define PAL_SIZE 256
1194 static void GetPalette(HPALETTE Pal
,RGBQUAD
*aRGB
)
1202 WORD NumberOfEntries
;
1203 PALETTEENTRY aEntries
[PAL_SIZE
];
1211 GetPaletteEntries(Pal
,0,PAL_SIZE
,Palette
.aEntries
);
1213 GetSystemPaletteEntries(hdc
,0,PAL_SIZE
,Palette
.aEntries
);
1214 if (GetSystemPaletteUse(hdc
) == SYSPAL_NOSTATIC
)
1216 for(i
= 0; i
<PAL_SIZE
; i
++)
1217 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1218 Palette
.aEntries
[255].peRed
= 255;
1219 Palette
.aEntries
[255].peGreen
= 255;
1220 Palette
.aEntries
[255].peBlue
= 255;
1221 Palette
.aEntries
[255].peFlags
= 0;
1222 Palette
.aEntries
[0].peRed
= 0;
1223 Palette
.aEntries
[0].peGreen
= 0;
1224 Palette
.aEntries
[0].peBlue
= 0;
1225 Palette
.aEntries
[0].peFlags
= 0;
1231 nStaticColors
= GetDeviceCaps(hdc
, NUMCOLORS
)/2;
1232 for (i
=0; i
<nStaticColors
; i
++)
1233 Palette
.aEntries
[i
].peFlags
= 0;
1234 nUsableColors
= PAL_SIZE
-nStaticColors
;
1235 for (; i
<nUsableColors
; i
++)
1236 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1237 for (; i
<PAL_SIZE
-nStaticColors
; i
++)
1238 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1239 for (i
=PAL_SIZE
-nStaticColors
; i
<PAL_SIZE
; i
++)
1240 Palette
.aEntries
[i
].peFlags
= 0;
1242 ReleaseDC(NULL
,hdc
);
1243 for (i
=0; i
<PAL_SIZE
; i
++)
1245 aRGB
[i
].rgbRed
=Palette
.aEntries
[i
].peRed
;
1246 aRGB
[i
].rgbGreen
=Palette
.aEntries
[i
].peGreen
;
1247 aRGB
[i
].rgbBlue
=Palette
.aEntries
[i
].peBlue
;
1248 aRGB
[i
].rgbReserved
=Palette
.aEntries
[i
].peFlags
;
1250 ENDPROFILE(GetPalette
)
1254 WMesaContext
WMesaCreateContext( HWND hWnd
,
1261 GLboolean true_color_flag
;
1262 c
= (struct wmesa_context
* ) calloc(1,sizeof(struct wmesa_context
));
1267 c
->hDC
= GetDC(hWnd
);
1268 true_color_flag
= GetDeviceCaps(c
->hDC
, BITSPIXEL
) > 8;
1270 if(true_color_flag
) c
->rgb_flag
= rgb_flag
= GL_TRUE
;
1275 if ((true_color_flag
==GL_FALSE
) && (rgb_flag
== GL_TRUE
)){
1276 c
->dither_flag
= GL_TRUE
;
1277 c
->hPalHalfTone
= WinGCreateHalftonePalette();
1280 c
->dither_flag
= GL_FALSE
;
1282 c
->dither_flag
= GL_FALSE
;
1286 if (rgb_flag
==GL_FALSE
)
1288 c
->rgb_flag
= GL_FALSE
;
1290 c
->db_flag
= db_flag
=GL_TRUE
; // WinG requires double buffering
1291 printf("Single buffer is not supported in color index mode, setting to double buffer.\n");
1295 c
->rgb_flag
= GL_TRUE
;
1298 GetClientRect(c
->Window
,&CR
);
1300 c
->height
=CR
.bottom
;
1304 /* Double buffered */
1306 // if (c->rgb_flag==GL_TRUE && c->dither_flag != GL_TRUE )
1308 wmCreateBackingStore(c
, c
->width
, c
->height
);
1315 /* Single Buffered */
1320 if (DDInit(c
,hWnd
) == GL_FALSE
) {
1327 c
->gl_visual
= gl_create_visual(rgb_flag
,
1328 GL_FALSE
, /* software alpha */
1329 db_flag
, /* db_flag */
1330 GL_FALSE
, /* stereo */
1331 16, /* depth_bits */
1332 8, /* stencil_bits */
1335 8,8,8,8 ); /* r, g, b, a bits */
1337 if (!c
->gl_visual
) {
1341 /* allocate a new Mesa context */
1342 c
->gl_ctx
= gl_create_context( c
->gl_visual
, NULL
, c
, GL_TRUE
);
1345 gl_destroy_visual( c
->gl_visual
);
1350 c
->gl_buffer
= gl_create_framebuffer( c
->gl_visual
);
1351 if (!c
->gl_buffer
) {
1352 gl_destroy_visual( c
->gl_visual
);
1353 gl_destroy_context( c
->gl_ctx
);
1358 c
->gl_ctx
->Driver
.UpdateState
= setup_DD_pointers
;
1360 // setup_DD_pointers(c->gl_ctx);
1365 void WMesaDestroyContext( void )
1367 WMesaContext c
= Current
;
1368 ReleaseDC(c
->Window
,c
->hDC
);
1370 if(c
->hPalHalfTone
!= NULL
)
1371 DeleteObject(c
->hPalHalfTone
);
1372 gl_destroy_visual( c
->gl_visual
);
1373 gl_destroy_framebuffer( c
->gl_buffer
);
1374 gl_destroy_context( c
->gl_ctx
);
1380 wmDeleteBackingStore(c
);
1383 //Following code is added to enable parallel render
1384 // Parallel render only work in double buffer mode
1385 #if !defined(NO_PARALLEL)
1387 PRDestroyRenderBuffer();
1392 void WMesaMakeCurrent( WMesaContext c
)
1400 // A little optimization
1401 // If it already is current,
1402 // don't set it again
1407 //gl_set_context( c->gl_ctx );
1408 gl_make_current(c
->gl_ctx
, c
->gl_buffer
);
1409 setup_DD_pointers(c
->gl_ctx
);
1411 if (Current
->gl_ctx
->Viewport
.Width
==0) {
1412 /* initialize viewport to window size */
1413 _mesa_set_viewport( Current
->gl_ctx
,
1414 0, 0, Current
->width
, Current
->height
);
1416 if ((c
->cColorBits
<= 8 ) && (c
->rgb_flag
== GL_TRUE
)){
1417 WMesaPaletteChange(c
->hPalHalfTone
);
1421 void WMesaSwapBuffers( void )
1423 HDC DC
= Current
->hDC
;
1424 if (Current
->db_flag
)
1428 void WMesaPaletteChange(HPALETTE Pal
)
1431 LPPALETTEENTRY pPal
;
1432 if (Current
&& (Current
->rgb_flag
==GL_FALSE
|| Current
->dither_flag
== GL_TRUE
))
1434 pPal
= (PALETTEENTRY
*)malloc( 256 * sizeof(PALETTEENTRY
));
1436 // GetPaletteEntries( Pal, 0, 256, pPal );
1437 GetPalette( Pal
, pPal
);
1439 Current
->lpDD
->lpVtbl
->CreatePalette(Current
->lpDD
,DDPCAPS_8BIT
,
1440 pPal
, &(Current
->lpDDPal
), NULL
);
1441 if (Current
->lpDDPal
)
1442 Current
->lpDDSPrimary
->lpVtbl
->SetPalette(Current
->lpDDSPrimary
,Current
->lpDDPal
);
1444 vRet
= SetDIBColorTable(Current
->dib
.hDC
,0,256,pPal
);
1451 static unsigned char threeto8
[8] = {
1452 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
1455 static unsigned char twoto8
[4] = {
1459 static unsigned char oneto8
[2] = {
1463 static unsigned char componentFromIndex(UCHAR i
, UINT nbits
, UINT shift
)
1480 return threeto8
[val
];
1487 void wmCreatePalette( PWMC pwdc
)
1489 /* Create a compressed and re-expanded 3:3:2 palette */
1492 BYTE rb
, rs
, gb
, gs
, bb
, bs
;
1494 pwdc
->nColors
= 0x100;
1496 pPal
= (PLOGPALETTE
)malloc(sizeof(LOGPALETTE
) + pwdc
->nColors
* sizeof(PALETTEENTRY
));
1497 memset( pPal
, 0, sizeof(LOGPALETTE
) + pwdc
->nColors
* sizeof(PALETTEENTRY
) );
1499 pPal
->palVersion
= 0x300;
1508 if (pwdc
->db_flag
) {
1510 /* Need to make two palettes: one for the screen DC and one for the DIB. */
1511 pPal
->palNumEntries
= pwdc
->nColors
;
1512 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1513 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1514 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1515 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1516 pPal
->palPalEntry
[i
].peFlags
= 0;
1518 pwdc
->hGLPalette
= CreatePalette( pPal
);
1519 pwdc
->hPalette
= CreatePalette( pPal
);
1523 pPal
->palNumEntries
= pwdc
->nColors
;
1524 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1525 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1526 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1527 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1528 pPal
->palPalEntry
[i
].peFlags
= 0;
1530 pwdc
->hGLPalette
= CreatePalette( pPal
);
1537 void wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1539 if(Current
->db_flag
){
1540 LPBYTE lpb
= pwc
->pbPixels
;
1543 UINT nBypp
= pwc
->cColorBits
/ 8;
1544 UINT nOffset
= iPixel
% nBypp
;
1546 // Move the pixel buffer pointer to the scanline that we
1549 // pwc->dib.fFlushed = FALSE;
1551 lpb
+= pwc
->ScanWidth
* iScanLine
;
1552 // Now move to the desired pixel
1553 lpb
+= iPixel
* nBypp
;
1554 lpb
= PIXELADDR(iPixel
, iScanLine
);
1555 lpdw
= (LPDWORD
)lpb
;
1559 if(pwc
->dither_flag
)
1560 *lpb
= DITHER_RGB_2_8BIT(r
,g
,b
,iScanLine
,iPixel
);
1565 *lpw
= BGR16(r
,g
,b
);
1566 else if (nBypp
== 3){
1567 *lpdw
= BGR24(r
,g
,b
);
1569 else if (nBypp
== 4)
1570 *lpdw
= BGR32(r
,g
,b
);
1574 SetPixel(DC
, iPixel
, iScanLine
, RGB(r
,g
,b
));
1579 void wmCreateDIBSection( HDC hDC
,
1580 PWMC pwc
, // handle of device context
1581 CONST BITMAPINFO
*pbmi
, // address of structure containing bitmap size, format, and color data
1582 UINT iUsage
// color data type indicator: RGB values or palette indices
1587 UINT nBypp
= pwc
->cColorBits
/ 8;
1590 dwScanWidth
= (((pwc
->ScanWidth
* nBypp
)+ 3) & ~3);
1592 pwc
->ScanWidth
=pwc
->pitch
= dwScanWidth
;
1595 pwc
->ScanWidth
= 2* pwc
->pitch
;
1597 dwSize
= sizeof(BITMAPINFO
) + (dwScanWidth
* pwc
->height
);
1599 pwc
->dib
.hFileMap
= CreateFileMapping((HANDLE
)PAGE_FILE
,
1601 PAGE_READWRITE
| SEC_COMMIT
,
1606 if (!pwc
->dib
.hFileMap
)
1609 pwc
->dib
.base
= MapViewOfFile(pwc
->dib
.hFileMap
,
1610 FILE_MAP_ALL_ACCESS
,
1616 CloseHandle(pwc
->dib
.hFileMap
);
1620 // pwc->pbPixels = pwc->addrOffScreen = ((LPBYTE)pwc->dib.base) + sizeof(BITMAPINFO);
1622 // pwc->dib.hDC = CreateCompatibleDC(hDC);
1624 CopyMemory(pwc
->dib
.base
, pbmi
, sizeof(BITMAPINFO
));
1626 hic
= CreateIC("display", NULL
, NULL
, NULL
);
1627 pwc
->dib
.hDC
= CreateCompatibleDC(hic
);
1630 /* pwc->hbmDIB = CreateDIBitmap(hic,
1631 &(pwc->bmi.bmiHeader),
1637 pwc
->hbmDIB
= CreateDIBSection(hic
,
1639 (iUsage
? DIB_PAL_COLORS
: DIB_RGB_COLORS
),
1644 pwc->hbmDIB = CreateDIBSection(hic,
1651 pwc
->ScreenMem
= pwc
->addrOffScreen
= pwc
->pbPixels
;
1652 pwc
->hOldBitmap
= SelectObject(pwc
->dib
.hDC
, pwc
->hbmDIB
);
1661 // Blit memory DC to screen DC
1663 BOOL
wmFlush(PWMC pwc
)
1671 // Now search through the torus frames and mark used colors
1674 if (pwc
->lpDDSOffScreen
== NULL
)
1675 if(DDCreateOffScreen(pwc
) == GL_FALSE
)
1678 pwc
->lpDDSOffScreen
->lpVtbl
->Unlock(pwc
->lpDDSOffScreen
, NULL
);
1682 ddrval
= pwc
->lpDDSPrimary
->lpVtbl
->Blt( pwc
->lpDDSPrimary
,
1683 &(pwc
->rectSurface
), pwc
->lpDDSOffScreen
, &(pwc
->rectOffScreen
), 0, NULL
);
1685 if( ddrval
== DD_OK
)
1689 if( ddrval
== DDERR_SURFACELOST
)
1691 if(!DDRestoreAll(pwc
))
1696 if( ddrval
!= DDERR_WASSTILLDRAWING
)
1702 while (pwc
->lpDDSOffScreen
->lpVtbl
->Lock(pwc
->lpDDSOffScreen
,
1703 NULL
, &(pwc
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
)
1707 dwErr
= GetLastError();
1709 bRet
= BitBlt(pwc
->hDC
, 0, 0, pwc
->width
, pwc
->height
,
1710 pwc
->dib
.hDC
, 0, 0, SRCCOPY
);
1718 // The following code is added by Li Wei to enable stereo display
1720 #if !defined(NO_STEREO)
1722 void WMesaShowStereo(GLuint list
)
1725 GLbitfield mask
= GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
;
1728 // Must use double Buffer
1729 if( ! Current
-> db_flag
)
1733 glGetIntegerv(GL_MATRIX_MODE
,&matrix_mode
);
1735 // glPushMatrix(); //****
1736 WMesaViewport(Current
->gl_ctx
,0,Current
->height
/2,Current
->width
,Current
->height
/2);
1737 // Current->gl_ctx->NewState = 0;
1739 // glViewport(0,0,Current->width,Current->height/2);
1740 if(matrix_mode
!=GL_MODELVIEW
)
1741 glMatrixMode(GL_MODELVIEW
);
1743 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1745 gluLookAt(viewDistance
/2,0.0,0.0 ,
1746 viewDistance
/2,0.0,-1.0,
1748 // glTranslatef(viewDistance/2.0,0.,0.);
1749 glMultMatrixf( cm
);
1751 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
;
1756 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1758 gluLookAt(-viewDistance
/2,0.0,0.0 ,
1759 -viewDistance
/2,0.0,-1.0,
1761 // glTranslatef(-viewDistance/2.0,0.,0.);
1764 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
+ Current
->pitch
;
1766 if(matrix_mode
!=GL_MODELVIEW
)
1767 glMatrixMode(matrix_mode
);
1772 WMesaViewport(Current
->gl_ctx
,0,0,Current
->width
,Current
->height
);
1773 // Current->gl_ctx->NewState = 0;
1778 void toggleStereoMode()
1780 if(!Current
->db_flag
)
1784 if(stereoBuffer
==GL_FALSE
)
1785 #if !defined(NO_PARALLEL)
1789 Current
->ScanWidth
= Current
->pitch
*2;
1794 #if !defined(NO_PARALLEL)
1797 Current
->ScanWidth
= Current
->pitch
;
1798 Current
->pbPixels
= Current
->addrOffScreen
;
1802 /* if in stereo mode, the following function is called */
1803 void glShowStereo(GLuint list
)
1805 WMesaShowStereo(list
);
1808 #endif // End if NO_STEREO not defined
1810 #if !defined(NO_PARALLEL)
1812 void toggleParallelMode(void)
1815 parallelFlag
= GL_TRUE
;
1816 if(parallelMachine
==GL_FALSE
){
1817 PRCreateRenderBuffer( Current
->rgb_flag
? GL_RGBA
:GL_COLOR_INDEX
,
1818 Current
->cColorBits
/8,
1819 Current
->width
,Current
->height
,
1821 Current
->rgb_flag
? Current
->pbPixels
: Current
->ScreenMem
);
1822 parallelMachine
= GL_TRUE
;
1826 parallelFlag
= GL_FALSE
;
1827 if(parallelMachine
==GL_TRUE
){
1828 PRDestroyRenderBuffer();
1829 parallelMachine
=GL_FALSE
;
1830 ReadyForNextFrame
= GL_TRUE
;
1833 /***********************************************
1834 // Seems something wrong!!!!
1835 ************************************************/
1837 WMesaMakeCurrent(Current
);
1838 #if !defined(NO_STEREO)
1839 stereo_flag
= GL_FALSE
;
1844 void PRShowRenderResult(void)
1847 if(!glImageRendered())
1856 #endif //End if NO_PARALLEL not defined
1860 BYTE
DITHER_RGB_2_8BIT( int red
, int green
, int blue
, int pixel
, int scanline
)
1862 char unsigned redtemp
, greentemp
, bluetemp
, paletteindex
;
1864 //*** now, look up each value in the halftone matrix
1865 //*** using an 8x8 ordered dither.
1866 redtemp
= aDividedBy51
[red
]
1867 + (aModulo51
[red
] > aHalftone8x8
[(pixel
%8)*8
1869 greentemp
= aDividedBy51
[(char unsigned)green
]
1870 + (aModulo51
[green
] > aHalftone8x8
[
1871 (pixel
%8)*8 + scanline
%8]);
1872 bluetemp
= aDividedBy51
[(char unsigned)blue
]
1873 + (aModulo51
[blue
] > aHalftone8x8
[
1874 (pixel
%8)*8 +scanline
%8]);
1876 //*** recombine the halftoned rgb values into a palette index
1878 redtemp
+ aTimes6
[greentemp
] + aTimes36
[bluetemp
];
1880 //*** and translate through the wing halftone palette
1881 //*** translation vector to give the correct value.
1882 return aWinGHalftoneTranslation
[paletteindex
];
1889 * restore all lost objects
1891 static HRESULT
DDRestoreAll( WMesaContext wc
)
1895 ddrval
= wc
->lpDDSPrimary
->lpVtbl
->Restore(wc
->lpDDSPrimary
);
1896 if( ddrval
== DD_OK
)
1898 ddrval
= wc
->lpDDSOffScreen
->lpVtbl
->Restore(wc
->lpDDSOffScreen
);
1906 * This function is called if the initialization function fails
1908 static BOOL
initFail( HWND hwnd
, WMesaContext wc
)
1911 MessageBox( hwnd
, "DirectDraw Init FAILED", "", MB_OK
);
1917 static void DDDeleteOffScreen(WMesaContext wc
)
1919 if( wc
->lpDDSOffScreen
!= NULL
)
1921 wc
->lpDDSOffScreen
->lpVtbl
->Unlock(wc
->lpDDSOffScreen
,NULL
);
1922 wc
->lpDDSOffScreen
->lpVtbl
->Release(wc
->lpDDSOffScreen
);
1923 wc
->lpDDSOffScreen
= NULL
;
1928 static void DDFreePrimarySurface(WMesaContext wc
)
1930 if( wc
->lpDDSPrimary
!= NULL
)
1932 if(wc
->db_flag
== GL_FALSE
)
1933 wc
->lpDDSPrimary
->lpVtbl
->ReleaseDC(wc
->lpDDSPrimary
, wc
->hDC
);
1934 wc
->lpDDSPrimary
->lpVtbl
->Release(wc
->lpDDSPrimary
);
1935 wc
->lpDDSPrimary
= NULL
;
1939 static BOOL
DDCreatePrimarySurface(WMesaContext wc
)
1943 wc
->ddsd
.dwSize
= sizeof( wc
->ddsd
);
1944 wc
->ddsd
.dwFlags
= DDSD_CAPS
;
1945 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
1947 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
,&(wc
->ddsd
), &(wc
->lpDDSPrimary
), NULL
);
1948 if( ddrval
!= DD_OK
)
1950 return initFail(wc
->hwnd
, wc
);
1952 if(wc
->db_flag
== GL_FALSE
)
1953 wc
->lpDDSPrimary
->lpVtbl
->GetDC(wc
->lpDDSPrimary
, wc
->hDC
);
1957 static BOOL
DDCreateOffScreen(WMesaContext wc
)
1961 if(wc
->lpDD
== NULL
)
1963 GetClientRect( wc
->hwnd
, &(wc
->rectOffScreen
) );
1964 wc
->ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1965 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
1966 wc
->ddsd
.dwHeight
= wc
->rectOffScreen
.bottom
- wc
->rectOffScreen
.top
;
1967 wc
->ddsd
.dwWidth
= wc
->rectOffScreen
.right
- wc
->rectOffScreen
.left
;
1969 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
, &(wc
->ddsd
), &(wc
->lpDDSOffScreen
), NULL
);
1970 if( ddrval
!= DD_OK
)
1975 while (wc
->lpDDSOffScreen
->lpVtbl
->Lock(wc
->lpDDSOffScreen
,NULL
, &(wc
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
)
1977 // while ((ddrval = wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, &(wc->ddsd), DDLOCK_SURFACEMEMORYPTR , NULL)) != DD_OK)
1979 if(wc
->ddsd
.lpSurface
==NULL
)
1980 return initFail(wc
->hwnd
, wc
);
1982 wc
->ScreenMem
= wc
->pbPixels
= wc
->addrOffScreen
= (PBYTE
)(wc
->ddsd
.lpSurface
);
1983 wc
->ScanWidth
= wc
->pitch
= wc
->ddsd
.lPitch
;
1985 wc
->ScanWidth
= wc
->ddsd
.lPitch
*2;
1987 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
1989 ClientToScreen( wc
->hwnd
, &pt
);
1990 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
1991 wmSetPixelFormat(wc
, wc
->hDC
);
1996 * doInit - do work required for every instance of the application:
1997 * create the window, initialize data
1999 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
)
2004 LPDIRECTDRAW lpDD
; // DirectDraw object
2005 LPDIRECTDRAW2 lpDD2
;
2008 wc
->fullScreen
= displayOptions
.fullScreen
;
2009 wc
->gMode
= displayOptions
.mode
;
2011 stereo_flag
= displayOptions
.stereo
;
2012 if(wc
->db_flag
!= GL_TRUE
)
2013 stereo_flag
= GL_FALSE
;
2015 * create the main DirectDraw object
2017 ddrval
= DirectDrawCreate( NULL
, &(wc
->lpDD
), NULL
);
2018 if( ddrval
!= DD_OK
)
2020 return initFail(hwnd
,wc
);
2023 // Get exclusive mode if requested
2026 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2030 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
, DDSCL_NORMAL
);
2032 if( ddrval
!= DD_OK
)
2034 return initFail(hwnd
, wc
);
2038 /* ddrval = wc->lpDD->lpVtbl->QueryInterface(wc->lpDD, IID_IDirectDraw2,
2039 (LPVOID *)((wc->lpDD2)));
2043 return initFail(hwnd
, wc
);
2046 //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
2047 // wc->lpDD2->lpVtbl->GetMonitorFrequency(wc->lpDD, &dwFrequency);
2050 case 1: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 640, 480, displayOptions
.bpp
); break;
2051 case 2: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 800, 600, displayOptions
.bpp
); break;
2052 case 3: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1024, 768, displayOptions
.bpp
); break;
2053 case 4: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1152, 864, displayOptions
.bpp
); break;
2054 case 5: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1280, 1024, displayOptions
.bpp
); break;
2057 if( ddrval
!= DD_OK
)
2059 printf("Can't modify display mode, current mode used\n");
2060 // return initFail(hwnd , wc);
2062 //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
2064 case DDERR_INVALIDOBJECT
:
2066 case DDERR_INVALIDPARAMS
:
2068 case DDERR_UNSUPPORTEDMODE
:
2072 if(DDCreatePrimarySurface(wc
) == GL_FALSE
)
2073 return initFail(hwnd
, wc
);
2076 return DDCreateOffScreen(wc
);
2079 static void DDFree( WMesaContext wc
)
2081 if( wc
->lpDD
!= NULL
)
2083 DDFreePrimarySurface(wc
);
2084 DDDeleteOffScreen(wc
);
2085 wc
->lpDD
->lpVtbl
->Release(wc
->lpDD
);
2088 // Clean up the screen on exit
2089 RedrawWindow( NULL
, NULL
, NULL
, RDW_INVALIDATE
| RDW_ERASE
|
2095 void WMesaMove(void)
2097 WMesaContext wc
= Current
;
2099 if (Current
!= NULL
){
2100 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2102 ClientToScreen( wc
->hwnd
, &pt
);
2103 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2110 * Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable
2113 #define PACK_8B8G8R( R, G, B ) ( ((B) << 16) | ((G) << 8) | (R) )
2116 /**********************************************************************/
2117 /*** Triangle rendering ***/
2118 /**********************************************************************/
2121 * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
2123 static void smooth_8A8B8G8R_z_triangle( GLcontext
*ctx
,
2124 GLuint v0
, GLuint v1
, GLuint v2
,
2127 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2129 #define INTERP_RGB 1
2130 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2131 #define PIXEL_TYPE GLuint
2132 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2133 #define BYTES_PER_ROW (wmesa->ScanWidth)
2134 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2136 GLint i, len = RIGHT-LEFT; \
2137 for (i=0;i<len;i++) { \
2138 GLdepth z = FixedToDepth(ffz); \
2139 if (z < zRow[i]) { \
2140 pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2141 FixedToInt(ffb) ); \
2144 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2149 #include "..\tritemp.h"
2151 #include "tritemp.h"
2157 * XImage, smooth, depth-buffered, PF_8R8G8B triangle.
2159 static void smooth_8R8G8B_z_triangle( GLcontext
*ctx
,
2160 GLuint v0
, GLuint v1
, GLuint v2
,
2163 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2165 #define INTERP_RGB 1
2166 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2167 #define PIXEL_TYPE GLuint
2168 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2169 #define BYTES_PER_ROW (wmesa->ScanWidth)
2170 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2172 GLint i, len = RIGHT-LEFT; \
2173 for (i=0;i<len;i++) { \
2174 GLdepth z = FixedToDepth(ffz); \
2175 if (z < zRow[i]) { \
2176 pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2177 FixedToInt(ffb) ); \
2180 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2185 #include "..\tritemp.h"
2187 #include "tritemp.h"
2194 * XImage, smooth, depth-buffered, PF_5R6G5B triangle.
2196 static void smooth_5R6G5B_z_triangle( GLcontext
*ctx
,
2197 GLuint v0
, GLuint v1
, GLuint v2
,
2200 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2202 #define INTERP_RGB 1
2203 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2204 #define PIXEL_TYPE GLushort
2205 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2206 #define BYTES_PER_ROW (wmesa->ScanWidth)
2207 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2209 GLint i, len = RIGHT-LEFT; \
2210 for (i=0;i<len;i++) { \
2211 GLdepth z = FixedToDepth(ffz); \
2212 if (z < zRow[i]) { \
2213 pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2214 FixedToInt(ffb) ); \
2217 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2222 #include "..\tritemp.h"
2224 #include "tritemp.h"
2229 * XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
2231 static void flat_8A8B8G8R_z_triangle( GLcontext
*ctx
, GLuint v0
,
2232 GLuint v1
, GLuint v2
, GLuint pv
)
2234 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2236 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2237 #define PIXEL_TYPE GLuint
2238 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2239 #define BYTES_PER_ROW (wmesa->ScanWidth)
2240 #define SETUP_CODE \
2241 unsigned long p = PACK_8B8G8R( VB->Color[pv][0], \
2242 VB->Color[pv][1], VB->Color[pv][2] );
2243 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2245 GLint i, len = RIGHT-LEFT; \
2246 for (i=0;i<len;i++) { \
2247 GLdepth z = FixedToDepth(ffz); \
2248 if (z < zRow[i]) { \
2256 #include "..\tritemp.h"
2258 #include "tritemp.h"
2264 * XImage, flat, depth-buffered, PF_8R8G8B triangle.
2266 static void flat_8R8G8B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2267 GLuint v2
, GLuint pv
)
2269 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2271 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2272 #define PIXEL_TYPE GLuint
2273 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2274 #define BYTES_PER_ROW (wmesa->ScanWidth)
2275 #define SETUP_CODE \
2276 unsigned long p = PACK_8R8G8B( VB->Color[pv][0], \
2277 VB->Color[pv][1], VB->Color[pv][2] );
2278 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2280 GLint i, len = RIGHT-LEFT; \
2281 for (i=0;i<len;i++) { \
2282 GLdepth z = FixedToDepth(ffz); \
2283 if (z < zRow[i]) { \
2291 #include "..\tritemp.h"
2293 #include "tritemp.h"
2299 * XImage, flat, depth-buffered, PF_5R6G5B triangle.
2301 static void flat_5R6G5B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2302 GLuint v2
, GLuint pv
)
2304 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2306 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2307 #define PIXEL_TYPE GLushort
2308 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2309 #define BYTES_PER_ROW (wmesa->ScanWidth)
2310 #define SETUP_CODE \
2311 unsigned long p = PACK_5R6G5B( VB->Color[pv][0], \
2312 VB->Color[pv][1], VB->Color[pv][2] );
2313 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2315 GLint i, len = RIGHT-LEFT; \
2316 for (i=0;i<len;i++) { \
2317 GLdepth z = FixedToDepth(ffz); \
2318 if (z < zRow[i]) { \
2326 #include "..\tritemp.h"
2328 #include "tritemp.h"
2334 * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
2336 static void smooth_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2337 GLuint v2
, GLuint pv
)
2339 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2340 #define INTERP_RGB 1
2341 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2342 #define PIXEL_TYPE GLuint
2343 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2344 #define BYTES_PER_ROW (wmesa->ScanWidth)
2345 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2348 PIXEL_TYPE *pixel = pRow; \
2349 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2350 *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2351 FixedToInt(ffb) ); \
2352 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2356 #include "..\tritemp.h"
2358 #include "tritemp.h"
2364 * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
2366 static void smooth_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2367 GLuint v2
, GLuint pv
)
2369 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2370 #define INTERP_RGB 1
2371 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2372 #define PIXEL_TYPE GLuint
2373 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2374 #define BYTES_PER_ROW (wmesa->ScanWidth)
2375 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2378 PIXEL_TYPE *pixel = pRow; \
2379 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2380 *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2381 FixedToInt(ffb) ); \
2382 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2386 #include "..\tritemp.h"
2388 #include "tritemp.h"
2394 * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
2396 static void smooth_5R6G5B_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) PIXELADDR2(X,Y)
2402 #define PIXEL_TYPE GLushort
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_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2411 FixedToInt(ffb) ); \
2412 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2416 #include "..\tritemp.h"
2418 #include "tritemp.h"
2425 * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
2427 static void flat_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
,
2428 GLuint v1
, GLuint v2
, GLuint pv
)
2430 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2431 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2432 #define PIXEL_TYPE GLuint
2433 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2434 #define BYTES_PER_ROW (wmesa->ScanWidth)
2435 #define SETUP_CODE \
2436 unsigned long p = PACK_8B8G8R( VB->Color[pv][0], \
2437 VB->Color[pv][1], VB->Color[pv][2] );
2438 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2441 PIXEL_TYPE *pixel = pRow; \
2442 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2447 #include "..\tritemp.h"
2449 #include "tritemp.h"
2455 * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
2457 static void flat_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2458 GLuint v2
, GLuint pv
)
2460 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2461 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2462 #define PIXEL_TYPE GLuint
2463 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2464 #define BYTES_PER_ROW (wmesa->ScanWidth)
2465 #define SETUP_CODE \
2466 unsigned long p = PACK_8R8G8B( VB->Color[pv][0], \
2467 VB->Color[pv][1], VB->Color[pv][2] );
2468 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2471 PIXEL_TYPE *pixel = pRow; \
2472 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2477 #include "..\tritemp.h"
2479 #include "tritemp.h"
2485 * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
2487 static void flat_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2488 GLuint v2
, GLuint pv
)
2490 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2491 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2492 #define PIXEL_TYPE GLushort
2493 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2494 #define BYTES_PER_ROW (wmesa->ScanWidth)
2495 #define SETUP_CODE \
2496 unsigned long p = PACK_5R6G5B( VB->Color[pv][0], \
2497 VB->Color[pv][1], VB->Color[pv][2] );
2498 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2501 PIXEL_TYPE *pixel = pRow; \
2502 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2507 #include "..\tritemp.h"
2509 #include "tritemp.h"
2515 * XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
2518 static void smooth_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2519 GLuint v2
, GLuint pv
)
2521 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2523 #define INTERP_INDEX 1
2524 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2525 #define PIXEL_TYPE GLubyte
2526 #define BYTES_PER_ROW (wmesa->ScanWidth)
2527 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2529 GLint i, len = RIGHT-LEFT; \
2530 for (i=0;i<len;i++) { \
2531 GLdepth z = FixedToDepth(ffz); \
2532 if (z < zRow[i]) { \
2533 pRow[i] = FixedToInt(ffi); \
2542 #include "..\tritemp.h"
2544 #include "tritemp.h"
2550 * XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
2553 static void flat_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2554 GLuint v2
, GLuint pv
)
2556 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2558 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2559 #define PIXEL_TYPE GLubyte
2560 #define BYTES_PER_ROW (wmesa->ScanWidth)
2561 #define SETUP_CODE \
2562 GLuint index = VB->Index[pv]; \
2563 if (!VB->MonoColor) { \
2564 /* set the color index */ \
2565 (*ctx->Driver.Index)( ctx, index ); \
2567 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2569 GLint i, len = RIGHT-LEFT; \
2570 for (i=0;i<len;i++) { \
2571 GLdepth z = FixedToDepth(ffz); \
2572 if (z < zRow[i]) { \
2580 #include "..\tritemp.h"
2582 #include "tritemp.h"
2589 * XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2592 static void smooth_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2593 GLuint v2
, GLuint pv
)
2595 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2597 #define INTERP_INDEX 1
2598 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2599 #define PIXEL_TYPE GLubyte
2600 #define BYTES_PER_ROW (wmesa->ScanWidth)
2601 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2604 PIXEL_TYPE *pixel = pRow; \
2605 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2606 *pixel = FixedToInt(ffi); \
2611 #include "..\tritemp.h"
2613 #include "tritemp.h"
2619 * XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2621 static void flat_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2622 GLuint v2
, GLuint pv
)
2624 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2626 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2627 #define PIXEL_TYPE GLubyte
2628 #define BYTES_PER_ROW (wmesa->ScanWidth)
2629 #define SETUP_CODE \
2630 GLuint index = VB->Index[pv]; \
2631 if (!VB->MonoColor) { \
2632 /* set the color index */ \
2633 (*ctx->Driver.Index)( ctx, index ); \
2635 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2638 PIXEL_TYPE *pixel = pRow; \
2639 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2644 #include "..\tritemp.h"
2646 #include "tritemp.h"
2651 * XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
2653 static void smooth_DITHER8_z_triangle( GLcontext
*ctx
,
2654 GLuint v0
, GLuint v1
, GLuint v2
,
2657 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2658 DITHER_RGB_TO_8BIT_SETUP
2660 #define INTERP_RGB 1
2661 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2662 #define PIXEL_TYPE GLubyte
2663 #define BYTES_PER_ROW (wmesa->ScanWidth)
2664 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2666 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
2667 for (i=0;i<len;i++,xx++) { \
2668 GLdepth z = FixedToDepth(ffz); \
2669 if (z < zRow[i]) { \
2670 DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg), \
2671 FixedToInt(ffb), xx, yy); \
2672 pRow[i] = pixelDithered; \
2675 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2680 #include "..\tritemp.h"
2682 #include "tritemp.h"
2687 * XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
2689 static void flat_DITHER8_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2690 GLuint v2
, GLuint pv
)
2692 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2693 DITHER_RGB_TO_8BIT_SETUP
2695 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2696 #define PIXEL_TYPE GLubyte
2697 #define BYTES_PER_ROW (wmesa->ScanWidth)
2699 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2701 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
2702 for (i=0;i<len;i++,xx++) { \
2703 GLdepth z = FixedToDepth(ffz); \
2704 if (z < zRow[i]) { \
2705 DITHER_RGB_TO_8BIT( VB->Color[pv][0], \
2706 VB->Color[pv][1], VB->Color[pv][2], xx, yy); \
2707 pRow[i] = pixelDithered; \
2714 #include "..\tritemp.h"
2716 #include "tritemp.h"
2721 * XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
2723 static void smooth_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2724 GLuint v2
, GLuint pv
)
2726 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2727 DITHER_RGB_TO_8BIT_SETUP
2728 #define INTERP_RGB 1
2729 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2730 #define PIXEL_TYPE GLubyte
2731 #define BYTES_PER_ROW (wmesa->ScanWidth)
2732 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2734 GLint xx, yy = FLIP(Y); \
2735 PIXEL_TYPE *pixel = pRow; \
2736 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2737 DITHER_RGB_TO_8BIT( VB->Color[pv][0], VB->Color[pv][1], VB->Color[pv][2], xx, yy);\
2738 *pixel = pixelDithered; \
2739 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2743 #include "..\tritemp.h"
2745 #include "tritemp.h"
2750 * XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
2753 static void flat_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2754 GLuint v2
, GLuint pv
)
2756 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2757 DITHER_RGB_TO_8BIT_SETUP
2758 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2759 #define PIXEL_TYPE GLubyte
2760 #define BYTES_PER_ROW (wmesa->ScanWidth)
2762 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2764 GLint xx, yy = FLIP(Y); \
2765 PIXEL_TYPE *pixel = pRow; \
2766 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2767 DITHER_RGB_TO_8BIT( VB->Color[pv][0], \
2768 VB->Color[pv][1], VB->Color[pv][2], xx, yy); \
2769 *pixel = pixelDithered; \
2773 #include "..\tritemp.h"
2775 #include "tritemp.h"
2782 static triangle_func
choose_triangle_function( GLcontext
*ctx
)
2784 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2785 int depth
= wmesa
->cColorBits
;
2787 if (ctx
->Polygon
.SmoothFlag
) return NULL
;
2788 if (ctx
->Texture
.Enabled
) return NULL
;
2789 if (!wmesa
->db_flag
) return NULL
;
2790 /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {
2791 if ( ctx
->Light
.ShadeModel
==GL_SMOOTH
2792 && ctx
->_RasterMask
==DEPTH_BIT
2793 && ctx
->Depth
.Func
==GL_LESS
2794 && ctx
->Depth
.Mask
==GL_TRUE
2795 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2796 switch (wmesa
->pixelformat
) {
2798 return smooth_8A8B8G8R_z_triangle
;
2800 return smooth_8R8G8B_z_triangle
;
2802 return smooth_5R6G5B_z_triangle
;
2804 return smooth_DITHER8_z_triangle
;
2806 return smooth_ci_z_triangle
;
2811 if ( ctx
->Light
.ShadeModel
==GL_FLAT
2812 && ctx
->_RasterMask
==DEPTH_BIT
2813 && ctx
->Depth
.Func
==GL_LESS
2814 && ctx
->Depth
.Mask
==GL_TRUE
2815 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2816 switch (wmesa
->pixelformat
) {
2818 return flat_8A8B8G8R_z_triangle
;
2820 return flat_8R8G8B_z_triangle
;
2822 return flat_5R6G5B_z_triangle
;
2824 return flat_DITHER8_z_triangle
;
2826 return flat_ci_z_triangle
;
2831 if ( ctx
->_RasterMask
==0 /* no depth test */
2832 && ctx
->Light
.ShadeModel
==GL_SMOOTH
2833 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2834 switch (wmesa
->pixelformat
) {
2836 return smooth_8A8B8G8R_triangle
;
2838 return smooth_8R8G8B_triangle
;
2840 return smooth_5R6G5B_triangle
;
2842 return smooth_DITHER8_triangle
;
2844 return smooth_ci_triangle
;
2850 if ( ctx
->_RasterMask
==0 /* no depth test */
2851 && ctx
->Light
.ShadeModel
==GL_FLAT
2852 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2853 switch (wmesa
->pixelformat
) {
2855 return flat_8A8B8G8R_triangle
;
2857 return flat_8R8G8B_triangle
;
2859 return flat_5R6G5B_triangle
;
2861 return flat_DITHER8_triangle
;
2863 return flat_ci_triangle
;
2874 * Define a new viewport and reallocate auxillary buffers if the size of
2875 * the window (color buffer) has changed.
2877 void WMesaViewport( GLcontext
*ctx
,
2878 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2881 ctx
->Viewport
.X
= x
;
2882 ctx
->Viewport
.Width
= width
;
2883 ctx
->Viewport
.Y
= y
;
2884 ctx
->Viewport
.Height
= height
;
2886 /* compute scale and bias values */
2887 ctx
->Viewport
.Sx
= (GLfloat
) width
/ 2.0F
;
2888 ctx
->Viewport
.Tx
= ctx
->Viewport
.Sx
+ x
;
2889 ctx
->Viewport
.Sy
= (GLfloat
) height
/ 2.0F
;
2890 ctx
->Viewport
.Ty
= ctx
->Viewport
.Sy
+ y
;