home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / mesa-1.2.8 / src / osmesa.c < prev    next >
C/C++ Source or Header  |  1996-05-27  |  18KB  |  740 lines

  1. /* $Id: osmesa.c,v 1.8 1996/04/25 20:43:15 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  1.2
  6.  * Copyright (C) 1995-1996  Brian Paul  (brianp@ssec.wisc.edu)
  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.8  1996/04/25  20:43:15  brianp
  27.  * removed optional, unimplemented DD functions
  28.  *
  29.  * Revision 1.7  1996/03/22  20:54:47  brianp
  30.  * replaced CC.ClipSpans with WINCLIP_BIT RasterMask flag
  31.  *
  32.  * Revision 1.6  1996/01/22  21:07:42  brianp
  33.  * used PIXELADDR macros instead of OFFSET macro
  34.  * added a few accelerated polygon drawing functions
  35.  *
  36.  * Revision 1.5  1995/11/03  17:40:00  brianp
  37.  * added casts for C++ compilation
  38.  *
  39.  * Revision 1.4  1995/10/30  15:32:58  brianp
  40.  * added mask argument to read_[color|index]_pixels functions
  41.  *
  42.  * Revision 1.3  1995/10/19  15:49:06  brianp
  43.  * changed clear_color and set_color arguments to GLubytes
  44.  * changed arguments to gl_new_context
  45.  *
  46.  * Revision 1.2  1995/10/13  22:41:58  brianp
  47.  * renamed index to set_index and color to set_color
  48.  * make index_mask and color_mask return GL_FALSE
  49.  *
  50.  * Revision 1.1  1995/10/12  17:00:03  brianp
  51.  * Initial revision
  52.  *
  53.  */
  54.  
  55.  
  56.  
  57. /*
  58.  * Off-Screen Mesa rendering / Rendering into client memory space
  59.  */
  60.  
  61.  
  62. #include <stdlib.h>
  63. #include <string.h>
  64. #include "GL/osmesa.h"
  65. #include "context.h"
  66. #include "dd.h"
  67. #include "depth.h"
  68. #include "macros.h"
  69. #include "vb.h"
  70. #include "xform.h"
  71.  
  72.  
  73. struct osmesa_context {
  74.    struct gl_context *gl_ctx;    /* The GL/Mesa context */
  75.    GLenum format;        /* either GL_RGBA or GL_COLOR_INDEX */
  76.    void *buffer;        /* the image buffer */
  77.    GLint width, height;        /* size of image buffer */
  78.    GLuint pixel;        /* current color index or RGBA pixel value */
  79.    GLuint clearpixel;        /* pixel for clearing the color buffer */
  80. };
  81.  
  82.  
  83.  
  84. static OSMesaContext Current = NULL;
  85.  
  86. static void osmesa_setup_DD_pointers( void );
  87.  
  88.  
  89.  
  90. /*
  91.  * Create an Off-Screen Mesa rendering context.  The only attribute needed is
  92.  * an RGBA vs Color-Index mode flag.
  93.  *
  94.  * Input:  format - either GL_RGBA or GL_COLOR_INDEX
  95.  *         sharelist - specifies another OSMesaContext with which to share
  96.  *                     display lists.  NULL indicates no sharing.
  97.  * Return:  an OSMesaContext or 0 if error
  98.  */
  99. OSMesaContext OSMesaCreateContext( GLenum format, OSMesaContext sharelist )
  100. {
  101.    OSMesaContext ctx;
  102.  
  103.    if (format!=GL_RGBA && format!=GL_COLOR_INDEX) {
  104.       return NULL;
  105.    }
  106.  
  107.    ctx = (OSMesaContext) malloc( sizeof(struct osmesa_context) );
  108.    if (ctx) {
  109.       ctx->gl_ctx = gl_new_context( (format==GL_RGBA) ? GL_TRUE : GL_FALSE,
  110.                                     255.0, 255.0, 255.0, 255.0,
  111.                                     GL_FALSE,
  112.                                     sharelist ? sharelist->gl_ctx : NULL );
  113.       if (!ctx->gl_ctx) {
  114.          free(ctx);
  115.          return NULL;
  116.       }
  117.       ctx->format = format;
  118.       ctx->buffer = NULL;
  119.       ctx->width = 0;
  120.       ctx->height = 0;
  121.       ctx->pixel = 0;
  122.       ctx->clearpixel = 0;
  123.    }
  124.    return ctx;
  125. }
  126.  
  127.  
  128.  
  129. /*
  130.  * Destroy an Off-Screen Mesa rendering context.
  131.  *
  132.  * Input:  ctx - the context to destroy
  133.  */
  134. void OSMesaDestroyContext( OSMesaContext ctx )
  135. {
  136.    if (ctx) {
  137.       gl_destroy_context( ctx->gl_ctx );
  138.       free( ctx );
  139.    }
  140. }
  141.  
  142.  
  143.  
  144. /*
  145.  * Bind an OSMesaContext to an image buffer.  The image buffer is just a
  146.  * block of memory which the client provides.  Its size must be at least
  147.  * as large as width*height*sizeof(type).  Its address should be a multiple
  148.  * of 4 if using RGBA mode.
  149.  *
  150.  * Image data is stored in the order of glDrawPixels:  row-major order
  151.  * with the lower-left image pixel stored in the first array position
  152.  * (ie. bottom-to-top).
  153.  *
  154.  * Since the only type initially supported is GL_UNSIGNED_BYTE, if the
  155.  * context is in RGBA mode, each pixel will be stored as a 4-byte RGBA
  156.  * value.  If the context is in color indexed mode, each pixel will be
  157.  * stored as a 1-byte value.
  158.  *
  159.  * If the context's viewport hasn't been initialized yet, it will now be
  160.  * initialized to (0,0,width,height).
  161.  *
  162.  * Input:  ctx - the rendering context
  163.  *         buffer - the image buffer memory
  164.  *         type - data type for pixel components, only GL_UNSIGNED_BYTE
  165.  *                supported now
  166.  *         width, height - size of image buffer in pixels, at least 1
  167.  * Return:  GL_TRUE if success, GL_FALSE if error because of invalid ctx,
  168.  *          invalid buffer address, type!=GL_UNSIGNED_BYTE, width<1, height<1,
  169.  *          width>internal limit or height>internal limit.
  170.  */
  171. GLboolean OSMesaMakeCurrent( OSMesaContext ctx, void *buffer, GLenum type,
  172.                              GLsizei width, GLsizei height )
  173. {
  174.    if (!ctx || !buffer || type!=GL_UNSIGNED_BYTE
  175.        || width<1 || height<1 || width>MAX_WIDTH || height>MAX_HEIGHT) {
  176.       return GL_FALSE;
  177.    }
  178.  
  179.    gl_set_context( ctx->gl_ctx );
  180.  
  181.    ctx->buffer = buffer;
  182.    ctx->width = width;
  183.    ctx->height = height;
  184.  
  185.    osmesa_setup_DD_pointers();
  186.  
  187.    Current = ctx;
  188.  
  189.    /* init viewport */
  190.    if (ctx->gl_ctx->Viewport.Width==0) {
  191.       /* initialize viewport and scissor box to buffer size */
  192.       gl_viewport( 0, 0, width, height );
  193.       CC.Scissor.X = 0;
  194.       CC.Scissor.Y = 0;
  195.       CC.Scissor.Width = width;
  196.       CC.Scissor.Height = height;
  197.    }
  198.  
  199.    return GL_TRUE;
  200. }
  201.  
  202.  
  203.  
  204.  
  205. /**********************************************************************/
  206. /*** Device Driver Functions                                        ***/
  207. /**********************************************************************/
  208.  
  209.  
  210. /*
  211.  * Useful macros:
  212.  */
  213. #define PACK_RGBA(R,G,B,A)  (((R) << 24) | ((G) << 16) | ((B) << 8) | (A))
  214. #define PACK_ABGR(R,G,B,A)  (((A) << 24) | ((B) << 16) | ((G) << 8) | (R))
  215.  
  216. #define PIXELADDR1(X,Y)  ((GLubyte *) Current->buffer + (Y)*Current->width + (X))
  217. #define PIXELADDR4(X,Y)   ((GLuint *) Current->buffer + (Y)*Current->width + (X))
  218. #define PIXELADDR4B(X,Y)  ((GLubyte *) Current->buffer + ((Y)*Current->width + (X))*4)
  219.  
  220.  
  221.  
  222.  
  223. static GLboolean set_buffer( GLenum mode )
  224. {
  225.    if (mode==GL_FRONT) {
  226.       return GL_TRUE;
  227.    }
  228.    else {
  229.       return GL_FALSE;
  230.    }
  231. }
  232.  
  233.  
  234. static void clear_index( GLuint index )
  235. {
  236.    Current->clearpixel = index;
  237. }
  238.  
  239.  
  240.  
  241. static void clear_color( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  242. {
  243.    /* This trick facilitates big & little endian */
  244.    GLubyte *clr = (GLubyte *) &Current->clearpixel;
  245.    clr[0] = r;
  246.    clr[1] = g;
  247.    clr[2] = b;
  248.    clr[3] = a;
  249. }
  250.  
  251.  
  252.  
  253. static void clear( GLboolean all, GLint x, GLint y, GLint width, GLint height )
  254. {
  255.    if (Current->format==GL_RGBA) {
  256.       if (all) {
  257.          /* Clear whole RGBA buffer */
  258.          GLuint i, n, *ptr4;
  259.          n = Current->width * Current->height;
  260.          ptr4 = (GLuint *) Current->buffer;
  261.          for (i=0;i<n;i++) {
  262.             *ptr4++ = Current->clearpixel;
  263.          }
  264.       }
  265.       else {
  266.          /* Clear part of RGBA buffer */
  267.          GLuint i, j;
  268.          for (i=0;i<height;i++) {
  269.             GLuint *ptr4 = PIXELADDR4( x, (y+i) );
  270.             for (j=0;j<width;j++) {
  271.                *ptr4++ = Current->clearpixel;
  272.             }
  273.          }
  274.       }
  275.    }
  276.    else {
  277.       if (all) {
  278.          /* Clear whole CI buffer */
  279.          MEMSET(Current->buffer, Current->clearpixel, Current->width*Current->height);
  280.       }
  281.       else {
  282.          /* Clear part of CI buffer */
  283.          GLuint i, j;
  284.          for (i=0;i<height;i++) {
  285.             GLubyte *ptr1 = PIXELADDR1( x, (y+i) );
  286.             for (j=0;j<width;j++) {
  287.                *ptr1++ = Current->clearpixel;
  288.             }
  289.          }
  290.       }
  291.    }
  292. }
  293.  
  294.  
  295.  
  296. static void set_index( GLuint index )
  297. {
  298.    Current->pixel = index;
  299. }
  300.  
  301.  
  302.  
  303. static void set_color( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  304. {
  305.    /* This trick facilitates big & little endian */
  306.    GLubyte *clr = (GLubyte *) &Current->pixel;
  307.    clr[0] = r;
  308.    clr[1] = g;
  309.    clr[2] = b;
  310.    clr[3] = a;
  311. }
  312.  
  313.  
  314.  
  315. static void buffer_size( GLuint *width, GLuint *height, GLuint *depth )
  316. {
  317.    *width = Current->width;
  318.    *height = Current->height;
  319.    *depth = 8;
  320. }
  321.  
  322.  
  323.  
  324. static void write_RGBA_span( GLuint n, GLint x, GLint y,
  325.                              const GLubyte red[], const GLubyte green[],
  326.                  const GLubyte blue[], const GLubyte alpha[],
  327.                  const GLubyte mask[] )
  328. {
  329.    GLuint *ptr4 = PIXELADDR4( x, y );
  330.    GLuint i;
  331.    if (mask) {
  332.       for (i=0;i<n;i++,ptr4++) {
  333.          if (mask[i]) {
  334.             *ptr4 = PACK_RGBA( red[i], green[i], blue[i], alpha[i] );
  335.          }
  336.       }
  337.    }
  338.    else {
  339.       for (i=0;i<n;i++,ptr4++) {
  340.          *ptr4 = PACK_RGBA( red[i], green[i], blue[i], alpha[i] );
  341.       }
  342.    }
  343. }
  344.  
  345.  
  346.  
  347. static void write_ABGR_span( GLuint n, GLint x, GLint y,
  348.                  const GLubyte red[], const GLubyte green[],
  349.                              const GLubyte blue[], const GLubyte alpha[],
  350.                  const GLubyte mask[] )
  351. {
  352.    GLuint *ptr4 = PIXELADDR4(x,y);
  353.    GLuint i;
  354.    if (mask) {
  355.       for (i=0;i<n;i++,ptr4++) {
  356.          if (mask[i]) {
  357.             *ptr4 = PACK_ABGR( red[i], green[i], blue[i], alpha[i] );
  358.          }
  359.       }
  360.    }
  361.    else {
  362.       for (i=0;i<n;i++,ptr4++) {
  363.          *ptr4 = PACK_ABGR( red[i], green[i], blue[i], alpha[i] );
  364.       }
  365.    }
  366. }
  367.  
  368.  
  369.  
  370. static void write_monocolor_span( GLuint n, GLint x, GLint y,
  371.                   const GLubyte mask[] )
  372. {
  373.    GLuint *ptr4 = PIXELADDR4(x,y);
  374.    GLuint i;
  375.    for (i=0;i<n;i++,ptr4++) {
  376.       if (mask[i]) {
  377.          *ptr4 = Current->pixel;
  378.       }
  379.    }
  380. }
  381.  
  382.  
  383.  
  384. static void write_RGBA_pixels( GLuint n, const GLint x[], const GLint y[],
  385.                                const GLubyte red[], const GLubyte green[],
  386.                    const GLubyte blue[], const GLubyte alpha[],
  387.                    const GLubyte mask[] )
  388. {
  389.    GLuint i;
  390.    for (i=0;i<n;i++) {
  391.       if (mask[i]) {
  392.          GLuint *ptr4 = PIXELADDR4(x[i],y[i]);
  393.          *ptr4 = PACK_RGBA( red[i], green[i], blue[i], alpha[i] );
  394.       }
  395.    }
  396. }
  397.  
  398.  
  399.  
  400. static void write_ABGR_pixels( GLuint n, const GLint x[], const GLint y[],
  401.                                const GLubyte red[], const GLubyte green[],
  402.                    const GLubyte blue[], const GLubyte alpha[],
  403.                    const GLubyte mask[] )
  404. {
  405.    GLuint i;
  406.    for (i=0;i<n;i++) {
  407.       if (mask[i]) {
  408.          GLuint *ptr4 = PIXELADDR4(x[i],y[i]);
  409.          *ptr4 = PACK_ABGR( red[i], green[i], blue[i], alpha[i] );
  410.       }
  411.    }
  412. }
  413.  
  414.  
  415.  
  416. static void write_monocolor_pixels( GLuint n, const GLint x[], const GLint y[],
  417.                     const GLubyte mask[] )
  418. {
  419.    GLuint i;
  420.    for (i=0;i<n;i++) {
  421.       if (mask[i]) {
  422.          GLuint *ptr4 = PIXELADDR4(x[i],y[i]);
  423.          *ptr4 = Current->pixel;
  424.       }
  425.    }
  426. }
  427.  
  428.  
  429.  
  430. static void write_index_span( GLuint n, GLint x, GLint y, const GLuint index[],
  431.                   const GLubyte mask[] )
  432. {
  433.    GLubyte *ptr1 = PIXELADDR1(x,y);
  434.    GLuint i;
  435.    for (i=0;i<n;i++,ptr1++) {
  436.       if (mask[i]) {
  437.          *ptr1 = (GLubyte) index[i];
  438.       }
  439.    }
  440. }
  441.  
  442.  
  443.  
  444. static void write_monoindex_span( GLuint n, GLint x, GLint y,
  445.                   const GLubyte mask[] )
  446. {
  447.    GLubyte *ptr1 = PIXELADDR1(x,y);
  448.    GLuint i;
  449.    for (i=0;i<n;i++,ptr1++) {
  450.       if (mask[i]) {
  451.          *ptr1 = (GLubyte) Current->pixel;
  452.       }
  453.    }
  454. }
  455.  
  456.  
  457.  
  458. static void write_index_pixels( GLuint n, const GLint x[], const GLint y[],
  459.                     const GLuint index[], const GLubyte mask[] )
  460. {
  461.    GLuint i;
  462.    for (i=0;i<n;i++) {
  463.       if (mask[i]) {
  464.          GLubyte *ptr1 = PIXELADDR1(x[i],y[i]);
  465.          *ptr1 = (GLubyte) index[i];
  466.       }
  467.    }
  468. }
  469.  
  470.  
  471.  
  472. static void write_monoindex_pixels( GLuint n, const GLint x[], const GLint y[],
  473.                     const GLubyte mask[] )
  474. {
  475.    GLuint i;
  476.    for (i=0;i<n;i++) {
  477.       if (mask[i]) {
  478.          GLubyte *ptr1 = PIXELADDR1(x[i],y[i]);
  479.          *ptr1 = (GLubyte) Current->pixel;
  480.       }
  481.    }
  482. }
  483.  
  484.  
  485.  
  486. static void read_index_span( GLuint n, GLint x, GLint y, GLuint index[] )
  487. {
  488.    GLuint i;
  489.    GLubyte *ptr1 = PIXELADDR1(x,y);
  490.    for (i=0;i<n;i++,ptr1++) {
  491.       index[i] = (GLuint) *ptr1;
  492.    }
  493. }
  494.  
  495.  
  496. static void read_color_span( GLuint n, GLint x, GLint y,
  497.                              GLubyte red[], GLubyte green[],
  498.                  GLubyte blue[], GLubyte alpha[] )
  499. {
  500.    GLuint i;
  501.    GLubyte *ptr1 = PIXELADDR4B(x,y);
  502.    for (i=0;i<n;i++) {
  503.       red[i]   = *ptr1++;
  504.       green[i] = *ptr1++;
  505.       blue[i]  = *ptr1++;
  506.       alpha[i] = *ptr1++;
  507.    }
  508. }
  509.  
  510.  
  511. static void read_index_pixels( GLuint n, const GLint x[], const GLint y[],
  512.                    GLuint index[], const GLubyte mask[] )
  513. {
  514.    GLuint i;
  515.    for (i=0;i<n;i++) {
  516.       if (mask[i] ) {
  517.          GLubyte *ptr1 = PIXELADDR1(x[i],y[i]);
  518.          index[i] = (GLuint) *ptr1;
  519.       }
  520.    }
  521. }
  522.  
  523.  
  524. static void read_color_pixels( GLuint n, const GLint x[], const GLint y[],
  525.                    GLubyte red[], GLubyte green[],
  526.                    GLubyte blue[], GLubyte alpha[],
  527.                                const GLubyte mask[] )
  528. {
  529.    GLuint i;
  530.    for (i=0;i<n;i++) {
  531.       if (mask[i]) {
  532.          GLubyte *ptr1 = PIXELADDR4B(x[i],y[i]);
  533.          red[i]   = *ptr1++;
  534.          green[i] = *ptr1++;
  535.          blue[i]  = *ptr1++;
  536.          alpha[i] = *ptr1;
  537.       }
  538.    }
  539. }
  540.  
  541.  
  542. static points_func choose_points_function( void )
  543. {
  544.    /* No accelerated points functions */
  545.    return NULL;
  546. }
  547.  
  548. static line_func choose_line_function( void )
  549. {
  550.    /* No accelerated line functions */
  551.    return NULL;
  552. }
  553.  
  554.  
  555.  
  556. /**********************************************************************/
  557. /*****                  Optimized polygon rendering               *****/
  558. /**********************************************************************/
  559.  
  560. static GLint lx[MAX_HEIGHT], rx[MAX_HEIGHT];    /* X bounds */
  561. static GLfixed lz[MAX_HEIGHT], rz[MAX_HEIGHT];    /* Z values */
  562. static GLfixed lr[MAX_HEIGHT], rr[MAX_HEIGHT];    /* Red */
  563. static GLfixed lg[MAX_HEIGHT], rg[MAX_HEIGHT];    /* Green */
  564. static GLfixed lb[MAX_HEIGHT], rb[MAX_HEIGHT];    /* Blue */
  565. static GLfixed la[MAX_HEIGHT], ra[MAX_HEIGHT];    /* Alpha */
  566.  
  567.  
  568.  
  569. /*
  570.  * Smooth-shaded, z-less polygon, RGBA byte order.
  571.  */
  572. static void smooth_RGBA_z_polygon( GLuint n, GLuint vlist[], GLuint pv )
  573. {
  574. #define INTERP_COLOR
  575. #define INTERP_ALPHA
  576. #define INTERP_Z
  577.  
  578. #define INNER_CODE                        \
  579.    GLint i;                            \
  580.    GLuint *img = PIXELADDR4(xmin,y);                   \
  581.    for (i=0;i<len;i++) {                    \
  582.       if (FixedToUns(fz) < *zptr) {                \
  583.          *img = PACK_RGBA( FixedToInt(fr), FixedToInt(fg),    \
  584.                    FixedToInt(fb), FixedToInt(fa) );    \
  585.          *zptr = FixedToUns(fz);                \
  586.       }                                \
  587.       fr += fdrdx;  fg += fdgdx;  fb += fdbdx;  fa += fdadx;    \
  588.       fz += fdzdx;  zptr++;  img++;                \
  589.    }
  590.  
  591. #include "polytemp.h"
  592. }
  593.  
  594.  
  595. /*
  596.  * Smooth-shaded, z-less polygon, ABGR byte order.
  597.  */
  598. static void smooth_ABGR_z_polygon( GLuint n, GLuint vlist[], GLuint pv )
  599. {
  600. #define INTERP_COLOR
  601. #define INTERP_ALPHA
  602. #define INTERP_Z
  603.  
  604. #define INNER_CODE                        \
  605.    GLint i;                            \
  606.    GLuint *img = PIXELADDR4(xmin,y);                   \
  607.    for (i=0;i<len;i++) {                    \
  608.       if (FixedToUns(fz) < *zptr) {                \
  609.          *img = PACK_ABGR( FixedToInt(fr), FixedToInt(fg),    \
  610.                    FixedToInt(fb), FixedToInt(fa) );    \
  611.          *zptr = FixedToUns(fz);                \
  612.       }                                \
  613.       fr += fdrdx;  fg += fdgdx;  fb += fdbdx;  fa += fdadx;    \
  614.       fz += fdzdx;  zptr++;  img++;                \
  615.    }
  616.  
  617. #include "polytemp.h"
  618. }
  619.  
  620.  
  621.  
  622. /*
  623.  * Smooth-shaded, z-less polygon.
  624.  */
  625. static void flat_RGBA_z_polygon( GLuint n, GLuint vlist[], GLuint pv )
  626. {
  627. #define INTERP_COLOR
  628. #define INTERP_ALPHA
  629. #define INTERP_Z
  630.  
  631. #define SETUP_CODE            \
  632.    GLubyte r = VB.Color[pv][0];        \
  633.    GLubyte g = VB.Color[pv][1];        \
  634.    GLubyte b = VB.Color[pv][2];        \
  635.    GLubyte a = VB.Color[pv][3];        \
  636.    GLuint pixel = PACK_RGBA(r,g,b,a );
  637.  
  638. #define INNER_CODE            \
  639.    GLint i;                \
  640.    GLuint *img = PIXELADDR4(xmin,y);       \
  641.    for (i=0;i<len;i++) {        \
  642.       if (FixedToUns(fz) < *zptr) {    \
  643.      *img = pixel;            \
  644.          *zptr = FixedToUns(fz);    \
  645.       }                    \
  646.       fz += fdzdx;  zptr++;  img++;    \
  647.    }
  648.  
  649. #include "polytemp.h"
  650. }
  651.  
  652.  
  653.  
  654. /*
  655.  * Return pointer to an accelerated polygon function if possible.
  656.  */
  657. static polygon_func choose_polygon_function( void )
  658. {
  659.    GLuint i4 = 1;
  660.    GLubyte *i1 = (GLubyte *) &i4;
  661.    GLint little_endian = *i1;
  662.  
  663.    if (CC.Polygon.SmoothFlag)     return NULL;
  664.    if (CC.Polygon.StippleFlag)    return NULL;
  665.    if (CC.Texture.Enabled)        return NULL;
  666.  
  667.    if (CC.RasterMask==DEPTH_BIT
  668.        && CC.Depth.Func==GL_LESS
  669.        && CC.Depth.Mask==GL_TRUE
  670.        && Current->format==GL_RGBA) {
  671.       if (CC.Light.ShadeModel==GL_SMOOTH) {
  672.          if (little_endian) {
  673.             return smooth_ABGR_z_polygon;
  674.          }
  675.          else {
  676.             return smooth_RGBA_z_polygon;
  677.          }
  678.       }
  679.       else {
  680.          return flat_RGBA_z_polygon;
  681.       }
  682.    }
  683.    return NULL;
  684. }
  685.  
  686.  
  687.  
  688. static void osmesa_setup_DD_pointers( void )
  689. {
  690.    GLuint i4 = 1;
  691.    GLubyte *i1 = (GLubyte *) &i4;
  692.    GLint little_endian = *i1;
  693.  
  694.    /* one-time setup for polygon drawing */
  695.    static int first_time=1;
  696.    if (first_time) {
  697.       int i;
  698.       for (i=0;i<MAX_HEIGHT;i++) {
  699.          lx[i] = MAX_WIDTH;
  700.          rx[i] = -1;
  701.       }
  702.       first_time=0;
  703.    }
  704.  
  705.    DD.update_state = osmesa_setup_DD_pointers;
  706.  
  707.    DD.set_buffer = set_buffer;
  708.    DD.color = set_color;
  709.    DD.index = set_index;
  710.    DD.clear_index = clear_index;
  711.    DD.clear_color = clear_color;
  712.    DD.clear = clear;
  713.  
  714.    DD.buffer_size = buffer_size;
  715.  
  716.    DD.get_points_func = choose_points_function;
  717.    DD.get_line_func = choose_line_function;
  718.    DD.get_polygon_func = choose_polygon_function;
  719.  
  720.    if (little_endian) {
  721.       DD.write_color_span = write_ABGR_span;
  722.       DD.write_color_pixels = write_ABGR_pixels;
  723.    }
  724.    else {
  725.       DD.write_color_span = write_RGBA_span;
  726.       DD.write_color_pixels = write_RGBA_pixels;
  727.    }
  728.    DD.write_index_span = write_index_span;
  729.    DD.write_monocolor_span = write_monocolor_span;
  730.    DD.write_monoindex_span = write_monoindex_span;
  731.    DD.write_index_pixels = write_index_pixels;
  732.    DD.write_monocolor_pixels = write_monocolor_pixels;
  733.    DD.write_monoindex_pixels = write_monoindex_pixels;
  734.  
  735.    DD.read_color_span = read_color_span;
  736.    DD.read_index_span = read_index_span;
  737.    DD.read_color_pixels = read_color_pixels;
  738.    DD.read_index_pixels = read_index_pixels;
  739. }
  740.