source: trunk/src/opengl/mesa/wmesa.c@ 2962

Last change on this file since 2962 was 2962, checked in by jeroen, 25 years ago

* empty log message *

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