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