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

  1. /* bitmap.c */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  1.2
  6.  * Copyright (C) 1995  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.  * glBitmap()
  26.  */
  27.  
  28.  
  29. /*
  30. $Id: bitmap.c,v 1.18 1996/02/26 15:06:42 brianp Exp $
  31.  
  32. $Log: bitmap.c,v $
  33.  * Revision 1.18  1996/02/26  15:06:42  brianp
  34.  * replaced CC.Current.Color with CC.Current.IntColor
  35.  *
  36.  * Revision 1.17  1996/01/22  15:26:03  brianp
  37.  * replaced gl_init_pb() with PB_INIT macro
  38.  *
  39.  * Revision 1.16  1996/01/16  15:06:38  brianp
  40.  * call gl_init_pb() if CC.NewState is set
  41.  *
  42.  * Revision 1.15  1995/12/30  00:46:10  brianp
  43.  * scale raster color to ints before calling PB_SET_COLOR
  44.  *
  45.  * Revision 1.14  1995/12/18  17:14:21  brianp
  46.  * replaced MAX_DEPTH with DEPTH_SCALE
  47.  *
  48.  * Revision 1.13  1995/09/07  19:46:56  brianp
  49.  * use CC.NewState convention
  50.  * truncate, don't round raster position to integer position
  51.  *
  52.  * Revision 1.12  1995/07/24  20:34:16  brianp
  53.  * replaced memset() with MEMSET() and memcpy() with MEMCPY()
  54.  *
  55.  * Revision 1.11  1995/07/11  15:29:33  brianp
  56.  * round rasterpos to nearest integer before drawing
  57.  *
  58.  * Revision 1.10  1995/06/20  16:19:10  brianp
  59.  * removed PB clipflag stuff
  60.  *
  61.  * Revision 1.9  1995/05/22  21:02:41  brianp
  62.  * Release 1.2
  63.  *
  64.  * Revision 1.8  1995/05/12  19:22:23  brianp
  65.  * added #include "macros.h"
  66.  *
  67.  * Revision 1.7  1995/05/12  19:20:19  brianp
  68.  * replaced CC.Mode!=0 with INSIDE_BEGIN_END
  69.  *
  70.  * Revision 1.6  1995/05/12  16:27:28  brianp
  71.  * better bitmap clipping scheme
  72.  *
  73.  * Revision 1.5  1995/03/13  15:58:42  brianp
  74.  * fixed bitmap bugs per Thorsten Ohl
  75.  *
  76.  * Revision 1.4  1995/03/07  14:19:41  brianp
  77.  * updated for new XSetForeground/GC scheme
  78.  *
  79.  * Revision 1.3  1995/03/04  19:29:44  brianp
  80.  * 1.1 beta revision
  81.  *
  82.  * Revision 1.2  1995/02/27  22:48:16  brianp
  83.  * modified for PB
  84.  *
  85.  * Revision 1.1  1995/02/24  14:16:45  brianp
  86.  * Initial revision
  87.  *
  88.  */
  89.  
  90.  
  91. #include <stdlib.h>
  92. #include <string.h>
  93. #include "context.h"
  94. #include "feedback.h"
  95. #include "list.h"
  96. #include "macros.h"
  97. #include "pb.h"
  98. #include "pixel.h"
  99.  
  100.  
  101.  
  102.  
  103.  
  104. void gl_bitmap( GLsizei width, GLsizei height,
  105.             GLfloat xorig, GLfloat yorig,
  106.             GLfloat xmove, GLfloat ymove,
  107.             const GLubyte *bitmap )
  108. {
  109.    /* Error checks */
  110.    if (width<0 || height<0) {
  111.       gl_error( GL_INVALID_VALUE, "glBitmap" );
  112.       return;
  113.    }
  114.    if (INSIDE_BEGIN_END) {
  115.       gl_error( GL_INVALID_OPERATION, "glBitmap" );
  116.       return;
  117.    }
  118.    if (CC.Current.RasterPosValid==GL_FALSE) {
  119.       /* do nothing */
  120.       return;
  121.    }
  122.  
  123.    if (CC.NewState) {
  124.       gl_update_state();
  125.       PB_INIT( GL_BITMAP );
  126.    }
  127.  
  128.    if (CC.RenderMode==GL_RENDER) {
  129.       GLint bx, by;      /* bitmap position */
  130.       GLint px, py, pz;  /* pixel position */
  131.       GLubyte *ptr;
  132.  
  133.       if (CC.RGBAflag) {
  134.          GLint r, g, b, a;
  135.          r = (GLint) (CC.Current.RasterColor[0] * CC.RedScale);
  136.          g = (GLint) (CC.Current.RasterColor[1] * CC.GreenScale);
  137.          b = (GLint) (CC.Current.RasterColor[2] * CC.BlueScale);
  138.          a = (GLint) (CC.Current.RasterColor[3] * CC.AlphaScale);
  139.      PB_SET_COLOR( r, g, b, a );
  140.       }
  141.       else {
  142.      PB_SET_INDEX( CC.Current.RasterIndex );
  143.       }
  144.  
  145.       px = (GLint) ( (CC.Current.RasterPos[0] - xorig) + 0.0F );
  146.       py = (GLint) ( (CC.Current.RasterPos[1] - yorig) + 0.0F );
  147.       pz = (GLint) ( CC.Current.RasterPos[2] * DEPTH_SCALE );
  148.       ptr = (GLubyte *) bitmap;
  149.  
  150.       for (by=0;by<height;by++) {
  151.      GLubyte bitmask;
  152.  
  153.      /* do a row */
  154.      bitmask = 128;
  155.      for (bx=0;bx<width;bx++) {
  156.         if (*ptr&bitmask) {
  157.            PB_WRITE_PIXEL( px+bx, py+by, pz );
  158.         }
  159.         bitmask = bitmask >> 1;
  160.         if (bitmask==0) {
  161.            ptr++;
  162.            bitmask = 128;
  163.         }
  164.      }
  165.  
  166.      PB_CHECK_FLUSH
  167.  
  168.      /* get ready for next row */
  169.      if (width%8)  ptr++;
  170.       }
  171.  
  172.       gl_flush_pb();
  173.  
  174.       /* update raster position */
  175.       CC.Current.RasterPos[0] += xmove;
  176.       CC.Current.RasterPos[1] += ymove;
  177.    }
  178.    else if (CC.RenderMode==GL_FEEDBACK) {
  179.       GLfloat color[4];
  180.       color[0] = CC.Current.IntColor[0] / CC.RedScale;
  181.       color[1] = CC.Current.IntColor[1] / CC.GreenScale;
  182.       color[2] = CC.Current.IntColor[2] / CC.BlueScale;
  183.       color[3] = CC.Current.IntColor[3] / CC.AlphaScale;
  184.       APPEND_TOKEN( (GLfloat) GL_BITMAP_TOKEN );
  185.       /* TODO: Verify XYZW values are correct: */
  186.       gl_feedback_vertex( CC.Current.RasterPos[0] - xorig,
  187.               CC.Current.RasterPos[1] - yorig,
  188.               CC.Current.RasterPos[2],
  189.               CC.Current.RasterPos[3],
  190.               color, CC.Current.Index,
  191.               CC.Current.TexCoord );
  192.    }
  193.    else if (CC.RenderMode==GL_SELECT) {
  194.       /* TODO: verify that this is correct */
  195.       CC.HitFlag = GL_TRUE;
  196.       if (CC.Current.RasterPos[2] < CC.HitMinZ) {
  197.      CC.HitMinZ = CC.Current.RasterPos[2];
  198.       }
  199.       if (CC.Current.RasterPos[2] > CC.HitMaxZ) {
  200.      CC.HitMaxZ = CC.Current.RasterPos[2];
  201.       }
  202.    }
  203. }
  204.  
  205.  
  206.  
  207. void glBitmap( GLsizei width, GLsizei height,
  208.            GLfloat xorig, GLfloat yorig,
  209.            GLfloat xmove, GLfloat ymove,
  210.            const GLubyte *bitmap )
  211. {
  212.    GLubyte *data;  /* The unpacked bitmap data */
  213.  
  214.    /*
  215.     * Data conversion:  we want:  unpack MSB first, unpack row length = width,
  216.     * unpack skip pixels = 0, unpack skip rows = 0, unpack alignment = 1
  217.     */
  218.    if (CC.UnpackLSBFirst==GL_FALSE && CC.UnpackAlignment==1
  219.        && CC.UnpackRowLength==0 && CC.UnpackSkipPixels==0
  220.        && CC.UnpackSkipRows==0) {
  221.       /* bitmap is already in desired form */
  222.       data = (GLubyte *) bitmap;
  223.    }
  224.    else {
  225.       /* Copy the data to a new buffer while applying all the glPixelStore
  226.        * pixel unpacking options.
  227.        */
  228.       GLuint bytes, bytes_per_row, width_in_bytes, skip;
  229.       GLuint i, j;
  230.       GLubyte *src, *dst;
  231.  
  232.       width_in_bytes = (width+7)/8;
  233.       bytes = width_in_bytes * height;
  234.  
  235.       /* allocate storage for unpacked bitmap data */
  236.       data = (GLubyte *) malloc( bytes );
  237.       if (!data) {
  238.      gl_error( GL_OUT_OF_MEMORY, "glBitmap" );
  239.      return;
  240.       }
  241.  
  242.       if (CC.UnpackRowLength==0) {
  243.      bytes_per_row = width_in_bytes;
  244.       }
  245.       else {
  246.      bytes_per_row = (CC.UnpackRowLength+7)/8;
  247.       }
  248.  
  249.       if (bytes_per_row % CC.UnpackAlignment) {
  250.      skip = CC.UnpackAlignment - bytes_per_row % CC.UnpackAlignment;
  251.       }
  252.       else {
  253.      skip = 0;
  254.       }
  255.  
  256.       skip += bytes_per_row - width_in_bytes;
  257.  
  258.       src = (GLubyte *) bitmap + CC.UnpackSkipPixels/8
  259.                       + CC.UnpackSkipRows*bytes_per_row;
  260.       dst = data;
  261.  
  262.       /* copy bytes from src to dst */
  263.       for (i=0;i<height;i++) {
  264.      for (j=0;j<width_in_bytes;j++) {
  265.         *dst++ = *src++;
  266.      }
  267.      src += skip;
  268.       }
  269.  
  270.       if (CC.UnpackLSBFirst) {
  271.      /* Flip the bits in each byte */
  272.      gl_flip_bytes( data, bytes );
  273.       }
  274.    }
  275.  
  276.    if (CC.CompileFlag) {
  277.       if (data==bitmap) {
  278.      /* make a copy to save in the display list */
  279.      GLuint bytes = (width + 7) / 8 * height;
  280.      data = (GLubyte *) malloc( bytes );
  281.      if (data) {
  282.         MEMCPY( data, bitmap, bytes );
  283.      }
  284.       }
  285.       gl_save_bitmap( width, height, xorig, yorig, xmove, ymove, data );
  286.    }
  287.    if (CC.ExecuteFlag) {
  288.       gl_bitmap( width, height, xorig, yorig, xmove, ymove, data );
  289.       if (!CC.CompileFlag && data!=bitmap) {
  290.      /* Free the unpacked data */
  291.      free( data );
  292.       }
  293.    }
  294. }
  295.  
  296.  
  297.