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