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