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

  1. /****************************************************************************
  2. *
  3. *                      Mesa bindings for SciTech MGL
  4. *
  5. *                   Copyright (C) 1996 SciTech Software.
  6. *                           All rights reserved.
  7. *
  8. * Filename:     $Workfile:   mglmesa.c  $
  9. * Version:      $Revision:   1.5  $
  10. *
  11. * Language:     ANSI C
  12. * Environment:  Any
  13. *
  14. * Description:  Main Mesa 3D library interface between the MGL and
  15. *               Mesa. For maximum peformance we call the MGL's internal
  16. *               rendering functions directly so we can bypass all the
  17. *               clipping and regular MGL API stuff as all that is already
  18. *               handled by Mesa before the calls get here.
  19. *
  20. *               Note also that all rendering is inherently single threaded
  21. *               so we optimize for this case by using a global current
  22. *               context structure.
  23. *
  24. *               This module contains generic interface routines.
  25. *
  26. * This library is free software; you can redistribute it and/or
  27. * modify it under the terms of the GNU Library General Public
  28. * License as published by the Free Software Foundation; either
  29. * version 2 of the License, or (at your option) any later version.
  30. *
  31. * This library is distributed in the hope that it will be useful,
  32. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  33. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  34. * Library General Public License for more details.
  35. *
  36. * You should have received a copy of the GNU Library General Public
  37. * License along with this library; if not, write to the Free
  38. * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  39. *
  40. * $Date:   23 Jun 1997 18:10:16  $ $Author:   KevinO  $
  41. *
  42. ****************************************************************************/
  43.  
  44. #include "mmesap.h"
  45. #pragma hdrstop
  46. #include "gl\mglmesa.h"
  47.  
  48. /*--------------------------- Global Variables ----------------------------*/
  49.  
  50. #ifdef  __WINDOWS__
  51. MGLCallbacks    _MGL_callbacks;         /* MGL callback functions       */
  52. #endif
  53. gmode_t         _MGL_mi;                /* MGL mode information         */
  54. pixel_format_t  _MGL_pf;                /* MGL mode pixel format        */
  55. vecs            _MGL_vecs;              /* MGL Rendering vectors        */
  56. MGLRC           _MM_rc;                 /* Current rendering context    */
  57. MGLRC           *_MM_rcPtr = NULL;      /* Pointer to current context   */
  58.  
  59. /*------------------------- Implementation --------------------------------*/
  60.  
  61. #pragma warn -par
  62.  
  63. /**********************************************************************/
  64. /*****              Miscellaneous device driver funcs             *****/
  65. /**********************************************************************/
  66.  
  67. PRIVATE void begin(GLcontext *ctx,GLenum mode)
  68. /****************************************************************************
  69. *
  70. * Function:     begin
  71. *
  72. * Description:  Called when glBegin is called. We use this oportunity to
  73. *               enable direct framebuffer access for our rendering functions.
  74. *
  75. ****************************************************************************/
  76. {
  77. //  TODO: Call begin directAccess depending on the currently selected mode
  78. //        and also the current rendering attributes (to determine if we need
  79. //        to directly access the buffer. We need this to support VBE/AF.
  80. //
  81. //        We should optimize this to have this code in here run fast, and
  82. //        put the complicated code into the setup_DD_funcs to avoid the
  83. //        overheads of checking in here.
  84.  
  85.     _MGL_vecs.beginDirectAccess();
  86. }
  87.  
  88. PRIVATE void end(GLcontext *ctx)
  89. /****************************************************************************
  90. *
  91. * Function:     end
  92. *
  93. * Description:  Called when glEnd is called. We use this oportunity to
  94. *               disable direct framebuffer access for our rendering
  95. *               functions.
  96. *
  97. ****************************************************************************/
  98. {
  99.     _MGL_vecs.endDirectAccess();
  100. }
  101.  
  102. PRIVATE void finish(GLcontext *ctx)
  103. /****************************************************************************
  104. *
  105. * Function:     finish
  106. *
  107. * Description:  Called when glFinish is called. We simply do nothing here.
  108. *
  109. ****************************************************************************/
  110. {
  111. }
  112.  
  113. PRIVATE void flush(GLcontext *ctx)
  114. /****************************************************************************
  115. *
  116. * Function:     flush
  117. *
  118. * Description:  Called when glFlush is called. We simply do nothing here
  119. *
  120. ****************************************************************************/
  121. {
  122. }
  123.  
  124. PRIVATE void clear_index(GLcontext *ctx, GLuint index)
  125. /****************************************************************************
  126. *
  127. * Function:     clear_index
  128. * Parameters:   index   - New color index for buffer clears
  129. *
  130. * Description:  Sets the current buffer clear color for color index buffers.
  131. *
  132. ****************************************************************************/
  133. {
  134.     RC.clearColor = index;
  135. }
  136.  
  137. PRIVATE void clear_color(GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a)
  138. /****************************************************************************
  139. *
  140. * Function:     clear_color
  141. * Parameters:   r,g,b,a - New RGBA color values for buffer clears
  142. *
  143. * Description:  Set the current buffer clear color for TrueColor buffers.
  144. *               Note that Mesa passes us color values pre-scaled to the
  145. *               proper number of color bits:
  146. *
  147. *                   [0,ctx->Visual->RedScale]
  148. *                   [0,ctx->Visual->GreenScale]
  149. *                   [0,ctx->Visual->BlueScale]
  150. *                   [0,ctx->Visual->AlphaScale]
  151. *
  152. ****************************************************************************/
  153. {
  154.     RC.clearColor = PACK_COLOR(r,g,b);
  155. }
  156.  
  157. PRIVATE void clear(GLcontext *ctx,GLboolean all, GLint x, GLint y, GLint width, GLint height)
  158. /****************************************************************************
  159. *
  160. * Function:     clear
  161. * Parameters:   all                 - True to clear entire buffer
  162. *               x,y,width,height    - Rectangle to clear
  163. *
  164. * Description:  Clears the buffer in the current clear color
  165. *
  166. ****************************************************************************/
  167. {
  168.     VECS.setColor(RC.clearColor);
  169.     if (all)
  170.         VECS.solid.fillRect(0,0,MI.xRes+1,MI.yRes+1);
  171.     else
  172.         VECS.solid.fillRect(x,y,x+width,y+height);
  173. }
  174.  
  175. PRIVATE void set_index(GLcontext *ctx, GLuint index)
  176. /****************************************************************************
  177. *
  178. * Function:     clear_index
  179. * Parameters:   index   - New color index
  180. *
  181. * Description:  Sets the current solid color for color index buffers.
  182. *
  183. ****************************************************************************/
  184. {
  185.     RC.color = index;
  186. }
  187.  
  188. PRIVATE void set_color(GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a)
  189. /****************************************************************************
  190. *
  191. * Function:     set_color
  192. * Parameters:   r,g,b,a - New RGBA color value
  193. *
  194. * Description:  Set the current solid color for TrueColor buffers.
  195. *               Note that Mesa passes us color values pre-scaled to the
  196. *               proper number of color bits:
  197. *
  198. *                   [0,ctx->Visual->RedScale]
  199. *                   [0,ctx->Visual->GreenScale]
  200. *                   [0,ctx->Visual->BlueScale]
  201. *                   [0,ctx->Visual->AlphaScale]
  202. *
  203. ****************************************************************************/
  204. {
  205.     RC.color = PACK_COLOR(r,g,b);
  206.     RC.red = r;
  207.     RC.green = g;
  208.     RC.blue = b;
  209. }
  210.  
  211. PRIVATE GLboolean index_mask(GLcontext *ctx, GLuint mask)
  212. /****************************************************************************
  213. *
  214. * Function:     index_mask
  215. * Parameters:   mask    - Color index mask
  216. * Returns:      True if we implement masking, false if not
  217. *
  218. * Description:  Implements color index masking ala glIndexMask if possible.
  219. *               We currently return false for this function.
  220. *
  221. ****************************************************************************/
  222. {
  223.     return GL_FALSE;
  224. }
  225.  
  226. PRIVATE GLboolean color_mask(GLcontext *ctx,
  227.     GLboolean rmask, GLboolean gmask,GLboolean bmask, GLboolean amask)
  228. /****************************************************************************
  229. *
  230. * Function:     color_mask
  231. * Parameters:   rmask   - Red mask
  232. *               gmask   - Green mask
  233. *               bmask   - Blue mask
  234. *               amask   - Alpha mask
  235. * Returns:      True if we implement masking, false if not
  236. *
  237. * Description:  Implements RGB color masking ala glColorMask if possible.
  238. *               We currently return false for this function.
  239. *
  240. ****************************************************************************/
  241. {
  242.     return GL_FALSE;
  243. }
  244.  
  245. PRIVATE GLboolean logicop(GLcontext *ctx, GLenum op)
  246. /****************************************************************************
  247. *
  248. * Function:     logicop
  249. * Parameters:   op  - New logic op to enable
  250. * Returns:      True if we implement masking, false if not
  251. *
  252. * Description:  Implements logic operations ala glLogicOp if possible. For
  253. *               op's that we dont support we simply return GL_FALSE and it
  254. *               is implemented in software by Mesa.
  255. *
  256. ****************************************************************************/
  257. {
  258. #if 0
  259.     int mode;
  260.  
  261.     switch (op) {
  262.         case GL_COPY:   mode = MGL_REPLACE_MODE;    break;
  263.         case GL_AND:    mode = MGL_AND_MODE;        break;
  264.         case GL_OR:     mode = MGL_OR_MODE;         break;
  265.         case GL_XOR:    mode = MGL_XOR_MODE;        break;
  266.         default:        return GL_FALSE;
  267.         }
  268.     DC.r.setWriteMode(mode);
  269.     return GL_TRUE;
  270. #else
  271.     return GL_FALSE;
  272. #endif
  273. }
  274.  
  275. PRIVATE void dither(GLcontext *ctx, GLboolean enable)
  276. /****************************************************************************
  277. *
  278. * Function:     dither
  279. * Parameters:   enable  - True to enable dithering, false to disable it 
  280. *
  281. * Description:  Enables dithering mode if applicable. For the moment if
  282. *               dithering is enabled we will simply fall back on Mesa's
  283. *               software rendering until we have support for this.
  284. *
  285. ****************************************************************************/
  286. {
  287.     if (enable) 
  288.         RC.pixelformat = RC.dithered_pf;
  289.     else
  290.         RC.pixelformat = RC.undithered_pf;
  291.     setup_DD_pointers(ctx);
  292. }
  293.  
  294. PRIVATE GLboolean set_buffer(GLcontext *ctx, GLenum mode)
  295. /****************************************************************************
  296. *
  297. * Function:     set_buffer
  298. * Parameters:   mode    - Buffer mode to enable 
  299. *
  300. * Description:  Sets the buffer access mode to the front buffer or the
  301. *               back buffer for the application. The MGL always allows
  302. *               direct access to both buffers in double buffered fullscreen
  303. *               modes, but when rendering to a memory device context (ie:
  304. *               when rendering in a window in the windows environment) we
  305. *               only have a single buffer available.
  306. *
  307. ****************************************************************************/
  308. {
  309.     if (!RC.gl_vis->DBflag) {
  310.         MGL_makeCurrentDC(RC.dc);
  311.         return (mode = GL_FRONT);
  312.         }
  313.     if (RC.dc->mi.maxPage > 0) {
  314.         /* Hardware page flipping */
  315.         if (mode == GL_FRONT)
  316.             MGL_setActivePage(RC.dc,RC.frontbuffer);
  317.         else if (mode == GL_BACK)
  318.             MGL_setActivePage(RC.dc,RC.backbuffer);
  319.         else
  320.             return GL_FALSE;
  321.         }
  322.     if (RC.memdc) {
  323.         /* Software double buffering using a memory DC. In some cases
  324.          * we may not be able to access the display memory surface for the
  325.          * front buffer in which case this will fail.
  326.          */
  327.         if (mode == GL_FRONT && (MGL_surfaceAccessType(RC.dc) != MGL_NO_ACCESS)) 
  328.             MGL_makeCurrentDC(RC.dc);
  329.         else if (mode == GL_BACK)
  330.             MGL_makeCurrentDC(RC.memdc);
  331.         else
  332.             return GL_FALSE;
  333.         }
  334.     else {
  335.         /* Hardware page flipping only */
  336.         MGL_makeCurrentDC(RC.dc);
  337.         }
  338.     RC.bufferMode = mode;
  339.     setup_DD_pointers(ctx);
  340.     return GL_TRUE;
  341. }
  342.  
  343. PRIVATE void get_buffer_size(GLcontext *ctx, GLuint *width, GLuint *height)
  344. /****************************************************************************
  345. *
  346. * Function:     get_buffer_size
  347. * Parameters:   width   - Place to store buffer width
  348. *               height  - Place to store buffer height 
  349. *
  350. * Description:  Returns the current buffer width and height. We simply
  351. *               return the currently active device context's width and
  352. *               height, which will change if the buffer is resized in a
  353. *               windowed environment.
  354. *
  355. ****************************************************************************/
  356. {
  357.     if (MI.xRes != RC.dispdc->mi.xRes || MI.yRes != RC.dispdc->mi.yRes) {
  358.         MI.xRes = RC.dispdc->mi.xRes;
  359.         MI.yRes = RC.dispdc->mi.yRes;
  360.  
  361.         /* Resize our system memory back buffer if we have one */
  362.         if (RC.memdc) {
  363.             MGL_destroyDC(RC.memdc);
  364.             RC.memdc = MGL_createMemoryDC(MI.xRes+1,MI.yRes+1,MI.bitsPerPixel,&PF);
  365.             if (!RC.memdc)
  366.                 exit(1);
  367.             RC.dc = RC.memdc;
  368.             if (RC.dispdc->mi.bitsPerPixel == 8) {
  369.                 palette_t pal[256];
  370.                 MGL_getPalette(RC.dispdc,pal,256,0);
  371.                 MGL_setPalette(RC.memdc,pal,256,0);
  372.                 MGL_realizePalette(RC.memdc,256,0,-1);
  373.                 }
  374.             MI = RC.dc->mi;
  375.             }
  376.         }
  377.     *width = MI.xRes+1;
  378.     *height = MI.yRes+1;
  379.     RC.bottom = MI.yRes;
  380. }
  381.  
  382. /**********************************************************************/
  383. /***                    Point rendering                             ***/
  384. /**********************************************************************/
  385.  
  386. PUBLIC points_func mmesa_get_points_func(GLcontext *ctx)
  387. /****************************************************************************
  388. *
  389. * Function:     mmesa_get_points_func
  390. * Parameters:   ctx - Context to examine
  391. *
  392. * Description:  Analyze context state to see if we can provide a fast points
  393. *               drawing function, like those in points.c.  Otherwise, return
  394. *               NULL.
  395. *
  396. ****************************************************************************/
  397. {
  398. #if 0
  399.     if (ctx->Point.Size == 1.0F && !ctx->Point.SmoothFlag && ctx->RasterMask == 0
  400.             && !ctx->Texture.Enabled) {
  401.         return draw_points;
  402.         }
  403. #endif
  404.     return NULL;
  405. }
  406.  
  407. /**********************************************************************/
  408. /***                      Line rendering                            ***/
  409. /**********************************************************************/
  410.  
  411. PUBLIC line_func mmesa_get_line_func(GLcontext *ctx)
  412. /****************************************************************************
  413. *
  414. * Function:     mmesa_get_line_func
  415. * Parameters:   ctx - Context to examine
  416. *
  417. * Description:  Analyze context state to see if we can provide a fast line
  418. *               drawing function, like those in lines.c.  Otherwise, return
  419. *               NULL.   
  420. *
  421. ****************************************************************************/
  422. {
  423. #if 0
  424.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  425.    int depth = xmesa->xm_visual->visinfo->depth;
  426.  
  427.    if (ctx->Line.SmoothFlag)              return NULL;
  428.    if (ctx->Texture.Enabled)              return NULL;
  429.    if (ctx->Light.ShadeModel!=GL_FLAT)    return NULL;
  430.  
  431.    if (xmesa->xm_buffer->buffer==XIMAGE
  432.        && ctx->RasterMask==DEPTH_BIT
  433.        && ctx->Depth.Func==GL_LESS
  434.        && ctx->Depth.Mask==GL_TRUE
  435.        && ctx->Line.Width==1.0F
  436.        && ctx->Line.StippleFlag==GL_FALSE) {
  437.       switch (xmesa->pixelformat) {
  438.          case PF_TRUECOLOR:
  439.             return flat_TRUECOLOR_z_line;
  440.          case PF_8A8B8G8R:
  441.             return flat_8A8B8G8R_z_line;
  442.          case PF_8R8G8B:
  443.             return flat_8R8G8B_z_line;
  444.          case PF_5R6G5B:
  445.             return flat_5R6G5B_z_line;
  446.          case PF_DITHER:
  447.             return (depth==8) ? flat_DITHER8_z_line : NULL;
  448.          case PF_LOOKUP:
  449.             return (depth==8) ? flat_LOOKUP8_z_line : NULL;
  450.          case PF_HPCR:
  451.             return flat_HPCR_z_line;
  452.          default:
  453.             return NULL;
  454.       }
  455.    }
  456.    if (xmesa->xm_buffer->buffer==XIMAGE
  457.        && ctx->RasterMask==0
  458.        && ctx->Line.Width==1.0F
  459.        && ctx->Line.StippleFlag==GL_FALSE) {
  460.       switch (xmesa->pixelformat) {
  461.          case PF_TRUECOLOR:
  462.             return flat_TRUECOLOR_line;
  463.          case PF_8A8B8G8R:
  464.             return flat_8A8B8G8R_line;
  465.          case PF_8R8G8B:
  466.             return flat_8R8G8B_line;
  467.          case PF_5R6G5B:
  468.             return flat_5R6G5B_line;
  469.          case PF_DITHER:
  470.             return (depth==8) ? flat_DITHER8_line : NULL;
  471.          case PF_LOOKUP:
  472.             return (depth==8) ? flat_LOOKUP8_line : NULL;
  473.          case PF_HPCR:
  474.             return flat_HPCR_line;
  475.      default:
  476.         return NULL;
  477.       }
  478.    }
  479.    if (xmesa->xm_buffer->buffer!=XIMAGE && ctx->RasterMask==0) {
  480.       setup_x_line_options( ctx );
  481.       return flat_pixmap_line;
  482.    }
  483. #endif
  484.     return NULL;
  485. }
  486.  
  487. /**********************************************************************/
  488. /***                   Triangle rendering                            ***/
  489. /**********************************************************************/
  490.  
  491. triangle_func mmesa_get_triangle_func(GLcontext *ctx)
  492. {
  493. #if 0
  494.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  495.    int depth = xmesa->xm_visual->visinfo->depth;
  496.  
  497.    if (ctx->Polygon.SmoothFlag)     return NULL;
  498.    if (ctx->Texture.Enabled)        return NULL;
  499.  
  500.    if (xmesa->xm_buffer->buffer==XIMAGE) {
  501.       if (   ctx->Light.ShadeModel==GL_SMOOTH
  502.           && ctx->RasterMask==DEPTH_BIT
  503.           && ctx->Depth.Func==GL_LESS
  504.           && ctx->Depth.Mask==GL_TRUE
  505.           && ctx->Polygon.StippleFlag==GL_FALSE) {
  506.          switch (xmesa->pixelformat) {
  507.             case PF_TRUECOLOR:
  508.            return smooth_TRUECOLOR_z_triangle;
  509.             case PF_8A8B8G8R:
  510.                return smooth_8A8B8G8R_z_triangle;
  511.             case PF_8R8G8B:
  512.                return smooth_8R8G8B_z_triangle;
  513.             case PF_5R6G5B:
  514.                return smooth_5R6G5B_z_triangle;
  515.             case PF_HPCR:
  516.            return smooth_HPCR_z_triangle;
  517.             case PF_DITHER:
  518.                return (depth==8) ? smooth_DITHER8_z_triangle
  519.                                         : smooth_DITHER_z_triangle;
  520.             case PF_LOOKUP:
  521.                return (depth==8) ? smooth_LOOKUP8_z_triangle : NULL;
  522.             default:
  523.                return NULL;
  524.          }
  525.       }
  526.       if (   ctx->Light.ShadeModel==GL_FLAT
  527.           && ctx->RasterMask==DEPTH_BIT
  528.           && ctx->Depth.Func==GL_LESS
  529.           && ctx->Depth.Mask==GL_TRUE
  530.           && ctx->Polygon.StippleFlag==GL_FALSE) {
  531.          switch (xmesa->pixelformat) {
  532.             case PF_TRUECOLOR:
  533.            return flat_TRUECOLOR_z_triangle;
  534.             case PF_8A8B8G8R:
  535.                return flat_8A8B8G8R_z_triangle;
  536.             case PF_8R8G8B:
  537.                return flat_8R8G8B_z_triangle;
  538.             case PF_5R6G5B:
  539.                return flat_5R6G5B_z_triangle;
  540.             case PF_HPCR:
  541.            return flat_HPCR_z_triangle;
  542.             case PF_DITHER:
  543.                return (depth==8) ? flat_DITHER8_z_triangle
  544.                                         : flat_DITHER_z_triangle;
  545.             case PF_LOOKUP:
  546.                return (depth==8) ? flat_LOOKUP8_z_triangle : NULL;
  547.             default:
  548.                return NULL;
  549.          }
  550.       }
  551.       if (   ctx->RasterMask==0   /* no depth test */
  552.           && ctx->Light.ShadeModel==GL_SMOOTH
  553.           && ctx->Polygon.StippleFlag==GL_FALSE) {
  554.          switch (xmesa->pixelformat) {
  555.             case PF_TRUECOLOR:
  556.            return smooth_TRUECOLOR_triangle;
  557.             case PF_8A8B8G8R:
  558.                return smooth_8A8B8G8R_triangle;
  559.             case PF_8R8G8B:
  560.                return smooth_8R8G8B_triangle;
  561.             case PF_5R6G5B:
  562.                return smooth_5R6G5B_triangle;
  563.             case PF_HPCR:
  564.            return smooth_HPCR_triangle;
  565.             case PF_DITHER:
  566.                return (depth==8) ? smooth_DITHER8_triangle
  567.                                         : smooth_DITHER_triangle;
  568.             case PF_LOOKUP:
  569.                return (depth==8) ? smooth_LOOKUP8_triangle : NULL;
  570.             default:
  571.                return NULL;
  572.          }
  573.       }
  574.  
  575.       if (   ctx->RasterMask==0   /* no depth test */
  576.           && ctx->Light.ShadeModel==GL_FLAT
  577.           && ctx->Polygon.StippleFlag==GL_FALSE) {
  578.          switch (xmesa->pixelformat) {
  579.             case PF_TRUECOLOR:
  580.            return flat_TRUECOLOR_triangle;
  581.             case PF_8A8B8G8R:
  582.                return flat_8A8B8G8R_triangle;
  583.             case PF_8R8G8B:
  584.                return flat_8R8G8B_triangle;
  585.             case PF_5R6G5B:
  586.                return flat_5R6G5B_triangle;
  587.             case PF_HPCR:
  588.            return flat_HPCR_triangle;
  589.             case PF_DITHER:
  590.                return (depth==8) ? flat_DITHER8_triangle
  591.                                         : flat_DITHER_triangle;
  592.             case PF_LOOKUP:
  593.                return (depth==8) ? flat_LOOKUP8_triangle : NULL;
  594.             default:
  595.                return NULL;
  596.          }
  597.       }
  598.  
  599.       return NULL;
  600.    }
  601.    else {
  602.       /* pixmap */
  603.       if (ctx->Light.ShadeModel==GL_FLAT && ctx->RasterMask==0) {
  604.          setup_x_polygon_options( ctx );
  605.          return flat_pixmap_triangle;
  606.       }
  607.       return NULL;
  608.    }
  609. #endif
  610.     return NULL;
  611. }
  612.  
  613. /**********************************************************************/
  614. /*****                 Miscellaneous functions                    *****/
  615. /**********************************************************************/
  616.  
  617. PRIVATE void setup_DD_pointers(GLcontext *ctx)
  618. /****************************************************************************
  619. *
  620. * Function:     setup_DD_pointer
  621. * Parameters:   ctx - Device context to setup pointers for
  622. *
  623. * Description:  Sets up all the device driver rendering pointers for the
  624. *               current rendering state. This function is where we swap in
  625. *               high performance rendering functions when the rendering
  626. *               state allows this.
  627. *
  628. ****************************************************************************/
  629. {
  630.     bool    doDither = false;
  631.  
  632.     /* Always the same */
  633.     ctx->Driver.UpdateState = setup_DD_pointers;
  634.     ctx->Driver.GetBufferSize = get_buffer_size;
  635.     ctx->Driver.Begin = begin;
  636.     ctx->Driver.End = end;
  637.     ctx->Driver.Flush = flush;
  638.     ctx->Driver.Finish = finish;
  639.     ctx->Driver.SetBuffer = set_buffer;
  640.     ctx->Driver.Index = set_index;
  641.     ctx->Driver.Color = set_color;
  642.     ctx->Driver.ClearIndex = clear_index;
  643.     ctx->Driver.ClearColor = clear_color;
  644.     ctx->Driver.Clear = clear;
  645.     ctx->Driver.IndexMask = index_mask;
  646.     ctx->Driver.ColorMask = color_mask;
  647.     ctx->Driver.LogicOp = logicop;
  648.     ctx->Driver.Dither = dither;
  649.  
  650.     /* Accelerated point, line and triangle functions */
  651.     ctx->Driver.PointsFunc = mmesa_get_points_func(ctx);
  652.     ctx->Driver.LineFunc = mmesa_get_line_func(ctx);
  653.     ctx->Driver.TriangleFunc = mmesa_get_triangle_func(ctx);
  654.  
  655.     /* Accelerated bitmap drawing functions */
  656. #if 0
  657.     ctx->Driver.DrawPixels = draw_pixels;
  658.     ctx->Driver.Bitmap = draw_bitmap;
  659. #endif
  660.  
  661.     /* Optimized pixel span reading/writing functions. Note that we use
  662.      * a (void*) cast as we have removed the 'const'ness of the parameters
  663.      * passed to these functions so we can use the pointers to step through
  664.      * our arrays efficiently.
  665.      */
  666.     switch (RC.pixelformat) {
  667.         case PF_INDEX:
  668.             ctx->Driver.WriteIndexSpan       = (void*)_mmesa_write_span_ci;
  669.             ctx->Driver.WriteMonoindexSpan   = (void*)_mmesa_write_span_mono_ci;
  670.             ctx->Driver.WriteIndexPixels     = (void*)_mmesa_write_pixels_ci;
  671.             ctx->Driver.WriteMonoindexPixels = (void*)_mmesa_write_pixels_mono_ci;
  672.             ctx->Driver.ReadIndexSpan        = (void*)_mmesa_read_span_ci;
  673.             ctx->Driver.ReadIndexPixels      = (void*)_mmesa_read_pixels_ci;
  674.             break;
  675.         case PF_RGB8:
  676.             ctx->Driver.WriteColorSpan       = (void*)_mmesa_write_span_8_8;
  677.             ctx->Driver.WriteMonocolorSpan   = (void*)_mmesa_write_span_mono_8;
  678.             ctx->Driver.WriteColorPixels     = (void*)_mmesa_write_pixels_8_8;
  679.             ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_8;
  680.             ctx->Driver.ReadColorSpan        = (void*)_mmesa_read_span_8;
  681.             ctx->Driver.ReadColorPixels      = (void*)_mmesa_read_pixels_8;
  682.             doDither = true;
  683.             break;
  684.         case PF_DITHER8:
  685.             ctx->Driver.WriteColorSpan       = (void*)_mmesa_write_span_8_DITHER8;
  686.             ctx->Driver.WriteMonocolorSpan   = (void*)_mmesa_write_span_mono_8_DITHER8;
  687.             ctx->Driver.WriteColorPixels     = (void*)_mmesa_write_pixels_8_DITHER8;
  688.             ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_8_DITHER8;
  689.             ctx->Driver.ReadColorSpan        = (void*)_mmesa_read_span_8;
  690.             ctx->Driver.ReadColorPixels      = (void*)_mmesa_read_pixels_8;
  691.             doDither = true;
  692.             break;
  693.         case PF_RGB555:
  694.             ctx->Driver.WriteColorSpan       = (void*)_mmesa_write_span_16_555;
  695.             ctx->Driver.WriteMonocolorSpan   = (void*)_mmesa_write_span_mono_16;
  696.             ctx->Driver.WriteColorPixels     = (void*)_mmesa_write_pixels_16_555;
  697.             ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_16;
  698.             ctx->Driver.ReadColorSpan        = (void*)_mmesa_read_span_16_555;
  699.             ctx->Driver.ReadColorPixels      = (void*)_mmesa_read_pixels_16_555;
  700.             break;
  701.         case PF_DITHER555:
  702.             ctx->Driver.WriteColorSpan       = (void*)_mmesa_write_span_16_DITHER555;
  703.             ctx->Driver.WriteMonocolorSpan   = (void*)_mmesa_write_span_mono_16_DITHER555;
  704.             ctx->Driver.WriteColorPixels     = (void*)_mmesa_write_pixels_16_DITHER555;
  705.             ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_16_DITHER555;
  706.             ctx->Driver.ReadColorSpan        = (void*)_mmesa_read_span_16_555;
  707.             ctx->Driver.ReadColorPixels      = (void*)_mmesa_read_pixels_16_555;
  708.             doDither = true;
  709.             break;
  710.         case PF_RGB565:
  711.             ctx->Driver.WriteColorSpan       = (void*)_mmesa_write_span_16_565;
  712.             ctx->Driver.WriteMonocolorSpan   = (void*)_mmesa_write_span_mono_16;
  713.             ctx->Driver.WriteColorPixels     = (void*)_mmesa_write_pixels_16_565;
  714.             ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_16;
  715.             ctx->Driver.ReadColorSpan        = (void*)_mmesa_read_span_16_565;
  716.             ctx->Driver.ReadColorPixels      = (void*)_mmesa_read_pixels_16_565;
  717.             break;
  718.         case PF_DITHER565:
  719.             ctx->Driver.WriteColorSpan       = (void*)_mmesa_write_span_16_DITHER565;
  720.             ctx->Driver.WriteMonocolorSpan   = (void*)_mmesa_write_span_mono_16_DITHER565;
  721.             ctx->Driver.WriteColorPixels     = (void*)_mmesa_write_pixels_16_DITHER565;
  722.             ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_16_DITHER565;
  723.             ctx->Driver.ReadColorSpan        = (void*)_mmesa_read_span_16_565;
  724.             ctx->Driver.ReadColorPixels      = (void*)_mmesa_read_pixels_16_565;
  725.             doDither = true;
  726.             break;
  727.         case PF_RGB888:
  728.             ctx->Driver.WriteColorSpan       = (void*)_mmesa_write_span_24_RGB;
  729.             ctx->Driver.WriteMonocolorSpan   = (void*)_mmesa_write_span_mono_24_RGB;
  730.             ctx->Driver.WriteColorPixels     = (void*)_mmesa_write_pixels_24_RGB;
  731.             ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_24_RGB;
  732.             ctx->Driver.ReadColorSpan        = (void*)_mmesa_read_span_24_RGB;
  733.             ctx->Driver.ReadColorPixels      = (void*)_mmesa_read_pixels_24_RGB;
  734.             break;
  735.         case PF_BGR888:
  736.             ctx->Driver.WriteColorSpan       = (void*)_mmesa_write_span_24_BGR;
  737.             ctx->Driver.WriteMonocolorSpan   = (void*)_mmesa_write_span_mono_24_BGR;
  738.             ctx->Driver.WriteColorPixels     = (void*)_mmesa_write_pixels_24_BGR;
  739.             ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_24_BGR;
  740.             ctx->Driver.ReadColorSpan        = (void*)_mmesa_read_span_24_BGR;
  741.             ctx->Driver.ReadColorPixels      = (void*)_mmesa_read_pixels_24_BGR;
  742.             break;
  743.         case PF_ARGB8888:
  744.             ctx->Driver.WriteColorSpan       = (void*)_mmesa_write_span_32_ARGB;
  745.             ctx->Driver.WriteMonocolorSpan   = (void*)_mmesa_write_span_mono_32;
  746.             ctx->Driver.WriteColorPixels     = (void*)_mmesa_write_pixels_32_ARGB;
  747.             ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_32;
  748.             ctx->Driver.ReadColorSpan        = (void*)_mmesa_read_span_32_ARGB;
  749.             ctx->Driver.ReadColorPixels      = (void*)_mmesa_read_pixels_32_ARGB;
  750.             break;
  751.         case PF_ABGR8888:
  752.             ctx->Driver.WriteColorSpan       = (void*)_mmesa_write_span_32_ABGR;
  753.             ctx->Driver.WriteMonocolorSpan   = (void*)_mmesa_write_span_mono_32;
  754.             ctx->Driver.WriteColorPixels     = (void*)_mmesa_write_pixels_32_ABGR;
  755.             ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_32;
  756.             ctx->Driver.ReadColorSpan        = (void*)_mmesa_read_span_32_ABGR;
  757.             ctx->Driver.ReadColorPixels      = (void*)_mmesa_read_pixels_32_ABGR;
  758.             break;
  759.         case PF_RGBA8888:
  760.             ctx->Driver.WriteColorSpan       = (void*)_mmesa_write_span_32_RGBA;
  761.             ctx->Driver.WriteMonocolorSpan   = (void*)_mmesa_write_span_mono_32;
  762.             ctx->Driver.WriteColorPixels     = (void*)_mmesa_write_pixels_32_RGBA;
  763.             ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_32;
  764.             ctx->Driver.ReadColorSpan        = (void*)_mmesa_read_span_32_RGBA;
  765.             ctx->Driver.ReadColorPixels      = (void*)_mmesa_read_pixels_32_RGBA;
  766.             break;
  767.         case PF_BGRA8888:
  768.             ctx->Driver.WriteColorSpan       = (void*)_mmesa_write_span_32_BGRA;
  769.             ctx->Driver.WriteMonocolorSpan   = (void*)_mmesa_write_span_mono_32;
  770.             ctx->Driver.WriteColorPixels     = (void*)_mmesa_write_pixels_32_BGRA;
  771.             ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_32;
  772.             ctx->Driver.ReadColorSpan        = (void*)_mmesa_read_span_32_BGRA;
  773.             ctx->Driver.ReadColorPixels      = (void*)_mmesa_read_pixels_32_BGRA;
  774.             break;
  775.         }
  776.  
  777.     /* Set the pixel format scale factos for dithering/non-dithering */
  778.     if (doDither) {
  779.         ctx->Visual->RedScale   = 255.0;
  780.         ctx->Visual->GreenScale = 255.0;
  781.         ctx->Visual->BlueScale  = 255.0;
  782.         }
  783.     else {
  784.         ctx->Visual->RedScale   = (GLfloat)PF.redMask;
  785.         ctx->Visual->GreenScale = (GLfloat)PF.greenMask;
  786.         ctx->Visual->BlueScale  = (GLfloat)PF.blueMask;
  787.         }
  788. }
  789.  
  790. /**********************************************************************/
  791. /*****               MGLMesa API Functions                        *****/
  792. /**********************************************************************/
  793.  
  794. #ifdef  __WINDOWS__
  795. bool APIENTRY MGLMesaInitDLL(MGLCallbacks *cb,char *version)
  796. /****************************************************************************
  797. *
  798. * Function:     MGLMesaInitDLL
  799. * Parameters:   cb      - MGL callbacks structure
  800. *               version - MGL version this DLL was built for 
  801. *
  802. * Description:  This function is called by the MGL when the MESAGL.DLL
  803. *               library is loaded under Windows. This registers a set of
  804. *               callback functions that Mesa uses to call MGL API functions
  805. *               so that we dont have to staticly link the MGL and Mesa into
  806. *               the same DLL or application.
  807. *
  808. *               We also pass back a copy of Mesa's internal global MGL
  809. *               device context which Mesa uses to directly access the MGL
  810. *               internal functions and structures. The MGL uses this pointer
  811. *               to maintain Mesa's internal structures  
  812. *
  813. *               Note that because we use the MGL's internal structures we
  814. *               also do a check to ensure that the MGL library calling us
  815. *               is the same version that we were built with.  
  816. *
  817. ****************************************************************************/
  818. {
  819.     /* Check for the correct MGL version */
  820.     if (strcmp(version,MGL_VERSION_STR) != 0)
  821.         return false;
  822.     _MGL_callbacks = *cb;
  823.     return true;
  824. }
  825. #endif
  826.  
  827. void APIENTRY MGLMesaChooseVisual(MGLDC *dc,MGLVisual *visual)
  828. /****************************************************************************
  829. *
  830. * Function:     MGLMesaChooseVisual
  831. * Parameters:   dc      - MGL device context
  832. *               visual  - Structure containing visual context information
  833. *
  834. * Description:  This function examines the visual passed to use to
  835. *               deteremine if we support the requested capabilities. If we
  836. *               don't we will modify the structure for the capabilities that
  837. *               we do support (ie: lowering the depth buffer size to 16
  838. *               bits etc).
  839. *
  840. ****************************************************************************/
  841. {
  842.     /* Force the depth buffer, stencil buffer and accum buffers to our sizes */
  843.     if (visual->depth_size)
  844.         visual->depth_size = 8 * sizeof(GLdepth);
  845.     if (visual->stencil_size)
  846.         visual->stencil_size = 8 * sizeof(GLstencil);
  847.     if (visual->accum_size)
  848.         visual->accum_size = 8 * sizeof(GLaccum);
  849.  
  850.     /* Force RGB mode for DirectColor and TrueColor modes */
  851.     if (dc->mi.bitsPerPixel > 8)
  852.         visual->rgb_flag = GL_TRUE;
  853.     if (MGL_isMemoryDC(dc))
  854.         visual->db_flag = GL_FALSE;
  855.     if (MGL_isWindowedDC(dc) || MGL_surfaceAccessType(dc) == MGL_NO_ACCESS)
  856.         visual->db_flag = GL_TRUE;
  857. }
  858.  
  859. PRIVATE int countBits(uint mask)
  860. /****************************************************************************
  861. *
  862. * Function:     countBits
  863. * Parameters:   mask    - 
  864. * Returns:      number of set bits.
  865. *
  866. * Description:  Counts the number of set bits in a mask and determines the 
  867. *               shift amount.
  868. *
  869. ****************************************************************************/
  870. {
  871.     int i=0;
  872.  
  873.     if (mask) {
  874.         /* count set bits */
  875.         while ( mask & (1 << i)) {  
  876.             i++; 
  877.             };
  878.         }
  879.  
  880.     return i;
  881. }
  882.  
  883. bool APIENTRY MGLMesaSetVisual(MGLDC *dc,MGLVisual *vis)
  884. /****************************************************************************
  885. *
  886. * Function:     MGLMesaSetVisual
  887. * Parameters:   dc      - MGL device context
  888. *               visual  - Structure containing visual context information
  889. * Returns:      True on success, false if visual creation failed
  890. *
  891. * Description:  This function attempts to create a Mesa visual for the
  892. *               device context. If this succeeds then Mesa can properly
  893. *               handle the requested visual.
  894. *
  895. ****************************************************************************/
  896. {
  897.     GLfloat red_scale, green_scale, blue_scale, alpha_scale;
  898.     GLint red_bits, green_bits, blue_bits, alpha_bits;
  899.  
  900.     /* Do quick check on incoming visual */
  901.     if (dc->mi.bitsPerPixel > 8 && !vis->rgb_flag)
  902.         return false;
  903.     if (dc->mi.bitsPerPixel < 8)
  904.         return false; 
  905.     if ((dc->mi.xRes+1 > MAX_WIDTH) || (dc->mi.yRes+1 > MAX_HEIGHT))
  906.         return false;
  907.     if (MGL_isMemoryDC(dc) && vis->db_flag)
  908.         return false;
  909.     if ((MGL_isWindowedDC(dc) || MGL_surfaceAccessType(dc) == MGL_NO_ACCESS) && !vis->db_flag)
  910.         return false;
  911.  
  912.     /* Create color channel scale factors from pixel format info */
  913.     red_scale   = (GLfloat)dc->pf.redMask;
  914.     green_scale = (GLfloat)dc->pf.greenMask;
  915.     blue_scale  = (GLfloat)dc->pf.blueMask;
  916.     alpha_scale = 255.0;
  917.  
  918.     red_bits    = countBits(dc->pf.redMask);    
  919.     green_bits  = countBits(dc->pf.greenMask);  
  920.     blue_bits   = countBits(dc->pf.blueMask);   
  921.     alpha_bits  = countBits(dc->pf.rsvdMask);
  922.  
  923.     MGL_clearCurrentDC();
  924.     dc->visual = gl_create_visual( vis->rgb_flag, 
  925.                                    vis->alpha_flag, 
  926.                                    vis->db_flag,
  927.                                    vis->depth_size, 
  928.                                    vis->stencil_size, 
  929.                                    vis->accum_size,
  930.                                    dc->mi.bitsPerPixel,
  931.                                    red_scale, 
  932.                                    green_scale,
  933.                                    blue_scale, 
  934.                                    alpha_scale,
  935.                                    red_bits, 
  936.                                    green_bits, 
  937.                                    blue_bits, 
  938.                                    alpha_bits);
  939.  
  940.     return (dc->visual != NULL);
  941. }
  942.  
  943. bool APIENTRY MGLMesaCreateContext(MGLDC *dc,bool forceMemDC)
  944. /****************************************************************************
  945. *
  946. * Function:     MGLMesaCreateContext
  947. * Parameters:   dc          - MGLDC to create rendering context for
  948. *               forceMemDC  - True to force rendering to memory back buffer
  949. * Returns:      True on success, false on failure.
  950. *
  951. * Description:  Attempts to create a Mesa rendering context for the
  952. *               device context. The application programmer must first
  953. *               call MGLMesaSetVisual on the MGLDC to set the visual format
  954. *               before calling this function.
  955. *
  956. *               If we dont have hardware page flipping or the user has
  957. *               forced memory buffering with the forceMemDC function then
  958. *               we will allocate a system memory back buffer for double
  959. *               buffering. Note that if we have hardware page flipping
  960. *               and system buffering has been forced, we will still flip
  961. *               between hardware pages to eliminate all tearing. This
  962. *               option is intended mainly as a performance option for
  963. *               systems where system memory rendering is faster. 
  964. *
  965. ****************************************************************************/
  966. {
  967.     palette_t   pal[256];
  968.  
  969.     /* Ensure that the visual has been created first */
  970.     MGL_clearCurrentDC();
  971.     if (!dc->visual)
  972.         return false;
  973.  
  974.     /* Allocate memory for the rendering context structure and create it */
  975.     if ((dc->rc = (void*)calloc(1,sizeof(MGLRC))) == NULL)
  976.         goto Error;
  977.     dc->rc->dispdc = dc;
  978.     dc->rc->gl_ctx = gl_create_context(dc->visual,NULL,(void*)dc->rc);
  979.     if (!dc->rc)
  980.         goto Error;
  981.  
  982.     /* Allocate the ancillary buffers */
  983.     if ((dc->rc->gl_buffer = gl_create_framebuffer(dc->visual)) == NULL)
  984.         goto Error;
  985.  
  986.     /* Allocate back memory DC buffer if necessary */
  987.     if ((dc->visual->DBflag && dc->mi.maxPage == 0) || forceMemDC || (MGL_surfaceAccessType(dc) == MGL_NO_ACCESS)) {
  988.         dc->rc->memdc = MGL_createMemoryDC(dc->mi.xRes+1,dc->mi.yRes+1,dc->mi.bitsPerPixel,&dc->pf);
  989.         if (!dc->rc->memdc)
  990.             goto Error;
  991.         dc->rc->dc = dc->rc->memdc;
  992.         }
  993.     else
  994.         dc->rc->dc = dc->rc->dispdc;
  995.  
  996.     /* Initialize double buffering */
  997.     if (dc->visual->DBflag && dc->mi.maxPage > 0) {
  998.         MGL_setVisualPage(dc,dc->rc->frontbuffer = 0,false);
  999.         MGL_setActivePage(dc,dc->rc->backbuffer = 1);
  1000.         }
  1001.  
  1002.     /* Initialize the private rendering context information */
  1003.     if (!dc->visual->RGBAflag) {
  1004.         dc->rc->dithered_pf = dc->rc->undithered_pf = PF_INDEX;
  1005.         MGL_getPalette(dc,pal,256,0);
  1006.         }
  1007.     else {
  1008.         if (dc->mi.bitsPerPixel > 8) {
  1009.             /* DirectColor or TrueColor display */
  1010.             if (dc->mi.bitsPerPixel == 15) {
  1011.                 dc->rc->undithered_pf = PF_RGB555;
  1012.                 dc->rc->dithered_pf = PF_DITHER555;
  1013.                 }
  1014.             else if (dc->mi.bitsPerPixel == 16) {
  1015.                 dc->rc->undithered_pf = PF_RGB565;
  1016.                 dc->rc->dithered_pf = PF_DITHER565;
  1017.                 }
  1018.             else if (dc->mi.bitsPerPixel == 24) {
  1019.                 if (dc->pf.redPos == 0)
  1020.                     dc->rc->undithered_pf = dc->rc->dithered_pf = PF_BGR888;
  1021.                 else
  1022.                     dc->rc->undithered_pf = dc->rc->dithered_pf = PF_RGB888;
  1023.                 }
  1024.             else {
  1025.                 if (dc->pf.redPos == 0)
  1026.                     dc->rc->undithered_pf = dc->rc->dithered_pf = PF_ABGR8888;
  1027.                 else if (dc->pf.redPos == 8)
  1028.                     dc->rc->undithered_pf = dc->rc->dithered_pf = PF_BGRA8888;
  1029.                 else if (dc->pf.redPos == 16)
  1030.                     dc->rc->undithered_pf = dc->rc->dithered_pf = PF_ARGB8888;
  1031.                 else
  1032.                     dc->rc->undithered_pf = dc->rc->dithered_pf = PF_RGBA8888;
  1033.                 }
  1034.             }
  1035.         else {
  1036.             /* 8bpp RGB display */
  1037.             dc->rc->undithered_pf = PF_RGB8;
  1038.             dc->rc->dithered_pf = PF_DITHER8;
  1039.             MGL_getHalfTonePalette(pal);
  1040.             }
  1041.         }
  1042.     dc->rc->gl_vis = dc->visual;
  1043.     dc->rc->bottom = dc->mi.yRes+1;
  1044.     dc->rc->pixelformat = dc->rc->dithered_pf;
  1045.     dc->rc->bufferMode = dc->visual->DBflag ? GL_BACK : GL_FRONT;
  1046.     setup_DD_pointers(dc->rc->gl_ctx);
  1047.  
  1048.     /* Setup the default palette for the device context */
  1049.     if (dc->mi.bitsPerPixel == 8) {
  1050.         MGLMesaSetPalette(dc,pal,256,0);
  1051.         MGLMesaRealizePalette(dc,256,0,false);
  1052.         }
  1053.     return true;
  1054.  
  1055. Error:
  1056.     MGLMesaDestroyContext(dc);
  1057.     return false;
  1058. }
  1059.  
  1060. void APIENTRY MGLMesaDestroyContext(MGLDC *dc)
  1061. /****************************************************************************
  1062. *
  1063. * Function:     MGLMesaDestroyContext
  1064. * Parameters:   dc  - MGLDC to destroy rendering context for
  1065. *
  1066. * Description:  Destroys the rendering context and returns the MGLDC back
  1067. *               to it's original state before 3D rendering was enabled.
  1068. *
  1069. ****************************************************************************/
  1070. {
  1071.     if (dc->rc) {
  1072.         if (dc->rc->memdc)
  1073.             MGL_destroyDC(dc->rc->memdc);
  1074.         gl_destroy_framebuffer(dc->rc->gl_buffer);
  1075.         gl_destroy_context(dc->rc->gl_ctx);
  1076.         free(dc->rc);
  1077.         }
  1078.     dc->rc = NULL;
  1079.     gl_destroy_visual(dc->visual);
  1080.     dc->visual = NULL;
  1081. }
  1082.  
  1083. void APIENTRY MGLMesaMakeCurrent(MGLDC *dc)
  1084. /****************************************************************************
  1085. *
  1086. * Function:     MGLMesaMakeCurrent
  1087. * Parameters:   dc  - MGLDC to make current
  1088. *
  1089. * Description:  Makes the passed in MGLDC the current rendering context
  1090. *               for OpenGL functions. Note that we cache a global copy
  1091. *               of this rendering context for speed (we are single threaded)
  1092. *               so we flush this back when the context is made a different
  1093. *               one.    
  1094. *
  1095. ****************************************************************************/
  1096. {
  1097.     if (dc && dc->rc == _MM_rcPtr)
  1098.         return;
  1099.     if (_MM_rcPtr) {
  1100.         *_MM_rcPtr = RC;                /* 'Write back' the old RC      */
  1101.         _MM_rcPtr = NULL;               /* This RC is no longer cached  */
  1102.         gl_make_current(NULL, NULL);
  1103.         MGL_clearCurrentDC();
  1104.         }
  1105.     if (dc) {
  1106.         gl_make_current(dc->rc->gl_ctx, dc->rc->gl_buffer);
  1107.         _MM_rcPtr = dc->rc;             /* Cache DC in global structure */
  1108.         RC = *dc->rc;                   /* Save pointer to original DC  */
  1109.         MI = RC.dc->mi;                 /* Save cached MGL internals    */
  1110.         PF = RC.dc->pf;
  1111.         VECS = RC.dc->r;
  1112.         set_buffer(dc->rc->gl_ctx,RC.bufferMode);
  1113.         if (RC.gl_ctx->Viewport.Width == 0) {
  1114.             /* initialize viewport to window size */
  1115.             gl_Viewport(RC.gl_ctx, 0, 0, MI.xRes+1, MI.yRes+1);
  1116.             RC.gl_ctx->Scissor.Width = MI.xRes+1;
  1117.             RC.gl_ctx->Scissor.Height = MI.yRes+1;
  1118.             }
  1119.         }
  1120. }
  1121.  
  1122. void APIENTRY MGLMesaSwapBuffers(MGLDC *dc,bool waitVRT)
  1123. /****************************************************************************
  1124. *
  1125. * Function:     MGLMesaSwapBuffers
  1126. * Parameters:   dc      - MGLDC to swap buffers for
  1127. *               waitVRT - True to wait for vertical retrace
  1128. *
  1129. * Description:  Swaps the display buffers for the MGL device context. If
  1130. *               we have a memory DC this is blitted to the display, and
  1131. *               if we have harware page flipping we flip hardware display
  1132. *               pages.  
  1133. *
  1134. ****************************************************************************/
  1135. {
  1136.     if (!RC.gl_vis->DBflag)
  1137.         return;
  1138.     if (RC.memdc) {
  1139.         /* We have a memory buffer so blit it to the screen */
  1140.         MGL_bitBltCoord(RC.dispdc,RC.memdc,0,0,MI.xRes+1,MI.yRes+1,0,0,MGL_REPLACE_MODE);
  1141.         }
  1142.     if (RC.dc->mi.maxPage > 0) {
  1143.         /* Hardware page flipping */
  1144.         RC.frontbuffer ^= 1;
  1145.         RC.backbuffer = RC.frontbuffer ^ 1;
  1146.         if (RC.bufferMode == GL_FRONT)
  1147.             MGL_setActivePage(RC.dc,RC.frontbuffer);
  1148.         else
  1149.             MGL_setActivePage(RC.dc,RC.backbuffer);
  1150.         MGL_setVisualPage(RC.dc,RC.frontbuffer,waitVRT);
  1151.         }
  1152. }
  1153.  
  1154. void APIENTRY MGLMesaSetPaletteEntry(MGLDC *dc,int entry,uchar red,uchar green,uchar blue)
  1155. /****************************************************************************
  1156. *
  1157. * Function:     MGLMesaSetPaletteEntry
  1158. * Parameters:   dc      - MGLDC to destroy rendering context for
  1159. *               entry   - Index of entry to set
  1160. *               red,... - Color values for palette entry
  1161. *
  1162. * Description:  Sets a single color palette entry in the device context.
  1163. *
  1164. ****************************************************************************/
  1165. {
  1166.     MGL_setPaletteEntry(dc,entry,red,green,blue);
  1167.     if (dc->rc && dc->rc->memdc)
  1168.         MGL_setPaletteEntry(dc->rc->memdc,entry,red,green,blue);
  1169. }
  1170.  
  1171. void APIENTRY MGLMesaSetPalette(MGLDC *dc,palette_t *pal,int numColors,int startIndex)
  1172. /****************************************************************************
  1173. *
  1174. * Function:     MGLMesaDestroyContext
  1175. * Parameters:   dc  - MGLDC to destroy rendering context for
  1176. *
  1177. * Description:  Destroys the rendering context and returns the MGLDC back
  1178. *               to it's original state before 3D rendering was enabled.
  1179. *
  1180. ****************************************************************************/
  1181. {
  1182.     MGL_setPalette(dc,pal,numColors,startIndex);
  1183.     if (dc->rc && dc->rc->memdc)
  1184.         MGL_setPalette(dc->rc->memdc,pal,numColors,startIndex);
  1185. }
  1186.  
  1187. void APIENTRY MGLMesaRealizePalette(MGLDC *dc,int numColors,int startIndex,int waitVRT)
  1188. /****************************************************************************
  1189. *
  1190. * Function:     MGLMesaDestroyContext
  1191. * Parameters:   dc  - MGLDC to destroy rendering context for
  1192. *
  1193. * Description:  Destroys the rendering context and returns the MGLDC back
  1194. *               to it's original state before 3D rendering was enabled.
  1195. *
  1196. ****************************************************************************/
  1197. {
  1198.     MGL_realizePalette(dc,numColors,startIndex,waitVRT);
  1199.     if (dc->rc && dc->rc->memdc)
  1200.         MGL_realizePalette(dc->rc->memdc,numColors,startIndex,waitVRT);
  1201. }
  1202.  
  1203.