1 /* $Id: wmesa.c,v 1.3 2000/03/03 23:21:57 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
25 * Revision 1.3 2000/03/03 23:21:57 brianp
26 * removed obsolete logicop function
28 * Revision 1.2 2000/02/17 20:52:02 brianp
29 * replaced renderer_string() with get_string() func
31 * Revision 1.1.1.1 1999/08/19 00:55:42 jtg
34 * Revision 3.10 1999/06/15 01:35:06 brianp
35 * small change to wmSetPixel() from TWILMOT@cpr.fr
37 * Revision 3.9 1999/05/11 19:06:01 brianp
38 * fixed a few VB->Index bugs (mikec@ensoniq.com)
40 * Revision 3.8 1999/05/08 15:15:23 brianp
41 * various updates from mikec@ensoniq.com
43 * Revision 3.7 1999/04/01 01:27:34 brianp
44 * always flip Y coord in read_rgba_span()
46 * Revision 3.6 1999/03/28 21:17:27 brianp
47 * updated SetBuffer driver function
49 * Revision 3.5 1999/03/16 01:36:42 brianp
50 * patched dither() to check if Current is NULL, per xzhou@nyx.net
52 * Revision 3.4 1999/02/25 14:12:33 keithw
55 * Revision 3.3 1999/01/03 03:08:57 brianp
58 * Revision 3.2 1998/08/29 00:26:01
59 * updated for Mesa 3.0 to accomodate EGCS-Mingw32 build
61 * Revision 3.1 1998/06/11 01:42:08 brianp
62 * updated for Mesa 3.0 device driver interface (but not tested)
64 * Revision 3.0 1998/06/11 01:18:25 brianp
70 #define WMESA_STEREO_C
76 #include "mesa_extend.h"
87 #pragma warning ( disable : 4133 4761 )
90 // #include "profile.h"
100 #define CopyMemory memcpy
103 #if !defined(NO_STEREO)
109 #if !defined(NO_PARALLEL)
110 // #include "parallel.h"
113 struct DISPLAY_OPTIONS displayOptions
;
115 GLenum stereoCompile
= GL_FALSE
;
116 GLenum stereoShowing
= GL_FALSE
;
117 GLenum stereoBuffer
= GL_FALSE
;
118 #if !defined(NO_STEREO)
119 GLint displayList
= MAXIMUM_DISPLAY_LIST
;
121 GLint stereo_flag
= 0 ;
123 /* end of added code*/
125 static PWMC Current
= NULL
;
126 WMesaContext WC
= NULL
;
129 #define assert(ignore) ((void) 0)
131 void Mesa_Assert(void *Cond
,void *File
,unsigned Line
)
134 sprintf(Msg
,"%s %s %d",Cond
,File
,Line
);
135 MessageBox(NULL
,Msg
,"Assertion failed.",MB_OK
);
138 #define assert(e) if (!e) Mesa_Assert(#e,__FILE__,__LINE__);
141 //#define DD_GETDC (Current->hDC )
142 #define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
143 //#define DD_GETDC ((Current->db_flag) ? Current->hDCPrimary : Current->hDCBack )
146 //#define BEGINGDICALL if(Current->rgb_flag)wmFlushBits(Current);
148 //#define ENDGDICALL if(Current->rgb_flag)wmGetBits(Current);
151 //#define FLIP(Y) (Current->dither_flag? Y : Current->height-(Y)-1)
152 //#define FLIP(Y) (Current->height-(Y)-1)
155 * XXX Why only flip Y coord if single buffered???
157 #define FLIP(Y) (Current->db_flag? Y: Current->height-(Y)-1)
159 #define ENDPROFILE(PARA)
161 #define DITHER_RGB_TO_8BIT_SETUP \
162 GLubyte pixelDithered;
164 #define DITHER_RGB_TO_8BIT(red, green, blue, pixel, scanline) \
166 char unsigned redtemp, greentemp, bluetemp, paletteindex; \
167 redtemp = aDividedBy51[red] \
168 + (aModulo51[red] > aHalftone8x8[(pixel%8)*8 \
170 greentemp = aDividedBy51[(char unsigned)green] \
171 + (aModulo51[green] > aHalftone8x8[ \
172 (pixel%8)*8 + scanline%8]); \
173 bluetemp = aDividedBy51[(char unsigned)blue] \
174 + (aModulo51[blue] > aHalftone8x8[ \
175 (pixel%8)*8 +scanline%8]); \
176 paletteindex = redtemp + aTimes6[greentemp] + aTimes36[bluetemp]; \
177 pixelDithered = aWinGHalftoneTranslation[paletteindex]; \
182 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
);
183 static void DDFree( WMesaContext wc
);
184 static HRESULT
DDRestoreAll( WMesaContext wc
);
185 static void DDDeleteOffScreen(WMesaContext wc
);
186 static BOOL
DDCreateOffScreen(WMesaContext wc
);
189 static void FlushToFile(PWMC pwc
, PSTR szFile
);
191 BOOL
wmCreateBackingStore(PWMC pwc
, long lxSize
, long lySize
);
192 BOOL
wmDeleteBackingStore(PWMC pwc
);
193 void wmCreatePalette( PWMC pwdc
);
194 BOOL
wmSetDibColors(PWMC pwc
);
195 void wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
);
197 void wmCreateDIBSection(
199 PWMC pwc
, // handle of device context
200 CONST BITMAPINFO
*pbmi
, // address of structure containing bitmap size, format, and color data
201 UINT iUsage
// color data type indicator: RGB values or palette indices
205 void WMesaViewport( GLcontext
*ctx
,
206 GLint x
, GLint y
, GLsizei width
, GLsizei height
);
209 static triangle_func
choose_triangle_function( GLcontext
*ctx
);
212 static void wmSetPixelFormat( PWMC wc
, HDC hDC
)
215 wc
->cColorBits
= GetDeviceCaps(hDC
, BITSPIXEL
);
218 switch(wc
->cColorBits
){
220 if(wc
->dither_flag
!= GL_TRUE
)
221 wc
->pixelformat
= PF_INDEX8
;
223 wc
->pixelformat
= PF_DITHER8
;
226 wc
->pixelformat
= PF_5R6G5B
;
229 wc
->pixelformat
= PF_8R8G8B
;
232 wc
->pixelformat
= PF_BADFORMAT
;
237 // This function sets the color table of a DIB section
238 // to match that of the destination DC
240 BOOL
/*WINAPI*/ wmSetDibColors(PWMC pwc
)
242 RGBQUAD
*pColTab
, *pRGB
;
243 PALETTEENTRY
*pPal
, *pPE
;
248 /* Build a color table in the DIB that maps to the
249 selected palette in the DC.
251 nColors
= 1 << pwc
->cColorBits
;
252 pPal
= (PALETTEENTRY
*)malloc( nColors
* sizeof(PALETTEENTRY
));
253 memset( pPal
, 0, nColors
* sizeof(PALETTEENTRY
) );
254 GetPaletteEntries( pwc
->hGLPalette
, 0, nColors
, pPal
);
255 pColTab
= (RGBQUAD
*)malloc( nColors
* sizeof(RGBQUAD
));
256 for (i
= 0, pRGB
= pColTab
, pPE
= pPal
; i
< nColors
; i
++, pRGB
++, pPE
++) {
257 pRGB
->rgbRed
= pPE
->peRed
;
258 pRGB
->rgbGreen
= pPE
->peGreen
;
259 pRGB
->rgbBlue
= pPE
->peBlue
;
262 bRet
= SetDIBColorTable(pwc
->dib
.hDC
, 0, nColors
, pColTab
);
265 dwErr
= GetLastError();
275 // Free up the dib section that was created
277 BOOL
wmDeleteBackingStore(PWMC pwc
)
279 SelectObject(pwc
->dib
.hDC
, pwc
->hOldBitmap
);
280 DeleteDC(pwc
->dib
.hDC
);
281 DeleteObject(pwc
->hbmDIB
);
282 UnmapViewOfFile(pwc
->dib
.base
);
283 CloseHandle(pwc
->dib
.hFileMap
);
289 // This function creates the DIB section that is used for combined
292 BOOL
/*WINAPI*/ wmCreateBackingStore(PWMC pwc
, long lxSize
, long lySize
)
295 LPBITMAPINFO pbmi
= &(pwc
->bmi
);
298 pbmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
299 pbmi
->bmiHeader
.biWidth
= lxSize
;
300 pbmi
->bmiHeader
.biHeight
= -lySize
;
301 pbmi
->bmiHeader
.biPlanes
= 1;
303 pbmi
->bmiHeader
.biBitCount
= GetDeviceCaps(pwc
->hDC
, BITSPIXEL
);
305 pbmi
->bmiHeader
.biBitCount
= 8;
306 pbmi
->bmiHeader
.biCompression
= BI_RGB
;
307 pbmi
->bmiHeader
.biSizeImage
= 0;
308 pbmi
->bmiHeader
.biXPelsPerMeter
= 0;
309 pbmi
->bmiHeader
.biYPelsPerMeter
= 0;
310 pbmi
->bmiHeader
.biClrUsed
= 0;
311 pbmi
->bmiHeader
.biClrImportant
= 0;
313 iUsage
= (pbmi
->bmiHeader
.biBitCount
<= 8) ? DIB_PAL_COLORS
: DIB_RGB_COLORS
;
315 pwc
->cColorBits
= pbmi
->bmiHeader
.biBitCount
;
316 pwc
->ScanWidth
= pwc
->pitch
= lxSize
;
318 wmCreateDIBSection(hdc
, pwc
, pbmi
, iUsage
);
320 if ((iUsage
== DIB_PAL_COLORS
) && !(pwc
->hGLPalette
)) {
321 wmCreatePalette( pwc
);
322 wmSetDibColors( pwc
);
324 wmSetPixelFormat(pwc
, pwc
->hDC
);
331 // This function copies one scan line in a DIB section to another
333 BOOL WINAPI
wmSetDIBits(PWMC pwc
, UINT uiScanWidth
, UINT uiNumScans
, UINT nBypp
, UINT uiNewWidth
, LPBYTE pBits
)
336 LPBYTE pDest
= pwc
->pbPixels
;
337 DWORD dwNextScan
= uiScanWidth
;
338 DWORD dwNewScan
= uiNewWidth
;
339 DWORD dwScanWidth
= (uiScanWidth
* nBypp
);
342 // We need to round up to the nearest DWORD
343 // and multiply by the number of bytes per
346 dwNextScan
= (((dwNextScan
* nBypp
)+ 3) & ~3);
347 dwNewScan
= (((dwNewScan
* nBypp
)+ 3) & ~3);
349 for(uiScans
= 0; uiScans
< uiNumScans
; uiScans
++){
350 CopyMemory(pDest
, pBits
, dwScanWidth
);
360 BOOL
wmFlush(PWMC pwc
);
364 Modified from file osmesa.c
368 #define PIXELADDR(X,Y) ((GLubyte *)Current->pbPixels + (Current->height-Y-1)* Current->ScanWidth + (X)*nBypp)
369 #define PIXELADDR1( X, Y ) \
370 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X))
371 #define PIXELADDR2( X, Y ) \
372 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*2)
373 #define PIXELADDR4( X, Y ) \
374 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*4)
377 BYTE
DITHER_RGB_2_8BIT( int r
, int g
, int b
, int x
, int y
);
379 /* Finish all pending operations and synchronize. */
380 static void finish(GLcontext
* ctx
)
387 // We cache all gl draw routines until a flush is made
389 static void flush(GLcontext
* ctx
)
392 if((Current
->rgb_flag
/*&& !(Current->dib.fFlushed)*/&&!(Current
->db_flag
))
393 ||(!Current
->rgb_flag
))
404 * Set the color index used to clear the color buffer.
406 static void clear_index(GLcontext
* ctx
, GLuint index
)
409 Current
->clearpixel
= index
;
410 ENDPROFILE(clear_index
)
416 * Set the color used to clear the color buffer.
418 static void clear_color( GLcontext
* ctx
, GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
421 Current
->clearpixel
=RGB(r
, g
, b
);
422 ENDPROFILE(clear_color
)
428 * Clear the specified region of the color buffer using the clear color
429 * or index as specified by one of the two functions above.
431 //static void clear(GLcontext* ctx,
432 // GLboolean all,GLint x, GLint y, GLint width, GLint height )
433 // TODO: I modified this function to match the prototype in dd.h. (swansma@geocities.com)
434 // dd.h does not explain what the return type is so I could not set this to the proper
436 static GLbitfield
clear(GLcontext
* ctx
, GLbitfield mask
,
437 GLboolean all
, GLint x
, GLint y
, GLint width
, GLint height
)
442 LPDWORD lpdw
= (LPDWORD
)Current
->pbPixels
;
443 LPWORD lpw
= (LPWORD
)Current
->pbPixels
;
444 LPBYTE lpb
= Current
->pbPixels
;
451 width
=Current
->width
;
452 height
=Current
->height
;
454 if(Current
->db_flag
==GL_TRUE
){
455 UINT nBypp
= Current
->cColorBits
/ 8;
460 /* Need rectification */
461 iSize
= Current
->width
/4;
462 bColor
= BGR8(GetRValue(Current
->clearpixel
),
463 GetGValue(Current
->clearpixel
),
464 GetBValue(Current
->clearpixel
));
465 wColor
= MAKEWORD(bColor
,bColor
);
466 dwColor
= MAKELONG(wColor
, wColor
);
469 iSize
= Current
->width
/ 2;
470 wColor
= BGR16(GetRValue(Current
->clearpixel
),
471 GetGValue(Current
->clearpixel
),
472 GetBValue(Current
->clearpixel
));
473 dwColor
= MAKELONG(wColor
, wColor
);
476 iSize
= Current
->width
;
477 dwColor
= BGR32(GetRValue(Current
->clearpixel
),
478 GetGValue(Current
->clearpixel
),
479 GetBValue(Current
->clearpixel
));
489 // This is the 24bit case
492 iSize
= Current
->width
*3/4;
493 dwColor
= BGR24(GetRValue(Current
->clearpixel
),
494 GetGValue(Current
->clearpixel
),
495 GetBValue(Current
->clearpixel
));
510 memcpy(lpb
, Current
->pbPixels
, iSize
*4);
511 lpb
+= Current
->ScanWidth
;
516 else { // For single buffer
518 HPEN Pen
=CreatePen(PS_SOLID
,1,Current
->clearpixel
);
519 HBRUSH Brush
=CreateSolidBrush(Current
->clearpixel
);
520 HPEN Old_Pen
=SelectObject(DC
,Pen
);
521 HBRUSH Old_Brush
=SelectObject(DC
,Brush
);
522 Rectangle(DC
,x
,y
,x
+width
,y
+height
);
523 SelectObject(DC
,Old_Pen
);
524 SelectObject(DC
,Old_Brush
);
534 return mask
; // TODO: I doubt this is correct. dd.h doesn't explain what this should
540 /* Set the current color index. */
541 static void set_index(GLcontext
* ctx
, GLuint index
)
544 Current
->pixel
=index
;
545 ENDPROFILE(set_index
)
550 /* Set the current RGBA color. */
551 static void set_color( GLcontext
* ctx
, GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
554 Current
->pixel
= RGB( r
, g
, b
);
555 ENDPROFILE(set_color
)
560 /* Set the index mode bitplane mask. */
561 static GLboolean
index_mask(GLcontext
* ctx
, GLuint mask
)
563 /* can't implement */
569 /* Set the RGBA drawing mask. */
570 static GLboolean
color_mask( GLcontext
* ctx
,
571 GLboolean rmask
, GLboolean gmask
,
572 GLboolean bmask
, GLboolean amask
)
574 /* can't implement */
580 static void dither( GLcontext
* ctx
, GLboolean enable
)
585 if(enable
== GL_FALSE
){
586 Current
->dither_flag
= GL_FALSE
;
587 if(Current
->cColorBits
== 8)
588 Current
->pixelformat
= PF_INDEX8
;
591 if (Current
->rgb_flag
&& Current
->cColorBits
== 8){
592 Current
->pixelformat
= PF_DITHER8
;
593 Current
->dither_flag
= GL_TRUE
;
596 Current
->dither_flag
= GL_FALSE
;
602 static GLboolean
set_buffer( GLcontext
* ctx
, GLenum mode
)
605 /* TODO: this could be better */
606 if (mode
==GL_FRONT_LEFT
|| mode
==GL_BACK_LEFT
) {
612 ENDPROFILE(set_buffer
)
617 /* Return characteristics of the output buffer. */
618 static void buffer_size( GLcontext
* ctx
, GLuint
*width
, GLuint
*height
)
624 GetClientRect(Current
->Window
,&CR
);
629 New_Size
=((*width
)!=Current
->width
) || ((*height
)!=Current
->height
);
632 Current
->width
=*width
;
633 Current
->height
=*height
;
634 Current
->ScanWidth
=Current
->width
;
635 if ((Current
->ScanWidth
%sizeof(long))!=0)
636 Current
->ScanWidth
+=(sizeof(long)-(Current
->ScanWidth
%sizeof(long)));
638 if (Current
->db_flag
){
640 DDDeleteOffScreen(Current
);
641 DDCreateOffScreen(Current
);
643 if (Current
->rgb_flag
==GL_TRUE
&& Current
->dither_flag
!=GL_TRUE
){
644 wmDeleteBackingStore(Current
);
645 wmCreateBackingStore(Current
, Current
->width
, Current
->height
);
650 // Resize OsmesaBuffer if in Parallel mode
651 #if !defined(NO_PARALLEL)
653 PRSizeRenderBuffer(Current
->width
, Current
->height
,Current
->ScanWidth
,
654 Current
->rgb_flag
== GL_TRUE
? Current
->pbPixels
: Current
->ScreenMem
);
657 ENDPROFILE(buffer_size
)
662 /**********************************************************************/
663 /***** Accelerated point, line, polygon rendering *****/
664 /**********************************************************************/
667 static void fast_rgb_points( GLcontext
* ctx
, GLuint first
, GLuint last
)
675 if (0 /*Current->gl_ctx->VB->MonoColor*/) {
676 /* all drawn with current color */
677 for (i
=first
;i
<=last
;i
++) {
678 if (!Current
->gl_ctx
->VB
->ClipMask
[i
]) {
680 x
= (GLint
) Current
->gl_ctx
->VB
->Win
.data
[i
][0];
681 y
= FLIP( (GLint
) Current
->gl_ctx
->VB
->Win
.data
[i
][1] );
682 wmSetPixel(pwc
, y
,x
,GetRValue(Current
->pixel
),
683 GetGValue(Current
->pixel
), GetBValue(Current
->pixel
));
688 /* draw points of different colors */
689 for (i
=first
;i
<=last
;i
++) {
690 if (!Current
->gl_ctx
->VB
->ClipMask
[i
]) {
692 unsigned long pixel
=RGB(Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][0]*255.0,
693 Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][1]*255.0,
694 Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][2]*255.0);
695 x
= (GLint
) Current
->gl_ctx
->VB
->Win
.data
[i
][0];
696 y
= FLIP( (GLint
) Current
->gl_ctx
->VB
->Win
.data
[i
][1] );
697 wmSetPixel(pwc
, y
,x
,Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][0]*255.0,
698 Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][1]*255.0,
699 Current
->gl_ctx
->VB
->ColorPtr
->data
[i
][2]*255.0);
704 ENDPROFILE(fast_rgb_points
)
709 /* Return pointer to accerated points function */
710 extern points_func
choose_points_function( GLcontext
* ctx
)
713 if (ctx
->Point
.Size
==1.0 && !ctx
->Point
.SmoothFlag
&& ctx
->RasterMask
==0
714 && !ctx
->Texture
.Enabled
&& ctx
->Visual
->RGBAflag
) {
715 ENDPROFILE(choose_points_function
)
716 return fast_rgb_points
;
719 ENDPROFILE(choose_points_function
)
726 /* Draw a line using the color specified by Current->gl_ctx->VB->ColorPtr->data[pv] */
727 static void fast_flat_rgb_line( GLcontext
* ctx
, GLuint v0
, GLuint v1
, GLuint pv
)
736 if (0 /*Current->gl_ctx->VB->MonoColor*/) {
737 pixel
= Current
->pixel
; /* use current color */
740 pixel
= RGB(Current
->gl_ctx
->VB
->ColorPtr
->data
[pv
][0]*255.0, Current
->gl_ctx
->VB
->ColorPtr
->data
[pv
][1]*255.0, Current
->gl_ctx
->VB
->ColorPtr
->data
[pv
][2]*255.0);
743 x0
= (int) Current
->gl_ctx
->VB
->Win
.data
[v0
][0];
744 y0
= FLIP( (int) Current
->gl_ctx
->VB
->Win
.data
[v0
][1] );
745 x1
= (int) Current
->gl_ctx
->VB
->Win
.data
[v1
][0];
746 y1
= FLIP( (int) Current
->gl_ctx
->VB
->Win
.data
[v1
][1] );
751 Pen
=CreatePen(PS_SOLID
,1,pixel
);
752 Old_Pen
=SelectObject(DC
,Pen
);
753 MoveToEx(DC
,x0
,y0
,NULL
);
755 SelectObject(DC
,Old_Pen
);
761 ENDPROFILE(fast_flat_rgb_line
)
766 /* Return pointer to accerated line function */
767 static line_func
choose_line_function( GLcontext
* ctx
)
770 if (ctx
->Line
.Width
==1.0 && !ctx
->Line
.SmoothFlag
&& !ctx
->Line
.StippleFlag
771 && ctx
->Light
.ShadeModel
==GL_FLAT
&& ctx
->RasterMask
==0
772 && !ctx
->Texture
.Enabled
&& Current
->rgb_flag
) {
773 ENDPROFILE(choose_line_function
)
774 return fast_flat_rgb_line
;
777 ENDPROFILE(choose_line_function
)
783 /**********************************************************************/
784 /***** Span-based pixel drawing *****/
785 /**********************************************************************/
788 /* Write a horizontal span of 32-bit color-index pixels with a boolean mask. */
789 static void write_ci32_span( const GLcontext
* ctx
,
790 GLuint n
, GLint x
, GLint y
,
791 const GLuint index
[],
792 const GLubyte mask
[] )
796 PBYTE Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
797 assert(Current
->rgb_flag
==GL_FALSE
);
801 ENDPROFILE(write_ci32_span
)
805 /* Write a horizontal span of 8-bit color-index pixels with a boolean mask. */
806 static void write_ci8_span( const GLcontext
* ctx
,
807 GLuint n
, GLint x
, GLint y
,
808 const GLubyte index
[],
809 const GLubyte mask
[] )
813 PBYTE Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
814 assert(Current
->rgb_flag
==GL_FALSE
);
818 ENDPROFILE(write_ci8_span
)
824 * Write a horizontal span of pixels with a boolean mask. The current
825 * color index is used for all pixels.
827 static void write_mono_ci_span(const GLcontext
* ctx
,
828 GLuint n
,GLint x
,GLint y
,
829 const GLubyte mask
[])
833 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
834 assert(Current
->rgb_flag
==GL_FALSE
);
837 Mem
[i
]=Current
->pixel
;
838 ENDPROFILE(write_mono_ci_span
)
842 * To improve the performance of this routine, frob the data into an actual
843 * scanline and call bitblt on the complete scan line instead of SetPixel.
846 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
847 static void write_rgba_span( const GLcontext
* ctx
, GLuint n
, GLint x
, GLint y
,
848 const GLubyte rgba
[][4], const GLubyte mask
[] )
853 if (pwc
->rgb_flag
==GL_TRUE
)
861 wmSetPixel(pwc
, y
, x
+ i
, rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
865 wmSetPixel(pwc
, y
, x
+ i
, rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
] );
872 BYTE
*Mem
=Current
->ScreenMem
+y
*Current
->ScanWidth
+x
;
877 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]));
881 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]));
884 ENDPROFILE(write_rgba_span
)
888 /* Write a horizontal span of RGB color pixels with a boolean mask. */
889 static void write_rgb_span( const GLcontext
* ctx
,
890 GLuint n
, GLint x
, GLint y
,
891 const GLubyte rgb
[][3], const GLubyte mask
[] )
896 if (pwc
->rgb_flag
==GL_TRUE
)
904 wmSetPixel(pwc
, y
, x
+ i
, rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]);
908 wmSetPixel(pwc
, y
, x
+ i
, rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
] );
915 BYTE
*Mem
=Current
->ScreenMem
+y
*Current
->ScanWidth
+x
;
920 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]));
924 Mem
[i
] = GetNearestPaletteIndex(Current
->hPal
,RGB(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]));
927 ENDPROFILE(write_rgb_span
)
932 * Write a horizontal span of pixels with a boolean mask. The current color
933 * is used for all pixels.
935 static void write_mono_rgba_span( const GLcontext
* ctx
,
936 GLuint n
, GLint x
, GLint y
,
937 const GLubyte mask
[])
943 assert(Current
->rgb_flag
==GL_TRUE
);
945 if(Current
->rgb_flag
==GL_TRUE
){
949 wmSetPixel(pwc
,y
,x
+i
,GetRValue(Current
->pixel
), GetGValue(Current
->pixel
), GetBValue(Current
->pixel
));
954 SetPixel(DC
, y
, x
+i
, Current
->pixel
);
957 ENDPROFILE(write_mono_rgba_span
)
962 /**********************************************************************/
963 /***** Array-based pixel drawing *****/
964 /**********************************************************************/
967 /* Write an array of 32-bit index pixels with a boolean mask. */
968 static void write_ci32_pixels( const GLcontext
* ctx
,
969 GLuint n
, const GLint x
[], const GLint y
[],
970 const GLuint index
[], const GLubyte mask
[] )
974 assert(Current
->rgb_flag
==GL_FALSE
);
975 for (i
=0; i
<n
; i
++) {
977 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
];
981 ENDPROFILE(write_ci32_pixels
)
987 * Write an array of pixels with a boolean mask. The current color
988 * index is used for all pixels.
990 static void write_mono_ci_pixels( const GLcontext
* ctx
,
992 const GLint x
[], const GLint y
[],
993 const GLubyte mask
[] )
997 assert(Current
->rgb_flag
==GL_FALSE
);
998 for (i
=0; i
<n
; i
++) {
1000 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
];
1001 *Mem
= Current
->pixel
;
1004 ENDPROFILE(write_mono_ci_pixels
)
1009 /* Write an array of RGBA pixels with a boolean mask. */
1010 static void write_rgba_pixels( const GLcontext
* ctx
,
1011 GLuint n
, const GLint x
[], const GLint y
[],
1012 const GLubyte rgba
[][4], const GLubyte mask
[] )
1018 assert(Current
->rgb_flag
==GL_TRUE
);
1021 wmSetPixel(pwc
, FLIP(y
[i
]),x
[i
],rgba
[i
][RCOMP
],rgba
[i
][GCOMP
],rgba
[i
][BCOMP
]);
1023 ENDPROFILE(write_rgba_pixels
)
1029 * Write an array of pixels with a boolean mask. The current color
1030 * is used for all pixels.
1032 static void write_mono_rgba_pixels( const GLcontext
* ctx
,
1034 const GLint x
[], const GLint y
[],
1035 const GLubyte mask
[] )
1041 assert(Current
->rgb_flag
==GL_TRUE
);
1044 wmSetPixel(pwc
, FLIP(y
[i
]),x
[i
],GetRValue(Current
->pixel
),
1045 GetGValue(Current
->pixel
), GetBValue(Current
->pixel
));
1047 ENDPROFILE(write_mono_rgba_pixels
)
1052 /**********************************************************************/
1053 /***** Read spans/arrays of pixels *****/
1054 /**********************************************************************/
1057 /* Read a horizontal span of color-index pixels. */
1058 static void read_ci32_span( const GLcontext
* ctx
, GLuint n
, GLint x
, GLint y
,
1063 BYTE
*Mem
=Current
->ScreenMem
+FLIP(y
)*Current
->ScanWidth
+x
;
1064 assert(Current
->rgb_flag
==GL_FALSE
);
1067 ENDPROFILE(read_ci32_span
)
1073 /* Read an array of color index pixels. */
1074 static void read_ci32_pixels( const GLcontext
* ctx
,
1075 GLuint n
, const GLint x
[], const GLint y
[],
1076 GLuint indx
[], const GLubyte mask
[] )
1080 assert(Current
->rgb_flag
==GL_FALSE
);
1081 for (i
=0; i
<n
; i
++) {
1083 indx
[i
]=*(Current
->ScreenMem
+FLIP(y
[i
])*Current
->ScanWidth
+x
[i
]);
1086 ENDPROFILE(read_ci32_pixels
)
1091 /* Read a horizontal span of color pixels. */
1092 static void read_rgba_span( const GLcontext
* ctx
,
1093 GLuint n
, GLint x
, GLint y
,
1100 assert(Current
->rgb_flag
==GL_TRUE
);
1102 y
= Current
->height
- y
- 1;
1103 for (i
=0; i
<n
; i
++) {
1104 Color
=GetPixel(DC
,x
+i
,y
);
1105 rgba
[i
][RCOMP
] = GetRValue(Color
);
1106 rgba
[i
][GCOMP
] = GetGValue(Color
);
1107 rgba
[i
][BCOMP
] = GetBValue(Color
);
1108 rgba
[i
][ACOMP
] = 255;
1111 // Brian P. Has mentioned to comment this out.
1112 // memset(alpha,0,n*sizeof(GLubyte));
1113 ENDPROFILE(read_rgba_span
)
1117 /* Read an array of color pixels. */
1118 static void read_rgba_pixels( const GLcontext
* ctx
,
1119 GLuint n
, const GLint x
[], const GLint y
[],
1120 GLubyte rgba
[][4], const GLubyte mask
[] )
1126 assert(Current
->rgb_flag
==GL_TRUE
);
1127 for (i
=0; i
<n
; i
++) {
1129 Color
=GetPixel(DC
,x
[i
],FLIP(y
[i
]));
1130 rgba
[i
][RCOMP
] = GetRValue(Color
);
1131 rgba
[i
][GCOMP
] = GetGValue(Color
);
1132 rgba
[i
][BCOMP
] = GetBValue(Color
);
1133 rgba
[i
][ACOMP
] = 255;
1137 // Brian P. has mentioned to comment this out.
1138 // memset(alpha,0,n*sizeof(GLint));
1139 ENDPROFILE(read_rgba_pixels
)
1144 /**********************************************************************/
1145 /**********************************************************************/
1148 static const GLubyte
*get_string(GLcontext
*ctx
, GLenum name
)
1150 if (name
== GL_RENDERER
) {
1151 return (GLubyte
*) "Mesa Windows";
1160 void setup_DD_pointers( GLcontext
* ctx
)
1162 ctx
->Driver
.GetString
= get_string
;
1163 ctx
->Driver
.UpdateState
= setup_DD_pointers
;
1164 ctx
->Driver
.GetBufferSize
= buffer_size
;
1165 ctx
->Driver
.Finish
= finish
;
1166 ctx
->Driver
.Flush
= flush
;
1168 ctx
->Driver
.ClearIndex
= clear_index
;
1169 ctx
->Driver
.ClearColor
= clear_color
;
1170 ctx
->Driver
.Clear
= clear
;
1172 ctx
->Driver
.Index
= set_index
;
1173 ctx
->Driver
.Color
= set_color
;
1174 ctx
->Driver
.IndexMask
= index_mask
;
1175 ctx
->Driver
.ColorMask
= color_mask
;
1177 ctx
->Driver
.Dither
= dither
;
1179 ctx
->Driver
.SetBuffer
= set_buffer
;
1180 ctx
->Driver
.GetBufferSize
= buffer_size
;
1182 ctx
->Driver
.PointsFunc
= choose_points_function(ctx
);
1183 ctx
->Driver
.LineFunc
= choose_line_function(ctx
);
1184 ctx
->Driver
.TriangleFunc
= choose_triangle_function( ctx
);
1186 /* Pixel/span writing functions: */
1187 ctx
->Driver
.WriteRGBASpan
= write_rgba_span
;
1188 ctx
->Driver
.WriteRGBSpan
= write_rgb_span
;
1189 ctx
->Driver
.WriteMonoRGBASpan
= write_mono_rgba_span
;
1190 ctx
->Driver
.WriteRGBAPixels
= write_rgba_pixels
;
1191 ctx
->Driver
.WriteMonoRGBAPixels
= write_mono_rgba_pixels
;
1192 ctx
->Driver
.WriteCI32Span
= write_ci32_span
;
1193 ctx
->Driver
.WriteCI8Span
= write_ci8_span
;
1194 ctx
->Driver
.WriteMonoCISpan
= write_mono_ci_span
;
1195 ctx
->Driver
.WriteCI32Pixels
= write_ci32_pixels
;
1196 ctx
->Driver
.WriteMonoCIPixels
= write_mono_ci_pixels
;
1198 ctx
->Driver
.ReadCI32Span
= read_ci32_span
;
1199 ctx
->Driver
.ReadRGBASpan
= read_rgba_span
;
1200 ctx
->Driver
.ReadCI32Pixels
= read_ci32_pixels
;
1201 ctx
->Driver
.ReadRGBAPixels
= read_rgba_pixels
;
1205 /**********************************************************************/
1206 /***** WMesa API Functions *****/
1207 /**********************************************************************/
1211 #define PAL_SIZE 256
1212 static void GetPalette(HPALETTE Pal
,RGBQUAD
*aRGB
)
1220 WORD NumberOfEntries
;
1221 PALETTEENTRY aEntries
[PAL_SIZE
];
1229 GetPaletteEntries(Pal
,0,PAL_SIZE
,Palette
.aEntries
);
1231 GetSystemPaletteEntries(hdc
,0,PAL_SIZE
,Palette
.aEntries
);
1232 if (GetSystemPaletteUse(hdc
) == SYSPAL_NOSTATIC
)
1234 for(i
= 0; i
<PAL_SIZE
; i
++)
1235 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1236 Palette
.aEntries
[255].peRed
= 255;
1237 Palette
.aEntries
[255].peGreen
= 255;
1238 Palette
.aEntries
[255].peBlue
= 255;
1239 Palette
.aEntries
[255].peFlags
= 0;
1240 Palette
.aEntries
[0].peRed
= 0;
1241 Palette
.aEntries
[0].peGreen
= 0;
1242 Palette
.aEntries
[0].peBlue
= 0;
1243 Palette
.aEntries
[0].peFlags
= 0;
1249 nStaticColors
= GetDeviceCaps(hdc
, NUMCOLORS
)/2;
1250 for (i
=0; i
<nStaticColors
; i
++)
1251 Palette
.aEntries
[i
].peFlags
= 0;
1252 nUsableColors
= PAL_SIZE
-nStaticColors
;
1253 for (; i
<nUsableColors
; i
++)
1254 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1255 for (; i
<PAL_SIZE
-nStaticColors
; i
++)
1256 Palette
.aEntries
[i
].peFlags
= PC_RESERVED
;
1257 for (i
=PAL_SIZE
-nStaticColors
; i
<PAL_SIZE
; i
++)
1258 Palette
.aEntries
[i
].peFlags
= 0;
1260 ReleaseDC(NULL
,hdc
);
1261 for (i
=0; i
<PAL_SIZE
; i
++)
1263 aRGB
[i
].rgbRed
=Palette
.aEntries
[i
].peRed
;
1264 aRGB
[i
].rgbGreen
=Palette
.aEntries
[i
].peGreen
;
1265 aRGB
[i
].rgbBlue
=Palette
.aEntries
[i
].peBlue
;
1266 aRGB
[i
].rgbReserved
=Palette
.aEntries
[i
].peFlags
;
1268 ENDPROFILE(GetPalette
)
1272 WMesaContext
WMesaCreateContext( HWND hWnd
, HPALETTE
* Pal
,
1278 GLboolean true_color_flag
;
1279 c
= (struct wmesa_context
* ) calloc(1,sizeof(struct wmesa_context
));
1284 c
->hDC
= GetDC(hWnd
);
1285 true_color_flag
= GetDeviceCaps(c
->hDC
, BITSPIXEL
) > 8;
1287 if(true_color_flag
) c
->rgb_flag
= rgb_flag
= GL_TRUE
;
1292 if ((true_color_flag
==GL_FALSE
) && (rgb_flag
== GL_TRUE
)){
1293 c
->dither_flag
= GL_TRUE
;
1294 c
->hPalHalfTone
= WinGCreateHalftonePalette();
1297 c
->dither_flag
= GL_FALSE
;
1299 c
->dither_flag
= GL_FALSE
;
1303 if (rgb_flag
==GL_FALSE
)
1305 c
->rgb_flag
= GL_FALSE
;
1307 c
->db_flag
= db_flag
=GL_TRUE
; // WinG requires double buffering
1308 printf("Single buffer is not supported in color index mode, setting to double buffer.\n");
1312 c
->rgb_flag
= GL_TRUE
;
1315 GetClientRect(c
->Window
,&CR
);
1317 c
->height
=CR
.bottom
;
1321 /* Double buffered */
1323 // if (c->rgb_flag==GL_TRUE && c->dither_flag != GL_TRUE )
1325 wmCreateBackingStore(c
, c
->width
, c
->height
);
1332 /* Single Buffered */
1337 if (DDInit(c
,hWnd
) == GL_FALSE
) {
1344 c
->gl_visual
= gl_create_visual(rgb_flag
,
1345 GL_FALSE
, /* software alpha */
1346 db_flag
, /* db_flag */
1347 GL_FALSE
, /* stereo */
1348 16, /* depth_bits */
1349 8, /* stencil_bits */
1352 8,8,8,8 ); /* r, g, b, a bits */
1354 if (!c
->gl_visual
) {
1358 /* allocate a new Mesa context */
1359 c
->gl_ctx
= gl_create_context( c
->gl_visual
, NULL
, c
, GL_TRUE
);
1362 gl_destroy_visual( c
->gl_visual
);
1367 c
->gl_buffer
= gl_create_framebuffer( c
->gl_visual
);
1368 if (!c
->gl_buffer
) {
1369 gl_destroy_visual( c
->gl_visual
);
1370 gl_destroy_context( c
->gl_ctx
);
1375 c
->gl_ctx
->Driver
.UpdateState
= setup_DD_pointers
;
1377 // setup_DD_pointers(c->gl_ctx);
1382 void WMesaDestroyContext( void )
1384 WMesaContext c
= Current
;
1385 ReleaseDC(c
->Window
,c
->hDC
);
1387 if(c
->hPalHalfTone
!= NULL
)
1388 DeleteObject(c
->hPalHalfTone
);
1389 gl_destroy_visual( c
->gl_visual
);
1390 gl_destroy_framebuffer( c
->gl_buffer
);
1391 gl_destroy_context( c
->gl_ctx
);
1397 wmDeleteBackingStore(c
);
1400 //Following code is added to enable parallel render
1401 // Parallel render only work in double buffer mode
1402 #if !defined(NO_PARALLEL)
1404 PRDestroyRenderBuffer();
1411 void /*APIENTRY*/ WMesaMakeCurrent( WMesaContext c
)
1419 // A little optimization
1420 // If it already is current,
1421 // don't set it again
1426 //gl_set_context( c->gl_ctx );
1427 gl_make_current(c
->gl_ctx
, c
->gl_buffer
);
1428 setup_DD_pointers(c
->gl_ctx
);
1430 if (Current
->gl_ctx
->Viewport
.Width
==0) {
1431 /* initialize viewport to window size */
1432 gl_Viewport( Current
->gl_ctx
,
1433 0, 0, Current
->width
, Current
->height
);
1435 if ((c
->cColorBits
<= 8 ) && (c
->rgb_flag
== GL_TRUE
)){
1436 WMesaPaletteChange(c
->hPalHalfTone
);
1442 void /*APIENTRY*/ WMesaSwapBuffers( void )
1444 HDC DC
= Current
->hDC
;
1445 if (Current
->db_flag
)
1451 void /*APIENTRY*/ WMesaPaletteChange(HPALETTE Pal
)
1454 LPPALETTEENTRY pPal
;
1455 if (Current
&& (Current
->rgb_flag
==GL_FALSE
|| Current
->dither_flag
== GL_TRUE
))
1457 pPal
= (PALETTEENTRY
*)malloc( 256 * sizeof(PALETTEENTRY
));
1459 // GetPaletteEntries( Pal, 0, 256, pPal );
1460 GetPalette( Pal
, pPal
);
1462 Current
->lpDD
->lpVtbl
->CreatePalette(Current
->lpDD
,DDPCAPS_8BIT
,
1463 pPal
, &(Current
->lpDDPal
), NULL
);
1464 if (Current
->lpDDPal
)
1465 Current
->lpDDSPrimary
->lpVtbl
->SetPalette(Current
->lpDDSPrimary
,Current
->lpDDPal
);
1467 vRet
= SetDIBColorTable(Current
->dib
.hDC
,0,256,pPal
);
1477 static unsigned char threeto8
[8] = {
1478 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
1481 static unsigned char twoto8
[4] = {
1485 static unsigned char oneto8
[2] = {
1489 static unsigned char componentFromIndex(UCHAR i
, UINT nbits
, UINT shift
)
1506 return threeto8
[val
];
1513 void /*WINAPI*/ wmCreatePalette( PWMC pwdc
)
1515 /* Create a compressed and re-expanded 3:3:2 palette */
1518 BYTE rb
, rs
, gb
, gs
, bb
, bs
;
1520 pwdc
->nColors
= 0x100;
1522 pPal
= (PLOGPALETTE
)malloc(sizeof(LOGPALETTE
) + pwdc
->nColors
* sizeof(PALETTEENTRY
));
1523 memset( pPal
, 0, sizeof(LOGPALETTE
) + pwdc
->nColors
* sizeof(PALETTEENTRY
) );
1525 pPal
->palVersion
= 0x300;
1534 if (pwdc
->db_flag
) {
1536 /* Need to make two palettes: one for the screen DC and one for the DIB. */
1537 pPal
->palNumEntries
= pwdc
->nColors
;
1538 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1539 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1540 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1541 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1542 pPal
->palPalEntry
[i
].peFlags
= 0;
1544 pwdc
->hGLPalette
= CreatePalette( pPal
);
1545 pwdc
->hPalette
= CreatePalette( pPal
);
1549 pPal
->palNumEntries
= pwdc
->nColors
;
1550 for (i
= 0; i
< pwdc
->nColors
; i
++) {
1551 pPal
->palPalEntry
[i
].peRed
= componentFromIndex( i
, rb
, rs
);
1552 pPal
->palPalEntry
[i
].peGreen
= componentFromIndex( i
, gb
, gs
);
1553 pPal
->palPalEntry
[i
].peBlue
= componentFromIndex( i
, bb
, bs
);
1554 pPal
->palPalEntry
[i
].peFlags
= 0;
1556 pwdc
->hGLPalette
= CreatePalette( pPal
);
1563 void /*WINAPI*/ wmSetPixel(PWMC pwc
, int iScanLine
, int iPixel
, BYTE r
, BYTE g
, BYTE b
)
1565 if (Current
->db_flag
) {
1566 LPBYTE lpb
= pwc
->pbPixels
;
1569 UINT nBypp
= pwc
->cColorBits
>> 3;
1570 UINT nOffset
= iPixel
% nBypp
;
1572 // Move the pixel buffer pointer to the scanline that we
1575 // pwc->dib.fFlushed = FALSE;
1577 lpb
+= pwc
->ScanWidth
* iScanLine
;
1578 // Now move to the desired pixel
1579 lpb
+= iPixel
* nBypp
;
1580 lpb
= PIXELADDR(iPixel
, iScanLine
);
1581 lpdw
= (LPDWORD
)lpb
;
1585 if(pwc
->dither_flag
)
1586 *lpb
= DITHER_RGB_2_8BIT(r
,g
,b
,iScanLine
,iPixel
);
1591 *lpw
= BGR16(r
,g
,b
);
1592 else if (nBypp
== 3){
1593 *lpdw
= BGR24(r
,g
,b
);
1595 else if (nBypp
== 4)
1596 *lpdw
= BGR32(r
,g
,b
);
1599 SetPixel(Current
->hDC
, iPixel
, iScanLine
, RGB(r
,g
,b
));
1604 void /*WINAPI*/ wmCreateDIBSection(
1606 PWMC pwc
, // handle of device context
1607 CONST BITMAPINFO
*pbmi
, // address of structure containing bitmap size, format, and color data
1608 UINT iUsage
// color data type indicator: RGB values or palette indices
1613 UINT nBypp
= pwc
->cColorBits
/ 8;
1616 dwScanWidth
= (((pwc
->ScanWidth
* nBypp
)+ 3) & ~3);
1618 pwc
->ScanWidth
=pwc
->pitch
= dwScanWidth
;
1621 pwc
->ScanWidth
= 2* pwc
->pitch
;
1623 dwSize
= sizeof(BITMAPINFO
) + (dwScanWidth
* pwc
->height
);
1625 pwc
->dib
.hFileMap
= CreateFileMapping((HANDLE
)PAGE_FILE
,
1627 PAGE_READWRITE
| SEC_COMMIT
,
1632 if (!pwc
->dib
.hFileMap
)
1635 pwc
->dib
.base
= MapViewOfFile(pwc
->dib
.hFileMap
,
1636 FILE_MAP_ALL_ACCESS
,
1642 CloseHandle(pwc
->dib
.hFileMap
);
1646 // pwc->pbPixels = pwc->addrOffScreen = ((LPBYTE)pwc->dib.base) + sizeof(BITMAPINFO);
1648 // pwc->dib.hDC = CreateCompatibleDC(hDC);
1650 CopyMemory(pwc
->dib
.base
, pbmi
, sizeof(BITMAPINFO
));
1652 hic
= CreateIC("display", NULL
, NULL
, NULL
);
1653 pwc
->dib
.hDC
= CreateCompatibleDC(hic
);
1656 /* pwc->hbmDIB = CreateDIBitmap(hic,
1657 &(pwc->bmi.bmiHeader),
1663 pwc
->hbmDIB
= CreateDIBSection(hic
,
1665 (iUsage
? DIB_PAL_COLORS
: DIB_RGB_COLORS
),
1670 pwc->hbmDIB = CreateDIBSection(hic,
1677 pwc
->ScreenMem
= pwc
->addrOffScreen
= pwc
->pbPixels
;
1678 pwc
->hOldBitmap
= SelectObject(pwc
->dib
.hDC
, pwc
->hbmDIB
);
1687 // Blit memory DC to screen DC
1689 BOOL
/*WINAPI*/ wmFlush(PWMC pwc
)
1697 // Now search through the torus frames and mark used colors
1700 if (pwc
->lpDDSOffScreen
== NULL
)
1701 if(DDCreateOffScreen(pwc
) == GL_FALSE
)
1704 pwc
->lpDDSOffScreen
->lpVtbl
->Unlock(pwc
->lpDDSOffScreen
, NULL
);
1708 ddrval
= pwc
->lpDDSPrimary
->lpVtbl
->Blt( pwc
->lpDDSPrimary
,
1709 &(pwc
->rectSurface
), pwc
->lpDDSOffScreen
, &(pwc
->rectOffScreen
), 0, NULL
);
1711 if( ddrval
== DD_OK
)
1715 if( ddrval
== DDERR_SURFACELOST
)
1717 if(!DDRestoreAll(pwc
))
1722 if( ddrval
!= DDERR_WASSTILLDRAWING
)
1728 while (pwc
->lpDDSOffScreen
->lpVtbl
->Lock(pwc
->lpDDSOffScreen
,
1729 NULL
, &(pwc
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
)
1733 dwErr
= GetLastError();
1735 bRet
= BitBlt(pwc
->hDC
, 0, 0, pwc
->width
, pwc
->height
,
1736 pwc
->dib
.hDC
, 0, 0, SRCCOPY
);
1745 // The following code is added by Li Wei to enable stereo display
1747 #if !defined(NO_STEREO)
1749 void WMesaShowStereo(GLuint list
)
1752 GLbitfield mask
= GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
;
1755 // Must use double Buffer
1756 if( ! Current
-> db_flag
)
1760 glGetIntegerv(GL_MATRIX_MODE
,&matrix_mode
);
1762 // glPushMatrix(); //****
1763 WMesaViewport(Current
->gl_ctx
,0,Current
->height
/2,Current
->width
,Current
->height
/2);
1764 // Current->gl_ctx->NewState = 0;
1766 // glViewport(0,0,Current->width,Current->height/2);
1767 if(matrix_mode
!=GL_MODELVIEW
)
1768 glMatrixMode(GL_MODELVIEW
);
1770 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1772 gluLookAt(viewDistance
/2,0.0,0.0 ,
1773 viewDistance
/2,0.0,-1.0,
1775 // glTranslatef(viewDistance/2.0,0.,0.);
1776 glMultMatrixf( cm
);
1778 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
;
1783 glGetFloatv(GL_MODELVIEW_MATRIX
,cm
);
1785 gluLookAt(-viewDistance
/2,0.0,0.0 ,
1786 -viewDistance
/2,0.0,-1.0,
1788 // glTranslatef(-viewDistance/2.0,0.,0.);
1791 Current
->ScreenMem
= Current
->pbPixels
= Current
->addrOffScreen
+ Current
->pitch
;
1793 if(matrix_mode
!=GL_MODELVIEW
)
1794 glMatrixMode(matrix_mode
);
1799 WMesaViewport(Current
->gl_ctx
,0,0,Current
->width
,Current
->height
);
1800 // Current->gl_ctx->NewState = 0;
1805 void toggleStereoMode()
1807 if(!Current
->db_flag
)
1811 if(stereoBuffer
==GL_FALSE
)
1812 #if !defined(NO_PARALLEL)
1816 Current
->ScanWidth
= Current
->pitch
*2;
1821 #if !defined(NO_PARALLEL)
1824 Current
->ScanWidth
= Current
->pitch
;
1825 Current
->pbPixels
= Current
->addrOffScreen
;
1829 /* if in stereo mode, the following function is called */
1830 void glShowStereo(GLuint list
)
1832 WMesaShowStereo(list
);
1835 #endif // End if NO_STEREO not defined
1837 #if !defined(NO_PARALLEL)
1839 void toggleParallelMode(void)
1842 parallelFlag
= GL_TRUE
;
1843 if(parallelMachine
==GL_FALSE
){
1844 PRCreateRenderBuffer( Current
->rgb_flag
? GL_RGBA
:GL_COLOR_INDEX
,
1845 Current
->cColorBits
/8,
1846 Current
->width
,Current
->height
,
1848 Current
->rgb_flag
? Current
->pbPixels
: Current
->ScreenMem
);
1849 parallelMachine
= GL_TRUE
;
1853 parallelFlag
= GL_FALSE
;
1854 if(parallelMachine
==GL_TRUE
){
1855 PRDestroyRenderBuffer();
1856 parallelMachine
=GL_FALSE
;
1857 ReadyForNextFrame
= GL_TRUE
;
1860 /***********************************************
1861 // Seems something wrong!!!!
1862 ************************************************/
1864 WMesaMakeCurrent(Current
);
1865 #if !defined(NO_STEREO)
1866 stereo_flag
= GL_FALSE
;
1871 void PRShowRenderResult(void)
1874 if(!glImageRendered())
1883 #endif //End if NO_PARALLEL not defined
1887 BYTE
DITHER_RGB_2_8BIT( int red
, int green
, int blue
, int pixel
, int scanline
)
1889 char unsigned redtemp
, greentemp
, bluetemp
, paletteindex
;
1891 //*** now, look up each value in the halftone matrix
1892 //*** using an 8x8 ordered dither.
1893 redtemp
= aDividedBy51
[red
]
1894 + (aModulo51
[red
] > aHalftone8x8
[(pixel
%8)*8
1896 greentemp
= aDividedBy51
[(char unsigned)green
]
1897 + (aModulo51
[green
] > aHalftone8x8
[
1898 (pixel
%8)*8 + scanline
%8]);
1899 bluetemp
= aDividedBy51
[(char unsigned)blue
]
1900 + (aModulo51
[blue
] > aHalftone8x8
[
1901 (pixel
%8)*8 +scanline
%8]);
1903 //*** recombine the halftoned rgb values into a palette index
1905 redtemp
+ aTimes6
[greentemp
] + aTimes36
[bluetemp
];
1907 //*** and translate through the wing halftone palette
1908 //*** translation vector to give the correct value.
1909 return aWinGHalftoneTranslation
[paletteindex
];
1916 * restore all lost objects
1918 HRESULT
DDRestoreAll( WMesaContext wc
)
1922 ddrval
= wc
->lpDDSPrimary
->lpVtbl
->Restore(wc
->lpDDSPrimary
);
1923 if( ddrval
== DD_OK
)
1925 ddrval
= wc
->lpDDSOffScreen
->lpVtbl
->Restore(wc
->lpDDSOffScreen
);
1933 * This function is called if the initialization function fails
1935 BOOL
initFail( HWND hwnd
, WMesaContext wc
)
1938 MessageBox( hwnd
, "DirectDraw Init FAILED", "", MB_OK
);
1944 static void DDDeleteOffScreen(WMesaContext wc
)
1946 if( wc
->lpDDSOffScreen
!= NULL
)
1948 wc
->lpDDSOffScreen
->lpVtbl
->Unlock(wc
->lpDDSOffScreen
,NULL
);
1949 wc
->lpDDSOffScreen
->lpVtbl
->Release(wc
->lpDDSOffScreen
);
1950 wc
->lpDDSOffScreen
= NULL
;
1955 static void DDFreePrimarySurface(WMesaContext wc
)
1957 if( wc
->lpDDSPrimary
!= NULL
)
1959 if(wc
->db_flag
== GL_FALSE
)
1960 wc
->lpDDSPrimary
->lpVtbl
->ReleaseDC(wc
->lpDDSPrimary
, wc
->hDC
);
1961 wc
->lpDDSPrimary
->lpVtbl
->Release(wc
->lpDDSPrimary
);
1962 wc
->lpDDSPrimary
= NULL
;
1966 static BOOL
DDCreatePrimarySurface(WMesaContext wc
)
1970 wc
->ddsd
.dwSize
= sizeof( wc
->ddsd
);
1971 wc
->ddsd
.dwFlags
= DDSD_CAPS
;
1972 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
1974 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
,&(wc
->ddsd
), &(wc
->lpDDSPrimary
), NULL
);
1975 if( ddrval
!= DD_OK
)
1977 return initFail(wc
->hwnd
, wc
);
1979 if(wc
->db_flag
== GL_FALSE
)
1980 wc
->lpDDSPrimary
->lpVtbl
->GetDC(wc
->lpDDSPrimary
, wc
->hDC
);
1984 static BOOL
DDCreateOffScreen(WMesaContext wc
)
1988 if(wc
->lpDD
== NULL
)
1990 GetClientRect( wc
->hwnd
, &(wc
->rectOffScreen
) );
1991 wc
->ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1992 wc
->ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
1993 wc
->ddsd
.dwHeight
= wc
->rectOffScreen
.bottom
- wc
->rectOffScreen
.top
;
1994 wc
->ddsd
.dwWidth
= wc
->rectOffScreen
.right
- wc
->rectOffScreen
.left
;
1996 ddrval
= wc
->lpDD
->lpVtbl
->CreateSurface( wc
->lpDD
, &(wc
->ddsd
), &(wc
->lpDDSOffScreen
), NULL
);
1997 if( ddrval
!= DD_OK
)
2002 while (wc
->lpDDSOffScreen
->lpVtbl
->Lock(wc
->lpDDSOffScreen
,NULL
, &(wc
->ddsd
), 0, NULL
) == DDERR_WASSTILLDRAWING
)
2004 // while ((ddrval = wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, &(wc->ddsd), DDLOCK_SURFACEMEMORYPTR , NULL)) != DD_OK)
2006 if(wc
->ddsd
.lpSurface
==NULL
)
2007 return initFail(wc
->hwnd
, wc
);
2009 wc
->ScreenMem
= wc
->pbPixels
= wc
->addrOffScreen
= (PBYTE
)(wc
->ddsd
.lpSurface
);
2010 wc
->ScanWidth
= wc
->pitch
= wc
->ddsd
.lPitch
;
2012 wc
->ScanWidth
= wc
->ddsd
.lPitch
*2;
2014 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2016 ClientToScreen( wc
->hwnd
, &pt
);
2017 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2018 wmSetPixelFormat(wc
, wc
->hDC
);
2023 * doInit - do work required for every instance of the application:
2024 * create the window, initialize data
2026 static BOOL
DDInit( WMesaContext wc
, HWND hwnd
)
2031 LPDIRECTDRAW lpDD
; // DirectDraw object
2032 LPDIRECTDRAW2 lpDD2
;
2035 wc
->fullScreen
= displayOptions
.fullScreen
;
2036 wc
->gMode
= displayOptions
.mode
;
2038 stereo_flag
= displayOptions
.stereo
;
2039 if(wc
->db_flag
!= GL_TRUE
)
2040 stereo_flag
= GL_FALSE
;
2042 * create the main DirectDraw object
2044 ddrval
= DirectDrawCreate( NULL
, &(wc
->lpDD
), NULL
);
2045 if( ddrval
!= DD_OK
)
2047 return initFail(hwnd
,wc
);
2050 // Get exclusive mode if requested
2053 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2057 ddrval
= wc
->lpDD
->lpVtbl
->SetCooperativeLevel( wc
->lpDD
, hwnd
, DDSCL_NORMAL
);
2059 if( ddrval
!= DD_OK
)
2061 return initFail(hwnd
, wc
);
2065 /* ddrval = wc->lpDD->lpVtbl->QueryInterface(wc->lpDD, IID_IDirectDraw2,
2066 (LPVOID *)((wc->lpDD2)));
2070 return initFail(hwnd
, wc
);
2073 //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
2074 // wc->lpDD2->lpVtbl->GetMonitorFrequency(wc->lpDD, &dwFrequency);
2077 case 1: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 640, 480, displayOptions
.bpp
); break;
2078 case 2: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 800, 600, displayOptions
.bpp
); break;
2079 case 3: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1024, 768, displayOptions
.bpp
); break;
2080 case 4: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1152, 864, displayOptions
.bpp
); break;
2081 case 5: ddrval
= wc
->lpDD
->lpVtbl
->SetDisplayMode( wc
->lpDD
, 1280, 1024, displayOptions
.bpp
); break;
2084 if( ddrval
!= DD_OK
)
2086 printf("Can't modify display mode, current mode used\n");
2087 // return initFail(hwnd , wc);
2089 //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
2091 case DDERR_INVALIDOBJECT
:
2093 case DDERR_INVALIDPARAMS
:
2095 case DDERR_UNSUPPORTEDMODE
:
2099 if(DDCreatePrimarySurface(wc
) == GL_FALSE
)
2100 return initFail(hwnd
, wc
);
2103 return DDCreateOffScreen(wc
);
2106 static void DDFree( WMesaContext wc
)
2108 if( wc
->lpDD
!= NULL
)
2110 DDFreePrimarySurface(wc
);
2111 DDDeleteOffScreen(wc
);
2112 wc
->lpDD
->lpVtbl
->Release(wc
->lpDD
);
2115 // Clean up the screen on exit
2116 RedrawWindow( NULL
, NULL
, NULL
, RDW_INVALIDATE
| RDW_ERASE
|
2122 void WMesaMove(void)
2124 WMesaContext wc
= Current
;
2126 if (Current
!= NULL
){
2127 GetClientRect( wc
->hwnd
, &(wc
->rectSurface
) );
2129 ClientToScreen( wc
->hwnd
, &pt
);
2130 OffsetRect(&(wc
->rectSurface
), pt
.x
, pt
.y
);
2137 * Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable
2140 #define PACK_8B8G8R( R, G, B ) ( ((B) << 16) | ((G) << 8) | (R) )
2143 /**********************************************************************/
2144 /*** Triangle rendering ***/
2145 /**********************************************************************/
2148 * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
2150 static void smooth_8A8B8G8R_z_triangle( GLcontext
*ctx
,
2151 GLuint v0
, GLuint v1
, GLuint v2
,
2154 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2156 #define INTERP_RGB 1
2157 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2158 #define PIXEL_TYPE GLuint
2159 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2160 #define BYTES_PER_ROW (wmesa->ScanWidth)
2161 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2163 GLint i, len = RIGHT-LEFT; \
2164 for (i=0;i<len;i++) { \
2165 GLdepth z = FixedToDepth(ffz); \
2166 if (z < zRow[i]) { \
2167 pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2168 FixedToInt(ffb) ); \
2171 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2177 #include "tritemp.h"
2181 #include "..\tritemp.h"
2183 #include "tritemp.h"
2190 * XImage, smooth, depth-buffered, PF_8R8G8B triangle.
2192 static void smooth_8R8G8B_z_triangle( GLcontext
*ctx
,
2193 GLuint v0
, GLuint v1
, GLuint v2
,
2196 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2198 #define INTERP_RGB 1
2199 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2200 #define PIXEL_TYPE GLuint
2201 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2202 #define BYTES_PER_ROW (wmesa->ScanWidth)
2203 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2205 GLint i, len = RIGHT-LEFT; \
2206 for (i=0;i<len;i++) { \
2207 GLdepth z = FixedToDepth(ffz); \
2208 if (z < zRow[i]) { \
2209 pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2210 FixedToInt(ffb) ); \
2213 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2218 #include "tritemp.h"
2222 #include "..\tritemp.h"
2224 #include "tritemp.h"
2232 * XImage, smooth, depth-buffered, PF_5R6G5B triangle.
2234 static void smooth_5R6G5B_z_triangle( GLcontext
*ctx
,
2235 GLuint v0
, GLuint v1
, GLuint v2
,
2238 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2240 #define INTERP_RGB 1
2241 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2242 #define PIXEL_TYPE GLushort
2243 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2244 #define BYTES_PER_ROW (wmesa->ScanWidth)
2245 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2247 GLint i, len = RIGHT-LEFT; \
2248 for (i=0;i<len;i++) { \
2249 GLdepth z = FixedToDepth(ffz); \
2250 if (z < zRow[i]) { \
2251 pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2252 FixedToInt(ffb) ); \
2255 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2260 #include "tritemp.h"
2264 #include "..\tritemp.h"
2266 #include "tritemp.h"
2272 * XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
2274 static void flat_8A8B8G8R_z_triangle( GLcontext
*ctx
, GLuint v0
,
2275 GLuint v1
, GLuint v2
, GLuint pv
)
2277 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2279 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2280 #define PIXEL_TYPE GLuint
2281 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2282 #define BYTES_PER_ROW (wmesa->ScanWidth)
2283 #define SETUP_CODE \
2284 unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \
2285 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2286 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2288 GLint i, len = RIGHT-LEFT; \
2289 for (i=0;i<len;i++) { \
2290 GLdepth z = FixedToDepth(ffz); \
2291 if (z < zRow[i]) { \
2299 #include "tritemp.h"
2303 #include "..\tritemp.h"
2305 #include "tritemp.h"
2312 * XImage, flat, depth-buffered, PF_8R8G8B triangle.
2314 static void flat_8R8G8B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2315 GLuint v2
, GLuint pv
)
2317 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2319 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2320 #define PIXEL_TYPE GLuint
2321 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2322 #define BYTES_PER_ROW (wmesa->ScanWidth)
2323 #define SETUP_CODE \
2324 unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \
2325 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2326 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2328 GLint i, len = RIGHT-LEFT; \
2329 for (i=0;i<len;i++) { \
2330 GLdepth z = FixedToDepth(ffz); \
2331 if (z < zRow[i]) { \
2339 #include "tritemp.h"
2343 #include "..\tritemp.h"
2345 #include "tritemp.h"
2352 * XImage, flat, depth-buffered, PF_5R6G5B triangle.
2354 static void flat_5R6G5B_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2355 GLuint v2
, GLuint pv
)
2357 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2359 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2360 #define PIXEL_TYPE GLushort
2361 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2362 #define BYTES_PER_ROW (wmesa->ScanWidth)
2363 #define SETUP_CODE \
2364 unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \
2365 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2366 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2368 GLint i, len = RIGHT-LEFT; \
2369 for (i=0;i<len;i++) { \
2370 GLdepth z = FixedToDepth(ffz); \
2371 if (z < zRow[i]) { \
2379 #include "tritemp.h"
2383 #include "..\tritemp.h"
2385 #include "tritemp.h"
2392 * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
2394 static void smooth_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2395 GLuint v2
, GLuint pv
)
2397 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2398 #define INTERP_RGB 1
2399 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2400 #define PIXEL_TYPE GLuint
2401 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2402 #define BYTES_PER_ROW (wmesa->ScanWidth)
2403 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2406 PIXEL_TYPE *pixel = pRow; \
2407 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2408 *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2409 FixedToInt(ffb) ); \
2410 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2414 #include "tritemp.h"
2418 #include "..\tritemp.h"
2420 #include "tritemp.h"
2427 * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
2429 static void smooth_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2430 GLuint v2
, GLuint pv
)
2432 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2433 #define INTERP_RGB 1
2434 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2435 #define PIXEL_TYPE GLuint
2436 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2437 #define BYTES_PER_ROW (wmesa->ScanWidth)
2438 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2441 PIXEL_TYPE *pixel = pRow; \
2442 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2443 *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2444 FixedToInt(ffb) ); \
2445 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2449 #include "tritemp.h"
2453 #include "..\tritemp.h"
2455 #include "tritemp.h"
2462 * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
2464 static void smooth_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2465 GLuint v2
, GLuint pv
)
2467 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2468 #define INTERP_RGB 1
2469 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2470 #define PIXEL_TYPE GLushort
2471 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2472 #define BYTES_PER_ROW (wmesa->ScanWidth)
2473 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2476 PIXEL_TYPE *pixel = pRow; \
2477 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2478 *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2479 FixedToInt(ffb) ); \
2480 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2484 #include "tritemp.h"
2488 #include "..\tritemp.h"
2490 #include "tritemp.h"
2498 * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
2500 static void flat_8A8B8G8R_triangle( GLcontext
*ctx
, GLuint v0
,
2501 GLuint v1
, GLuint v2
, GLuint pv
)
2503 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2504 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2505 #define PIXEL_TYPE GLuint
2506 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2507 #define BYTES_PER_ROW (wmesa->ScanWidth)
2508 #define SETUP_CODE \
2509 unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \
2510 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2511 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2514 PIXEL_TYPE *pixel = pRow; \
2515 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2521 #include "tritemp.h"
2525 #include "..\tritemp.h"
2527 #include "tritemp.h"
2534 * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
2536 static void flat_8R8G8B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2537 GLuint v2
, GLuint pv
)
2539 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2540 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2541 #define PIXEL_TYPE GLuint
2542 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2543 #define BYTES_PER_ROW (wmesa->ScanWidth)
2544 #define SETUP_CODE \
2545 unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \
2546 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2547 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2550 PIXEL_TYPE *pixel = pRow; \
2551 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2556 #include "tritemp.h"
2560 #include "..\tritemp.h"
2562 #include "tritemp.h"
2569 * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
2571 static void flat_5R6G5B_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2572 GLuint v2
, GLuint pv
)
2574 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2575 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2576 #define PIXEL_TYPE GLushort
2577 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2578 #define BYTES_PER_ROW (wmesa->ScanWidth)
2579 #define SETUP_CODE \
2580 unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \
2581 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2582 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2585 PIXEL_TYPE *pixel = pRow; \
2586 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2591 #include "tritemp.h"
2595 #include "..\tritemp.h"
2597 #include "tritemp.h"
2604 * XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
2607 static void smooth_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2608 GLuint v2
, GLuint pv
)
2610 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2612 #define INTERP_INDEX 1
2613 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2614 #define PIXEL_TYPE GLubyte
2615 #define BYTES_PER_ROW (wmesa->ScanWidth)
2616 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2618 GLint i, len = RIGHT-LEFT; \
2619 for (i=0;i<len;i++) { \
2620 GLdepth z = FixedToDepth(ffz); \
2621 if (z < zRow[i]) { \
2622 pRow[i] = FixedToInt(ffi); \
2630 #include "tritemp.h"
2634 #include "..\tritemp.h"
2636 #include "tritemp.h"
2643 * XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
2646 static void flat_ci_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2647 GLuint v2
, GLuint pv
)
2649 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2651 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2652 #define PIXEL_TYPE GLubyte
2653 #define BYTES_PER_ROW (wmesa->ScanWidth)
2654 #define SETUP_CODE \
2655 GLuint index = VB->IndexPtr->data[pv]; \
2656 (*ctx->Driver.Index)( ctx, index );
2657 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2659 GLint i, len = RIGHT-LEFT; \
2660 for (i=0;i<len;i++) { \
2661 GLdepth z = FixedToDepth(ffz); \
2662 if (z < zRow[i]) { \
2670 #include "tritemp.h"
2674 #include "..\tritemp.h"
2676 #include "tritemp.h"
2684 * XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2687 static void smooth_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2688 GLuint v2
, GLuint pv
)
2690 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2692 #define INTERP_INDEX 1
2693 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2694 #define PIXEL_TYPE GLubyte
2695 #define BYTES_PER_ROW (wmesa->ScanWidth)
2696 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2699 PIXEL_TYPE *pixel = pRow; \
2700 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2701 *pixel = FixedToInt(ffi); \
2706 #include "tritemp.h"
2710 #include "..\tritemp.h"
2712 #include "tritemp.h"
2719 * XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2721 static void flat_ci_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2722 GLuint v2
, GLuint pv
)
2724 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2726 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2727 #define PIXEL_TYPE GLubyte
2728 #define BYTES_PER_ROW (wmesa->ScanWidth)
2729 #define SETUP_CODE \
2730 GLuint index = VB->IndexPtr->data[pv]; \
2731 (*ctx->Driver.Index)( ctx, index );
2732 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2735 PIXEL_TYPE *pixel = pRow; \
2736 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2741 #include "tritemp.h"
2745 #include "..\tritemp.h"
2747 #include "tritemp.h"
2753 * XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
2755 static void smooth_DITHER8_z_triangle( GLcontext
*ctx
,
2756 GLuint v0
, GLuint v1
, GLuint v2
,
2759 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2760 DITHER_RGB_TO_8BIT_SETUP
2762 #define INTERP_RGB 1
2763 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2764 #define PIXEL_TYPE GLubyte
2765 #define BYTES_PER_ROW (wmesa->ScanWidth)
2766 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2768 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
2769 for (i=0;i<len;i++,xx++) { \
2770 GLdepth z = FixedToDepth(ffz); \
2771 if (z < zRow[i]) { \
2772 DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg), \
2773 FixedToInt(ffb), xx, yy); \
2774 pRow[i] = pixelDithered; \
2777 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2782 #include "tritemp.h"
2786 #include "..\tritemp.h"
2788 #include "tritemp.h"
2794 * XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
2796 static void flat_DITHER8_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2797 GLuint v2
, GLuint pv
)
2799 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2800 DITHER_RGB_TO_8BIT_SETUP
2802 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2803 #define PIXEL_TYPE GLubyte
2804 #define BYTES_PER_ROW (wmesa->ScanWidth)
2806 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2808 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
2809 for (i=0;i<len;i++,xx++) { \
2810 GLdepth z = FixedToDepth(ffz); \
2811 if (z < zRow[i]) { \
2812 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \
2813 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \
2814 pRow[i] = pixelDithered; \
2821 #include "tritemp.h"
2825 #include "..\tritemp.h"
2827 #include "tritemp.h"
2833 * XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
2835 static void smooth_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2836 GLuint v2
, GLuint pv
)
2838 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2839 DITHER_RGB_TO_8BIT_SETUP
2840 #define INTERP_RGB 1
2841 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2842 #define PIXEL_TYPE GLubyte
2843 #define BYTES_PER_ROW (wmesa->ScanWidth)
2844 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2846 GLint xx, yy = FLIP(Y); \
2847 PIXEL_TYPE *pixel = pRow; \
2848 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2849 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy);\
2850 *pixel = pixelDithered; \
2851 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2855 #include "tritemp.h"
2859 #include "..\tritemp.h"
2861 #include "tritemp.h"
2867 * XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
2870 static void flat_DITHER8_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
2871 GLuint v2
, GLuint pv
)
2873 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2874 DITHER_RGB_TO_8BIT_SETUP
2875 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2876 #define PIXEL_TYPE GLubyte
2877 #define BYTES_PER_ROW (wmesa->ScanWidth)
2879 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2881 GLint xx, yy = FLIP(Y); \
2882 PIXEL_TYPE *pixel = pRow; \
2883 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2884 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \
2885 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \
2886 *pixel = pixelDithered; \
2890 #include "tritemp.h"
2894 #include "..\tritemp.h"
2896 #include "tritemp.h"
2904 static triangle_func
choose_triangle_function( GLcontext
*ctx
)
2906 WMesaContext wmesa
= (WMesaContext
) ctx
->DriverCtx
;
2907 int depth
= wmesa
->cColorBits
;
2909 if (ctx
->Polygon
.SmoothFlag
) return NULL
;
2910 if (ctx
->Texture
.Enabled
) return NULL
;
2911 if (!wmesa
->db_flag
) return NULL
;
2912 /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {
2913 if ( ctx
->Light
.ShadeModel
==GL_SMOOTH
2914 && ctx
->RasterMask
==DEPTH_BIT
2915 && ctx
->Depth
.Func
==GL_LESS
2916 && ctx
->Depth
.Mask
==GL_TRUE
2917 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2918 switch (wmesa
->pixelformat
) {
2920 return smooth_8A8B8G8R_z_triangle
;
2922 return smooth_8R8G8B_z_triangle
;
2924 return smooth_5R6G5B_z_triangle
;
2926 return smooth_DITHER8_z_triangle
;
2928 return smooth_ci_z_triangle
;
2933 if ( ctx
->Light
.ShadeModel
==GL_FLAT
2934 && ctx
->RasterMask
==DEPTH_BIT
2935 && ctx
->Depth
.Func
==GL_LESS
2936 && ctx
->Depth
.Mask
==GL_TRUE
2937 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2938 switch (wmesa
->pixelformat
) {
2940 return flat_8A8B8G8R_z_triangle
;
2942 return flat_8R8G8B_z_triangle
;
2944 return flat_5R6G5B_z_triangle
;
2946 return flat_DITHER8_z_triangle
;
2948 return flat_ci_z_triangle
;
2953 if ( ctx
->RasterMask
==0 /* no depth test */
2954 && ctx
->Light
.ShadeModel
==GL_SMOOTH
2955 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2956 switch (wmesa
->pixelformat
) {
2958 return smooth_8A8B8G8R_triangle
;
2960 return smooth_8R8G8B_triangle
;
2962 return smooth_5R6G5B_triangle
;
2964 return smooth_DITHER8_triangle
;
2966 return smooth_ci_triangle
;
2972 if ( ctx
->RasterMask
==0 /* no depth test */
2973 && ctx
->Light
.ShadeModel
==GL_FLAT
2974 && ctx
->Polygon
.StippleFlag
==GL_FALSE
) {
2975 switch (wmesa
->pixelformat
) {
2977 return flat_8A8B8G8R_triangle
;
2979 return flat_8R8G8B_triangle
;
2981 return flat_5R6G5B_triangle
;
2983 return flat_DITHER8_triangle
;
2985 return flat_ci_triangle
;
2996 * Define a new viewport and reallocate auxillary buffers if the size of
2997 * the window (color buffer) has changed.
2999 void WMesaViewport( GLcontext
*ctx
,
3000 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
3003 ctx
->Viewport
.X
= x
;
3004 ctx
->Viewport
.Width
= width
;
3005 ctx
->Viewport
.Y
= y
;
3006 ctx
->Viewport
.Height
= height
;
3008 /* compute scale and bias values */
3009 /* Pre-Keith 3.1 changes
3010 ctx->Viewport.Map.m[Sx] = (GLfloat) width / 2.0F;
3011 ctx->Viewport.Map.m[Tx] = ctx->Viewport.Sx + x;
3012 ctx->Viewport.Map.m[Sy] = (GLfloat) height / 2.0F;
3013 ctx->Viewport.Map.m[Ty] = ctx->Viewport.Sy + y;
3015 ctx
->Viewport
.WindowMap
.m
[MAT_SX
] = (GLfloat
) width
/ 2.0F
;
3016 ctx
->Viewport
.WindowMap
.m
[MAT_TX
] = ctx
->Viewport
.WindowMap
.m
[MAT_SX
] + x
;
3017 ctx
->Viewport
.WindowMap
.m
[MAT_SY
] = (GLfloat
) height
/ 2.0F
;
3018 ctx
->Viewport
.WindowMap
.m
[MAT_TY
] = ctx
->Viewport
.WindowMap
.m
[MAT_SY
] + y
;