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