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

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

* empty log message *

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