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