fix GL_BACK color material bug
[mesa.git] / src / mesa / drivers / windows / wmesaOld.c
1 /*
2 * File name : wmesa.c
3 * Version : 2.3
4 *
5 * Display driver for Mesa 2.3 under
6 * Windows95 and WindowsNT
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
20
21 /*
22 * $Log: wmesaOld.c,v $
23 * Revision 1.1 1999/08/19 00:55:42 jtg
24 * Initial revision
25 *
26 * Revision 1.2 1999/01/03 03:08:57 brianp
27 * Ted Jump's changes
28 *
29 * Revision 1.0 1997/06/14 17:51:00 CST by Li Wei(liwei@aiar.xjtu.edu.cn)
30 * New display driver for Mesa 2.x using Microsoft Direct Draw
31 * Initial vision
32 */
33
34
35 #define WMESA_STEREO_C
36
37 #include <windows.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <GL/wmesa.h>
41 #include "wmesadef.h"
42 #include "context.h"
43 #include "dd.h"
44 #include "xform.h"
45 #include "vb.h"
46 #include "matrix.h"
47 #include "depth.h"
48
49 #ifdef PROFILE
50 // #include "profile.h"
51 #endif
52
53 #ifdef DITHER
54 #include <wing.h>
55 #endif
56
57 #ifdef __CYGWIN32__
58 #include "macros.h"
59 #include <string.h>
60 #define CopyMemory memcpy
61 #endif
62 #include "mesa_extend.h"
63 #include "colors.h"
64
65 #if !defined(NO_STEREO)
66
67 #include "gl\glu.h"
68 #include "stereo.h"
69
70 #endif
71 #if !defined(NO_PARALLEL)
72 // #include "parallel.h"
73 #endif
74
75 struct DISPLAY_OPTIONS displayOptions;
76
77 GLenum stereoCompile = GL_FALSE ;
78 GLenum stereoShowing = GL_FALSE ;
79 GLenum stereoBuffer = GL_FALSE;
80 #if !defined(NO_STEREO)
81 GLint displayList = MAXIMUM_DISPLAY_LIST ;
82 #endif
83 GLint stereo_flag = 0 ;
84
85 /* end of added code*/
86
87 static PWMC Current = NULL;
88 WMesaContext WC = NULL;
89
90 #ifdef NDEBUG
91 #define assert(ignore) ((void) 0)
92 #else
93 void Mesa_Assert(void *Cond,void *File,unsigned Line)
94 {
95 char Msg[512];
96 sprintf(Msg,"%s %s %d",Cond,File,Line);
97 MessageBox(NULL,Msg,"Assertion failed.",MB_OK);
98 exit(1);
99 }
100 #define assert(e) if (!e) Mesa_Assert(#e,__FILE__,__LINE__);
101 #endif
102
103 //#define DD_GETDC (Current->hDC )
104 #define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
105 //#define DD_GETDC ((Current->db_flag) ? Current->hDCPrimary : Current->hDCBack )
106 #define DD_RELEASEDC
107
108 //#define BEGINGDICALL if(Current->rgb_flag)wmFlushBits(Current);
109 #define BEGINGDICALL
110 //#define ENDGDICALL if(Current->rgb_flag)wmGetBits(Current);
111 #define ENDGDICALL
112
113 //#define FLIP(Y) (Current->dither_flag? Y : Current->height-(Y)-1)
114 //#define FLIP(Y) (Current->height-(Y)-1)
115 //#define FLIP(Y) Y
116 #define FLIP(Y) (Current->db_flag? Y: Current->height-(Y)-1)
117 #define STARTPROFILE
118 #define ENDPROFILE(PARA)
119
120 #define DITHER_RGB_TO_8BIT_SETUP \
121 GLubyte pixelDithered;
122
123 #define DITHER_RGB_TO_8BIT(red, green, blue, pixel, scanline) \
124 { \
125 char unsigned redtemp, greentemp, bluetemp, paletteindex; \
126 redtemp = aDividedBy51[red] \
127 + (aModulo51[red] > aHalftone8x8[(pixel%8)*8 \
128 + scanline%8]); \
129 greentemp = aDividedBy51[(char unsigned)green] \
130 + (aModulo51[green] > aHalftone8x8[ \
131 (pixel%8)*8 + scanline%8]); \
132 bluetemp = aDividedBy51[(char unsigned)blue] \
133 + (aModulo51[blue] > aHalftone8x8[ \
134 (pixel%8)*8 +scanline%8]); \
135 paletteindex = redtemp + aTimes6[greentemp] + aTimes36[bluetemp]; \
136 pixelDithered = aWinGHalftoneTranslation[paletteindex]; \
137 }
138
139
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 #endif
147
148 static void FlushToFile(PWMC pwc, PSTR szFile);
149
150 BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize);
151 BOOL wmDeleteBackingStore(PWMC pwc);
152 void wmCreatePalette( PWMC pwdc );
153 BOOL wmSetDibColors(PWMC pwc);
154 void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b);
155
156 void wmCreateDIBSection(
157 HDC hDC,
158 PWMC pwc, // handle of device context
159 CONST BITMAPINFO *pbmi, // address of structure containing bitmap size, format, and color data
160 UINT iUsage // color data type indicator: RGB values or palette indices
161 );
162
163
164 void WMesaViewport( GLcontext *ctx,
165 GLint x, GLint y, GLsizei width, GLsizei height );
166
167 static triangle_func choose_triangle_function( GLcontext *ctx );
168
169 static void wmSetPixelFormat( PWMC wc, HDC hDC)
170 {
171 if(wc->rgb_flag)
172 wc->cColorBits = GetDeviceCaps(hDC, BITSPIXEL);
173 else
174 wc->cColorBits = 8;
175 switch(wc->cColorBits){
176 case 8:
177 if(wc->dither_flag != GL_TRUE)
178 wc->pixelformat = PF_INDEX8;
179 else
180 wc->pixelformat = PF_DITHER8;
181 break;
182 case 16:
183 wc->pixelformat = PF_5R6G5B;
184 break;
185 case 32:
186 wc->pixelformat = PF_8R8G8B;
187 break;
188 default:
189 wc->pixelformat = PF_BADFORMAT;
190 }
191 }
192
193 //
194 // This function sets the color table of a DIB section
195 // to match that of the destination DC
196 //
197 BOOL /*WINAPI*/ wmSetDibColors(PWMC pwc)
198 {
199 RGBQUAD *pColTab, *pRGB;
200 PALETTEENTRY *pPal, *pPE;
201 int i, nColors;
202 BOOL bRet=TRUE;
203 DWORD dwErr=0;
204
205 /* Build a color table in the DIB that maps to the
206 selected palette in the DC.
207 */
208 nColors = 1 << pwc->cColorBits;
209 pPal = (PALETTEENTRY *)malloc( nColors * sizeof(PALETTEENTRY));
210 memset( pPal, 0, nColors * sizeof(PALETTEENTRY) );
211 GetPaletteEntries( pwc->hGLPalette, 0, nColors, pPal );
212 pColTab = (RGBQUAD *)malloc( nColors * sizeof(RGBQUAD));
213 for (i = 0, pRGB = pColTab, pPE = pPal; i < nColors; i++, pRGB++, pPE++) {
214 pRGB->rgbRed = pPE->peRed;
215 pRGB->rgbGreen = pPE->peGreen;
216 pRGB->rgbBlue = pPE->peBlue;
217 }
218 if(pwc->db_flag)
219 bRet = SetDIBColorTable(pwc->dib.hDC, 0, nColors, pColTab );
220
221 if(!bRet)
222 dwErr = GetLastError();
223
224 free( pColTab );
225 free( pPal );
226
227 return(bRet);
228 }
229
230
231 //
232 // Free up the dib section that was created
233 //
234 BOOL wmDeleteBackingStore(PWMC pwc)
235 {
236 SelectObject(pwc->dib.hDC, pwc->hOldBitmap);
237 DeleteDC(pwc->dib.hDC);
238 DeleteObject(pwc->hbmDIB);
239 UnmapViewOfFile(pwc->dib.base);
240 CloseHandle(pwc->dib.hFileMap);
241 return TRUE;
242 }
243
244
245 //
246 // This function creates the DIB section that is used for combined
247 // GL and GDI calls
248 //
249 BOOL /*WINAPI*/ wmCreateBackingStore(PWMC pwc, long lxSize, long lySize)
250 {
251 HDC hdc = pwc->hDC;
252 LPBITMAPINFO pbmi = &(pwc->bmi);
253 int iUsage;
254
255 pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
256 pbmi->bmiHeader.biWidth = lxSize;
257 pbmi->bmiHeader.biHeight= -lySize;
258 pbmi->bmiHeader.biPlanes = 1;
259 if(pwc->rgb_flag)
260 pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwc->hDC, BITSPIXEL);
261 else
262 pbmi->bmiHeader.biBitCount = 8;
263 pbmi->bmiHeader.biCompression = BI_RGB;
264 pbmi->bmiHeader.biSizeImage = 0;
265 pbmi->bmiHeader.biXPelsPerMeter = 0;
266 pbmi->bmiHeader.biYPelsPerMeter = 0;
267 pbmi->bmiHeader.biClrUsed = 0;
268 pbmi->bmiHeader.biClrImportant = 0;
269
270 iUsage = (pbmi->bmiHeader.biBitCount <= 8) ? DIB_PAL_COLORS : DIB_RGB_COLORS;
271
272 pwc->cColorBits = pbmi->bmiHeader.biBitCount;
273 pwc->ScanWidth = pwc->pitch = lxSize;
274
275 wmCreateDIBSection(hdc, pwc, pbmi, iUsage);
276
277 if ((iUsage == DIB_PAL_COLORS) && !(pwc->hGLPalette)) {
278 wmCreatePalette( pwc );
279 wmSetDibColors( pwc );
280 }
281 wmSetPixelFormat(pwc, pwc->hDC);
282 return(TRUE);
283
284 }
285
286
287 //
288 // This function copies one scan line in a DIB section to another
289 //
290 BOOL GLWINAPI wmSetDIBits(PWMC pwc, UINT uiScanWidth, UINT uiNumScans, UINT nBypp, UINT uiNewWidth, LPBYTE pBits)
291 {
292 UINT uiScans = 0;
293 LPBYTE pDest = pwc->pbPixels;
294 DWORD dwNextScan = uiScanWidth;
295 DWORD dwNewScan = uiNewWidth;
296 DWORD dwScanWidth = (uiScanWidth * nBypp);
297
298 //
299 // We need to round up to the nearest DWORD
300 // and multiply by the number of bytes per
301 // pixel
302 //
303 dwNextScan = (((dwNextScan * nBypp)+ 3) & ~3);
304 dwNewScan = (((dwNewScan * nBypp)+ 3) & ~3);
305
306 for(uiScans = 0; uiScans < uiNumScans; uiScans++){
307 CopyMemory(pDest, pBits, dwScanWidth);
308 pBits += dwNextScan;
309 pDest += dwNewScan;
310 }
311
312 return(TRUE);
313
314 }
315
316
317 BOOL wmFlush(PWMC pwc);
318
319 /*
320 * Useful macros:
321 Modified from file osmesa.c
322 */
323
324
325 #define PIXELADDR(X,Y) ((GLubyte *)Current->pbPixels + (Current->height-Y-1)* Current->ScanWidth + (X)*nBypp)
326 #define PIXELADDR1( X, Y ) \
327 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X))
328 #define PIXELADDR2( X, Y ) \
329 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*2)
330 #define PIXELADDR4( X, Y ) \
331 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*4)
332
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 //
344 // We cache all gl draw routines until a flush is made
345 //
346 static void flush(GLcontext* ctx)
347 {
348 STARTPROFILE
349 if((Current->rgb_flag /*&& !(Current->dib.fFlushed)*/&&!(Current->db_flag))
350 ||(!Current->rgb_flag))
351 {
352 wmFlush(Current);
353 }
354 ENDPROFILE(flush)
355
356 }
357
358
359
360 /*
361 * Set the color index used to clear the color buffer.
362 */
363 static void clear_index(GLcontext* ctx, GLuint index)
364 {
365 STARTPROFILE
366 Current->clearpixel = index;
367 ENDPROFILE(clear_index)
368 }
369
370
371
372 /*
373 * Set the color used to clear the color buffer.
374 */
375 static void clear_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
376 {
377 STARTPROFILE
378 Current->clearpixel=RGB(r, g, b );
379 ENDPROFILE(clear_color)
380 }
381
382
383
384 /*
385 * Clear the specified region of the color buffer using the clear color
386 * or index as specified by one of the two functions above.
387 */
388 static void clear(GLcontext* ctx,
389 GLboolean all,GLint x, GLint y, GLint width, GLint height )
390 {
391 DWORD dwColor;
392 WORD wColor;
393 BYTE bColor;
394 LPDWORD lpdw = (LPDWORD)Current->pbPixels;
395 LPWORD lpw = (LPWORD)Current->pbPixels;
396 LPBYTE lpb = Current->pbPixels;
397 int lines;
398
399 STARTPROFILE
400
401 if (all){
402 x=y=0;
403 width=Current->width;
404 height=Current->height;
405 }
406 if(Current->db_flag==GL_TRUE){
407 UINT nBypp = Current->cColorBits / 8;
408 int i = 0;
409 int iSize;
410
411 if(nBypp ==1 ){
412 /* Need rectification */
413 iSize = Current->width/4;
414 bColor = BGR8(GetRValue(Current->clearpixel),
415 GetGValue(Current->clearpixel),
416 GetBValue(Current->clearpixel));
417 wColor = MAKEWORD(bColor,bColor);
418 dwColor = MAKELONG(wColor, wColor);
419 }
420 if(nBypp == 2){
421 iSize = Current->width / 2;
422 wColor = BGR16(GetRValue(Current->clearpixel),
423 GetGValue(Current->clearpixel),
424 GetBValue(Current->clearpixel));
425 dwColor = MAKELONG(wColor, wColor);
426 }
427 else if(nBypp == 4){
428 iSize = Current->width;
429 dwColor = BGR32(GetRValue(Current->clearpixel),
430 GetGValue(Current->clearpixel),
431 GetBValue(Current->clearpixel));
432 }
433
434 while(i < iSize){
435 *lpdw = dwColor;
436 lpdw++;
437 i++;
438 }
439
440 //
441 // This is the 24bit case
442 //
443 if (nBypp == 3) {
444 iSize = Current->width *3/4;
445 dwColor = BGR24(GetRValue(Current->clearpixel),
446 GetGValue(Current->clearpixel),
447 GetBValue(Current->clearpixel));
448 while(i < iSize){
449 *lpdw = dwColor;
450 lpb += nBypp;
451 lpdw = (LPDWORD)lpb;
452 i++;
453 }
454 }
455
456 i = 0;
457 if(stereo_flag) lines = height /2;
458 else lines = height;
459 do{
460 lpb += Current->ScanWidth;
461 memcpy(lpb, Current->pbPixels, iSize*4);
462 i++;
463 }
464 while(i<lines-1);
465 }
466 else{ // For single buffer
467 HDC DC=DD_GETDC;
468 HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);
469 HBRUSH Brush=CreateSolidBrush(Current->clearpixel);
470 HPEN Old_Pen=SelectObject(DC,Pen);
471 HBRUSH Old_Brush=SelectObject(DC,Brush);
472 Rectangle(DC,x,y,x+width,y+height);
473 SelectObject(DC,Old_Pen);
474 SelectObject(DC,Old_Brush);
475 DeleteObject(Pen);
476 DeleteObject(Brush);
477 DD_RELEASEDC;
478 }
479
480
481
482 ENDPROFILE(clear)
483 }
484
485
486
487 /* Set the current color index. */
488 static void set_index(GLcontext* ctx, GLuint index)
489 {
490 STARTPROFILE
491 Current->pixel=index;
492 ENDPROFILE(set_index)
493 }
494
495
496
497 /* Set the current RGBA color. */
498 static void set_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
499 {
500 STARTPROFILE
501 Current->pixel = RGB( r, g, b );
502 ENDPROFILE(set_color)
503 }
504
505
506
507 /* Set the index mode bitplane mask. */
508 static GLboolean index_mask(GLcontext* ctx, GLuint mask)
509 {
510 /* can't implement */
511 return GL_FALSE;
512 }
513
514
515
516 /* Set the RGBA drawing mask. */
517 static GLboolean color_mask( GLcontext* ctx,
518 GLboolean rmask, GLboolean gmask,
519 GLboolean bmask, GLboolean amask)
520 {
521 /* can't implement */
522 return GL_FALSE;
523 }
524
525
526
527 /*
528 * Set the pixel logic operation. Return GL_TRUE if the device driver
529 * can perform the operation, otherwise return GL_FALSE. If GL_FALSE
530 * is returned, the logic op will be done in software by Mesa.
531 */
532 GLboolean logicop( GLcontext* ctx, GLenum op )
533 {
534 /* can't implement */
535 return GL_FALSE;
536 }
537
538
539 static void dither( GLcontext* ctx, GLboolean enable )
540 {
541 if(enable == GL_FALSE){
542 Current->dither_flag = GL_FALSE;
543 if(Current->cColorBits == 8)
544 Current->pixelformat = PF_INDEX8;
545 }
546 else{
547 if (Current->rgb_flag && Current->cColorBits == 8){
548 Current->pixelformat = PF_DITHER8;
549 Current->dither_flag = GL_TRUE;
550 }
551 else
552 Current->dither_flag = GL_FALSE;
553 }
554 }
555
556
557
558 static GLboolean set_buffer( GLcontext* ctx, GLenum mode )
559 {
560 STARTPROFILE
561 /* TODO: this could be better */
562 if (mode==GL_FRONT || mode==GL_BACK) {
563 return GL_TRUE;
564 }
565 else {
566 return GL_FALSE;
567 }
568 ENDPROFILE(set_buffer)
569 }
570
571
572
573 /* Return characteristics of the output buffer. */
574 static void buffer_size( GLcontext* ctx, GLuint *width, GLuint *height /*, GLuint *depth */)
575 {
576
577 int New_Size;
578 RECT CR;
579
580 STARTPROFILE
581 GetClientRect(Current->Window,&CR);
582
583 *width=CR.right;
584 *height=CR.bottom;
585 // *depth = Current->depth;
586
587 New_Size=((*width)!=Current->width) || ((*height)!=Current->height);
588
589 if (New_Size){
590 Current->width=*width;
591 Current->height=*height;
592 Current->ScanWidth=Current->width;
593 if ((Current->ScanWidth%sizeof(long))!=0)
594 Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));
595
596 if (Current->db_flag){
597 #ifdef DDRAW
598 DDDeleteOffScreen(Current);
599 DDCreateOffScreen(Current);
600 #else
601 if (Current->rgb_flag==GL_TRUE && Current->dither_flag!=GL_TRUE){
602 wmDeleteBackingStore(Current);
603 wmCreateBackingStore(Current, Current->width, Current->height);
604 }
605 #endif
606 }
607
608 // Resize OsmesaBuffer if in Parallel mode
609 #if !defined(NO_PARALLEL)
610 if(parallelFlag)
611 PRSizeRenderBuffer(Current->width, Current->height,Current->ScanWidth,
612 Current->rgb_flag == GL_TRUE ? Current->pbPixels: Current->ScreenMem);
613 #endif
614 }
615 ENDPROFILE(buffer_size)
616 }
617
618
619
620 /**********************************************************************/
621 /***** Accelerated point, line, polygon rendering *****/
622 /**********************************************************************/
623
624
625 static void fast_rgb_points( GLcontext* ctx, GLuint first, GLuint last )
626 {
627 GLuint i;
628 // HDC DC=DD_GETDC;
629 PWMC pwc = Current;
630
631 STARTPROFILE
632
633 if (Current->gl_ctx->VB->MonoColor) {
634 /* all drawn with current color */
635 for (i=first;i<=last;i++) {
636 if (!Current->gl_ctx->VB->ClipMask[i]) {
637 int x, y;
638 x = (GLint) Current->gl_ctx->VB->Win[i][0];
639 y = FLIP( (GLint) Current->gl_ctx->VB->Win[i][1] );
640 wmSetPixel(pwc, y,x,GetRValue(Current->pixel),
641 GetGValue(Current->pixel), GetBValue(Current->pixel));
642 }
643 }
644 }
645 else {
646 /* draw points of different colors */
647 for (i=first;i<=last;i++) {
648 if (!Current->gl_ctx->VB->ClipMask[i]) {
649 int x, y;
650 unsigned long pixel=RGB(Current->gl_ctx->VB->Color[i][0]*255.0,
651 Current->gl_ctx->VB->Color[i][1]*255.0,
652 Current->gl_ctx->VB->Color[i][2]*255.0);
653 x = (GLint) Current->gl_ctx->VB->Win[i][0];
654 y = FLIP( (GLint) Current->gl_ctx->VB->Win[i][1] );
655 wmSetPixel(pwc, y,x,Current->gl_ctx->VB->Color[i][0]*255.0,
656 Current->gl_ctx->VB->Color[i][1]*255.0,
657 Current->gl_ctx->VB->Color[i][2]*255.0);
658 }
659 }
660 }
661 // DD_RELEASEDC;
662 ENDPROFILE(fast_rgb_points)
663 }
664
665
666
667 /* Return pointer to accerated points function */
668 extern points_func choose_points_function( GLcontext* ctx )
669 {
670 STARTPROFILE
671 if (ctx->Point.Size==1.0 && !ctx->Point.SmoothFlag && ctx->RasterMask==0
672 && !ctx->Texture.Enabled && ctx->Visual->RGBAflag) {
673 ENDPROFILE(choose_points_function)
674 return fast_rgb_points;
675 }
676 else {
677 ENDPROFILE(choose_points_function)
678 return NULL;
679 }
680 }
681
682
683
684 /* Draw a line using the color specified by Current->gl_ctx->VB->Color[pv] */
685 static void fast_flat_rgb_line( GLcontext* ctx, GLuint v0, GLuint v1, GLuint pv )
686 {
687 STARTPROFILE
688 int x0, y0, x1, y1;
689 unsigned long pixel;
690 HDC DC=DD_GETDC;
691 HPEN Pen;
692 HPEN Old_Pen;
693
694 if (Current->gl_ctx->VB->MonoColor) {
695 pixel = Current->pixel; /* use current color */
696 }
697 else {
698 pixel = RGB(Current->gl_ctx->VB->Color[pv][0]*255.0, Current->gl_ctx->VB->Color[pv][1]*255.0, Current->gl_ctx->VB->Color[pv][2]*255.0);
699 }
700
701 x0 = (int) Current->gl_ctx->VB->Win[v0][0];
702 y0 = FLIP( (int) Current->gl_ctx->VB->Win[v0][1] );
703 x1 = (int) Current->gl_ctx->VB->Win[v1][0];
704 y1 = FLIP( (int) Current->gl_ctx->VB->Win[v1][1] );
705
706
707 BEGINGDICALL
708
709 Pen=CreatePen(PS_SOLID,1,pixel);
710 Old_Pen=SelectObject(DC,Pen);
711 MoveToEx(DC,x0,y0,NULL);
712 LineTo(DC,x1,y1);
713 SelectObject(DC,Old_Pen);
714 DeleteObject(Pen);
715 DD_RELEASEDC;
716
717 ENDGDICALL
718
719 ENDPROFILE(fast_flat_rgb_line)
720 }
721
722
723
724 /* Return pointer to accerated line function */
725 static line_func choose_line_function( GLcontext* ctx )
726 {
727 STARTPROFILE
728 if (ctx->Line.Width==1.0 && !ctx->Line.SmoothFlag && !ctx->Line.StippleFlag
729 && ctx->Light.ShadeModel==GL_FLAT && ctx->RasterMask==0
730 && !ctx->Texture.Enabled && Current->rgb_flag) {
731 ENDPROFILE(choose_line_function)
732 return fast_flat_rgb_line;
733 }
734 else {
735 ENDPROFILE(choose_line_function)
736 return NULL;
737 }
738 }
739
740
741 /**********************************************************************/
742 /***** Span-based pixel drawing *****/
743 /**********************************************************************/
744
745
746 /* Write a horizontal span of color-index pixels with a boolean mask. */
747 static void write_index_span( GLcontext* ctx,
748 GLuint n, GLint x, GLint y,
749 const GLuint index[],
750 const GLubyte mask[] )
751 {
752 STARTPROFILE
753 GLuint i;
754 PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
755 assert(Current->rgb_flag==GL_FALSE);
756 for (i=0; i<n; i++)
757 if (mask[i])
758 Mem[i]=index[i];
759 ENDPROFILE(write_index_span)
760 }
761
762
763
764 /*
765 * Write a horizontal span of pixels with a boolean mask. The current
766 * color index is used for all pixels.
767 */
768 static void write_monoindex_span(GLcontext* ctx,
769 GLuint n,GLint x,GLint y,
770 const GLubyte mask[])
771 {
772 STARTPROFILE
773 GLuint i;
774 BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
775 assert(Current->rgb_flag==GL_FALSE);
776 for (i=0; i<n; i++)
777 if (mask[i])
778 Mem[i]=Current->pixel;
779 ENDPROFILE(write_monoindex_span)
780 }
781
782 /*
783 To improve the performance of this routine, frob the data into an actual scanline
784 and call bitblt on the complete scan line instead of SetPixel.
785 */
786
787 /* Write a horizontal span of color pixels with a boolean mask. */
788 static void write_color_span( GLcontext* ctx,
789 GLuint n, GLint x, GLint y,
790 const GLubyte
791 red[], const GLubyte green[],
792 const GLubyte blue[], const GLubyte alpha[],
793 const GLubyte mask[] )
794 {
795 STARTPROFILE
796
797 PWMC pwc = Current;
798
799 if (pwc->rgb_flag==GL_TRUE)
800 {
801 GLuint i;
802 HDC DC=DD_GETDC;
803 y=FLIP(y);
804
805 if (mask) {
806 for (i=0; i<n; i++)
807 if (mask[i])
808 wmSetPixel(pwc, y, x + i,red[i], green[i], blue[i]);
809 }
810
811 else {
812 for (i=0; i<n; i++)
813 wmSetPixel(pwc, y, x + i, red[i], green[i], blue[i]);
814 }
815
816 DD_RELEASEDC;
817
818 }
819
820 else
821 {
822 GLuint i;
823 BYTE *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
824 y=FLIP(y);
825 if (mask) {
826 for (i=0; i<n; i++)
827 if (mask[i])
828 Mem[i]=GetNearestPaletteIndex(Current->hPal,RGB(red[i],green[i],blue[i]));
829 }
830 else {
831 for (i=0; i<n; i++)
832 Mem[i]=GetNearestPaletteIndex(Current->hPal,RGB(red[i],green[i],blue[i]));
833 }
834 }
835 ENDPROFILE(write_color_span)
836
837 }
838
839 /*
840 * Write a horizontal span of pixels with a boolean mask. The current color
841 * is used for all pixels.
842 */
843 static void write_monocolor_span( GLcontext* ctx,
844 GLuint n, GLint x, GLint y,
845 const GLubyte mask[])
846 {
847 STARTPROFILE
848 GLuint i;
849 HDC DC=DD_GETDC;
850 PWMC pwc = Current;
851
852 assert(Current->rgb_flag==GL_TRUE);
853 y=FLIP(y);
854
855 if(Current->rgb_flag==GL_TRUE){
856 for (i=0; i<n; i++)
857 if (mask[i])
858 // Trying
859 wmSetPixel(pwc,y,x+i,GetRValue(Current->pixel), GetGValue(Current->pixel), GetBValue(Current->pixel));
860 }
861 else {
862 for (i=0; i<n; i++)
863 if (mask[i])
864 SetPixel(DC, y, x+i, Current->pixel);
865 }
866
867 DD_RELEASEDC;
868
869 ENDPROFILE(write_monocolor_span)
870 }
871
872
873
874 /**********************************************************************/
875 /***** Array-based pixel drawing *****/
876 /**********************************************************************/
877
878
879 /* Write an array of pixels with a boolean mask. */
880 static void write_index_pixels( GLcontext* ctx,
881 GLuint n, const GLint x[], const GLint y[],
882 const GLuint index[], const GLubyte mask[] )
883 {
884 STARTPROFILE
885 GLuint i;
886 assert(Current->rgb_flag==GL_FALSE);
887 for (i=0; i<n; i++) {
888 if (mask[i]) {
889 BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];
890 *Mem = index[i];
891 }
892 }
893 ENDPROFILE(write_index_pixels)
894 }
895
896
897
898 /*
899 * Write an array of pixels with a boolean mask. The current color
900 * index is used for all pixels.
901 */
902 static void write_monoindex_pixels( GLcontext* ctx,
903 GLuint n,
904 const GLint x[], const GLint y[],
905 const GLubyte mask[] )
906 {
907 STARTPROFILE
908 GLuint i;
909 assert(Current->rgb_flag==GL_FALSE);
910 for (i=0; i<n; i++) {
911 if (mask[i]) {
912 BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];
913 *Mem = Current->pixel;
914 }
915 }
916 ENDPROFILE(write_monoindex_pixels)
917 }
918
919
920
921 /* Write an array of pixels with a boolean mask. */
922 static void write_color_pixels( GLcontext* ctx,
923 GLuint n, const GLint x[], const GLint y[],
924 const GLubyte r[], const GLubyte g[],
925 const GLubyte b[], const GLubyte a[],
926 const GLubyte mask[] )
927 {
928 STARTPROFILE
929 GLuint i;
930 PWMC pwc = Current;
931 HDC DC=DD_GETDC;
932 assert(Current->rgb_flag==GL_TRUE);
933 for (i=0; i<n; i++)
934 if (mask[i])
935 wmSetPixel(pwc, FLIP(y[i]),x[i],r[i],g[i],b[i]);
936 DD_RELEASEDC;
937 ENDPROFILE(write_color_pixels)
938 }
939
940
941
942 /*
943 * Write an array of pixels with a boolean mask. The current color
944 * is used for all pixels.
945 */
946 static void write_monocolor_pixels( GLcontext* ctx,
947 GLuint n,
948 const GLint x[], const GLint y[],
949 const GLubyte mask[] )
950 {
951 STARTPROFILE
952 GLuint i;
953 PWMC pwc = Current;
954 HDC DC=DD_GETDC;
955 assert(Current->rgb_flag==GL_TRUE);
956 for (i=0; i<n; i++)
957 if (mask[i])
958 wmSetPixel(pwc, FLIP(y[i]),x[i],GetRValue(Current->pixel),
959 GetGValue(Current->pixel), GetBValue(Current->pixel));
960 DD_RELEASEDC;
961 ENDPROFILE(write_monocolor_pixels)
962 }
963
964
965
966 /**********************************************************************/
967 /***** Read spans/arrays of pixels *****/
968 /**********************************************************************/
969
970
971 /* Read a horizontal span of color-index pixels. */
972 static void read_index_span( GLcontext* ctx, GLuint n, GLint x, GLint y, GLuint index[])
973 {
974 STARTPROFILE
975 GLuint i;
976 BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
977 assert(Current->rgb_flag==GL_FALSE);
978 for (i=0; i<n; i++)
979 index[i]=Mem[i];
980 ENDPROFILE(read_index_span)
981
982 }
983
984
985
986
987 /* Read an array of color index pixels. */
988 static void read_index_pixels( GLcontext* ctx,
989 GLuint n, const GLint x[], const GLint y[],
990 GLuint indx[], const GLubyte mask[] )
991 {
992 STARTPROFILE
993 GLuint i;
994 assert(Current->rgb_flag==GL_FALSE);
995 for (i=0; i<n; i++) {
996 if (mask[i]) {
997 indx[i]=*(Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i]);
998 }
999 }
1000 ENDPROFILE(read_index_pixels)
1001 }
1002
1003
1004
1005 /* Read a horizontal span of color pixels. */
1006 static void read_color_span( GLcontext* ctx,
1007 GLuint n, GLint x, GLint y,
1008 GLubyte red[], GLubyte green[],
1009 GLubyte blue[], GLubyte alpha[] )
1010 {
1011 STARTPROFILE
1012 UINT i;
1013 COLORREF Color;
1014 HDC DC=DD_GETDC;
1015 assert(Current->rgb_flag==GL_TRUE);
1016 y=FLIP(y);
1017 for (i=0; i<n; i++)
1018 {
1019 Color=GetPixel(DC,x+i,y);
1020 red[i]=GetRValue(Color);
1021 green[i]=GetGValue(Color);
1022 blue[i]=GetBValue(Color);
1023 alpha[i]=255;
1024 }
1025 DD_RELEASEDC;
1026 memset(alpha,0,n*sizeof(GLint));
1027 ENDPROFILE(read_color_span)
1028 }
1029
1030
1031 /* Read an array of color pixels. */
1032 static void read_color_pixels( GLcontext* ctx,
1033 GLuint n, const GLint x[], const GLint y[],
1034 GLubyte red[], GLubyte green[],
1035 GLubyte blue[], GLubyte alpha[],
1036 const GLubyte mask[] )
1037 {
1038 STARTPROFILE
1039 GLuint i;
1040 COLORREF Color;
1041 HDC DC=DD_GETDC;
1042 assert(Current->rgb_flag==GL_TRUE);
1043 for (i=0; i<n; i++) {
1044 if (mask[i]) {
1045 Color=GetPixel(DC,x[i],FLIP(y[i]));
1046 red[i]=GetRValue(Color);
1047 green[i]=GetGValue(Color);
1048 blue[i]=GetBValue(Color);
1049 alpha[i]=255;
1050 }
1051 }
1052 DD_RELEASEDC;
1053 memset(alpha,0,n*sizeof(GLint));
1054 ENDPROFILE(read_color_pixels)
1055 }
1056
1057
1058
1059 /**********************************************************************/
1060 /**********************************************************************/
1061
1062
1063
1064 void setup_DD_pointers( GLcontext* ctx )
1065 {
1066 ctx->Driver.UpdateState = setup_DD_pointers;
1067 ctx->Driver.GetBufferSize = buffer_size;
1068 ctx->Driver.Finish = finish;
1069 ctx->Driver.Flush = flush;
1070
1071 ctx->Driver.ClearIndex = clear_index;
1072 ctx->Driver.ClearColor = clear_color;
1073 ctx->Driver.Clear = clear;
1074
1075 ctx->Driver.Index = set_index;
1076 ctx->Driver.Color = set_color;
1077 ctx->Driver.IndexMask = index_mask;
1078 ctx->Driver.ColorMask = color_mask;
1079
1080 ctx->Driver.LogicOp = logicop;
1081 ctx->Driver.Dither = dither;
1082
1083 ctx->Driver.SetBuffer = set_buffer;
1084 ctx->Driver.GetBufferSize = buffer_size;
1085
1086 ctx->Driver.PointsFunc = choose_points_function(ctx);
1087 ctx->Driver.LineFunc = choose_line_function(ctx);
1088 ctx->Driver.TriangleFunc = choose_triangle_function( ctx );
1089
1090 /* Pixel/span writing functions: */
1091 ctx->Driver.WriteColorSpan = write_color_span;
1092 ctx->Driver.WriteMonocolorSpan = write_monocolor_span;
1093 ctx->Driver.WriteColorPixels = write_color_pixels;
1094 ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels;
1095 ctx->Driver.WriteIndexSpan = write_index_span;
1096 ctx->Driver.WriteMonoindexSpan = write_monoindex_span;
1097 ctx->Driver.WriteIndexPixels = write_index_pixels;
1098 ctx->Driver.WriteMonoindexPixels = write_monoindex_pixels;
1099
1100 /* Pixel/span reading functions: */
1101 ctx->Driver.ReadIndexSpan = read_index_span;
1102 ctx->Driver.ReadColorSpan = read_color_span;
1103 ctx->Driver.ReadIndexPixels = read_index_pixels;
1104 ctx->Driver.ReadColorPixels = read_color_pixels;
1105 }
1106
1107
1108 /**********************************************************************/
1109 /***** WMesa API Functions *****/
1110 /**********************************************************************/
1111
1112
1113
1114 #define PAL_SIZE 256
1115 static void GetPalette(HPALETTE Pal,RGBQUAD *aRGB)
1116 {
1117 STARTPROFILE
1118 int i;
1119 HDC hdc;
1120 struct
1121 {
1122 WORD Version;
1123 WORD NumberOfEntries;
1124 PALETTEENTRY aEntries[PAL_SIZE];
1125 } Palette =
1126 {
1127 0x300,
1128 PAL_SIZE
1129 };
1130 hdc=GetDC(NULL);
1131 if (Pal!=NULL)
1132 GetPaletteEntries(Pal,0,PAL_SIZE,Palette.aEntries);
1133 else
1134 GetSystemPaletteEntries(hdc,0,PAL_SIZE,Palette.aEntries);
1135 if (GetSystemPaletteUse(hdc) == SYSPAL_NOSTATIC)
1136 {
1137 for(i = 0; i <PAL_SIZE; i++)
1138 Palette.aEntries[i].peFlags = PC_RESERVED;
1139 Palette.aEntries[255].peRed = 255;
1140 Palette.aEntries[255].peGreen = 255;
1141 Palette.aEntries[255].peBlue = 255;
1142 Palette.aEntries[255].peFlags = 0;
1143 Palette.aEntries[0].peRed = 0;
1144 Palette.aEntries[0].peGreen = 0;
1145 Palette.aEntries[0].peBlue = 0;
1146 Palette.aEntries[0].peFlags = 0;
1147 }
1148 else
1149 {
1150 int nStaticColors;
1151 int nUsableColors;
1152 nStaticColors = GetDeviceCaps(hdc, NUMCOLORS)/2;
1153 for (i=0; i<nStaticColors; i++)
1154 Palette.aEntries[i].peFlags = 0;
1155 nUsableColors = PAL_SIZE-nStaticColors;
1156 for (; i<nUsableColors; i++)
1157 Palette.aEntries[i].peFlags = PC_RESERVED;
1158 for (; i<PAL_SIZE-nStaticColors; i++)
1159 Palette.aEntries[i].peFlags = PC_RESERVED;
1160 for (i=PAL_SIZE-nStaticColors; i<PAL_SIZE; i++)
1161 Palette.aEntries[i].peFlags = 0;
1162 }
1163 ReleaseDC(NULL,hdc);
1164 for (i=0; i<PAL_SIZE; i++)
1165 {
1166 aRGB[i].rgbRed=Palette.aEntries[i].peRed;
1167 aRGB[i].rgbGreen=Palette.aEntries[i].peGreen;
1168 aRGB[i].rgbBlue=Palette.aEntries[i].peBlue;
1169 aRGB[i].rgbReserved=Palette.aEntries[i].peFlags;
1170 }
1171 ENDPROFILE(GetPalette)
1172 }
1173
1174
1175 WMesaContext WMesaCreateContext( HWND hWnd, HPALETTE* Pal,
1176 GLboolean rgb_flag,
1177 GLboolean db_flag )
1178 {
1179 RECT CR;
1180 WMesaContext c;
1181 GLboolean true_color_flag;
1182 c = (struct wmesa_context * ) calloc(1,sizeof(struct wmesa_context));
1183 if (!c)
1184 return NULL;
1185
1186 c->Window=hWnd;
1187 c->hDC = GetDC(hWnd);
1188 true_color_flag = GetDeviceCaps(c->hDC, BITSPIXEL) > 8;
1189 #ifdef DDRAW
1190 if(true_color_flag) c->rgb_flag = rgb_flag = GL_TRUE;
1191 #endif
1192
1193
1194 #ifdef DITHER
1195 if ((true_color_flag==GL_FALSE) && (rgb_flag == GL_TRUE)){
1196 c->dither_flag = GL_TRUE;
1197 c->hPalHalfTone = WinGCreateHalftonePalette();
1198 }
1199 else
1200 c->dither_flag = GL_FALSE;
1201 #else
1202 c->dither_flag = GL_FALSE;
1203 #endif
1204
1205
1206 if (rgb_flag==GL_FALSE)
1207 {
1208 c->rgb_flag = GL_FALSE;
1209 // c->pixel = 1;
1210 c->db_flag = db_flag =GL_TRUE; // WinG requires double buffering
1211 printf("Single buffer is not supported in color index mode, setting to double buffer.\n");
1212 }
1213 else
1214 {
1215 c->rgb_flag = GL_TRUE;
1216 // c->pixel = 0;
1217 }
1218 GetClientRect(c->Window,&CR);
1219 c->width=CR.right;
1220 c->height=CR.bottom;
1221 if (db_flag)
1222 {
1223 c->db_flag = 1;
1224 /* Double buffered */
1225 #ifndef DDRAW
1226 // if (c->rgb_flag==GL_TRUE && c->dither_flag != GL_TRUE )
1227 {
1228 wmCreateBackingStore(c, c->width, c->height);
1229
1230 }
1231 #endif
1232 }
1233 else
1234 {
1235 /* Single Buffered */
1236 if (c->rgb_flag)
1237 c->db_flag = 0;
1238 }
1239 #ifdef DDRAW
1240 if (DDInit(c,hWnd) == GL_FALSE) {
1241 free( (void *) c );
1242 exit(1);
1243 }
1244 #endif
1245
1246
1247 c->gl_visual = gl_create_visual(rgb_flag,
1248 GL_FALSE, /* software alpha */
1249 db_flag, /* db_flag */
1250 16, /* depth_bits */
1251 8, /* stencil_bits */
1252 8, /* accum_bits */
1253 8,
1254 255.0, 255.0, 255.0, 255.0,
1255 8,8,8,8 );
1256
1257 if (!c->gl_visual) {
1258 return NULL;
1259 }
1260
1261 /* allocate a new Mesa context */
1262 c->gl_ctx = gl_create_context( c->gl_visual, NULL,c);
1263
1264 if (!c->gl_ctx) {
1265 gl_destroy_visual( c->gl_visual );
1266 free(c);
1267 return NULL;
1268 }
1269
1270 c->gl_buffer = gl_create_framebuffer( c->gl_visual );
1271 if (!c->gl_buffer) {
1272 gl_destroy_visual( c->gl_visual );
1273 gl_destroy_context( c->gl_ctx );
1274 free(c);
1275 return NULL;
1276 }
1277 // setup_DD_pointers(c->gl_ctx);
1278
1279 return c;
1280 }
1281
1282 void WMesaDestroyContext( void )
1283 {
1284 WMesaContext c = Current;
1285 ReleaseDC(c->Window,c->hDC);
1286 WC = c;
1287 if(c->hPalHalfTone != NULL)
1288 DeleteObject(c->hPalHalfTone);
1289 gl_destroy_visual( c->gl_visual );
1290 gl_destroy_framebuffer( c->gl_buffer );
1291 gl_destroy_context( c->gl_ctx );
1292
1293 if (c->db_flag)
1294 #ifdef DDRAW
1295 DDFree(c);
1296 #else
1297 wmDeleteBackingStore(c);
1298 #endif
1299 free( (void *) c );
1300 //Following code is added to enable parallel render
1301 // Parallel render only work in double buffer mode
1302 #if !defined(NO_PARALLEL)
1303 if(parallelMachine)
1304 PRDestroyRenderBuffer();
1305 #endif
1306 // End modification
1307 }
1308
1309
1310
1311 void /*APIENTRY*/ WMesaMakeCurrent( WMesaContext c )
1312 {
1313 if(!c){
1314 Current = c;
1315 return;
1316 }
1317
1318 //
1319 // A little optimization
1320 // If it already is current,
1321 // don't set it again
1322 //
1323 if(Current == c)
1324 return;
1325
1326 //gl_set_context( c->gl_ctx );
1327 gl_make_current(c->gl_ctx, c->gl_buffer);
1328 Current = c;
1329 setup_DD_pointers(c->gl_ctx);
1330 if (Current->gl_ctx->Viewport.Width==0) {
1331 /* initialize viewport to window size */
1332 gl_Viewport( Current->gl_ctx,
1333 0, 0, Current->width, Current->height );
1334 }
1335 if ((c->cColorBits <= 8 ) && (c->rgb_flag == GL_TRUE)){
1336 WMesaPaletteChange(c->hPalHalfTone);
1337 }
1338 }
1339
1340
1341
1342 void /*APIENTRY*/ WMesaSwapBuffers( void )
1343 {
1344 HDC DC = Current->hDC;
1345 if (Current->db_flag)
1346 wmFlush(Current);
1347 }
1348
1349
1350
1351 void /*APIENTRY*/ WMesaPaletteChange(HPALETTE Pal)
1352 {
1353 int vRet;
1354 LPPALETTEENTRY pPal;
1355 if (Current && (Current->rgb_flag==GL_FALSE || Current->dither_flag == GL_TRUE))
1356 {
1357 pPal = (PALETTEENTRY *)malloc( 256 * sizeof(PALETTEENTRY));
1358 Current->hPal=Pal;
1359 // GetPaletteEntries( Pal, 0, 256, pPal );
1360 GetPalette( Pal, pPal );
1361 #ifdef DDRAW
1362 Current->lpDD->lpVtbl->CreatePalette(Current->lpDD,DDPCAPS_8BIT,
1363 pPal, &(Current->lpDDPal), NULL);
1364 if (Current->lpDDPal)
1365 Current->lpDDSPrimary->lpVtbl->SetPalette(Current->lpDDSPrimary,Current->lpDDPal);
1366 #else
1367 vRet = SetDIBColorTable(Current->dib.hDC,0,256,pPal);
1368 #endif
1369 free( pPal );
1370 }
1371
1372 }
1373
1374
1375
1376
1377 static unsigned char threeto8[8] = {
1378 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
1379 };
1380
1381 static unsigned char twoto8[4] = {
1382 0, 0x55, 0xaa, 0xff
1383 };
1384
1385 static unsigned char oneto8[2] = {
1386 0, 255
1387 };
1388
1389 static unsigned char componentFromIndex(UCHAR i, UINT nbits, UINT shift)
1390 {
1391 unsigned char val;
1392
1393 val = i >> shift;
1394 switch (nbits) {
1395
1396 case 1:
1397 val &= 0x1;
1398 return oneto8[val];
1399
1400 case 2:
1401 val &= 0x3;
1402 return twoto8[val];
1403
1404 case 3:
1405 val &= 0x7;
1406 return threeto8[val];
1407
1408 default:
1409 return 0;
1410 }
1411 }
1412
1413 void /*WINAPI*/ wmCreatePalette( PWMC pwdc )
1414 {
1415 /* Create a compressed and re-expanded 3:3:2 palette */
1416 int i;
1417 LOGPALETTE *pPal;
1418 BYTE rb, rs, gb, gs, bb, bs;
1419
1420 pwdc->nColors = 0x100;
1421
1422 pPal = (PLOGPALETTE)malloc(sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY));
1423 memset( pPal, 0, sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY) );
1424
1425 pPal->palVersion = 0x300;
1426
1427 rb = REDBITS;
1428 rs = REDSHIFT;
1429 gb = GREENBITS;
1430 gs = GREENSHIFT;
1431 bb = BLUEBITS;
1432 bs = BLUESHIFT;
1433
1434 if (pwdc->db_flag) {
1435
1436 /* Need to make two palettes: one for the screen DC and one for the DIB. */
1437 pPal->palNumEntries = pwdc->nColors;
1438 for (i = 0; i < pwdc->nColors; i++) {
1439 pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
1440 pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
1441 pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
1442 pPal->palPalEntry[i].peFlags = 0;
1443 }
1444 pwdc->hGLPalette = CreatePalette( pPal );
1445 pwdc->hPalette = CreatePalette( pPal );
1446 }
1447
1448 else {
1449 pPal->palNumEntries = pwdc->nColors;
1450 for (i = 0; i < pwdc->nColors; i++) {
1451 pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
1452 pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
1453 pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
1454 pPal->palPalEntry[i].peFlags = 0;
1455 }
1456 pwdc->hGLPalette = CreatePalette( pPal );
1457 }
1458
1459 free(pPal);
1460
1461 }
1462
1463 void /*WINAPI*/ wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1464 {
1465 if(Current->db_flag){
1466 LPBYTE lpb = pwc->pbPixels;
1467 LPDWORD lpdw;
1468 LPWORD lpw;
1469 UINT nBypp = pwc->cColorBits / 8;
1470 UINT nOffset = iPixel % nBypp;
1471
1472 // Move the pixel buffer pointer to the scanline that we
1473 // want to access
1474
1475 // pwc->dib.fFlushed = FALSE;
1476
1477 lpb += pwc->ScanWidth * iScanLine;
1478 // Now move to the desired pixel
1479 lpb += iPixel * nBypp;
1480 lpb = PIXELADDR(iPixel, iScanLine);
1481 lpdw = (LPDWORD)lpb;
1482 lpw = (LPWORD)lpb;
1483
1484 if(nBypp == 1){
1485 if(pwc->dither_flag)
1486 *lpb = DITHER_RGB_2_8BIT(r,g,b,iScanLine,iPixel);
1487 else
1488 *lpb = BGR8(r,g,b);
1489 }
1490 else if(nBypp == 2)
1491 *lpw = BGR16(r,g,b);
1492 else if (nBypp == 3){
1493 *lpdw = BGR24(r,g,b);
1494 }
1495 else if (nBypp == 4)
1496 *lpdw = BGR32(r,g,b);
1497 }
1498 else{
1499 HDC DC = DD_GETDC;
1500 SetPixel(DC, iPixel, iScanLine, RGB(r,g,b));
1501 DD_RELEASEDC;
1502 }
1503 }
1504
1505 void /*WINAPI*/ wmCreateDIBSection(
1506 HDC hDC,
1507 PWMC pwc, // handle of device context
1508 CONST BITMAPINFO *pbmi, // address of structure containing bitmap size, format, and color data
1509 UINT iUsage // color data type indicator: RGB values or palette indices
1510 )
1511 {
1512 DWORD dwSize = 0;
1513 DWORD dwScanWidth;
1514 UINT nBypp = pwc->cColorBits / 8;
1515 HDC hic;
1516
1517 dwScanWidth = (((pwc->ScanWidth * nBypp)+ 3) & ~3);
1518
1519 pwc->ScanWidth =pwc->pitch = dwScanWidth;
1520
1521 if (stereo_flag)
1522 pwc->ScanWidth = 2* pwc->pitch;
1523
1524 dwSize = sizeof(BITMAPINFO) + (dwScanWidth * pwc->height);
1525
1526 pwc->dib.hFileMap = CreateFileMapping((HANDLE)PAGE_FILE,
1527 NULL,
1528 PAGE_READWRITE | SEC_COMMIT,
1529 0,
1530 dwSize,
1531 NULL);
1532
1533 if (!pwc->dib.hFileMap)
1534 return;
1535
1536 pwc->dib.base = MapViewOfFile(pwc->dib.hFileMap,
1537 FILE_MAP_ALL_ACCESS,
1538 0,
1539 0,
1540 0);
1541
1542 if(!pwc->dib.base){
1543 CloseHandle(pwc->dib.hFileMap);
1544 return;
1545 }
1546
1547 // pwc->pbPixels = pwc->addrOffScreen = ((LPBYTE)pwc->dib.base) + sizeof(BITMAPINFO);
1548
1549 // pwc->dib.hDC = CreateCompatibleDC(hDC);
1550
1551 CopyMemory(pwc->dib.base, pbmi, sizeof(BITMAPINFO));
1552
1553 hic = CreateIC("display", NULL, NULL, NULL);
1554 pwc->dib.hDC = CreateCompatibleDC(hic);
1555
1556
1557 /* pwc->hbmDIB = CreateDIBitmap(hic,
1558 &(pwc->bmi.bmiHeader),
1559 CBM_INIT,
1560 pwc->pbPixels,
1561 &(pwc->bmi),
1562 DIB_RGB_COLORS);
1563 */
1564 pwc->hbmDIB = CreateDIBSection(hic,
1565 &(pwc->bmi),
1566 (iUsage ? DIB_PAL_COLORS : DIB_RGB_COLORS),
1567 &(pwc->pbPixels),
1568 pwc->dib.hFileMap,
1569 0);
1570 /*
1571 pwc->hbmDIB = CreateDIBSection(hic,
1572 &(pwc->bmi),
1573 DIB_RGB_COLORS,
1574 &(pwc->pbPixels),
1575 pwc->dib.hFileMap,
1576 0);
1577 */
1578 pwc->ScreenMem = pwc->addrOffScreen = pwc->pbPixels;
1579 pwc->hOldBitmap = SelectObject(pwc->dib.hDC, pwc->hbmDIB);
1580
1581 DeleteDC(hic);
1582
1583 return;
1584
1585 }
1586
1587 //
1588 // Blit memory DC to screen DC
1589 //
1590 BOOL /*WINAPI*/ wmFlush(PWMC pwc)
1591 {
1592 BOOL bRet = 0;
1593 DWORD dwErr = 0;
1594 HRESULT ddrval;
1595
1596 // Now search through the torus frames and mark used colors
1597 if(pwc->db_flag){
1598 #ifdef DDRAW
1599 if (pwc->lpDDSOffScreen == NULL)
1600 if(DDCreateOffScreen(pwc) == GL_FALSE)
1601 return;
1602
1603 pwc->lpDDSOffScreen->lpVtbl->Unlock(pwc->lpDDSOffScreen, NULL);
1604
1605 while( 1 )
1606 {
1607 ddrval = pwc->lpDDSPrimary->lpVtbl->Blt( pwc->lpDDSPrimary,
1608 &(pwc->rectSurface), pwc->lpDDSOffScreen, &(pwc->rectOffScreen), 0, NULL );
1609
1610 if( ddrval == DD_OK )
1611 {
1612 break;
1613 }
1614 if( ddrval == DDERR_SURFACELOST )
1615 {
1616 if(!DDRestoreAll(pwc))
1617 {
1618 break;
1619 }
1620 }
1621 if( ddrval != DDERR_WASSTILLDRAWING )
1622 {
1623 break;
1624 }
1625 }
1626
1627 while (pwc->lpDDSOffScreen->lpVtbl->Lock(pwc->lpDDSOffScreen,
1628 NULL, &(pwc->ddsd), 0, NULL) == DDERR_WASSTILLDRAWING)
1629 ;
1630
1631 if(ddrval != DD_OK)
1632 dwErr = GetLastError();
1633 #else
1634 bRet = BitBlt(pwc->hDC, 0, 0, pwc->width, pwc->height,
1635 pwc->dib.hDC, 0, 0, SRCCOPY);
1636 #endif
1637 }
1638
1639 return(TRUE);
1640
1641 }
1642
1643
1644 // The following code is added by Li Wei to enable stereo display
1645
1646 #if !defined(NO_STEREO)
1647
1648 void WMesaShowStereo(GLuint list)
1649 {
1650
1651 GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
1652 GLfloat cm[16];
1653 GLint matrix_mode;
1654 // Must use double Buffer
1655 if( ! Current-> db_flag )
1656 return;
1657
1658
1659 glGetIntegerv(GL_MATRIX_MODE,&matrix_mode);
1660
1661 // glPushMatrix(); //****
1662 WMesaViewport(Current->gl_ctx,0,Current->height/2,Current->width,Current->height/2);
1663 // Current->gl_ctx->NewState = 0;
1664
1665 // glViewport(0,0,Current->width,Current->height/2);
1666 if(matrix_mode!=GL_MODELVIEW)
1667 glMatrixMode(GL_MODELVIEW);
1668
1669 glGetFloatv(GL_MODELVIEW_MATRIX,cm);
1670 glLoadIdentity();
1671 gluLookAt(viewDistance/2,0.0,0.0 ,
1672 viewDistance/2,0.0,-1.0,
1673 0.0,1.0,0.0 );
1674 // glTranslatef(viewDistance/2.0,0.,0.);
1675 glMultMatrixf( cm );
1676
1677 Current->ScreenMem = Current->pbPixels = Current->addrOffScreen;
1678 //glPushMatrix();
1679 glCallList( list );
1680 //glPopMatrix();
1681
1682 glGetFloatv(GL_MODELVIEW_MATRIX,cm);
1683 glLoadIdentity();
1684 gluLookAt(-viewDistance/2,0.0,0.0 ,
1685 -viewDistance/2,0.0,-1.0,
1686 0.0,1.0,0.0 );
1687 // glTranslatef(-viewDistance/2.0,0.,0.);
1688 glMultMatrixf(cm);
1689
1690 Current->ScreenMem = Current->pbPixels = Current->addrOffScreen + Current->pitch;
1691 glCallList(list);
1692 if(matrix_mode!=GL_MODELVIEW)
1693 glMatrixMode(matrix_mode);
1694
1695 // glPopMatrix();
1696 glFlush();
1697
1698 WMesaViewport(Current->gl_ctx,0,0,Current->width,Current->height);
1699 // Current->gl_ctx->NewState = 0;
1700 WMesaSwapBuffers();
1701
1702 }
1703
1704 void toggleStereoMode()
1705 {
1706 if(!Current->db_flag)
1707 return;
1708 if(!stereo_flag){
1709 stereo_flag = 1;
1710 if(stereoBuffer==GL_FALSE)
1711 #if !defined(NO_PARALLEL)
1712 if(!parallelFlag)
1713 #endif
1714 {
1715 Current->ScanWidth = Current->pitch*2;
1716 }
1717 }
1718 else {
1719 stereo_flag = 0;
1720 #if !defined(NO_PARALLEL)
1721 if(!parallelFlag)
1722 #endif
1723 Current->ScanWidth = Current->pitch;
1724 Current->pbPixels = Current->addrOffScreen;
1725 }
1726 }
1727
1728 /* if in stereo mode, the following function is called */
1729 void glShowStereo(GLuint list)
1730 {
1731 WMesaShowStereo(list);
1732 }
1733
1734 #endif // End if NO_STEREO not defined
1735
1736 #if !defined(NO_PARALLEL)
1737
1738 void toggleParallelMode(void)
1739 {
1740 if(!parallelFlag){
1741 parallelFlag = GL_TRUE;
1742 if(parallelMachine==GL_FALSE){
1743 PRCreateRenderBuffer( Current->rgb_flag? GL_RGBA :GL_COLOR_INDEX,
1744 Current->cColorBits/8,
1745 Current->width ,Current->height,
1746 Current->ScanWidth,
1747 Current->rgb_flag? Current->pbPixels: Current->ScreenMem);
1748 parallelMachine = GL_TRUE;
1749 }
1750 }
1751 else {
1752 parallelFlag = GL_FALSE;
1753 if(parallelMachine==GL_TRUE){
1754 PRDestroyRenderBuffer();
1755 parallelMachine=GL_FALSE;
1756 ReadyForNextFrame = GL_TRUE;
1757 }
1758
1759 /***********************************************
1760 // Seems something wrong!!!!
1761 ************************************************/
1762
1763 WMesaMakeCurrent(Current);
1764 #if !defined(NO_STEREO)
1765 stereo_flag = GL_FALSE ;
1766 #endif
1767 }
1768 }
1769
1770 void PRShowRenderResult(void)
1771 {
1772 int flag = 0;
1773 if(!glImageRendered())
1774 return;
1775
1776 if (parallelFlag)
1777 {
1778 WMesaSwapBuffers();
1779 }
1780
1781 }
1782 #endif //End if NO_PARALLEL not defined
1783
1784 //end modification
1785
1786 BYTE DITHER_RGB_2_8BIT( int red, int green, int blue, int pixel, int scanline)
1787 {
1788 char unsigned redtemp, greentemp, bluetemp, paletteindex;
1789
1790 //*** now, look up each value in the halftone matrix
1791 //*** using an 8x8 ordered dither.
1792 redtemp = aDividedBy51[red]
1793 + (aModulo51[red] > aHalftone8x8[(pixel%8)*8
1794 + scanline%8]);
1795 greentemp = aDividedBy51[(char unsigned)green]
1796 + (aModulo51[green] > aHalftone8x8[
1797 (pixel%8)*8 + scanline%8]);
1798 bluetemp = aDividedBy51[(char unsigned)blue]
1799 + (aModulo51[blue] > aHalftone8x8[
1800 (pixel%8)*8 +scanline%8]);
1801
1802 //*** recombine the halftoned rgb values into a palette index
1803 paletteindex =
1804 redtemp + aTimes6[greentemp] + aTimes36[bluetemp];
1805
1806 //*** and translate through the wing halftone palette
1807 //*** translation vector to give the correct value.
1808 return aWinGHalftoneTranslation[paletteindex];
1809 }
1810
1811 #ifdef DDRAW
1812 /*
1813 * restoreAll
1814 *
1815 * restore all lost objects
1816 */
1817 HRESULT DDRestoreAll( WMesaContext wc )
1818 {
1819 HRESULT ddrval;
1820
1821 ddrval = wc->lpDDSPrimary->lpVtbl->Restore(wc->lpDDSPrimary);
1822 if( ddrval == DD_OK )
1823 {
1824 ddrval = wc->lpDDSOffScreen->lpVtbl->Restore(wc->lpDDSOffScreen);
1825 }
1826 return ddrval;
1827
1828 } /* restoreAll */
1829
1830
1831 /*
1832 * This function is called if the initialization function fails
1833 */
1834 BOOL initFail( HWND hwnd, WMesaContext wc )
1835 {
1836 DDFree(wc);
1837 MessageBox( hwnd, "DirectDraw Init FAILED", "", MB_OK );
1838 return FALSE;
1839
1840 } /* initFail */
1841
1842
1843 static void DDDeleteOffScreen(WMesaContext wc)
1844 {
1845 if( wc->lpDDSOffScreen != NULL )
1846 {
1847 wc->lpDDSOffScreen->lpVtbl->Unlock(wc->lpDDSOffScreen,NULL);
1848 wc->lpDDSOffScreen->lpVtbl->Release(wc->lpDDSOffScreen);
1849 wc->lpDDSOffScreen = NULL;
1850 }
1851
1852 }
1853
1854 static void DDFreePrimarySurface(WMesaContext wc)
1855 {
1856 if( wc->lpDDSPrimary != NULL )
1857 {
1858 if(wc->db_flag == GL_FALSE)
1859 wc->lpDDSPrimary->lpVtbl->ReleaseDC(wc->lpDDSPrimary, wc->hDC);
1860 wc->lpDDSPrimary->lpVtbl->Release(wc->lpDDSPrimary);
1861 wc->lpDDSPrimary = NULL;
1862 }
1863 }
1864
1865 static BOOL DDCreatePrimarySurface(WMesaContext wc)
1866 {
1867 HRESULT ddrval;
1868 DDSCAPS ddscaps;
1869 wc->ddsd.dwSize = sizeof( wc->ddsd );
1870 wc->ddsd.dwFlags = DDSD_CAPS;
1871 wc->ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1872
1873 ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD,&(wc->ddsd), &(wc->lpDDSPrimary), NULL );
1874 if( ddrval != DD_OK )
1875 {
1876 return initFail(wc->hwnd , wc);
1877 }
1878 if(wc->db_flag == GL_FALSE)
1879 wc->lpDDSPrimary->lpVtbl->GetDC(wc->lpDDSPrimary, wc->hDC);
1880 return TRUE;
1881 }
1882
1883 static BOOL DDCreateOffScreen(WMesaContext wc)
1884 {
1885 POINT pt;
1886 HRESULT ddrval;
1887 if(wc->lpDD == NULL)
1888 return FALSE;
1889 GetClientRect( wc->hwnd, &(wc->rectOffScreen) );
1890 wc->ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
1891 wc->ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1892 wc->ddsd.dwHeight = wc->rectOffScreen.bottom - wc->rectOffScreen.top;
1893 wc->ddsd.dwWidth = wc->rectOffScreen.right - wc->rectOffScreen.left;
1894
1895 ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD, &(wc->ddsd), &(wc->lpDDSOffScreen), NULL );
1896 if( ddrval != DD_OK )
1897 {
1898 return FALSE;
1899 }
1900
1901 while (wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, &(wc->ddsd), 0, NULL) == DDERR_WASSTILLDRAWING)
1902 ;
1903 // while ((ddrval = wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, &(wc->ddsd), DDLOCK_SURFACEMEMORYPTR , NULL)) != DD_OK)
1904 ;
1905 if(wc->ddsd.lpSurface==NULL)
1906 return initFail(wc->hwnd, wc);
1907
1908 wc->ScreenMem = wc->pbPixels = wc->addrOffScreen = (PBYTE)(wc->ddsd.lpSurface);
1909 wc->ScanWidth = wc->pitch = wc->ddsd.lPitch;
1910 if (stereo_flag)
1911 wc->ScanWidth = wc->ddsd.lPitch*2;
1912
1913 GetClientRect( wc->hwnd, &(wc->rectSurface) );
1914 pt.x = pt.y = 0;
1915 ClientToScreen( wc->hwnd, &pt );
1916 OffsetRect(&(wc->rectSurface), pt.x, pt.y);
1917 wmSetPixelFormat(wc, wc->hDC);
1918 return TRUE;
1919 }
1920
1921 /*
1922 * doInit - do work required for every instance of the application:
1923 * create the window, initialize data
1924 */
1925 static BOOL DDInit( WMesaContext wc, HWND hwnd)
1926 {
1927 HRESULT ddrval;
1928 DWORD dwFrequency;
1929
1930 LPDIRECTDRAW lpDD; // DirectDraw object
1931 LPDIRECTDRAW2 lpDD2;
1932
1933
1934 wc->fullScreen = displayOptions.fullScreen;
1935 wc->gMode = displayOptions.mode;
1936 wc->hwnd = hwnd;
1937 stereo_flag = displayOptions.stereo;
1938 if(wc->db_flag!= GL_TRUE)
1939 stereo_flag = GL_FALSE;
1940 /*
1941 * create the main DirectDraw object
1942 */
1943 ddrval = DirectDrawCreate( NULL, &(wc->lpDD), NULL );
1944 if( ddrval != DD_OK )
1945 {
1946 return initFail(hwnd,wc);
1947 }
1948
1949 // Get exclusive mode if requested
1950 if(wc->fullScreen)
1951 {
1952 ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
1953 }
1954 else
1955 {
1956 ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd, DDSCL_NORMAL );
1957 }
1958 if( ddrval != DD_OK )
1959 {
1960 return initFail(hwnd , wc);
1961 }
1962
1963
1964 /* ddrval = wc->lpDD->lpVtbl->QueryInterface(wc->lpDD, IID_IDirectDraw2,
1965 (LPVOID *)((wc->lpDD2)));
1966
1967 */
1968 if(ddrval != DD_OK)
1969 return initFail(hwnd , wc);
1970
1971
1972 //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
1973 // wc->lpDD2->lpVtbl->GetMonitorFrequency(wc->lpDD, &dwFrequency);
1974 switch( wc->gMode )
1975 {
1976 case 1: ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 640, 480, displayOptions.bpp); break;
1977 case 2: ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 800, 600, displayOptions.bpp); break;
1978 case 3: ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1024, 768, displayOptions.bpp); break;
1979 case 4: ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1152, 864, displayOptions.bpp); break;
1980 case 5: ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1280, 1024, displayOptions.bpp); break;
1981 }
1982
1983 if( ddrval != DD_OK )
1984 {
1985 printf("Can't modify display mode, current mode used\n");
1986 // return initFail(hwnd , wc);
1987 }
1988 //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
1989 switch(ddrval){
1990 case DDERR_INVALIDOBJECT:
1991 break;
1992 case DDERR_INVALIDPARAMS:
1993 break;
1994 case DDERR_UNSUPPORTEDMODE:
1995 ;
1996 }
1997
1998 if(DDCreatePrimarySurface(wc) == GL_FALSE)
1999 return initFail(hwnd, wc);
2000
2001 if(wc->db_flag)
2002 return DDCreateOffScreen(wc);
2003 } /* DDInit */
2004
2005 static void DDFree( WMesaContext wc)
2006 {
2007 if( wc->lpDD != NULL )
2008 {
2009 DDFreePrimarySurface(wc);
2010 DDDeleteOffScreen(wc);
2011 wc->lpDD->lpVtbl->Release(wc->lpDD);
2012 wc->lpDD = NULL;
2013 }
2014 // Clean up the screen on exit
2015 RedrawWindow( NULL, NULL, NULL, RDW_INVALIDATE | RDW_ERASE |
2016 RDW_ALLCHILDREN );
2017
2018 }
2019 #endif
2020
2021 void WMesaMove(void)
2022 {
2023 WMesaContext wc = Current;
2024 POINT pt;
2025 if (Current != NULL){
2026 GetClientRect( wc->hwnd, &(wc->rectSurface) );
2027 pt.x = pt.y = 0;
2028 ClientToScreen( wc->hwnd, &pt );
2029 OffsetRect(&(wc->rectSurface), pt.x, pt.y);
2030 }
2031 }
2032
2033 /*
2034 * Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable
2035 * shortcut.
2036 */
2037 #define PACK_8B8G8R( R, G, B ) ( ((B) << 16) | ((G) << 8) | (R) )
2038
2039
2040 /**********************************************************************/
2041 /*** Triangle rendering ***/
2042 /**********************************************************************/
2043
2044
2045
2046 /*
2047 * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
2048 */
2049 static void smooth_8A8B8G8R_z_triangle( GLcontext *ctx,
2050 GLuint v0, GLuint v1, GLuint v2,
2051 GLuint pv )
2052 {
2053 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2054 #define INTERP_Z 1
2055 #define INTERP_RGB 1
2056 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2057 #define PIXEL_TYPE GLuint
2058 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2059 #define BYTES_PER_ROW (wmesa->ScanWidth)
2060 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2061 { \
2062 GLint i, len = RIGHT-LEFT; \
2063 for (i=0;i<len;i++) { \
2064 GLdepth z = FixedToDepth(ffz); \
2065 if (z < zRow[i]) { \
2066 pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2067 FixedToInt(ffb) ); \
2068 zRow[i] = z; \
2069 } \
2070 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2071 ffz += fdzdx; \
2072 } \
2073 }
2074 #include "tritemp.h"
2075 }
2076
2077
2078 /*
2079 * XImage, smooth, depth-buffered, PF_8R8G8B triangle.
2080 */
2081 static void smooth_8R8G8B_z_triangle( GLcontext *ctx,
2082 GLuint v0, GLuint v1, GLuint v2,
2083 GLuint pv )
2084 {
2085 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2086 #define INTERP_Z 1
2087 #define INTERP_RGB 1
2088 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2089 #define PIXEL_TYPE GLuint
2090 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2091 #define BYTES_PER_ROW (wmesa->ScanWidth)
2092 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2093 { \
2094 GLint i, len = RIGHT-LEFT; \
2095 for (i=0;i<len;i++) { \
2096 GLdepth z = FixedToDepth(ffz); \
2097 if (z < zRow[i]) { \
2098 pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2099 FixedToInt(ffb) ); \
2100 zRow[i] = z; \
2101 } \
2102 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2103 ffz += fdzdx; \
2104 } \
2105 }
2106 #include "tritemp.h"
2107 }
2108
2109
2110
2111 /*
2112 * XImage, smooth, depth-buffered, PF_5R6G5B triangle.
2113 */
2114 static void smooth_5R6G5B_z_triangle( GLcontext *ctx,
2115 GLuint v0, GLuint v1, GLuint v2,
2116 GLuint pv )
2117 {
2118 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2119 #define INTERP_Z 1
2120 #define INTERP_RGB 1
2121 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2122 #define PIXEL_TYPE GLushort
2123 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2124 #define BYTES_PER_ROW (wmesa->ScanWidth)
2125 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2126 { \
2127 GLint i, len = RIGHT-LEFT; \
2128 for (i=0;i<len;i++) { \
2129 GLdepth z = FixedToDepth(ffz); \
2130 if (z < zRow[i]) { \
2131 pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2132 FixedToInt(ffb) ); \
2133 zRow[i] = z; \
2134 } \
2135 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2136 ffz += fdzdx; \
2137 } \
2138 }
2139 #include "tritemp.h"
2140 }
2141
2142 /*
2143 * XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
2144 */
2145 static void flat_8A8B8G8R_z_triangle( GLcontext *ctx, GLuint v0,
2146 GLuint v1, GLuint v2, GLuint pv )
2147 {
2148 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2149 #define INTERP_Z 1
2150 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2151 #define PIXEL_TYPE GLuint
2152 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2153 #define BYTES_PER_ROW (wmesa->ScanWidth)
2154 #define SETUP_CODE \
2155 unsigned long p = PACK_8B8G8R( VB->Color[pv][0], \
2156 VB->Color[pv][1], VB->Color[pv][2] );
2157 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2158 { \
2159 GLint i, len = RIGHT-LEFT; \
2160 for (i=0;i<len;i++) { \
2161 GLdepth z = FixedToDepth(ffz); \
2162 if (z < zRow[i]) { \
2163 pRow[i] = p; \
2164 zRow[i] = z; \
2165 } \
2166 ffz += fdzdx; \
2167 } \
2168 }
2169 #include "tritemp.h"
2170 }
2171
2172
2173 /*
2174 * XImage, flat, depth-buffered, PF_8R8G8B triangle.
2175 */
2176 static void flat_8R8G8B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2177 GLuint v2, GLuint pv )
2178 {
2179 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2180 #define INTERP_Z 1
2181 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2182 #define PIXEL_TYPE GLuint
2183 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2184 #define BYTES_PER_ROW (wmesa->ScanWidth)
2185 #define SETUP_CODE \
2186 unsigned long p = PACK_8R8G8B( VB->Color[pv][0], \
2187 VB->Color[pv][1], VB->Color[pv][2] );
2188 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2189 { \
2190 GLint i, len = RIGHT-LEFT; \
2191 for (i=0;i<len;i++) { \
2192 GLdepth z = FixedToDepth(ffz); \
2193 if (z < zRow[i]) { \
2194 pRow[i] = p; \
2195 zRow[i] = z; \
2196 } \
2197 ffz += fdzdx; \
2198 } \
2199 }
2200 #include "tritemp.h"
2201 }
2202
2203
2204 /*
2205 * XImage, flat, depth-buffered, PF_5R6G5B triangle.
2206 */
2207 static void flat_5R6G5B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2208 GLuint v2, GLuint pv )
2209 {
2210 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2211 #define INTERP_Z 1
2212 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2213 #define PIXEL_TYPE GLushort
2214 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2215 #define BYTES_PER_ROW (wmesa->ScanWidth)
2216 #define SETUP_CODE \
2217 unsigned long p = PACK_5R6G5B( VB->Color[pv][0], \
2218 VB->Color[pv][1], VB->Color[pv][2] );
2219 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2220 { \
2221 GLint i, len = RIGHT-LEFT; \
2222 for (i=0;i<len;i++) { \
2223 GLdepth z = FixedToDepth(ffz); \
2224 if (z < zRow[i]) { \
2225 pRow[i] = p; \
2226 zRow[i] = z; \
2227 } \
2228 ffz += fdzdx; \
2229 } \
2230 }
2231 #include "tritemp.h"
2232 }
2233
2234
2235 /*
2236 * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
2237 */
2238 static void smooth_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2239 GLuint v2, GLuint pv )
2240 {
2241 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2242 #define INTERP_RGB 1
2243 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2244 #define PIXEL_TYPE GLuint
2245 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2246 #define BYTES_PER_ROW (wmesa->ScanWidth)
2247 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2248 { \
2249 GLint xx; \
2250 PIXEL_TYPE *pixel = pRow; \
2251 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2252 *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2253 FixedToInt(ffb) ); \
2254 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2255 } \
2256 }
2257 #include "tritemp.h"
2258 }
2259
2260
2261 /*
2262 * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
2263 */
2264 static void smooth_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2265 GLuint v2, GLuint pv )
2266 {
2267 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2268 #define INTERP_RGB 1
2269 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2270 #define PIXEL_TYPE GLuint
2271 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2272 #define BYTES_PER_ROW (wmesa->ScanWidth)
2273 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2274 { \
2275 GLint xx; \
2276 PIXEL_TYPE *pixel = pRow; \
2277 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2278 *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2279 FixedToInt(ffb) ); \
2280 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2281 } \
2282 }
2283 #include "tritemp.h"
2284 }
2285
2286
2287 /*
2288 * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
2289 */
2290 static void smooth_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2291 GLuint v2, GLuint pv )
2292 {
2293 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2294 #define INTERP_RGB 1
2295 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2296 #define PIXEL_TYPE GLushort
2297 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2298 #define BYTES_PER_ROW (wmesa->ScanWidth)
2299 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2300 { \
2301 GLint xx; \
2302 PIXEL_TYPE *pixel = pRow; \
2303 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2304 *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2305 FixedToInt(ffb) ); \
2306 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2307 } \
2308 }
2309 #include "tritemp.h"
2310 }
2311
2312
2313
2314 /*
2315 * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
2316 */
2317 static void flat_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0,
2318 GLuint v1, GLuint v2, GLuint pv )
2319 {
2320 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2321 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2322 #define PIXEL_TYPE GLuint
2323 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2324 #define BYTES_PER_ROW (wmesa->ScanWidth)
2325 #define SETUP_CODE \
2326 unsigned long p = PACK_8B8G8R( VB->Color[pv][0], \
2327 VB->Color[pv][1], VB->Color[pv][2] );
2328 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2329 { \
2330 GLint xx; \
2331 PIXEL_TYPE *pixel = pRow; \
2332 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2333 *pixel = p; \
2334 } \
2335 }
2336 #include "tritemp.h"
2337 }
2338
2339
2340 /*
2341 * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
2342 */
2343 static void flat_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2344 GLuint v2, GLuint pv )
2345 {
2346 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2347 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2348 #define PIXEL_TYPE GLuint
2349 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2350 #define BYTES_PER_ROW (wmesa->ScanWidth)
2351 #define SETUP_CODE \
2352 unsigned long p = PACK_8R8G8B( VB->Color[pv][0], \
2353 VB->Color[pv][1], VB->Color[pv][2] );
2354 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2355 { \
2356 GLint xx; \
2357 PIXEL_TYPE *pixel = pRow; \
2358 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2359 *pixel = p; \
2360 } \
2361 }
2362 #include "tritemp.h"
2363 }
2364
2365
2366 /*
2367 * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
2368 */
2369 static void flat_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2370 GLuint v2, GLuint pv )
2371 {
2372 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2373 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2374 #define PIXEL_TYPE GLushort
2375 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2376 #define BYTES_PER_ROW (wmesa->ScanWidth)
2377 #define SETUP_CODE \
2378 unsigned long p = PACK_5R6G5B( VB->Color[pv][0], \
2379 VB->Color[pv][1], VB->Color[pv][2] );
2380 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2381 { \
2382 GLint xx; \
2383 PIXEL_TYPE *pixel = pRow; \
2384 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2385 *pixel = p; \
2386 } \
2387 }
2388 #include "tritemp.h"
2389 }
2390
2391
2392 /*
2393 * XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
2394 */
2395
2396 static void smooth_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2397 GLuint v2, GLuint pv )
2398 {
2399 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2400 #define INTERP_Z 1
2401 #define INTERP_INDEX 1
2402 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2403 #define PIXEL_TYPE GLubyte
2404 #define BYTES_PER_ROW (wmesa->ScanWidth)
2405 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2406 { \
2407 GLint i, len = RIGHT-LEFT; \
2408 for (i=0;i<len;i++) { \
2409 GLdepth z = FixedToDepth(ffz); \
2410 if (z < zRow[i]) { \
2411 pRow[i] = FixedToInt(ffi); \
2412 zRow[i] = z; \
2413 } \
2414 ffi += fdidx; \
2415 ffz += fdzdx; \
2416 } \
2417 }
2418
2419 #include "tritemp.h"
2420 }
2421
2422
2423 /*
2424 * XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
2425 */
2426
2427 static void flat_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2428 GLuint v2, GLuint pv )
2429 {
2430 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2431 #define INTERP_Z 1
2432 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2433 #define PIXEL_TYPE GLubyte
2434 #define BYTES_PER_ROW (wmesa->ScanWidth)
2435 #define SETUP_CODE \
2436 GLuint index = VB->Index[pv]; \
2437 if (!VB->MonoColor) { \
2438 /* set the color index */ \
2439 (*ctx->Driver.Index)( ctx, index ); \
2440 }
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] = index; \
2448 zRow[i] = z; \
2449 } \
2450 ffz += fdzdx; \
2451 } \
2452 }
2453 #include "tritemp.h"
2454 }
2455
2456
2457
2458 /*
2459 * XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2460 */
2461
2462 static void smooth_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2463 GLuint v2, GLuint pv )
2464 {
2465 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2466 #define INTERP_Z 1
2467 #define INTERP_INDEX 1
2468 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2469 #define PIXEL_TYPE GLubyte
2470 #define BYTES_PER_ROW (wmesa->ScanWidth)
2471 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2472 { \
2473 GLint xx; \
2474 PIXEL_TYPE *pixel = pRow; \
2475 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2476 *pixel = FixedToInt(ffi); \
2477 ffi += fdidx; \
2478 } \
2479 }
2480 #include "tritemp.h"
2481 }
2482
2483
2484 /*
2485 * XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2486 */
2487 static void flat_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2488 GLuint v2, GLuint pv )
2489 {
2490 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2491 #define INTERP_Z 1
2492 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2493 #define PIXEL_TYPE GLubyte
2494 #define BYTES_PER_ROW (wmesa->ScanWidth)
2495 #define SETUP_CODE \
2496 GLuint index = VB->Index[pv]; \
2497 if (!VB->MonoColor) { \
2498 /* set the color index */ \
2499 (*ctx->Driver.Index)( ctx, index ); \
2500 }
2501 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2502 { \
2503 GLint xx; \
2504 PIXEL_TYPE *pixel = pRow; \
2505 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2506 *pixel = index; \
2507 } \
2508 }
2509 #include "tritemp.h"
2510 }
2511
2512 /*
2513 * XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
2514 */
2515 static void smooth_DITHER8_z_triangle( GLcontext *ctx,
2516 GLuint v0, GLuint v1, GLuint v2,
2517 GLuint pv )
2518 {
2519 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2520 DITHER_RGB_TO_8BIT_SETUP
2521 #define INTERP_Z 1
2522 #define INTERP_RGB 1
2523 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2524 #define PIXEL_TYPE GLubyte
2525 #define BYTES_PER_ROW (wmesa->ScanWidth)
2526 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2527 { \
2528 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
2529 for (i=0;i<len;i++,xx++) { \
2530 GLdepth z = FixedToDepth(ffz); \
2531 if (z < zRow[i]) { \
2532 DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg), \
2533 FixedToInt(ffb), xx, yy); \
2534 pRow[i] = pixelDithered; \
2535 zRow[i] = z; \
2536 } \
2537 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2538 ffz += fdzdx; \
2539 } \
2540 }
2541 #include "tritemp.h"
2542 }
2543
2544 /*
2545 * XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
2546 */
2547 static void flat_DITHER8_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2548 GLuint v2, GLuint pv )
2549 {
2550 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2551 DITHER_RGB_TO_8BIT_SETUP
2552 #define INTERP_Z 1
2553 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2554 #define PIXEL_TYPE GLubyte
2555 #define BYTES_PER_ROW (wmesa->ScanWidth)
2556
2557 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2558 { \
2559 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
2560 for (i=0;i<len;i++,xx++) { \
2561 GLdepth z = FixedToDepth(ffz); \
2562 if (z < zRow[i]) { \
2563 DITHER_RGB_TO_8BIT( VB->Color[pv][0], \
2564 VB->Color[pv][1], VB->Color[pv][2], xx, yy); \
2565 pRow[i] = pixelDithered; \
2566 zRow[i] = z; \
2567 } \
2568 ffz += fdzdx; \
2569 } \
2570 }
2571 #include "tritemp.h"
2572 }
2573
2574 /*
2575 * XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
2576 */
2577 static void smooth_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2578 GLuint v2, GLuint pv )
2579 {
2580 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2581 DITHER_RGB_TO_8BIT_SETUP
2582 #define INTERP_RGB 1
2583 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2584 #define PIXEL_TYPE GLubyte
2585 #define BYTES_PER_ROW (wmesa->ScanWidth)
2586 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2587 { \
2588 GLint xx, yy = FLIP(Y); \
2589 PIXEL_TYPE *pixel = pRow; \
2590 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2591 DITHER_RGB_TO_8BIT( VB->Color[pv][0], VB->Color[pv][1], VB->Color[pv][2], xx, yy);\
2592 *pixel = pixelDithered; \
2593 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2594 } \
2595 }
2596 #include "tritemp.h"
2597 }
2598
2599 /*
2600 * XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
2601 */
2602
2603 static void flat_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2604 GLuint v2, GLuint pv )
2605 {
2606 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2607 DITHER_RGB_TO_8BIT_SETUP
2608 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2609 #define PIXEL_TYPE GLubyte
2610 #define BYTES_PER_ROW (wmesa->ScanWidth)
2611
2612 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2613 { \
2614 GLint xx, yy = FLIP(Y); \
2615 PIXEL_TYPE *pixel = pRow; \
2616 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2617 DITHER_RGB_TO_8BIT( VB->Color[pv][0], \
2618 VB->Color[pv][1], VB->Color[pv][2], xx, yy); \
2619 *pixel = pixelDithered; \
2620 } \
2621 }
2622 #include "tritemp.h"
2623 }
2624
2625
2626
2627
2628 static triangle_func choose_triangle_function( GLcontext *ctx )
2629 {
2630 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2631 int depth = wmesa->cColorBits;
2632
2633 if (ctx->Polygon.SmoothFlag) return NULL;
2634 if (ctx->Texture.Enabled) return NULL;
2635 if (!wmesa->db_flag) return NULL;
2636 /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {
2637 if ( ctx->Light.ShadeModel==GL_SMOOTH
2638 && ctx->RasterMask==DEPTH_BIT
2639 && ctx->Depth.Func==GL_LESS
2640 && ctx->Depth.Mask==GL_TRUE
2641 && ctx->Polygon.StippleFlag==GL_FALSE) {
2642 switch (wmesa->pixelformat) {
2643 case PF_8A8B8G8R:
2644 return smooth_8A8B8G8R_z_triangle;
2645 case PF_8R8G8B:
2646 return smooth_8R8G8B_z_triangle;
2647 case PF_5R6G5B:
2648 return smooth_5R6G5B_z_triangle;
2649 case PF_DITHER8:
2650 return smooth_DITHER8_z_triangle;
2651 case PF_INDEX8:
2652 return smooth_ci_z_triangle;
2653 default:
2654 return NULL;
2655 }
2656 }
2657 if ( ctx->Light.ShadeModel==GL_FLAT
2658 && ctx->RasterMask==DEPTH_BIT
2659 && ctx->Depth.Func==GL_LESS
2660 && ctx->Depth.Mask==GL_TRUE
2661 && ctx->Polygon.StippleFlag==GL_FALSE) {
2662 switch (wmesa->pixelformat) {
2663 case PF_8A8B8G8R:
2664 return flat_8A8B8G8R_z_triangle;
2665 case PF_8R8G8B:
2666 return flat_8R8G8B_z_triangle;
2667 case PF_5R6G5B:
2668 return flat_5R6G5B_z_triangle;
2669 case PF_DITHER8:
2670 return flat_DITHER8_z_triangle;
2671 case PF_INDEX8:
2672 return flat_ci_z_triangle;
2673 default:
2674 return NULL;
2675 }
2676 }
2677 if ( ctx->RasterMask==0 /* no depth test */
2678 && ctx->Light.ShadeModel==GL_SMOOTH
2679 && ctx->Polygon.StippleFlag==GL_FALSE) {
2680 switch (wmesa->pixelformat) {
2681 case PF_8A8B8G8R:
2682 return smooth_8A8B8G8R_triangle;
2683 case PF_8R8G8B:
2684 return smooth_8R8G8B_triangle;
2685 case PF_5R6G5B:
2686 return smooth_5R6G5B_triangle;
2687 case PF_DITHER8:
2688 return smooth_DITHER8_triangle;
2689 case PF_INDEX8:
2690 return smooth_ci_triangle;
2691 default:
2692 return NULL;
2693 }
2694 }
2695
2696 if ( ctx->RasterMask==0 /* no depth test */
2697 && ctx->Light.ShadeModel==GL_FLAT
2698 && ctx->Polygon.StippleFlag==GL_FALSE) {
2699 switch (wmesa->pixelformat) {
2700 case PF_8A8B8G8R:
2701 return flat_8A8B8G8R_triangle;
2702 case PF_8R8G8B:
2703 return flat_8R8G8B_triangle;
2704 case PF_5R6G5B:
2705 return flat_5R6G5B_triangle;
2706 case PF_DITHER8:
2707 return flat_DITHER8_triangle;
2708 case PF_INDEX8:
2709 return flat_ci_triangle;
2710 default:
2711 return NULL;
2712 }
2713 }
2714
2715 return NULL;
2716 }
2717 }
2718
2719 /*
2720 * Define a new viewport and reallocate auxillary buffers if the size of
2721 * the window (color buffer) has changed.
2722 */
2723 void WMesaViewport( GLcontext *ctx,
2724 GLint x, GLint y, GLsizei width, GLsizei height )
2725 {
2726 /* Save viewport */
2727 ctx->Viewport.X = x;
2728 ctx->Viewport.Width = width;
2729 ctx->Viewport.Y = y;
2730 ctx->Viewport.Height = height;
2731
2732 /* compute scale and bias values */
2733 ctx->Viewport.Sx = (GLfloat) width / 2.0F;
2734 ctx->Viewport.Tx = ctx->Viewport.Sx + x;
2735 ctx->Viewport.Sy = (GLfloat) height / 2.0F;
2736 ctx->Viewport.Ty = ctx->Viewport.Sy + y;
2737 }