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

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