home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 5 / MA_Cover_5.iso / ppc / mesa / src / wmesa.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-31  |  83.1 KB  |  2,736 lines

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