Removed ctx->Driver.LogicOp().
[mesa.git] / src / mesa / drivers / windows / wmesa_stereo.c
1 /*
2 WMesa_stereo.c
3 */
4 // Stereo display feature added by Li Wei
5 // Updated 1996/10/06 11:16:15 CST
6 // Paralell render feature added by Li Wei
7 // liwei@aiar.xjtu.edu.cn
8 // http://sun.aiar.xjtu.edu.cn
9
10 #define WMESA_STEREO_C
11
12 #include <windows.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <wmesadef.h>
16
17 #include <GL\wmesa.h>
18 #include "context.h"
19 #include "dd.h"
20 #include "xform.h"
21 #include "vb.h"
22 #include "matrix.h"
23 #include "depth.h"
24
25 #ifdef PROFILE
26 #include "profile.h"
27 #endif
28
29 #include <wing.h>
30
31 // Code added by Li Wei to enable stereo display and Paralell render
32
33
34 /*#include "mesa_extend.h"*/
35
36 #if !defined(NO_STEREO)
37
38 #include "gl\glu.h"
39 #include "stereo.h"
40
41 PBYTE Buffer_Stereo;
42
43 void WMesaCreateStereoBuffer(void);
44
45 void WMesaInterleave( GLenum aView);
46
47 void WMesaDestroyStereoBuffer(void);
48
49 void WMesaShowStereo(GLuint list);
50 #endif
51 #if !defined(NO_PARALLEL)
52 #include "parallel.h"
53 #endif
54
55 /* end of added code*/
56
57 /* Bit's used for dest: */
58 #define FRONT_PIXMAP 1
59 #define BACK_PIXMAP 2
60 #define BACK_XIMAGE 4
61
62 static PWMC Current = NULL;
63 WMesaContext WC = NULL;
64
65 #ifdef NDEBUG
66 #define assert(ignore) ((void) 0)
67 #else
68 void Mesa_Assert(void *Cond,void *File,unsigned Line)
69 {
70 char Msg[512];
71 sprintf(Msg,"%s %s %d",Cond,File,Line);
72 MessageBox(NULL,Msg,"Assertion failed.",MB_OK);
73 exit(1);
74 }
75 #define assert(e) if (!e) Mesa_Assert(#e,__FILE__,__LINE__);
76 #endif
77
78 #define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
79 #define DD_RELEASEDC
80
81 //#define BEGINGDICALL if(Current->rgb_flag)wmFlushBits(Current);
82 #define BEGINGDICALL
83 //#define ENDGDICALL if(Current->rgb_flag)wmGetBits(Current);
84 #define ENDGDICALL
85
86 #define FLIP(Y) (Current->height-(Y)-1)
87
88 #define STARTPROFILE
89 #define ENDPROFILE(PARA)
90
91 static void FlushToFile(PWMC pwc, PSTR szFile);
92
93 BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize);
94
95 BOOL wmDeleteBackingStore(PWMC pwc);
96
97 void wmCreatePalette( PWMC pwdc );
98 BOOL wmSetDibColors(PWMC pwc);
99 void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b);
100
101 void wmCreateDIBSection(
102 HDC hDC,
103 PWMC pwc, // handle of device context
104 CONST BITMAPINFO *pbmi, // address of structure containing bitmap size, format, and color data
105 UINT iUsage // color data type indicator: RGB values or palette indices
106 );
107
108 BOOL wmFlush(PWMC pwc);
109
110 /*
111 * Useful macros:
112 Modified from file osmesa.c
113 */
114
115 #define PIXELADDR(X,Y) ((GLbyte *)Current->pbPixels + (Current->height-Y)* Current->ScanWidth + (X)*nBypp)
116
117
118 /* Finish all pending operations and synchronize. */
119 static void finish(GLcontext* ctx)
120 {
121 /* no op */
122 }
123
124
125 //
126 // We cache all gl draw routines until a flush is made
127 //
128 static void flush(GLcontext* ctx)
129 {
130 STARTPROFILE
131 if(Current->rgb_flag && !(Current->dib.fFlushed)&&!(Current->db_flag)){
132 wmFlush(Current);
133 }
134 ENDPROFILE(flush)
135
136 }
137
138
139
140 /*
141 * Set the color index used to clear the color buffer.
142 */
143 static void clear_index(GLcontext* ctx, GLuint index)
144 {
145 STARTPROFILE
146 Current->clearpixel = index;
147 ENDPROFILE(clear_index)
148 }
149
150
151
152 /*
153 * Set the color used to clear the color buffer.
154 */
155 static void clear_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
156 {
157 STARTPROFILE
158 Current->clearpixel=RGB(r, g, b );
159 ENDPROFILE(clear_color)
160 }
161
162
163
164 /*
165 * Clear the specified region of the color buffer using the clear color
166 * or index as specified by one of the two functions above.
167 */
168 static void clear(GLcontext* ctx,
169 GLboolean all,GLint x, GLint y, GLint width, GLint height )
170 {
171 DWORD dwColor;
172 WORD wColor;
173 LPDWORD lpdw = (LPDWORD)Current->pbPixels;
174 LPWORD lpw = (LPWORD)Current->pbPixels;
175 LPBYTE lpb = Current->pbPixels;
176
177 STARTPROFILE
178
179 if (all){
180 x=y=0;
181 width=Current->width;
182 height=Current->height;
183 }
184 if (Current->rgb_flag==GL_TRUE){
185 if(Current->db_flag==GL_TRUE){
186 UINT nBypp = Current->cColorBits / 8;
187 int i = 0;
188 int iSize;
189
190 if(nBypp == 2){
191 iSize = (Current->width * Current->height) / nBypp;
192
193 wColor = BGR16(GetRValue(Current->clearpixel),
194 GetGValue(Current->clearpixel),
195 GetBValue(Current->clearpixel));
196 dwColor = MAKELONG(wColor, wColor);
197 }
198 else if(nBypp == 4){
199 iSize = (Current->width * Current->height);
200
201 dwColor = BGR32(GetRValue(Current->clearpixel),
202 GetGValue(Current->clearpixel),
203 GetBValue(Current->clearpixel));
204 }
205 //
206 // This is the 24bit case
207 //
208 else {
209
210 iSize = (Current->width * Current->height) / nBypp;
211
212 dwColor = BGR24(GetRValue(Current->clearpixel),
213 GetGValue(Current->clearpixel),
214 GetBValue(Current->clearpixel));
215
216
217 while(i < iSize){
218 *lpdw = dwColor;
219 lpb += nBypp;
220 lpdw = (LPDWORD)lpb;
221 i++;
222 }
223
224 // ENDPROFILE(clear)
225
226 return;
227 }
228
229 while(i < iSize){
230 *lpdw = dwColor;
231 lpdw++;
232 i++;
233 }
234 }
235 else{ // For single buffer
236 HDC DC=DD_GETDC;
237 HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);
238 HBRUSH Brush=CreateSolidBrush(Current->clearpixel);
239 HPEN Old_Pen=SelectObject(DC,Pen);
240 HBRUSH Old_Brush=SelectObject(DC,Brush);
241 Rectangle(DC,x,y,x+width,y+height);
242 SelectObject(DC,Old_Pen);
243 SelectObject(DC,Old_Brush);
244 DeleteObject(Pen);
245 DeleteObject(Brush);
246 DD_RELEASEDC;
247 }
248 }
249 else {
250 int i;
251 char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
252 for (i=0; i<height; i++){
253 memset(Mem,Current->clearpixel,width);
254 Mem+=width;
255 }
256 }
257 ENDPROFILE(clear)
258 }
259
260
261
262 /* Set the current color index. */
263 static void set_index(GLcontext* ctx, GLuint index)
264 {
265 STARTPROFILE
266 Current->pixel=index;
267 ENDPROFILE(set_index)
268 }
269
270
271
272 /* Set the current RGBA color. */
273 static void set_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
274 {
275 STARTPROFILE
276 Current->pixel = RGB( r, g, b );
277 ENDPROFILE(set_color)
278 }
279
280
281
282 /* Set the index mode bitplane mask. */
283 static GLboolean index_mask(GLcontext* ctx, GLuint mask)
284 {
285 /* can't implement */
286 return GL_FALSE;
287 }
288
289
290
291 /* Set the RGBA drawing mask. */
292 static GLboolean color_mask( GLcontext* ctx,
293 GLboolean rmask, GLboolean gmask,
294 GLboolean bmask, GLboolean amask)
295 {
296 /* can't implement */
297 return GL_FALSE;
298 }
299
300
301
302 static void dither( GLcontext* ctx, GLboolean enable )
303 {
304 /* No op */
305 }
306
307
308
309 static GLboolean set_buffer( GLcontext* ctx, GLenum mode )
310 {
311 STARTPROFILE
312 /* TODO: this could be better */
313 if (mode==GL_FRONT || mode==GL_BACK) {
314 return GL_TRUE;
315 }
316 else {
317 return GL_FALSE;
318 }
319 ENDPROFILE(set_buffer)
320 }
321
322
323
324 /* Return characteristics of the output buffer. */
325 static void buffer_size( GLcontext* ctx, GLuint *width, GLuint *height /*, GLuint *depth */)
326 {
327
328 int New_Size;
329 RECT CR;
330
331 STARTPROFILE
332 GetClientRect(Current->Window,&CR);
333
334 *width=CR.right;
335 *height=CR.bottom;
336 // *depth = Current->depth;
337
338 New_Size=((*width)!=Current->width) || ((*height)!=Current->height);
339
340 if (New_Size){
341 Current->width=*width;
342 Current->height=*height;
343 Current->ScanWidth=Current->width;
344 if ((Current->ScanWidth%sizeof(long))!=0)
345 Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));
346
347 if (Current->db_flag){
348 if (Current->rgb_flag==GL_TRUE){
349 wmDeleteBackingStore(Current);
350 wmCreateBackingStore(Current, Current->width, Current->height);
351 }
352 else{
353 Current->ScanWidth=Current->width;
354 if ((Current->ScanWidth%sizeof(long))!=0)
355 Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));
356
357 Current->IndexFormat->bmiHeader.biWidth=Current->width;
358
359 if (Current->IndexFormat->bmiHeader.biHeight<0)
360 Current->IndexFormat->bmiHeader.biHeight=-(Current->height);
361 else
362 Current->IndexFormat->bmiHeader.biHeight=Current->height;
363
364 Current->Compat_BM=WinGCreateBitmap(Current->dib.hDC,Current->IndexFormat,&((void *) Current->ScreenMem));
365
366 DeleteObject(SelectObject(Current->dib.hDC,Current->Compat_BM));
367 }
368 //Code added by Li Wei to enable stereo display
369 // Recreate stereo buffer when stereo_flag is TRUE while parallelFlag is FALSE
370 #if !defined(NO_STEREO)
371 if(stereo_flag
372 #if !defined(NO_PARALLEL)
373 &&!parallelFlag
374 #endif
375 ) {
376 if(stereoBuffer == GL_TRUE)
377 WMesaDestroyStereoBuffer();
378 WMesaCreateStereoBuffer();
379 }
380 #endif
381 // Resize OsmesaBuffer if in Parallel mode
382 #if !defined(NO_PARALLEL)
383 if(parallelFlag)
384 PRSizeRenderBuffer(Current->width, Current->height,Current->ScanWidth,
385 Current->rgb_flag == GL_TRUE ? Current->pbPixels: Current->ScreenMem);
386 #endif
387 //end modification
388
389 }
390 }
391
392 ENDPROFILE(buffer_size)
393 }
394
395
396
397 /**********************************************************************/
398 /***** Accelerated point, line, polygon rendering *****/
399 /**********************************************************************/
400
401
402 static void fast_rgb_points( GLcontext* ctx, GLuint first, GLuint last )
403 {
404 GLuint i;
405 // HDC DC=DD_GETDC;
406 PWMC pwc = Current;
407
408 STARTPROFILE
409
410 if (Current->gl_ctx->VB->MonoColor) {
411 /* all drawn with current color */
412 for (i=first;i<=last;i++) {
413 if (Current->gl_ctx->VB->ClipMask[i]==0) {
414 int x, y;
415 x = (GLint) Current->gl_ctx->VB->Win[i][0];
416 y = FLIP( (GLint) Current->gl_ctx->VB->Win[i][1] );
417 wmSetPixel(pwc, y,x,GetRValue(Current->pixel),
418 GetGValue(Current->pixel), GetBValue(Current->pixel));
419 }
420 }
421 }
422 else {
423 /* draw points of different colors */
424 for (i=first;i<=last;i++) {
425 if (Current->gl_ctx->VB->ClipMask[i]==0) {
426 int x, y;
427 unsigned long pixel=RGB(Current->gl_ctx->VB->Color[i][0]*255.0,
428 Current->gl_ctx->VB->Color[i][1]*255.0,
429 Current->gl_ctx->VB->Color[i][2]*255.0);
430 x = (GLint) Current->gl_ctx->VB->Win[i][0];
431 y = FLIP( (GLint) Current->gl_ctx->VB->Win[i][1] );
432 wmSetPixel(pwc, y,x,Current->gl_ctx->VB->Color[i][0]*255.0,
433 Current->gl_ctx->VB->Color[i][1]*255.0,
434 Current->gl_ctx->VB->Color[i][2]*255.0);
435 }
436 }
437 }
438 // DD_RELEASEDC;
439 ENDPROFILE(fast_rgb_points)
440 }
441
442
443
444 /* Return pointer to accerated points function */
445 extern points_func choose_points_function( GLcontext* ctx )
446 {
447 STARTPROFILE
448 if (ctx->Point.Size==1.0 && !ctx->Point.SmoothFlag && ctx->RasterMask==0
449 && !ctx->Texture.Enabled && ctx->Visual->RGBAflag) {
450 ENDPROFILE(choose_points_function)
451 return fast_rgb_points;
452 }
453 else {
454 ENDPROFILE(choose_points_function)
455 return NULL;
456 }
457 }
458
459
460
461 /* Draw a line using the color specified by Current->gl_ctx->VB->Color[pv] */
462 static void fast_flat_rgb_line( GLcontext* ctx, GLuint v0, GLuint v1, GLuint pv )
463 {
464 STARTPROFILE
465 int x0, y0, x1, y1;
466 unsigned long pixel;
467 HDC DC=DD_GETDC;
468 HPEN Pen;
469 HPEN Old_Pen;
470
471 if (Current->gl_ctx->VB->MonoColor) {
472 pixel = Current->pixel; /* use current color */
473 }
474 else {
475 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);
476 }
477
478 x0 = (int) Current->gl_ctx->VB->Win[v0][0];
479 y0 = FLIP( (int) Current->gl_ctx->VB->Win[v0][1] );
480 x1 = (int) Current->gl_ctx->VB->Win[v1][0];
481 y1 = FLIP( (int) Current->gl_ctx->VB->Win[v1][1] );
482
483
484 BEGINGDICALL
485
486 Pen=CreatePen(PS_SOLID,1,pixel);
487 Old_Pen=SelectObject(DC,Pen);
488 MoveToEx(DC,x0,y0,NULL);
489 LineTo(DC,x1,y1);
490 SelectObject(DC,Old_Pen);
491 DeleteObject(Pen);
492 DD_RELEASEDC;
493
494 ENDGDICALL
495
496 ENDPROFILE(fast_flat_rgb_line)
497 }
498
499
500
501 /* Return pointer to accerated line function */
502 static line_func choose_line_function( GLcontext* ctx )
503 {
504 STARTPROFILE
505 if (ctx->Line.Width==1.0 && !ctx->Line.SmoothFlag && !ctx->Line.StippleFlag
506 && ctx->Light.ShadeModel==GL_FLAT && ctx->RasterMask==0
507 && !ctx->Texture.Enabled && Current->rgb_flag) {
508 ENDPROFILE(choose_line_function)
509 return fast_flat_rgb_line;
510 }
511 else {
512 ENDPROFILE(choose_line_function)
513 return NULL;
514 }
515 }
516
517 /**********************************************************************/
518 /***** Optimized triangle rendering *****/
519 /**********************************************************************/
520
521
522 /*
523 * Smooth-shaded, z-less triangle, RGBA color.
524 */
525 static void smooth_color_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
526 GLuint v2, GLuint pv )
527 {
528 UINT nBypp = Current->cColorBits / 8;
529 GLbyte* img;
530 GLushort* img16;
531 GLuint *img24 ,*img32;
532 #define INTERP_Z 1
533 #define INTERP_RGB 1
534 #define INTERP_ALPHA 1
535 #define INNER_LOOP( LEFT, RIGHT, Y ) \
536 { \
537 GLint i, len = RIGHT-LEFT; \
538 img = PIXELADDR(LEFT,Y); \
539 for (i=0;i<len;i++,img+=nBypp) { \
540 GLdepth z = FixedToDepth(ffz); \
541 if (z < zRow[i]) { \
542 img16 = img24 = img32 = img; \
543 if(nBypp == 2) \
544 *img16 = BGR16( FixedToInt(ffr), FixedToInt(ffg), \
545 FixedToInt(ffb)); \
546 if(nBypp == 3) \
547 *img24 = BGR24( FixedToInt(ffr), FixedToInt(ffg), \
548 FixedToInt(ffb)); \
549 if(nBypp == 4) \
550 *img32 = BGR32( FixedToInt(ffr), FixedToInt(ffg), \
551 FixedToInt(ffb)); \
552 zRow[i] = z; \
553 } \
554 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; ffa += fdadx;\
555 ffz += fdzdx; \
556 } \
557 }
558
559 #include "tritemp.h"
560 }
561
562
563
564
565 /*
566 * Flat-shaded, z-less triangle, RGBA color.
567 */
568 static void flat_color_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
569 GLuint v2, GLuint pv )
570 {
571 GLbyte* img;
572 GLushort* img16;
573 GLuint *img24, *img32;
574 UINT nBypp = Current->cColorBits / 8;
575 GLubyte r, g, b ;
576 GLushort pixel16 = BGR16(r,g,b);
577 GLuint pixel24 = BGR24(r,g,b);
578 GLuint pixel32 = BGR32(r,g,b);
579
580 #define INTERP_Z 1
581 #define SETUP_CODE \
582 r = VB->Color[pv][0]; \
583 g = VB->Color[pv][1]; \
584 b = VB->Color[pv][2];
585
586 #define INNER_LOOP( LEFT, RIGHT, Y ) \
587 { \
588 GLint i, len = RIGHT-LEFT; \
589 img = PIXELADDR(LEFT,Y); \
590 for (i=0;i<len;i++,img+=nBypp) { \
591 GLdepth z = FixedToDepth(ffz); \
592 if (z < zRow[i]) { \
593 img16 = img24 = img32 = img; \
594 if(nBypp == 2) \
595 *img16 = pixel16; \
596 if(nBypp == 3) \
597 *img24 = pixel24; \
598 if(nBypp == 4) \
599 *img32 = pixel32; \
600 zRow[i] = z; \
601 } \
602 ffz += fdzdx; \
603 } \
604 }
605
606 #include "tritemp.h"
607 }
608
609
610
611 /*
612 * Return pointer to an accelerated triangle function if possible.
613 */
614 static triangle_func choose_triangle_function( GLcontext *ctx )
615 {
616 if (ctx->Polygon.SmoothFlag) return NULL;
617 if (ctx->Polygon.StippleFlag) return NULL;
618 if (ctx->Texture.Enabled) return NULL;
619
620 if (ctx->RasterMask==DEPTH_BIT
621 && ctx->Depth.Func==GL_LESS
622 && ctx->Depth.Mask==GL_TRUE
623 && ctx->Visual->RGBAflag) {
624 if (ctx->Light.ShadeModel==GL_SMOOTH) {
625 return smooth_color_z_triangle;
626 }
627 else {
628 return flat_color_z_triangle;
629 }
630 }
631 return NULL;
632 }
633
634
635 /* Draw a convex polygon using color Current->gl_ctx->VB->Color[pv] */
636 static void fast_flat_rgb_polygon( GLcontext* ctx, GLuint n, GLuint vlist[], GLuint pv )
637 {
638 STARTPROFILE
639 POINT *Pts=(POINT *) malloc(n*sizeof(POINT));
640 HDC DC=DD_GETDC;
641 HPEN Pen;
642 HBRUSH Brush;
643 HPEN Old_Pen;
644 HBRUSH Old_Brush;
645 GLint pixel;
646 GLuint i;
647
648 if (Current->gl_ctx->VB->MonoColor) {
649 pixel = Current->pixel; /* use current color */
650 }
651 else {
652 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);
653 }
654
655 Pen=CreatePen(PS_SOLID,1,pixel);
656 Brush=CreateSolidBrush(pixel);
657 Old_Pen=SelectObject(DC,Pen);
658 Old_Brush=SelectObject(DC,Brush);
659
660 for (i=0; i<n; i++) {
661 int j = vlist[i];
662 Pts[i].x = (int) Current->gl_ctx->VB->Win[j][0];
663 Pts[i].y = FLIP( (int) Current->gl_ctx->VB->Win[j][1] );
664 }
665
666 BEGINGDICALL
667
668 Polygon(DC,Pts,n);
669 SelectObject(DC,Old_Pen);
670 SelectObject(DC,Old_Brush);
671 DeleteObject(Pen);
672 DeleteObject(Brush);
673 DD_RELEASEDC;
674 free(Pts);
675
676 ENDGDICALL
677
678 ENDPROFILE(fast_flat_rgb_polygon)
679 }
680
681
682
683 /* Return pointer to accerated polygon function */
684 static polygon_func choose_polygon_function( GLcontext* ctx )
685 {
686 STARTPROFILE
687 if (!ctx->Polygon.SmoothFlag && !ctx->Polygon.StippleFlag
688 && ctx->Light.ShadeModel==GL_FLAT && ctx->RasterMask==0
689 && !ctx->Texture.Enabled && Current->rgb_flag==GL_TRUE) {
690 ENDPROFILE(choose_polygon_function)
691 return fast_flat_rgb_polygon;
692 }
693 else {
694 ENDPROFILE(choose_polygon_function)
695 return NULL;
696 }
697 }
698
699
700
701 /**********************************************************************/
702 /***** Span-based pixel drawing *****/
703 /**********************************************************************/
704
705
706 /* Write a horizontal span of color-index pixels with a boolean mask. */
707 static void write_index_span( GLcontext* ctx,
708 GLuint n, GLint x, GLint y,
709 const GLuint index[],
710 const GLubyte mask[] )
711 {
712 STARTPROFILE
713 GLuint i;
714 char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
715 assert(Current->rgb_flag==GL_FALSE);
716 for (i=0; i<n; i++)
717 if (mask[i])
718 Mem[i]=index[i];
719 ENDPROFILE(write_index_span)
720 }
721
722
723
724 /*
725 * Write a horizontal span of pixels with a boolean mask. The current
726 * color index is used for all pixels.
727 */
728 static void write_monoindex_span(GLcontext* ctx,
729 GLuint n,GLint x,GLint y,
730 const GLubyte mask[])
731 {
732 STARTPROFILE
733 GLuint i;
734 char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
735 assert(Current->rgb_flag==GL_FALSE);
736 for (i=0; i<n; i++)
737 if (mask[i])
738 Mem[i]=Current->pixel;
739 ENDPROFILE(write_monoindex_span)
740 }
741
742 /*
743 To improve the performance of this routine, frob the data into an actual scanline
744 and call bitblt on the complete scan line instead of SetPixel.
745 */
746
747 /* Write a horizontal span of color pixels with a boolean mask. */
748 static void write_color_span( GLcontext* ctx,
749 GLuint n, GLint x, GLint y,
750 const GLubyte
751 red[], const GLubyte green[],
752 const GLubyte blue[], const GLubyte alpha[],
753 const GLubyte mask[] )
754 {
755 STARTPROFILE
756
757 PWMC pwc = Current;
758
759 if (pwc->rgb_flag==GL_TRUE)
760 {
761 GLuint i;
762 HDC DC=DD_GETDC;
763 y=FLIP(y);
764
765 if (mask) {
766 for (i=0; i<n; i++)
767 if (mask[i])
768 wmSetPixel(pwc, y, x + i,red[i], green[i], blue[i]);
769 }
770
771 else {
772 for (i=0; i<n; i++)
773 wmSetPixel(pwc, y, x + i, red[i], green[i], blue[i]);
774 }
775
776 DD_RELEASEDC;
777
778 }
779
780 else
781 {
782 GLuint i;
783 char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
784 if (mask) {
785 for (i=0; i<n; i++)
786 if (mask[i])
787 Mem[i]=GetNearestPaletteIndex(Current->hPal,RGB(red[i],green[i],blue[i]));
788 }
789 else {
790 for (i=0; i<n; i++)
791 Mem[i]=GetNearestPaletteIndex(Current->hPal,RGB(red[i],green[i],blue[i]));
792 }
793 }
794 ENDPROFILE(write_color_span)
795
796 }
797
798 /*
799 * Write a horizontal span of pixels with a boolean mask. The current color
800 * is used for all pixels.
801 */
802 static void write_monocolor_span( GLcontext* ctx,
803 GLuint n, GLint x, GLint y,
804 const GLubyte mask[])
805 {
806 STARTPROFILE
807 GLuint i;
808 HDC DC=DD_GETDC;
809 PWMC pwc = Current;
810
811 assert(Current->rgb_flag==GL_TRUE);
812 y=FLIP(y);
813
814 if(Current->rgb_flag==GL_TRUE){
815 for (i=0; i<n; i++)
816 if (mask[i])
817 // Trying
818 wmSetPixel(pwc,y,x+i,GetRValue(Current->pixel), GetGValue(Current->pixel), GetBValue(Current->pixel));
819 }
820 else {
821 for (i=0; i<n; i++)
822 if (mask[i])
823 SetPixel(DC, y, x+i, Current->pixel);
824 }
825
826 DD_RELEASEDC;
827
828 ENDPROFILE(write_monocolor_span)
829 }
830
831
832
833 /**********************************************************************/
834 /***** Array-based pixel drawing *****/
835 /**********************************************************************/
836
837
838 /* Write an array of pixels with a boolean mask. */
839 static void write_index_pixels( GLcontext* ctx,
840 GLuint n, const GLint x[], const GLint y[],
841 const GLuint index[], const GLubyte mask[] )
842 {
843 STARTPROFILE
844 GLuint i;
845 assert(Current->rgb_flag==GL_FALSE);
846 for (i=0; i<n; i++) {
847 if (mask[i]) {
848 char *Mem=Current->ScreenMem+y[i]*Current->ScanWidth+x[i];
849 *Mem = index[i];
850 }
851 }
852 ENDPROFILE(write_index_pixels)
853 }
854
855
856
857 /*
858 * Write an array of pixels with a boolean mask. The current color
859 * index is used for all pixels.
860 */
861 static void write_monoindex_pixels( GLcontext* ctx,
862 GLuint n,
863 const GLint x[], const GLint y[],
864 const GLubyte mask[] )
865 {
866 STARTPROFILE
867 GLuint i;
868 assert(Current->rgb_flag==GL_FALSE);
869 for (i=0; i<n; i++) {
870 if (mask[i]) {
871 char *Mem=Current->ScreenMem+y[i]*Current->ScanWidth+x[i];
872 *Mem = Current->pixel;
873 }
874 }
875 ENDPROFILE(write_monoindex_pixels)
876 }
877
878
879
880 /* Write an array of pixels with a boolean mask. */
881 static void write_color_pixels( GLcontext* ctx,
882 GLuint n, const GLint x[], const GLint y[],
883 const GLubyte r[], const GLubyte g[],
884 const GLubyte b[], const GLubyte a[],
885 const GLubyte mask[] )
886 {
887 STARTPROFILE
888 GLuint i;
889 PWMC pwc = Current;
890 HDC DC=DD_GETDC;
891 assert(Current->rgb_flag==GL_TRUE);
892 for (i=0; i<n; i++)
893 if (mask[i])
894 wmSetPixel(pwc, FLIP(y[i]),x[i],r[i],g[i],b[i]);
895 DD_RELEASEDC;
896 ENDPROFILE(write_color_pixels)
897 }
898
899
900
901 /*
902 * Write an array of pixels with a boolean mask. The current color
903 * is used for all pixels.
904 */
905 static void write_monocolor_pixels( GLcontext* ctx,
906 GLuint n,
907 const GLint x[], const GLint y[],
908 const GLubyte mask[] )
909 {
910 STARTPROFILE
911 GLuint i;
912 PWMC pwc = Current;
913 HDC DC=DD_GETDC;
914 assert(Current->rgb_flag==GL_TRUE);
915 for (i=0; i<n; i++)
916 if (mask[i])
917 wmSetPixel(pwc, FLIP(y[i]),x[i],GetRValue(Current->pixel),
918 GetGValue(Current->pixel), GetBValue(Current->pixel));
919 DD_RELEASEDC;
920 ENDPROFILE(write_monocolor_pixels)
921 }
922
923
924
925 /**********************************************************************/
926 /***** Read spans/arrays of pixels *****/
927 /**********************************************************************/
928
929
930 /* Read a horizontal span of color-index pixels. */
931 static void read_index_span( GLcontext* ctx, GLuint n, GLint x, GLint y, GLuint index[])
932 {
933 STARTPROFILE
934 GLuint i;
935 char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
936 assert(Current->rgb_flag==GL_FALSE);
937 for (i=0; i<n; i++)
938 index[i]=Mem[i];
939 ENDPROFILE(read_index_span)
940
941 }
942
943
944
945
946 /* Read an array of color index pixels. */
947 static void read_index_pixels( GLcontext* ctx,
948 GLuint n, const GLint x[], const GLint y[],
949 GLuint indx[], const GLubyte mask[] )
950 {
951 STARTPROFILE
952 GLuint i;
953 assert(Current->rgb_flag==GL_FALSE);
954 for (i=0; i<n; i++) {
955 if (mask[i]) {
956 indx[i]=*(Current->ScreenMem+y[i]*Current->ScanWidth+x[i]);
957 }
958 }
959 ENDPROFILE(read_index_pixels)
960 }
961
962
963
964 /* Read a horizontal span of color pixels. */
965 static void read_color_span( GLcontext* ctx,
966 GLuint n, GLint x, GLint y,
967 GLubyte red[], GLubyte green[],
968 GLubyte blue[], GLubyte alpha[] )
969 {
970 STARTPROFILE
971 UINT i;
972 COLORREF Color;
973 HDC DC=DD_GETDC;
974 assert(Current->rgb_flag==GL_TRUE);
975 y=FLIP(y);
976 for (i=0; i<n; i++)
977 {
978 Color=GetPixel(DC,x+i,y);
979 red[i]=GetRValue(Color);
980 green[i]=GetGValue(Color);
981 blue[i]=GetBValue(Color);
982 alpha[i]=255;
983 }
984 DD_RELEASEDC;
985 memset(alpha,0,n*sizeof(GLint));
986 ENDPROFILE(read_color_span)
987 }
988
989
990 /* Read an array of color pixels. */
991 static void read_color_pixels( GLcontext* ctx,
992 GLuint n, const GLint x[], const GLint y[],
993 GLubyte red[], GLubyte green[],
994 GLubyte blue[], GLubyte alpha[],
995 const GLubyte mask[] )
996 {
997 STARTPROFILE
998 GLuint i;
999 COLORREF Color;
1000 HDC DC=DD_GETDC;
1001 assert(Current->rgb_flag==GL_TRUE);
1002 for (i=0; i<n; i++) {
1003 if (mask[i]) {
1004 Color=GetPixel(DC,x[i],FLIP(y[i]));
1005 red[i]=GetRValue(Color);
1006 green[i]=GetGValue(Color);
1007 blue[i]=GetBValue(Color);
1008 alpha[i]=255;
1009 }
1010 }
1011 DD_RELEASEDC;
1012 memset(alpha,0,n*sizeof(GLint));
1013 ENDPROFILE(read_color_pixels)
1014 }
1015
1016
1017
1018 /**********************************************************************/
1019 /**********************************************************************/
1020
1021
1022
1023 void setup_DD_pointers( GLcontext* ctx )
1024 {
1025 ctx->Driver.Finish = finish;
1026 ctx->Driver.Flush = flush;
1027
1028 ctx->Driver.ClearIndex = clear_index;
1029 ctx->Driver.ClearColor = clear_color;
1030 ctx->Driver.Clear = clear;
1031
1032 ctx->Driver.Index = set_index;
1033 ctx->Driver.Color = set_color;
1034 ctx->Driver.IndexMask = index_mask;
1035 ctx->Driver.ColorMask = color_mask;
1036
1037 ctx->Driver.Dither = dither;
1038
1039 ctx->Driver.SetBuffer = set_buffer;
1040 ctx->Driver.GetBufferSize = buffer_size;
1041
1042 ctx->Driver.PointsFunc = choose_points_function(ctx);
1043 ctx->Driver.LineFunc = choose_line_function(ctx);
1044 ctx->Driver.TriangleFunc = choose_triangle_function( ctx );
1045 // ctx->Driver.TriangleFunc = choose_polygon_function(ctx);
1046
1047 /* Pixel/span writing functions: */
1048 ctx->Driver.WriteColorSpan = write_color_span;
1049 ctx->Driver.WriteMonocolorSpan = write_monocolor_span;
1050 ctx->Driver.WriteColorPixels = write_color_pixels;
1051 ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels;
1052 ctx->Driver.WriteIndexSpan = write_index_span;
1053 ctx->Driver.WriteMonoindexSpan = write_monoindex_span;
1054 ctx->Driver.WriteIndexPixels = write_index_pixels;
1055 ctx->Driver.WriteMonoindexPixels = write_monoindex_pixels;
1056
1057 /* Pixel/span reading functions: */
1058 ctx->Driver.ReadIndexSpan = read_index_span;
1059 ctx->Driver.ReadColorSpan = read_color_span;
1060 ctx->Driver.ReadIndexPixels = read_index_pixels;
1061 ctx->Driver.ReadColorPixels = read_color_pixels;
1062 }
1063
1064 //
1065 // MesaGL32 is the DLL version of MesaGL for Win32
1066 //
1067
1068 /**********************************************************************/
1069 /***** WMesa API Functions *****/
1070 /**********************************************************************/
1071
1072
1073
1074 #define PAL_SIZE 256
1075 static void GetPalette(HPALETTE Pal,RGBQUAD *aRGB)
1076 {
1077 STARTPROFILE
1078 int i;
1079 HDC hdc;
1080 struct
1081 {
1082 WORD Version;
1083 WORD NumberOfEntries;
1084 PALETTEENTRY aEntries[PAL_SIZE];
1085 } Palette =
1086 {
1087 0x300,
1088 PAL_SIZE
1089 };
1090 hdc=GetDC(NULL);
1091 if (Pal!=NULL)
1092 GetPaletteEntries(Pal,0,PAL_SIZE,Palette.aEntries);
1093 else
1094 GetSystemPaletteEntries(hdc,0,PAL_SIZE,Palette.aEntries);
1095 if (GetSystemPaletteUse(hdc) == SYSPAL_NOSTATIC)
1096 {
1097 for(i = 0; i <PAL_SIZE; i++)
1098 Palette.aEntries[i].peFlags = PC_RESERVED;
1099 Palette.aEntries[255].peRed = 255;
1100 Palette.aEntries[255].peGreen = 255;
1101 Palette.aEntries[255].peBlue = 255;
1102 Palette.aEntries[255].peFlags = 0;
1103 Palette.aEntries[0].peRed = 0;
1104 Palette.aEntries[0].peGreen = 0;
1105 Palette.aEntries[0].peBlue = 0;
1106 Palette.aEntries[0].peFlags = 0;
1107 }
1108 else
1109 {
1110 int nStaticColors;
1111 int nUsableColors;
1112 nStaticColors = GetDeviceCaps(hdc, NUMCOLORS)/2;
1113 for (i=0; i<nStaticColors; i++)
1114 Palette.aEntries[i].peFlags = 0;
1115 nUsableColors = PAL_SIZE-nStaticColors;
1116 for (; i<nUsableColors; i++)
1117 Palette.aEntries[i].peFlags = PC_RESERVED;
1118 for (; i<PAL_SIZE-nStaticColors; i++)
1119 Palette.aEntries[i].peFlags = PC_RESERVED;
1120 for (i=PAL_SIZE-nStaticColors; i<PAL_SIZE; i++)
1121 Palette.aEntries[i].peFlags = 0;
1122 }
1123 ReleaseDC(NULL,hdc);
1124 for (i=0; i<PAL_SIZE; i++)
1125 {
1126 aRGB[i].rgbRed=Palette.aEntries[i].peRed;
1127 aRGB[i].rgbGreen=Palette.aEntries[i].peGreen;
1128 aRGB[i].rgbBlue=Palette.aEntries[i].peBlue;
1129 aRGB[i].rgbReserved=Palette.aEntries[i].peFlags;
1130 }
1131 ENDPROFILE(GetPalette)
1132 }
1133
1134
1135 WMesaContext /*APIENTRY*/ WMesaCreateContext( HWND hWnd, HPALETTE Pal,
1136 /*HDC hDC,*/ GLboolean rgb_flag,
1137 GLboolean db_flag )
1138 {
1139 BITMAPINFO *Rec;
1140 //HDC DC;
1141 RECT CR;
1142 WMesaContext c;
1143
1144 c = (struct wmesa_context * ) calloc(1,sizeof(struct wmesa_context));
1145 if (!c)
1146 return NULL;
1147
1148 c->Window=hWnd;
1149 c->hDC = GetDC(hWnd);
1150
1151 if (rgb_flag==GL_FALSE)
1152 {
1153 c->rgb_flag = GL_FALSE;
1154 c->pixel = 1;
1155 db_flag=GL_TRUE; // WinG requires double buffering
1156 //c->gl_ctx->BufferDepth = windepth;
1157 }
1158 else
1159 {
1160 c->rgb_flag = GL_TRUE;
1161 c->pixel = 0;
1162 }
1163 GetClientRect(c->Window,&CR);
1164 c->width=CR.right;
1165 c->height=CR.bottom;
1166 if (db_flag)
1167 {
1168 c->db_flag = 1;
1169 // c->hDC GetDC(c->Window);
1170 /* Double buffered */
1171 if (c->rgb_flag==GL_TRUE)
1172 {
1173 //DC = c->hDC = hDC;
1174
1175 // DC = c->hDC = GetDC(c->Window);
1176 wmCreateBackingStore(c, c->width, c->height);
1177 // ReleaseDC(c->Window,DC);
1178 }
1179 else
1180 {
1181 c->dib.hDC=WinGCreateDC();
1182 Rec=(BITMAPINFO *) malloc(sizeof(BITMAPINFO)+(PAL_SIZE-1)*sizeof(RGBQUAD));
1183 c->hPal=Pal;
1184 GetPalette(Pal,Rec->bmiColors);
1185 WinGRecommendDIBFormat(Rec);
1186 Rec->bmiHeader.biWidth=c->width;
1187 Rec->bmiHeader.biHeight*=c->height;
1188 Rec->bmiHeader.biClrUsed=PAL_SIZE;
1189 if (Rec->bmiHeader.biPlanes!=1 || Rec->bmiHeader.biBitCount!=8)
1190 {
1191 MessageBox(NULL,"Error.","This code presumes a 256 color, single plane, WinG Device.\n",MB_OK);
1192 exit(1);
1193 }
1194 c->Compat_BM=WinGCreateBitmap(c->dib.hDC,Rec,&((void *) c->ScreenMem));
1195 c->Old_Compat_BM=SelectObject(c->dib.hDC,c->Compat_BM);
1196 WinGSetDIBColorTable(c->dib.hDC,0,PAL_SIZE,Rec->bmiColors);
1197 c->IndexFormat=Rec;
1198 c->ScanWidth=c->width;
1199 c->cColorBits = 8;
1200 if ((c->ScanWidth%sizeof(long))!=0)
1201 c->ScanWidth+=(sizeof(long)-(c->ScanWidth%sizeof(long)));
1202 }
1203 }
1204 else
1205 {
1206 /* Single Buffered */
1207 c->db_flag = 0;
1208
1209 // wmCreateBackingStore(c, c->width, c->height);
1210 }
1211
1212
1213
1214 c->gl_visual = gl_create_visual(rgb_flag,
1215 GL_FALSE, /* software alpha */
1216 db_flag, /* db_flag */
1217 16, /* depth_bits */
1218 8, /* stencil_bits */
1219 8, /* accum_bits */
1220 8,
1221 255.0, 255.0, 255.0, 255.0 );
1222
1223 if (!c->gl_visual) {
1224 return NULL;
1225 }
1226
1227 /* allocate a new Mesa context */
1228 c->gl_ctx = gl_create_context( c->gl_visual, NULL,c);
1229
1230 if (!c->gl_ctx) {
1231 gl_destroy_visual( c->gl_visual );
1232 free(c);
1233 return NULL;
1234 }
1235
1236 c->gl_buffer = gl_create_framebuffer( c->gl_visual );
1237 if (!c->gl_buffer) {
1238 gl_destroy_visual( c->gl_visual );
1239 gl_destroy_context( c->gl_ctx );
1240 free(c);
1241 return NULL;
1242 }
1243 // setup_DD_pointers(c->gl_ctx);
1244
1245 return c;
1246 }
1247
1248
1249
1250 void /*APIENTRY*/ WMesaDestroyContext( void )
1251 {
1252 WMesaContext c = Current;
1253 ReleaseDC(c->Window,c->hDC);
1254 WC = c;
1255
1256 gl_destroy_visual( c->gl_visual );
1257 gl_destroy_framebuffer( c->gl_buffer );
1258 gl_destroy_context( c->gl_ctx );
1259
1260 if (c->db_flag){
1261 wmDeleteBackingStore(c);
1262
1263 //Code added by Li Wei to enable parallel render
1264 #if !defined(NO_STEREO)
1265 if(stereoBuffer==GL_TRUE){
1266 WMesaDestroyStereoBuffer();
1267 stereoBuffer=GL_FALSE;
1268 }
1269 #endif
1270 // End modification
1271 }
1272 free( (void *) c );
1273 //Code added by Li Wei to enable parallel render
1274 // Parallel render only work in double buffer mode
1275 #if !defined(NO_PARALLEL)
1276 if(parallelMachine)
1277 PRDestroyRenderBuffer();
1278 #endif
1279 // End modification
1280 }
1281
1282
1283
1284 void /*APIENTRY*/ WMesaMakeCurrent( WMesaContext c )
1285 {
1286 if(!c){
1287 Current = c;
1288 return;
1289 }
1290
1291 //
1292 // A little optimization
1293 // If it already is current,
1294 // don't set it again
1295 //
1296 if(Current == c)
1297 return;
1298
1299 //gl_set_context( c->gl_ctx );
1300 gl_make_current(c->gl_ctx, c->gl_buffer);
1301 Current = c;
1302 setup_DD_pointers(c->gl_ctx);
1303 if (Current->gl_ctx->Viewport.Width==0) {
1304 /* initialize viewport to window size */
1305 gl_Viewport( Current->gl_ctx,
1306 0, 0, Current->width, Current->height );
1307 }
1308 }
1309
1310
1311
1312 void /*APIENTRY*/ WMesaSwapBuffers( void )
1313 {
1314 HDC DC = Current->hDC;
1315 if (Current->db_flag)
1316 {
1317 if (Current->rgb_flag)
1318 wmFlush(Current);
1319 else
1320 WinGBitBlt(DC,0,0,Current->width,Current->height,Current->dib.hDC,0,0);
1321 }
1322 }
1323
1324
1325
1326 void /*APIENTRY*/ WMesaPaletteChange(HPALETTE Pal)
1327 {
1328 if (Current && Current->rgb_flag==GL_FALSE)
1329 {
1330 Current->hPal=Pal;
1331 GetPalette(Pal,Current->IndexFormat->bmiColors);
1332 WinGSetDIBColorTable(Current->dib.hDC,0,PAL_SIZE,Current->IndexFormat->bmiColors);
1333 }
1334 }
1335
1336 //
1337 // Free up the dib section that was created
1338 //
1339 BOOL wmDeleteBackingStore(PWMC pwc)
1340 {
1341 SelectObject(pwc->dib.hDC, pwc->hOldBitmap);
1342 DeleteDC(pwc->dib.hDC);
1343 DeleteObject(pwc->hbmDIB);
1344 UnmapViewOfFile(pwc->dib.base);
1345 CloseHandle(pwc->dib.hFileMap);
1346 return TRUE;
1347 }
1348
1349
1350 //
1351 // This function creates the DIB section that is used for combined
1352 // GL and GDI calls
1353 //
1354 BOOL /*WINAPI*/ wmCreateBackingStore(PWMC pwc, long lxSize, long lySize)
1355 {
1356 HDC hdc = pwc->hDC;
1357 LPBITMAPINFO pbmi = &(pwc->bmi);
1358 int iUsage;
1359
1360 pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1361 pbmi->bmiHeader.biWidth = lxSize;
1362 pbmi->bmiHeader.biHeight= -lySize;
1363 pbmi->bmiHeader.biPlanes = 1;
1364 pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwc->hDC, BITSPIXEL);
1365 pbmi->bmiHeader.biCompression = BI_RGB;
1366 pbmi->bmiHeader.biSizeImage = 0;
1367 pbmi->bmiHeader.biXPelsPerMeter = 0;
1368 pbmi->bmiHeader.biYPelsPerMeter = 0;
1369 pbmi->bmiHeader.biClrUsed = 0;
1370 pbmi->bmiHeader.biClrImportant = 0;
1371
1372 iUsage = (pbmi->bmiHeader.biBitCount <= 8) ? DIB_PAL_COLORS : DIB_RGB_COLORS;
1373
1374 pwc->cColorBits = pbmi->bmiHeader.biBitCount;
1375 pwc->ScanWidth = lxSize;
1376
1377 wmCreateDIBSection(hdc, pwc, pbmi, iUsage);
1378
1379 if ((iUsage == DIB_PAL_COLORS) && !(pwc->hGLPalette)) {
1380 wmCreatePalette( pwc );
1381 wmSetDibColors( pwc );
1382 }
1383
1384 return(TRUE);
1385
1386 }
1387
1388
1389 //
1390 // This function copies one scan line in a DIB section to another
1391 //
1392 BOOL GLWINAPI wmSetDIBits(PWMC pwc, UINT uiScanWidth, UINT uiNumScans, UINT nBypp, UINT uiNewWidth, LPBYTE pBits)
1393 {
1394 UINT uiScans = 0;
1395 LPBYTE pDest = pwc->pbPixels;
1396 DWORD dwNextScan = uiScanWidth;
1397 DWORD dwNewScan = uiNewWidth;
1398 DWORD dwScanWidth = (uiScanWidth * nBypp);
1399
1400 //
1401 // We need to round up to the nearest DWORD
1402 // and multiply by the number of bytes per
1403 // pixel
1404 //
1405 dwNextScan = (((dwNextScan * nBypp)+ 3) & ~3);
1406 dwNewScan = (((dwNewScan * nBypp)+ 3) & ~3);
1407
1408 for(uiScans = 0; uiScans < uiNumScans; uiScans++){
1409 CopyMemory(pDest, pBits, dwScanWidth);
1410 pBits += dwNextScan;
1411 pDest += dwNewScan;
1412 }
1413
1414 return(TRUE);
1415
1416 }
1417
1418 BOOL GLWINAPI wmSetPixelFormat( PWMC pwdc, HDC hDC, DWORD dwFlags )
1419 {
1420 return(TRUE);
1421 }
1422
1423 static unsigned char threeto8[8] = {
1424 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
1425 };
1426
1427 static unsigned char twoto8[4] = {
1428 0, 0x55, 0xaa, 0xff
1429 };
1430
1431 static unsigned char oneto8[2] = {
1432 0, 255
1433 };
1434
1435 static unsigned char componentFromIndex(UCHAR i, UINT nbits, UINT shift)
1436 {
1437 unsigned char val;
1438
1439 val = i >> shift;
1440 switch (nbits) {
1441
1442 case 1:
1443 val &= 0x1;
1444 return oneto8[val];
1445
1446 case 2:
1447 val &= 0x3;
1448 return twoto8[val];
1449
1450 case 3:
1451 val &= 0x7;
1452 return threeto8[val];
1453
1454 default:
1455 return 0;
1456 }
1457 }
1458
1459 void /*WINAPI*/ wmCreatePalette( PWMC pwdc )
1460 {
1461 /* Create a compressed and re-expanded 3:3:2 palette */
1462 int i;
1463 LOGPALETTE *pPal;
1464 BYTE rb, rs, gb, gs, bb, bs;
1465
1466 pwdc->nColors = 0x100;
1467
1468 pPal = (PLOGPALETTE)malloc(sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY));
1469 memset( pPal, 0, sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY) );
1470
1471 pPal->palVersion = 0x300;
1472
1473 rb = REDBITS;
1474 rs = REDSHIFT;
1475 gb = GREENBITS;
1476 gs = GREENSHIFT;
1477 bb = BLUEBITS;
1478 bs = BLUESHIFT;
1479
1480 if (pwdc->db_flag) {
1481
1482 /* Need to make two palettes: one for the screen DC and one for the DIB. */
1483 pPal->palNumEntries = pwdc->nColors;
1484 for (i = 0; i < pwdc->nColors; i++) {
1485 pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
1486 pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
1487 pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
1488 pPal->palPalEntry[i].peFlags = 0;
1489 }
1490 pwdc->hGLPalette = CreatePalette( pPal );
1491 pwdc->hPalette = CreatePalette( pPal );
1492 }
1493
1494 else {
1495 pPal->palNumEntries = pwdc->nColors;
1496 for (i = 0; i < pwdc->nColors; i++) {
1497 pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
1498 pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
1499 pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
1500 pPal->palPalEntry[i].peFlags = 0;
1501 }
1502 pwdc->hGLPalette = CreatePalette( pPal );
1503 }
1504
1505 free(pPal);
1506
1507 }
1508
1509 //
1510 // This function sets the color table of a DIB section
1511 // to match that of the destination DC
1512 //
1513 BOOL /*WINAPI*/ wmSetDibColors(PWMC pwc)
1514 {
1515 RGBQUAD *pColTab, *pRGB;
1516 PALETTEENTRY *pPal, *pPE;
1517 int i, nColors;
1518 BOOL bRet=TRUE;
1519 DWORD dwErr=0;
1520
1521 /* Build a color table in the DIB that maps to the
1522 selected palette in the DC.
1523 */
1524 nColors = 1 << pwc->cColorBits;
1525 pPal = (PALETTEENTRY *)malloc( nColors * sizeof(PALETTEENTRY));
1526 memset( pPal, 0, nColors * sizeof(PALETTEENTRY) );
1527 GetPaletteEntries( pwc->hGLPalette, 0, nColors, pPal );
1528 pColTab = (RGBQUAD *)malloc( nColors * sizeof(RGBQUAD));
1529 for (i = 0, pRGB = pColTab, pPE = pPal; i < nColors; i++, pRGB++, pPE++) {
1530 pRGB->rgbRed = pPE->peRed;
1531 pRGB->rgbGreen = pPE->peGreen;
1532 pRGB->rgbBlue = pPE->peBlue;
1533 }
1534 if(pwc->db_flag)
1535 bRet = SetDIBColorTable(pwc->hDC, 0, nColors, pColTab );
1536
1537 if(!bRet)
1538 dwErr = GetLastError();
1539
1540 free( pColTab );
1541 free( pPal );
1542
1543 return(bRet);
1544 }
1545
1546 void /*WINAPI*/ wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1547 {
1548 if(Current->db_flag){
1549 LPBYTE lpb = pwc->pbPixels;
1550 LPDWORD lpdw;
1551 LPWORD lpw;
1552 UINT nBypp = pwc->cColorBits / 8;
1553 UINT nOffset = iPixel % nBypp;
1554
1555 // Move the pixel buffer pointer to the scanline that we
1556 // want to access
1557
1558 pwc->dib.fFlushed = FALSE;
1559
1560 lpb += pwc->ScanWidth * iScanLine;
1561 // Now move to the desired pixel
1562 lpb += iPixel * nBypp;
1563
1564 lpdw = (LPDWORD)lpb;
1565 lpw = (LPWORD)lpb;
1566
1567 if(nBypp == 2)
1568 *lpw = BGR16(r,g,b);
1569 else if (nBypp == 3){
1570 *lpdw = BGR24(r,g,b);
1571 }
1572 else
1573 *lpdw = BGR32(r,g,b);
1574 }
1575 else{
1576 HDC DC = DD_GETDC;
1577 SetPixel(DC, iPixel, iScanLine, RGB(r,g,b));
1578 DD_RELEASEDC;
1579 }
1580 }
1581
1582 void /*WINAPI*/ wmCreateDIBSection(
1583 HDC hDC,
1584 PWMC pwc, // handle of device context
1585 CONST BITMAPINFO *pbmi, // address of structure containing bitmap size, format, and color data
1586 UINT iUsage // color data type indicator: RGB values or palette indices
1587 )
1588 {
1589 DWORD dwSize = 0;
1590 DWORD dwScanWidth;
1591 UINT nBypp = pwc->cColorBits / 8;
1592 HDC hic;
1593
1594 dwScanWidth = (((pwc->ScanWidth * nBypp)+ 3) & ~3);
1595
1596 pwc->ScanWidth = dwScanWidth;
1597
1598 dwSize = sizeof(BITMAPINFO) + (dwScanWidth * pwc->height);
1599
1600 pwc->dib.hFileMap = CreateFileMapping((HANDLE)PAGE_FILE,
1601 NULL,
1602 PAGE_READWRITE | SEC_COMMIT,
1603 0,
1604 dwSize,
1605 NULL);
1606
1607 if (!pwc->dib.hFileMap)
1608 return;
1609
1610 pwc->dib.base = MapViewOfFile(pwc->dib.hFileMap,
1611 FILE_MAP_ALL_ACCESS,
1612 0,
1613 0,
1614 0);
1615
1616 if(!pwc->dib.base){
1617 CloseHandle(pwc->dib.hFileMap);
1618 return;
1619 }
1620
1621 pwc->pbPixels = ((LPBYTE)pwc->dib.base) + sizeof(BITMAPINFO);
1622
1623 pwc->dib.hDC = CreateCompatibleDC(hDC);
1624
1625 CopyMemory(pwc->dib.base, pbmi, sizeof(BITMAPINFO));
1626
1627 hic = CreateIC("display", NULL, NULL, NULL);
1628
1629 /* pwc->hbmDIB = CreateDIBitmap(hic,
1630 &(pwc->bmi.bmiHeader),
1631 CBM_INIT,
1632 pwc->pbPixels,
1633 &(pwc->bmi),
1634 DIB_RGB_COLORS);
1635 */
1636 pwc->hbmDIB = CreateDIBSection(hic,
1637 &(pwc->bmi.bmiHeader),
1638 DIB_RGB_COLORS,
1639 &(pwc->pbPixels),
1640 pwc->dib.hFileMap,
1641 0);
1642 pwc->hOldBitmap = SelectObject(pwc->dib.hDC, pwc->hbmDIB);
1643
1644 DeleteDC(hic);
1645
1646 return;
1647
1648 }
1649
1650 //
1651 // Blit memory DC to screen DC
1652 //
1653 BOOL /*WINAPI*/ wmFlush(PWMC pwc)
1654 {
1655 BOOL bRet = 0;
1656 DWORD dwErr = 0;
1657
1658
1659 // wmFlushBits(pwc);
1660
1661 bRet = BitBlt(pwc->hDC, 0, 0, pwc->width, pwc->height,
1662 pwc->dib.hDC, 0, 0, SRCCOPY);
1663
1664 if(!bRet)
1665 dwErr = GetLastError();
1666
1667 pwc->dib.fFlushed = TRUE;
1668
1669 return(TRUE);
1670
1671 }
1672
1673
1674 // The following code is added by Li Wei to enable stereo display
1675
1676 #if !defined(NO_STEREO)
1677
1678 void WMesaCreateStereoBuffer()
1679 {
1680 /* Must use double buffer and not in parallelMode */
1681 if (! Current->db_flag
1682 #if !defined(NO_PARALLEL)
1683 || parallelFlag
1684 #endif
1685 )
1686 return;
1687
1688 Buffer_Stereo = malloc( Current->ScanWidth * Current->height);
1689 ZeroMemory(Buffer_Stereo,Current->ScanWidth * Current->height);
1690 stereoBuffer = GL_TRUE ;
1691 }
1692
1693 void WMesaDestroyStereoBuffer()
1694 {
1695 /* Must use double buffer and not in parallelMode */
1696 if (! Current->db_flag
1697 #if !defined(NO_PARALLEL)
1698 || parallelFlag
1699 #endif
1700 )
1701 return;
1702 if(stereoBuffer){
1703 free(Buffer_Stereo);
1704 stereoBuffer = GL_FALSE ;
1705 }
1706 }
1707
1708 void WMesaInterleave(GLenum aView)
1709 {
1710 int offset;
1711 unsigned line;
1712 LPBYTE dest;
1713 LPBYTE src;
1714 if(aView == FIRST)
1715 offset = 0;
1716 else offset = 1;
1717
1718 dest = Buffer_Stereo + offset * Current->ScanWidth;
1719 if(Current->rgb_flag )
1720 src = Current->pbPixels + Current->ScanWidth*(Current->height/2);
1721 else
1722 src = Current->ScreenMem;
1723
1724 for(line = 0; line<Current->height/2; line ++){
1725 CopyMemory(dest, src, Current->ScanWidth);
1726 dest += 2*Current->ScanWidth;
1727 src += Current->ScanWidth;
1728 }
1729 if(aView == SECOND)
1730 if(Current->rgb_flag)
1731 CopyMemory(Current->pbPixels, Buffer_Stereo, Current->ScanWidth*Current->height);
1732 else
1733 CopyMemory(Current->ScreenMem, Buffer_Stereo, Current->ScanWidth*Current->height);
1734 }
1735
1736 void WMesaShowStereo(GLuint list)
1737 {
1738
1739 GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
1740 GLfloat cm[16];
1741 // Must use double Buffer
1742 if( ! Current-> db_flag )
1743 return;
1744
1745 glViewport(0,0,Current->width,Current->height/2);
1746
1747 glGetFloatv(GL_MODELVIEW_MATRIX,cm);
1748 glMatrixMode(GL_MODELVIEW);
1749 glLoadIdentity();
1750 gluLookAt(viewDistance/2,0.0,0.0 ,
1751 viewDistance/2,0.0,-1.0,
1752 0.0,1.0,0.0 );
1753 glMultMatrixf( cm );
1754 glMatrixMode(GL_MODELVIEW);
1755 glPushMatrix();
1756 glCallList( list );
1757 glPopMatrix();
1758 glFlush();
1759 WMesaInterleave( FIRST );
1760
1761 glGetFloatv(GL_MODELVIEW_MATRIX,cm);
1762 glMatrixMode(GL_MODELVIEW);
1763 glLoadIdentity();
1764 gluLookAt(-viewDistance/2,0.0,0.0 ,
1765 -viewDistance/2,0.0,-1.0,
1766 0.0,1.0,0.0 );
1767 glMultMatrixf(cm);
1768 glMatrixMode(GL_MODELVIEW);
1769 glCallList(list);
1770 glFlush();
1771 WMesaInterleave( SECOND );
1772 glViewport(0,0,Current->width,Current->height);
1773 WMesaSwapBuffers();
1774
1775 }
1776
1777 void toggleStereoMode()
1778 {
1779 if(!Current->db_flag)
1780 return;
1781 if(!stereo_flag){
1782 stereo_flag = 1;
1783 if(stereoBuffer==GL_FALSE)
1784 #if !defined(NO_PARALLEL)
1785 if(!parallelFlag)
1786 #endif
1787 {
1788 WMesaCreateStereoBuffer();
1789 }
1790 }
1791 else {
1792 stereo_flag = 0;
1793 if(stereoBuffer==GL_TRUE)
1794 #if !defined(NO_PARALLEL)
1795 if(!parallelFlag)
1796 #endif
1797 if(stereoBuffer==GL_TRUE){
1798 WMesaDestroyStereoBuffer();
1799 }
1800 }
1801 }
1802
1803 /* if in stereo mode, the following function is called */
1804 void glShowStereo(GLuint list)
1805 {
1806 WMesaShowStereo(list);
1807 }
1808
1809 #endif // End if NO_STEREO not defined
1810
1811 #if !defined(NO_PARALLEL)
1812
1813 void toggleParallelMode(void)
1814 {
1815 if(!parallelFlag){
1816 parallelFlag = GL_TRUE;
1817 if(parallelMachine==GL_FALSE){
1818 PRCreateRenderBuffer( Current->rgb_flag? GL_RGBA :GL_COLOR_INDEX,
1819 Current->cColorBits/8,
1820 Current->width ,Current->height,
1821 Current->ScanWidth,
1822 Current->rgb_flag? Current->pbPixels: Current->ScreenMem);
1823 parallelMachine = GL_TRUE;
1824 }
1825 }
1826 else {
1827 parallelFlag = GL_FALSE;
1828 if(parallelMachine==GL_TRUE){
1829 PRDestroyRenderBuffer();
1830 parallelMachine=GL_FALSE;
1831 ReadyForNextFrame = GL_TRUE;
1832 }
1833
1834 /***********************************************
1835 // Seems something wrong!!!!
1836 ************************************************/
1837
1838 WMesaMakeCurrent(Current);
1839 #if !defined(NO_STEREO)
1840 stereo_flag = GL_FALSE ;
1841 #endif
1842 }
1843 }
1844
1845 void PRShowRenderResult(void)
1846 {
1847 int flag = 0;
1848 if(!glImageRendered())
1849 return;
1850
1851 if (parallelFlag)
1852 {
1853 WMesaSwapBuffers();
1854 }
1855
1856 }
1857 #endif //End if NO_PARALLEL not defined
1858
1859 //end modification