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