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