home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / System / Mesa-3.1 / src / OSmesa / osmesa.c < prev   
C/C++ Source or Header  |  1999-08-18  |  46KB  |  1,595 lines

  1. /* $Id: osmesa.c,v 1.1.1.1 1999/08/19 00:55:42 jtg Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.1
  6.  * 
  7.  * Copyright (C) 1999  Brian Paul   All Rights Reserved.
  8.  * 
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  * 
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  * 
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  */
  26.  
  27.  
  28. /*
  29.  * Off-Screen Mesa rendering / Rendering into client memory space
  30.  */
  31.  
  32.  
  33. #ifdef PC_HEADER
  34. #include "all.h"
  35. #else
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #include "GL/osmesa.h"
  39. #include "context.h"
  40. #include "depth.h"
  41. #include "macros.h"
  42. #include "matrix.h"
  43. #include "types.h"
  44. #include "vb.h"
  45. #endif
  46.  
  47.  
  48. struct osmesa_context {
  49.    GLcontext *gl_ctx;        /* The core GL/Mesa context */
  50.    GLvisual *gl_visual;        /* Describes the buffers */
  51.    GLframebuffer *gl_buffer;    /* Depth, stencil, accum, etc buffers */
  52.    GLenum format;        /* either GL_RGBA or GL_COLOR_INDEX */
  53.    void *buffer;        /* the image buffer */
  54.    GLint width, height;        /* size of image buffer */
  55.    GLuint pixel;        /* current color index or RGBA pixel value */
  56.    GLuint clearpixel;        /* pixel for clearing the color buffer */
  57.    GLint rowlength;        /* number of pixels per row */
  58.    GLint userRowLength;        /* user-specified number of pixels per row */
  59.    GLint rshift, gshift;    /* bit shifts for RGBA formats */
  60.    GLint bshift, ashift;
  61.    GLint rind, gind, bind;    /* index offsets for RGBA formats */
  62.    void *rowaddr[MAX_HEIGHT];    /* address of first pixel in each image row */
  63.    GLboolean yup;        /* TRUE  -> Y increases upward */
  64.                 /* FALSE -> Y increases downward */
  65. };
  66.  
  67.  
  68.  
  69. #ifdef THREADS
  70.  
  71. #include "mthreads.h" /* Mesa platform independent threads interface */
  72.  
  73. static MesaTSD osmesa_ctx_tsd;
  74.  
  75. static void osmesa_ctx_thread_init() {
  76.   MesaInitTSD(&osmesa_ctx_tsd);
  77. }
  78.  
  79. static OSMesaContext osmesa_get_thread_context( void ) {
  80.   return (OSMesaContext) MesaGetTSD(&osmesa_ctx_tsd);
  81. }
  82.  
  83. static void osmesa_set_thread_context( OSMesaContext ctx ) {
  84.   MesaSetTSD(&osmesa_ctx_tsd, ctx, osmesa_ctx_thread_init);
  85. }
  86.  
  87.  
  88. #else
  89.    /* One current context for address space, all threads */
  90.    static OSMesaContext Current = NULL;
  91. #endif
  92.  
  93.  
  94.  
  95. /* A forward declaration: */
  96. static void osmesa_update_state( GLcontext *ctx );
  97.  
  98.  
  99.  
  100. /**********************************************************************/
  101. /*****                    Public Functions                        *****/
  102. /**********************************************************************/
  103.  
  104.  
  105. /*
  106.  * Create an Off-Screen Mesa rendering context.  The only attribute needed is
  107.  * an RGBA vs Color-Index mode flag.
  108.  *
  109.  * Input:  format - either GL_RGBA or GL_COLOR_INDEX
  110.  *         sharelist - specifies another OSMesaContext with which to share
  111.  *                     display lists.  NULL indicates no sharing.
  112.  * Return:  an OSMesaContext or 0 if error
  113.  */
  114. OSMesaContext GLAPIENTRY OSMesaCreateContext( GLenum format, OSMesaContext sharelist )
  115. {
  116.    OSMesaContext osmesa;
  117.    GLint rshift, gshift, bshift, ashift;
  118.    GLint rind, gind, bind;
  119.    GLint indexBits, alphaBits;
  120.    GLboolean rgbmode;
  121.    GLboolean swalpha;
  122.    GLuint i4 = 1;
  123.    GLubyte *i1 = (GLubyte *) &i4;
  124.    GLint little_endian = *i1;
  125.  
  126.    swalpha = GL_FALSE;
  127.    rind = gind = bind = 0;
  128.    if (format==OSMESA_COLOR_INDEX) {
  129.       indexBits = 8;
  130.       rshift = gshift = bshift = ashift = 0;
  131.       rgbmode = GL_FALSE;
  132.    }
  133.    else if (format==OSMESA_RGBA) {
  134.       indexBits = 0;
  135.       alphaBits = 8;
  136.       if (little_endian) {
  137.          rshift = 0;
  138.          gshift = 8;
  139.          bshift = 16;
  140.          ashift = 24;
  141.       }
  142.       else {
  143.          rshift = 24;
  144.          gshift = 16;
  145.          bshift = 8;
  146.          ashift = 0;
  147.       }
  148.       rgbmode = GL_TRUE;
  149.    }
  150.    else if (format==OSMESA_BGRA) {
  151.       indexBits = 0;
  152.       alphaBits = 8;
  153.       if (little_endian) {
  154.          ashift = 0;
  155.          rshift = 8;
  156.          gshift = 16;
  157.          bshift = 24;
  158.       }
  159.       else {
  160.          bshift = 24;
  161.          gshift = 16;
  162.          rshift = 8;
  163.          ashift = 0;
  164.       }
  165.       rgbmode = GL_TRUE;
  166.    }
  167.    else if (format==OSMESA_ARGB) {
  168.       indexBits = 0;
  169.       alphaBits = 8;
  170.       if (little_endian) {
  171.          bshift = 0;
  172.          gshift = 8;
  173.          rshift = 16;
  174.          ashift = 24;
  175.       }
  176.       else {
  177.          ashift = 24;
  178.          rshift = 16;
  179.          gshift = 8;
  180.          bshift = 0;
  181.       }
  182.       rgbmode = GL_TRUE;
  183.    }
  184.    else if (format==OSMESA_RGB) {
  185.       indexBits = 0;
  186.       alphaBits = 0;
  187.       bshift = 0;
  188.       gshift = 8;
  189.       rshift = 16;
  190.       ashift = 24;
  191.       bind = 2;
  192.       gind = 1;
  193.       rind = 0;
  194.       rgbmode = GL_TRUE;
  195.       swalpha = GL_TRUE;
  196.    }
  197.    else if (format==OSMESA_BGR) {
  198.       indexBits = 0;
  199.       alphaBits = 0;
  200.       bshift = 0;
  201.       gshift = 8;
  202.       rshift = 16;
  203.       ashift = 24;
  204.       bind = 0;
  205.       gind = 1;
  206.       rind = 2;
  207.       rgbmode = GL_TRUE;
  208.       swalpha = GL_TRUE;
  209.    }
  210.    else {
  211.       return NULL;
  212.    }
  213.  
  214.  
  215.    osmesa = (OSMesaContext) calloc( 1, sizeof(struct osmesa_context) );
  216.    if (osmesa) {
  217.       osmesa->gl_visual = gl_create_visual( rgbmode,
  218.                                             swalpha,    /* software alpha */
  219.                                             GL_FALSE,    /* double buffer */
  220.                                             GL_FALSE,    /* stereo */
  221.                                             DEPTH_BITS,
  222.                                             STENCIL_BITS,
  223.                                             ACCUM_BITS,
  224.                                             indexBits,
  225.                                             8, 8, 8, alphaBits );
  226.       if (!osmesa->gl_visual) {
  227.          return NULL;
  228.       }
  229.  
  230.       osmesa->gl_ctx = gl_create_context( osmesa->gl_visual,
  231.                             sharelist ? sharelist->gl_ctx : (GLcontext *) NULL,
  232.                             (void *) osmesa, GL_TRUE );
  233.       if (!osmesa->gl_ctx) {
  234.          gl_destroy_visual( osmesa->gl_visual );
  235.          free(osmesa);
  236.          return NULL;
  237.       }
  238.       osmesa->gl_buffer = gl_create_framebuffer( osmesa->gl_visual );
  239.       if (!osmesa->gl_buffer) {
  240.          gl_destroy_visual( osmesa->gl_visual );
  241.          gl_destroy_context( osmesa->gl_ctx );
  242.          free(osmesa);
  243.          return NULL;
  244.       }
  245.       osmesa->format = format;
  246.       osmesa->buffer = NULL;
  247.       osmesa->width = 0;
  248.       osmesa->height = 0;
  249.       osmesa->pixel = 0;
  250.       osmesa->clearpixel = 0;
  251.       osmesa->userRowLength = 0;
  252.       osmesa->rowlength = 0;
  253.       osmesa->yup = GL_TRUE;
  254.       osmesa->rshift = rshift;
  255.       osmesa->gshift = gshift;
  256.       osmesa->bshift = bshift;
  257.       osmesa->ashift = ashift;
  258.       osmesa->rind = rind;
  259.       osmesa->gind = gind;
  260.       osmesa->bind = bind;
  261.    }
  262.    return osmesa;
  263. }
  264.  
  265.  
  266.  
  267. /*
  268.  * Destroy an Off-Screen Mesa rendering context.
  269.  *
  270.  * Input:  ctx - the context to destroy
  271.  */
  272. void GLAPIENTRY OSMesaDestroyContext( OSMesaContext ctx )
  273. {
  274.    if (ctx) {
  275.       gl_destroy_visual( ctx->gl_visual );
  276.       gl_destroy_framebuffer( ctx->gl_buffer );
  277.       gl_destroy_context( ctx->gl_ctx );
  278.       free( ctx );
  279.    }
  280. }
  281.  
  282.  
  283.  
  284. /*
  285.  * Recompute the values of the context's rowaddr array.
  286.  */
  287. static void compute_row_addresses( OSMesaContext ctx )
  288. {
  289.    GLint i;
  290.  
  291.    if (ctx->yup) {
  292.       /* Y=0 is bottom line of window */
  293.       if (ctx->format==OSMESA_COLOR_INDEX) {
  294.          /* 1-byte CI mode */
  295.          GLubyte *origin = (GLubyte *) ctx->buffer;
  296.          for (i=0;i<MAX_HEIGHT;i++) {
  297.             ctx->rowaddr[i] = origin + i * ctx->rowlength;
  298.          }
  299.       }
  300.       else {
  301.          if ((ctx->format==OSMESA_RGB) || (ctx->format==OSMESA_BGR)) {
  302.             /* 3-byte RGB mode */
  303.             GLubyte *origin = (GLubyte *) ctx->buffer;
  304.             for (i=0;i<MAX_HEIGHT;i++) {
  305.                ctx->rowaddr[i] = origin + (i * (ctx->rowlength*3));
  306.             }
  307.          } else {
  308.             /* 4-byte RGBA mode */
  309.             GLuint *origin = (GLuint *) ctx->buffer;
  310.             for (i=0;i<MAX_HEIGHT;i++) {
  311.                ctx->rowaddr[i] = origin + i * ctx->rowlength;
  312.             }
  313.          }
  314.       }
  315.    }
  316.    else {
  317.       /* Y=0 is top line of window */
  318.       if (ctx->format==OSMESA_COLOR_INDEX) {
  319.          /* 1-byte CI mode */
  320.          GLubyte *origin = (GLubyte *) ctx->buffer;
  321.          for (i=0;i<MAX_HEIGHT;i++) {
  322.             ctx->rowaddr[i] = origin + (ctx->height-i-1) * ctx->rowlength;
  323.          }
  324.       }
  325.       else {
  326.          if ((ctx->format==OSMESA_RGB) || (ctx->format==OSMESA_BGR)) {
  327.             /* 3-byte RGB mode */
  328.             GLubyte *origin = (GLubyte *) ctx->buffer;
  329.             for (i=0;i<MAX_HEIGHT;i++) {
  330.                ctx->rowaddr[i] = origin + ((ctx->height-i-1) * (ctx->rowlength*3));
  331.             }
  332.          } else {
  333.             /* 4-byte RGBA mode */
  334.             GLuint *origin = (GLuint *) ctx->buffer;
  335.             for (i=0;i<MAX_HEIGHT;i++) {
  336.                ctx->rowaddr[i] = origin + (ctx->height-i-1) * ctx->rowlength;
  337.             }
  338.          }
  339.       }
  340.    }
  341. }
  342.  
  343.  
  344. /*
  345.  * Bind an OSMesaContext to an image buffer.  The image buffer is just a
  346.  * block of memory which the client provides.  Its size must be at least
  347.  * as large as width*height*sizeof(type).  Its address should be a multiple
  348.  * of 4 if using RGBA mode.
  349.  *
  350.  * Image data is stored in the order of glDrawPixels:  row-major order
  351.  * with the lower-left image pixel stored in the first array position
  352.  * (ie. bottom-to-top).
  353.  *
  354.  * Since the only type initially supported is GL_UNSIGNED_BYTE, if the
  355.  * context is in RGBA mode, each pixel will be stored as a 4-byte RGBA
  356.  * value.  If the context is in color indexed mode, each pixel will be
  357.  * stored as a 1-byte value.
  358.  *
  359.  * If the context's viewport hasn't been initialized yet, it will now be
  360.  * initialized to (0,0,width,height).
  361.  *
  362.  * Input:  ctx - the rendering context
  363.  *         buffer - the image buffer memory
  364.  *         type - data type for pixel components, only GL_UNSIGNED_BYTE
  365.  *                supported now
  366.  *         width, height - size of image buffer in pixels, at least 1
  367.  * Return:  GL_TRUE if success, GL_FALSE if error because of invalid ctx,
  368.  *          invalid buffer address, type!=GL_UNSIGNED_BYTE, width<1, height<1,
  369.  *          width>internal limit or height>internal limit.
  370.  */
  371. GLboolean GLAPIENTRY OSMesaMakeCurrent( OSMesaContext ctx, void *buffer, GLenum type,
  372.                              GLsizei width, GLsizei height )
  373. {
  374.    if (!ctx || !buffer || type!=GL_UNSIGNED_BYTE
  375.        || width<1 || height<1 || width>MAX_WIDTH || height>MAX_HEIGHT) {
  376.       return GL_FALSE;
  377.    }
  378.  
  379.    osmesa_update_state( ctx->gl_ctx );
  380.    gl_make_current( ctx->gl_ctx, ctx->gl_buffer );
  381.  
  382.    ctx->buffer = buffer;
  383.    ctx->width = width;
  384.    ctx->height = height;
  385.    if (ctx->userRowLength)
  386.       ctx->rowlength = ctx->userRowLength;
  387.    else
  388.       ctx->rowlength = width;
  389.  
  390. #ifdef THREADS
  391.    /* Set current context for the calling thread */
  392.    osmesa_set_thread_context(ctx);
  393. #else
  394.    /* Set current context for the address space, all threads */
  395.    Current = ctx;
  396. #endif
  397.  
  398.    compute_row_addresses( ctx );
  399.  
  400.    /* init viewport */
  401.    if (ctx->gl_ctx->Viewport.Width==0) {
  402.       /* initialize viewport and scissor box to buffer size */
  403.       gl_Viewport( ctx->gl_ctx, 0, 0, width, height );
  404.       ctx->gl_ctx->Scissor.Width = width;
  405.       ctx->gl_ctx->Scissor.Height = height;
  406.    }
  407.  
  408.    return GL_TRUE;
  409. }
  410.  
  411.  
  412.  
  413.  
  414. OSMesaContext GLAPIENTRY OSMesaGetCurrentContext( void )
  415. {
  416. #ifdef THREADS
  417.    /* Return current handle for the calling thread */
  418.    return osmesa_get_thread_context();
  419. #else
  420.    /* Return current handle for the address space, all threads */
  421.    return Current;
  422. #endif
  423. }
  424.  
  425.  
  426.  
  427. void GLAPIENTRY OSMesaPixelStore( GLint pname, GLint value )
  428. {
  429.    OSMesaContext ctx = OSMesaGetCurrentContext();
  430.  
  431.    switch (pname) {
  432.       case OSMESA_ROW_LENGTH:
  433.          if (value<0) {
  434.             gl_error( ctx->gl_ctx, GL_INVALID_VALUE,
  435.                       "OSMesaPixelStore(value)" );
  436.             return;
  437.          }
  438.          ctx->userRowLength = value;
  439.          ctx->rowlength = value;
  440.          break;
  441.       case OSMESA_Y_UP:
  442.          ctx->yup = value ? GL_TRUE : GL_FALSE;
  443.          break;
  444.       default:
  445.          gl_error( ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaPixelStore(pname)" );
  446.          return;
  447.    }
  448.  
  449.    compute_row_addresses( ctx );
  450. }
  451.  
  452.  
  453. void GLAPIENTRY OSMesaGetIntegerv( GLint pname, GLint *value )
  454. {
  455.    OSMesaContext ctx = OSMesaGetCurrentContext();
  456.  
  457.    switch (pname) {
  458.       case OSMESA_WIDTH:
  459.          *value = ctx->width;
  460.          return;
  461.       case OSMESA_HEIGHT:
  462.          *value = ctx->height;
  463.          return;
  464.       case OSMESA_FORMAT:
  465.          *value = ctx->format;
  466.          return;
  467.       case OSMESA_TYPE:
  468.          *value = GL_UNSIGNED_BYTE;
  469.          return;
  470.       case OSMESA_ROW_LENGTH:
  471.          *value = ctx->rowlength;
  472.          return;
  473.       case OSMESA_Y_UP:
  474.          *value = ctx->yup;
  475.          return;
  476.       default:
  477.          gl_error( ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaGetIntergerv(pname)" );
  478.          return;
  479.    }
  480. }
  481.  
  482.  
  483.  
  484. /*
  485.  * Return the depth buffer associated with an OSMesa context.
  486.  * Input:  c - the OSMesa context
  487.  * Output:  width, height - size of buffer in pixels
  488.  *          bytesPerValue - bytes per depth value (2 or 4)
  489.  *          buffer - pointer to depth buffer values
  490.  * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
  491.  */
  492. GLboolean GLAPIENTRY OSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height,
  493.                                 GLint *bytesPerValue, void **buffer )
  494. {
  495.    if ((!c->gl_buffer) || (!c->gl_buffer->Depth)) {
  496.       *width = 0;
  497.       *height = 0;
  498.       *bytesPerValue = 0;
  499.       *buffer = 0;
  500.       return GL_FALSE;
  501.    }
  502.    else {
  503.       *width = c->gl_buffer->Width;
  504.       *height = c->gl_buffer->Height;
  505.       *bytesPerValue = sizeof(GLdepth);
  506.       *buffer = c->gl_buffer->Depth;
  507.       return GL_TRUE;
  508.    }
  509. }
  510.  
  511.  
  512.  
  513.  
  514. /**********************************************************************/
  515. /*** Device Driver Functions                                        ***/
  516. /**********************************************************************/
  517.  
  518.  
  519. /*
  520.  * Useful macros:
  521.  */
  522. #define PACK_RGBA(R,G,B,A)  (  ((R) << osmesa->rshift) \
  523.                              | ((G) << osmesa->gshift) \
  524.                              | ((B) << osmesa->bshift) \
  525.                              | ((A) << osmesa->ashift) )
  526.  
  527. #define PACK_RGBA2(R,G,B,A)  (  ((R) << rshift) \
  528.                               | ((G) << gshift) \
  529.                               | ((B) << bshift) \
  530.                               | ((A) << ashift) )
  531.  
  532. #define UNPACK_RED(P)      (((P) >> osmesa->rshift) & 0xff)
  533. #define UNPACK_GREEN(P)    (((P) >> osmesa->gshift) & 0xff)
  534. #define UNPACK_BLUE(P)     (((P) >> osmesa->bshift) & 0xff)
  535. #define UNPACK_ALPHA(P)    (((P) >> osmesa->ashift) & 0xff)
  536.  
  537. #define PIXELADDR1(X,Y)  ((GLubyte *) osmesa->rowaddr[Y] + (X))
  538. #define PIXELADDR3(X,Y)  ((GLubyte *) osmesa->rowaddr[Y] + ((X)*3))
  539. #define PIXELADDR4(X,Y)  ((GLuint *)  osmesa->rowaddr[Y] + (X))
  540.  
  541.  
  542.  
  543.  
  544. static GLboolean set_buffer( GLcontext *ctx, GLenum mode )
  545. {
  546.    (void) ctx;
  547.    if (mode==GL_FRONT_LEFT) {
  548.       return GL_TRUE;
  549.    }
  550.    else {
  551.       return GL_FALSE;
  552.    }
  553. }
  554.  
  555.  
  556. static void clear_index( GLcontext *ctx, GLuint index )
  557. {
  558.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  559.    osmesa->clearpixel = index;
  560. }
  561.  
  562.  
  563.  
  564. static void clear_color( GLcontext *ctx,
  565.                          GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  566. {
  567.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  568.    osmesa->clearpixel = PACK_RGBA( r, g, b, a );
  569. }
  570.  
  571.  
  572.  
  573. static GLbitfield clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
  574.                          GLint x, GLint y, GLint width, GLint height )
  575. {
  576.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  577.    if (mask & GL_COLOR_BUFFER_BIT) {
  578.       if (osmesa->format==OSMESA_COLOR_INDEX) {
  579.          if (all) {
  580.             /* Clear whole CI buffer */
  581.             MEMSET(osmesa->buffer, osmesa->clearpixel,
  582.                    osmesa->rowlength * osmesa->height);
  583.          }
  584.          else {
  585.             /* Clear part of CI buffer */
  586.             GLint i, j;
  587.             for (i=0;i<height;i++) {
  588.                GLubyte *ptr1 = PIXELADDR1( x, (y+i) );
  589.                for (j=0;j<width;j++) {
  590.                   *ptr1++ = osmesa->clearpixel;
  591.                }
  592.             }
  593.          }
  594.       }
  595.       else if ((osmesa->format==OSMESA_RGB)||(osmesa->format==OSMESA_BGR)) {
  596.          GLubyte rval = UNPACK_RED(osmesa->clearpixel);
  597.          GLubyte gval = UNPACK_GREEN(osmesa->clearpixel);
  598.          GLubyte bval = UNPACK_BLUE(osmesa->clearpixel);
  599.          GLint   rind = osmesa->rind;
  600.          GLint   gind = osmesa->gind;
  601.          GLint   bind = osmesa->bind;
  602.          if (all) {
  603.             GLuint  i, n;
  604.             GLubyte *ptr3 = (GLubyte *) osmesa->buffer;
  605.             /* Clear whole RGB buffer */
  606.             n = osmesa->rowlength * osmesa->height;
  607.             for (i=0;i<n;i++) {
  608.                ptr3[rind] = rval;
  609.                ptr3[gind] = gval;
  610.                ptr3[bind] = bval;
  611.                ptr3 += 3;
  612.             }
  613.          }
  614.          else {
  615.             /* Clear part of RGB buffer */
  616.             GLint i, j;
  617.             for (i=0;i<height;i++) {
  618.                GLubyte *ptr3 = PIXELADDR3( x, (y+i) );
  619.                for (j=0;j<width;j++) {
  620.                   ptr3[rind] = rval;
  621.                   ptr3[gind] = gval;
  622.                   ptr3[bind] = bval;
  623.                   ptr3 += 3;
  624.                }
  625.             }
  626.          }
  627.       }
  628.       else {
  629.          if (all) {
  630.             /* Clear whole RGBA buffer */
  631.             GLuint i, n, *ptr4;
  632.             n = osmesa->rowlength * osmesa->height;
  633.             ptr4 = (GLuint *) osmesa->buffer;
  634.             for (i=0;i<n;i++) {
  635.                *ptr4++ = osmesa->clearpixel;
  636.             }
  637.          }
  638.          else {
  639.             /* Clear part of RGBA buffer */
  640.             GLint i, j;
  641.             for (i=0;i<height;i++) {
  642.                GLuint *ptr4 = PIXELADDR4( x, (y+i) );
  643.                for (j=0;j<width;j++) {
  644.                   *ptr4++ = osmesa->clearpixel;
  645.                }
  646.             }
  647.          }
  648.       }
  649.    }
  650.    return mask & (~GL_COLOR_BUFFER_BIT);
  651. }
  652.  
  653.  
  654.  
  655. static void set_index( GLcontext *ctx, GLuint index )
  656. {
  657.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  658.    osmesa->pixel = index;
  659. }
  660.  
  661.  
  662.  
  663. static void set_color( GLcontext *ctx,
  664.                        GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  665. {
  666.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  667.    osmesa->pixel = PACK_RGBA( r, g, b, a );
  668. }
  669.  
  670.  
  671.  
  672. static void buffer_size( GLcontext *ctx, GLuint *width, GLuint *height )
  673. {
  674.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  675.    *width = osmesa->width;
  676.    *height = osmesa->height;
  677. }
  678.  
  679.  
  680. /**********************************************************************/
  681. /*****        Read/write spans/arrays of RGBA pixels              *****/
  682. /**********************************************************************/
  683.  
  684. /* Write RGBA pixels to an RGBA (or permuted) buffer. */
  685. static void write_rgba_span( const GLcontext *ctx,
  686.                              GLuint n, GLint x, GLint y,
  687.                              CONST GLubyte rgba[][4], const GLubyte mask[] )
  688. {
  689.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  690.    GLuint *ptr4 = PIXELADDR4( x, y );
  691.    GLuint i;
  692.    GLint rshift = osmesa->rshift;
  693.    GLint gshift = osmesa->gshift;
  694.    GLint bshift = osmesa->bshift;
  695.    GLint ashift = osmesa->ashift;
  696.    if (mask) {
  697.       for (i=0;i<n;i++,ptr4++) {
  698.          if (mask[i]) {
  699.             *ptr4 = PACK_RGBA2( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
  700.          }
  701.       }
  702.    }
  703.    else {
  704.       for (i=0;i<n;i++,ptr4++) {
  705.          *ptr4 = PACK_RGBA2( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
  706.       }
  707.    }
  708. }
  709.  
  710.  
  711. /* Write RGBA pixels to an RGBA buffer.  This is the fastest span-writer. */
  712. static void write_rgba_span_rgba( const GLcontext *ctx,
  713.                                   GLuint n, GLint x, GLint y,
  714.                                   CONST GLubyte rgba[][4],
  715.                                   const GLubyte mask[] )
  716. {
  717.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  718.    GLuint *ptr4 = PIXELADDR4( x, y );
  719.    const GLuint *rgba4 = (const GLuint *) rgba;
  720.    GLuint i;
  721.    if (mask) {
  722.       for (i=0;i<n;i++) {
  723.          if (mask[i]) {
  724.             ptr4[i] = rgba4[i];
  725.          }
  726.       }
  727.    }
  728.    else {
  729.       MEMCPY( ptr4, rgba4, n * 4 );
  730.    }
  731. }
  732.  
  733.  
  734. /* Write RGB pixels to an RGBA (or permuted) buffer. */
  735. static void write_rgb_span( const GLcontext *ctx,
  736.                             GLuint n, GLint x, GLint y,
  737.                             CONST GLubyte rgb[][3], const GLubyte mask[] )
  738. {
  739.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  740.    GLuint *ptr4 = PIXELADDR4( x, y );
  741.    GLuint i;
  742.    GLint rshift = osmesa->rshift;
  743.    GLint gshift = osmesa->gshift;
  744.    GLint bshift = osmesa->bshift;
  745.    GLint ashift = osmesa->ashift;
  746.    if (mask) {
  747.       for (i=0;i<n;i++,ptr4++) {
  748.          if (mask[i]) {
  749.             *ptr4 = PACK_RGBA2( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255 );
  750.          }
  751.       }
  752.    }
  753.    else {
  754.       for (i=0;i<n;i++,ptr4++) {
  755.          *ptr4 = PACK_RGBA2( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255);
  756.       }
  757.    }
  758. }
  759.  
  760.  
  761.  
  762. static void write_monocolor_span( const GLcontext *ctx,
  763.                                   GLuint n, GLint x, GLint y,
  764.                   const GLubyte mask[] )
  765. {
  766.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  767.    GLuint *ptr4 = PIXELADDR4(x,y);
  768.    GLuint i;
  769.    for (i=0;i<n;i++,ptr4++) {
  770.       if (mask[i]) {
  771.          *ptr4 = osmesa->pixel;
  772.       }
  773.    }
  774. }
  775.  
  776.  
  777.  
  778. static void write_rgba_pixels( const GLcontext *ctx,
  779.                                GLuint n, const GLint x[], const GLint y[],
  780.                                CONST GLubyte rgba[][4], const GLubyte mask[] )
  781. {
  782.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  783.    GLuint i;
  784.    GLint rshift = osmesa->rshift;
  785.    GLint gshift = osmesa->gshift;
  786.    GLint bshift = osmesa->bshift;
  787.    GLint ashift = osmesa->ashift;
  788.    for (i=0;i<n;i++) {
  789.       if (mask[i]) {
  790.          GLuint *ptr4 = PIXELADDR4(x[i],y[i]);
  791.          *ptr4 = PACK_RGBA2( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
  792.       }
  793.    }
  794. }
  795.  
  796.  
  797.  
  798. static void write_monocolor_pixels( const GLcontext *ctx,
  799.                                     GLuint n, const GLint x[], const GLint y[],
  800.                     const GLubyte mask[] )
  801. {
  802.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  803.    GLuint i;
  804.    for (i=0;i<n;i++) {
  805.       if (mask[i]) {
  806.          GLuint *ptr4 = PIXELADDR4(x[i],y[i]);
  807.          *ptr4 = osmesa->pixel;
  808.       }
  809.    }
  810. }
  811.  
  812.  
  813. static void read_rgba_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
  814.                              GLubyte rgba[][4] )
  815. {
  816.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  817.    GLuint i;
  818.    GLuint *ptr4 = PIXELADDR4(x,y);
  819.    for (i=0;i<n;i++) {
  820.       GLuint pixel = *ptr4++;
  821.       rgba[i][RCOMP] = UNPACK_RED(pixel);
  822.       rgba[i][GCOMP] = UNPACK_GREEN(pixel);
  823.       rgba[i][BCOMP] = UNPACK_BLUE(pixel);
  824.       rgba[i][ACOMP] = UNPACK_ALPHA(pixel);
  825.    }
  826. }
  827.  
  828.  
  829. /* Read RGBA pixels from an RGBA buffer */
  830. static void read_rgba_span_rgba( const GLcontext *ctx,
  831.                                  GLuint n, GLint x, GLint y,
  832.                                  GLubyte rgba[][4] )
  833. {
  834.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  835.    GLuint *ptr4 = PIXELADDR4(x,y);
  836.    MEMCPY( rgba, ptr4, n * 4 * sizeof(GLubyte) );
  837. }
  838.  
  839.  
  840. static void read_rgba_pixels( const GLcontext *ctx,
  841.                                GLuint n, const GLint x[], const GLint y[],
  842.                    GLubyte rgba[][4], const GLubyte mask[] )
  843. {
  844.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  845.    GLuint i;
  846.    for (i=0;i<n;i++) {
  847.       if (mask[i]) {
  848.          GLuint *ptr4 = PIXELADDR4(x[i],y[i]);
  849.          GLuint pixel = *ptr4;
  850.          rgba[i][RCOMP] = UNPACK_RED(pixel);
  851.          rgba[i][GCOMP] = UNPACK_GREEN(pixel);
  852.          rgba[i][BCOMP] = UNPACK_BLUE(pixel);
  853.          rgba[i][ACOMP] = UNPACK_ALPHA(pixel);
  854.       }
  855.    }
  856. }
  857.  
  858. /**********************************************************************/
  859. /*****                3 byte RGB pixel support funcs              *****/
  860. /**********************************************************************/
  861.  
  862. /* Write RGBA pixels to an RGB or BGR buffer. */
  863. static void write_rgba_span3( const GLcontext *ctx,
  864.                               GLuint n, GLint x, GLint y,
  865.                               CONST GLubyte rgba[][4], const GLubyte mask[] )
  866. {
  867.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  868.    GLubyte *ptr3 = PIXELADDR3( x, y);
  869.    GLuint i;
  870.    GLint rind = osmesa->rind;
  871.    GLint gind = osmesa->gind;
  872.    GLint bind = osmesa->bind;
  873.    if (mask) {
  874.       for (i=0;i<n;i++,ptr3+=3) {
  875.          if (mask[i]) {
  876.             ptr3[rind] = rgba[i][RCOMP];
  877.             ptr3[gind] = rgba[i][GCOMP];
  878.             ptr3[bind] = rgba[i][BCOMP];
  879.          }
  880.       }
  881.    }
  882.    else {
  883.       for (i=0;i<n;i++,ptr3+=3) {
  884.          ptr3[rind] = rgba[i][RCOMP];
  885.          ptr3[gind] = rgba[i][GCOMP];
  886.          ptr3[bind] = rgba[i][BCOMP];
  887.       }
  888.    }
  889. }
  890.  
  891. /* Write RGB pixels to an RGB or BGR buffer. */
  892. static void write_rgb_span3( const GLcontext *ctx,
  893.                              GLuint n, GLint x, GLint y,
  894.                              CONST GLubyte rgb[][3], const GLubyte mask[] )
  895. {
  896.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  897.    GLubyte *ptr3 = PIXELADDR3( x, y);
  898.    GLuint i;
  899.    GLint rind = osmesa->rind;
  900.    GLint gind = osmesa->gind;
  901.    GLint bind = osmesa->bind;
  902.    if (mask) {
  903.       for (i=0;i<n;i++,ptr3+=3) {
  904.          if (mask[i]) {
  905.             ptr3[rind] = rgb[i][RCOMP];
  906.             ptr3[gind] = rgb[i][GCOMP];
  907.             ptr3[bind] = rgb[i][BCOMP];
  908.          }
  909.       }
  910.    }
  911.    else {
  912.       for (i=0;i<n;i++,ptr3+=3) {
  913.          ptr3[rind] = rgb[i][RCOMP];
  914.          ptr3[gind] = rgb[i][GCOMP];
  915.          ptr3[bind] = rgb[i][BCOMP];
  916.       }
  917.    }
  918. }
  919.  
  920.  
  921. static void write_monocolor_span3( const GLcontext *ctx,
  922.                                   GLuint n, GLint x, GLint y,
  923.                   const GLubyte mask[] )
  924. {
  925.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  926.  
  927.    GLubyte rval = UNPACK_RED(osmesa->pixel);
  928.    GLubyte gval = UNPACK_GREEN(osmesa->pixel);
  929.    GLubyte bval = UNPACK_BLUE(osmesa->pixel);
  930.    GLint   rind = osmesa->rind;
  931.    GLint   gind = osmesa->gind;
  932.    GLint   bind = osmesa->bind;
  933.  
  934.  
  935.    GLubyte *ptr3 = PIXELADDR3( x, y);
  936.    GLuint i;
  937.    for (i=0;i<n;i++,ptr3+=3) {
  938.       if (mask[i]) {
  939.          ptr3[rind] = rval;
  940.          ptr3[gind] = gval;
  941.          ptr3[bind] = bval;
  942.       }
  943.    }
  944. }
  945.  
  946. static void write_rgba_pixels3( const GLcontext *ctx,
  947.                                 GLuint n, const GLint x[], const GLint y[],
  948.                                 CONST GLubyte rgba[][4], const GLubyte mask[] )
  949. {
  950.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  951.    GLuint i;
  952.    GLint rind = osmesa->rind;
  953.    GLint gind = osmesa->gind;
  954.    GLint bind = osmesa->bind;
  955.  
  956.    for (i=0;i<n;i++) {
  957.       if (mask[i]) {
  958.          GLubyte *ptr3 = PIXELADDR3(x[i],y[i]);
  959.          ptr3[rind] = rgba[i][RCOMP];
  960.          ptr3[gind] = rgba[i][GCOMP];
  961.          ptr3[bind] = rgba[i][BCOMP];
  962.       }
  963.    }
  964. }
  965.  
  966. static void write_monocolor_pixels3( const GLcontext *ctx,
  967.                                     GLuint n, const GLint x[], const GLint y[],
  968.                     const GLubyte mask[] )
  969. {
  970.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  971.    GLuint i;
  972.    GLint rind = osmesa->rind;
  973.    GLint gind = osmesa->gind;
  974.    GLint bind = osmesa->bind;
  975.    GLubyte rval = UNPACK_RED(osmesa->pixel);
  976.    GLubyte gval = UNPACK_GREEN(osmesa->pixel);
  977.    GLubyte bval = UNPACK_BLUE(osmesa->pixel);
  978.    for (i=0;i<n;i++) {
  979.       if (mask[i]) {
  980.          GLubyte *ptr3 = PIXELADDR3(x[i],y[i]);
  981.          ptr3[rind] = rval;
  982.          ptr3[gind] = gval;
  983.          ptr3[bind] = bval;
  984.       }
  985.    }
  986. }
  987.  
  988. static void read_rgba_span3( const GLcontext *ctx,
  989.                              GLuint n, GLint x, GLint y,
  990.                              GLubyte rgba[][4] )
  991. {
  992.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  993.    GLuint i;
  994.    GLint rind = osmesa->rind;
  995.    GLint gind = osmesa->gind;
  996.    GLint bind = osmesa->bind;
  997.    GLubyte *ptr3 = PIXELADDR3( x, y);
  998.    for (i=0;i<n;i++,ptr3+=3) {
  999.       rgba[i][RCOMP] = ptr3[rind];
  1000.       rgba[i][GCOMP] = ptr3[gind];
  1001.       rgba[i][BCOMP] = ptr3[bind];
  1002.       rgba[i][ACOMP] = 0;
  1003.    }
  1004. }
  1005.  
  1006. static void read_rgba_pixels3( const GLcontext *ctx,
  1007.                                GLuint n, const GLint x[], const GLint y[],
  1008.                    GLubyte rgba[][4], const GLubyte mask[] )
  1009. {
  1010.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1011.    GLuint i;
  1012.    GLint rind = osmesa->rind;
  1013.    GLint gind = osmesa->gind;
  1014.    GLint bind = osmesa->bind;
  1015.    for (i=0;i<n;i++) {
  1016.       if (mask[i]) {
  1017.          GLubyte *ptr3 = PIXELADDR3(x[i],y[i]);
  1018.          rgba[i][RCOMP] = ptr3[rind];
  1019.          rgba[i][GCOMP] = ptr3[gind];
  1020.          rgba[i][BCOMP] = ptr3[bind];
  1021.          rgba[i][ACOMP] = 0;
  1022.       }
  1023.    }
  1024. }
  1025.  
  1026.  
  1027. /**********************************************************************/
  1028. /*****        Read/write spans/arrays of CI pixels                *****/
  1029. /**********************************************************************/
  1030.  
  1031. /* Write 32-bit color index to buffer */
  1032. static void write_index32_span( const GLcontext *ctx,
  1033.                                 GLuint n, GLint x, GLint y,
  1034.                                 const GLuint index[], const GLubyte mask[] )
  1035. {
  1036.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1037.    GLubyte *ptr1 = PIXELADDR1(x,y);
  1038.    GLuint i;
  1039.    if (mask) {
  1040.       for (i=0;i<n;i++,ptr1++) {
  1041.          if (mask[i]) {
  1042.             *ptr1 = (GLubyte) index[i];
  1043.          }
  1044.       }
  1045.    }
  1046.    else {
  1047.       for (i=0;i<n;i++,ptr1++) {
  1048.          *ptr1 = (GLubyte) index[i];
  1049.       }
  1050.    }
  1051. }
  1052.  
  1053.  
  1054. /* Write 8-bit color index to buffer */
  1055. static void write_index8_span( const GLcontext *ctx,
  1056.                                GLuint n, GLint x, GLint y,
  1057.                                const GLubyte index[], const GLubyte mask[] )
  1058. {
  1059.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1060.    GLubyte *ptr1 = PIXELADDR1(x,y);
  1061.    GLuint i;
  1062.    if (mask) {
  1063.       for (i=0;i<n;i++,ptr1++) {
  1064.          if (mask[i]) {
  1065.             *ptr1 = (GLubyte) index[i];
  1066.          }
  1067.       }
  1068.    }
  1069.    else {
  1070.       MEMCPY( ptr1, index, n );
  1071.    }
  1072. }
  1073.  
  1074.  
  1075. static void write_monoindex_span( const GLcontext *ctx,
  1076.                                   GLuint n, GLint x, GLint y,
  1077.                   const GLubyte mask[] )
  1078. {
  1079.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1080.    GLubyte *ptr1 = PIXELADDR1(x,y);
  1081.    GLuint i;
  1082.    for (i=0;i<n;i++,ptr1++) {
  1083.       if (mask[i]) {
  1084.          *ptr1 = (GLubyte) osmesa->pixel;
  1085.       }
  1086.    }
  1087. }
  1088.  
  1089.  
  1090. static void write_index_pixels( const GLcontext *ctx,
  1091.                                 GLuint n, const GLint x[], const GLint y[],
  1092.                     const GLuint index[], const GLubyte mask[] )
  1093. {
  1094.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1095.    GLuint i;
  1096.    for (i=0;i<n;i++) {
  1097.       if (mask[i]) {
  1098.          GLubyte *ptr1 = PIXELADDR1(x[i],y[i]);
  1099.          *ptr1 = (GLubyte) index[i];
  1100.       }
  1101.    }
  1102. }
  1103.  
  1104.  
  1105. static void write_monoindex_pixels( const GLcontext *ctx,
  1106.                                     GLuint n, const GLint x[], const GLint y[],
  1107.                     const GLubyte mask[] )
  1108. {
  1109.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1110.    GLuint i;
  1111.    for (i=0;i<n;i++) {
  1112.       if (mask[i]) {
  1113.          GLubyte *ptr1 = PIXELADDR1(x[i],y[i]);
  1114.          *ptr1 = (GLubyte) osmesa->pixel;
  1115.       }
  1116.    }
  1117. }
  1118.  
  1119.  
  1120. static void read_index_span( const GLcontext *ctx,
  1121.                              GLuint n, GLint x, GLint y, GLuint index[] )
  1122. {
  1123.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1124.    GLuint i;
  1125.    GLubyte *ptr1 = PIXELADDR1(x,y);
  1126.    for (i=0;i<n;i++,ptr1++) {
  1127.       index[i] = (GLuint) *ptr1;
  1128.    }
  1129. }
  1130.  
  1131.  
  1132. static void read_index_pixels( const GLcontext *ctx,
  1133.                                GLuint n, const GLint x[], const GLint y[],
  1134.                    GLuint index[], const GLubyte mask[] )
  1135. {
  1136.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1137.    GLuint i;
  1138.    for (i=0;i<n;i++) {
  1139.       if (mask[i] ) {
  1140.          GLubyte *ptr1 = PIXELADDR1(x[i],y[i]);
  1141.          index[i] = (GLuint) *ptr1;
  1142.       }
  1143.    }
  1144. }
  1145.  
  1146.  
  1147.  
  1148. /**********************************************************************/
  1149. /*****                   Optimized line rendering                 *****/
  1150. /**********************************************************************/
  1151.  
  1152.  
  1153. /*
  1154.  * Draw a flat-shaded, RGB line into an osmesa buffer.
  1155.  */
  1156. static void flat_rgba_line( GLcontext *ctx,
  1157.                             GLuint vert0, GLuint vert1, GLuint pvert )
  1158. {
  1159.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1160.    GLubyte *color = ctx->VB->ColorPtr->data[pvert];
  1161.    unsigned long pixel = PACK_RGBA( color[0], color[1], color[2], color[3] );
  1162.  
  1163. #define INTERP_XY 1
  1164. #define CLIP_HACK 1
  1165. #define PLOT(X,Y) { GLuint *ptr4 = PIXELADDR4(X,Y); *ptr4 = pixel; }
  1166.  
  1167. #ifdef WIN32
  1168. #include "..\linetemp.h"
  1169. #else
  1170. #include "linetemp.h"
  1171. #endif
  1172. }
  1173.  
  1174.  
  1175. /*
  1176.  * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer.
  1177.  */
  1178. static void flat_rgba_z_line( GLcontext *ctx,
  1179.                               GLuint vert0, GLuint vert1, GLuint pvert )
  1180. {
  1181.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1182.    GLubyte *color = ctx->VB->ColorPtr->data[pvert];
  1183.    unsigned long pixel = PACK_RGBA( color[0], color[1], color[2], color[3] );
  1184.  
  1185. #define INTERP_XY 1
  1186. #define INTERP_Z 1
  1187. #define CLIP_HACK 1
  1188. #define PLOT(X,Y)                \
  1189.     if (Z < *zPtr) {            \
  1190.        GLuint *ptr4 = PIXELADDR4(X,Y);    \
  1191.        *ptr4 = pixel;            \
  1192.        *zPtr = Z;                \
  1193.     }
  1194.  
  1195. #ifdef WIN32
  1196. #include "..\linetemp.h"
  1197. #else
  1198. #include "linetemp.h"
  1199. #endif
  1200. }
  1201.  
  1202.  
  1203. /*
  1204.  * Draw a flat-shaded, alpha-blended, RGB line into an osmesa buffer.
  1205.  */
  1206. static void flat_blend_rgba_line( GLcontext *ctx,
  1207.                                   GLuint vert0, GLuint vert1, GLuint pvert )
  1208. {
  1209.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1210.    struct vertex_buffer *VB = ctx->VB;
  1211.    GLint rshift = osmesa->rshift;
  1212.    GLint gshift = osmesa->gshift;
  1213.    GLint bshift = osmesa->bshift;
  1214.    GLint avalue = VB->ColorPtr->data[pvert][3];
  1215.    GLint msavalue = 255 - avalue;
  1216.    GLint rvalue = VB->ColorPtr->data[pvert][0]*avalue;
  1217.    GLint gvalue = VB->ColorPtr->data[pvert][1]*avalue;
  1218.    GLint bvalue = VB->ColorPtr->data[pvert][2]*avalue;
  1219.  
  1220. #define INTERP_XY 1
  1221. #define CLIP_HACK 1
  1222. #define PLOT(X,Y)                    \
  1223.    { GLuint *ptr4 = PIXELADDR4(X,Y); \
  1224.      GLuint  pixel = 0; \
  1225.      pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
  1226.      pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
  1227.      pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
  1228.      *ptr4 = pixel; \
  1229.    }
  1230.  
  1231. #ifdef WIN32
  1232. #include "..\linetemp.h"
  1233. #else
  1234. #include "linetemp.h"
  1235. #endif
  1236. }
  1237.  
  1238. /*
  1239.  * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
  1240.  */
  1241. static void flat_blend_rgba_z_line( GLcontext *ctx,
  1242.                                    GLuint vert0, GLuint vert1, GLuint pvert )
  1243. {
  1244.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1245.    struct vertex_buffer *VB = ctx->VB;
  1246.    GLint rshift = osmesa->rshift;
  1247.    GLint gshift = osmesa->gshift;
  1248.    GLint bshift = osmesa->bshift;
  1249.    GLint avalue = VB->ColorPtr->data[pvert][3];
  1250.    GLint msavalue = 256 - avalue;
  1251.    GLint rvalue = VB->ColorPtr->data[pvert][0]*avalue;
  1252.    GLint gvalue = VB->ColorPtr->data[pvert][1]*avalue;
  1253.    GLint bvalue = VB->ColorPtr->data[pvert][2]*avalue;
  1254.  
  1255. #define INTERP_XY 1
  1256. #define INTERP_Z 1
  1257. #define CLIP_HACK 1
  1258. #define PLOT(X,Y)                \
  1259.     if (Z < *zPtr) {            \
  1260.    { GLuint *ptr4 = PIXELADDR4(X,Y); \
  1261.      GLuint  pixel = 0; \
  1262.      pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
  1263.      pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
  1264.      pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
  1265.      *ptr4 = pixel; \
  1266.    } \
  1267.     }
  1268.  
  1269. #ifdef WIN32
  1270. #include "..\linetemp.h"
  1271. #else
  1272. #include "linetemp.h"
  1273. #endif
  1274. }
  1275.  
  1276. /*
  1277.  * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
  1278.  */
  1279. static void flat_blend_rgba_z_line_write( GLcontext *ctx,
  1280.                                    GLuint vert0, GLuint vert1, GLuint pvert )
  1281. {
  1282.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1283.    struct vertex_buffer *VB = ctx->VB;
  1284.    GLint rshift = osmesa->rshift;
  1285.    GLint gshift = osmesa->gshift;
  1286.    GLint bshift = osmesa->bshift;
  1287.    GLint avalue = VB->ColorPtr->data[pvert][3];
  1288.    GLint msavalue = 256 - avalue;
  1289.    GLint rvalue = VB->ColorPtr->data[pvert][0]*avalue;
  1290.    GLint gvalue = VB->ColorPtr->data[pvert][1]*avalue;
  1291.    GLint bvalue = VB->ColorPtr->data[pvert][2]*avalue;
  1292.  
  1293. #define INTERP_XY 1
  1294. #define INTERP_Z 1
  1295. #define CLIP_HACK 1
  1296. #define PLOT(X,Y)                \
  1297.     if (Z < *zPtr) {            \
  1298.    { GLuint *ptr4 = PIXELADDR4(X,Y); \
  1299.      GLuint  pixel = 0; \
  1300.      pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
  1301.      pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
  1302.      pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
  1303.      *ptr4 = pixel; \
  1304.    } \
  1305.        *zPtr = Z;                \
  1306.     }
  1307.  
  1308. #ifdef WIN32
  1309. #include "..\linetemp.h"
  1310. #else
  1311. #include "linetemp.h"
  1312. #endif
  1313. }
  1314.  
  1315.  
  1316. /*
  1317.  * Analyze context state to see if we can provide a fast line drawing
  1318.  * function, like those in lines.c.  Otherwise, return NULL.
  1319.  */
  1320. static line_func choose_line_function( GLcontext *ctx )
  1321. {
  1322.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1323.  
  1324.    if (ctx->Line.SmoothFlag)              return NULL;
  1325.    if (ctx->Texture.Enabled)              return NULL;
  1326.    if (ctx->Light.ShadeModel!=GL_FLAT)    return NULL;
  1327.  
  1328.    if (ctx->Line.Width==1.0F
  1329.        && ctx->Line.StippleFlag==GL_FALSE) {
  1330.  
  1331.        if (ctx->RasterMask==DEPTH_BIT
  1332.            && ctx->Depth.Func==GL_LESS
  1333.            && ctx->Depth.Mask==GL_TRUE) {
  1334.            switch(osmesa->format) {
  1335.                case OSMESA_RGBA:
  1336.                case OSMESA_BGRA:
  1337.                case OSMESA_ARGB:
  1338.                    return flat_rgba_z_line;
  1339.                default:
  1340.                    return NULL;
  1341.            }
  1342.        }
  1343.  
  1344.        if (ctx->RasterMask==0) {
  1345.            switch(osmesa->format) {
  1346.                case OSMESA_RGBA:
  1347.                case OSMESA_BGRA:
  1348.                case OSMESA_ARGB:
  1349.                    return flat_rgba_line;
  1350.                default:
  1351.                    return NULL;
  1352.            }
  1353.        }
  1354.  
  1355.        if (ctx->RasterMask==(DEPTH_BIT|BLEND_BIT)
  1356.            && ctx->Depth.Func==GL_LESS
  1357.            && ctx->Depth.Mask==GL_TRUE
  1358.            && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
  1359.            && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
  1360.            && ctx->Color.BlendSrcA==GL_SRC_ALPHA
  1361.            && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
  1362.            && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
  1363.            switch(osmesa->format) {
  1364.                case OSMESA_RGBA:
  1365.                case OSMESA_BGRA:
  1366.                case OSMESA_ARGB:
  1367.                    return flat_blend_rgba_z_line_write;
  1368.                default:
  1369.                    return NULL;
  1370.            }
  1371.        }
  1372.  
  1373.        if (ctx->RasterMask==(DEPTH_BIT|BLEND_BIT)
  1374.            && ctx->Depth.Func==GL_LESS
  1375.            && ctx->Depth.Mask==GL_FALSE
  1376.            && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
  1377.            && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
  1378.            && ctx->Color.BlendSrcA==GL_SRC_ALPHA
  1379.            && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
  1380.            && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
  1381.            switch(osmesa->format) {
  1382.                case OSMESA_RGBA:
  1383.                case OSMESA_BGRA:
  1384.                case OSMESA_ARGB:
  1385.                    return flat_blend_rgba_z_line;
  1386.                default:
  1387.                    return NULL;
  1388.            }
  1389.        }
  1390.  
  1391.        if (ctx->RasterMask==BLEND_BIT
  1392.            && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
  1393.            && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
  1394.            && ctx->Color.BlendSrcA==GL_SRC_ALPHA
  1395.            && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
  1396.            && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
  1397.            switch(osmesa->format) {
  1398.                case OSMESA_RGBA:
  1399.                case OSMESA_BGRA:
  1400.                case OSMESA_ARGB:
  1401.                    return flat_blend_rgba_line;
  1402.                default:
  1403.                    return NULL;
  1404.            }
  1405.        }
  1406.  
  1407.    }
  1408.    return NULL;
  1409. }
  1410.  
  1411.  
  1412. /**********************************************************************/
  1413. /*****                 Optimized triangle rendering               *****/
  1414. /**********************************************************************/
  1415.  
  1416.  
  1417. /*
  1418.  * Smooth-shaded, z-less triangle, RGBA color.
  1419.  */
  1420. static void smooth_rgba_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1421.                                     GLuint v2, GLuint pv )
  1422. {
  1423.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1424.    GLint rshift = osmesa->rshift;
  1425.    GLint gshift = osmesa->gshift;
  1426.    GLint bshift = osmesa->bshift;
  1427.    GLint ashift = osmesa->ashift;
  1428.    (void) pv;
  1429. #define INTERP_Z 1
  1430. #define INTERP_RGB 1
  1431. #define INTERP_ALPHA 1
  1432. #define INNER_LOOP( LEFT, RIGHT, Y )                \
  1433. {                                \
  1434.    GLint i, len = RIGHT-LEFT;                    \
  1435.    GLuint *img = PIXELADDR4(LEFT,Y);                   \
  1436.    for (i=0;i<len;i++,img++) {                    \
  1437.       GLdepth z = FixedToDepth(ffz);                \
  1438.       if (z < zRow[i]) {                    \
  1439.          *img = PACK_RGBA2( FixedToInt(ffr), FixedToInt(ffg),    \
  1440.                     FixedToInt(ffb), FixedToInt(ffa) );    \
  1441.          zRow[i] = z;                        \
  1442.       }                                \
  1443.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;  ffa += fdadx;\
  1444.       ffz += fdzdx;                        \
  1445.    }                                \
  1446. }
  1447. #ifdef WIN32
  1448. #include "..\tritemp.h"
  1449. #else
  1450. #include "tritemp.h"
  1451. #endif
  1452. }
  1453.  
  1454.  
  1455.  
  1456.  
  1457. /*
  1458.  * Flat-shaded, z-less triangle, RGBA color.
  1459.  */
  1460. static void flat_rgba_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1461.                                    GLuint v2, GLuint pv )
  1462. {
  1463.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1464. #define INTERP_Z 1
  1465. #define SETUP_CODE            \
  1466.    GLubyte r = VB->ColorPtr->data[pv][0];    \
  1467.    GLubyte g = VB->ColorPtr->data[pv][1];    \
  1468.    GLubyte b = VB->ColorPtr->data[pv][2];    \
  1469.    GLubyte a = VB->ColorPtr->data[pv][3];    \
  1470.    GLuint pixel = PACK_RGBA(r,g,b,a);
  1471.  
  1472. #define INNER_LOOP( LEFT, RIGHT, Y )    \
  1473. {                    \
  1474.    GLint i, len = RIGHT-LEFT;        \
  1475.    GLuint *img = PIXELADDR4(LEFT,Y);       \
  1476.    for (i=0;i<len;i++,img++) {        \
  1477.       GLdepth z = FixedToDepth(ffz);    \
  1478.       if (z < zRow[i]) {        \
  1479.          *img = pixel;            \
  1480.          zRow[i] = z;            \
  1481.       }                    \
  1482.       ffz += fdzdx;            \
  1483.    }                    \
  1484. }
  1485. #ifdef WIN32
  1486. #include "..\tritemp.h"
  1487. #else
  1488. #include "tritemp.h"
  1489. #endif
  1490. }
  1491.  
  1492.  
  1493.  
  1494. /*
  1495.  * Return pointer to an accelerated triangle function if possible.
  1496.  */
  1497. static triangle_func choose_triangle_function( GLcontext *ctx )
  1498. {
  1499.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1500.  
  1501.    if ((osmesa->format==OSMESA_RGB)||(osmesa->format==OSMESA_BGR)) return NULL;
  1502.  
  1503.    if (ctx->Polygon.SmoothFlag)     return NULL;
  1504.    if (ctx->Polygon.StippleFlag)    return NULL;
  1505.    if (ctx->Texture.Enabled)        return NULL;
  1506.  
  1507.    if (ctx->RasterMask==DEPTH_BIT
  1508.        && ctx->Depth.Func==GL_LESS
  1509.        && ctx->Depth.Mask==GL_TRUE
  1510.        && osmesa->format!=OSMESA_COLOR_INDEX) {
  1511.       if (ctx->Light.ShadeModel==GL_SMOOTH) {
  1512.          return smooth_rgba_z_triangle;
  1513.       }
  1514.       else {
  1515.          return flat_rgba_z_triangle;
  1516.       }
  1517.    }
  1518.    return NULL;
  1519. }
  1520.  
  1521.  
  1522.  
  1523. static const GLubyte *get_string( GLcontext *ctx, GLenum name )
  1524. {
  1525.    (void) ctx;
  1526.    switch (name) {
  1527.       case GL_RENDERER:
  1528.          return (const GLubyte *) "Mesa OffScreen";
  1529.       default:
  1530.          return NULL;
  1531.    }
  1532. }
  1533.  
  1534.  
  1535. static void osmesa_update_state( GLcontext *ctx )
  1536. {
  1537.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1538.  
  1539.    ctx->Driver.GetString = get_string;
  1540.    ctx->Driver.UpdateState = osmesa_update_state;
  1541.  
  1542.    ctx->Driver.SetBuffer = set_buffer;
  1543.    ctx->Driver.Color = set_color;
  1544.    ctx->Driver.Index = set_index;
  1545.    ctx->Driver.ClearIndex = clear_index;
  1546.    ctx->Driver.ClearColor = clear_color;
  1547.    ctx->Driver.Clear = clear;
  1548.  
  1549.    ctx->Driver.GetBufferSize = buffer_size;
  1550.  
  1551.    ctx->Driver.PointsFunc = NULL;
  1552.    ctx->Driver.LineFunc = choose_line_function( ctx );
  1553.    ctx->Driver.TriangleFunc = choose_triangle_function( ctx );
  1554.  
  1555.  
  1556.    /* RGB(A) span/pixel functions */
  1557.    if ((osmesa->format==OSMESA_RGB) || (osmesa->format==OSMESA_BGR)) {
  1558.       /* 3 bytes / pixel in frame buffer */
  1559.       ctx->Driver.WriteRGBASpan = write_rgba_span3;
  1560.       ctx->Driver.WriteRGBSpan = write_rgb_span3;
  1561.       ctx->Driver.WriteRGBAPixels = write_rgba_pixels3;
  1562.       ctx->Driver.WriteMonoRGBASpan = write_monocolor_span3;
  1563.       ctx->Driver.WriteMonoRGBAPixels = write_monocolor_pixels3;
  1564.       ctx->Driver.ReadRGBASpan = read_rgba_span3;
  1565.       ctx->Driver.ReadRGBAPixels = read_rgba_pixels3;
  1566.    }
  1567.    else {
  1568.       /* 4 bytes / pixel in frame buffer */
  1569.       if (osmesa->format==OSMESA_RGBA
  1570.           && RCOMP==0 && GCOMP==1 && BCOMP==2 && ACOMP==3)
  1571.          ctx->Driver.WriteRGBASpan = write_rgba_span_rgba;
  1572.       else
  1573.          ctx->Driver.WriteRGBASpan = write_rgba_span;
  1574.       ctx->Driver.WriteRGBSpan = write_rgb_span;
  1575.       ctx->Driver.WriteRGBAPixels = write_rgba_pixels;
  1576.       ctx->Driver.WriteMonoRGBASpan = write_monocolor_span;
  1577.       ctx->Driver.WriteMonoRGBAPixels = write_monocolor_pixels;
  1578.       if (osmesa->format==OSMESA_RGBA
  1579.           && RCOMP==0 && GCOMP==1 && BCOMP==2 && ACOMP==3)
  1580.          ctx->Driver.ReadRGBASpan = read_rgba_span_rgba;
  1581.       else
  1582.          ctx->Driver.ReadRGBASpan = read_rgba_span;
  1583.       ctx->Driver.ReadRGBAPixels = read_rgba_pixels;
  1584.    }
  1585.  
  1586.    /* CI span/pixel functions */
  1587.    ctx->Driver.WriteCI32Span = write_index32_span;
  1588.    ctx->Driver.WriteCI8Span = write_index8_span;
  1589.    ctx->Driver.WriteMonoCISpan = write_monoindex_span;
  1590.    ctx->Driver.WriteCI32Pixels = write_index_pixels;
  1591.    ctx->Driver.WriteMonoCIPixels = write_monoindex_pixels;
  1592.    ctx->Driver.ReadCI32Span = read_index_span;
  1593.    ctx->Driver.ReadCI32Pixels = read_index_pixels;
  1594. }
  1595.