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