5 * Display driver for Mesa 2.3 under
6 * Windows95 and WindowsNT
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
22 * $Log: wmesaOld.c,v $
23 * Revision 1.1 1999/08/19 00:55:42 jtg
26 * Revision 1.2 1999/01/03 03:08:57 brianp
29 * Revision 1.0 1997/06/14 17:51:00 CST by Li Wei(liwei@aiar.xjtu.edu.cn)
30 * New display driver for Mesa 2.x using Microsoft Direct Draw
35 #define WMESA_STEREO_C
50 // #include "profile.h"
60 #define CopyMemory memcpy
62 #include "mesa_extend.h"
65 #if !defined(NO_STEREO)
71 #if !defined(NO_PARALLEL)
72 // #include "parallel.h"
75 struct DISPLAY_OPTIONS displayOptions
;
77 GLenum stereoCompile
= GL_FALSE
;
78 GLenum stereoShowing
= GL_FALSE
;
79 GLenum stereoBuffer
= GL_FALSE
;
80 #if !defined(NO_STEREO)
81 GLint displayList
= MAXIMUM_DISPLAY_LIST
;
83 GLint stereo_flag
= 0 ;
85 /* end of added code*/
87 static PWMC Current
= NULL
;
88 WMesaContext WC
= NULL
;
91 #define assert(ignore) ((void) 0)
93 void Mesa_Assert(void *Cond
,void *File
,unsigned Line
)
96 sprintf(Msg
,"%s %s %d",Cond
,File
,Line
);
97 MessageBox(NULL
,Msg
,"Assertion failed.",MB_OK
);
100 #define assert(e) if (!e) Mesa_Assert(#e,__FILE__,__LINE__);
103 //#define DD_GETDC (Current->hDC )
104 #define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
105 //#define DD_GETDC ((Current->db_flag) ? Current->hDCPrimary : Current->hDCBack )
108 //#define BEGINGDICALL if(Current->rgb_flag)wmFlushBits(Current);
110 //#define ENDGDICALL if(Current->rgb_flag)wmGetBits(Current);
113 //#define FLIP(Y) (Current->dither_flag? Y : Current->height-(Y)-1)
114 //#define FLIP(Y) (Current->height-(Y)-1)
116 #define FLIP(Y) (Current->db_flag? Y: Current->height-(Y)-1)
118 #define ENDPROFILE(PARA)
120 #define DITHER_RGB_TO_8BIT_SETUP \
121 GLubyte pixelDithered;
123 #define DITHER_RGB_TO_8BIT(red, green, blue, pixel, scanline) \
125 char unsigned redtemp, greentemp, bluetemp, paletteindex; \
126 redtemp = aDividedBy51[red] \
127 + (aModulo51[red] > aHalftone8x8[(pixel%8)*8 \
129 greentemp = aDividedBy51[(char unsigned)green] \
130 + (aModulo51[green] > aHalftone8x8[ \
131 (pixel%8)*8 + scanline%8]); \
132 bluetemp = aDividedBy51[(char unsigned)blue] \
133 + (aModulo51[blue] > aHalftone8x8[ \
134 (pixel%8)*8 +scanline%8]); \
135 paletteindex = redtemp + aTimes6[greentemp] + aTimes36[bluetemp]; \
136 pixelDithered = aWinGHalftoneTranslation[paletteindex]; \
141 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
);
142 static void DDFree( WMesaContext wc
);
143 static HRESULT
DDRestoreAll( WMesaContext wc
);
144 static void DDDeleteOffScreen(WMesaContext wc
);
145 static BOOL
DDCreateOffScreen(WMesaContext wc
);
148 static void FlushToFile(PWMC pwc
, PSTR szFile
);
150 BOOL
wmCreateBackingStore(PWMC pwc
, long lxSize
, long lySize
);
151 BOOL
wmDeleteBackingStore(PWMC pwc
);
152 void wmCreatePalette( PWMC pwdc
);
153 BOOL
wmSetDibColors(PWMC pwc
);
154 void wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
);
156 void wmCreateDIBSection(
158 PWMC pwc
, // handle of device context
159 CONST BITMAPINFO
*pbmi
, // address of structure containing bitmap size, format, and color data
160 UINT iUsage
// color data type indicator: RGB values or palette indices
164 void WMesaViewport( GLcontext
*ctx
,
165 GLint x
, GLint y
, GLsizei width
, GLsizei height
);
167 static triangle_func
choose_triangle_function( GLcontext
*ctx
);
169 static void wmSetPixelFormat( PWMC wc
, HDC hDC
)
172 wc
->cColorBits
= GetDeviceCaps(hDC
, BITSPIXEL
);
175 switch(wc
->cColorBits
){
177 if(wc
->dither_flag
!= GL_TRUE
)
178 wc
->pixelformat
= PF_INDEX8
;
180 wc
->pixelformat
= PF_DITHER8
;
183 wc
->pixelformat
= PF_5R6G5B
;
186 wc
->pixelformat
= PF_8R8G8B
;
189 wc
->pixelformat
= PF_BADFORMAT
;
194 // This function sets the color table of a DIB section
195 // to match that of the destination DC
197 BOOL
/*WINAPI*/ wmSetDibColors(PWMC pwc
)
199 RGBQUAD
*pColTab
, *pRGB
;
200 PALETTEENTRY
*pPal
, *pPE
;
205 /* Build a color table in the DIB that maps to the
206 selected palette in the DC.
208 nColors
= 1 << pwc
->cColorBits
;
209 pPal
= (PALETTEENTRY
*)malloc( nColors
* sizeof(PALETTEENTRY
));
210 memset( pPal
, 0, nColors
* sizeof(PALETTEENTRY
) );
211 GetPaletteEntries( pwc
->hGLPalette
, 0, nColors
, pPal
);
212 pColTab
= (RGBQUAD
*)malloc( nColors
* sizeof(RGBQUAD
));
213 for (i
= 0, pRGB
= pColTab
, pPE
= pPal
; i
< nColors
; i
++, pRGB
++, pPE
++) {
214 pRGB
->rgbRed
= pPE
->peRed
;
215 pRGB
->rgbGreen
= pPE
->peGreen
;
216 pRGB
->rgbBlue
= pPE
->peBlue
;
219 bRet
= SetDIBColorTable(pwc
->dib
.hDC
, 0, nColors
, pColTab
);
222 dwErr
= GetLastError();
232 // Free up the dib section that was created
234 BOOL
wmDeleteBackingStore(PWMC pwc
)
236 SelectObject(pwc
->dib
.hDC
, pwc
->hOldBitmap
);
237 DeleteDC(pwc
->dib
.hDC
);
238 DeleteObject(pwc
->hbmDIB
);
239 UnmapViewOfFile(pwc
->dib
.base
);
240 CloseHandle(pwc
->dib
.hFileMap
);
246 // This function creates the DIB section that is used for combined
249 BOOL
/*WINAPI*/ wmCreateBackingStore(PWMC pwc
, long lxSize
, long lySize
)
252 LPBITMAPINFO pbmi
= &(pwc
->bmi
);
255 pbmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
256 pbmi
->bmiHeader
.biWidth
= lxSize
;
257 pbmi
->bmiHeader
.biHeight
= -lySize
;
258 pbmi
->bmiHeader
.biPlanes
= 1;
260 pbmi
->bmiHeader
.biBitCount
= GetDeviceCaps(pwc
->hDC
, BITSPIXEL
);
262 pbmi
->bmiHeader
.biBitCount
= 8;
263 pbmi
->bmiHeader
.biCompression
= BI_RGB
;
264 pbmi
->bmiHeader
.biSizeImage
= 0;
265 pbmi
->bmiHeader
.biXPelsPerMeter
= 0;
266 pbmi
->bmiHeader
.biYPelsPerMeter
= 0;
267 pbmi
->bmiHeader
.biClrUsed
= 0;
268 pbmi
->bmiHeader
.biClrImportant
= 0;
270 iUsage
= (pbmi
->bmiHeader
.biBitCount
<= 8) ? DIB_PAL_COLORS
: DIB_RGB_COLORS
;
272 pwc
->cColorBits
= pbmi
->bmiHeader
.biBitCount
;
273 pwc
->ScanWidth
= pwc
->pitch
= lxSize
;
275 wmCreateDIBSection(hdc
, pwc
, pbmi
, iUsage
);
277 if ((iUsage
== DIB_PAL_COLORS
) && !(pwc
->hGLPalette
)) {
278 wmCreatePalette( pwc
);
279 wmSetDibColors( pwc
);
281 wmSetPixelFormat(pwc
, pwc
->hDC
);
288 // This function copies one scan line in a DIB section to another
290 BOOL GLWINAPI
wmSetDIBits(PWMC pwc
, UINT uiScanWidth
, UINT uiNumScans
, UINT nBypp
, UINT uiNewWidth
, LPBYTE pBits
)
293 LPBYTE pDest
= pwc
->pbPixels
;
294 DWORD dwNextScan
= uiScanWidth
;
295 DWORD dwNewScan
= uiNewWidth
;
296 DWORD dwScanWidth
= (uiScanWidth
* nBypp
);
299 // We need to round up to the nearest DWORD
300 // and multiply by the number of bytes per
303 dwNextScan
= (((dwNextScan
* nBypp
)+ 3) & ~3);
304 dwNewScan
= (((dwNewScan
* nBypp
)+ 3) & ~3);
306 for(uiScans
= 0; uiScans
< uiNumScans
; uiScans
++){
307 CopyMemory(pDest
, pBits
, dwScanWidth
);
317 BOOL
wmFlush(PWMC pwc
);
321 Modified from file osmesa.c
325 #define PIXELADDR(X,Y) ((GLubyte *)Current->pbPixels + (Current->height-Y-1)* Current->ScanWidth + (X)*nBypp)
326 #define PIXELADDR1( X, Y ) \
327 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X))
328 #define PIXELADDR2( X, Y ) \
329 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*2)
330 #define PIXELADDR4( X, Y ) \
331 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*4)
334 BYTE
DITHER_RGB_2_8BIT( int r
, int g
, int b
, int x
, int y
);
336 /* Finish all pending operations and synchronize. */
337 static void finish(GLcontext
* ctx
)
344 // We cache all gl draw routines until a flush is made
346 static void flush(GLcontext
* ctx
)
349 if((Current
->rgb_flag
/*&& !(Current->dib.fFlushed)*/&&!(Current
->db_flag
))
350 ||(!Current
->rgb_flag
))
361 * Set the color index used to clear the color buffer.
363 static void clear_index(GLcontext
* ctx
, GLuint index
)
366 Current
->clearpixel
= index
;
367 ENDPROFILE(clear_index
)
373 * Set the color used to clear the color buffer.
375 static void clear_color( GLcontext
* ctx
, GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
378 Current
->clearpixel
=RGB(r
, g
, b
);
379 ENDPROFILE(clear_color
)
385 * Clear the specified region of the color buffer using the clear color
386 * or index as specified by one of the two functions above.
388 static void clear(GLcontext
* ctx
,
389 GLboolean all
,GLint x
, GLint y
, GLint width
, GLint height
)
394 LPDWORD lpdw
= (LPDWORD
)Current
->pbPixels
;
395 LPWORD lpw
= (LPWORD
)Current
->pbPixels
;
396 LPBYTE lpb
= Current
->pbPixels
;
403 width
=Current
->width
;
404 height
=Current
->height
;
406 if(Current
->db_flag
==GL_TRUE
){
407 UINT nBypp
= Current
->cColorBits
/ 8;
412 /* Need rectification */
413 iSize
= Current
->width
/4;
414 bColor
= BGR8(GetRValue(Current
->clearpixel
),
415 GetGValue(Current
->clearpixel
),
416 GetBValue(Current
->clearpixel
));
417 wColor
= MAKEWORD(bColor
,bColor
);
418 dwColor
= MAKELONG(wColor
, wColor
);
421 iSize
= Current
->width
/ 2;
422 wColor
= BGR16(GetRValue(Current
->clearpixel
),
423 GetGValue(Current
->clearpixel
),
424 GetBValue(Current
->clearpixel
));
425 dwColor
= MAKELONG(wColor
, wColor
);
428 iSize
= Current
->width
;
429 dwColor
= BGR32(GetRValue(Current
->clearpixel
),
430 GetGValue(Current
->clearpixel
),
431 GetBValue(Current
->clearpixel
));
441 // This is the 24bit case
444 iSize
= Current
->width
*3/4;
445 dwColor
= BGR24(GetRValue(Current
->clearpixel
),
446 GetGValue(Current
->clearpixel
),
447 GetBValue(Current
->clearpixel
));
457 if(stereo_flag
) lines
= height
/2;
460 lpb
+= Current
->ScanWidth
;
461 memcpy(lpb
, Current
->pbPixels
, iSize
*4);
466 else{ // For single buffer
468 HPEN Pen
=CreatePen(PS_SOLID
,1,Current
->clearpixel
);
469 HBRUSH Brush
=CreateSolidBrush(Current
->clearpixel
);
470 HPEN Old_Pen
=SelectObject(DC
,Pen
);
471 HBRUSH Old_Brush
=SelectObject(DC
,Brush
);
472 Rectangle(DC
,x
,y
,x
+width
,y
+height
);
473 SelectObject(DC
,Old_Pen
);
474 SelectObject(DC
,Old_Brush
);
487 /* Set the current color index. */
488 static void set_index(GLcontext
* ctx
, GLuint index
)
491 Current
->pixel
=index
;
492 ENDPROFILE(set_index
)
497 /* Set the current RGBA color. */
498 static void set_color( GLcontext
* ctx
, GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
501 Current
->pixel
= RGB( r
, g
, b
);
502 ENDPROFILE(set_color
)
507 /* Set the index mode bitplane mask. */
508 static GLboolean
index_mask(GLcontext
* ctx
, GLuint mask
)
510 /* can't implement */
516 /* Set the RGBA drawing mask. */
517 static GLboolean
color_mask( GLcontext
* ctx
,
518 GLboolean rmask
, GLboolean gmask
,
519 GLboolean bmask
, GLboolean amask
)
521 /* can't implement */
528 * Set the pixel logic operation. Return GL_TRUE if the device driver
529 * can perform the operation, otherwise return GL_FALSE. If GL_FALSE
530 * is returned, the logic op will be done in software by Mesa.
532 GLboolean
logicop( GLcontext
* ctx
, GLenum op
)
534 /* can't implement */
539 static void dither( GLcontext
* ctx
, GLboolean enable
)
541 if(enable
== GL_FALSE
){
542 Current
->dither_flag
= GL_FALSE
;
543 if(Current
->cColorBits
== 8)
544 Current
->pixelformat
= PF_INDEX8
;
547 if (Current
->rgb_flag
&& Current
->cColorBits
== 8){
548 Current
->pixelformat
= PF_DITHER8
;
549 Current
->dither_flag
= GL_TRUE
;
552 Current
->dither_flag
= GL_FALSE
;
558 static GLboolean
set_buffer( GLcontext
* ctx
, GLenum mode
)
561 /* TODO: this could be better */
562 if (mode
==GL_FRONT
|| mode
==GL_BACK
) {
568 ENDPROFILE(set_buffer
)
573 /* Return characteristics of the output buffer. */
574 static void buffer_size( GLcontext
* ctx
, GLuint
*width
, GLuint
*height
/*, GLuint *depth */)
581 GetClientRect(Current
->Window
,&CR
);
585 // *depth = Current->depth;
587 New_Size
=((*width
)!=Current
->width
) || ((*height
)!=Current
->height
);
590 Current
->width
=*width
;
591 Current
->height
=*height
;
592 Current
->ScanWidth
=Current
->width
;
593 if ((Current
->ScanWidth
%sizeof(long))!=0)
594 Current
->ScanWidth
+=(sizeof(long)-(Current
->ScanWidth
%sizeof(long)));
596 if (Current
->db_flag
){
598 DDDeleteOffScreen(Current
);
599 DDCreateOffScreen(Current
);
601 if (Current
->rgb_flag
==GL_TRUE
&& Current
->dither_flag
!=GL_TRUE
){
602 wmDeleteBackingStore(Current
);
603 wmCreateBackingStore(Current
, Current
->width
, Current
->height
);
608 // Resize OsmesaBuffer if in Parallel mode
609 #if !defined(NO_PARALLEL)
611 PRSizeRenderBuffer(Current
->width
, Current
->height
,Current
->ScanWidth
,
612 Current
->rgb_flag
== GL_TRUE
? Current
->pbPixels
: Current
->ScreenMem
);
615 ENDPROFILE(buffer_size
)
620 /**********************************************************************/
621 /***** Accelerated point, line, polygon rendering *****/
622 /**********************************************************************/
625 static void fast_rgb_points( GLcontext
* ctx
, GLuint first
, GLuint last
)
633 if (Current
->gl_ctx
->VB
->MonoColor
) {
634 /* all drawn with current color */
635 for (i
=first
;i
<=last
;i
++) {
636 if (!Current
->gl_ctx
->VB
->ClipMask
[i
]) {
638 x
= (GLint
) Current
->gl_ctx
->VB
->Win
[i
][0];
639 y
= FLIP( (GLint
) Current
->gl_ctx
->VB
->Win
[i
][1] );
640 wmSetPixel(pwc
, y
,x
,GetRValue(Current
->pixel
),
641 GetGValue(Current
->pixel
), GetBValue(Current
->pixel
));
646 /* draw points of different colors */
647 for (i
=first
;i
<=last
;i
++) {
648 if (!Current
->gl_ctx
->VB
->ClipMask
[i
]) {
650 unsigned long pixel
=RGB(Current
->gl_ctx
->VB
->Color
[i
][0]*255.0,
651 Current
->gl_ctx
->VB
->Color
[i
][1]*255.0,
652 Current
->gl_ctx
->VB
->Color
[i
][2]*255.0);
653 x
= (GLint
) Current
->gl_ctx
->VB
->Win
[i
][0];
654 y
= FLIP( (GLint
) Current
->gl_ctx
->VB
->Win
[i
][1] );
655 wmSetPixel(pwc
, y
,x
,Current
->gl_ctx
->VB
->Color
[i
][0]*255.0,
656 Current
->gl_ctx
->VB
->Color
[i
][1]*255.0,
657 Current
->gl_ctx
->VB
->Color
[i
][2]*255.0);
662 ENDPROFILE(fast_rgb_points
)
667 /* Return pointer to accerated points function */
668 extern points_func
choose_points_function( GLcontext
* ctx
)
671 if (ctx
->Point
.Size
==1.0 && !ctx
->Point
.SmoothFlag
&& ctx
->RasterMask
==0
672 && !ctx
->Texture
.Enabled
&& ctx
->Visual
->RGBAflag
) {
673 ENDPROFILE(choose_points_function
)
674 return fast_rgb_points
;
677 ENDPROFILE(choose_points_function
)
684 /* Draw a line using the color specified by Current->gl_ctx->VB->Color[pv] */
685 static void fast_flat_rgb_line( GLcontext
* ctx
, GLuint v0
, GLuint v1
, GLuint pv
)
694 if (Current
->gl_ctx
->VB
->MonoColor
) {
695 pixel
= Current
->pixel
; /* use current color */
698 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);
701 x0
= (int) Current
->gl_ctx
->VB
->Win
[v0
][0];
702 y0
= FLIP( (int) Current
->gl_ctx
->VB
->Win
[v0
][1] );
703 x1
= (int) Current
->gl_ctx
->VB
->Win
[v1
][0];
704 y1
= FLIP( (int) Current
->gl_ctx
->VB
->Win
[v1
][1] );
709 Pen
=CreatePen(PS_SOLID
,1,pixel
);
710 Old_Pen
=SelectObject(DC
,Pen
);
711 MoveToEx(DC
,x0
,y0
,NULL
);
713 SelectObject(DC
,Old_Pen
);
719 ENDPROFILE(fast_flat_rgb_line
)
724 /* Return pointer to accerated line function */
725 static line_func
choose_line_function( GLcontext
* ctx
)
728 if (ctx
->Line
.Width
==1.0 && !ctx
->Line
.SmoothFlag
&& !ctx
->Line
.StippleFlag
729 && ctx
->Light
.ShadeModel
==GL_FLAT
&& ctx
->RasterMask
==0
730 && !ctx
->Texture
.Enabled
&& Current
->rgb_flag
) {
731 ENDPROFILE(choose_line_function
)
732 return fast_flat_rgb_line
;
735 ENDPROFILE(choose_line_function
)
741 /**********************************************************************/
742 /***** Span-based pixel drawing *****/
743 /**********************************************************************/
746 /* Write a horizontal span of color-index pixels with a boolean mask. */
747 static void write_index_span( GLcontext
* ctx
,
748 GLuint n
, GLint x
, GLint y
,
749 const GLuint index
[],
750 const GLubyte mask
[] )
754 PBYTE Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
755 assert(Current
->rgb_flag
==GL_FALSE
);
759 ENDPROFILE(write_index_span
)
765 * Write a horizontal span of pixels with a boolean mask. The current
766 * color index is used for all pixels.
768 static void write_monoindex_span(GLcontext
* ctx
,
769 GLuint n
,GLint x
,GLint y
,
770 const GLubyte mask
[])
774 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
775 assert(Current
->rgb_flag
==GL_FALSE
);
778 Mem
[i
]=Current
->pixel
;
779 ENDPROFILE(write_monoindex_span
)
783 To improve the performance of this routine, frob the data into an actual scanline
784 and call bitblt on the complete scan line instead of SetPixel.
787 /* Write a horizontal span of color pixels with a boolean mask. */
788 static void write_color_span( GLcontext
* ctx
,
789 GLuint n
, GLint x
, GLint y
,
791 red
[], const GLubyte green
[],
792 const GLubyte blue
[], const GLubyte alpha
[],
793 const GLubyte mask
[] )
799 if (pwc
->rgb_flag
==GL_TRUE
)
808 wmSetPixel(pwc
, y
, x
+ i
,red
[i
], green
[i
], blue
[i
]);
813 wmSetPixel(pwc
, y
, x
+ i
, red
[i
], green
[i
], blue
[i
]);
823 BYTE
*Mem
=Current
->ScreenMem
+y
*Current
->ScanWidth
+x
;
828 Mem
[i
]=GetNearestPaletteIndex(Current
->hPal
,RGB(red
[i
],green
[i
],blue
[i
]));
832 Mem
[i
]=GetNearestPaletteIndex(Current
->hPal
,RGB(red
[i
],green
[i
],blue
[i
]));
835 ENDPROFILE(write_color_span
)
840 * Write a horizontal span of pixels with a boolean mask. The current color
841 * is used for all pixels.
843 static void write_monocolor_span( GLcontext
* ctx
,
844 GLuint n
, GLint x
, GLint y
,
845 const GLubyte mask
[])
852 assert(Current
->rgb_flag
==GL_TRUE
);
855 if(Current
->rgb_flag
==GL_TRUE
){
859 wmSetPixel(pwc
,y
,x
+i
,GetRValue(Current
->pixel
), GetGValue(Current
->pixel
), GetBValue(Current
->pixel
));
864 SetPixel(DC
, y
, x
+i
, Current
->pixel
);
869 ENDPROFILE(write_monocolor_span
)
874 /**********************************************************************/
875 /***** Array-based pixel drawing *****/
876 /**********************************************************************/
879 /* Write an array of pixels with a boolean mask. */
880 static void write_index_pixels( GLcontext
* ctx
,
881 GLuint n
, const GLint x
[], const GLint y
[],
882 const GLuint index
[], const GLubyte mask
[] )
886 assert(Current
->rgb_flag
==GL_FALSE
);
887 for (i
=0; i
<n
; i
++) {
889 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
];
893 ENDPROFILE(write_index_pixels
)
899 * Write an array of pixels with a boolean mask. The current color
900 * index is used for all pixels.
902 static void write_monoindex_pixels( GLcontext
* ctx
,
904 const GLint x
[], const GLint y
[],
905 const GLubyte mask
[] )
909 assert(Current
->rgb_flag
==GL_FALSE
);
910 for (i
=0; i
<n
; i
++) {
912 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
];
913 *Mem
= Current
->pixel
;
916 ENDPROFILE(write_monoindex_pixels
)
921 /* Write an array of pixels with a boolean mask. */
922 static void write_color_pixels( GLcontext
* ctx
,
923 GLuint n
, const GLint x
[], const GLint y
[],
924 const GLubyte r
[], const GLubyte g
[],
925 const GLubyte b
[], const GLubyte a
[],
926 const GLubyte mask
[] )
932 assert(Current
->rgb_flag
==GL_TRUE
);
935 wmSetPixel(pwc
, FLIP(y
[i
]),x
[i
],r
[i
],g
[i
],b
[i
]);
937 ENDPROFILE(write_color_pixels
)
943 * Write an array of pixels with a boolean mask. The current color
944 * is used for all pixels.
946 static void write_monocolor_pixels( GLcontext
* ctx
,
948 const GLint x
[], const GLint y
[],
949 const GLubyte mask
[] )
955 assert(Current
->rgb_flag
==GL_TRUE
);
958 wmSetPixel(pwc
, FLIP(y
[i
]),x
[i
],GetRValue(Current
->pixel
),
959 GetGValue(Current
->pixel
), GetBValue(Current
->pixel
));
961 ENDPROFILE(write_monocolor_pixels
)
966 /**********************************************************************/
967 /***** Read spans/arrays of pixels *****/
968 /**********************************************************************/
971 /* Read a horizontal span of color-index pixels. */
972 static void read_index_span( GLcontext
* ctx
, GLuint n
, GLint x
, GLint y
, GLuint index
[])
976 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
977 assert(Current
->rgb_flag
==GL_FALSE
);
980 ENDPROFILE(read_index_span
)
987 /* Read an array of color index pixels. */
988 static void read_index_pixels( GLcontext
* ctx
,
989 GLuint n
, const GLint x
[], const GLint y
[],
990 GLuint indx
[], const GLubyte mask
[] )
994 assert(Current
->rgb_flag
==GL_FALSE
);
995 for (i
=0; i
<n
; i
++) {
997 indx
[i
]=*(Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
]);
1000 ENDPROFILE(read_index_pixels
)
1005 /* Read a horizontal span of color pixels. */
1006 static void read_color_span( GLcontext
* ctx
,
1007 GLuint n
, GLint x
, GLint y
,
1008 GLubyte red
[], GLubyte green
[],
1009 GLubyte blue
[], GLubyte alpha
[] )
1015 assert(Current
->rgb_flag
==GL_TRUE
);
1019 Color
=GetPixel(DC
,x
+i
,y
);
1020 red
[i
]=GetRValue(Color
);
1021 green
[i
]=GetGValue(Color
);
1022 blue
[i
]=GetBValue(Color
);
1026 memset(alpha
,0,n
*sizeof(GLint
));
1027 ENDPROFILE(read_color_span
)
1031 /* Read an array of color pixels. */
1032 static void read_color_pixels( GLcontext
* ctx
,
1033 GLuint n
, const GLint x
[], const GLint y
[],
1034 GLubyte red
[], GLubyte green
[],
1035 GLubyte blue
[], GLubyte alpha
[],
1036 const GLubyte mask
[] )
1042 assert(Current
->rgb_flag
==GL_TRUE
);
1043 for (i
=0; i
<n
; i
++) {
1045 Color
=GetPixel(DC
,x
[i
],FLIP(y
[i
]));
1046 red
[i
]=GetRValue(Color
);
1047 green
[i
]=GetGValue(Color
);
1048 blue
[i
]=GetBValue(Color
);
1053 memset(alpha
,0,n
*sizeof(GLint
));
1054 ENDPROFILE(read_color_pixels
)
1059 /**********************************************************************/
1060 /**********************************************************************/
1064 void setup_DD_pointers( GLcontext
* ctx
)
1066 ctx
->Driver
.UpdateState
= setup_DD_pointers
;
1067 ctx
->Driver
.GetBufferSize
= buffer_size
;
1068 ctx
->Driver
.Finish
= finish
;
1069 ctx
->Driver
.Flush
= flush
;
1071 ctx
->Driver
.ClearIndex
= clear_index
;
1072 ctx
->Driver
.ClearColor
= clear_color
;
1073 ctx
->Driver
.Clear
= clear
;
1075 ctx
->Driver
.Index
= set_index
;
1076 ctx
->Driver
.Color
= set_color
;
1077 ctx
->Driver
.IndexMask
= index_mask
;
1078 ctx
->Driver
.ColorMask
= color_mask
;
1080 ctx
->Driver
.LogicOp
= logicop
;
1081 ctx
->Driver
.Dither
= dither
;
1083 ctx
->Driver
.SetBuffer
= set_buffer
;
1084 ctx
->Driver
.GetBufferSize
= buffer_size
;
1086 ctx
->Driver
.PointsFunc
= choose_points_function(ctx
);
1087 ctx
->Driver
.LineFunc
= choose_line_function(ctx
);
1088 ctx
->Driver
.TriangleFunc
= choose_triangle_function( ctx
);
1090 /* Pixel/span writing functions: */
1091 ctx
->Driver
.WriteColorSpan
= write_color_span
;
1092 ctx
->Driver
.WriteMonocolorSpan
= write_monocolor_span
;
1093 ctx
->Driver
.WriteColorPixels
= write_color_pixels
;
1094 ctx
->Driver
.WriteMonocolorPixels
= write_monocolor_pixels
;
1095 ctx
->Driver
.WriteIndexSpan
= write_index_span
;
1096 ctx
->Driver
.WriteMonoindexSpan
= write_monoindex_span
;
1097 ctx
->Driver
.WriteIndexPixels
= write_index_pixels
;
1098 ctx
->Driver
.WriteMonoindexPixels
= write_monoindex_pixels
;
1100 /* Pixel/span reading functions: */
1101 ctx
->Driver
.ReadIndexSpan
= read_index_span
;
1102 ctx
->Driver
.ReadColorSpan
= read_color_span
;
1103 ctx
->Driver
.ReadIndexPixels
= read_index_pixels
;
1104 ctx
->Driver
.ReadColorPixels
= read_color_pixels
;
1108 /**********************************************************************/
1109 /***** WMesa API Functions *****/
1110 /**********************************************************************/
1114 #define PAL_SIZE 256
1115 static void GetPalette(HPALETTE Pal
,RGBQUAD
*aRGB
)
1123 WORD NumberOfEntries
;
1124 PALETTEENTRY aEntries
[PAL_SIZE
];
1132 GetPaletteEntries(Pal
,0,PAL_SIZE
,Palette
.aEntries
);
1134 GetSystemPaletteEntries(hdc
,0,PAL_SIZE
,Palette
.aEntries
);
1135 if (GetSystemPaletteUse(hdc
) == SYSPAL_NOSTATIC
)
1137 for(i
= 0; i
<PAL_SIZE
; i
++)
1138 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1139 Palette
.aEntries
[255].peRed
= 255;
1140 Palette
.aEntries
[255].peGreen
= 255;
1141 Palette
.aEntries
[255].peBlue
= 255;
1142 Palette
.aEntries
[255].peFlags
= 0;
1143 Palette
.aEntries
[0].peRed
= 0;
1144 Palette
.aEntries
[0].peGreen
= 0;
1145 Palette
.aEntries
[0].peBlue
= 0;
1146 Palette
.aEntries
[0].peFlags
= 0;
1152 nStaticColors
= GetDeviceCaps(hdc
, NUMCOLORS
)/2;
1153 for (i
=0; i
<nStaticColors
; i
++)
1154 Palette
.aEntries
[i
].peFlags
= 0;
1155 nUsableColors
= PAL_SIZE
-nStaticColors
;
1156 for (; i
<nUsableColors
; i
++)
1157 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1158 for (; i
<PAL_SIZE
-nStaticColors
; i
++)
1159 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1160 for (i
=PAL_SIZE
-nStaticColors
; i
<PAL_SIZE
; i
++)
1161 Palette
.aEntries
[i
].peFlags
= 0;
1163 ReleaseDC(NULL
,hdc
);
1164 for (i
=0; i
<PAL_SIZE
; i
++)
1166 aRGB
[i
].rgbRed
=Palette
.aEntries
[i
].peRed
;
1167 aRGB
[i
].rgbGreen
=Palette
.aEntries
[i
].peGreen
;
1168 aRGB
[i
].rgbBlue
=Palette
.aEntries
[i
].peBlue
;
1169 aRGB
[i
].rgbReserved
=Palette
.aEntries
[i
].peFlags
;
1171 ENDPROFILE(GetPalette
)
1175 WMesaContext
WMesaCreateContext( HWND hWnd
, HPALETTE
* Pal
,
1181 GLboolean true_color_flag
;
1182 c
= (struct wmesa_context
* ) calloc(1,sizeof(struct wmesa_context
));
1187 c
->hDC
= GetDC(hWnd
);
1188 true_color_flag
= GetDeviceCaps(c
->hDC
, BITSPIXEL
) > 8;
1190 if(true_color_flag
) c
->rgb_flag
= rgb_flag
= GL_TRUE
;
1195 if ((true_color_flag
==GL_FALSE
) && (rgb_flag
== GL_TRUE
)){
1196 c
->dither_flag
= GL_TRUE
;
1197 c
->hPalHalfTone
= WinGCreateHalftonePalette();
1200 c
->dither_flag
= GL_FALSE
;
1202 c
->dither_flag
= GL_FALSE
;
1206 if (rgb_flag
==GL_FALSE
)
1208 c
->rgb_flag
= GL_FALSE
;
1210 c
->db_flag
= db_flag
=GL_TRUE
; // WinG requires double buffering
1211 printf("Single buffer is not supported in color index mode, setting to double buffer.\n");
1215 c
->rgb_flag
= GL_TRUE
;
1218 GetClientRect(c
->Window
,&CR
);
1220 c
->height
=CR
.bottom
;
1224 /* Double buffered */
1226 // if (c->rgb_flag==GL_TRUE && c->dither_flag != GL_TRUE )
1228 wmCreateBackingStore(c
, c
->width
, c
->height
);
1235 /* Single Buffered */
1240 if (DDInit(c
,hWnd
) == GL_FALSE
) {
1247 c
->gl_visual
= gl_create_visual(rgb_flag
,
1248 GL_FALSE
, /* software alpha */
1249 db_flag
, /* db_flag */
1250 16, /* depth_bits */
1251 8, /* stencil_bits */
1254 255.0, 255.0, 255.0, 255.0,
1257 if (!c
->gl_visual
) {
1261 /* allocate a new Mesa context */
1262 c
->gl_ctx
= gl_create_context( c
->gl_visual
, NULL
,c
);
1265 gl_destroy_visual( c
->gl_visual
);
1270 c
->gl_buffer
= gl_create_framebuffer( c
->gl_visual
);
1271 if (!c
->gl_buffer
) {
1272 gl_destroy_visual( c
->gl_visual
);
1273 gl_destroy_context( c
->gl_ctx
);
1277 // setup_DD_pointers(c->gl_ctx);
1282 void WMesaDestroyContext( void )
1284 WMesaContext c
= Current
;
1285 ReleaseDC(c
->Window
,c
->hDC
);
1287 if(c
->hPalHalfTone
!= NULL
)
1288 DeleteObject(c
->hPalHalfTone
);
1289 gl_destroy_visual( c
->gl_visual
);
1290 gl_destroy_framebuffer( c
->gl_buffer
);
1291 gl_destroy_context( c
->gl_ctx
);
1297 wmDeleteBackingStore(c
);
1300 //Following code is added to enable parallel render
1301 // Parallel render only work in double buffer mode
1302 #if !defined(NO_PARALLEL)
1304 PRDestroyRenderBuffer();
1311 void /*APIENTRY*/ WMesaMakeCurrent( WMesaContext c
)
1319 // A little optimization
1320 // If it already is current,
1321 // don't set it again
1326 //gl_set_context( c->gl_ctx );
1327 gl_make_current(c
->gl_ctx
, c
->gl_buffer
);
1329 setup_DD_pointers(c
->gl_ctx
);
1330 if (Current
->gl_ctx
->Viewport
.Width
==0) {
1331 /* initialize viewport to window size */
1332 gl_Viewport( Current
->gl_ctx
,
1333 0, 0, Current
->width
, Current
->height
);
1335 if ((c
->cColorBits
<= 8 ) && (c
->rgb_flag
== GL_TRUE
)){
1336 WMesaPaletteChange(c
->hPalHalfTone
);
1342 void /*APIENTRY*/ WMesaSwapBuffers( void )
1344 HDC DC
= Current
->hDC
;
1345 if (Current
->db_flag
)
1351 void /*APIENTRY*/ WMesaPaletteChange(HPALETTE Pal
)
1354 LPPALETTEENTRY pPal
;
1355 if (Current
&& (Current
->rgb_flag
==GL_FALSE
|| Current
->dither_flag
== GL_TRUE
))
1357 pPal
= (PALETTEENTRY
*)malloc( 256 * sizeof(PALETTEENTRY
));
1359 // GetPaletteEntries( Pal, 0, 256, pPal );
1360 GetPalette( Pal
, pPal
);
1362 Current
->lpDD
->lpVtbl
->CreatePalette(Current
->lpDD
,DDPCAPS_8BIT
,
1363 pPal
, &(Current
->lpDDPal
), NULL
);
1364 if (Current
->lpDDPal
)
1365 Current
->lpDDSPrimary
->lpVtbl
->SetPalette(Current
->lpDDSPrimary
,Current
->lpDDPal
);
1367 vRet
= SetDIBColorTable(Current
->dib
.hDC
,0,256,pPal
);
1377 static unsigned char threeto8
[8] = {
1378 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
1381 static unsigned char twoto8
[4] = {
1385 static unsigned char oneto8
[2] = {
1389 static unsigned char componentFromIndex(UCHAR i
, UINT nbits
, UINT shift
)
1406 return threeto8
[val
];
1413 void /*WINAPI*/ wmCreatePalette( PWMC pwdc
)
1415 /* Create a compressed and re-expanded 3:3:2 palette */
1418 BYTE rb
, rs
, gb
, gs
, bb
, bs
;
1420 pwdc
->nColors
= 0x100;
1422 pPal
= (PLOGPALETTE
)malloc(sizeof(LOGPALETTE
) + pwdc
->nColors
* sizeof(PALETTEENTRY
));
1423 memset( pPal
, 0, sizeof(LOGPALETTE
) + pwdc
->nColors
* sizeof(PALETTEENTRY
) );
1425 pPal
->palVersion
= 0x300;
1434 if (pwdc
->db_flag
) {
1436 /* Need to make two palettes: one for the screen DC and one for the DIB. */
1437 pPal
->palNumEntries
= pwdc
->nColors
;
1438 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1439 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1440 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1441 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1442 pPal
->palPalEntry
[i
].peFlags
= 0;
1444 pwdc
->hGLPalette
= CreatePalette( pPal
);
1445 pwdc
->hPalette
= CreatePalette( pPal
);
1449 pPal
->palNumEntries
= pwdc
->nColors
;
1450 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1451 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1452 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1453 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1454 pPal
->palPalEntry
[i
].peFlags
= 0;
1456 pwdc
->hGLPalette
= CreatePalette( pPal
);
1463 void /*WINAPI*/ wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1465 if(Current
->db_flag
){
1466 LPBYTE lpb
= pwc
->pbPixels
;
1469 UINT nBypp
= pwc
->cColorBits
/ 8;
1470 UINT nOffset
= iPixel
% nBypp
;
1472 // Move the pixel buffer pointer to the scanline that we
1475 // pwc->dib.fFlushed = FALSE;
1477 lpb
+= pwc
->ScanWidth
* iScanLine
;
1478 // Now move to the desired pixel
1479 lpb
+= iPixel
* nBypp
;
1480 lpb
= PIXELADDR(iPixel
, iScanLine
);
1481 lpdw
= (LPDWORD
)lpb
;
1485 if(pwc
->dither_flag
)
1486 *lpb
= DITHER_RGB_2_8BIT(r
,g
,b
,iScanLine
,iPixel
);
1491 *lpw
= BGR16(r
,g
,b
);
1492 else if (nBypp
== 3){
1493 *lpdw
= BGR24(r
,g
,b
);
1495 else if (nBypp
== 4)
1496 *lpdw
= BGR32(r
,g
,b
);
1500 SetPixel(DC
, iPixel
, iScanLine
, RGB(r
,g
,b
));
1505 void /*WINAPI*/ wmCreateDIBSection(
1507 PWMC pwc
, // handle of device context
1508 CONST BITMAPINFO
*pbmi
, // address of structure containing bitmap size, format, and color data
1509 UINT iUsage
// color data type indicator: RGB values or palette indices
1514 UINT nBypp
= pwc
->cColorBits
/ 8;
1517 dwScanWidth
= (((pwc
->ScanWidth
* nBypp
)+ 3) & ~3);
1519 pwc
->ScanWidth
=pwc
->pitch
= dwScanWidth
;
1522 pwc
->ScanWidth
= 2* pwc
->pitch
;
1524 dwSize
= sizeof(BITMAPINFO
) + (dwScanWidth
* pwc
->height
);
1526 pwc
->dib
.hFileMap
= CreateFileMapping((HANDLE
)PAGE_FILE
,
1528 PAGE_READWRITE
| SEC_COMMIT
,
1533 if (!pwc
->dib
.hFileMap
)
1536 pwc
->dib
.base
= MapViewOfFile(pwc
->dib
.hFileMap
,
1537 FILE_MAP_ALL_ACCESS
,
1543 CloseHandle(pwc
->dib
.hFileMap
);
1547 // pwc->pbPixels = pwc->addrOffScreen = ((LPBYTE)pwc->dib.base) + sizeof(BITMAPINFO);
1549 // pwc->dib.hDC = CreateCompatibleDC(hDC);
1551 CopyMemory(pwc
->dib
.base
, pbmi
, sizeof(BITMAPINFO
));
1553 hic
= CreateIC("display", NULL
, NULL
, NULL
);
1554 pwc
->dib
.hDC
= CreateCompatibleDC(hic
);
1557 /* pwc->hbmDIB = CreateDIBitmap(hic,
1558 &(pwc->bmi.bmiHeader),
1564 pwc
->hbmDIB
= CreateDIBSection(hic
,
1566 (iUsage
? DIB_PAL_COLORS
: DIB_RGB_COLORS
),
1571 pwc->hbmDIB = CreateDIBSection(hic,
1578 pwc
->ScreenMem
= pwc
->addrOffScreen
= pwc
->pbPixels
;
1579 pwc
->hOldBitmap
= SelectObject(pwc
->dib
.hDC
, pwc
->hbmDIB
);
1588 // Blit memory DC to screen DC
1590 BOOL
/*WINAPI*/ wmFlush(PWMC pwc
)
1596 // Now search through the torus frames and mark used colors
1599 if (pwc
->lpDDSOffScreen
== NULL
)
1600 if(DDCreateOffScreen(pwc
) == GL_FALSE
)
1603 pwc
->lpDDSOffScreen
->lpVtbl
->Unlock(pwc
->lpDDSOffScreen
, NULL
);
1607 ddrval
= pwc
->lpDDSPrimary
->lpVtbl
->Blt( pwc
->lpDDSPrimary
,
1608 &(pwc
->rectSurface
), pwc
->lpDDSOffScreen
, &(pwc
->rectOffScreen
), 0, NULL
);
1610 if( ddrval
== DD_OK
)
1614 if( ddrval
== DDERR_SURFACELOST
)
1616 if(!DDRestoreAll(pwc
))
1621 if( ddrval
!= DDERR_WASSTILLDRAWING
)
1627 while (pwc
->lpDDSOffScreen
->lpVtbl
->Lock(pwc
->lpDDSOffScreen
,
1628 NULL
, &(pwc
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
)
1632 dwErr
= GetLastError();
1634 bRet
= BitBlt(pwc
->hDC
, 0, 0, pwc
->width
, pwc
->height
,
1635 pwc
->dib
.hDC
, 0, 0, SRCCOPY
);
1644 // The following code is added by Li Wei to enable stereo display
1646 #if !defined(NO_STEREO)
1648 void WMesaShowStereo(GLuint list
)
1651 GLbitfield mask
= GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
;
1654 // Must use double Buffer
1655 if( ! Current
-> db_flag
)
1659 glGetIntegerv(GL_MATRIX_MODE
,&matrix_mode
);
1661 // glPushMatrix(); //****
1662 WMesaViewport(Current
->gl_ctx
,0,Current
->height
/2,Current
->width
,Current
->height
/2);
1663 // Current->gl_ctx->NewState = 0;
1665 // glViewport(0,0,Current->width,Current->height/2);
1666 if(matrix_mode
!=GL_MODELVIEW
)
1667 glMatrixMode(GL_MODELVIEW
);
1669 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1671 gluLookAt(viewDistance
/2,0.0,0.0 ,
1672 viewDistance
/2,0.0,-1.0,
1674 // glTranslatef(viewDistance/2.0,0.,0.);
1675 glMultMatrixf( cm
);
1677 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
;
1682 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1684 gluLookAt(-viewDistance
/2,0.0,0.0 ,
1685 -viewDistance
/2,0.0,-1.0,
1687 // glTranslatef(-viewDistance/2.0,0.,0.);
1690 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
+ Current
->pitch
;
1692 if(matrix_mode
!=GL_MODELVIEW
)
1693 glMatrixMode(matrix_mode
);
1698 WMesaViewport(Current
->gl_ctx
,0,0,Current
->width
,Current
->height
);
1699 // Current->gl_ctx->NewState = 0;
1704 void toggleStereoMode()
1706 if(!Current
->db_flag
)
1710 if(stereoBuffer
==GL_FALSE
)
1711 #if !defined(NO_PARALLEL)
1715 Current
->ScanWidth
= Current
->pitch
*2;
1720 #if !defined(NO_PARALLEL)
1723 Current
->ScanWidth
= Current
->pitch
;
1724 Current
->pbPixels
= Current
->addrOffScreen
;
1728 /* if in stereo mode, the following function is called */
1729 void glShowStereo(GLuint list
)
1731 WMesaShowStereo(list
);
1734 #endif // End if NO_STEREO not defined
1736 #if !defined(NO_PARALLEL)
1738 void toggleParallelMode(void)
1741 parallelFlag
= GL_TRUE
;
1742 if(parallelMachine
==GL_FALSE
){
1743 PRCreateRenderBuffer( Current
->rgb_flag
? GL_RGBA
:GL_COLOR_INDEX
,
1744 Current
->cColorBits
/8,
1745 Current
->width
,Current
->height
,
1747 Current
->rgb_flag
? Current
->pbPixels
: Current
->ScreenMem
);
1748 parallelMachine
= GL_TRUE
;
1752 parallelFlag
= GL_FALSE
;
1753 if(parallelMachine
==GL_TRUE
){
1754 PRDestroyRenderBuffer();
1755 parallelMachine
=GL_FALSE
;
1756 ReadyForNextFrame
= GL_TRUE
;
1759 /***********************************************
1760 // Seems something wrong!!!!
1761 ************************************************/
1763 WMesaMakeCurrent(Current
);
1764 #if !defined(NO_STEREO)
1765 stereo_flag
= GL_FALSE
;
1770 void PRShowRenderResult(void)
1773 if(!glImageRendered())
1782 #endif //End if NO_PARALLEL not defined
1786 BYTE
DITHER_RGB_2_8BIT( int red
, int green
, int blue
, int pixel
, int scanline
)
1788 char unsigned redtemp
, greentemp
, bluetemp
, paletteindex
;
1790 //*** now, look up each value in the halftone matrix
1791 //*** using an 8x8 ordered dither.
1792 redtemp
= aDividedBy51
[red
]
1793 + (aModulo51
[red
] > aHalftone8x8
[(pixel
%8)*8
1795 greentemp
= aDividedBy51
[(char unsigned)green
]
1796 + (aModulo51
[green
] > aHalftone8x8
[
1797 (pixel
%8)*8 + scanline
%8]);
1798 bluetemp
= aDividedBy51
[(char unsigned)blue
]
1799 + (aModulo51
[blue
] > aHalftone8x8
[
1800 (pixel
%8)*8 +scanline
%8]);
1802 //*** recombine the halftoned rgb values into a palette index
1804 redtemp
+ aTimes6
[greentemp
] + aTimes36
[bluetemp
];
1806 //*** and translate through the wing halftone palette
1807 //*** translation vector to give the correct value.
1808 return aWinGHalftoneTranslation
[paletteindex
];
1815 * restore all lost objects
1817 HRESULT
DDRestoreAll( WMesaContext wc
)
1821 ddrval
= wc
->lpDDSPrimary
->lpVtbl
->Restore(wc
->lpDDSPrimary
);
1822 if( ddrval
== DD_OK
)
1824 ddrval
= wc
->lpDDSOffScreen
->lpVtbl
->Restore(wc
->lpDDSOffScreen
);
1832 * This function is called if the initialization function fails
1834 BOOL
initFail( HWND hwnd
, WMesaContext wc
)
1837 MessageBox( hwnd
, "DirectDraw Init FAILED", "", MB_OK
);
1843 static void DDDeleteOffScreen(WMesaContext wc
)
1845 if( wc
->lpDDSOffScreen
!= NULL
)
1847 wc
->lpDDSOffScreen
->lpVtbl
->Unlock(wc
->lpDDSOffScreen
,NULL
);
1848 wc
->lpDDSOffScreen
->lpVtbl
->Release(wc
->lpDDSOffScreen
);
1849 wc
->lpDDSOffScreen
= NULL
;
1854 static void DDFreePrimarySurface(WMesaContext wc
)
1856 if( wc
->lpDDSPrimary
!= NULL
)
1858 if(wc
->db_flag
== GL_FALSE
)
1859 wc
->lpDDSPrimary
->lpVtbl
->ReleaseDC(wc
->lpDDSPrimary
, wc
->hDC
);
1860 wc
->lpDDSPrimary
->lpVtbl
->Release(wc
->lpDDSPrimary
);
1861 wc
->lpDDSPrimary
= NULL
;
1865 static BOOL
DDCreatePrimarySurface(WMesaContext wc
)
1869 wc
->ddsd
.dwSize
= sizeof( wc
->ddsd
);
1870 wc
->ddsd
.dwFlags
= DDSD_CAPS
;
1871 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
1873 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
,&(wc
->ddsd
), &(wc
->lpDDSPrimary
), NULL
);
1874 if( ddrval
!= DD_OK
)
1876 return initFail(wc
->hwnd
, wc
);
1878 if(wc
->db_flag
== GL_FALSE
)
1879 wc
->lpDDSPrimary
->lpVtbl
->GetDC(wc
->lpDDSPrimary
, wc
->hDC
);
1883 static BOOL
DDCreateOffScreen(WMesaContext wc
)
1887 if(wc
->lpDD
== NULL
)
1889 GetClientRect( wc
->hwnd
, &(wc
->rectOffScreen
) );
1890 wc
->ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1891 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
1892 wc
->ddsd
.dwHeight
= wc
->rectOffScreen
.bottom
- wc
->rectOffScreen
.top
;
1893 wc
->ddsd
.dwWidth
= wc
->rectOffScreen
.right
- wc
->rectOffScreen
.left
;
1895 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
, &(wc
->ddsd
), &(wc
->lpDDSOffScreen
), NULL
);
1896 if( ddrval
!= DD_OK
)
1901 while (wc
->lpDDSOffScreen
->lpVtbl
->Lock(wc
->lpDDSOffScreen
,NULL
, &(wc
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
)
1903 // while ((ddrval = wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, &(wc->ddsd), DDLOCK_SURFACEMEMORYPTR , NULL)) != DD_OK)
1905 if(wc
->ddsd
.lpSurface
==NULL
)
1906 return initFail(wc
->hwnd
, wc
);
1908 wc
->ScreenMem
= wc
->pbPixels
= wc
->addrOffScreen
= (PBYTE
)(wc
->ddsd
.lpSurface
);
1909 wc
->ScanWidth
= wc
->pitch
= wc
->ddsd
.lPitch
;
1911 wc
->ScanWidth
= wc
->ddsd
.lPitch
*2;
1913 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
1915 ClientToScreen( wc
->hwnd
, &pt
);
1916 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
1917 wmSetPixelFormat(wc
, wc
->hDC
);
1922 * doInit - do work required for every instance of the application:
1923 * create the window, initialize data
1925 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
)
1930 LPDIRECTDRAW lpDD
; // DirectDraw object
1931 LPDIRECTDRAW2 lpDD2
;
1934 wc
->fullScreen
= displayOptions
.fullScreen
;
1935 wc
->gMode
= displayOptions
.mode
;
1937 stereo_flag
= displayOptions
.stereo
;
1938 if(wc
->db_flag
!= GL_TRUE
)
1939 stereo_flag
= GL_FALSE
;
1941 * create the main DirectDraw object
1943 ddrval
= DirectDrawCreate( NULL
, &(wc
->lpDD
), NULL
);
1944 if( ddrval
!= DD_OK
)
1946 return initFail(hwnd
,wc
);
1949 // Get exclusive mode if requested
1952 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1956 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
, DDSCL_NORMAL
);
1958 if( ddrval
!= DD_OK
)
1960 return initFail(hwnd
, wc
);
1964 /* ddrval = wc->lpDD->lpVtbl->QueryInterface(wc->lpDD, IID_IDirectDraw2,
1965 (LPVOID *)((wc->lpDD2)));
1969 return initFail(hwnd
, wc
);
1972 //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
1973 // wc->lpDD2->lpVtbl->GetMonitorFrequency(wc->lpDD, &dwFrequency);
1976 case 1: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 640, 480, displayOptions
.bpp
); break;
1977 case 2: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 800, 600, displayOptions
.bpp
); break;
1978 case 3: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1024, 768, displayOptions
.bpp
); break;
1979 case 4: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1152, 864, displayOptions
.bpp
); break;
1980 case 5: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1280, 1024, displayOptions
.bpp
); break;
1983 if( ddrval
!= DD_OK
)
1985 printf("Can't modify display mode, current mode used\n");
1986 // return initFail(hwnd , wc);
1988 //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
1990 case DDERR_INVALIDOBJECT
:
1992 case DDERR_INVALIDPARAMS
:
1994 case DDERR_UNSUPPORTEDMODE
:
1998 if(DDCreatePrimarySurface(wc
) == GL_FALSE
)
1999 return initFail(hwnd
, wc
);
2002 return DDCreateOffScreen(wc
);
2005 static void DDFree( WMesaContext wc
)
2007 if( wc
->lpDD
!= NULL
)
2009 DDFreePrimarySurface(wc
);
2010 DDDeleteOffScreen(wc
);
2011 wc
->lpDD
->lpVtbl
->Release(wc
->lpDD
);
2014 // Clean up the screen on exit
2015 RedrawWindow( NULL
, NULL
, NULL
, RDW_INVALIDATE
| RDW_ERASE
|
2021 void WMesaMove(void)
2023 WMesaContext wc
= Current
;
2025 if (Current
!= NULL
){
2026 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2028 ClientToScreen( wc
->hwnd
, &pt
);
2029 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2034 * Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable
2037 #define PACK_8B8G8R( R, G, B ) ( ((B) << 16) | ((G) << 8) | (R) )
2040 /**********************************************************************/
2041 /*** Triangle rendering ***/
2042 /**********************************************************************/
2047 * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
2049 static void smooth_8A8B8G8R_z_triangle( GLcontext
*ctx
,
2050 GLuint v0
, GLuint v1
, GLuint v2
,
2053 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2055 #define INTERP_RGB 1
2056 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2057 #define PIXEL_TYPE GLuint
2058 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2059 #define BYTES_PER_ROW (wmesa->ScanWidth)
2060 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2062 GLint i, len = RIGHT-LEFT; \
2063 for (i=0;i<len;i++) { \
2064 GLdepth z = FixedToDepth(ffz); \
2065 if (z < zRow[i]) { \
2066 pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2067 FixedToInt(ffb) ); \
2070 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2074 #include "tritemp.h"
2079 * XImage, smooth, depth-buffered, PF_8R8G8B triangle.
2081 static void smooth_8R8G8B_z_triangle( GLcontext
*ctx
,
2082 GLuint v0
, GLuint v1
, GLuint v2
,
2085 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2087 #define INTERP_RGB 1
2088 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2089 #define PIXEL_TYPE GLuint
2090 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2091 #define BYTES_PER_ROW (wmesa->ScanWidth)
2092 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2094 GLint i, len = RIGHT-LEFT; \
2095 for (i=0;i<len;i++) { \
2096 GLdepth z = FixedToDepth(ffz); \
2097 if (z < zRow[i]) { \
2098 pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2099 FixedToInt(ffb) ); \
2102 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2106 #include "tritemp.h"
2112 * XImage, smooth, depth-buffered, PF_5R6G5B triangle.
2114 static void smooth_5R6G5B_z_triangle( GLcontext
*ctx
,
2115 GLuint v0
, GLuint v1
, GLuint v2
,
2118 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2120 #define INTERP_RGB 1
2121 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2122 #define PIXEL_TYPE GLushort
2123 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2124 #define BYTES_PER_ROW (wmesa->ScanWidth)
2125 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2127 GLint i, len = RIGHT-LEFT; \
2128 for (i=0;i<len;i++) { \
2129 GLdepth z = FixedToDepth(ffz); \
2130 if (z < zRow[i]) { \
2131 pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2132 FixedToInt(ffb) ); \
2135 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2139 #include "tritemp.h"
2143 * XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
2145 static void flat_8A8B8G8R_z_triangle( GLcontext
*ctx
, GLuint v0
,
2146 GLuint v1
, GLuint v2
, GLuint pv
)
2148 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2150 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2151 #define PIXEL_TYPE GLuint
2152 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2153 #define BYTES_PER_ROW (wmesa->ScanWidth)
2154 #define SETUP_CODE \
2155 unsigned long p = PACK_8B8G8R( VB->Color[pv][0], \
2156 VB->Color[pv][1], VB->Color[pv][2] );
2157 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2159 GLint i, len = RIGHT-LEFT; \
2160 for (i=0;i<len;i++) { \
2161 GLdepth z = FixedToDepth(ffz); \
2162 if (z < zRow[i]) { \
2169 #include "tritemp.h"
2174 * XImage, flat, depth-buffered, PF_8R8G8B triangle.
2176 static void flat_8R8G8B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2177 GLuint v2
, GLuint pv
)
2179 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2181 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2182 #define PIXEL_TYPE GLuint
2183 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2184 #define BYTES_PER_ROW (wmesa->ScanWidth)
2185 #define SETUP_CODE \
2186 unsigned long p = PACK_8R8G8B( VB->Color[pv][0], \
2187 VB->Color[pv][1], VB->Color[pv][2] );
2188 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2190 GLint i, len = RIGHT-LEFT; \
2191 for (i=0;i<len;i++) { \
2192 GLdepth z = FixedToDepth(ffz); \
2193 if (z < zRow[i]) { \
2200 #include "tritemp.h"
2205 * XImage, flat, depth-buffered, PF_5R6G5B triangle.
2207 static void flat_5R6G5B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2208 GLuint v2
, GLuint pv
)
2210 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2212 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2213 #define PIXEL_TYPE GLushort
2214 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2215 #define BYTES_PER_ROW (wmesa->ScanWidth)
2216 #define SETUP_CODE \
2217 unsigned long p = PACK_5R6G5B( VB->Color[pv][0], \
2218 VB->Color[pv][1], VB->Color[pv][2] );
2219 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2221 GLint i, len = RIGHT-LEFT; \
2222 for (i=0;i<len;i++) { \
2223 GLdepth z = FixedToDepth(ffz); \
2224 if (z < zRow[i]) { \
2231 #include "tritemp.h"
2236 * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
2238 static void smooth_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2239 GLuint v2
, GLuint pv
)
2241 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2242 #define INTERP_RGB 1
2243 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2244 #define PIXEL_TYPE GLuint
2245 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2246 #define BYTES_PER_ROW (wmesa->ScanWidth)
2247 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2250 PIXEL_TYPE *pixel = pRow; \
2251 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2252 *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2253 FixedToInt(ffb) ); \
2254 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2257 #include "tritemp.h"
2262 * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
2264 static void smooth_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2265 GLuint v2
, GLuint pv
)
2267 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2268 #define INTERP_RGB 1
2269 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2270 #define PIXEL_TYPE GLuint
2271 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2272 #define BYTES_PER_ROW (wmesa->ScanWidth)
2273 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2276 PIXEL_TYPE *pixel = pRow; \
2277 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2278 *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2279 FixedToInt(ffb) ); \
2280 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2283 #include "tritemp.h"
2288 * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
2290 static void smooth_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2291 GLuint v2
, GLuint pv
)
2293 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2294 #define INTERP_RGB 1
2295 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2296 #define PIXEL_TYPE GLushort
2297 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2298 #define BYTES_PER_ROW (wmesa->ScanWidth)
2299 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2302 PIXEL_TYPE *pixel = pRow; \
2303 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2304 *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2305 FixedToInt(ffb) ); \
2306 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2309 #include "tritemp.h"
2315 * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
2317 static void flat_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
,
2318 GLuint v1
, GLuint v2
, GLuint pv
)
2320 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2321 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2322 #define PIXEL_TYPE GLuint
2323 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2324 #define BYTES_PER_ROW (wmesa->ScanWidth)
2325 #define SETUP_CODE \
2326 unsigned long p = PACK_8B8G8R( VB->Color[pv][0], \
2327 VB->Color[pv][1], VB->Color[pv][2] );
2328 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2331 PIXEL_TYPE *pixel = pRow; \
2332 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2336 #include "tritemp.h"
2341 * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
2343 static void flat_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2344 GLuint v2
, GLuint pv
)
2346 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2347 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2348 #define PIXEL_TYPE GLuint
2349 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2350 #define BYTES_PER_ROW (wmesa->ScanWidth)
2351 #define SETUP_CODE \
2352 unsigned long p = PACK_8R8G8B( VB->Color[pv][0], \
2353 VB->Color[pv][1], VB->Color[pv][2] );
2354 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2357 PIXEL_TYPE *pixel = pRow; \
2358 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2362 #include "tritemp.h"
2367 * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
2369 static void flat_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2370 GLuint v2
, GLuint pv
)
2372 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2373 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2374 #define PIXEL_TYPE GLushort
2375 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2376 #define BYTES_PER_ROW (wmesa->ScanWidth)
2377 #define SETUP_CODE \
2378 unsigned long p = PACK_5R6G5B( VB->Color[pv][0], \
2379 VB->Color[pv][1], VB->Color[pv][2] );
2380 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2383 PIXEL_TYPE *pixel = pRow; \
2384 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2388 #include "tritemp.h"
2393 * XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
2396 static void smooth_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2397 GLuint v2
, GLuint pv
)
2399 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2401 #define INTERP_INDEX 1
2402 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2403 #define PIXEL_TYPE GLubyte
2404 #define BYTES_PER_ROW (wmesa->ScanWidth)
2405 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2407 GLint i, len = RIGHT-LEFT; \
2408 for (i=0;i<len;i++) { \
2409 GLdepth z = FixedToDepth(ffz); \
2410 if (z < zRow[i]) { \
2411 pRow[i] = FixedToInt(ffi); \
2419 #include "tritemp.h"
2424 * XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
2427 static void flat_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2428 GLuint v2
, GLuint pv
)
2430 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2432 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2433 #define PIXEL_TYPE GLubyte
2434 #define BYTES_PER_ROW (wmesa->ScanWidth)
2435 #define SETUP_CODE \
2436 GLuint index = VB->Index[pv]; \
2437 if (!VB->MonoColor) { \
2438 /* set the color index */ \
2439 (*ctx->Driver.Index)( ctx, index ); \
2441 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2443 GLint i, len = RIGHT-LEFT; \
2444 for (i=0;i<len;i++) { \
2445 GLdepth z = FixedToDepth(ffz); \
2446 if (z < zRow[i]) { \
2453 #include "tritemp.h"
2459 * XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2462 static void smooth_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2463 GLuint v2
, GLuint pv
)
2465 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2467 #define INTERP_INDEX 1
2468 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2469 #define PIXEL_TYPE GLubyte
2470 #define BYTES_PER_ROW (wmesa->ScanWidth)
2471 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2474 PIXEL_TYPE *pixel = pRow; \
2475 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2476 *pixel = FixedToInt(ffi); \
2480 #include "tritemp.h"
2485 * XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2487 static void flat_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2488 GLuint v2
, GLuint pv
)
2490 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2492 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2493 #define PIXEL_TYPE GLubyte
2494 #define BYTES_PER_ROW (wmesa->ScanWidth)
2495 #define SETUP_CODE \
2496 GLuint index = VB->Index[pv]; \
2497 if (!VB->MonoColor) { \
2498 /* set the color index */ \
2499 (*ctx->Driver.Index)( ctx, index ); \
2501 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2504 PIXEL_TYPE *pixel = pRow; \
2505 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2509 #include "tritemp.h"
2513 * XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
2515 static void smooth_DITHER8_z_triangle( GLcontext
*ctx
,
2516 GLuint v0
, GLuint v1
, GLuint v2
,
2519 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2520 DITHER_RGB_TO_8BIT_SETUP
2522 #define INTERP_RGB 1
2523 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2524 #define PIXEL_TYPE GLubyte
2525 #define BYTES_PER_ROW (wmesa->ScanWidth)
2526 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2528 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
2529 for (i=0;i<len;i++,xx++) { \
2530 GLdepth z = FixedToDepth(ffz); \
2531 if (z < zRow[i]) { \
2532 DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg), \
2533 FixedToInt(ffb), xx, yy); \
2534 pRow[i] = pixelDithered; \
2537 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2541 #include "tritemp.h"
2545 * XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
2547 static void flat_DITHER8_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2548 GLuint v2
, GLuint pv
)
2550 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2551 DITHER_RGB_TO_8BIT_SETUP
2553 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2554 #define PIXEL_TYPE GLubyte
2555 #define BYTES_PER_ROW (wmesa->ScanWidth)
2557 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2559 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
2560 for (i=0;i<len;i++,xx++) { \
2561 GLdepth z = FixedToDepth(ffz); \
2562 if (z < zRow[i]) { \
2563 DITHER_RGB_TO_8BIT( VB->Color[pv][0], \
2564 VB->Color[pv][1], VB->Color[pv][2], xx, yy); \
2565 pRow[i] = pixelDithered; \
2571 #include "tritemp.h"
2575 * XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
2577 static void smooth_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2578 GLuint v2
, GLuint pv
)
2580 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2581 DITHER_RGB_TO_8BIT_SETUP
2582 #define INTERP_RGB 1
2583 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2584 #define PIXEL_TYPE GLubyte
2585 #define BYTES_PER_ROW (wmesa->ScanWidth)
2586 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2588 GLint xx, yy = FLIP(Y); \
2589 PIXEL_TYPE *pixel = pRow; \
2590 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2591 DITHER_RGB_TO_8BIT( VB->Color[pv][0], VB->Color[pv][1], VB->Color[pv][2], xx, yy);\
2592 *pixel = pixelDithered; \
2593 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2596 #include "tritemp.h"
2600 * XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
2603 static void flat_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2604 GLuint v2
, GLuint pv
)
2606 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2607 DITHER_RGB_TO_8BIT_SETUP
2608 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2609 #define PIXEL_TYPE GLubyte
2610 #define BYTES_PER_ROW (wmesa->ScanWidth)
2612 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2614 GLint xx, yy = FLIP(Y); \
2615 PIXEL_TYPE *pixel = pRow; \
2616 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2617 DITHER_RGB_TO_8BIT( VB->Color[pv][0], \
2618 VB->Color[pv][1], VB->Color[pv][2], xx, yy); \
2619 *pixel = pixelDithered; \
2622 #include "tritemp.h"
2628 static triangle_func
choose_triangle_function( GLcontext
*ctx
)
2630 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2631 int depth
= wmesa
->cColorBits
;
2633 if (ctx
->Polygon
.SmoothFlag
) return NULL
;
2634 if (ctx
->Texture
.Enabled
) return NULL
;
2635 if (!wmesa
->db_flag
) return NULL
;
2636 /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {
2637 if ( ctx
->Light
.ShadeModel
==GL_SMOOTH
2638 && ctx
->RasterMask
==DEPTH_BIT
2639 && ctx
->Depth
.Func
==GL_LESS
2640 && ctx
->Depth
.Mask
==GL_TRUE
2641 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2642 switch (wmesa
->pixelformat
) {
2644 return smooth_8A8B8G8R_z_triangle
;
2646 return smooth_8R8G8B_z_triangle
;
2648 return smooth_5R6G5B_z_triangle
;
2650 return smooth_DITHER8_z_triangle
;
2652 return smooth_ci_z_triangle
;
2657 if ( ctx
->Light
.ShadeModel
==GL_FLAT
2658 && ctx
->RasterMask
==DEPTH_BIT
2659 && ctx
->Depth
.Func
==GL_LESS
2660 && ctx
->Depth
.Mask
==GL_TRUE
2661 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2662 switch (wmesa
->pixelformat
) {
2664 return flat_8A8B8G8R_z_triangle
;
2666 return flat_8R8G8B_z_triangle
;
2668 return flat_5R6G5B_z_triangle
;
2670 return flat_DITHER8_z_triangle
;
2672 return flat_ci_z_triangle
;
2677 if ( ctx
->RasterMask
==0 /* no depth test */
2678 && ctx
->Light
.ShadeModel
==GL_SMOOTH
2679 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2680 switch (wmesa
->pixelformat
) {
2682 return smooth_8A8B8G8R_triangle
;
2684 return smooth_8R8G8B_triangle
;
2686 return smooth_5R6G5B_triangle
;
2688 return smooth_DITHER8_triangle
;
2690 return smooth_ci_triangle
;
2696 if ( ctx
->RasterMask
==0 /* no depth test */
2697 && ctx
->Light
.ShadeModel
==GL_FLAT
2698 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2699 switch (wmesa
->pixelformat
) {
2701 return flat_8A8B8G8R_triangle
;
2703 return flat_8R8G8B_triangle
;
2705 return flat_5R6G5B_triangle
;
2707 return flat_DITHER8_triangle
;
2709 return flat_ci_triangle
;
2720 * Define a new viewport and reallocate auxillary buffers if the size of
2721 * the window (color buffer) has changed.
2723 void WMesaViewport( GLcontext
*ctx
,
2724 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2727 ctx
->Viewport
.X
= x
;
2728 ctx
->Viewport
.Width
= width
;
2729 ctx
->Viewport
.Y
= y
;
2730 ctx
->Viewport
.Height
= height
;
2732 /* compute scale and bias values */
2733 ctx
->Viewport
.Sx
= (GLfloat
) width
/ 2.0F
;
2734 ctx
->Viewport
.Tx
= ctx
->Viewport
.Sx
+ x
;
2735 ctx
->Viewport
.Sy
= (GLfloat
) height
/ 2.0F
;
2736 ctx
->Viewport
.Ty
= ctx
->Viewport
.Sy
+ y
;