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