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