fix AccessViolation bug (#835861)
[mesa.git] / src / mesa / drivers / windows / gdi / wmesa.c
1 /* $Id: wmesa.c,v 1.2 2003/11/04 23:37:53 brianp 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 "imports.h"
40 #include "macros.h"
41 #include "matrix.h"
42 #include "mtypes.h"
43 #include "texformat.h"
44 #include "teximage.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 #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(GLcontext *ctx)
1036 {
1037 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );
1038 ctx->Driver.GetString = get_string;
1039 ctx->Driver.UpdateState = wmesa_update_state;
1040 ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
1041 ctx->Driver.GetBufferSize = buffer_size;
1042
1043 ctx->Driver.Accum = _swrast_Accum;
1044 ctx->Driver.Bitmap = _swrast_Bitmap;
1045 ctx->Driver.Clear = clear;
1046
1047 ctx->Driver.Flush = flush;
1048 ctx->Driver.ClearIndex = clear_index;
1049 ctx->Driver.ClearColor = clear_color;
1050 ctx->Driver.Enable = enable;
1051
1052 ctx->Driver.CopyPixels = _swrast_CopyPixels;
1053 ctx->Driver.DrawPixels = _swrast_DrawPixels;
1054 ctx->Driver.ReadPixels = _swrast_ReadPixels;
1055 ctx->Driver.DrawBuffer = _swrast_DrawBuffer;
1056
1057 ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
1058 ctx->Driver.TexImage1D = _mesa_store_teximage1d;
1059 ctx->Driver.TexImage2D = _mesa_store_teximage2d;
1060 ctx->Driver.TexImage3D = _mesa_store_teximage3d;
1061 ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
1062 ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
1063 ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
1064 ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
1065
1066 ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d;
1067 ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d;
1068 ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d;
1069 ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d;
1070 ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d;
1071 ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d;
1072
1073 ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
1074 ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
1075 ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
1076 ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
1077 ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
1078 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
1079 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
1080 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
1081 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
1082
1083 swdd->SetBuffer = set_buffer;
1084
1085 /* Pixel/span writing functions: */
1086 swdd->WriteRGBASpan = write_rgba_span;
1087 swdd->WriteRGBSpan = write_rgb_span;
1088 swdd->WriteMonoRGBASpan = write_mono_rgba_span;
1089 swdd->WriteRGBAPixels = write_rgba_pixels;
1090 swdd->WriteMonoRGBAPixels = write_mono_rgba_pixels;
1091 swdd->WriteCI32Span = write_ci32_span;
1092 swdd->WriteCI8Span = write_ci8_span;
1093 swdd->WriteMonoCISpan = write_mono_ci_span;
1094 swdd->WriteCI32Pixels = write_ci32_pixels;
1095 swdd->WriteMonoCIPixels = write_mono_ci_pixels;
1096
1097 swdd->ReadCI32Span = read_ci32_span;
1098 swdd->ReadRGBASpan = read_rgba_span;
1099 swdd->ReadCI32Pixels = read_ci32_pixels;
1100 swdd->ReadRGBAPixels = read_rgba_pixels;
1101
1102 }
1103
1104 static void wmesa_update_state( GLcontext *ctx, GLuint new_state )
1105 {
1106 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );
1107 TNLcontext *tnl = TNL_CONTEXT(ctx);
1108
1109 /*
1110 * XXX these function pointers could be initialized just once during
1111 * context creation since they don't depend on any state changes.
1112 * kws - This is true - this function gets called a lot and it
1113 * would be good to minimize setting all this when not needed.
1114 */
1115 #ifndef SET_FPOINTERS_ONCE
1116 SetFunctionPointers(ctx);
1117 #if 0
1118 ctx->Driver.GetString = get_string;
1119 ctx->Driver.UpdateState = wmesa_update_state;
1120 ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
1121 ctx->Driver.GetBufferSize = buffer_size;
1122
1123 ctx->Driver.Accum = _swrast_Accum;
1124 ctx->Driver.Bitmap = _swrast_Bitmap;
1125 ctx->Driver.Clear = clear;
1126
1127 ctx->Driver.Flush = flush;
1128 ctx->Driver.ClearIndex = clear_index;
1129 ctx->Driver.ClearColor = clear_color;
1130 ctx->Driver.Enable = enable;
1131
1132 ctx->Driver.CopyPixels = _swrast_CopyPixels;
1133 ctx->Driver.DrawPixels = _swrast_DrawPixels;
1134 ctx->Driver.ReadPixels = _swrast_ReadPixels;
1135
1136 ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
1137 ctx->Driver.TexImage1D = _mesa_store_teximage1d;
1138 ctx->Driver.TexImage2D = _mesa_store_teximage2d;
1139 ctx->Driver.TexImage3D = _mesa_store_teximage3d;
1140 ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
1141 ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
1142 ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
1143 ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
1144
1145 ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d;
1146 ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d;
1147 ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d;
1148 ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d;
1149 ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d;
1150 ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d;
1151
1152 ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
1153 ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
1154 ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
1155 ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
1156 ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
1157 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
1158 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
1159 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
1160 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
1161
1162 swdd->SetBuffer = set_buffer;
1163
1164 /* Pixel/span writing functions: */
1165 swdd->WriteRGBASpan = write_rgba_span;
1166 swdd->WriteRGBSpan = write_rgb_span;
1167 swdd->WriteMonoRGBASpan = write_mono_rgba_span;
1168 swdd->WriteRGBAPixels = write_rgba_pixels;
1169 swdd->WriteMonoRGBAPixels = write_mono_rgba_pixels;
1170 swdd->WriteCI32Span = write_ci32_span;
1171 swdd->WriteCI8Span = write_ci8_span;
1172 swdd->WriteMonoCISpan = write_mono_ci_span;
1173 swdd->WriteCI32Pixels = write_ci32_pixels;
1174 swdd->WriteMonoCIPixels = write_mono_ci_pixels;
1175
1176 swdd->ReadCI32Span = read_ci32_span;
1177 swdd->ReadRGBASpan = read_rgba_span;
1178 swdd->ReadCI32Pixels = read_ci32_pixels;
1179 swdd->ReadRGBAPixels = read_rgba_pixels;
1180 #endif // 0
1181 #endif // !SET_FPOINTERS_ONCE
1182 tnl->Driver.RunPipeline = _tnl_run_pipeline;
1183
1184 _swrast_InvalidateState( ctx, new_state );
1185 _swsetup_InvalidateState( ctx, new_state );
1186 _ac_InvalidateState( ctx, new_state );
1187 _tnl_InvalidateState( ctx, new_state );
1188 }
1189
1190
1191
1192
1193 /**********************************************************************/
1194 /***** WMesa API Functions *****/
1195 /**********************************************************************/
1196
1197
1198
1199 #define PAL_SIZE 256
1200 static void GetPalette(HPALETTE Pal,RGBQUAD *aRGB)
1201 {
1202 int i;
1203 HDC hdc;
1204 struct
1205 {
1206 WORD Version;
1207 WORD NumberOfEntries;
1208 PALETTEENTRY aEntries[PAL_SIZE];
1209 } Palette =
1210 {
1211 0x300,
1212 PAL_SIZE
1213 };
1214 hdc=GetDC(NULL);
1215 if (Pal!=NULL)
1216 GetPaletteEntries(Pal,0,PAL_SIZE,Palette.aEntries);
1217 else
1218 GetSystemPaletteEntries(hdc,0,PAL_SIZE,Palette.aEntries);
1219 if (GetSystemPaletteUse(hdc) == SYSPAL_NOSTATIC)
1220 {
1221 for(i = 0; i <PAL_SIZE; i++)
1222 Palette.aEntries[i].peFlags = PC_RESERVED;
1223 Palette.aEntries[255].peRed = 255;
1224 Palette.aEntries[255].peGreen = 255;
1225 Palette.aEntries[255].peBlue = 255;
1226 Palette.aEntries[255].peFlags = 0;
1227 Palette.aEntries[0].peRed = 0;
1228 Palette.aEntries[0].peGreen = 0;
1229 Palette.aEntries[0].peBlue = 0;
1230 Palette.aEntries[0].peFlags = 0;
1231 }
1232 else
1233 {
1234 int nStaticColors;
1235 int nUsableColors;
1236 nStaticColors = GetDeviceCaps(hdc, NUMCOLORS)/2;
1237 for (i=0; i<nStaticColors; i++)
1238 Palette.aEntries[i].peFlags = 0;
1239 nUsableColors = PAL_SIZE-nStaticColors;
1240 for (; i<nUsableColors; i++)
1241 Palette.aEntries[i].peFlags = PC_RESERVED;
1242 for (; i<PAL_SIZE-nStaticColors; i++)
1243 Palette.aEntries[i].peFlags = PC_RESERVED;
1244 for (i=PAL_SIZE-nStaticColors; i<PAL_SIZE; i++)
1245 Palette.aEntries[i].peFlags = 0;
1246 }
1247 ReleaseDC(NULL,hdc);
1248 for (i=0; i<PAL_SIZE; i++)
1249 {
1250 aRGB[i].rgbRed=Palette.aEntries[i].peRed;
1251 aRGB[i].rgbGreen=Palette.aEntries[i].peGreen;
1252 aRGB[i].rgbBlue=Palette.aEntries[i].peBlue;
1253 aRGB[i].rgbReserved=Palette.aEntries[i].peFlags;
1254 }
1255 }
1256
1257
1258 WMesaContext WMesaCreateContext( HWND hWnd, HPALETTE* Pal,
1259 GLboolean rgb_flag,
1260 GLboolean db_flag,
1261 GLboolean alpha_flag )
1262 {
1263 RECT CR;
1264 WMesaContext c;
1265 GLboolean true_color_flag;
1266
1267 c = (struct wmesa_context * ) calloc(1,sizeof(struct wmesa_context));
1268 if (!c)
1269 return NULL;
1270
1271 c->Window=hWnd;
1272 c->hDC = GetDC(hWnd);
1273 true_color_flag = GetDeviceCaps(c->hDC, BITSPIXEL) > 8;
1274 #ifdef DDRAW
1275 if(true_color_flag) c->rgb_flag = rgb_flag = GL_TRUE;
1276 #endif
1277
1278
1279 #ifdef DITHER
1280 if ((true_color_flag==GL_FALSE) && (rgb_flag == GL_TRUE)){
1281 c->dither_flag = GL_TRUE;
1282 #ifdef USE_WING
1283 c->hPalHalfTone = WinGCreateHalftonePalette();
1284 #else
1285 c->hPalHalfTone = CreateHalftonePalette(c->hDC);
1286 #endif
1287 }
1288 else
1289 c->dither_flag = GL_FALSE;
1290 #else
1291 c->dither_flag = GL_FALSE;
1292 #endif
1293
1294
1295 if (rgb_flag==GL_FALSE)
1296 {
1297 c->rgb_flag = GL_FALSE;
1298 #if 0
1299 /* Old WinG stuff???? */
1300 c->db_flag = db_flag =GL_TRUE; /* WinG requires double buffering */
1301 printf("Single buffer is not supported in color index mode, ",
1302 "setting to double buffer.\n");
1303 #endif
1304 }
1305 else
1306 {
1307 c->rgb_flag = GL_TRUE;
1308 }
1309 GetClientRect(c->Window,&CR);
1310 c->width=CR.right;
1311 c->height=CR.bottom;
1312 if (db_flag)
1313 {
1314 c->db_flag = 1;
1315 /* Double buffered */
1316 #ifndef DDRAW
1317 {
1318 wmCreateBackingStore(c, c->width, c->height);
1319
1320 }
1321 #endif
1322 }
1323 else
1324 {
1325 /* Single Buffered */
1326 if (c->rgb_flag)
1327 c->db_flag = 0;
1328 }
1329 #ifdef DDRAW
1330 if (DDInit(c,hWnd) == GL_FALSE) {
1331 free( (void *) c );
1332 exit(1);
1333 }
1334 #endif
1335
1336
1337 c->gl_visual = _mesa_create_visual(rgb_flag,
1338 db_flag, /* db_flag */
1339 GL_FALSE, /* stereo */
1340 8,8,8, /* r, g, b bits */
1341 alpha_flag ? 8 : 0, /* alpha bits */
1342 0, /* index bits */
1343 16, /* depth_bits */
1344 8, /* stencil_bits */
1345 16,16,16,/* accum_bits */
1346 alpha_flag ? 16 : 0, /* alpha accum */
1347 1);
1348
1349 if (!c->gl_visual) {
1350 return NULL;
1351 }
1352
1353 /* allocate a new Mesa context */
1354 c->gl_ctx = _mesa_create_context( c->gl_visual, NULL, (void *) c, GL_FALSE );
1355
1356 if (!c->gl_ctx) {
1357 _mesa_destroy_visual( c->gl_visual );
1358 free(c);
1359 return NULL;
1360 }
1361
1362 _mesa_enable_sw_extensions(c->gl_ctx);
1363 _mesa_enable_1_3_extensions(c->gl_ctx);
1364 _mesa_enable_1_4_extensions(c->gl_ctx);
1365
1366 c->gl_buffer = _mesa_create_framebuffer( c->gl_visual,
1367 c->gl_visual->depthBits > 0,
1368 c->gl_visual->stencilBits > 0,
1369 c->gl_visual->accumRedBits > 0,
1370 alpha_flag /* s/w alpha */ );
1371 if (!c->gl_buffer) {
1372 _mesa_destroy_visual( c->gl_visual );
1373 _mesa_free_context_data( c->gl_ctx );
1374 free(c);
1375 return NULL;
1376 }
1377
1378 /* Initialize the software rasterizer and helper modules.
1379 */
1380 {
1381 GLcontext *ctx = c->gl_ctx;
1382 _swrast_CreateContext( ctx );
1383 _ac_CreateContext( ctx );
1384 _tnl_CreateContext( ctx );
1385 _swsetup_CreateContext( ctx );
1386
1387 #ifdef SET_FPOINTERS_ONCE
1388 SetFunctionPointers(ctx);
1389 #endif // SET_FPOINTERS_ONCE
1390 _swsetup_Wakeup( ctx );
1391 }
1392 #ifdef COMPILE_SETPIXEL
1393 ChooseSetPixel(c);
1394 #endif
1395 return c;
1396 }
1397
1398 void WMesaDestroyContext( void )
1399 {
1400 WMesaContext c = Current;
1401 ReleaseDC(c->Window,c->hDC);
1402 WC = c;
1403 if(c->hPalHalfTone != NULL)
1404 DeleteObject(c->hPalHalfTone);
1405
1406 _swsetup_DestroyContext( c->gl_ctx );
1407 _tnl_DestroyContext( c->gl_ctx );
1408 _ac_DestroyContext( c->gl_ctx );
1409 _swrast_DestroyContext( c->gl_ctx );
1410
1411 _mesa_destroy_visual( c->gl_visual );
1412 _mesa_destroy_framebuffer( c->gl_buffer );
1413 _mesa_free_context_data( c->gl_ctx );
1414 free( (void *) c->gl_ctx);
1415
1416 if (c->db_flag)
1417 #ifdef DDRAW
1418 DDFree(c);
1419 #else
1420 wmDeleteBackingStore(c);
1421 #endif
1422 free( (void *) c );
1423 #if !defined(NO_PARALLEL)
1424 if(parallelMachine)
1425 PRDestroyRenderBuffer();
1426 #endif
1427
1428 // Destroyed context no longer valid
1429 WMesaMakeCurrent( NULL );
1430 }
1431
1432
1433 void WMesaMakeCurrent( WMesaContext c )
1434 {
1435 if(!c){
1436 Current = c;
1437 return;
1438 }
1439
1440 if(Current == c)
1441 return;
1442
1443 Current = c;
1444 wmesa_update_state(c->gl_ctx, 0);
1445 _mesa_make_current(c->gl_ctx, c->gl_buffer);
1446 if (Current->gl_ctx->Viewport.Width==0) {
1447 /* initialize viewport to window size */
1448 _mesa_Viewport( 0, 0, Current->width, Current->height );
1449 Current->gl_ctx->Scissor.Width = Current->width;
1450 Current->gl_ctx->Scissor.Height = Current->height;
1451 }
1452 if ((c->cColorBits <= 8 ) && (c->rgb_flag == GL_TRUE)){
1453 WMesaPaletteChange(c->hPalHalfTone);
1454 }
1455 }
1456
1457
1458
1459 void WMesaSwapBuffers( void )
1460 {
1461 HDC DC = Current->hDC;
1462 GET_CURRENT_CONTEXT(ctx);
1463
1464 /* If we're swapping the buffer associated with the current context
1465 * we have to flush any pending rendering commands first.
1466 */
1467 if (Current && Current->gl_ctx == ctx)
1468 _mesa_notifySwapBuffers(ctx);
1469
1470 if (Current->db_flag)
1471 wmFlush(Current);
1472 }
1473
1474
1475
1476 void WMesaPaletteChange(HPALETTE Pal)
1477 {
1478 #ifndef DDRAW
1479 int vRet;
1480 #endif
1481 LPPALETTEENTRY pPal;
1482 if (Current && (Current->rgb_flag==GL_FALSE ||
1483 Current->dither_flag == GL_TRUE))
1484 {
1485 pPal = (PALETTEENTRY *)malloc( 256 * sizeof(PALETTEENTRY));
1486 Current->hPal=Pal;
1487 GetPaletteEntries( Pal, 0, 256, pPal );
1488 #ifdef DDRAW
1489 Current->lpDD->lpVtbl->CreatePalette(Current->lpDD,DDPCAPS_8BIT,
1490 pPal, &(Current->lpDDPal), NULL);
1491 if (Current->lpDDPal)
1492 Current->lpDDSPrimary->lpVtbl->SetPalette(Current->lpDDSPrimary,
1493 Current->lpDDPal);
1494 #else
1495 vRet = SetDIBColorTable(Current->dib.hDC, 0, 256, (RGBQUAD*)pPal);
1496 #endif
1497 free( pPal );
1498 }
1499 }
1500
1501
1502
1503
1504 static unsigned char threeto8[8] = {
1505 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
1506 };
1507
1508 static unsigned char twoto8[4] = {
1509 0, 0x55, 0xaa, 0xff
1510 };
1511
1512 static unsigned char oneto8[2] = {
1513 0, 255
1514 };
1515
1516 static unsigned char componentFromIndex(UCHAR i, UINT nbits, UINT shift)
1517 {
1518 unsigned char val;
1519
1520 val = i >> shift;
1521 switch (nbits) {
1522
1523 case 1:
1524 val &= 0x1;
1525 return oneto8[val];
1526
1527 case 2:
1528 val &= 0x3;
1529 return twoto8[val];
1530
1531 case 3:
1532 val &= 0x7;
1533 return threeto8[val];
1534
1535 default:
1536 return 0;
1537 }
1538 }
1539
1540 void wmCreatePalette( PWMC pwdc )
1541 {
1542 /* Create a compressed and re-expanded 3:3:2 palette */
1543 int i;
1544 LOGPALETTE *pPal;
1545 BYTE rb, rs, gb, gs, bb, bs;
1546
1547 pwdc->nColors = 0x100;
1548
1549 pPal = (PLOGPALETTE)malloc(sizeof(LOGPALETTE) +
1550 pwdc->nColors * sizeof(PALETTEENTRY));
1551 memset( pPal, 0, sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY) );
1552
1553 pPal->palVersion = 0x300;
1554
1555 rb = REDBITS;
1556 rs = REDSHIFT;
1557 gb = GREENBITS;
1558 gs = GREENSHIFT;
1559 bb = BLUEBITS;
1560 bs = BLUESHIFT;
1561
1562 if (pwdc->db_flag) {
1563
1564 /* Need to make two palettes: one for the screen DC and one for the DIB. */
1565 pPal->palNumEntries = pwdc->nColors;
1566 for (i = 0; i < pwdc->nColors; i++) {
1567 pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
1568 pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
1569 pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
1570 pPal->palPalEntry[i].peFlags = 0;
1571 }
1572 pwdc->hGLPalette = CreatePalette( pPal );
1573 pwdc->hPalette = CreatePalette( pPal );
1574 }
1575
1576 else {
1577 pPal->palNumEntries = pwdc->nColors;
1578 for (i = 0; i < pwdc->nColors; i++) {
1579 pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
1580 pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
1581 pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
1582 pPal->palPalEntry[i].peFlags = 0;
1583 }
1584 pwdc->hGLPalette = CreatePalette( pPal );
1585 }
1586
1587 free(pPal);
1588
1589 }
1590
1591
1592 void
1593 #ifdef COMPILE_SETPIXEL
1594
1595 wmSetPixelDefault(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1596 {
1597 if (Current->db_flag)
1598 {
1599 #ifdef DDRAW
1600 HDC hdc = NULL;
1601 Current->lpDDSOffScreen->lpVtbl->Unlock(Current->lpDDSOffScreen,NULL);
1602 Current->lpDDSOffScreen->lpVtbl->GetDC(Current->lpDDSOffScreen,&hdc);
1603 SetPixelV(hdc,iPixel, iScanLine, RGB(r,g,b));
1604 Current->lpDDSOffScreen->lpVtbl->ReleaseDC(Current->lpDDSOffScreen,hdc);
1605 while (Current->lpDDSOffScreen->lpVtbl->Lock(Current->lpDDSOffScreen,NULL, &(Current->ddsd), 0, NULL) == DDERR_WASSTILLDRAWING);
1606 #else
1607 SetPixelV(Current->hDC, iPixel, iScanLine, RGB(r,g,b));
1608 #endif
1609 }
1610 else
1611 {
1612 SetPixelV(Current->hDC, iPixel+pwc->rectSurface.left, pwc->rectSurface.top+iScanLine, RGB(r,g,b));
1613 }
1614 }
1615 #else
1616 wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1617 {
1618 if (Current->db_flag)
1619 {
1620 LPBYTE lpb = pwc->pbPixels;
1621 UINT nBypp = pwc->cColorBits >> 3;
1622
1623 lpb += pwc->ScanWidth * iScanLine;
1624 lpb += iPixel * nBypp;
1625
1626 if(nBypp == 1)
1627 {
1628 if(pwc->dither_flag)
1629 *lpb = DITHER_RGB_2_8BIT(r,g,b,iScanLine,iPixel);
1630 else
1631 *lpb = BGR8(r,g,b);
1632 }
1633 else if(nBypp == 2)
1634 *((LPWORD)lpb) = BGR16(r,g,b);
1635 else if (nBypp == 3)
1636 {
1637 *lpb++ = b;
1638 *lpb++ = g;
1639 *lpb = r;
1640 }
1641 else if (nBypp == 4)
1642 *((LPDWORD)lpb) = BGR32(r,g,b);
1643 }
1644 else
1645 {
1646 SetPixel(Current->hDC, iPixel, iScanLine, RGB(r,g,b));
1647 }
1648 }
1649 #endif
1650 #ifdef COMPILE_SETPIXEL
1651 void wmSetPixel4(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1652 {
1653 LPDWORD lpdw = ((LPDWORD)(pwc->pbPixels + pwc->ScanWidth * iScanLine)) + iPixel;
1654 *lpdw = BGR32(r,g,b);
1655 // LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel + iPixel + iPixel;
1656 // *((LPDWORD)lpb) = BGR32(r,g,b);
1657 }
1658
1659 void wmSetPixel3(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1660 {
1661 LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel + iPixel;
1662 *lpb++ = b;
1663 *lpb++ = g;
1664 *lpb = r;
1665 }
1666
1667 void wmSetPixel2(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1668 {
1669 LPWORD lpw = ((LPWORD)(pwc->pbPixels + pwc->ScanWidth * iScanLine)) + iPixel;
1670 *lpw = BGR16(r,g,b);
1671 // LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel;
1672 // *((LPWORD)lpb) = BGR16(r,g,b);
1673 }
1674
1675 void wmSetPixel1(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1676 {
1677 LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel;
1678 *lpb = BGR8(r,g,b);
1679 }
1680
1681 void wmSetPixel1Dither(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1682 {
1683 LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel;
1684 *lpb = DITHER_RGB_2_8BIT(r,g,b,iScanLine,iPixel);
1685 }
1686
1687
1688 void ChooseSetPixel(PWMC pwc)
1689 {
1690 UINT nBypp = (pwc ) ? pwc->cColorBits >> 3 : 0;
1691 switch(nBypp)
1692 {
1693 case 1:
1694 pwc->wmSetPixel = pwc->dither_flag ? &wmSetPixel1Dither : &wmSetPixel1;
1695 break;
1696 case 2:
1697 pwc->wmSetPixel = &wmSetPixel2;
1698 break;
1699 case 3:
1700 pwc->wmSetPixel = &wmSetPixel3;
1701 break;
1702 case 4:
1703 pwc->wmSetPixel = &wmSetPixel4;
1704 break;
1705 default:
1706 pwc->wmSetPixel = &wmSetPixelDefault;
1707 break;
1708 }
1709 }
1710
1711 #endif
1712
1713 void wmCreateDIBSection(
1714 HDC hDC,
1715 PWMC pwc, // handle of device context
1716 CONST BITMAPINFO *pbmi, // bitmap size, format, and color data
1717 UINT iUsage // color data type indicator: RGB values or palette indices
1718 )
1719 {
1720 DWORD dwSize = 0;
1721 DWORD dwScanWidth;
1722 UINT nBypp = pwc->cColorBits / 8;
1723 HDC hic;
1724
1725 dwScanWidth = (((pwc->ScanWidth * nBypp)+ 3) & ~3);
1726
1727 pwc->ScanWidth =pwc->pitch = dwScanWidth;
1728
1729 if (stereo_flag)
1730 pwc->ScanWidth = 2* pwc->pitch;
1731
1732 dwSize = sizeof(BITMAPINFO) + (dwScanWidth * pwc->height);
1733 #ifdef USE_MAPPED_FILE
1734 pwc->dib.hFileMap = CreateFileMapping((HANDLE)PAGE_FILE,
1735 NULL,
1736 PAGE_READWRITE | SEC_COMMIT,
1737 0,
1738 dwSize,
1739 NULL);
1740
1741 if (!pwc->dib.hFileMap)
1742 return;
1743
1744 pwc->dib.base = MapViewOfFile(pwc->dib.hFileMap,
1745 FILE_MAP_ALL_ACCESS,
1746 0,
1747 0,
1748 0);
1749
1750 if(!pwc->dib.base){
1751 CloseHandle(pwc->dib.hFileMap);
1752 return;
1753 }
1754
1755
1756 CopyMemory(pwc->dib.base, pbmi, sizeof(BITMAPINFO));
1757 #endif // USE_MAPPED_FILE
1758
1759 hic = CreateIC("display", NULL, NULL, NULL);
1760 pwc->dib.hDC = CreateCompatibleDC(hic);
1761
1762 #ifdef USE_MAPPED_FILE
1763
1764 pwc->hbmDIB = CreateDIBSection(hic,
1765 &(pwc->bmi),
1766 (iUsage ? DIB_PAL_COLORS : DIB_RGB_COLORS),
1767 &(pwc->pbPixels),
1768 pwc->dib.hFileMap,
1769 0);
1770 #else
1771 pwc->hbmDIB = CreateDIBSection(hic,
1772 &(pwc->bmi),
1773 (iUsage ? DIB_PAL_COLORS : DIB_RGB_COLORS),
1774 &(pwc->pbPixels),
1775 0,
1776 0);
1777 #endif // USE_MAPPED_FILE
1778 pwc->ScreenMem = pwc->addrOffScreen = pwc->pbPixels;
1779 pwc->hOldBitmap = SelectObject(pwc->dib.hDC, pwc->hbmDIB);
1780
1781 DeleteDC(hic);
1782
1783 return;
1784
1785 }
1786
1787 /*
1788 * Blit memory DC to screen DC
1789 */
1790 BOOL wmFlush(PWMC pwc)
1791 {
1792 BOOL bRet = 0;
1793 DWORD dwErr = 0;
1794 #ifdef DDRAW
1795 HRESULT ddrval;
1796 #endif
1797
1798 if(pwc->db_flag){
1799 #ifdef DDRAW
1800 if (pwc->lpDDSOffScreen == NULL)
1801 if(DDCreateOffScreen(pwc) == GL_FALSE)
1802 return FALSE;
1803
1804 pwc->lpDDSOffScreen->lpVtbl->Unlock(pwc->lpDDSOffScreen, NULL);
1805
1806 while( 1 )
1807 {
1808 ddrval = pwc->lpDDSPrimary->lpVtbl->Blt( pwc->lpDDSPrimary,
1809 &(pwc->rectSurface),
1810 pwc->lpDDSOffScreen,
1811 &(pwc->rectOffScreen),
1812 0, NULL );
1813
1814 if( ddrval == DD_OK )
1815 {
1816 break;
1817 }
1818 if( ddrval == DDERR_SURFACELOST )
1819 {
1820 if(!DDRestoreAll(pwc))
1821 {
1822 break;
1823 }
1824 }
1825 if( ddrval != DDERR_WASSTILLDRAWING )
1826 {
1827 break;
1828 }
1829 }
1830
1831 while (pwc->lpDDSOffScreen->lpVtbl->Lock(pwc->lpDDSOffScreen,
1832 NULL, &(pwc->ddsd), 0, NULL) ==
1833 DDERR_WASSTILLDRAWING)
1834 ;
1835
1836 if(ddrval != DD_OK)
1837 dwErr = GetLastError();
1838 #else
1839 bRet = BitBlt(pwc->hDC, 0, 0, pwc->width, pwc->height,
1840 pwc->dib.hDC, 0, 0, SRCCOPY);
1841 #endif
1842 }
1843
1844 return(TRUE);
1845
1846 }
1847
1848
1849 /* The following code is added by Li Wei to enable stereo display */
1850
1851 #if !defined(NO_STEREO)
1852
1853 static void __gluMakeIdentityf(GLfloat m[16])
1854 {
1855 m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0;
1856 m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0;
1857 m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0;
1858 m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1;
1859 }
1860
1861 static void normalize(float v[3])
1862 {
1863 float r;
1864
1865 r = sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] );
1866 if (r == 0.0) return;
1867
1868 v[0] /= r;
1869 v[1] /= r;
1870 v[2] /= r;
1871 }
1872
1873 static void cross(float v1[3], float v2[3], float result[3])
1874 {
1875 result[0] = v1[1]*v2[2] - v1[2]*v2[1];
1876 result[1] = v1[2]*v2[0] - v1[0]*v2[2];
1877 result[2] = v1[0]*v2[1] - v1[1]*v2[0];
1878 }
1879
1880
1881 static void
1882 __gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx,
1883 GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy,
1884 GLdouble upz)
1885 {
1886 int i;
1887 float forward[3], side[3], up[3];
1888 GLfloat m[4][4];
1889
1890 forward[0] = centerx - eyex;
1891 forward[1] = centery - eyey;
1892 forward[2] = centerz - eyez;
1893
1894 up[0] = upx;
1895 up[1] = upy;
1896 up[2] = upz;
1897
1898 normalize(forward);
1899
1900 /* Side = forward x up */
1901 cross(forward, up, side);
1902 normalize(side);
1903
1904 /* Recompute up as: up = side x forward */
1905 cross(side, forward, up);
1906
1907 __gluMakeIdentityf(&m[0][0]);
1908 m[0][0] = side[0];
1909 m[1][0] = side[1];
1910 m[2][0] = side[2];
1911
1912 m[0][1] = up[0];
1913 m[1][1] = up[1];
1914 m[2][1] = up[2];
1915
1916 m[0][2] = -forward[0];
1917 m[1][2] = -forward[1];
1918 m[2][2] = -forward[2];
1919
1920 glMultMatrixf(&m[0][0]);
1921 glTranslated(-eyex, -eyey, -eyez);
1922 }
1923
1924 GLfloat viewDistance = 1.0;
1925
1926 void WMesaShowStereo(GLuint list)
1927 {
1928
1929 GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
1930 GLfloat cm[16];
1931 GLint matrix_mode;
1932 /* Must use double Buffer */
1933 if( ! Current-> db_flag )
1934 return;
1935
1936
1937 glGetIntegerv(GL_MATRIX_MODE,&matrix_mode);
1938
1939 WMesaViewport(Current->gl_ctx,0,Current->height/2,
1940 Current->width,Current->height/2);
1941 if(matrix_mode!=GL_MODELVIEW)
1942 glMatrixMode(GL_MODELVIEW);
1943
1944 glGetFloatv(GL_MODELVIEW_MATRIX,cm);
1945 glLoadIdentity();
1946 __gluLookAt(viewDistance/2,0.0,0.0 ,
1947 viewDistance/2,0.0,-1.0,
1948 0.0,1.0,0.0 );
1949 glMultMatrixf( cm );
1950
1951 Current->ScreenMem = Current->pbPixels = Current->addrOffScreen;
1952 glCallList( list );
1953
1954 glGetFloatv(GL_MODELVIEW_MATRIX,cm);
1955 glLoadIdentity();
1956 __gluLookAt(-viewDistance/2,0.0,0.0 ,
1957 -viewDistance/2,0.0,-1.0,
1958 0.0,1.0,0.0 );
1959 glMultMatrixf(cm);
1960
1961 Current->ScreenMem = Current->pbPixels = Current->addrOffScreen + Current->pitch;
1962 glCallList(list);
1963 if(matrix_mode!=GL_MODELVIEW)
1964 glMatrixMode(matrix_mode);
1965
1966 glFlush();
1967
1968 WMesaViewport(Current->gl_ctx,0,0,Current->width,Current->height);
1969 WMesaSwapBuffers();
1970 }
1971
1972 void toggleStereoMode()
1973 {
1974 if(!Current->db_flag)
1975 return;
1976 if(!stereo_flag){
1977 stereo_flag = 1;
1978 if(stereoBuffer==GL_FALSE)
1979 #if !defined(NO_PARALLEL)
1980 if(!parallelFlag)
1981 #endif
1982 {
1983 Current->ScanWidth = Current->pitch*2;
1984 }
1985 }
1986 else {
1987 stereo_flag = 0;
1988 #if !defined(NO_PARALLEL)
1989 if(!parallelFlag)
1990 #endif
1991 Current->ScanWidth = Current->pitch;
1992 Current->pbPixels = Current->addrOffScreen;
1993 }
1994 }
1995
1996 /* if in stereo mode, the following function is called */
1997 void glShowStereo(GLuint list)
1998 {
1999 WMesaShowStereo(list);
2000 }
2001
2002 #endif /* NO_STEREO */
2003
2004 #if !defined(NO_PARALLEL)
2005
2006 void toggleParallelMode(void)
2007 {
2008 if(!parallelFlag){
2009 parallelFlag = GL_TRUE;
2010 if(parallelMachine==GL_FALSE){
2011 PRCreateRenderBuffer( Current->rgb_flag? GL_RGBA :GL_COLOR_INDEX,
2012 Current->cColorBits/8,
2013 Current->width ,Current->height,
2014 Current->ScanWidth,
2015 Current->rgb_flag? Current->pbPixels:
2016 Current->ScreenMem);
2017 parallelMachine = GL_TRUE;
2018 }
2019 }
2020 else {
2021 parallelFlag = GL_FALSE;
2022 if(parallelMachine==GL_TRUE){
2023 PRDestroyRenderBuffer();
2024 parallelMachine=GL_FALSE;
2025 ReadyForNextFrame = GL_TRUE;
2026 }
2027
2028 /***********************************************
2029 * Seems something wrong!!!!
2030 ************************************************/
2031
2032 WMesaMakeCurrent(Current);
2033 #if !defined(NO_STEREO)
2034 stereo_flag = GL_FALSE ;
2035 #endif
2036 }
2037 }
2038
2039 void PRShowRenderResult(void)
2040 {
2041 int flag = 0;
2042 if(!glImageRendered())
2043 return;
2044
2045 if (parallelFlag)
2046 {
2047 WMesaSwapBuffers();
2048 }
2049
2050 }
2051 #endif /* NO_PARALLEL */
2052
2053 BYTE DITHER_RGB_2_8BIT( int red, int green, int blue, int pixel, int scanline)
2054 {
2055 char unsigned redtemp, greentemp, bluetemp, paletteindex;
2056
2057 //*** now, look up each value in the halftone matrix
2058 //*** using an 8x8 ordered dither.
2059 redtemp = aDividedBy51[red]
2060 + (aModulo51[red] > aHalftone8x8[(pixel%8)*8
2061 + scanline%8]);
2062 greentemp = aDividedBy51[(char unsigned)green]
2063 + (aModulo51[green] > aHalftone8x8[
2064 (pixel%8)*8 + scanline%8]);
2065 bluetemp = aDividedBy51[(char unsigned)blue]
2066 + (aModulo51[blue] > aHalftone8x8[
2067 (pixel%8)*8 +scanline%8]);
2068
2069 //*** recombine the halftoned rgb values into a palette index
2070 paletteindex =
2071 redtemp + aTimes6[greentemp] + aTimes36[bluetemp];
2072
2073 //*** and translate through the wing halftone palette
2074 //*** translation vector to give the correct value.
2075 return aWinGHalftoneTranslation[paletteindex];
2076 }
2077
2078 #ifdef DDRAW
2079 /*
2080 * restoreAll
2081 *
2082 * restore all lost objects
2083 */
2084 HRESULT DDRestoreAll( WMesaContext wc )
2085 {
2086 HRESULT ddrval;
2087
2088 ddrval = wc->lpDDSPrimary->lpVtbl->Restore(wc->lpDDSPrimary);
2089 if( ddrval == DD_OK )
2090 {
2091 ddrval = wc->lpDDSOffScreen->lpVtbl->Restore(wc->lpDDSOffScreen);
2092 }
2093 return ddrval;
2094
2095 } /* restoreAll */
2096
2097
2098 /*
2099 * This function is called if the initialization function fails
2100 */
2101 BOOL initFail( HWND hwnd, WMesaContext wc )
2102 {
2103 DDFree(wc);
2104 MessageBox( hwnd, "DirectDraw Init FAILED", "", MB_OK );
2105 return FALSE;
2106
2107 } /* initFail */
2108
2109
2110 static void DDDeleteOffScreen(WMesaContext wc)
2111 {
2112 if( wc->lpDDSOffScreen != NULL )
2113 {
2114 wc->lpDDSOffScreen->lpVtbl->Unlock(wc->lpDDSOffScreen,NULL);
2115 wc->lpDDSOffScreen->lpVtbl->Release(wc->lpDDSOffScreen);
2116 wc->lpDDSOffScreen = NULL;
2117 }
2118
2119 }
2120
2121 static void DDFreePrimarySurface(WMesaContext wc)
2122 {
2123 if( wc->lpDDSPrimary != NULL )
2124 {
2125 if(wc->db_flag == GL_FALSE)
2126 wc->lpDDSPrimary->lpVtbl->ReleaseDC(wc->lpDDSPrimary, wc->hDC);
2127 wc->lpDDSPrimary->lpVtbl->Release(wc->lpDDSPrimary);
2128 wc->lpDDSPrimary = NULL;
2129 }
2130 }
2131
2132 static BOOL DDCreatePrimarySurface(WMesaContext wc)
2133 {
2134 HRESULT ddrval;
2135 // DDSCAPS ddscaps;
2136 wc->ddsd.dwSize = sizeof( wc->ddsd );
2137 wc->ddsd.dwFlags = DDSD_CAPS;
2138 wc->ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2139
2140 ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD,&(wc->ddsd),
2141 &(wc->lpDDSPrimary), NULL );
2142 if( ddrval != DD_OK )
2143 {
2144 return initFail(wc->hwnd , wc);
2145 }
2146 if(wc->db_flag == GL_FALSE)
2147 wc->lpDDSPrimary->lpVtbl->GetDC(wc->lpDDSPrimary, &(wc->hDC));
2148 return TRUE;
2149 }
2150
2151 static BOOL DDCreateOffScreen(WMesaContext wc)
2152 {
2153 POINT pt;
2154 HRESULT ddrval;
2155 if(wc->lpDD == NULL)
2156 return FALSE;
2157 GetClientRect( wc->hwnd, &(wc->rectOffScreen) );
2158 wc->ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2159 wc->ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2160 wc->ddsd.dwHeight = wc->rectOffScreen.bottom - wc->rectOffScreen.top;
2161 wc->ddsd.dwWidth = wc->rectOffScreen.right - wc->rectOffScreen.left;
2162
2163 ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD, &(wc->ddsd),
2164 &(wc->lpDDSOffScreen), NULL );
2165 if( ddrval != DD_OK )
2166 {
2167 return FALSE;
2168 }
2169
2170 while (wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL,
2171 &(wc->ddsd), 0, NULL) ==
2172 DDERR_WASSTILLDRAWING)
2173 ;
2174
2175 if(wc->ddsd.lpSurface==NULL)
2176 return initFail(wc->hwnd, wc);
2177
2178 wc->ScreenMem = wc->pbPixels = wc->addrOffScreen =
2179 (PBYTE)(wc->ddsd.lpSurface);
2180 wc->ScanWidth = wc->pitch = wc->ddsd.lPitch;
2181 if (stereo_flag)
2182 wc->ScanWidth = wc->ddsd.lPitch*2;
2183
2184 GetClientRect( wc->hwnd, &(wc->rectSurface) );
2185 pt.x = pt.y = 0;
2186 ClientToScreen( wc->hwnd, &pt );
2187 OffsetRect(&(wc->rectSurface), pt.x, pt.y);
2188 wmSetPixelFormat(wc, wc->hDC);
2189 return TRUE;
2190 }
2191
2192 typedef
2193 struct tagWMesaContextList
2194 {
2195 WMesaContext wc;
2196 struct tagWMesaContextList *next;
2197 }WMesaContextList;
2198
2199 WMesaContextList *head = 0;
2200
2201 void AddContext(WMesaContext wc)
2202 {
2203 WMesaContextList *lst = (WMesaContextList *)malloc(sizeof(WMesaContextList));
2204 lst->wc = wc;
2205 if( head )
2206 lst->next = head;
2207 head = lst;
2208 }
2209
2210 WMesaContext FindContext(HWND hWnd)
2211 {
2212 WMesaContextList *tmp = head;
2213 while(tmp)
2214 {
2215 if( tmp->wc->hwnd == hWnd )
2216 return tmp->wc;
2217 tmp = tmp->next;
2218 }
2219 return NULL;
2220 }
2221
2222 void RemoveContext(HWND hWnd)
2223 {
2224 WMesaContextList *tmp = head;
2225 if(tmp )
2226 {
2227 if( tmp->wc->hwnd == hWnd )
2228 {
2229 WMesaContextList *lst = tmp;
2230
2231 head = tmp->next;
2232 free((void *)lst);
2233 }
2234 else
2235 while(tmp->next)
2236 {
2237 if( tmp->next->wc->hwnd == hWnd )
2238 {
2239 WMesaContextList *lst = tmp->next;
2240 tmp->next = tmp->next->next;
2241 free((void *)lst);
2242 }
2243 tmp = tmp->next;
2244 }
2245 }
2246 }
2247
2248 static LRESULT CALLBACK MyWndProc(HWND hwnd,UINT message,WPARAM wParam, LPARAM lParam)
2249 {
2250 WMesaContext wc;
2251
2252 if (Current==0 || Current->hwnd != hwnd)
2253 wc=FindContext(hwnd);
2254 else
2255 wc=Current;
2256
2257
2258 if( wc )
2259 {
2260 LRESULT lret = CallWindowProc((WNDPROC)(wc->oldWndProc),hwnd,message,wParam,lParam);
2261 if( message = WM_MOVE )
2262 {
2263 POINT pt = {0};
2264 GetClientRect( wc->hwnd, &(wc->rectSurface) );
2265 ClientToScreen( hwnd, &pt );
2266 OffsetRect(&(wc->rectSurface), pt.x, pt.y);
2267 }
2268 return lret;
2269 }
2270 return 0L;
2271 }
2272
2273 /*
2274 * doInit - do work required for every instance of the application:
2275 * create the window, initialize data
2276 */
2277 static BOOL DDInit( WMesaContext wc, HWND hwnd)
2278 {
2279 HRESULT ddrval;
2280 // DWORD dwFrequency;
2281
2282 // LPDIRECTDRAW lpDD; // DirectDraw object
2283 // LPDIRECTDRAW2 lpDD2;
2284 LPDIRECTDRAWCLIPPER pcClipper = NULL;
2285
2286 wc->fullScreen = displayOptions.fullScreen;
2287 wc->gMode = displayOptions.mode;
2288 wc->hwnd = hwnd;
2289 stereo_flag = displayOptions.stereo;
2290 if(wc->db_flag!= GL_TRUE)
2291 stereo_flag = GL_FALSE;
2292 /*
2293 * create the main DirectDraw object
2294 */
2295 ddrval = DirectDrawCreate( NULL, &(wc->lpDD), NULL );
2296 if( ddrval != DD_OK )
2297 {
2298 return initFail(hwnd,wc);
2299 }
2300
2301 // Get exclusive mode if requested
2302 if(wc->fullScreen)
2303 {
2304 ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd,
2305 DDSCL_EXCLUSIVE |
2306 DDSCL_FULLSCREEN );
2307 }
2308 else
2309 {
2310 ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd,
2311 DDSCL_NORMAL );
2312 }
2313 if( ddrval != DD_OK )
2314 {
2315 return initFail(hwnd , wc);
2316 }
2317
2318
2319 if(ddrval != DD_OK)
2320 return initFail(hwnd , wc);
2321
2322
2323 switch( wc->gMode )
2324 {
2325 case 1:
2326 ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 640, 480,
2327 displayOptions.bpp);
2328 break;
2329 case 2:
2330 ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 800, 600,
2331 displayOptions.bpp);
2332 break;
2333 case 3:
2334 ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1024, 768,
2335 displayOptions.bpp);
2336 break;
2337 case 4:
2338 ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1152, 864,
2339 displayOptions.bpp);
2340 break;
2341 case 5:
2342 ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1280, 1024,
2343 displayOptions.bpp);
2344 break;
2345 }
2346
2347 if( ddrval != DD_OK )
2348 {
2349 printf("Can't modify display mode, current mode used\n");
2350 }
2351 switch(ddrval){
2352 case DDERR_INVALIDOBJECT:
2353 break;
2354 case DDERR_INVALIDPARAMS:
2355 break;
2356 case DDERR_UNSUPPORTEDMODE:
2357 ;
2358 }
2359
2360 if(DDCreatePrimarySurface(wc) == GL_FALSE)
2361 return initFail(hwnd, wc);
2362
2363 if(wc->db_flag)
2364 DDCreateOffScreen(wc);
2365
2366 if( FAILED( ddrval = wc->lpDD->lpVtbl->CreateClipper(wc->lpDD, 0, &pcClipper, NULL ) ) )
2367 return E_FAIL;
2368
2369 if( FAILED( ddrval = pcClipper->lpVtbl->SetHWnd(pcClipper, 0, wc->hwnd ) ) )
2370 {
2371 pcClipper->lpVtbl->Release(pcClipper);
2372 return E_FAIL;
2373 }
2374
2375 if( FAILED( ddrval = wc->lpDDSPrimary->lpVtbl->SetClipper(wc->lpDDSPrimary, pcClipper ) ) )
2376 {
2377 pcClipper->lpVtbl->Release(pcClipper);
2378 return E_FAIL;
2379 }
2380
2381 // Done with clipper
2382 pcClipper->lpVtbl->Release(pcClipper);
2383 AddContext(wc);
2384 // Hook the window so we can update the drawing rectangle when the window moves
2385 wc->oldWndProc = SetWindowLong(wc->hwnd,GWL_WNDPROC,(LONG)MyWndProc);
2386
2387 return TRUE;
2388
2389 } /* DDInit */
2390
2391 static void DDFree( WMesaContext wc)
2392 {
2393 RemoveContext(wc->hwnd);
2394 SetWindowLong(wc->hwnd,GWL_WNDPROC,(LONG)(wc->oldWndProc));
2395 wc->oldWndProc = 0;
2396 if( wc->lpDD != NULL )
2397 {
2398 DDFreePrimarySurface(wc);
2399 DDDeleteOffScreen(wc);
2400 wc->lpDD->lpVtbl->Release(wc->lpDD);
2401 wc->lpDD = NULL;
2402 }
2403 // Clean up the screen on exit
2404 RedrawWindow( NULL, NULL, NULL, RDW_INVALIDATE | RDW_ERASE |
2405 RDW_ALLCHILDREN );
2406
2407 }
2408 #endif
2409
2410 void WMesaMove(void)
2411 {
2412 WMesaContext wc = Current;
2413 POINT pt;
2414 if (Current != NULL){
2415 GetClientRect( wc->hwnd, &(wc->rectSurface) );
2416 pt.x = pt.y = 0;
2417 ClientToScreen( wc->hwnd, &pt );
2418 OffsetRect(&(wc->rectSurface), pt.x, pt.y);
2419 }
2420 }
2421
2422
2423 /************************************************
2424 * Mesa 4.0 - These triangle rasterizers are not
2425 * implemented in this version of the Windows
2426 * driver. They could be implemented for a
2427 * potential performance improvement.
2428 * See OSMesa for an example of the approach
2429 * to use.
2430 * This old code is left in this file in case
2431 * it is useful. However, it may end up looking
2432 * a lot more like the OSMesa code.
2433 ************************************************/
2434
2435
2436 #if defined(FAST_RASTERIZERS)
2437
2438
2439 /*
2440 * Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable
2441 * shortcut.
2442 */
2443 #define PACK_8B8G8R( R, G, B ) ( ((B) << 16) | ((G) << 8) | (R) )
2444
2445 /**********************************************************************/
2446 /*** Triangle rendering ***/
2447 /**********************************************************************/
2448
2449 /*
2450 * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
2451 */
2452 static void smooth_8A8B8G8R_z_triangle( GLcontext *ctx,
2453 GLuint v0, GLuint v1, GLuint v2,
2454 GLuint pv )
2455 {
2456 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2457 #define INTERP_Z 1
2458 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
2459 #define INTERP_RGB 1
2460 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2461 #define PIXEL_TYPE GLuint
2462 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2463 #define BYTES_PER_ROW (wmesa->ScanWidth)
2464 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2465 { \
2466 GLint i, len = RIGHT-LEFT; \
2467 for (i=0;i<len;i++) { \
2468 GLdepth z = FixedToDepth(ffz); \
2469 if (z < zRow[i]) { \
2470 pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2471 FixedToInt(ffb) ); \
2472 zRow[i] = z; \
2473 } \
2474 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2475 ffz += fdzdx; \
2476 } \
2477 }
2478
2479 #ifdef __MINGW32__
2480 #include "tritemp.h"
2481 #else
2482
2483 #ifdef WIN32
2484 // #include "..\tritemp.h"
2485 #else
2486 #include "tritemp.h"
2487 #endif
2488 #endif
2489 }
2490
2491
2492 /*
2493 * XImage, smooth, depth-buffered, PF_8R8G8B triangle.
2494 */
2495 static void smooth_8R8G8B_z_triangle( GLcontext *ctx,
2496 GLuint v0, GLuint v1, GLuint v2,
2497 GLuint pv )
2498 {
2499 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2500 #define INTERP_Z 1
2501 #define INTERP_RGB 1
2502 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2503 #define PIXEL_TYPE GLuint
2504 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2505 #define BYTES_PER_ROW (wmesa->ScanWidth)
2506 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2507 { \
2508 GLint i, len = RIGHT-LEFT; \
2509 for (i=0;i<len;i++) { \
2510 GLdepth z = FixedToDepth(ffz); \
2511 if (z < zRow[i]) { \
2512 pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2513 FixedToInt(ffb) ); \
2514 zRow[i] = z; \
2515 } \
2516 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2517 ffz += fdzdx; \
2518 } \
2519 }
2520 #ifdef __MINGW32__
2521 #include "tritemp.h"
2522 #else
2523
2524 #ifdef WIN32
2525 // #include "..\tritemp.h"
2526 #else
2527 #include "tritemp.h"
2528 #endif
2529 #endif
2530 }
2531
2532
2533
2534 /*
2535 * XImage, smooth, depth-buffered, PF_5R6G5B triangle.
2536 */
2537 static void smooth_5R6G5B_z_triangle( GLcontext *ctx,
2538 GLuint v0, GLuint v1, GLuint v2,
2539 GLuint pv )
2540 {
2541 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2542 #define INTERP_Z 1
2543 #define INTERP_RGB 1
2544 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2545 #define PIXEL_TYPE GLushort
2546 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2547 #define BYTES_PER_ROW (wmesa->ScanWidth)
2548 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2549 { \
2550 GLint i, len = RIGHT-LEFT; \
2551 for (i=0;i<len;i++) { \
2552 GLdepth z = FixedToDepth(ffz); \
2553 if (z < zRow[i]) { \
2554 pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2555 FixedToInt(ffb) ); \
2556 zRow[i] = z; \
2557 } \
2558 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2559 ffz += fdzdx; \
2560 } \
2561 }
2562 #ifdef __MINGW32__
2563 #include "tritemp.h"
2564 #else
2565
2566 #ifdef WIN32
2567 // #include "..\tritemp.h"
2568 #else
2569 #include "tritemp.h"
2570 #endif
2571 #endif
2572 }
2573
2574 /*
2575 * XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
2576 */
2577 static void flat_8A8B8G8R_z_triangle( GLcontext *ctx, GLuint v0,
2578 GLuint v1, GLuint v2, GLuint pv )
2579 {
2580 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2581 #define INTERP_Z 1
2582 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2583 #define PIXEL_TYPE GLuint
2584 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2585 #define BYTES_PER_ROW (wmesa->ScanWidth)
2586 #define SETUP_CODE \
2587 unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \
2588 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2589 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2590 { \
2591 GLint i, len = RIGHT-LEFT; \
2592 for (i=0;i<len;i++) { \
2593 GLdepth z = FixedToDepth(ffz); \
2594 if (z < zRow[i]) { \
2595 pRow[i] = p; \
2596 zRow[i] = z; \
2597 } \
2598 ffz += fdzdx; \
2599 } \
2600 }
2601 #ifdef __MINGW32__
2602 #include "tritemp.h"
2603 #else
2604
2605 #ifdef WIN32
2606 // #include "..\tritemp.h"
2607 #else
2608 #include "tritemp.h"
2609 #endif
2610 #endif
2611 }
2612
2613
2614 /*
2615 * XImage, flat, depth-buffered, PF_8R8G8B triangle.
2616 */
2617 static void flat_8R8G8B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2618 GLuint v2, GLuint pv )
2619 {
2620 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2621 #define INTERP_Z 1
2622 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2623 #define PIXEL_TYPE GLuint
2624 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2625 #define BYTES_PER_ROW (wmesa->ScanWidth)
2626 #define SETUP_CODE \
2627 unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \
2628 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2629 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2630 { \
2631 GLint i, len = RIGHT-LEFT; \
2632 for (i=0;i<len;i++) { \
2633 GLdepth z = FixedToDepth(ffz); \
2634 if (z < zRow[i]) { \
2635 pRow[i] = p; \
2636 zRow[i] = z; \
2637 } \
2638 ffz += fdzdx; \
2639 } \
2640 }
2641 #ifdef __MINGW32__
2642 #include "tritemp.h"
2643 #else
2644
2645 #ifdef WIN32
2646 // #include "..\tritemp.h"
2647 #else
2648 #include "tritemp.h"
2649 #endif
2650 #endif
2651 }
2652
2653
2654 /*
2655 * XImage, flat, depth-buffered, PF_5R6G5B triangle.
2656 */
2657 static void flat_5R6G5B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2658 GLuint v2, GLuint pv )
2659 {
2660 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2661 #define INTERP_Z 1
2662 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2663 #define PIXEL_TYPE GLushort
2664 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2665 #define BYTES_PER_ROW (wmesa->ScanWidth)
2666 #define SETUP_CODE \
2667 unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \
2668 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2669 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2670 { \
2671 GLint i, len = RIGHT-LEFT; \
2672 for (i=0;i<len;i++) { \
2673 GLdepth z = FixedToDepth(ffz); \
2674 if (z < zRow[i]) { \
2675 pRow[i] = p; \
2676 zRow[i] = z; \
2677 } \
2678 ffz += fdzdx; \
2679 } \
2680 }
2681 #ifdef __MINGW32__
2682 #include "tritemp.h"
2683 #else
2684
2685 #ifdef WIN32
2686 // #include "..\tritemp.h"
2687 #else
2688 #include "tritemp.h"
2689 #endif
2690 #endif
2691 }
2692
2693
2694 /*
2695 * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
2696 */
2697 static void smooth_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2698 GLuint v2, GLuint pv )
2699 {
2700 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2701 #define INTERP_RGB 1
2702 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2703 #define PIXEL_TYPE GLuint
2704 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2705 #define BYTES_PER_ROW (wmesa->ScanWidth)
2706 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2707 { \
2708 GLint xx; \
2709 PIXEL_TYPE *pixel = pRow; \
2710 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2711 *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2712 FixedToInt(ffb) ); \
2713 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2714 } \
2715 }
2716 #ifdef __MINGW32__
2717 #include "tritemp.h"
2718 #else
2719
2720 #ifdef WIN32
2721 // #include "..\tritemp.h"
2722 #else
2723 #include "tritemp.h"
2724 #endif
2725 #endif
2726 }
2727
2728
2729 /*
2730 * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
2731 */
2732 static void smooth_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2733 GLuint v2, GLuint pv )
2734 {
2735 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2736 #define INTERP_RGB 1
2737 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2738 #define PIXEL_TYPE GLuint
2739 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2740 #define BYTES_PER_ROW (wmesa->ScanWidth)
2741 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2742 { \
2743 GLint xx; \
2744 PIXEL_TYPE *pixel = pRow; \
2745 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2746 *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2747 FixedToInt(ffb) ); \
2748 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2749 } \
2750 }
2751 #ifdef __MINGW32__
2752 #include "tritemp.h"
2753 #else
2754
2755 #ifdef WIN32
2756 // #include "..\tritemp.h"
2757 #else
2758 #include "tritemp.h"
2759 #endif
2760 #endif
2761 }
2762
2763
2764 /*
2765 * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
2766 */
2767 static void smooth_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2768 GLuint v2, GLuint pv )
2769 {
2770 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2771 #define INTERP_RGB 1
2772 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2773 #define PIXEL_TYPE GLushort
2774 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2775 #define BYTES_PER_ROW (wmesa->ScanWidth)
2776 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2777 { \
2778 GLint xx; \
2779 PIXEL_TYPE *pixel = pRow; \
2780 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2781 *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2782 FixedToInt(ffb) ); \
2783 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
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 /*
2801 * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
2802 */
2803 static void flat_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0,
2804 GLuint v1, GLuint v2, GLuint pv )
2805 {
2806 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2807 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2808 #define PIXEL_TYPE GLuint
2809 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2810 #define BYTES_PER_ROW (wmesa->ScanWidth)
2811 #define SETUP_CODE \
2812 unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \
2813 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2814 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2815 { \
2816 GLint xx; \
2817 PIXEL_TYPE *pixel = pRow; \
2818 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2819 *pixel = p; \
2820 } \
2821 }
2822
2823 #ifdef __MINGW32__
2824 #include "tritemp.h"
2825 #else
2826
2827 #ifdef WIN32
2828 // #include "..\tritemp.h"
2829 #else
2830 #include "tritemp.h"
2831 #endif
2832 #endif
2833 }
2834
2835
2836 /*
2837 * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
2838 */
2839 static void flat_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2840 GLuint v2, GLuint pv )
2841 {
2842 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2843 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2844 #define PIXEL_TYPE GLuint
2845 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2846 #define BYTES_PER_ROW (wmesa->ScanWidth)
2847 #define SETUP_CODE \
2848 unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \
2849 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2850 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2851 { \
2852 GLint xx; \
2853 PIXEL_TYPE *pixel = pRow; \
2854 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2855 *pixel = p; \
2856 } \
2857 }
2858 #ifdef __MINGW32__
2859 #include "tritemp.h"
2860 #else
2861
2862 #ifdef WIN32
2863 // #include "..\tritemp.h"
2864 #else
2865 #include "tritemp.h"
2866 #endif
2867 #endif
2868 }
2869
2870
2871 /*
2872 * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
2873 */
2874 static void flat_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2875 GLuint v2, GLuint pv )
2876 {
2877 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2878 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2879 #define PIXEL_TYPE GLushort
2880 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2881 #define BYTES_PER_ROW (wmesa->ScanWidth)
2882 #define SETUP_CODE \
2883 unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \
2884 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2885 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2886 { \
2887 GLint xx; \
2888 PIXEL_TYPE *pixel = pRow; \
2889 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2890 *pixel = p; \
2891 } \
2892 }
2893 #ifdef __MINGW32__
2894 #include "tritemp.h"
2895 #else
2896
2897 #ifdef WIN32
2898 // #include "..\tritemp.h"
2899 #else
2900 #include "tritemp.h"
2901 #endif
2902 #endif
2903 }
2904
2905
2906 /*
2907 * XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
2908 */
2909
2910 static void smooth_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2911 GLuint v2, GLuint pv )
2912 {
2913 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2914 #define INTERP_Z 1
2915 #define INTERP_INDEX 1
2916 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2917 #define PIXEL_TYPE GLubyte
2918 #define BYTES_PER_ROW (wmesa->ScanWidth)
2919 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2920 { \
2921 GLint i, len = RIGHT-LEFT; \
2922 for (i=0;i<len;i++) { \
2923 GLdepth z = FixedToDepth(ffz); \
2924 if (z < zRow[i]) { \
2925 pRow[i] = FixedToInt(ffi); \
2926 zRow[i] = z; \
2927 } \
2928 ffi += fdidx; \
2929 ffz += fdzdx; \
2930 } \
2931 }
2932 #ifdef __MINGW32__
2933 #include "tritemp.h"
2934 #else
2935
2936 #ifdef WIN32
2937 // #include "..\tritemp.h"
2938 #else
2939 #include "tritemp.h"
2940 #endif
2941 #endif
2942 }
2943
2944
2945 /*
2946 * XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
2947 */
2948
2949 static void flat_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2950 GLuint v2, GLuint pv )
2951 {
2952 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2953 #define INTERP_Z 1
2954 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2955 #define PIXEL_TYPE GLubyte
2956 #define BYTES_PER_ROW (wmesa->ScanWidth)
2957 #define SETUP_CODE \
2958 GLuint index = VB->IndexPtr->data[pv]; \
2959 (*ctx->Driver.Index)( ctx, index );
2960 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2961 { \
2962 GLint i, len = RIGHT-LEFT; \
2963 for (i=0;i<len;i++) { \
2964 GLdepth z = FixedToDepth(ffz); \
2965 if (z < zRow[i]) { \
2966 pRow[i] = index; \
2967 zRow[i] = z; \
2968 } \
2969 ffz += fdzdx; \
2970 } \
2971 }
2972 #ifdef __MINGW32__
2973 #include "tritemp.h"
2974 #else
2975
2976 #ifdef WIN32
2977 // #include "..\tritemp.h"
2978 #else
2979 #include "tritemp.h"
2980 #endif
2981 #endif
2982 }
2983
2984
2985
2986 /*
2987 * XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2988 */
2989
2990 static void smooth_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2991 GLuint v2, GLuint pv )
2992 {
2993 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2994 #define INTERP_Z 1
2995 #define INTERP_INDEX 1
2996 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2997 #define PIXEL_TYPE GLubyte
2998 #define BYTES_PER_ROW (wmesa->ScanWidth)
2999 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3000 { \
3001 GLint xx; \
3002 PIXEL_TYPE *pixel = pRow; \
3003 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
3004 *pixel = FixedToInt(ffi); \
3005 ffi += fdidx; \
3006 } \
3007 }
3008 #ifdef __MINGW32__
3009 #include "tritemp.h"
3010 #else
3011
3012 #ifdef WIN32
3013 // #include "..\tritemp.h"
3014 #else
3015 #include "tritemp.h"
3016 #endif
3017 #endif
3018 }
3019
3020
3021 /*
3022 * XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
3023 */
3024 static void flat_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
3025 GLuint v2, GLuint pv )
3026 {
3027 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
3028 #define INTERP_Z 1
3029 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3030 #define PIXEL_TYPE GLubyte
3031 #define BYTES_PER_ROW (wmesa->ScanWidth)
3032 #define SETUP_CODE \
3033 GLuint index = VB->IndexPtr->data[pv]; \
3034 (*ctx->Driver.Index)( ctx, index );
3035 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3036 { \
3037 GLint xx; \
3038 PIXEL_TYPE *pixel = pRow; \
3039 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
3040 *pixel = index; \
3041 } \
3042 }
3043 #ifdef __MINGW32__
3044 #include "tritemp.h"
3045 #else
3046
3047 #ifdef WIN32
3048 // #include "..\tritemp.h"
3049 #else
3050 #include "tritemp.h"
3051 #endif
3052 #endif
3053 }
3054
3055 /*
3056 * XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
3057 */
3058 static void smooth_DITHER8_z_triangle( GLcontext *ctx,
3059 GLuint v0, GLuint v1, GLuint v2,
3060 GLuint pv )
3061 {
3062 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
3063 DITHER_RGB_TO_8BIT_SETUP
3064 #define INTERP_Z 1
3065 #define INTERP_RGB 1
3066 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3067 #define PIXEL_TYPE GLubyte
3068 #define BYTES_PER_ROW (wmesa->ScanWidth)
3069 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3070 { \
3071 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
3072 for (i=0;i<len;i++,xx++) { \
3073 GLdepth z = FixedToDepth(ffz); \
3074 if (z < zRow[i]) { \
3075 DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg), \
3076 FixedToInt(ffb), xx, yy); \
3077 pRow[i] = pixelDithered; \
3078 zRow[i] = z; \
3079 } \
3080 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
3081 ffz += fdzdx; \
3082 } \
3083 }
3084 #ifdef __MINGW32__
3085 #include "tritemp.h"
3086 #else
3087
3088 #ifdef WIN32
3089 // #include "..\tritemp.h"
3090 #else
3091 #include "tritemp.h"
3092 #endif
3093 #endif
3094 }
3095
3096 /*
3097 * XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
3098 */
3099 static void flat_DITHER8_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
3100 GLuint v2, GLuint pv )
3101 {
3102 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
3103 DITHER_RGB_TO_8BIT_SETUP
3104 #define INTERP_Z 1
3105 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3106 #define PIXEL_TYPE GLubyte
3107 #define BYTES_PER_ROW (wmesa->ScanWidth)
3108
3109 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3110 { \
3111 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
3112 for (i=0;i<len;i++,xx++) { \
3113 GLdepth z = FixedToDepth(ffz); \
3114 if (z < zRow[i]) { \
3115 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \
3116 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \
3117 pRow[i] = pixelDithered; \
3118 zRow[i] = z; \
3119 } \
3120 ffz += fdzdx; \
3121 } \
3122 }
3123 #ifdef __MINGW32__
3124 #include "tritemp.h"
3125 #else
3126
3127 #ifdef WIN32
3128 // #include "..\tritemp.h"
3129 #else
3130 #include "tritemp.h"
3131 #endif
3132 #endif
3133 }
3134
3135 /*
3136 * XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
3137 */
3138 static void smooth_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
3139 GLuint v2, GLuint pv )
3140 {
3141 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
3142 DITHER_RGB_TO_8BIT_SETUP
3143 #define INTERP_RGB 1
3144 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3145 #define PIXEL_TYPE GLubyte
3146 #define BYTES_PER_ROW (wmesa->ScanWidth)
3147 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3148 { \
3149 GLint xx, yy = FLIP(Y); \
3150 PIXEL_TYPE *pixel = pRow; \
3151 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
3152 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy);\
3153 *pixel = pixelDithered; \
3154 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
3155 } \
3156 }
3157 #ifdef __MINGW32__
3158 #include "tritemp.h"
3159 #else
3160
3161 #ifdef WIN32
3162 // #include "..\tritemp.h"
3163 #else
3164 #include "tritemp.h"
3165 #endif
3166 #endif
3167 }
3168
3169 /*
3170 * XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
3171 */
3172
3173 static void flat_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
3174 GLuint v2, GLuint pv )
3175 {
3176 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
3177 DITHER_RGB_TO_8BIT_SETUP
3178 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3179 #define PIXEL_TYPE GLubyte
3180 #define BYTES_PER_ROW (wmesa->ScanWidth)
3181
3182 #define INNER_LOOP( LEFT, RIGHT, Y ) \
3183 { \
3184 GLint xx, yy = FLIP(Y); \
3185 PIXEL_TYPE *pixel = pRow; \
3186 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
3187 DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \
3188 VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \
3189 *pixel = pixelDithered; \
3190 } \
3191 }
3192 #ifdef __MINGW32__
3193 #include "tritemp.h"
3194 #else
3195
3196 #ifdef WIN32
3197 // #include "..\tritemp.h"
3198 #else
3199 #include "tritemp.h"
3200 #endif
3201 #endif
3202 }
3203
3204 #endif
3205 /************** END DEAD TRIANGLE CODE ***********************/
3206
3207 static triangle_func choose_triangle_function( GLcontext *ctx )
3208 {
3209 #if 0
3210 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
3211 int depth = wmesa->cColorBits;
3212
3213 if (ctx->Polygon.SmoothFlag) return NULL;
3214 if (ctx->Texture._EnabledUnits) return NULL;
3215 if (!wmesa->db_flag) return NULL;
3216 if (ctx->swrast->_RasterMask & MULTI_DRAW_BIT) return NULL;
3217
3218 /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {
3219 if ( ctx->Light.ShadeModel==GL_SMOOTH
3220 && ctx->_RasterMask==DEPTH_BIT
3221 && ctx->Depth.Func==GL_LESS
3222 && ctx->Depth.Mask==GL_TRUE
3223 && ctx->Polygon.StippleFlag==GL_FALSE) {
3224 switch (wmesa->pixelformat) {
3225 case PF_8A8B8G8R:
3226 return smooth_8A8B8G8R_z_triangle;
3227 case PF_8R8G8B:
3228 return smooth_8R8G8B_z_triangle;
3229 case PF_5R6G5B:
3230 return smooth_5R6G5B_z_triangle;
3231 case PF_DITHER8:
3232 return smooth_DITHER8_z_triangle;
3233 case PF_INDEX8:
3234 return smooth_ci_z_triangle;
3235 default:
3236 return NULL;
3237 }
3238 }
3239 if ( ctx->Light.ShadeModel==GL_FLAT
3240 && ctx->_RasterMask==DEPTH_BIT
3241 && ctx->Depth.Func==GL_LESS
3242 && ctx->Depth.Mask==GL_TRUE
3243 && ctx->Polygon.StippleFlag==GL_FALSE) {
3244 switch (wmesa->pixelformat) {
3245 case PF_8A8B8G8R:
3246 return flat_8A8B8G8R_z_triangle;
3247 case PF_8R8G8B:
3248 return flat_8R8G8B_z_triangle;
3249 case PF_5R6G5B:
3250 return flat_5R6G5B_z_triangle;
3251 case PF_DITHER8:
3252 return flat_DITHER8_z_triangle;
3253 case PF_INDEX8:
3254 return flat_ci_z_triangle;
3255 default:
3256 return NULL;
3257 }
3258 }
3259 if ( ctx->_RasterMask==0 /* no depth test */
3260 && ctx->Light.ShadeModel==GL_SMOOTH
3261 && ctx->Polygon.StippleFlag==GL_FALSE) {
3262 switch (wmesa->pixelformat) {
3263 case PF_8A8B8G8R:
3264 return smooth_8A8B8G8R_triangle;
3265 case PF_8R8G8B:
3266 return smooth_8R8G8B_triangle;
3267 case PF_5R6G5B:
3268 return smooth_5R6G5B_triangle;
3269 case PF_DITHER8:
3270 return smooth_DITHER8_triangle;
3271 case PF_INDEX8:
3272 return smooth_ci_triangle;
3273 default:
3274 return NULL;
3275 }
3276 }
3277
3278 if ( ctx->_RasterMask==0 /* no depth test */
3279 && ctx->Light.ShadeModel==GL_FLAT
3280 && ctx->Polygon.StippleFlag==GL_FALSE) {
3281 switch (wmesa->pixelformat) {
3282 case PF_8A8B8G8R:
3283 return flat_8A8B8G8R_triangle;
3284 case PF_8R8G8B:
3285 return flat_8R8G8B_triangle;
3286 case PF_5R6G5B:
3287 return flat_5R6G5B_triangle;
3288 case PF_DITHER8:
3289 return flat_DITHER8_triangle;
3290 case PF_INDEX8:
3291 return flat_ci_triangle;
3292 default:
3293 return NULL;
3294 }
3295 }
3296
3297 return NULL;
3298 }
3299 #endif
3300 }
3301
3302 /*
3303 * Define a new viewport and reallocate auxillary buffers if the size of
3304 * the window (color buffer) has changed.
3305 */
3306 void WMesaViewport( GLcontext *ctx,
3307 GLint x, GLint y, GLsizei width, GLsizei height )
3308 {
3309 assert(0); /* I don't think that this is being used. */
3310 #if 0
3311 /* Save viewport */
3312 ctx->Viewport.X = x;
3313 ctx->Viewport.Width = width;
3314 ctx->Viewport.Y = y;
3315 ctx->Viewport.Height = height;
3316
3317 /* compute scale and bias values */
3318 /* Pre-Keith 3.1 changes
3319 ctx->Viewport.Map.m[Sx] = (GLfloat) width / 2.0F;
3320 ctx->Viewport.Map.m[Tx] = ctx->Viewport.Sx + x;
3321 ctx->Viewport.Map.m[Sy] = (GLfloat) height / 2.0F;
3322 ctx->Viewport.Map.m[Ty] = ctx->Viewport.Sy + y;
3323 */
3324 ctx->Viewport.WindowMap.m[MAT_SX] = (GLfloat) width / 2.0F;
3325 ctx->Viewport.WindowMap.m[MAT_TX] = ctx->Viewport.WindowMap.m[MAT_SX] + x;
3326 ctx->Viewport.WindowMap.m[MAT_SY] = (GLfloat) height / 2.0F;
3327 ctx->Viewport.WindowMap.m[MAT_TY] = ctx->Viewport.WindowMap.m[MAT_SY] + y;
3328 #endif
3329 }