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