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

  1. /* $Id: drawpix.c,v 1.25 1996/05/15 16:37:28 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: drawpix.c,v $
  26.  * Revision 1.25  1996/05/15  16:37:28  brianp
  27.  * added optimization for GL_LUMINANCE images from Frederic Devernay
  28.  *
  29.  * Revision 1.24  1996/05/01  15:48:57  brianp
  30.  * optimized glDrawPixels() for GLuint and GLushort GL_DEPTH drawing
  31.  *
  32.  * Revision 1.23  1996/04/25  20:41:30  brianp
  33.  * added support for DD.draw_pixels()
  34.  *
  35.  * Revision 1.22  1996/04/15  14:13:46  brianp
  36.  * better pixel mapping
  37.  *
  38.  * Revision 1.21  1996/02/26  15:07:16  brianp
  39.  * replaced CC.Current.Color with CC.Current.IntColor
  40.  *
  41.  * Revision 1.20  1995/12/19  16:43:05  brianp
  42.  * added quickdraw_rgb() function
  43.  *
  44.  * Revision 1.19  1995/12/18  17:27:05  brianp
  45.  * use new GLdepth datatype
  46.  *
  47.  * Revision 1.18  1995/11/09  15:15:29  brianp
  48.  * allow glDrawPixels width and height to be zero
  49.  *
  50.  * Revision 1.17  1995/11/03  17:41:17  brianp
  51.  * fixed a few things for C++ compilation
  52.  *
  53.  * Revision 1.16  1995/10/19  15:48:51  brianp
  54.  * replaced a for loop with MEMSET
  55.  *
  56.  * Revision 1.15  1995/10/16  15:25:49  brianp
  57.  * added zooming for stencil drawing/copying
  58.  *
  59.  * Revision 1.14  1995/10/14  16:28:07  brianp
  60.  * added glPixelZoom support
  61.  *
  62.  * Revision 1.13  1995/09/28  16:18:48  brianp
  63.  * replaced a loop in draw_color_pixels with a MEMSET
  64.  *
  65.  * Revision 1.12  1995/09/15  18:46:10  brianp
  66.  * directly call DD.write_color_span under right conditions
  67.  *
  68.  * Revision 1.11  1995/07/24  20:35:20  brianp
  69.  * replaced memset() with MEMSET() and memcpy() with MEMCPY()
  70.  *
  71.  * Revision 1.10  1995/07/24  18:59:42  brianp
  72.  * convert real window coords to ints with rounding, not truncating
  73.  *
  74.  * Revision 1.9  1995/06/12  15:53:40  brianp
  75.  * removed garbage chars from end of file
  76.  *
  77.  * Revision 1.8  1995/06/12  15:50:44  brianp
  78.  * renamed from drawpixels.[ch] to drawpix.[ch]
  79.  *
  80.  * Revision 1.7  1995/06/12  15:38:55  brianp
  81.  * changed color arrays to GLubyte
  82.  *
  83.  * Revision 1.6  1995/05/31  14:58:26  brianp
  84.  * check that rasterpos is valid before drawing
  85.  *
  86.  * Revision 1.5  1995/05/22  21:02:41  brianp
  87.  * Release 1.2
  88.  *
  89.  * Revision 1.4  1995/05/12  19:26:43  brianp
  90.  * replaced CC.Mode!=0 with INSIDE_BEGIN_END
  91.  *
  92.  * Revision 1.3  1995/05/10  18:43:58  brianp
  93.  * removed extraneous parenthesis
  94.  * moved clip_pixels() to span.c
  95.  *
  96.  * Revision 1.2  1995/03/04  19:29:44  brianp
  97.  * 1.1 beta revision
  98.  *
  99.  * Revision 1.1  1995/02/24  14:20:50  brianp
  100.  * Initial revision
  101.  *
  102.  */
  103.  
  104.  
  105. #include <stdlib.h>
  106. #include <string.h>
  107. #include "context.h"
  108. #include "dd.h"
  109. #include "feedback.h"
  110. #include "list.h"
  111. #include "macros.h"
  112. #include "pixel.h"
  113. #include "span.h"
  114. #include "stencil.h"
  115.  
  116.  
  117.  
  118.  
  119. /* TODO:  apply texture mapping to fragments */
  120.  
  121.  
  122.  
  123. static void draw_index_pixels( GLsizei width, GLsizei height,
  124.                    GLenum type, const GLvoid *pixels )
  125. {
  126.    GLint x, y, desty;
  127.    GLuint i, j;
  128.    GLdepth zspan[MAX_WIDTH];
  129.    GLboolean zoom;
  130.  
  131.    zoom = CC.Pixel.ZoomX!=1.0 || CC.Pixel.ZoomY!=1.0;
  132.  
  133.    /* Position, depth of pixels */
  134.    x = (GLint) (CC.Current.RasterPos[0] + 0.5F);
  135.    y = (GLint) (CC.Current.RasterPos[1] + 0.5F);
  136.    desty = y;
  137.    if (CC.Depth.Test) {
  138.       GLdepth zval = (GLdepth) (CC.Current.RasterPos[2] * DEPTH_SCALE);
  139.       for (i=0;i<width;i++) {
  140.      zspan[i] = zval;
  141.       }
  142.    }
  143.  
  144.    /* process the image row by row */
  145.    for (i=0;i<height;i++,y++) {
  146.       GLuint ispan[MAX_WIDTH];
  147.  
  148.       /* convert to uints */
  149.       switch (type) {
  150.      case GL_UNSIGNED_BYTE:
  151.         {
  152.            GLubyte *src = (GLubyte *) pixels + i * width;
  153.            for (j=0;j<width;j++) {
  154.           ispan[j] = (GLuint) *src++;
  155.            }
  156.         }
  157.         break;
  158.      case GL_BYTE:
  159.         {
  160.            GLbyte *src = (GLbyte *) pixels + i * width;
  161.            for (j=0;j<width;j++) {
  162.           ispan[j] = (GLuint) *src++;
  163.            }
  164.         }
  165.         break;
  166.      case GL_UNSIGNED_SHORT:
  167.         {
  168.            GLushort *src = (GLushort *) pixels + i * width;
  169.            for (j=0;j<width;j++) {
  170.           ispan[j] = (GLuint) *src++;
  171.            }
  172.         }
  173.         break;
  174.      case GL_SHORT:
  175.         {
  176.            GLshort *src = (GLshort *) pixels + i * width;
  177.            for (j=0;j<width;j++) {
  178.           ispan[j] = (GLuint) *src++;
  179.            }
  180.         }
  181.         break;
  182.      case GL_UNSIGNED_INT:
  183.         {
  184.            GLuint *src = (GLuint *) pixels + i * width;
  185.            for (j=0;j<width;j++) {
  186.           ispan[j] = *src++;
  187.            }
  188.         }
  189.         break;
  190.      case GL_INT:
  191.         {
  192.            GLint *src = (GLint *) pixels + i * width;
  193.            for (j=0;j<width;j++) {
  194.           ispan[j] = (GLuint) *src++;
  195.            }
  196.         }
  197.         break;
  198.      case GL_BITMAP:
  199.         /* TODO */
  200.         break;
  201.      case GL_FLOAT:
  202.         {
  203.            GLfloat *src = (GLfloat *) pixels + i * width;
  204.            for (j=0;j<width;j++) {
  205.           ispan[j] = (GLuint) (GLint) *src++;
  206.            }
  207.         }
  208.         break;
  209.      default:
  210.         gl_error( GL_INVALID_ENUM, "Internal: draw_index_pixels" );
  211.       }
  212.  
  213.       /* apply shift and offset */
  214.       if (CC.Pixel.IndexOffset || CC.Pixel.IndexShift) {
  215.      if (CC.Pixel.IndexShift>=0) {
  216.         for (j=0;j<width;j++) {
  217.            ispan[j] = (ispan[j] << CC.Pixel.IndexShift)
  218.                   + CC.Pixel.IndexOffset;
  219.         }
  220.      }
  221.      else {
  222.         for (j=0;j<width;j++) {
  223.            ispan[j] = (ispan[j] >> -CC.Pixel.IndexShift)
  224.                   + CC.Pixel.IndexOffset;
  225.         }
  226.      }
  227.       }
  228.  
  229.       if (CC.RGBAflag) {
  230.      /* Convert index to RGBA and write to frame buffer */
  231.      GLubyte red[MAX_WIDTH], green[MAX_WIDTH];
  232.      GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];
  233.      for (j=0;j<width;j++) {
  234.         red[j]   = (GLint) (CC.Pixel.MapItoR[ispan[j]] * CC.RedScale);
  235.         green[j] = (GLint) (CC.Pixel.MapItoG[ispan[j]] * CC.GreenScale);
  236.         blue[j]  = (GLint) (CC.Pixel.MapItoB[ispan[j]] * CC.BlueScale);
  237.         alpha[j] = (GLint) (CC.Pixel.MapItoA[ispan[j]] * CC.AlphaScale);
  238.      }
  239.          if (zoom) {
  240.             gl_write_zoomed_color_span( width, x, y, zspan,
  241.                                         red, green, blue, alpha, desty );
  242.          }
  243.          else {
  244.             gl_write_color_span( width, x, y, zspan,
  245.                                  red, green, blue, alpha, GL_BITMAP );
  246.          }
  247.       }
  248.       else {
  249.      /* optionally apply index map then write to frame buffer */
  250.      if (CC.Pixel.MapColorFlag) {
  251.         for (j=0;j<width;j++) {
  252.            ispan[j] = CC.Pixel.MapItoI[ispan[j]];
  253.         }
  254.      }
  255.          if (zoom) {
  256.             gl_write_zoomed_index_span( width, x, y, zspan, ispan, desty );
  257.          }
  258.          else {
  259.             gl_write_index_span( width, x, y, zspan, ispan, GL_BITMAP );
  260.          }
  261.       }
  262.    }
  263.  
  264. }
  265.  
  266.  
  267.  
  268. static void draw_stencil_pixels( GLsizei width, GLsizei height,
  269.                      GLenum type, const GLvoid *pixels )
  270. {
  271.    GLint x, y, desty;
  272.    GLuint i, j;
  273.    GLboolean zoom;
  274.  
  275.    zoom = CC.Pixel.ZoomX!=1.0 || CC.Pixel.ZoomY!=1.0;
  276.  
  277.    /* Position, depth of pixels */
  278.    x = (GLint) (CC.Current.RasterPos[0] + 0.5F);
  279.    y = (GLint) (CC.Current.RasterPos[1] + 0.5F);
  280.    desty = y;
  281.  
  282.    /* process the image row by row */
  283.    for (i=0;i<height;i++,y++) {
  284.       GLubyte stencil[MAX_WIDTH];
  285.  
  286.       /* convert to ubytes */
  287.       switch (type) {
  288.      case GL_UNSIGNED_BYTE:
  289.         {
  290.            GLubyte *src = (GLubyte *) pixels + i * width;
  291.            MEMCPY( stencil, src, width );
  292.         }
  293.         break;
  294.      case GL_BYTE:
  295.         {
  296.            GLbyte *src = (GLbyte *) pixels + i * width;
  297.            MEMCPY( stencil, src, width );
  298.         }
  299.         break;
  300.      case GL_UNSIGNED_SHORT:
  301.         {
  302.            GLushort *src = (GLushort *) pixels + i * width;
  303.            for (j=0;j<width;j++) {
  304.           stencil[j] = (GLubyte) ((*src++) & 0xff);
  305.            }
  306.         }
  307.         break;
  308.      case GL_SHORT:
  309.         {
  310.            GLshort *src = (GLshort *) pixels + i * width;
  311.            for (j=0;j<width;j++) {
  312.           stencil[j] = (GLubyte) ((*src++) & 0xff);
  313.            }
  314.         }
  315.         break;
  316.      case GL_UNSIGNED_INT:
  317.         {
  318.            GLuint *src = (GLuint *) pixels + i * width;
  319.            for (j=0;j<width;j++) {
  320.           stencil[j] = (GLubyte) ((*src++) & 0xff);
  321.            }
  322.         }
  323.         break;
  324.      case GL_INT:
  325.         {
  326.            GLint *src = (GLint *) pixels + i * width;
  327.            for (j=0;j<width;j++) {
  328.           stencil[j] = (GLubyte) ((*src++) & 0xff);
  329.            }
  330.         }
  331.         break;
  332.      case GL_BITMAP:
  333.         /* TODO */
  334.         break;
  335.      case GL_FLOAT:
  336.         {
  337.            GLfloat *src = (GLfloat *) pixels + i * width;
  338.            for (j=0;j<width;j++) {
  339.           stencil[j] = (GLubyte) (((GLint) *src++) & 0xff);
  340.            }
  341.         }
  342.         break;
  343.      default:
  344.         gl_error( GL_INVALID_ENUM, "Internal: draw_stencil_pixels" );
  345.       }
  346.  
  347.       /* apply shift and offset */
  348.       if (CC.Pixel.IndexOffset || CC.Pixel.IndexShift) {
  349.      if (CC.Pixel.IndexShift>=0) {
  350.         for (j=0;j<width;j++) {
  351.            stencil[j] = (stencil[j] << CC.Pixel.IndexShift)
  352.                   + CC.Pixel.IndexOffset;
  353.         }
  354.      }
  355.      else {
  356.         for (j=0;j<width;j++) {
  357.            stencil[j] = (stencil[j] >> -CC.Pixel.IndexShift)
  358.                   + CC.Pixel.IndexOffset;
  359.         }
  360.      }
  361.       }
  362.  
  363.       /* mapping */
  364.       if (CC.Pixel.MapStencilFlag) {
  365.      for (j=0;j<width;j++) {
  366.         stencil[j] = CC.Pixel.MapStoS[ stencil[j] ];
  367.      }
  368.       }
  369.  
  370.       /* write stencil values to stencil buffer */
  371.       if (zoom) {
  372.          gl_write_zoomed_stencil_span( (GLuint) width, x, y, stencil, desty );
  373.       }
  374.       else {
  375.          gl_write_stencil_span( (GLuint) width, x, y, stencil );
  376.       }
  377.    }
  378. }
  379.  
  380.  
  381.  
  382. static void draw_depth_pixels( GLsizei width, GLsizei height,
  383.                    GLenum type, const GLvoid *pixels )
  384. {
  385.    GLint x, y, desty;
  386.    GLubyte red[MAX_WIDTH], green[MAX_WIDTH], blue[MAX_WIDTH], alpha[MAX_WIDTH];
  387.    GLuint ispan[MAX_WIDTH];
  388.    GLboolean bias_or_scale;
  389.    GLboolean zoom;
  390.  
  391.    bias_or_scale = CC.Pixel.DepthBias!=0.0 || CC.Pixel.DepthScale!=1.0;
  392.    zoom = CC.Pixel.ZoomX!=1.0 || CC.Pixel.ZoomY!=1.0;
  393.  
  394.    /* Position, depth of pixels */
  395.    x = (GLint) (CC.Current.RasterPos[0] + 0.5F);
  396.    y = (GLint) (CC.Current.RasterPos[1] + 0.5F);
  397.    desty = y;
  398.  
  399.    /* Color or index */
  400.    if (CC.RGBAflag) {
  401.       GLint r, g, b, a;
  402.       r = (GLint) (CC.Current.RasterColor[0] * CC.RedScale);
  403.       g = (GLint) (CC.Current.RasterColor[1] * CC.GreenScale);
  404.       b = (GLint) (CC.Current.RasterColor[2] * CC.BlueScale);
  405.       a = (GLint) (CC.Current.RasterColor[3] * CC.AlphaScale);
  406.       MEMSET( red,   r, width );
  407.       MEMSET( green, g, width );
  408.       MEMSET( blue,  b, width );
  409.       MEMSET( alpha, a, width );
  410.    }
  411.    else {
  412.       GLuint i;
  413.       for (i=0;i<width;i++) {
  414.      ispan[i] = CC.Current.RasterIndex;
  415.       }
  416.    }
  417.  
  418.    if (type==GL_UNSIGNED_SHORT && sizeof(GLdepth)==sizeof(GLushort)
  419.        && !bias_or_scale && !zoom && CC.RGBAflag) {
  420.       /* Special case: directly write 16-bit depth values */
  421.       GLuint j;
  422.       for (j=0;j<height;j++,y++) {
  423.          GLdepth *zptr = (GLdepth *) pixels + j * width;
  424.          gl_write_color_span( width, x, y, zptr,
  425.                               red, green, blue, alpha, GL_BITMAP );
  426.       }
  427.    }
  428.    else if (type==GL_UNSIGNED_INT && sizeof(GLdepth)==sizeof(GLuint)
  429.        && !bias_or_scale && !zoom && CC.RGBAflag) {
  430.       /* Special case: directly write 32-bit depth values */
  431.       GLuint i, j;
  432.       /* Compute shift value to scale 32-bit uints down to depth values. */
  433.       GLuint shift = 0;
  434.       GLuint max = MAX_DEPTH;
  435.       while ((max&0x80000000)==0) {
  436.          max = max << 1;
  437.          shift++;
  438.       }
  439.       for (j=0;j<height;j++,y++) {
  440.          GLdepth zspan[MAX_WIDTH];
  441.          GLuint *zptr = (GLuint *) pixels + j * width;
  442.          for (i=0;i<width;i++) {
  443.             zspan[i] = zptr[i] >> shift;
  444.          }
  445.          gl_write_color_span( width, x, y, zspan,
  446.                               red, green, blue, alpha, GL_BITMAP );
  447.       }
  448.    }
  449.    else {
  450.       /* General case (slower) */
  451.       GLuint i, j;
  452.  
  453.       /* process image row by row */
  454.       for (i=0;i<height;i++,y++) {
  455.          GLfloat depth[MAX_WIDTH];
  456.          GLdepth zspan[MAX_WIDTH];
  457.  
  458.          switch (type) {
  459.             case GL_UNSIGNED_BYTE:
  460.                {
  461.                   GLubyte *src = (GLubyte *) pixels + i * width;
  462.                   for (j=0;j<width;j++) {
  463.                      depth[j] = UBYTE_TO_FLOAT( *src++ );
  464.                   }
  465.                }
  466.                break;
  467.             case GL_BYTE:
  468.                {
  469.                   GLbyte *src = (GLbyte *) pixels + i * width;
  470.                   for (j=0;j<width;j++) {
  471.                      depth[j] = BYTE_TO_FLOAT( *src++ );
  472.                   }
  473.                }
  474.                break;
  475.             case GL_UNSIGNED_SHORT:
  476.                {
  477.                   GLushort *src = (GLushort *) pixels + i * width;
  478.                   for (j=0;j<width;j++) {
  479.                      depth[j] = USHORT_TO_FLOAT( *src++ );
  480.                   }
  481.                }
  482.                break;
  483.             case GL_SHORT:
  484.                {
  485.                   GLshort *src = (GLshort *) pixels + i * width;
  486.                   for (j=0;j<width;j++) {
  487.                      depth[j] = SHORT_TO_FLOAT( *src++ );
  488.                   }
  489.                }
  490.                break;
  491.             case GL_UNSIGNED_INT:
  492.                {
  493.                   GLuint *src = (GLuint *) pixels + i * width;
  494.                   for (j=0;j<width;j++) {
  495.                      depth[j] = UINT_TO_FLOAT( *src++ );
  496.                   }
  497.                }
  498.                break;
  499.             case GL_INT:
  500.                {
  501.                   GLint *src = (GLint *) pixels + i * width;
  502.                   for (j=0;j<width;j++) {
  503.                      depth[j] = INT_TO_FLOAT( *src++ );
  504.                   }
  505.                }
  506.                break;
  507.             case GL_FLOAT:
  508.                {
  509.                   GLfloat *src = (GLfloat *) pixels + i * width;
  510.                   for (j=0;j<width;j++) {
  511.                      depth[j] = *src++;
  512.                   }
  513.                }
  514.                break;
  515.          }
  516.  
  517.          /* apply depth scale and bias */
  518.          if (CC.Pixel.DepthScale!=1.0 || CC.Pixel.DepthBias!=0.0) {
  519.             for (j=0;j<width;j++) {
  520.                depth[j] = depth[j] * CC.Pixel.DepthScale + CC.Pixel.DepthBias;
  521.             }
  522.          }
  523.  
  524.          /* clamp depth values to [0,1] and convert from floats to integers */
  525.          for (j=0;j<width;j++) {
  526.             zspan[j] = (GLdepth) (CLAMP( depth[j], 0.0F, 1.0F ) * DEPTH_SCALE);
  527.          }
  528.  
  529.          if (CC.RGBAflag) {
  530.             if (zoom) {
  531.                gl_write_zoomed_color_span( width, x, y, zspan,
  532.                                            red, green, blue, alpha, desty );
  533.             }
  534.             else {
  535.                gl_write_color_span( width, x, y, zspan,
  536.                                     red, green, blue, alpha, GL_BITMAP );
  537.             }
  538.          }
  539.          else {
  540.             if (zoom) {
  541.                gl_write_zoomed_index_span( width, x, y, zspan,
  542.                                            ispan, GL_BITMAP );
  543.             }
  544.             else {
  545.                gl_write_index_span( width, x, y, zspan, ispan, GL_BITMAP );
  546.             }
  547.          }
  548.  
  549.       }
  550.    }
  551. }
  552.  
  553.  
  554.  
  555. static void draw_color_pixels( GLsizei width, GLsizei height, GLenum format,
  556.                    GLenum type, const GLvoid *pixels )
  557. {
  558.    GLuint i, j;
  559.    GLint x, y, desty;
  560.    GLdepth zspan[MAX_WIDTH];
  561.    GLboolean scale_or_bias, quick_draw;
  562.    GLboolean zoom;
  563.  
  564.    zoom = CC.Pixel.ZoomX!=1.0 || CC.Pixel.ZoomY!=1.0;
  565.  
  566.    /* Position, depth of pixels */
  567.    x = (GLint) (CC.Current.RasterPos[0] + 0.5F);
  568.    y = (GLint) (CC.Current.RasterPos[1] + 0.5F);
  569.    desty = y;
  570.    if (CC.Depth.Test) {
  571.       /* fill in array of z values */
  572.       GLdepth z = (GLdepth) (CC.Current.RasterPos[2] * DEPTH_SCALE);
  573.       for (i=0;i<width;i++) {
  574.      zspan[i] = z;
  575.       }
  576.    }
  577.  
  578.    /* Determine if scaling and/or biasing is needed */
  579.    if (CC.Pixel.RedScale!=1.0F   || CC.Pixel.RedBias!=0.0F ||
  580.        CC.Pixel.GreenScale!=1.0F || CC.Pixel.GreenBias!=0.0F ||
  581.        CC.Pixel.BlueScale!=1.0F  || CC.Pixel.BlueBias!=0.0F ||
  582.        CC.Pixel.AlphaScale!=1.0F || CC.Pixel.AlphaBias!=0.0F) {
  583.       scale_or_bias = GL_TRUE;
  584.    }
  585.    else {
  586.       scale_or_bias = GL_FALSE;
  587.    }
  588.  
  589.    /* Determine if we can directly call the device driver function */
  590.    if (CC.RasterMask==0 && !zoom && x>=0 && y>=0
  591.        && x+width<=CC.BufferWidth && y+height<=CC.BufferHeight) {
  592.       quick_draw = GL_TRUE;
  593.    }
  594.    else {
  595.       quick_draw = GL_FALSE;
  596.    }
  597.  
  598.    /* First check for common cases */
  599.    if (type==GL_UNSIGNED_BYTE && (format==GL_RGB || format == GL_LUMINANCE)
  600.        && !CC.Pixel.MapColorFlag && !scale_or_bias
  601.        && CC.RedScale==255.0 && CC.GreenScale==255.0 && CC.BlueScale==255.0) {
  602.       DEFARRAY( GLubyte, alpha, MAX_WIDTH );
  603.       GLubyte *src = (GLubyte *) pixels;
  604.       /* constant alpha */
  605.       MEMSET( alpha, (GLint) CC.AlphaScale, width );
  606.       if (format == GL_RGB) {
  607.      /* 8-bit RGB pixels */
  608.      DEFARRAY( GLubyte, red, MAX_WIDTH );
  609.      DEFARRAY( GLubyte, green, MAX_WIDTH );
  610.      DEFARRAY( GLubyte, blue, MAX_WIDTH );
  611.      for (i=0;i<height;i++,y++) {
  612.         for (j=0;j<width;j++) {
  613.            red[j]   = *src++;
  614.            green[j] = *src++;
  615.            blue[j]  = *src++;
  616.         }
  617.         if (quick_draw) {
  618.            (*DD.write_color_span)( width, x,y, red, green, blue, alpha, NULL);
  619.         }
  620.         else if (zoom) {
  621.            gl_write_zoomed_color_span( (GLuint) width, x, y, zspan,
  622.                        red, green, blue, alpha, desty );
  623.         }
  624.         else {
  625.            gl_write_color_span( (GLuint) width, x, y, zspan,
  626.                     red, green, blue, alpha, GL_BITMAP );
  627.         }
  628.      }
  629.      UNDEFARRAY( red );
  630.      UNDEFARRAY( green );
  631.      UNDEFARRAY( blue );
  632.       }
  633.       else {
  634.      /* 8-bit Luminance pixels */
  635.      GLubyte *lum = (GLubyte *) pixels;
  636.      for (i=0;i<height;i++,y++,lum+=width) {
  637.         if (quick_draw) {
  638.            (*DD.write_color_span)( width, x,y, lum, lum, lum, alpha, NULL);
  639.         }
  640.         else if (zoom) {
  641.            gl_write_zoomed_color_span( (GLuint) width, x, y, zspan,
  642.                        lum, lum, lum, alpha, desty );
  643.         }
  644.         else {
  645.            gl_write_color_span( (GLuint) width, x, y, zspan,
  646.                     lum, lum, lum, alpha, GL_BITMAP );
  647.         }
  648.      }
  649.       }
  650.       UNDEFARRAY( alpha );
  651.    }
  652.    else {
  653.       /* General solution */
  654.       GLboolean r_flag, g_flag, b_flag, a_flag, l_flag;
  655.       GLuint components;
  656.  
  657.       r_flag = g_flag = b_flag = a_flag = l_flag = GL_FALSE;
  658.       switch (format) {
  659.      case GL_RED:
  660.         r_flag = GL_TRUE;
  661.         components = 1;
  662.         break;
  663.      case GL_GREEN:
  664.         g_flag = GL_TRUE;
  665.         components = 1;
  666.         break;
  667.      case GL_BLUE:
  668.         b_flag = GL_TRUE;
  669.         components = 1;
  670.         break;
  671.      case GL_ALPHA:
  672.         a_flag = GL_TRUE;
  673.         components = 1;
  674.         break;
  675.      case GL_RGB:
  676.         r_flag = g_flag = b_flag = GL_TRUE;
  677.         components = 3;
  678.         break;
  679.      case GL_LUMINANCE:
  680.         l_flag = GL_TRUE;
  681.         components = 1;
  682.         break;
  683.      case GL_LUMINANCE_ALPHA:
  684.         l_flag = a_flag = GL_TRUE;
  685.         components = 2;
  686.         break;
  687.      case GL_RGBA:
  688.         r_flag = g_flag = b_flag = a_flag = GL_TRUE;
  689.         components = 4;
  690.         break;
  691.       }
  692.  
  693.       /* process the image row by row */
  694.       for (i=0;i<height;i++,y++) {
  695.      GLfloat rf[MAX_WIDTH], gf[MAX_WIDTH], bf[MAX_WIDTH], af[MAX_WIDTH];
  696.      GLubyte red[MAX_WIDTH], green[MAX_WIDTH];
  697.      GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];
  698.  
  699.      /* convert to floats */
  700.      switch (type) {
  701.         case GL_UNSIGNED_BYTE:
  702.            {
  703.           GLubyte *src = (GLubyte *) pixels + i * width * components;
  704.           for (j=0;j<width;j++) {
  705.              if (l_flag) {
  706.             rf[j] = gf[j] = bf[j] = UBYTE_TO_FLOAT(*src++);
  707.              }
  708.              else {
  709.             rf[j] = r_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
  710.             gf[j] = g_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
  711.             bf[j] = b_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
  712.              }
  713.              af[j] = a_flag ? UBYTE_TO_FLOAT(*src++) : 1.0;
  714.           }
  715.            }
  716.            break;
  717.         case GL_BYTE:
  718.            {
  719.           GLbyte *src = (GLbyte *) pixels + i * width * components;
  720.           for (j=0;j<width;j++) {
  721.              if (l_flag) {
  722.             rf[j] = gf[j] = bf[j] = BYTE_TO_FLOAT(*src++);
  723.              }
  724.              else {
  725.             rf[j] = r_flag ? BYTE_TO_FLOAT(*src++) : 0.0;
  726.             gf[j] = g_flag ? BYTE_TO_FLOAT(*src++) : 0.0;
  727.             bf[j] = b_flag ? BYTE_TO_FLOAT(*src++) : 0.0;
  728.              }
  729.              af[j] = a_flag ? BYTE_TO_FLOAT(*src++) : 1.0;
  730.           }
  731.            }
  732.            break;
  733.         case GL_BITMAP:
  734.            /* special case */
  735.            break;
  736.         case GL_UNSIGNED_SHORT:
  737.            {
  738.           GLushort *src = (GLushort *) pixels + i * width * components;
  739.           for (j=0;j<width;j++) {
  740.              if (l_flag) {
  741.             rf[j] = gf[j] = bf[j] = USHORT_TO_FLOAT(*src++);
  742.              }
  743.              else {
  744.             rf[j] = r_flag ? USHORT_TO_FLOAT(*src++) : 0.0;
  745.             gf[j] = g_flag ? USHORT_TO_FLOAT(*src++) : 0.0;
  746.             bf[j] = b_flag ? USHORT_TO_FLOAT(*src++) : 0.0;
  747.              }
  748.              af[j] = a_flag ? USHORT_TO_FLOAT(*src++) : 1.0;
  749.           }
  750.            }
  751.            break;
  752.         case GL_SHORT:
  753.            {
  754.           GLshort *src = (GLshort *) pixels + i * width * components;
  755.           for (j=0;j<width;j++) {
  756.              if (l_flag) {
  757.             rf[j] = gf[j] = bf[j] = SHORT_TO_FLOAT(*src++);
  758.              }
  759.              else {
  760.             rf[j] = r_flag ? SHORT_TO_FLOAT(*src++) : 0.0;
  761.             gf[j] = g_flag ? SHORT_TO_FLOAT(*src++) : 0.0;
  762.             bf[j] = b_flag ? SHORT_TO_FLOAT(*src++) : 0.0;
  763.              }
  764.              af[j] = a_flag ? SHORT_TO_FLOAT(*src++) : 1.0;
  765.           }
  766.            }
  767.            break;
  768.         case GL_UNSIGNED_INT:
  769.            {
  770.           GLuint *src = (GLuint *) pixels + i * width * components;
  771.           for (j=0;j<width;j++) {
  772.              if (l_flag) {
  773.             rf[j] = gf[j] = bf[j] = UINT_TO_FLOAT(*src++);
  774.              }
  775.              else {
  776.             rf[j] = r_flag ? UINT_TO_FLOAT(*src++) : 0.0;
  777.             gf[j] = g_flag ? UINT_TO_FLOAT(*src++) : 0.0;
  778.             bf[j] = b_flag ? UINT_TO_FLOAT(*src++) : 0.0;
  779.              }
  780.              af[j] = a_flag ? af[j] = UINT_TO_FLOAT(*src++) : 1.0;
  781.           }
  782.            }
  783.            break;
  784.         case GL_INT:
  785.            {
  786.           GLint *src = (GLint *) pixels + i * width * components;
  787.           for (j=0;j<width;j++) {
  788.              if (l_flag) {
  789.             rf[j] = gf[j] = bf[j] = INT_TO_FLOAT(*src++);
  790.              }
  791.              else {
  792.             rf[j] = r_flag ? INT_TO_FLOAT(*src++) : 0.0;
  793.             gf[j] = g_flag ? INT_TO_FLOAT(*src++) : 0.0;
  794.             bf[j] = b_flag ? INT_TO_FLOAT(*src++) : 0.0;
  795.              }
  796.              af[j] = a_flag ? INT_TO_FLOAT(*src++) : 1.0;
  797.           }
  798.            }
  799.            break;
  800.         case GL_FLOAT:
  801.            {
  802.           GLfloat *src = (GLfloat *) pixels + i * width * components;
  803.           for (j=0;j<width;j++) {
  804.              if (l_flag) {
  805.             rf[j] = gf[j] = bf[j] = *src++;
  806.              }
  807.              else {
  808.             rf[j] = r_flag ? *src++ : 0.0;
  809.             gf[j] = g_flag ? *src++ : 0.0;
  810.             bf[j] = b_flag ? *src++ : 0.0;
  811.              }
  812.              af[j] = a_flag ? *src++ : 1.0;
  813.           }
  814.            }
  815.            break;
  816.         default:
  817.            gl_error( GL_INVALID_ENUM, "glDrawPixels" );
  818.            return;
  819.      }
  820.  
  821.      /* apply scale and bias */
  822.      if (scale_or_bias) {
  823.         for (j=0;j<width;j++) {
  824.            GLfloat r, g, b, a;
  825.            r = rf[j] * CC.Pixel.RedScale   + CC.Pixel.RedBias;
  826.            g = gf[j] * CC.Pixel.GreenScale + CC.Pixel.GreenBias;
  827.            b = bf[j] * CC.Pixel.BlueScale  + CC.Pixel.BlueBias;
  828.            a = af[j] * CC.Pixel.AlphaScale + CC.Pixel.AlphaBias;
  829.            rf[j] = CLAMP( r, 0.0, 1.0 );
  830.            gf[j] = CLAMP( g, 0.0, 1.0 );
  831.            bf[j] = CLAMP( b, 0.0, 1.0 );
  832.            af[j] = CLAMP( a, 0.0, 1.0 );
  833.         }
  834.      }
  835.  
  836.      /* apply pixel mappings */
  837.      if (CC.Pixel.MapColorFlag) {
  838.             GLfloat rscale = CC.Pixel.MapRtoRsize-1;
  839.             GLfloat gscale = CC.Pixel.MapGtoGsize-1;
  840.             GLfloat bscale = CC.Pixel.MapBtoBsize-1;
  841.             GLfloat ascale = CC.Pixel.MapAtoAsize-1;
  842.         for (j=0;j<width;j++) {
  843.            rf[j] = CC.Pixel.MapRtoR[ (GLint) (rf[j] * rscale) ];
  844.            gf[j] = CC.Pixel.MapGtoG[ (GLint) (gf[j] * gscale) ];
  845.            bf[j] = CC.Pixel.MapBtoB[ (GLint) (bf[j] * bscale) ];
  846.            af[j] = CC.Pixel.MapAtoA[ (GLint) (af[j] * ascale) ];
  847.         }
  848.      }
  849.  
  850.      /* convert to integers */
  851.      for (j=0;j<width;j++) {
  852.         red[j]   = (GLint) (rf[j] * CC.RedScale);
  853.         green[j] = (GLint) (gf[j] * CC.GreenScale);
  854.         blue[j]  = (GLint) (bf[j] * CC.BlueScale);
  855.         alpha[j] = (GLint) (af[j] * CC.AlphaScale);
  856.      }
  857.  
  858.      /* write to frame buffer */
  859.          if (quick_draw) {
  860.             (*DD.write_color_span)( width, x,y, red, green, blue, alpha, NULL);
  861.          }
  862.          else if (zoom) {
  863.             gl_write_zoomed_color_span( width, x, y, zspan,
  864.                                         red, green, blue, alpha, desty );
  865.          }
  866.          else {
  867.             gl_write_color_span( (GLuint) width, x, y, zspan,
  868.                                  red, green, blue, alpha, GL_BITMAP );
  869.          }
  870.       }
  871.    }
  872.  
  873. }
  874.  
  875.  
  876.  
  877. /*
  878.  * Do a glDrawPixels( w, h, GL_RGB, GL_UNSIGNED_BYTE, pixels ) optimized
  879.  * for the case of no pixel mapping, no scale, no bias, no zoom, default
  880.  * storage mode, no raster ops, and no pixel clipping.
  881.  * Return:  GL_TRUE if success
  882.  *          GL_FALSE if conditions weren't met for optimized drawing
  883.  */
  884. static GLboolean quickdraw_rgb( GLsizei width, GLsizei height,
  885.                                 const void *pixels )
  886. {
  887.    DEFARRAY( GLubyte, red, MAX_WIDTH );
  888.    DEFARRAY( GLubyte, green, MAX_WIDTH );
  889.    DEFARRAY( GLubyte, blue, MAX_WIDTH );
  890.    DEFARRAY( GLubyte, alpha, MAX_WIDTH );
  891.    GLint i, j;
  892.    GLint x, y;
  893.    GLint bytes_per_row;
  894.  
  895.    bytes_per_row = width * 3 + (width % CC.UnpackAlignment);
  896.  
  897.    if (!CC.Current.RasterPosValid) {
  898.       return GL_TRUE;  /* this is success */
  899.    }
  900.  
  901.    x = (GLint) (CC.Current.RasterPos[0] + 0.5F);
  902.    y = (GLint) (CC.Current.RasterPos[1] + 0.5F);
  903.  
  904.    if (x<0 || y<0 || x+width>CC.BufferWidth || y+height>CC.BufferHeight) {
  905.       return GL_FALSE;
  906.    }
  907.  
  908.    /* constant alpha */
  909.    for (j=0;j<width;j++) {
  910.       alpha[j] = (GLint) CC.AlphaScale;
  911.    }
  912.  
  913.    /* write directly to device driver */
  914.    for (i=0;i<height;i++) {
  915.       /* each row of pixel data starts at 4-byte boundary */
  916.       GLubyte *src = (GLubyte *) pixels + i * bytes_per_row;
  917.       for (j=0;j<width;j++) {
  918.          red[j]   = *src++;
  919.          green[j] = *src++;
  920.          blue[j]  = *src++;
  921.       }
  922.       (*DD.write_color_span)( width, x, y+i, red, green, blue, alpha, NULL);
  923.    }
  924.  
  925.    UNDEFARRAY( red );
  926.    UNDEFARRAY( green );
  927.    UNDEFARRAY( blue );
  928.    UNDEFARRAY( alpha );
  929.  
  930.    return GL_TRUE;
  931. }
  932.  
  933.  
  934.  
  935. /*
  936.  * Implements general glDrawPixels operation.
  937.  */
  938. void gl_drawpixels( GLsizei width, GLsizei height,
  939.             GLenum format, GLenum type, const GLvoid *pixels )
  940. {
  941.    if (INSIDE_BEGIN_END) {
  942.       gl_error( GL_INVALID_OPERATION, "glDrawPixels" );
  943.       return;
  944.    }
  945.  
  946.    if (CC.NewState) {
  947.       gl_update_state();
  948.    }
  949.  
  950.    if (CC.RenderMode==GL_RENDER) {
  951.       if (!CC.Current.RasterPosValid) {
  952.      return;
  953.       }
  954.       switch (format) {
  955.      case GL_COLOR_INDEX:
  956.             draw_index_pixels( width, height, type, pixels );
  957.         break;
  958.      case GL_STENCIL_INDEX:
  959.         draw_stencil_pixels( width, height, type, pixels );
  960.         break;
  961.      case GL_DEPTH_COMPONENT:
  962.         draw_depth_pixels( width, height, type, pixels );
  963.         break;
  964.      case GL_RED:
  965.      case GL_GREEN:
  966.      case GL_BLUE:
  967.      case GL_ALPHA:
  968.      case GL_RGB:
  969.      case GL_LUMINANCE:
  970.      case GL_LUMINANCE_ALPHA:
  971.      case GL_RGBA:
  972.             draw_color_pixels( width, height, format, type, pixels );
  973.         break;
  974.      default:
  975.         gl_error( GL_INVALID_ENUM, "glDrawPixels" );
  976.       }
  977.    }
  978.    else if (CC.RenderMode==GL_FEEDBACK) {
  979.       GLfloat color[4];
  980.       color[0] = CC.Current.IntColor[0] / CC.RedScale;
  981.       color[1] = CC.Current.IntColor[1] / CC.GreenScale;
  982.       color[2] = CC.Current.IntColor[2] / CC.BlueScale;
  983.       color[3] = CC.Current.IntColor[3] / CC.AlphaScale;
  984.       APPEND_TOKEN( (GLfloat) GL_DRAW_PIXEL_TOKEN );
  985.       gl_feedback_vertex( CC.Current.RasterPos[0],
  986.               CC.Current.RasterPos[1],
  987.               CC.Current.RasterPos[2],
  988.               CC.Current.RasterPos[3],
  989.               color, CC.Current.Index,
  990.               CC.Current.TexCoord );
  991.    }
  992.    else if (CC.RenderMode==GL_SELECT) {
  993.       /* TODO: verify that this is correct */
  994.       CC.HitFlag = GL_TRUE;
  995.       if (CC.Current.RasterPos[2] < CC.HitMinZ) {
  996.      CC.HitMinZ = CC.Current.RasterPos[2];
  997.       }
  998.       if (CC.Current.RasterPos[2] > CC.HitMaxZ) {
  999.      CC.HitMaxZ = CC.Current.RasterPos[2];
  1000.       }
  1001.    }
  1002. }
  1003.  
  1004.  
  1005.  
  1006. void glDrawPixels( GLsizei width, GLsizei height,
  1007.            GLenum format, GLenum type, const GLvoid *pixels )
  1008. {
  1009.    GLvoid *image;
  1010.  
  1011.    if (width<0 || height<0) {
  1012.       gl_error( GL_INVALID_VALUE, "glDrawPixels" );
  1013.       return;
  1014.    }
  1015.  
  1016.    /* Let the device driver take a crack at glDrawPixels */
  1017.    if (!CC.CompileFlag && DD.draw_pixels) {
  1018.       GLint x = (GLint) (CC.Current.RasterPos[0] + 0.5F);
  1019.       GLint y = (GLint) (CC.Current.RasterPos[1] + 0.5F);
  1020.       if ((*DD.draw_pixels)( x, y, width, height, format, type, GL_FALSE,
  1021.                              pixels )) {
  1022.          /* Device driver did the job */
  1023.          return;
  1024.       }
  1025.    }
  1026.  
  1027.    if (format==GL_RGB && type==GL_UNSIGNED_BYTE && CC.FastDrawPixels
  1028.        && !CC.CompileFlag && CC.RenderMode==GL_RENDER && CC.RasterMask==0) {
  1029.       /* optimized path */
  1030.       if (quickdraw_rgb( width, height, pixels )) {
  1031.          /* success */
  1032.          return;
  1033.       }
  1034.    }
  1035.  
  1036.    /* take the general path */
  1037.    image = gl_unpack( width, height, format, type, pixels );
  1038.    if (!image) {
  1039.       gl_error( GL_OUT_OF_MEMORY, "glDrawPixels" );
  1040.       return;
  1041.    }
  1042.  
  1043.    if (CC.CompileFlag) {
  1044.       gl_save_drawpixels( width, height, format, type, image );
  1045.    }
  1046.    if (CC.ExecuteFlag) {
  1047.       gl_drawpixels( width, height, format, type, image );
  1048.       if (!CC.CompileFlag) {
  1049.          /* may discard unpacked image now */
  1050.          free( image );
  1051.       }
  1052.    }
  1053. }
  1054.  
  1055.  
  1056.