Updates for improved DirectDraw support (Daniel Slater)
[mesa.git] / src / mesa / drivers / windows / wmesa.c
1 /* $Id: wmesa.c,v 1.23 2001/11/01 22:44:47 kschultz Exp $ */
2
3 /*
4 * Windows (Win32) device driver for Mesa 3.4
5 *
6 * Original author:
7 *
8 * Copyright (C) 1996- Li Wei
9 * Address : Institute of Artificial Intelligence
10 * : & Robotics
11 * : Xi'an Jiaotong University
12 * Email : liwei@aiar.xjtu.edu.cn
13 * Web page : http://sun.aiar.xjtu.edu.cn
14 *
15 * This file and its associations are partially borrowed from the
16 * Windows NT driver for Mesa 1.8 , written by Mark Leaming
17 * (mark@rsinc.com).
18 *
19 * Updated for Mesa 4.0 by Karl Schultz (kschultz@sourceforge.net)
20 */
21
22 #ifdef NDEBUG
23 #pragma auto_inline(on)
24 #pragma inline_depth(255)
25 #pragma inline_recursion(on)
26 #endif
27
28 #include "wmesadef.h"
29 #include <GL/wmesa.h>
30 #include "mesa_extend.h"
31
32 #include "glheader.h"
33 #include "colors.h"
34 #include "context.h"
35 #include "colormac.h"
36 #include "dd.h"
37 #include "depth.h"
38 #include "extensions.h"
39 #include "macros.h"
40 #include "matrix.h"
41 #include "mem.h"
42 #include "mmath.h"
43 #include "mtypes.h"
44 #include "texformat.h"
45 #include "texstore.h"
46 #include "array_cache/acache.h"
47 #include "swrast/swrast.h"
48 #include "swrast_setup/swrast_setup.h"
49 #include "swrast/s_context.h"
50 #include "swrast/s_depth.h"
51 #include "swrast/s_lines.h"
52 #include "swrast/s_triangle.h"
53 #include "swrast/s_trispan.h"
54 #include "tnl/tnl.h"
55 #include "tnl/t_context.h"
56 #include "tnl/t_pipeline.h"
57
58 /* Dither not tested for Mesa 4.0 */
59 #ifdef DITHER
60 #ifdef USE_WING
61 #include <wing.h>
62 #endif // USE_WING
63 #endif
64
65 #ifdef __CYGWIN32__
66 #include "macros.h"
67 #include <string.h>
68 #define CopyMemory memcpy
69 #endif
70
71 /* Stereo and parallel not tested for Mesa 4.0. */
72 #if !defined(NO_STEREO)
73 #include "gl\glu.h"
74 #include "stereo.h"
75 #endif
76
77 #if !defined(NO_PARALLEL)
78 #include "parallel.h"
79 #endif
80
81
82 /* File global varaibles */
83 struct DISPLAY_OPTIONS displayOptions =
84 {
85 0, // stereo
86 0, // fullScreen
87 0, // full screen mode (1,2,3,4)
88 0 // bpp (8,16,24,32)
89 };
90 GLenum stereoCompile = GL_FALSE ;
91 GLenum stereoShowing = GL_FALSE ;
92 GLenum stereoBuffer = GL_FALSE;
93 #if !defined(NO_STEREO)
94 GLint displayList = MAXIMUM_DISPLAY_LIST ;
95 #endif
96 GLint stereo_flag = 0 ;
97
98 static PWMC Current = NULL;
99 WMesaContext WC = NULL;
100
101 #ifdef COMPILE_SETPIXEL
102
103 __forceinline void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
104 {
105 pwc->wmSetPixel(pwc,iScanLine,iPixel,r,g,b);
106 }
107
108 void ChooseSetPixel(PWMC pwc);
109
110 #endif // COMPILE_SETPIXEL
111
112 /* If we are double-buffering, we want to get the DC for the
113 * off-screen DIB, otherwise the DC for the window.
114 */
115 #define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
116 #define DD_RELEASEDC
117
118 #define FLIP(Y) (Current->height-(Y)-1)
119
120 #define DITHER_RGB_TO_8BIT_SETUP \
121 GLubyte pixelDithered;
122
123 #define DITHER_RGB_TO_8BIT(red, green, blue, pixel, scanline) \
124 { \
125 char unsigned redtemp, greentemp, bluetemp, paletteindex; \
126 redtemp = aDividedBy51[red] \
127 + (aModulo51[red] > aHalftone8x8[(pixel%8)*8 \
128 + scanline%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]; \
137 }
138
139 #ifdef DDRAW
140 static BOOL DDInit( WMesaContext wc, HWND hwnd);
141 static void DDFree( WMesaContext wc);
142 static HRESULT DDRestoreAll( WMesaContext wc );
143 static void DDDeleteOffScreen(WMesaContext wc);
144 static BOOL DDCreateOffScreen(WMesaContext wc);
145
146 // define this to use the GDI Rectangle call to
147 // clear the back buffer. Otherwise will manually
148 // set the pixels. On an NVidia GEForce 2MX under Windows XP
149 // and DirectX 8 , defining this makes apps run much much faster
150 #define USE_GDI_TO_CLEAR 1
151 #endif
152
153 static void FlushToFile(PWMC pwc, PSTR szFile);
154 BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize);
155 BOOL wmDeleteBackingStore(PWMC pwc);
156 void wmCreatePalette( PWMC pwdc );
157 BOOL wmSetDibColors(PWMC pwc);
158 void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b);
159 BOOL wmFlush(PWMC pwc);
160 void wmCreateDIBSection(
161 HDC hDC,
162 PWMC pwc, // handle of device context
163 CONST BITMAPINFO *pbmi, // bitmap size, format, and color data
164 UINT iUsage // color data type indicator: RGB values or palette indices
165 );
166 void WMesaViewport( GLcontext *ctx,
167 GLint x, GLint y, GLsizei width, GLsizei height );
168
169
170 static void wmSetPixelFormat( PWMC wc, HDC hDC)
171 {
172 if(wc->rgb_flag)
173 wc->cColorBits = GetDeviceCaps(hDC, BITSPIXEL);
174 else
175 wc->cColorBits = 8;
176 switch(wc->cColorBits){
177 case 8:
178 if(wc->dither_flag != GL_TRUE)
179 wc->pixelformat = PF_INDEX8;
180 else
181 wc->pixelformat = PF_DITHER8;
182 break;
183 case 16:
184 wc->pixelformat = PF_5R6G5B;
185 break;
186 case 32:
187 wc->pixelformat = PF_8R8G8B;
188 break;
189 default:
190 wc->pixelformat = PF_BADFORMAT;
191 }
192 }
193
194
195 /* This function sets the color table of a DIB section
196 * to match that of the destination DC
197 */
198 BOOL wmSetDibColors(PWMC pwc)
199 {
200 RGBQUAD *pColTab, *pRGB;
201 PALETTEENTRY *pPal, *pPE;
202 int i, nColors;
203 BOOL bRet=TRUE;
204 DWORD dwErr=0;
205
206 /* Build a color table in the DIB that maps to the
207 * selected palette in the DC.
208 */
209 nColors = 1 << pwc->cColorBits;
210 pPal = (PALETTEENTRY *)malloc( nColors * sizeof(PALETTEENTRY));
211 memset( pPal, 0, nColors * sizeof(PALETTEENTRY) );
212 GetPaletteEntries( pwc->hGLPalette, 0, nColors, pPal );
213 pColTab = (RGBQUAD *)malloc( nColors * sizeof(RGBQUAD));
214 for (i = 0, pRGB = pColTab, pPE = pPal; i < nColors; i++, pRGB++, pPE++) {
215 pRGB->rgbRed = pPE->peRed;
216 pRGB->rgbGreen = pPE->peGreen;
217 pRGB->rgbBlue = pPE->peBlue;
218 }
219 if(pwc->db_flag)
220 bRet = SetDIBColorTable(pwc->dib.hDC, 0, nColors, pColTab );
221
222 if(!bRet)
223 dwErr = GetLastError();
224
225 free( pColTab );
226 free( pPal );
227
228 return bRet;
229 }
230
231
232 /*
233 * Free up the dib section that was created
234 */
235 BOOL wmDeleteBackingStore(PWMC pwc)
236 {
237 SelectObject(pwc->dib.hDC, pwc->hOldBitmap);
238 DeleteDC(pwc->dib.hDC);
239 DeleteObject(pwc->hbmDIB);
240 #ifdef USE_MAPPED_FILE
241 UnmapViewOfFile(pwc->dib.base);
242 CloseHandle(pwc->dib.hFileMap);
243 #endif
244 return TRUE;
245 }
246
247
248 /*
249 * This function creates the DIB section that is used for combined
250 * GL and GDI calls
251 */
252 BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize)
253 {
254 HDC hdc = pwc->hDC;
255 LPBITMAPINFO pbmi = &(pwc->bmi);
256 int iUsage;
257
258 pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
259 pbmi->bmiHeader.biWidth = lxSize;
260 pbmi->bmiHeader.biHeight= -lySize;
261 pbmi->bmiHeader.biPlanes = 1;
262 if(pwc->rgb_flag)
263 pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwc->hDC, BITSPIXEL);
264 else
265 pbmi->bmiHeader.biBitCount = 8;
266 pbmi->bmiHeader.biCompression = BI_RGB;
267 pbmi->bmiHeader.biSizeImage = 0;
268 pbmi->bmiHeader.biXPelsPerMeter = 0;
269 pbmi->bmiHeader.biYPelsPerMeter = 0;
270 pbmi->bmiHeader.biClrUsed = 0;
271 pbmi->bmiHeader.biClrImportant = 0;
272
273 iUsage = (pbmi->bmiHeader.biBitCount <= 8) ? DIB_PAL_COLORS : DIB_RGB_COLORS;
274
275 pwc->cColorBits = pbmi->bmiHeader.biBitCount;
276 pwc->ScanWidth = pwc->pitch = lxSize;
277
278 wmCreateDIBSection(hdc, pwc, pbmi, iUsage);
279
280 if ((iUsage == DIB_PAL_COLORS) && !(pwc->hGLPalette)) {
281 wmCreatePalette( pwc );
282 wmSetDibColors( pwc );
283 }
284 wmSetPixelFormat(pwc, pwc->hDC);
285 return TRUE;
286 }
287
288 #if 0
289 // D.R.S. 10/30/01 - this function is never referenced
290 /*
291 * This function copies one scan line in a DIB section to another
292 */
293 BOOL wmSetDIBits(PWMC pwc, UINT uiScanWidth, UINT uiNumScans,
294 UINT nBypp, UINT uiNewWidth, LPBYTE pBits)
295 {
296 UINT uiScans = 0;
297 LPBYTE pDest = pwc->pbPixels;
298 DWORD dwNextScan = uiScanWidth;
299 DWORD dwNewScan = uiNewWidth;
300 DWORD dwScanWidth = (uiScanWidth * nBypp);
301
302 /*
303 * We need to round up to the nearest DWORD
304 * and multiply by the number of bytes per
305 * pixel
306 */
307 dwNextScan = (((dwNextScan * nBypp)+ 3) & ~3);
308 dwNewScan = (((dwNewScan * nBypp)+ 3) & ~3);
309
310 for(uiScans = 0; uiScans < uiNumScans; uiScans++){
311 CopyMemory(pDest, pBits, dwScanWidth);
312 pBits += dwNextScan;
313 pDest += dwNewScan;
314 }
315 return TRUE;
316 }
317 #endif // 0
318
319 #if defined(FAST_RASTERIZERS)
320
321 #define PIXELADDR(X,Y) \
322 ((GLubyte *)Current->pbPixels + (Current->height-Y-1)* \
323 Current->ScanWidth + (X)*nBypp)
324 #define PIXELADDR1( X, Y ) \
325 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X))
326 #define PIXELADDR2( X, Y ) \
327 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*2)
328 #define PIXELADDR4( X, Y ) \
329 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*4)
330
331 #endif // 0
332
333 BYTE DITHER_RGB_2_8BIT( int r, int g, int b, int x, int y);
334
335 /* Finish all pending operations and synchronize. */
336 static void finish(GLcontext* ctx)
337 {
338 /* No op */
339 }
340
341
342 static void flush(GLcontext* ctx)
343 {
344 if((Current->rgb_flag &&!(Current->db_flag))
345 ||(!Current->rgb_flag))
346 {
347 wmFlush(Current);
348 }
349
350 }
351
352
353
354 /*
355 * Set the color index used to clear the color buffer.
356 */
357 static void clear_index(GLcontext* ctx, GLuint index)
358 {
359 Current->clearpixel = index;
360 }
361
362
363
364 /*
365 * Set the color used to clear the color buffer.
366 */
367 static void clear_color( GLcontext* ctx, const GLchan color[4] )
368 {
369 Current->clearpixel = RGB(color[0], color[1], color[2]);
370 }
371
372
373
374 /*
375 * Clear the specified region of the color buffer using the clear color
376 * or index as specified by one of the two functions above.
377 *
378 * This procedure clears either the front and/or the back COLOR buffers.
379 * Only the "left" buffer is cleared since we are not stereo.
380 * Clearing of the other non-color buffers is left to the swrast.
381 * We also only clear the color buffers if the color masks are all 1's.
382 * Otherwise, we let swrast do it.
383 */
384
385 static clear(GLcontext* ctx, GLbitfield mask,
386 GLboolean all, GLint x, GLint y, GLint width, GLint height)
387 {
388 const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask;
389
390 if (all){
391 x=y=0;
392 width=Current->width;
393 height=Current->height;
394 }
395
396
397 /* sanity check - can't have right(stereo) buffers */
398 assert((mask & (DD_FRONT_RIGHT_BIT | DD_BACK_RIGHT_BIT)) == 0);
399
400 if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) {
401 if (mask & DD_BACK_LEFT_BIT) {
402 #if defined(USE_GDI_TO_CLEAR)
403 #if defined(DDRAW)
404 // D.R.S. 10/29/01 on my system (Pentium 4 with nvidia GeForce2 MX card,
405 // this is almose 100 times faster that the code below
406 HDC DC=NULL;
407 HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);
408 HBRUSH Brush=CreateSolidBrush(Current->clearpixel);
409 HPEN Old_Pen=NULL;
410 HBRUSH Old_Brush=NULL;
411 Current->lpDDSOffScreen->lpVtbl->Unlock(Current->lpDDSOffScreen,NULL);
412 Current->lpDDSOffScreen->lpVtbl->GetDC(Current->lpDDSOffScreen,&DC);
413 Old_Pen=SelectObject(DC,Pen);
414 Old_Brush=SelectObject(DC,Brush);
415 Rectangle(DC,x,y,x+width,y+height);
416 SelectObject(DC,Old_Pen);
417 SelectObject(DC,Old_Brush);
418 DeleteObject(Pen);
419 DeleteObject(Brush);
420 Current->lpDDSOffScreen->lpVtbl->ReleaseDC(Current->lpDDSOffScreen,DC);
421 while (Current->lpDDSOffScreen->lpVtbl->Lock(Current->lpDDSOffScreen,NULL, &(Current->ddsd), 0, NULL) == DDERR_WASSTILLDRAWING);
422 mask &= ~DD_BACK_LEFT_BIT;
423 #else
424 /* single-buffer */
425 HDC DC=DD_GETDC;
426 HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);
427 HBRUSH Brush=CreateSolidBrush(Current->clearpixel);
428 HPEN Old_Pen=SelectObject(DC,Pen);
429 HBRUSH Old_Brush=SelectObject(DC,Brush);
430 Rectangle(DC,x+Current->rectSurface.left,Current->rectSurface.top+y,x+width+Current->rectSurface.left,y+height+Current->rectSurface.top);
431 SelectObject(DC,Old_Pen);
432 SelectObject(DC,Old_Brush);
433 DeleteObject(Pen);
434 DeleteObject(Brush);
435 DD_RELEASEDC;
436 mask &= ~DD_BACK_LEFT_BIT;
437 #endif // DDRAW
438 #else
439 DWORD dwColor;
440 WORD wColor;
441 BYTE bColor;
442 LPDWORD lpdw = (LPDWORD)Current->pbPixels;
443 LPWORD lpw = (LPWORD)Current->pbPixels;
444 LPBYTE lpb = Current->pbPixels;
445 int lines;
446 /* Double-buffering - clear back buffer */
447 UINT nBypp = Current->cColorBits / 8;
448 int i = 0;
449 int iSize = 0;
450
451 assert(Current->db_flag==GL_TRUE); /* we'd better be double buffer */
452 if(nBypp ==1 ){
453 iSize = Current->width/4;
454 bColor = BGR8(GetRValue(Current->clearpixel),
455 GetGValue(Current->clearpixel),
456 GetBValue(Current->clearpixel));
457 wColor = MAKEWORD(bColor,bColor);
458 dwColor = MAKELONG(wColor, wColor);
459 }
460 if(nBypp == 2){
461 iSize = Current->width / 2;
462 wColor = BGR16(GetRValue(Current->clearpixel),
463 GetGValue(Current->clearpixel),
464 GetBValue(Current->clearpixel));
465 dwColor = MAKELONG(wColor, wColor);
466 }
467 else if(nBypp == 4){
468 iSize = Current->width;
469 dwColor = BGR32(GetRValue(Current->clearpixel),
470 GetGValue(Current->clearpixel),
471 GetBValue(Current->clearpixel));
472 }
473
474 /* clear a line */
475 while(i < iSize){
476 *lpdw = dwColor;
477 lpdw++;
478 i++;
479 }
480
481 /* This is the 24bit case */
482 if (nBypp == 3) {
483 iSize = Current->width *3/4;
484 dwColor = BGR24(GetRValue(Current->clearpixel),
485 GetGValue(Current->clearpixel),
486 GetBValue(Current->clearpixel));
487 while(i < iSize){
488 *lpdw = dwColor;
489 lpb += nBypp;
490 lpdw = (LPDWORD)lpb;
491 i++;
492 }
493 }
494
495 i = 0;
496 if (stereo_flag)
497 lines = height /2;
498 else
499 lines = height;
500 /* copy cleared line to other lines in buffer */
501 do {
502 memcpy(lpb, Current->pbPixels, iSize*4);
503 lpb += Current->ScanWidth;
504 i++;
505 }
506 while (i<lines-1);
507 mask &= ~DD_BACK_LEFT_BIT;
508 #endif // defined(USE_GDI_TO_CLEAR)
509 } /* double-buffer */
510
511 if (mask & DD_FRONT_LEFT_BIT) {
512 /* single-buffer */
513 HDC DC=DD_GETDC;
514 HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);
515 HBRUSH Brush=CreateSolidBrush(Current->clearpixel);
516 HPEN Old_Pen=SelectObject(DC,Pen);
517 HBRUSH Old_Brush=SelectObject(DC,Brush);
518 Rectangle(DC,x+Current->rectSurface.left,Current->rectSurface.top+y,x+width+Current->rectSurface.left,y+height+Current->rectSurface.top);
519 SelectObject(DC,Old_Pen);
520 SelectObject(DC,Old_Brush);
521 DeleteObject(Pen);
522 DeleteObject(Brush);
523 DD_RELEASEDC;
524 mask &= ~DD_FRONT_LEFT_BIT;
525 } /* single-buffer */
526 } /* if masks are all 1's */
527
528 /* Call swrast if there is anything left to clear (like DEPTH) */
529 if (mask)
530 _swrast_Clear( ctx, mask, all, x, y, width, height );
531 }
532
533
534
535 static void enable( GLcontext* ctx, GLenum pname, GLboolean enable )
536 {
537 if (!Current)
538 return;
539
540 if (pname == GL_DITHER) {
541 if(enable == GL_FALSE){
542 Current->dither_flag = GL_FALSE;
543 if(Current->cColorBits == 8)
544 Current->pixelformat = PF_INDEX8;
545 }
546 else{
547 if (Current->rgb_flag && Current->cColorBits == 8){
548 Current->pixelformat = PF_DITHER8;
549 Current->dither_flag = GL_TRUE;
550 }
551 else
552 Current->dither_flag = GL_FALSE;
553 }
554 }
555 }
556
557 static GLboolean set_draw_buffer( GLcontext* ctx, GLenum mode )
558 {
559 /* TODO: this could be better */
560 if (mode==GL_FRONT_LEFT || mode==GL_BACK_LEFT) {
561 return GL_TRUE;
562 }
563 else {
564 return GL_FALSE;
565 }
566 }
567
568
569 static void set_read_buffer(GLcontext *ctx, GLframebuffer *colorBuffer,
570 GLenum buffer )
571 {
572 /* XXX todo */
573 return;
574 }
575
576
577
578 /* Return characteristics of the output buffer. */
579 static void buffer_size( GLcontext* ctx, GLuint *width, GLuint *height )
580 {
581 int New_Size;
582 RECT CR;
583
584 GetClientRect(Current->Window,&CR);
585
586 *width=CR.right;
587 *height=CR.bottom;
588
589 New_Size=((*width)!=Current->width) || ((*height)!=Current->height);
590
591 if (New_Size){
592 Current->width=*width;
593 Current->height=*height;
594 Current->ScanWidth=Current->width;
595 if ((Current->ScanWidth%sizeof(long))!=0)
596 Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));
597
598 if (Current->db_flag){
599 #ifdef DDRAW
600 DDDeleteOffScreen(Current);
601 DDCreateOffScreen(Current);
602 #else
603 if (Current->rgb_flag==GL_TRUE && Current->dither_flag!=GL_TRUE){
604 wmDeleteBackingStore(Current);
605 wmCreateBackingStore(Current, Current->width, Current->height);
606 }
607 #endif
608 }
609
610 /* Resize OsmesaBuffer if in Parallel mode */
611 #if !defined(NO_PARALLEL)
612 if(parallelFlag)
613 PRSizeRenderBuffer(Current->width, Current->height,Current->ScanWidth,
614 Current->rgb_flag == GL_TRUE ? Current->pbPixels:
615 Current->ScreenMem);
616 #endif
617 }
618 }
619
620
621
622 /**********************************************************************/
623 /***** Accelerated point, line, polygon rendering *****/
624 /**********************************************************************/
625
626 /* Accelerated routines are not implemented in 4.0. See OSMesa for ideas. */
627
628 static void fast_rgb_points( GLcontext* ctx, GLuint first, GLuint last )
629 {
630 }
631
632 /* Return pointer to accelerated points function */
633 extern points_func choose_points_function( GLcontext* ctx )
634 {
635 return NULL;
636 }
637
638 static void fast_flat_rgb_line( GLcontext* ctx, GLuint v0,
639 GLuint v1, GLuint pv )
640 {
641 }
642
643 static line_func choose_line_function( GLcontext* ctx )
644 {
645 }
646
647
648 /**********************************************************************/
649 /***** Span-based pixel drawing *****/
650 /**********************************************************************/
651
652
653 /* Write a horizontal span of 32-bit color-index pixels with a boolean mask. */
654 static void write_ci32_span( const GLcontext* ctx,
655 GLuint n, GLint x, GLint y,
656 const GLuint index[],
657 const GLubyte mask[] )
658 {
659 GLuint i;
660 PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
661 assert(Current->rgb_flag==GL_FALSE);
662 for (i=0; i<n; i++)
663 if (mask[i])
664 Mem[i]=index[i];
665 }
666
667
668 /* Write a horizontal span of 8-bit color-index pixels with a boolean mask. */
669 static void write_ci8_span( const GLcontext* ctx,
670 GLuint n, GLint x, GLint y,
671 const GLubyte index[],
672 const GLubyte mask[] )
673 {
674 GLuint i;
675 PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
676 assert(Current->rgb_flag==GL_FALSE);
677 for (i=0; i<n; i++)
678 if (mask[i])
679 Mem[i]=index[i];
680 }
681
682
683
684 /*
685 * Write a horizontal span of pixels with a boolean mask. The current
686 * color index is used for all pixels.
687 */
688 static void write_mono_ci_span(const GLcontext* ctx,
689 GLuint n,GLint x,GLint y,
690 GLuint colorIndex, const GLubyte mask[])
691 {
692 GLuint i;
693 BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
694 assert(Current->rgb_flag==GL_FALSE);
695 for (i=0; i<n; i++)
696 if (mask[i])
697 Mem[i]=colorIndex;
698 }
699
700 /*
701 * To improve the performance of this routine, frob the data into an actual
702 * scanline and call bitblt on the complete scan line instead of SetPixel.
703 */
704
705 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
706 static void write_rgba_span( const GLcontext* ctx, GLuint n, GLint x, GLint y,
707 const GLubyte rgba[][4], const GLubyte mask[] )
708 {
709 PWMC pwc = Current;
710
711 if (pwc->rgb_flag==GL_TRUE)
712 {
713 GLuint i;
714 HDC DC=DD_GETDC;
715 y=FLIP(y);
716 if (mask) {
717 for (i=0; i<n; i++)
718 if (mask[i])
719 wmSetPixel(pwc, y, x + i,
720 rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
721 }
722 else {
723 for (i=0; i<n; i++)
724 wmSetPixel(pwc, y, x + i,
725 rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
726 }
727 DD_RELEASEDC;
728 }
729 else
730 {
731 GLuint i;
732 BYTE *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
733 y = FLIP(y);
734 if (mask) {
735 for (i=0; i<n; i++)
736 if (mask[i])
737 Mem[i] = GetNearestPaletteIndex(Current->hPal,
738 RGB(rgba[i][RCOMP],
739 rgba[i][GCOMP],
740 rgba[i][BCOMP]));
741 }
742 else {
743 for (i=0; i<n; i++)
744 Mem[i] = GetNearestPaletteIndex(Current->hPal,
745 RGB(rgba[i][RCOMP],
746 rgba[i][GCOMP],
747 rgba[i][BCOMP]));
748 }
749 }
750 }
751
752 /* Write a horizontal span of RGB color pixels with a boolean mask. */
753 static void write_rgb_span( const GLcontext* ctx,
754 GLuint n, GLint x, GLint y,
755 const GLubyte rgb[][3], const GLubyte mask[] )
756 {
757 PWMC pwc = Current;
758
759 if (pwc->rgb_flag==GL_TRUE)
760 {
761 GLuint i;
762 HDC DC=DD_GETDC;
763 y=FLIP(y);
764 if (mask) {
765 for (i=0; i<n; i++)
766 if (mask[i])
767 wmSetPixel(pwc, y, x + i,
768 rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
769 }
770 else {
771 for (i=0; i<n; i++)
772 wmSetPixel(pwc, y, x + i,
773 rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
774 }
775 DD_RELEASEDC;
776 }
777 else
778 {
779 GLuint i;
780 BYTE *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
781 y = FLIP(y);
782 if (mask) {
783 for (i=0; i<n; i++)
784 if (mask[i])
785 Mem[i] = GetNearestPaletteIndex(Current->hPal,
786 RGB(rgb[i][RCOMP],
787 rgb[i][GCOMP],
788 rgb[i][BCOMP]));
789 }
790 else {
791 for (i=0; i<n; i++)
792 Mem[i] = GetNearestPaletteIndex(Current->hPal,
793 RGB(rgb[i][RCOMP],
794 rgb[i][GCOMP],
795 rgb[i][BCOMP]));
796 }
797 }
798 }
799
800 /*
801 * Write a horizontal span of pixels with a boolean mask. The current color
802 * is used for all pixels.
803 */
804 static void write_mono_rgba_span( const GLcontext* ctx,
805 GLuint n, GLint x, GLint y,
806 const GLchan color[4], const GLubyte mask[])
807 {
808 GLuint i;
809 PWMC pwc = Current;
810 assert(Current->rgb_flag==GL_TRUE);
811 y=FLIP(y);
812 if(Current->rgb_flag==GL_TRUE)
813 {
814 for (i=0; i<n; i++)
815 if (mask[i])
816 wmSetPixel(pwc,y,x+i,color[RCOMP], color[GCOMP], color[BCOMP]);
817 }
818 else
819 {
820 HDC DC=DD_GETDC;
821 ULONG pixel = RGB( color[RCOMP], color[GCOMP], color[BCOMP] );
822 for (i=0; i<n; i++)
823 if (mask[i])
824 SetPixel(DC, y, x+i, pixel);
825 DD_RELEASEDC;
826 }
827 }
828
829
830
831 /**********************************************************************/
832 /***** Array-based pixel drawing *****/
833 /**********************************************************************/
834
835
836 /* Write an array of 32-bit index pixels with a boolean mask. */
837 static void write_ci32_pixels( const GLcontext* ctx,
838 GLuint n, const GLint x[], const GLint y[],
839 const GLuint index[], const GLubyte mask[] )
840 {
841 GLuint i;
842 assert(Current->rgb_flag==GL_FALSE);
843 for (i=0; i<n; i++) {
844 if (mask[i]) {
845 BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];
846 *Mem = index[i];
847 }
848 }
849 }
850
851
852
853 /*
854 * Write an array of pixels with a boolean mask. The current color
855 * index is used for all pixels.
856 */
857 static void write_mono_ci_pixels( const GLcontext* ctx,
858 GLuint n,
859 const GLint x[], const GLint y[],
860 GLuint colorIndex, const GLubyte mask[] )
861 {
862 GLuint i;
863 assert(Current->rgb_flag==GL_FALSE);
864 for (i=0; i<n; i++) {
865 if (mask[i]) {
866 BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];
867 *Mem = colorIndex;
868 }
869 }
870 }
871
872
873
874 /* Write an array of RGBA pixels with a boolean mask. */
875 static void write_rgba_pixels( const GLcontext* ctx,
876 GLuint n, const GLint x[], const GLint y[],
877 const GLubyte rgba[][4], const GLubyte mask[] )
878 {
879 GLuint i;
880 PWMC pwc = Current;
881 HDC DC=DD_GETDC;
882 assert(Current->rgb_flag==GL_TRUE);
883 for (i=0; i<n; i++)
884 if (mask[i])
885 wmSetPixel(pwc, FLIP(y[i]), x[i],
886 rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
887 DD_RELEASEDC;
888 }
889
890
891
892 /*
893 * Write an array of pixels with a boolean mask. The current color
894 * is used for all pixels.
895 */
896 static void write_mono_rgba_pixels( const GLcontext* ctx,
897 GLuint n,
898 const GLint x[], const GLint y[],
899 const GLchan color[4],
900 const GLubyte mask[] )
901 {
902 GLuint i;
903 PWMC pwc = Current;
904 HDC DC=DD_GETDC;
905 assert(Current->rgb_flag==GL_TRUE);
906 for (i=0; i<n; i++)
907 if (mask[i])
908 wmSetPixel(pwc, FLIP(y[i]),x[i],color[RCOMP],
909 color[GCOMP], color[BCOMP]);
910 DD_RELEASEDC;
911 }
912
913
914
915 /**********************************************************************/
916 /***** Read spans/arrays of pixels *****/
917 /**********************************************************************/
918
919
920 /* Read a horizontal span of color-index pixels. */
921 static void read_ci32_span( const GLcontext* ctx, GLuint n, GLint x, GLint y,
922 GLuint index[])
923 {
924 GLuint i;
925 BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
926 assert(Current->rgb_flag==GL_FALSE);
927 for (i=0; i<n; i++)
928 index[i]=Mem[i];
929 }
930
931
932
933
934 /* Read an array of color index pixels. */
935 static void read_ci32_pixels( const GLcontext* ctx,
936 GLuint n, const GLint x[], const GLint y[],
937 GLuint indx[], const GLubyte mask[] )
938 {
939 GLuint i;
940 assert(Current->rgb_flag==GL_FALSE);
941 for (i=0; i<n; i++) {
942 if (mask[i]) {
943 indx[i]=*(Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i]);
944 }
945 }
946 }
947
948
949
950 /* Read a horizontal span of color pixels. */
951 static void read_rgba_span( const GLcontext* ctx,
952 GLuint n, GLint x, GLint y,
953 GLubyte rgba[][4] )
954 {
955 UINT i;
956 COLORREF Color;
957 HDC DC=DD_GETDC;
958 assert(Current->rgb_flag==GL_TRUE);
959 y = Current->height - y - 1;
960 for (i=0; i<n; i++) {
961 Color=GetPixel(DC,x+i,y);
962 rgba[i][RCOMP] = GetRValue(Color);
963 rgba[i][GCOMP] = GetGValue(Color);
964 rgba[i][BCOMP] = GetBValue(Color);
965 rgba[i][ACOMP] = 255;
966 }
967 DD_RELEASEDC;
968 }
969
970
971 /* Read an array of color pixels. */
972 static void read_rgba_pixels( const GLcontext* ctx,
973 GLuint n, const GLint x[], const GLint y[],
974 GLubyte rgba[][4], const GLubyte mask[] )
975 {
976 GLuint i;
977 COLORREF Color;
978 HDC DC=DD_GETDC;
979 assert(Current->rgb_flag==GL_TRUE);
980 for (i=0; i<n; i++) {
981 if (mask[i]) {
982 GLint y2 = Current->height - y[i] - 1;
983 Color=GetPixel(DC,x[i],y2);
984 rgba[i][RCOMP] = GetRValue(Color);
985 rgba[i][GCOMP] = GetGValue(Color);
986 rgba[i][BCOMP] = GetBValue(Color);
987 rgba[i][ACOMP] = 255;
988 }
989 }
990 DD_RELEASEDC;
991 }
992
993
994
995 /**********************************************************************/
996 /**********************************************************************/
997
998
999 static const GLubyte *get_string(GLcontext *ctx, GLenum name)
1000 {
1001 if (name == GL_RENDERER) {
1002 return (GLubyte *) "Mesa Windows";
1003 }
1004 else {
1005 return NULL;
1006 }
1007 }
1008
1009 static void wmesa_update_state( GLcontext *ctx, GLuint new_state );
1010
1011 static void SetFunctionPointers(GLcontext *ctx)
1012 {
1013 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );
1014 ctx->Driver.GetString = get_string;
1015 ctx->Driver.UpdateState = wmesa_update_state;
1016 ctx->Driver.SetDrawBuffer = set_draw_buffer;
1017 ctx->Driver.ResizeBuffersMESA = _swrast_alloc_buffers;
1018 ctx->Driver.GetBufferSize = buffer_size;
1019
1020 ctx->Driver.Accum = _swrast_Accum;
1021 ctx->Driver.Bitmap = _swrast_Bitmap;
1022 ctx->Driver.Clear = clear;
1023
1024 ctx->Driver.Flush = flush;
1025 ctx->Driver.ClearIndex = clear_index;
1026 ctx->Driver.ClearColor = clear_color;
1027 ctx->Driver.Enable = enable;
1028
1029 ctx->Driver.CopyPixels = _swrast_CopyPixels;
1030 ctx->Driver.DrawPixels = _swrast_DrawPixels;
1031 ctx->Driver.ReadPixels = _swrast_ReadPixels;
1032
1033 ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
1034 ctx->Driver.TexImage1D = _mesa_store_teximage1d;
1035 ctx->Driver.TexImage2D = _mesa_store_teximage2d;
1036 ctx->Driver.TexImage3D = _mesa_store_teximage3d;
1037 ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
1038 ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
1039 ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
1040 ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
1041
1042 ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
1043 ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
1044 ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
1045 ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
1046 ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
1047 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
1048 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
1049 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
1050 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
1051
1052 ctx->Driver.BaseCompressedTexFormat = _mesa_base_compressed_texformat;
1053 ctx->Driver.CompressedTextureSize = _mesa_compressed_texture_size;
1054 ctx->Driver.GetCompressedTexImage = _mesa_get_compressed_teximage;
1055
1056
1057 swdd->SetReadBuffer = set_read_buffer;
1058
1059
1060 /* Pixel/span writing functions: */
1061 swdd->WriteRGBASpan = write_rgba_span;
1062 swdd->WriteRGBSpan = write_rgb_span;
1063 swdd->WriteMonoRGBASpan = write_mono_rgba_span;
1064 swdd->WriteRGBAPixels = write_rgba_pixels;
1065 swdd->WriteMonoRGBAPixels = write_mono_rgba_pixels;
1066 swdd->WriteCI32Span = write_ci32_span;
1067 swdd->WriteCI8Span = write_ci8_span;
1068 swdd->WriteMonoCISpan = write_mono_ci_span;
1069 swdd->WriteCI32Pixels = write_ci32_pixels;
1070 swdd->WriteMonoCIPixels = write_mono_ci_pixels;
1071
1072 swdd->ReadCI32Span = read_ci32_span;
1073 swdd->ReadRGBASpan = read_rgba_span;
1074 swdd->ReadCI32Pixels = read_ci32_pixels;
1075 swdd->ReadRGBAPixels = read_rgba_pixels;
1076
1077 }
1078
1079 static void wmesa_update_state( GLcontext *ctx, GLuint new_state )
1080 {
1081 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );
1082 TNLcontext *tnl = TNL_CONTEXT(ctx);
1083
1084 /*
1085 * XXX these function pointers could be initialized just once during
1086 * context creation since they don't depend on any state changes.
1087 * kws - This is true - this function gets called a lot and it
1088 * would be good to minimize setting all this when not needed.
1089 */
1090 #ifndef SET_FPOINTERS_ONCE
1091 SetFunctionPointers(ctx);
1092 #if 0
1093 ctx->Driver.GetString = get_string;
1094 ctx->Driver.UpdateState = wmesa_update_state;
1095 ctx->Driver.SetDrawBuffer = set_draw_buffer;
1096 ctx->Driver.ResizeBuffersMESA = _swrast_alloc_buffers;
1097 ctx->Driver.GetBufferSize = buffer_size;
1098
1099 ctx->Driver.Accum = _swrast_Accum;
1100 ctx->Driver.Bitmap = _swrast_Bitmap;
1101 ctx->Driver.Clear = clear;
1102
1103 ctx->Driver.Flush = flush;
1104 ctx->Driver.ClearIndex = clear_index;
1105 ctx->Driver.ClearColor = clear_color;
1106 ctx->Driver.Enable = enable;
1107
1108 ctx->Driver.CopyPixels = _swrast_CopyPixels;
1109 ctx->Driver.DrawPixels = _swrast_DrawPixels;
1110 ctx->Driver.ReadPixels = _swrast_ReadPixels;
1111
1112 ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
1113 ctx->Driver.TexImage1D = _mesa_store_teximage1d;
1114 ctx->Driver.TexImage2D = _mesa_store_teximage2d;
1115 ctx->Driver.TexImage3D = _mesa_store_teximage3d;
1116 ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
1117 ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
1118 ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
1119 ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
1120
1121 ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
1122 ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
1123 ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
1124 ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
1125 ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
1126 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
1127 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
1128 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
1129 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
1130
1131 ctx->Driver.BaseCompressedTexFormat = _mesa_base_compressed_texformat;
1132 ctx->Driver.CompressedTextureSize = _mesa_compressed_texture_size;
1133 ctx->Driver.GetCompressedTexImage = _mesa_get_compressed_teximage;
1134
1135
1136 swdd->SetReadBuffer = set_read_buffer;
1137
1138
1139 /* Pixel/span writing functions: */
1140 swdd->WriteRGBASpan = write_rgba_span;
1141 swdd->WriteRGBSpan = write_rgb_span;
1142 swdd->WriteMonoRGBASpan = write_mono_rgba_span;
1143 swdd->WriteRGBAPixels = write_rgba_pixels;
1144 swdd->WriteMonoRGBAPixels = write_mono_rgba_pixels;
1145 swdd->WriteCI32Span = write_ci32_span;
1146 swdd->WriteCI8Span = write_ci8_span;
1147 swdd->WriteMonoCISpan = write_mono_ci_span;
1148 swdd->WriteCI32Pixels = write_ci32_pixels;
1149 swdd->WriteMonoCIPixels = write_mono_ci_pixels;
1150
1151 swdd->ReadCI32Span = read_ci32_span;
1152 swdd->ReadRGBASpan = read_rgba_span;
1153 swdd->ReadCI32Pixels = read_ci32_pixels;
1154 swdd->ReadRGBAPixels = read_rgba_pixels;
1155 #endif // 0
1156 #endif // !SET_FPOINTERS_ONCE
1157 tnl->Driver.RunPipeline = _tnl_run_pipeline;
1158
1159 _swrast_InvalidateState( ctx, new_state );
1160 _swsetup_InvalidateState( ctx, new_state );
1161 _ac_InvalidateState( ctx, new_state );
1162 _tnl_InvalidateState( ctx, new_state );
1163 }
1164
1165
1166
1167
1168 /**********************************************************************/
1169 /***** WMesa API Functions *****/
1170 /**********************************************************************/
1171
1172
1173
1174 #define PAL_SIZE 256
1175 static void GetPalette(HPALETTE Pal,RGBQUAD *aRGB)
1176 {
1177 int i;
1178 HDC hdc;
1179 struct
1180 {
1181 WORD Version;
1182 WORD NumberOfEntries;
1183 PALETTEENTRY aEntries[PAL_SIZE];
1184 } Palette =
1185 {
1186 0x300,
1187 PAL_SIZE
1188 };
1189 hdc=GetDC(NULL);
1190 if (Pal!=NULL)
1191 GetPaletteEntries(Pal,0,PAL_SIZE,Palette.aEntries);
1192 else
1193 GetSystemPaletteEntries(hdc,0,PAL_SIZE,Palette.aEntries);
1194 if (GetSystemPaletteUse(hdc) == SYSPAL_NOSTATIC)
1195 {
1196 for(i = 0; i <PAL_SIZE; i++)
1197 Palette.aEntries[i].peFlags = PC_RESERVED;
1198 Palette.aEntries[255].peRed = 255;
1199 Palette.aEntries[255].peGreen = 255;
1200 Palette.aEntries[255].peBlue = 255;
1201 Palette.aEntries[255].peFlags = 0;
1202 Palette.aEntries[0].peRed = 0;
1203 Palette.aEntries[0].peGreen = 0;
1204 Palette.aEntries[0].peBlue = 0;
1205 Palette.aEntries[0].peFlags = 0;
1206 }
1207 else
1208 {
1209 int nStaticColors;
1210 int nUsableColors;
1211 nStaticColors = GetDeviceCaps(hdc, NUMCOLORS)/2;
1212 for (i=0; i<nStaticColors; i++)
1213 Palette.aEntries[i].peFlags = 0;
1214 nUsableColors = PAL_SIZE-nStaticColors;
1215 for (; i<nUsableColors; i++)
1216 Palette.aEntries[i].peFlags = PC_RESERVED;
1217 for (; i<PAL_SIZE-nStaticColors; i++)
1218 Palette.aEntries[i].peFlags = PC_RESERVED;
1219 for (i=PAL_SIZE-nStaticColors; i<PAL_SIZE; i++)
1220 Palette.aEntries[i].peFlags = 0;
1221 }
1222 ReleaseDC(NULL,hdc);
1223 for (i=0; i<PAL_SIZE; i++)
1224 {
1225 aRGB[i].rgbRed=Palette.aEntries[i].peRed;
1226 aRGB[i].rgbGreen=Palette.aEntries[i].peGreen;
1227 aRGB[i].rgbBlue=Palette.aEntries[i].peBlue;
1228 aRGB[i].rgbReserved=Palette.aEntries[i].peFlags;
1229 }
1230 }
1231
1232
1233 WMesaContext WMesaCreateContext( HWND hWnd, HPALETTE* Pal,
1234 GLboolean rgb_flag,
1235 GLboolean db_flag )
1236 {
1237 RECT CR;
1238 WMesaContext c;
1239 GLboolean true_color_flag;
1240 c = (struct wmesa_context * ) calloc(1,sizeof(struct wmesa_context));
1241 if (!c)
1242 return NULL;
1243
1244 c->Window=hWnd;
1245 c->hDC = GetDC(hWnd);
1246 true_color_flag = GetDeviceCaps(c->hDC, BITSPIXEL) > 8;
1247 #ifdef DDRAW
1248 if(true_color_flag) c->rgb_flag = rgb_flag = GL_TRUE;
1249 #endif
1250
1251
1252 #ifdef DITHER
1253 if ((true_color_flag==GL_FALSE) && (rgb_flag == GL_TRUE)){
1254 c->dither_flag = GL_TRUE;
1255 #ifdef USE_WING
1256 c->hPalHalfTone = WinGCreateHalftonePalette();
1257 #else
1258 c->hPalHalfTone = CreateHalftonePalette(c->hDC);
1259 #endif
1260 }
1261 else
1262 c->dither_flag = GL_FALSE;
1263 #else
1264 c->dither_flag = GL_FALSE;
1265 #endif
1266
1267
1268 if (rgb_flag==GL_FALSE)
1269 {
1270 c->rgb_flag = GL_FALSE;
1271 #if 0
1272 /* Old WinG stuff???? */
1273 c->db_flag = db_flag =GL_TRUE; /* WinG requires double buffering */
1274 printf("Single buffer is not supported in color index mode, ",
1275 "setting to double buffer.\n");
1276 #endif
1277 }
1278 else
1279 {
1280 c->rgb_flag = GL_TRUE;
1281 }
1282 GetClientRect(c->Window,&CR);
1283 c->width=CR.right;
1284 c->height=CR.bottom;
1285 if (db_flag)
1286 {
1287 c->db_flag = 1;
1288 /* Double buffered */
1289 #ifndef DDRAW
1290 {
1291 wmCreateBackingStore(c, c->width, c->height);
1292
1293 }
1294 #endif
1295 }
1296 else
1297 {
1298 /* Single Buffered */
1299 if (c->rgb_flag)
1300 c->db_flag = 0;
1301 }
1302 #ifdef DDRAW
1303 if (DDInit(c,hWnd) == GL_FALSE) {
1304 free( (void *) c );
1305 exit(1);
1306 }
1307 #endif
1308
1309
1310 c->gl_visual = _mesa_create_visual(rgb_flag,
1311 db_flag, /* db_flag */
1312 GL_FALSE, /* stereo */
1313 8,8,8,8, /* r, g, b, a bits */
1314 0, /* index bits */
1315 16, /* depth_bits */
1316 8, /* stencil_bits */
1317 16,16,16,16,/* accum_bits */
1318 1);
1319
1320 if (!c->gl_visual) {
1321 return NULL;
1322 }
1323
1324 /* allocate a new Mesa context */
1325 c->gl_ctx = _mesa_create_context( c->gl_visual, NULL, c, GL_TRUE);
1326
1327 if (!c->gl_ctx) {
1328 _mesa_destroy_visual( c->gl_visual );
1329 free(c);
1330 return NULL;
1331 }
1332
1333 if (!_mesa_initialize_context(c->gl_ctx,
1334 c->gl_visual,
1335 (GLcontext *) NULL,
1336 (void *) c, GL_TRUE )) {
1337 _mesa_destroy_visual( c->gl_visual );
1338 free(c);
1339 return NULL;
1340 }
1341
1342
1343 _mesa_enable_sw_extensions(c->gl_ctx);
1344 _mesa_enable_1_3_extensions(c->gl_ctx);
1345
1346 c->gl_buffer = _mesa_create_framebuffer( c->gl_visual,
1347 c->gl_visual->depthBits > 0,
1348 c->gl_visual->stencilBits > 0,
1349 c->gl_visual->accumRedBits > 0,
1350 GL_FALSE /* s/w alpha */ );
1351 if (!c->gl_buffer) {
1352 _mesa_destroy_visual( c->gl_visual );
1353 _mesa_free_context_data( c->gl_ctx );
1354 free(c);
1355 return NULL;
1356 }
1357
1358 /* Initialize the software rasterizer and helper modules.
1359 */
1360 {
1361 GLcontext *ctx = c->gl_ctx;
1362 _swrast_CreateContext( ctx );
1363 _ac_CreateContext( ctx );
1364 _tnl_CreateContext( ctx );
1365 _swsetup_CreateContext( ctx );
1366
1367 #ifdef SET_FPOINTERS_ONCE
1368 SetFunctionPointers(ctx);
1369 #endif // SET_FPOINTERS_ONCE
1370 _swsetup_Wakeup( ctx );
1371 }
1372 #ifdef COMPILE_SETPIXEL
1373 ChooseSetPixel(c);
1374 #endif
1375 return c;
1376 }
1377
1378 void WMesaDestroyContext( void )
1379 {
1380 WMesaContext c = Current;
1381 ReleaseDC(c->Window,c->hDC);
1382 WC = c;
1383 if(c->hPalHalfTone != NULL)
1384 DeleteObject(c->hPalHalfTone);
1385
1386 _swsetup_DestroyContext( c->gl_ctx );
1387 _tnl_DestroyContext( c->gl_ctx );
1388 _ac_DestroyContext( c->gl_ctx );
1389 _swrast_DestroyContext( c->gl_ctx );
1390
1391 _mesa_destroy_visual( c->gl_visual );
1392 _mesa_destroy_framebuffer( c->gl_buffer );
1393 _mesa_free_context_data( c->gl_ctx );
1394
1395 if (c->db_flag)
1396 #ifdef DDRAW
1397 DDFree(c);
1398 #else
1399 wmDeleteBackingStore(c);
1400 #endif
1401 free( (void *) c );
1402 #if !defined(NO_PARALLEL)
1403 if(parallelMachine)
1404 PRDestroyRenderBuffer();
1405 #endif
1406 }
1407
1408
1409 void WMesaMakeCurrent( WMesaContext c )
1410 {
1411 if(!c){
1412 Current = c;
1413 return;
1414 }
1415
1416 if(Current == c)
1417 return;
1418
1419 wmesa_update_state(c->gl_ctx, 0);
1420 _mesa_make_current(c->gl_ctx, c->gl_buffer);
1421 Current = c;
1422 if (Current->gl_ctx->Viewport.Width==0) {
1423 /* initialize viewport to window size */
1424 _mesa_Viewport( 0, 0, Current->width, Current->height );
1425 Current->gl_ctx->Scissor.Width = Current->width;
1426 Current->gl_ctx->Scissor.Height = Current->height;
1427 }
1428 if ((c->cColorBits <= 8 ) && (c->rgb_flag == GL_TRUE)){
1429 WMesaPaletteChange(c->hPalHalfTone);
1430 }
1431 }
1432
1433
1434
1435 void WMesaSwapBuffers( void )
1436 {
1437 HDC DC = Current->hDC;
1438 GET_CURRENT_CONTEXT(ctx);
1439
1440 /* If we're swapping the buffer associated with the current context
1441 * we have to flush any pending rendering commands first.
1442 */
1443 if (Current && Current->gl_ctx == ctx)
1444 _mesa_swapbuffers(ctx);
1445
1446 if (Current->db_flag)
1447 wmFlush(Current);
1448 }
1449
1450
1451
1452 void WMesaPaletteChange(HPALETTE Pal)
1453 {
1454 #ifndef DDRAW
1455 int vRet;
1456 #endif
1457 LPPALETTEENTRY pPal;
1458 if (Current && (Current->rgb_flag==GL_FALSE ||
1459 Current->dither_flag == GL_TRUE))
1460 {
1461 pPal = (PALETTEENTRY *)malloc( 256 * sizeof(PALETTEENTRY));
1462 Current->hPal=Pal;
1463 GetPaletteEntries( Pal, 0, 256, pPal );
1464 #ifdef DDRAW
1465 Current->lpDD->lpVtbl->CreatePalette(Current->lpDD,DDPCAPS_8BIT,
1466 pPal, &(Current->lpDDPal), NULL);
1467 if (Current->lpDDPal)
1468 Current->lpDDSPrimary->lpVtbl->SetPalette(Current->lpDDSPrimary,
1469 Current->lpDDPal);
1470 #else
1471 vRet = SetDIBColorTable(Current->dib.hDC, 0, 256, (RGBQUAD*)pPal);
1472 #endif
1473 free( pPal );
1474 }
1475 }
1476
1477
1478
1479
1480 static unsigned char threeto8[8] = {
1481 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
1482 };
1483
1484 static unsigned char twoto8[4] = {
1485 0, 0x55, 0xaa, 0xff
1486 };
1487
1488 static unsigned char oneto8[2] = {
1489 0, 255
1490 };
1491
1492 static unsigned char componentFromIndex(UCHAR i, UINT nbits, UINT shift)
1493 {
1494 unsigned char val;
1495
1496 val = i >> shift;
1497 switch (nbits) {
1498
1499 case 1:
1500 val &= 0x1;
1501 return oneto8[val];
1502
1503 case 2:
1504 val &= 0x3;
1505 return twoto8[val];
1506
1507 case 3:
1508 val &= 0x7;
1509 return threeto8[val];
1510
1511 default:
1512 return 0;
1513 }
1514 }
1515
1516 void wmCreatePalette( PWMC pwdc )
1517 {
1518 /* Create a compressed and re-expanded 3:3:2 palette */
1519 int i;
1520 LOGPALETTE *pPal;
1521 BYTE rb, rs, gb, gs, bb, bs;
1522
1523 pwdc->nColors = 0x100;
1524
1525 pPal = (PLOGPALETTE)malloc(sizeof(LOGPALETTE) +
1526 pwdc->nColors * sizeof(PALETTEENTRY));
1527 memset( pPal, 0, sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY) );
1528
1529 pPal->palVersion = 0x300;
1530
1531 rb = REDBITS;
1532 rs = REDSHIFT;
1533 gb = GREENBITS;
1534 gs = GREENSHIFT;
1535 bb = BLUEBITS;
1536 bs = BLUESHIFT;
1537
1538 if (pwdc->db_flag) {
1539
1540 /* Need to make two palettes: one for the screen DC and one for the DIB. */
1541 pPal->palNumEntries = pwdc->nColors;
1542 for (i = 0; i < pwdc->nColors; i++) {
1543 pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
1544 pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
1545 pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
1546 pPal->palPalEntry[i].peFlags = 0;
1547 }
1548 pwdc->hGLPalette = CreatePalette( pPal );
1549 pwdc->hPalette = CreatePalette( pPal );
1550 }
1551
1552 else {
1553 pPal->palNumEntries = pwdc->nColors;
1554 for (i = 0; i < pwdc->nColors; i++) {
1555 pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
1556 pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
1557 pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
1558 pPal->palPalEntry[i].peFlags = 0;
1559 }
1560 pwdc->hGLPalette = CreatePalette( pPal );
1561 }
1562
1563 free(pPal);
1564
1565 }
1566
1567
1568 void
1569 #ifdef COMPILE_SETPIXEL
1570
1571 wmSetPixelDefault(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1572 {
1573 if (Current->db_flag)
1574 {
1575 #ifdef DDRAW
1576 HDC hdc = NULL;
1577 Current->lpDDSOffScreen->lpVtbl->Unlock(Current->lpDDSOffScreen,NULL);
1578 Current->lpDDSOffScreen->lpVtbl->GetDC(Current->lpDDSOffScreen,&hdc);
1579 SetPixelV(hdc,iPixel, iScanLine, RGB(r,g,b));
1580 Current->lpDDSOffScreen->lpVtbl->ReleaseDC(Current->lpDDSOffScreen,hdc);
1581 while (Current->lpDDSOffScreen->lpVtbl->Lock(Current->lpDDSOffScreen,NULL, &(Current->ddsd), 0, NULL) == DDERR_WASSTILLDRAWING);
1582 #else
1583 SetPixelV(Current->hDC, iPixel, iScanLine, RGB(r,g,b));
1584 #endif
1585 }
1586 else
1587 {
1588 SetPixelV(Current->hDC, iPixel+pwc->rectSurface.left, pwc->rectSurface.top+iScanLine, RGB(r,g,b));
1589 }
1590 }
1591 #else
1592 wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1593 {
1594 if (Current->db_flag)
1595 {
1596 LPBYTE lpb = pwc->pbPixels;
1597 UINT nBypp = pwc->cColorBits >> 3;
1598
1599 lpb += pwc->ScanWidth * iScanLine;
1600 lpb += iPixel * nBypp;
1601
1602 if(nBypp == 1)
1603 {
1604 if(pwc->dither_flag)
1605 *lpb = DITHER_RGB_2_8BIT(r,g,b,iScanLine,iPixel);
1606 else
1607 *lpb = BGR8(r,g,b);
1608 }
1609 else if(nBypp == 2)
1610 *((LPWORD)lpb) = BGR16(r,g,b);
1611 else if (nBypp == 3)
1612 *((LPDWORD)lpb) = BGR24(r,g,b);
1613 else if (nBypp == 4)
1614 *((LPDWORD)lpb) = BGR32(r,g,b);
1615 }
1616 else
1617 {
1618 SetPixel(Current->hDC, iPixel, iScanLine, RGB(r,g,b));
1619 }
1620 }
1621 #endif
1622 #ifdef COMPILE_SETPIXEL
1623 void wmSetPixel4(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1624 {
1625 LPDWORD lpdw = ((LPDWORD)(pwc->pbPixels + pwc->ScanWidth * iScanLine)) + iPixel;
1626 *lpdw = BGR32(r,g,b);
1627 // LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel + iPixel + iPixel;
1628 // *((LPDWORD)lpb) = BGR32(r,g,b);
1629 }
1630
1631 void wmSetPixel3(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1632 {
1633 LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel + iPixel;
1634 *((LPDWORD)lpb) = BGR24(r,g,b);
1635 }
1636
1637 void wmSetPixel2(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1638 {
1639 LPWORD lpw = ((LPWORD)(pwc->pbPixels + pwc->ScanWidth * iScanLine)) + iPixel;
1640 *lpw = BGR16(r,g,b);
1641 // LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel;
1642 // *((LPWORD)lpb) = BGR16(r,g,b);
1643 }
1644
1645 void wmSetPixel1(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1646 {
1647 LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel;
1648 *lpb = BGR8(r,g,b);
1649 }
1650
1651 void wmSetPixel1Dither(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1652 {
1653 LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel;
1654 *lpb = DITHER_RGB_2_8BIT(r,g,b,iScanLine,iPixel);
1655 }
1656
1657
1658 void ChooseSetPixel(PWMC pwc)
1659 {
1660 UINT nBypp = (pwc ) ? pwc->cColorBits >> 3 : 0;
1661 switch(nBypp)
1662 {
1663 case 1:
1664 pwc->wmSetPixel = pwc->dither_flag ? &wmSetPixel1Dither : &wmSetPixel1;
1665 break;
1666 case 2:
1667 pwc->wmSetPixel = &wmSetPixel2;
1668 break;
1669 case 3:
1670 pwc->wmSetPixel = &wmSetPixel3;
1671 break;
1672 case 4:
1673 pwc->wmSetPixel = &wmSetPixel4;
1674 break;
1675 default:
1676 pwc->wmSetPixel = &wmSetPixelDefault;
1677 break;
1678 }
1679 }
1680
1681 #endif
1682
1683 void wmCreateDIBSection(
1684 HDC hDC,
1685 PWMC pwc, // handle of device context
1686 CONST BITMAPINFO *pbmi, // bitmap size, format, and color data
1687 UINT iUsage // color data type indicator: RGB values or palette indices
1688 )
1689 {
1690 DWORD dwSize = 0;
1691 DWORD dwScanWidth;
1692 UINT nBypp = pwc->cColorBits / 8;
1693 HDC hic;
1694
1695 dwScanWidth = (((pwc->ScanWidth * nBypp)+ 3) & ~3);
1696
1697 pwc->ScanWidth =pwc->pitch = dwScanWidth;
1698
1699 if (stereo_flag)
1700 pwc->ScanWidth = 2* pwc->pitch;
1701
1702 dwSize = sizeof(BITMAPINFO) + (dwScanWidth * pwc->height);
1703 #ifdef USE_MAPPED_FILE
1704 pwc->dib.hFileMap = CreateFileMapping((HANDLE)PAGE_FILE,
1705 NULL,
1706 PAGE_READWRITE | SEC_COMMIT,
1707 0,
1708 dwSize,
1709 NULL);
1710
1711 if (!pwc->dib.hFileMap)
1712 return;
1713
1714 pwc->dib.base = MapViewOfFile(pwc->dib.hFileMap,
1715 FILE_MAP_ALL_ACCESS,
1716 0,
1717 0,
1718 0);
1719
1720 if(!pwc->dib.base){
1721 CloseHandle(pwc->dib.hFileMap);
1722 return;
1723 }
1724
1725
1726 CopyMemory(pwc->dib.base, pbmi, sizeof(BITMAPINFO));
1727 #endif // USE_MAPPED_FILE
1728
1729 hic = CreateIC("display", NULL, NULL, NULL);
1730 pwc->dib.hDC = CreateCompatibleDC(hic);
1731
1732 #ifdef USE_MAPPED_FILE
1733
1734 pwc->hbmDIB = CreateDIBSection(hic,
1735 &(pwc->bmi),
1736 (iUsage ? DIB_PAL_COLORS : DIB_RGB_COLORS),
1737 &(pwc->pbPixels),
1738 pwc->dib.hFileMap,
1739 0);
1740 #else
1741 pwc->hbmDIB = CreateDIBSection(hic,
1742 &(pwc->bmi),
1743 (iUsage ? DIB_PAL_COLORS : DIB_RGB_COLORS),
1744 &(pwc->pbPixels),
1745 0,
1746 0);
1747 #endif // USE_MAPPED_FILE
1748 pwc->ScreenMem = pwc->addrOffScreen = pwc->pbPixels;
1749 pwc->hOldBitmap = SelectObject(pwc->dib.hDC, pwc->hbmDIB);
1750
1751 DeleteDC(hic);
1752
1753 return;
1754
1755 }
1756
1757 /*
1758 * Blit memory DC to screen DC
1759 */
1760 BOOL wmFlush(PWMC pwc)
1761 {
1762 BOOL bRet = 0;
1763 DWORD dwErr = 0;
1764 #ifdef DDRAW
1765 HRESULT ddrval;
1766 #endif
1767
1768 if(pwc->db_flag){
1769 #ifdef DDRAW
1770 if (pwc->lpDDSOffScreen == NULL)
1771 if(DDCreateOffScreen(pwc) == GL_FALSE)
1772 return FALSE;
1773
1774 pwc->lpDDSOffScreen->lpVtbl->Unlock(pwc->lpDDSOffScreen, NULL);
1775
1776 while( 1 )
1777 {
1778 ddrval = pwc->lpDDSPrimary->lpVtbl->Blt( pwc->lpDDSPrimary,
1779 &(pwc->rectSurface),
1780 pwc->lpDDSOffScreen,
1781 &(pwc->rectOffScreen),
1782 0, NULL );
1783
1784 if( ddrval == DD_OK )
1785 {
1786 break;
1787 }
1788 if( ddrval == DDERR_SURFACELOST )
1789 {
1790 if(!DDRestoreAll(pwc))
1791 {
1792 break;
1793 }
1794 }
1795 if( ddrval != DDERR_WASSTILLDRAWING )
1796 {
1797 break;
1798 }
1799 }
1800
1801 while (pwc->lpDDSOffScreen->lpVtbl->Lock(pwc->lpDDSOffScreen,
1802 NULL, &(pwc->ddsd), 0, NULL) ==
1803 DDERR_WASSTILLDRAWING)
1804 ;
1805
1806 if(ddrval != DD_OK)
1807 dwErr = GetLastError();
1808 #else
1809 bRet = BitBlt(pwc->hDC, 0, 0, pwc->width, pwc->height,
1810 pwc->dib.hDC, 0, 0, SRCCOPY);
1811 #endif
1812 }
1813
1814 return(TRUE);
1815
1816 }
1817
1818
1819 /* The following code is added by Li Wei to enable stereo display */
1820
1821 #if !defined(NO_STEREO)
1822
1823 static void __gluMakeIdentityf(GLfloat m[16])
1824 {
1825 m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0;
1826 m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0;
1827 m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0;
1828 m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1;
1829 }
1830
1831 static void normalize(float v[3])
1832 {
1833 float r;
1834
1835 r = sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] );
1836 if (r == 0.0) return;
1837
1838 v[0] /= r;
1839 v[1] /= r;
1840 v[2] /= r;
1841 }
1842
1843 static void cross(float v1[3], float v2[3], float result[3])
1844 {
1845 result[0] = v1[1]*v2[2] - v1[2]*v2[1];
1846 result[1] = v1[2]*v2[0] - v1[0]*v2[2];
1847 result[2] = v1[0]*v2[1] - v1[1]*v2[0];
1848 }
1849
1850
1851 static void
1852 __gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx,
1853 GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy,
1854 GLdouble upz)
1855 {
1856 int i;
1857 float forward[3], side[3], up[3];
1858 GLfloat m[4][4];
1859
1860 forward[0] = centerx - eyex;
1861 forward[1] = centery - eyey;
1862 forward[2] = centerz - eyez;
1863
1864 up[0] = upx;
1865 up[1] = upy;
1866 up[2] = upz;
1867
1868 normalize(forward);
1869
1870 /* Side = forward x up */
1871 cross(forward, up, side);
1872 normalize(side);
1873
1874 /* Recompute up as: up = side x forward */
1875 cross(side, forward, up);
1876
1877 __gluMakeIdentityf(&m[0][0]);
1878 m[0][0] = side[0];
1879 m[1][0] = side[1];
1880 m[2][0] = side[2];
1881
1882 m[0][1] = up[0];
1883 m[1][1] = up[1];
1884 m[2][1] = up[2];
1885
1886 m[0][2] = -forward[0];
1887 m[1][2] = -forward[1];
1888 m[2][2] = -forward[2];
1889
1890 glMultMatrixf(&m[0][0]);
1891 glTranslated(-eyex, -eyey, -eyez);
1892 }
1893
1894 GLfloat viewDistance = 1.0;
1895
1896 void WMesaShowStereo(GLuint list)
1897 {
1898
1899 GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
1900 GLfloat cm[16];
1901 GLint matrix_mode;
1902 /* Must use double Buffer */
1903 if( ! Current-> db_flag )
1904 return;
1905
1906
1907 glGetIntegerv(GL_MATRIX_MODE,&matrix_mode);
1908
1909 WMesaViewport(Current->gl_ctx,0,Current->height/2,
1910 Current->width,Current->height/2);
1911 if(matrix_mode!=GL_MODELVIEW)
1912 glMatrixMode(GL_MODELVIEW);
1913
1914 glGetFloatv(GL_MODELVIEW_MATRIX,cm);
1915 glLoadIdentity();
1916 __gluLookAt(viewDistance/2,0.0,0.0 ,
1917 viewDistance/2,0.0,-1.0,
1918 0.0,1.0,0.0 );
1919 glMultMatrixf( cm );
1920
1921 Current->ScreenMem = Current->pbPixels = Current->addrOffScreen;
1922 glCallList( list );
1923
1924 glGetFloatv(GL_MODELVIEW_MATRIX,cm);
1925 glLoadIdentity();
1926 __gluLookAt(-viewDistance/2,0.0,0.0 ,
1927 -viewDistance/2,0.0,-1.0,
1928 0.0,1.0,0.0 );
1929 glMultMatrixf(cm);
1930
1931 Current->ScreenMem = Current->pbPixels = Current->addrOffScreen + Current->pitch;
1932 glCallList(list);
1933 if(matrix_mode!=GL_MODELVIEW)
1934 glMatrixMode(matrix_mode);
1935
1936 glFlush();
1937
1938 WMesaViewport(Current->gl_ctx,0,0,Current->width,Current->height);
1939 WMesaSwapBuffers();
1940 }
1941
1942 void toggleStereoMode()
1943 {
1944 if(!Current->db_flag)
1945 return;
1946 if(!stereo_flag){
1947 stereo_flag = 1;
1948 if(stereoBuffer==GL_FALSE)
1949 #if !defined(NO_PARALLEL)
1950 if(!parallelFlag)
1951 #endif
1952 {
1953 Current->ScanWidth = Current->pitch*2;
1954 }
1955 }
1956 else {
1957 stereo_flag = 0;
1958 #if !defined(NO_PARALLEL)
1959 if(!parallelFlag)
1960 #endif
1961 Current->ScanWidth = Current->pitch;
1962 Current->pbPixels = Current->addrOffScreen;
1963 }
1964 }
1965
1966 /* if in stereo mode, the following function is called */
1967 void glShowStereo(GLuint list)
1968 {
1969 WMesaShowStereo(list);
1970 }
1971
1972 #endif /* NO_STEREO */
1973
1974 #if !defined(NO_PARALLEL)
1975
1976 void toggleParallelMode(void)
1977 {
1978 if(!parallelFlag){
1979 parallelFlag = GL_TRUE;
1980 if(parallelMachine==GL_FALSE){
1981 PRCreateRenderBuffer( Current->rgb_flag? GL_RGBA :GL_COLOR_INDEX,
1982 Current->cColorBits/8,
1983 Current->width ,Current->height,
1984 Current->ScanWidth,
1985 Current->rgb_flag? Current->pbPixels:
1986 Current->ScreenMem);
1987 parallelMachine = GL_TRUE;
1988 }
1989 }
1990 else {
1991 parallelFlag = GL_FALSE;
1992 if(parallelMachine==GL_TRUE){
1993 PRDestroyRenderBuffer();
1994 parallelMachine=GL_FALSE;
1995 ReadyForNextFrame = GL_TRUE;
1996 }
1997
1998 /***********************************************
1999 * Seems something wrong!!!!
2000 ************************************************/
2001
2002 WMesaMakeCurrent(Current);
2003 #if !defined(NO_STEREO)
2004 stereo_flag = GL_FALSE ;
2005 #endif
2006 }
2007 }
2008
2009 void PRShowRenderResult(void)
2010 {
2011 int flag = 0;
2012 if(!glImageRendered())
2013 return;
2014
2015 if (parallelFlag)
2016 {
2017 WMesaSwapBuffers();
2018 }
2019
2020 }
2021 #endif /* NO_PARALLEL */
2022
2023 BYTE DITHER_RGB_2_8BIT( int red, int green, int blue, int pixel, int scanline)
2024 {
2025 char unsigned redtemp, greentemp, bluetemp, paletteindex;
2026
2027 //*** now, look up each value in the halftone matrix
2028 //*** using an 8x8 ordered dither.
2029 redtemp = aDividedBy51[red]
2030 + (aModulo51[red] > aHalftone8x8[(pixel%8)*8
2031 + scanline%8]);
2032 greentemp = aDividedBy51[(char unsigned)green]
2033 + (aModulo51[green] > aHalftone8x8[
2034 (pixel%8)*8 + scanline%8]);
2035 bluetemp = aDividedBy51[(char unsigned)blue]
2036 + (aModulo51[blue] > aHalftone8x8[
2037 (pixel%8)*8 +scanline%8]);
2038
2039 //*** recombine the halftoned rgb values into a palette index
2040 paletteindex =
2041 redtemp + aTimes6[greentemp] + aTimes36[bluetemp];
2042
2043 //*** and translate through the wing halftone palette
2044 //*** translation vector to give the correct value.
2045 return aWinGHalftoneTranslation[paletteindex];
2046 }
2047
2048 #ifdef DDRAW
2049 /*
2050 * restoreAll
2051 *
2052 * restore all lost objects
2053 */
2054 HRESULT DDRestoreAll( WMesaContext wc )
2055 {
2056 HRESULT ddrval;
2057
2058 ddrval = wc->lpDDSPrimary->lpVtbl->Restore(wc->lpDDSPrimary);
2059 if( ddrval == DD_OK )
2060 {
2061 ddrval = wc->lpDDSOffScreen->lpVtbl->Restore(wc->lpDDSOffScreen);
2062 }
2063 return ddrval;
2064
2065 } /* restoreAll */
2066
2067
2068 /*
2069 * This function is called if the initialization function fails
2070 */
2071 BOOL initFail( HWND hwnd, WMesaContext wc )
2072 {
2073 DDFree(wc);
2074 MessageBox( hwnd, "DirectDraw Init FAILED", "", MB_OK );
2075 return FALSE;
2076
2077 } /* initFail */
2078
2079
2080 static void DDDeleteOffScreen(WMesaContext wc)
2081 {
2082 if( wc->lpDDSOffScreen != NULL )
2083 {
2084 wc->lpDDSOffScreen->lpVtbl->Unlock(wc->lpDDSOffScreen,NULL);
2085 wc->lpDDSOffScreen->lpVtbl->Release(wc->lpDDSOffScreen);
2086 wc->lpDDSOffScreen = NULL;
2087 }
2088
2089 }
2090
2091 static void DDFreePrimarySurface(WMesaContext wc)
2092 {
2093 if( wc->lpDDSPrimary != NULL )
2094 {
2095 if(wc->db_flag == GL_FALSE)
2096 wc->lpDDSPrimary->lpVtbl->ReleaseDC(wc->lpDDSPrimary, wc->hDC);
2097 wc->lpDDSPrimary->lpVtbl->Release(wc->lpDDSPrimary);
2098 wc->lpDDSPrimary = NULL;
2099 }
2100 }
2101
2102 static BOOL DDCreatePrimarySurface(WMesaContext wc)
2103 {
2104 HRESULT ddrval;
2105 // DDSCAPS ddscaps;
2106 wc->ddsd.dwSize = sizeof( wc->ddsd );
2107 wc->ddsd.dwFlags = DDSD_CAPS;
2108 wc->ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2109
2110 ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD,&(wc->ddsd),
2111 &(wc->lpDDSPrimary), NULL );
2112 if( ddrval != DD_OK )
2113 {
2114 return initFail(wc->hwnd , wc);
2115 }
2116 if(wc->db_flag == GL_FALSE)
2117 wc->lpDDSPrimary->lpVtbl->GetDC(wc->lpDDSPrimary, &(wc->hDC));
2118 return TRUE;
2119 }
2120
2121 static BOOL DDCreateOffScreen(WMesaContext wc)
2122 {
2123 POINT pt;
2124 HRESULT ddrval;
2125 if(wc->lpDD == NULL)
2126 return FALSE;
2127 GetClientRect( wc->hwnd, &(wc->rectOffScreen) );
2128 wc->ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2129 wc->ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2130 wc->ddsd.dwHeight = wc->rectOffScreen.bottom - wc->rectOffScreen.top;
2131 wc->ddsd.dwWidth = wc->rectOffScreen.right - wc->rectOffScreen.left;
2132
2133 ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD, &(wc->ddsd),
2134 &(wc->lpDDSOffScreen), NULL );
2135 if( ddrval != DD_OK )
2136 {
2137 return FALSE;
2138 }
2139
2140 while (wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL,
2141 &(wc->ddsd), 0, NULL) ==
2142 DDERR_WASSTILLDRAWING)
2143 ;
2144
2145 if(wc->ddsd.lpSurface==NULL)
2146 return initFail(wc->hwnd, wc);
2147
2148 wc->ScreenMem = wc->pbPixels = wc->addrOffScreen =
2149 (PBYTE)(wc->ddsd.lpSurface);
2150 wc->ScanWidth = wc->pitch = wc->ddsd.lPitch;
2151 if (stereo_flag)
2152 wc->ScanWidth = wc->ddsd.lPitch*2;
2153
2154 GetClientRect( wc->hwnd, &(wc->rectSurface) );
2155 pt.x = pt.y = 0;
2156 ClientToScreen( wc->hwnd, &pt );
2157 OffsetRect(&(wc->rectSurface), pt.x, pt.y);
2158 wmSetPixelFormat(wc, wc->hDC);
2159 return TRUE;
2160 }
2161
2162 typedef
2163 struct tagWMesaContextList
2164 {
2165 WMesaContext wc;
2166 struct tagWMesaContextList *next;
2167 }WMesaContextList;
2168
2169 WMesaContextList *head = 0;
2170
2171 void AddContext(WMesaContext wc)
2172 {
2173 WMesaContextList *lst = (WMesaContextList *)malloc(sizeof(WMesaContextList));
2174 lst->wc = wc;
2175 if( head )
2176 lst->next = head;
2177 head = lst;
2178 }
2179
2180 WMesaContext FindContext(HWND hWnd)
2181 {
2182 WMesaContextList *tmp = head;
2183 while(tmp)
2184 {
2185 if( tmp->wc->hwnd == hWnd )
2186 return tmp->wc;
2187 tmp = tmp->next;
2188 }
2189 return NULL;
2190 }
2191
2192 void RemoveContext(HWND hWnd)
2193 {
2194 WMesaContextList *tmp = head;
2195 if(tmp )
2196 {
2197 if( tmp->wc->hwnd == hWnd )
2198 {
2199 WMesaContextList *lst = tmp;
2200
2201 head = tmp->next;
2202 free((void *)lst);
2203 }
2204 else
2205 while(tmp->next)
2206 {
2207 if( tmp->next->wc->hwnd == hWnd )
2208 {
2209 WMesaContextList *lst = tmp->next;
2210 tmp->next = tmp->next->next;
2211 free((void *)lst);
2212 }
2213 tmp = tmp->next;
2214 }
2215 }
2216 }
2217
2218 static LRESULT CALLBACK MyWndProc(HWND hwnd,UINT message,WPARAM wParam, LPARAM lParam)
2219 {
2220 WMesaContext wc = Current->hwnd == hwnd ? Current : FindContext(hwnd);
2221 if( wc )
2222 {
2223 LRESULT lret = CallWindowProc((WNDPROC)(wc->oldWndProc),hwnd,message,wParam,lParam);
2224 if( message = WM_MOVE )
2225 {
2226 POINT pt = {0};
2227 GetClientRect( wc->hwnd, &(wc->rectSurface) );
2228 ClientToScreen( hwnd, &pt );
2229 OffsetRect(&(wc->rectSurface), pt.x, pt.y);
2230 }
2231 return lret;
2232 }
2233 return 0L;
2234 }
2235
2236 /*
2237 * doInit - do work required for every instance of the application:
2238 * create the window, initialize data
2239 */
2240 static BOOL DDInit( WMesaContext wc, HWND hwnd)
2241 {
2242 HRESULT ddrval;
2243 // DWORD dwFrequency;
2244
2245 // LPDIRECTDRAW lpDD; // DirectDraw object
2246 // LPDIRECTDRAW2 lpDD2;
2247 LPDIRECTDRAWCLIPPER pcClipper = NULL;
2248
2249 wc->fullScreen = displayOptions.fullScreen;
2250 wc->gMode = displayOptions.mode;
2251 wc->hwnd = hwnd;
2252 stereo_flag = displayOptions.stereo;
2253 if(wc->db_flag!= GL_TRUE)
2254 stereo_flag = GL_FALSE;
2255 /*
2256 * create the main DirectDraw object
2257 */
2258 ddrval = DirectDrawCreate( NULL, &(wc->lpDD), NULL );
2259 if( ddrval != DD_OK )
2260 {
2261 return initFail(hwnd,wc);
2262 }
2263
2264 // Get exclusive mode if requested
2265 if(wc->fullScreen)
2266 {
2267 ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd,
2268 DDSCL_EXCLUSIVE |
2269 DDSCL_FULLSCREEN );
2270 }
2271 else
2272 {
2273 ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd,
2274 DDSCL_NORMAL );
2275 }
2276 if( ddrval != DD_OK )
2277 {
2278 return initFail(hwnd , wc);
2279 }
2280
2281
2282 if(ddrval != DD_OK)
2283 return initFail(hwnd , wc);
2284
2285
2286 switch( wc->gMode )
2287 {
2288 case 1:
2289 ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 640, 480,
2290 displayOptions.bpp);
2291 break;
2292 case 2:
2293 ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 800, 600,
2294 displayOptions.bpp);
2295 break;
2296 case 3:
2297 ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1024, 768,
2298 displayOptions.bpp);
2299 break;
2300 case 4:
2301 ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1152, 864,
2302 displayOptions.bpp);
2303 break;
2304 case 5:
2305 ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1280, 1024,
2306 displayOptions.bpp);
2307 break;
2308 }
2309
2310 if( ddrval != DD_OK )
2311 {
2312 printf("Can't modify display mode, current mode used\n");
2313 }
2314 switch(ddrval){
2315 case DDERR_INVALIDOBJECT:
2316 break;
2317 case DDERR_INVALIDPARAMS:
2318 break;
2319 case DDERR_UNSUPPORTEDMODE:
2320 ;
2321 }
2322
2323 if(DDCreatePrimarySurface(wc) == GL_FALSE)
2324 return initFail(hwnd, wc);
2325
2326 if(wc->db_flag)
2327 DDCreateOffScreen(wc);
2328
2329 if( FAILED( ddrval = wc->lpDD->lpVtbl->CreateClipper(wc->lpDD, 0, &pcClipper, NULL ) ) )
2330 return E_FAIL;
2331
2332 if( FAILED( ddrval = pcClipper->lpVtbl->SetHWnd(pcClipper, 0, wc->hwnd ) ) )
2333 {
2334 pcClipper->lpVtbl->Release(pcClipper);
2335 return E_FAIL;
2336 }
2337
2338 if( FAILED( ddrval = wc->lpDDSPrimary->lpVtbl->SetClipper(wc->lpDDSPrimary, pcClipper ) ) )
2339 {
2340 pcClipper->lpVtbl->Release(pcClipper);
2341 return E_FAIL;
2342 }
2343
2344 // Done with clipper
2345 pcClipper->lpVtbl->Release(pcClipper);
2346 AddContext(wc);
2347 // Hook the window so we can update the drawing rectangle when the window moves
2348 wc->oldWndProc = SetWindowLong(wc->hwnd,GWL_WNDPROC,(LONG)MyWndProc);
2349
2350 return TRUE;
2351
2352 } /* DDInit */
2353
2354 static void DDFree( WMesaContext wc)
2355 {
2356 RemoveContext(wc->hwnd);
2357 SetWindowLong(wc->hwnd,GWL_WNDPROC,(LONG)(wc->oldWndProc));
2358 wc->oldWndProc = 0;
2359 if( wc->lpDD != NULL )
2360 {
2361 DDFreePrimarySurface(wc);
2362 DDDeleteOffScreen(wc);
2363 wc->lpDD->lpVtbl->Release(wc->lpDD);
2364 wc->lpDD = NULL;
2365 }
2366 // Clean up the screen on exit
2367 RedrawWindow( NULL, NULL, NULL, RDW_INVALIDATE | RDW_ERASE |
2368 RDW_ALLCHILDREN );
2369
2370 }
2371 #endif
2372
2373 void WMesaMove(void)
2374 {
2375 WMesaContext wc = Current;
2376 POINT pt;
2377 if (Current != NULL){
2378 GetClientRect( wc->hwnd, &(wc->rectSurface) );
2379 pt.x = pt.y = 0;
2380 ClientToScreen( wc->hwnd, &pt );
2381 OffsetRect(&(wc->rectSurface), pt.x, pt.y);
2382 }
2383 }
2384
2385
2386 /************************************************
2387 * Mesa 4.0 - These triangle rasterizers are not
2388 * implemented in this version of the Windows
2389 * driver. They could be implemented for a
2390 * potential performance improvement.
2391 * See OSMesa for an example of the approach
2392 * to use.
2393 * This old code is left in this file in case
2394 * it is useful. However, it may end up looking
2395 * a lot more like the OSMesa code.
2396 ************************************************/
2397
2398
2399 #if defined(FAST_RASTERIZERS)
2400
2401
2402 /*
2403 * Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable
2404 * shortcut.
2405 */
2406 #define PACK_8B8G8R( R, G, B ) ( ((B) << 16) | ((G) << 8) | (R) )
2407
2408 /**********************************************************************/
2409 /*** Triangle rendering ***/
2410 /**********************************************************************/
2411
2412 /*
2413 * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
2414 */
2415 static void smooth_8A8B8G8R_z_triangle( GLcontext *ctx,
2416 GLuint v0, GLuint v1, GLuint v2,
2417 GLuint pv )
2418 {
2419 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2420 #define INTERP_Z 1
2421 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
2422 #define INTERP_RGB 1
2423 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2424 #define PIXEL_TYPE GLuint
2425 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2426 #define BYTES_PER_ROW (wmesa->ScanWidth)
2427 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2428 { \
2429 GLint i, len = RIGHT-LEFT; \
2430 for (i=0;i<len;i++) { \
2431 GLdepth z = FixedToDepth(ffz); \
2432 if (z < zRow[i]) { \
2433 pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2434 FixedToInt(ffb) ); \
2435 zRow[i] = z; \
2436 } \
2437 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2438 ffz += fdzdx; \
2439 } \
2440 }
2441
2442 #ifdef __MINGW32__
2443 #include "tritemp.h"
2444 #else
2445
2446 #ifdef WIN32
2447 // #include "..\tritemp.h"
2448 #else
2449 #include "tritemp.h"
2450 #endif
2451 #endif
2452 }
2453
2454
2455 /*
2456 * XImage, smooth, depth-buffered, PF_8R8G8B triangle.
2457 */
2458 static void smooth_8R8G8B_z_triangle( GLcontext *ctx,
2459 GLuint v0, GLuint v1, GLuint v2,
2460 GLuint pv )
2461 {
2462 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2463 #define INTERP_Z 1
2464 #define INTERP_RGB 1
2465 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2466 #define PIXEL_TYPE GLuint
2467 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2468 #define BYTES_PER_ROW (wmesa->ScanWidth)
2469 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2470 { \
2471 GLint i, len = RIGHT-LEFT; \
2472 for (i=0;i<len;i++) { \
2473 GLdepth z = FixedToDepth(ffz); \
2474 if (z < zRow[i]) { \
2475 pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2476 FixedToInt(ffb) ); \
2477 zRow[i] = z; \
2478 } \
2479 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2480 ffz += fdzdx; \
2481 } \
2482 }
2483 #ifdef __MINGW32__
2484 #include "tritemp.h"
2485 #else
2486
2487 #ifdef WIN32
2488 // #include "..\tritemp.h"
2489 #else
2490 #include "tritemp.h"
2491 #endif
2492 #endif
2493 }
2494
2495
2496
2497 /*
2498 * XImage, smooth, depth-buffered, PF_5R6G5B triangle.
2499 */
2500 static void smooth_5R6G5B_z_triangle( GLcontext *ctx,
2501 GLuint v0, GLuint v1, GLuint v2,
2502 GLuint pv )
2503 {
2504 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2505 #define INTERP_Z 1
2506 #define INTERP_RGB 1
2507 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2508 #define PIXEL_TYPE GLushort
2509 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2510 #define BYTES_PER_ROW (wmesa->ScanWidth)
2511 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2512 { \
2513 GLint i, len = RIGHT-LEFT; \
2514 for (i=0;i<len;i++) { \
2515 GLdepth z = FixedToDepth(ffz); \
2516 if (z < zRow[i]) { \
2517 pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2518 FixedToInt(ffb) ); \
2519 zRow[i] = z; \
2520 } \
2521 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2522 ffz += fdzdx; \
2523 } \
2524 }
2525 #ifdef __MINGW32__
2526 #include "tritemp.h"
2527 #else
2528
2529 #ifdef WIN32
2530 // #include "..\tritemp.h"
2531 #else
2532 #include "tritemp.h"
2533 #endif
2534 #endif
2535 }
2536
2537 /*
2538 * XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
2539 */
2540 static void flat_8A8B8G8R_z_triangle( GLcontext *ctx, GLuint v0,
2541 GLuint v1, GLuint v2, GLuint pv )
2542 {
2543 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2544 #define INTERP_Z 1
2545 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2546 #define PIXEL_TYPE GLuint
2547 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2548 #define BYTES_PER_ROW (wmesa->ScanWidth)
2549 #define SETUP_CODE \
2550 unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \
2551 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2552 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2553 { \
2554 GLint i, len = RIGHT-LEFT; \
2555 for (i=0;i<len;i++) { \
2556 GLdepth z = FixedToDepth(ffz); \
2557 if (z < zRow[i]) { \
2558 pRow[i] = p; \
2559 zRow[i] = z; \
2560 } \
2561 ffz += fdzdx; \
2562 } \
2563 }
2564 #ifdef __MINGW32__
2565 #include "tritemp.h"
2566 #else
2567
2568 #ifdef WIN32
2569 // #include "..\tritemp.h"
2570 #else
2571 #include "tritemp.h"
2572 #endif
2573 #endif
2574 }
2575
2576
2577 /*
2578 * XImage, flat, depth-buffered, PF_8R8G8B triangle.
2579 */
2580 static void flat_8R8G8B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2581 GLuint v2, GLuint pv )
2582 {
2583 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2584 #define INTERP_Z 1
2585 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2586 #define PIXEL_TYPE GLuint
2587 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2588 #define BYTES_PER_ROW (wmesa->ScanWidth)
2589 #define SETUP_CODE \
2590 unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \
2591 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2592 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2593 { \
2594 GLint i, len = RIGHT-LEFT; \
2595 for (i=0;i<len;i++) { \
2596 GLdepth z = FixedToDepth(ffz); \
2597 if (z < zRow[i]) { \
2598 pRow[i] = p; \
2599 zRow[i] = z; \
2600 } \
2601 ffz += fdzdx; \
2602 } \
2603 }
2604 #ifdef __MINGW32__
2605 #include "tritemp.h"
2606 #else
2607
2608 #ifdef WIN32
2609 // #include "..\tritemp.h"
2610 #else
2611 #include "tritemp.h"
2612 #endif
2613 #endif
2614 }
2615
2616
2617 /*
2618 * XImage, flat, depth-buffered, PF_5R6G5B triangle.
2619 */
2620 static void flat_5R6G5B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2621 GLuint v2, GLuint pv )
2622 {
2623 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2624 #define INTERP_Z 1
2625 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2626 #define PIXEL_TYPE GLushort
2627 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2628 #define BYTES_PER_ROW (wmesa->ScanWidth)
2629 #define SETUP_CODE \
2630 unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \
2631 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2632 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2633 { \
2634 GLint i, len = RIGHT-LEFT; \
2635 for (i=0;i<len;i++) { \
2636 GLdepth z = FixedToDepth(ffz); \
2637 if (z < zRow[i]) { \
2638 pRow[i] = p; \
2639 zRow[i] = z; \
2640 } \
2641 ffz += fdzdx; \
2642 } \
2643 }
2644 #ifdef __MINGW32__
2645 #include "tritemp.h"
2646 #else
2647
2648 #ifdef WIN32
2649 // #include "..\tritemp.h"
2650 #else
2651 #include "tritemp.h"
2652 #endif
2653 #endif
2654 }
2655
2656
2657 /*
2658 * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
2659 */
2660 static void smooth_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2661 GLuint v2, GLuint pv )
2662 {
2663 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2664 #define INTERP_RGB 1
2665 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2666 #define PIXEL_TYPE GLuint
2667 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2668 #define BYTES_PER_ROW (wmesa->ScanWidth)
2669 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2670 { \
2671 GLint xx; \
2672 PIXEL_TYPE *pixel = pRow; \
2673 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2674 *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2675 FixedToInt(ffb) ); \
2676 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2677 } \
2678 }
2679 #ifdef __MINGW32__
2680 #include "tritemp.h"
2681 #else
2682
2683 #ifdef WIN32
2684 // #include "..\tritemp.h"
2685 #else
2686 #include "tritemp.h"
2687 #endif
2688 #endif
2689 }
2690
2691
2692 /*
2693 * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
2694 */
2695 static void smooth_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2696 GLuint v2, GLuint pv )
2697 {
2698 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2699 #define INTERP_RGB 1
2700 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2701 #define PIXEL_TYPE GLuint
2702 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2703 #define BYTES_PER_ROW (wmesa->ScanWidth)
2704 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2705 { \
2706 GLint xx; \
2707 PIXEL_TYPE *pixel = pRow; \
2708 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2709 *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2710 FixedToInt(ffb) ); \
2711 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2712 } \
2713 }
2714 #ifdef __MINGW32__
2715 #include "tritemp.h"
2716 #else
2717
2718 #ifdef WIN32
2719 // #include "..\tritemp.h"
2720 #else
2721 #include "tritemp.h"
2722 #endif
2723 #endif
2724 }
2725
2726
2727 /*
2728 * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
2729 */
2730 static void smooth_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2731 GLuint v2, GLuint pv )
2732 {
2733 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2734 #define INTERP_RGB 1
2735 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2736 #define PIXEL_TYPE GLushort
2737 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2738 #define BYTES_PER_ROW (wmesa->ScanWidth)
2739 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2740 { \
2741 GLint xx; \
2742 PIXEL_TYPE *pixel = pRow; \
2743 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2744 *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2745 FixedToInt(ffb) ); \
2746 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2747 } \
2748 }
2749 #ifdef __MINGW32__
2750 #include "tritemp.h"
2751 #else
2752
2753 #ifdef WIN32
2754 // #include "..\tritemp.h"
2755 #else
2756 #include "tritemp.h"
2757 #endif
2758 #endif
2759 }
2760
2761
2762
2763 /*
2764 * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
2765 */
2766 static void flat_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0,
2767 GLuint v1, GLuint v2, GLuint pv )
2768 {
2769 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2770 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2771 #define PIXEL_TYPE GLuint
2772 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2773 #define BYTES_PER_ROW (wmesa->ScanWidth)
2774 #define SETUP_CODE \
2775 unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \
2776 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2777 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2778 { \
2779 GLint xx; \
2780 PIXEL_TYPE *pixel = pRow; \
2781 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2782 *pixel = p; \
2783 } \
2784 }
2785
2786 #ifdef __MINGW32__
2787 #include "tritemp.h"
2788 #else
2789
2790 #ifdef WIN32
2791 // #include "..\tritemp.h"
2792 #else
2793 #include "tritemp.h"
2794 #endif
2795 #endif
2796 }
2797
2798
2799 /*
2800 * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
2801 */
2802 static void flat_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2803 GLuint v2, GLuint pv )
2804 {
2805 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2806 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2807 #define PIXEL_TYPE GLuint
2808 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2809 #define BYTES_PER_ROW (wmesa->ScanWidth)
2810 #define SETUP_CODE \
2811 unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \
2812 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2813 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2814 { \
2815 GLint xx; \
2816 PIXEL_TYPE *pixel = pRow; \
2817 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2818 *pixel = p; \
2819 } \
2820 }
2821 #ifdef __MINGW32__
2822 #include "tritemp.h"
2823 #else
2824
2825 #ifdef WIN32
2826 // #include "..\tritemp.h"
2827 #else
2828 #include "tritemp.h"
2829 #endif
2830 #endif
2831 }
2832
2833
2834 /*
2835 * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
2836 */
2837 static void flat_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2838 GLuint v2, GLuint pv )
2839 {
2840 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2841 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2842 #define PIXEL_TYPE GLushort
2843 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2844 #define BYTES_PER_ROW (wmesa->ScanWidth)
2845 #define SETUP_CODE \
2846 unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \
2847 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2848 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2849 { \
2850 GLint xx; \
2851 PIXEL_TYPE *pixel = pRow; \
2852 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2853 *pixel = p; \
2854 } \
2855 }
2856 #ifdef __MINGW32__
2857 #include "tritemp.h"
2858 #else
2859
2860 #ifdef WIN32
2861 // #include "..\tritemp.h"
2862 #else
2863 #include "tritemp.h"
2864 #endif
2865 #endif
2866 }
2867
2868
2869 /*
2870 * XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
2871 */
2872
2873 static void smooth_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2874 GLuint v2, GLuint pv )
2875 {
2876 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2877 #define INTERP_Z 1
2878 #define INTERP_INDEX 1
2879 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2880 #define PIXEL_TYPE GLubyte
2881 #define BYTES_PER_ROW (wmesa->ScanWidth)
2882 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2883 { \
2884 GLint i, len = RIGHT-LEFT; \
2885 for (i=0;i<len;i++) { \
2886 GLdepth z = FixedToDepth(ffz); \
2887 if (z < zRow[i]) { \
2888 pRow[i] = FixedToInt(ffi); \
2889 zRow[i] = z; \
2890 } \
2891 ffi += fdidx; \
2892 ffz += fdzdx; \
2893 } \
2894 }
2895 #ifdef __MINGW32__
2896 #include "tritemp.h"
2897 #else
2898
2899 #ifdef WIN32
2900 // #include "..\tritemp.h"
2901 #else
2902 #include "tritemp.h"
2903 #endif
2904 #endif
2905 }
2906
2907
2908 /*
2909 * XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
2910 */
2911
2912 static void flat_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2913 GLuint v2, GLuint pv )
2914 {
2915 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2916 #define INTERP_Z 1
2917 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2918 #define PIXEL_TYPE GLubyte
2919 #define BYTES_PER_ROW (wmesa->ScanWidth)
2920 #define SETUP_CODE \
2921 GLuint index = VB->IndexPtr->data[pv]; \
2922 (*ctx->Driver.Index)( ctx, index );
2923 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2924 { \
2925 GLint i, len = RIGHT-LEFT; \
2926 for (i=0;i<len;i++) { \
2927 GLdepth z = FixedToDepth(ffz); \
2928 if (z < zRow[i]) { \
2929 pRow[i] = index; \
2930 zRow[i] = z; \
2931 } \
2932 ffz += fdzdx; \
2933 } \
2934 }
2935 #ifdef __MINGW32__
2936 #include "tritemp.h"
2937 #else
2938
2939 #ifdef WIN32
2940 // #include "..\tritemp.h"
2941 #else
2942 #include "tritemp.h"
2943 #endif
2944 #endif
2945 }
2946
2947
2948
2949 /*
2950 * XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2951 */
2952
2953 static void smooth_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2954 GLuint v2, GLuint pv )
2955 {
2956 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2957 #define INTERP_Z 1
2958 #define INTERP_INDEX 1
2959 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2960 #define PIXEL_TYPE GLubyte
2961 #define BYTES_PER_ROW (wmesa->ScanWidth)
2962 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2963 { \
2964 GLint xx; \
2965 PIXEL_TYPE *pixel = pRow; \
2966 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2967 *pixel = FixedToInt(ffi); \
2968 ffi += fdidx; \
2969 } \
2970 }
2971 #ifdef __MINGW32__
2972 #include "tritemp.h"
2973 #else
2974
2975 #ifdef WIN32
2976 // #include "..\tritemp.h"
2977 #else
2978 #include "tritemp.h"
2979 #endif
2980 #endif
2981 }
2982
2983
2984 /*
2985 * XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2986 */
2987 static void flat_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2988 GLuint v2, GLuint pv )
2989 {
2990 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2991 #define INTERP_Z 1
2992 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2993 #define PIXEL_TYPE GLubyte
2994 #define BYTES_PER_ROW (wmesa->ScanWidth)
2995 #define SETUP_CODE \
2996 GLuint index = VB->IndexPtr->data[pv]; \
2997 (*ctx->Driver.Index)( ctx, index );
2998 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2999 { \
3000 GLint xx; \
3001 PIXEL_TYPE *pixel = pRow; \
3002 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
3003 *pixel = index; \
3004 } \
3005 }
3006 #ifdef __MINGW32__
3007 #include "tritemp.h"
3008 #else
3009
3010 #ifdef WIN32
3011 // #include "..\tritemp.h"
3012 #else
3013 #include "tritemp.h"
3014 #endif
3015 #endif
3016 }
3017
3018 /*
3019 * XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
3020 */
3021 static void smooth_DITHER8_z_triangle( GLcontext *ctx,
3022 GLuint v0, GLuint v1, GLuint v2,
3023 GLuint pv )
3024 {
3025 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
3026 DITHER_RGB_TO_8BIT_SETUP
3027 #define INTERP_Z 1
3028 #define INTERP_RGB 1
3029 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3030 #define PIXEL_TYPE GLubyte
3031 #define BYTES_PER_ROW (wmesa->ScanWidth)
3032 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3033 { \
3034 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
3035 for (i=0;i<len;i++,xx++) { \
3036 GLdepth z = FixedToDepth(ffz); \
3037 if (z < zRow[i]) { \
3038 DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg), \
3039 FixedToInt(ffb), xx, yy); \
3040 pRow[i] = pixelDithered; \
3041 zRow[i] = z; \
3042 } \
3043 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
3044 ffz += fdzdx; \
3045 } \
3046 }
3047 #ifdef __MINGW32__
3048 #include "tritemp.h"
3049 #else
3050
3051 #ifdef WIN32
3052 // #include "..\tritemp.h"
3053 #else
3054 #include "tritemp.h"
3055 #endif
3056 #endif
3057 }
3058
3059 /*
3060 * XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
3061 */
3062 static void flat_DITHER8_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
3063 GLuint v2, GLuint pv )
3064 {
3065 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
3066 DITHER_RGB_TO_8BIT_SETUP
3067 #define INTERP_Z 1
3068 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3069 #define PIXEL_TYPE GLubyte
3070 #define BYTES_PER_ROW (wmesa->ScanWidth)
3071
3072 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3073 { \
3074 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
3075 for (i=0;i<len;i++,xx++) { \
3076 GLdepth z = FixedToDepth(ffz); \
3077 if (z < zRow[i]) { \
3078 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \
3079 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \
3080 pRow[i] = pixelDithered; \
3081 zRow[i] = z; \
3082 } \
3083 ffz += fdzdx; \
3084 } \
3085 }
3086 #ifdef __MINGW32__
3087 #include "tritemp.h"
3088 #else
3089
3090 #ifdef WIN32
3091 // #include "..\tritemp.h"
3092 #else
3093 #include "tritemp.h"
3094 #endif
3095 #endif
3096 }
3097
3098 /*
3099 * XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
3100 */
3101 static void smooth_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
3102 GLuint v2, GLuint pv )
3103 {
3104 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
3105 DITHER_RGB_TO_8BIT_SETUP
3106 #define INTERP_RGB 1
3107 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3108 #define PIXEL_TYPE GLubyte
3109 #define BYTES_PER_ROW (wmesa->ScanWidth)
3110 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3111 { \
3112 GLint xx, yy = FLIP(Y); \
3113 PIXEL_TYPE *pixel = pRow; \
3114 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
3115 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy);\
3116 *pixel = pixelDithered; \
3117 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
3118 } \
3119 }
3120 #ifdef __MINGW32__
3121 #include "tritemp.h"
3122 #else
3123
3124 #ifdef WIN32
3125 // #include "..\tritemp.h"
3126 #else
3127 #include "tritemp.h"
3128 #endif
3129 #endif
3130 }
3131
3132 /*
3133 * XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
3134 */
3135
3136 static void flat_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
3137 GLuint v2, GLuint pv )
3138 {
3139 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
3140 DITHER_RGB_TO_8BIT_SETUP
3141 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3142 #define PIXEL_TYPE GLubyte
3143 #define BYTES_PER_ROW (wmesa->ScanWidth)
3144
3145 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3146 { \
3147 GLint xx, yy = FLIP(Y); \
3148 PIXEL_TYPE *pixel = pRow; \
3149 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
3150 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \
3151 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \
3152 *pixel = pixelDithered; \
3153 } \
3154 }
3155 #ifdef __MINGW32__
3156 #include "tritemp.h"
3157 #else
3158
3159 #ifdef WIN32
3160 // #include "..\tritemp.h"
3161 #else
3162 #include "tritemp.h"
3163 #endif
3164 #endif
3165 }
3166
3167 #endif
3168 /************** END DEAD TRIANGLE CODE ***********************/
3169
3170 static triangle_func choose_triangle_function( GLcontext *ctx )
3171 {
3172 #if 0
3173 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
3174 int depth = wmesa->cColorBits;
3175
3176 if (ctx->Polygon.SmoothFlag) return NULL;
3177 if (ctx->Texture._ReallyEnabled) return NULL;
3178 if (!wmesa->db_flag) return NULL;
3179 /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {
3180 if ( ctx->Light.ShadeModel==GL_SMOOTH
3181 && ctx->_RasterMask==DEPTH_BIT
3182 && ctx->Depth.Func==GL_LESS
3183 && ctx->Depth.Mask==GL_TRUE
3184 && ctx->Polygon.StippleFlag==GL_FALSE) {
3185 switch (wmesa->pixelformat) {
3186 case PF_8A8B8G8R:
3187 return smooth_8A8B8G8R_z_triangle;
3188 case PF_8R8G8B:
3189 return smooth_8R8G8B_z_triangle;
3190 case PF_5R6G5B:
3191 return smooth_5R6G5B_z_triangle;
3192 case PF_DITHER8:
3193 return smooth_DITHER8_z_triangle;
3194 case PF_INDEX8:
3195 return smooth_ci_z_triangle;
3196 default:
3197 return NULL;
3198 }
3199 }
3200 if ( ctx->Light.ShadeModel==GL_FLAT
3201 && ctx->_RasterMask==DEPTH_BIT
3202 && ctx->Depth.Func==GL_LESS
3203 && ctx->Depth.Mask==GL_TRUE
3204 && ctx->Polygon.StippleFlag==GL_FALSE) {
3205 switch (wmesa->pixelformat) {
3206 case PF_8A8B8G8R:
3207 return flat_8A8B8G8R_z_triangle;
3208 case PF_8R8G8B:
3209 return flat_8R8G8B_z_triangle;
3210 case PF_5R6G5B:
3211 return flat_5R6G5B_z_triangle;
3212 case PF_DITHER8:
3213 return flat_DITHER8_z_triangle;
3214 case PF_INDEX8:
3215 return flat_ci_z_triangle;
3216 default:
3217 return NULL;
3218 }
3219 }
3220 if ( ctx->_RasterMask==0 /* no depth test */
3221 && ctx->Light.ShadeModel==GL_SMOOTH
3222 && ctx->Polygon.StippleFlag==GL_FALSE) {
3223 switch (wmesa->pixelformat) {
3224 case PF_8A8B8G8R:
3225 return smooth_8A8B8G8R_triangle;
3226 case PF_8R8G8B:
3227 return smooth_8R8G8B_triangle;
3228 case PF_5R6G5B:
3229 return smooth_5R6G5B_triangle;
3230 case PF_DITHER8:
3231 return smooth_DITHER8_triangle;
3232 case PF_INDEX8:
3233 return smooth_ci_triangle;
3234 default:
3235 return NULL;
3236 }
3237 }
3238
3239 if ( ctx->_RasterMask==0 /* no depth test */
3240 && ctx->Light.ShadeModel==GL_FLAT
3241 && ctx->Polygon.StippleFlag==GL_FALSE) {
3242 switch (wmesa->pixelformat) {
3243 case PF_8A8B8G8R:
3244 return flat_8A8B8G8R_triangle;
3245 case PF_8R8G8B:
3246 return flat_8R8G8B_triangle;
3247 case PF_5R6G5B:
3248 return flat_5R6G5B_triangle;
3249 case PF_DITHER8:
3250 return flat_DITHER8_triangle;
3251 case PF_INDEX8:
3252 return flat_ci_triangle;
3253 default:
3254 return NULL;
3255 }
3256 }
3257
3258 return NULL;
3259 }
3260 #endif
3261 }
3262
3263 /*
3264 * Define a new viewport and reallocate auxillary buffers if the size of
3265 * the window (color buffer) has changed.
3266 */
3267 void WMesaViewport( GLcontext *ctx,
3268 GLint x, GLint y, GLsizei width, GLsizei height )
3269 {
3270 assert(0); /* I don't think that this is being used. */
3271 #if 0
3272 /* Save viewport */
3273 ctx->Viewport.X = x;
3274 ctx->Viewport.Width = width;
3275 ctx->Viewport.Y = y;
3276 ctx->Viewport.Height = height;
3277
3278 /* compute scale and bias values */
3279 /* Pre-Keith 3.1 changes
3280 ctx->Viewport.Map.m[Sx] = (GLfloat) width / 2.0F;
3281 ctx->Viewport.Map.m[Tx] = ctx->Viewport.Sx + x;
3282 ctx->Viewport.Map.m[Sy] = (GLfloat) height / 2.0F;
3283 ctx->Viewport.Map.m[Ty] = ctx->Viewport.Sy + y;
3284 */
3285 ctx->Viewport.WindowMap.m[MAT_SX] = (GLfloat) width / 2.0F;
3286 ctx->Viewport.WindowMap.m[MAT_TX] = ctx->Viewport.WindowMap.m[MAT_SX] + x;
3287 ctx->Viewport.WindowMap.m[MAT_SY] = (GLfloat) height / 2.0F;
3288 ctx->Viewport.WindowMap.m[MAT_TY] = ctx->Viewport.WindowMap.m[MAT_SY] + y;
3289 #endif
3290 }