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

  1. /* $Id: varray.c,v 1.16 1997/08/14 01:15:47 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: varray.c,v $
  26.  * Revision 1.16  1997/08/14 01:15:47  brianp
  27.  * gl_ArrayElement()'s assignment of current normal was wrong
  28.  *
  29.  * Revision 1.15  1997/07/24 01:25:54  brianp
  30.  * changed precompiled header symbol from PCH to PC_HEADER
  31.  *
  32.  * Revision 1.14  1997/06/20 02:50:19  brianp
  33.  * replaced Current.IntColor with Current.ByteColor
  34.  *
  35.  * Revision 1.13  1997/05/28 03:26:49  brianp
  36.  * added precompiled header (PCH) support
  37.  *
  38.  * Revision 1.12  1997/05/24 12:07:43  brianp
  39.  * colors weren't being used in gl_ArrayElement()
  40.  *
  41.  * Revision 1.11  1997/04/20 20:29:11  brianp
  42.  * replaced abort() with gl_problem()
  43.  *
  44.  * Revision 1.10  1997/04/02 03:12:31  brianp
  45.  * misc changes for new vertex buffer organization
  46.  *
  47.  * Revision 1.9  1997/01/30 21:05:03  brianp
  48.  * moved gl_GetPointerv() to get.c
  49.  *
  50.  * Revision 1.8  1996/12/18 20:00:57  brianp
  51.  * gl_set_material() now takes a bitmask instead of face and pname
  52.  *
  53.  * Revision 1.7  1996/12/07 10:21:28  brianp
  54.  * call gl_set_material() instead of gl_Materialfv()
  55.  *
  56.  * Revision 1.6  1996/11/09 03:12:34  brianp
  57.  * now call gl_render_vb() after gl_transform_vb_part2() call
  58.  *
  59.  * Revision 1.5  1996/10/08 00:05:06  brianp
  60.  * added some missing stuff to gl_ArrayElement()
  61.  *
  62.  * Revision 1.4  1996/10/04 02:37:06  brianp
  63.  * gl_ArrayElement() wasn't always initializing vertex Z and W values
  64.  *
  65.  * Revision 1.3  1996/10/03 00:47:56  brianp
  66.  * added #include <stdlib.h> for abort()
  67.  *
  68.  * Revision 1.2  1996/09/27 01:33:07  brianp
  69.  * added missing default cases to switches
  70.  *
  71.  * Revision 1.1  1996/09/13 01:38:16  brianp
  72.  * Initial revision
  73.  *
  74.  */
  75.  
  76.  
  77.  
  78. /*
  79.  * NOTE:  At this time, only three vertex array configurations are optimized:
  80.  *  1.  glVertex3fv(), zero stride
  81.  *  2.  glNormal3fv() with glVertex3fv(), zero stride
  82.  *  3.  glNormal3fv() with glVertex4fv(), zero stride
  83.  *
  84.  * More optimized array configurations can be added.
  85.  */
  86.  
  87.  
  88. #ifdef PC_HEADER
  89. #include "all.h"
  90. #else
  91. #include <stdlib.h>
  92. #include <string.h>
  93. #include "context.h"
  94. #include "enable.h"
  95. #include "dlist.h"
  96. #include "light.h"
  97. #include "macros.h"
  98. #include "types.h"
  99. #include "varray.h"
  100. #include "vb.h"
  101. #include "vbfill.h"
  102. #include "vbrender.h"
  103. #include "vbxform.h"
  104. #include "xform.h"
  105. #endif
  106.  
  107.  
  108. void gl_VertexPointer( GLcontext *ctx,
  109.                GLint size, GLenum type, GLsizei stride,
  110.                const GLvoid *ptr )
  111. {
  112.    if (size<2 || size>4) {
  113.       gl_error( ctx, GL_INVALID_VALUE, "glVertexPointer(size)" );
  114.       return;
  115.    }
  116.    if (stride<0) {
  117.       gl_error( ctx, GL_INVALID_VALUE, "glVertexPointer(stride)" );
  118.       return;
  119.    }
  120.    switch (type) {
  121.       case GL_SHORT:
  122.      ctx->Array.VertexStrideB = stride ? stride : size*sizeof(GLshort);
  123.      break;
  124.       case GL_INT:
  125.      ctx->Array.VertexStrideB = stride ? stride : size*sizeof(GLint);
  126.      break;
  127.       case GL_FLOAT:
  128.      ctx->Array.VertexStrideB = stride ? stride : size*sizeof(GLfloat);
  129.      break;
  130.       case GL_DOUBLE:
  131.      ctx->Array.VertexStrideB = stride ? stride : size*sizeof(GLdouble);
  132.      break;
  133.       default:
  134.      gl_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" );
  135.      return;
  136.    }
  137.    ctx->Array.VertexSize = size;
  138.    ctx->Array.VertexType = type;
  139.    ctx->Array.VertexStride = stride;
  140.    ctx->Array.VertexPtr = (void *) ptr;
  141. }
  142.  
  143.  
  144.  
  145.  
  146. void gl_NormalPointer( GLcontext *ctx,
  147.                GLenum type, GLsizei stride, const GLvoid *ptr )
  148. {
  149.    if (stride<0) {
  150.       gl_error( ctx, GL_INVALID_VALUE, "glNormalPointer(stride)" );
  151.       return;
  152.    }
  153.    switch (type) {
  154.       case GL_BYTE:
  155.      ctx->Array.NormalStrideB = stride ? stride : 3*sizeof(GLbyte);
  156.      break;
  157.       case GL_SHORT:
  158.      ctx->Array.NormalStrideB = stride ? stride : 3*sizeof(GLshort);
  159.      break;
  160.       case GL_INT:
  161.      ctx->Array.NormalStrideB = stride ? stride : 3*sizeof(GLint);
  162.      break;
  163.       case GL_FLOAT:
  164.      ctx->Array.NormalStrideB = stride ? stride : 3*sizeof(GLfloat);
  165.      break;
  166.       case GL_DOUBLE:
  167.      ctx->Array.NormalStrideB = stride ? stride : 3*sizeof(GLdouble);
  168.      break;
  169.       default:
  170.      gl_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" );
  171.      return;
  172.    }
  173.    ctx->Array.NormalType = type;
  174.    ctx->Array.NormalStride = stride;
  175.    ctx->Array.NormalPtr = (void *) ptr;
  176. }
  177.  
  178.  
  179.  
  180. void gl_ColorPointer( GLcontext *ctx,
  181.               GLint size, GLenum type, GLsizei stride,
  182.               const GLvoid *ptr )
  183. {
  184.    if (size<3 || size>4) {
  185.       gl_error( ctx, GL_INVALID_VALUE, "glColorPointer(size)" );
  186.       return;
  187.    }
  188.    if (stride<0) {
  189.       gl_error( ctx, GL_INVALID_VALUE, "glColorPointer(stride)" );
  190.       return;
  191.    }
  192.    switch (type) {
  193.       case GL_BYTE:
  194.      ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLbyte);
  195.      break;
  196.       case GL_UNSIGNED_BYTE:
  197.      ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLubyte);
  198.      break;
  199.       case GL_SHORT:
  200.      ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLshort);
  201.      break;
  202.       case GL_UNSIGNED_SHORT:
  203.      ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLushort);
  204.      break;
  205.       case GL_INT:
  206.      ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLint);
  207.      break;
  208.       case GL_UNSIGNED_INT:
  209.      ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLuint);
  210.      break;
  211.       case GL_FLOAT:
  212.      ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLfloat);
  213.      break;
  214.       case GL_DOUBLE:
  215.      ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLdouble);
  216.      break;
  217.       default:
  218.      gl_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" );
  219.      return;
  220.    }
  221.    ctx->Array.ColorSize = size;
  222.    ctx->Array.ColorType = type;
  223.    ctx->Array.ColorStride = stride;
  224.    ctx->Array.ColorPtr = (void *) ptr;
  225. }
  226.  
  227.  
  228.  
  229. void gl_IndexPointer( GLcontext *ctx,
  230.               GLenum type, GLsizei stride, const GLvoid *ptr )
  231. {
  232.    if (stride<0) {
  233.       gl_error( ctx, GL_INVALID_VALUE, "glIndexPointer(stride)" );
  234.       return;
  235.    }
  236.    switch (type) {
  237.       case GL_SHORT:
  238.      ctx->Array.IndexStrideB = stride ? stride : sizeof(GLbyte);
  239.      break;
  240.       case GL_INT:
  241.      ctx->Array.IndexStrideB = stride ? stride : sizeof(GLint);
  242.      break;
  243.       case GL_FLOAT:
  244.      ctx->Array.IndexStrideB = stride ? stride : sizeof(GLfloat);
  245.      break;
  246.       case GL_DOUBLE:
  247.      ctx->Array.IndexStrideB = stride ? stride : sizeof(GLdouble);
  248.      break;
  249.       default:
  250.      gl_error( ctx, GL_INVALID_ENUM, "glIndexPointer(type)" );
  251.      return;
  252.    }
  253.    ctx->Array.IndexType = type;
  254.    ctx->Array.IndexStride = stride;
  255.    ctx->Array.IndexPtr = (void *) ptr;
  256. }
  257.  
  258.  
  259.  
  260. void gl_TexCoordPointer( GLcontext *ctx,
  261.              GLint size, GLenum type, GLsizei stride,
  262.              const GLvoid *ptr )
  263. {
  264.    if (size<1 || size>4) {
  265.       gl_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(size)" );
  266.       return;
  267.    }
  268.    switch (type) {
  269.       case GL_SHORT:
  270.      ctx->Array.TexCoordStrideB = stride ? stride : size*sizeof(GLshort);
  271.      break;
  272.       case GL_INT:
  273.      ctx->Array.TexCoordStrideB = stride ? stride : size*sizeof(GLint);
  274.      break;
  275.       case GL_FLOAT:
  276.      ctx->Array.TexCoordStrideB = stride ? stride : size*sizeof(GLfloat);
  277.      break;
  278.       case GL_DOUBLE:
  279.      ctx->Array.TexCoordStrideB = stride ? stride : size*sizeof(GLdouble);
  280.      break;
  281.       default:
  282.      gl_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" );
  283.      return;
  284.    }
  285.    if (stride<0) {
  286.       gl_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(stride)" );
  287.       return;
  288.    }
  289.    ctx->Array.TexCoordSize = size;
  290.    ctx->Array.TexCoordType = type;
  291.    ctx->Array.TexCoordStride = stride;
  292.    ctx->Array.TexCoordPtr = (void *) ptr;
  293. }
  294.  
  295.  
  296.  
  297. void gl_EdgeFlagPointer( GLcontext *ctx,
  298.              GLsizei stride, const GLboolean *ptr )
  299. {
  300.    if (stride<0) {
  301.       gl_error( ctx, GL_INVALID_VALUE, "glEdgeFlagPointer(stride)" );
  302.       return;
  303.    }
  304.    ctx->Array.EdgeFlagStride = stride;
  305.    ctx->Array.EdgeFlagStrideB = stride ? stride : sizeof(GLboolean);
  306.    ctx->Array.EdgeFlagPtr = (GLboolean *) ptr;
  307. }
  308.  
  309.  
  310.  
  311. /*
  312.  * Execute
  313.  */
  314. void gl_ArrayElement( GLcontext *ctx, GLint i )
  315. {
  316.    struct vertex_buffer *VB = ctx->VB;
  317.    GLint count = VB->Count;
  318.  
  319.    /* copy vertex data into the Vertex Buffer */
  320.  
  321.    if (ctx->Array.NormalEnabled) {
  322.       GLbyte *p = (GLbyte*) ctx->Array.NormalPtr
  323.           + i * ctx->Array.NormalStrideB;
  324.       switch (ctx->Array.NormalType) {
  325.      case GL_BYTE:
  326.         VB->Normal[count][0] = BYTE_TO_FLOAT( p[0] );
  327.         VB->Normal[count][1] = BYTE_TO_FLOAT( p[1] );
  328.         VB->Normal[count][2] = BYTE_TO_FLOAT( p[2] );
  329.         break;
  330.      case GL_SHORT:
  331.         VB->Normal[count][0] = SHORT_TO_FLOAT( ((GLshort*)p)[0] );
  332.         VB->Normal[count][1] = SHORT_TO_FLOAT( ((GLshort*)p)[1] );
  333.         VB->Normal[count][2] = SHORT_TO_FLOAT( ((GLshort*)p)[2] );
  334.         break;
  335.      case GL_INT:
  336.         VB->Normal[count][0] = INT_TO_FLOAT( ((GLint*)p)[0] );
  337.         VB->Normal[count][1] = INT_TO_FLOAT( ((GLint*)p)[1] );
  338.         VB->Normal[count][2] = INT_TO_FLOAT( ((GLint*)p)[2] );
  339.         break;
  340.      case GL_FLOAT:
  341.         VB->Normal[count][0] = ((GLfloat*)p)[0];
  342.         VB->Normal[count][1] = ((GLfloat*)p)[1];
  343.         VB->Normal[count][2] = ((GLfloat*)p)[2];
  344.         break;
  345.      case GL_DOUBLE:
  346.         VB->Normal[count][0] = ((GLdouble*)p)[0];
  347.         VB->Normal[count][1] = ((GLdouble*)p)[1];
  348.         VB->Normal[count][2] = ((GLdouble*)p)[2];
  349.         break;
  350.      default:
  351.         gl_problem(ctx, "Bad normal type in gl_ArrayElement");
  352.         return;
  353.       }
  354.       VB->MonoNormal = GL_FALSE;
  355.    }
  356.    else {
  357.       VB->Normal[count][0] = ctx->Current.Normal[0];
  358.       VB->Normal[count][1] = ctx->Current.Normal[1];
  359.       VB->Normal[count][2] = ctx->Current.Normal[2];
  360.    } 
  361.  
  362.    /* TODO: directly set VB->Fcolor instead of calling a glColor command */
  363.    if (ctx->Array.ColorEnabled) {
  364.       GLbyte *p = (GLbyte*) ctx->Array.ColorPtr + i * ctx->Array.ColorStrideB;
  365.       switch (ctx->Array.ColorType) {
  366.      case GL_BYTE:
  367.         switch (ctx->Array.ColorSize) {
  368.            case 4:   glColor4bv( (GLbyte*) p );   break;
  369.            case 3:   glColor3bv( (GLbyte*) p );   break;
  370.         }
  371.         break;
  372.      case GL_UNSIGNED_BYTE:
  373.         switch (ctx->Array.ColorSize) {
  374.            case 3:   glColor3ubv( (GLubyte*) p );   break;
  375.            case 4:   glColor4ubv( (GLubyte*) p );   break;
  376.         }
  377.         break;
  378.      case GL_SHORT:
  379.         switch (ctx->Array.ColorSize) {
  380.            case 3:   glColor3sv( (GLshort*) p );   break;
  381.            case 4:   glColor4sv( (GLshort*) p );   break;
  382.         }
  383.         break;
  384.      case GL_UNSIGNED_SHORT:
  385.         switch (ctx->Array.ColorSize) {
  386.            case 3:   glColor3usv( (GLushort*) p );   break;
  387.            case 4:   glColor4usv( (GLushort*) p );   break;
  388.         }
  389.         break;
  390.      case GL_INT:
  391.         switch (ctx->Array.ColorSize) {
  392.            case 3:   glColor3iv( (GLint*) p );   break;
  393.            case 4:   glColor4iv( (GLint*) p );   break;
  394.         }
  395.         break;
  396.      case GL_UNSIGNED_INT:
  397.         switch (ctx->Array.ColorSize) {
  398.            case 3:   glColor3uiv( (GLuint*) p );   break;
  399.            case 4:   glColor4uiv( (GLuint*) p );   break;
  400.         }
  401.         break;
  402.      case GL_FLOAT:
  403.         switch (ctx->Array.ColorSize) {
  404.            case 3:   glColor3fv( (GLfloat*) p );   break;
  405.            case 4:   glColor4fv( (GLfloat*) p );   break;
  406.         }
  407.         break;
  408.      case GL_DOUBLE:
  409.         switch (ctx->Array.ColorSize) {
  410.            case 3:   glColor3dv( (GLdouble*) p );   break;
  411.            case 4:   glColor4dv( (GLdouble*) p );   break;
  412.         }
  413.         break;
  414.      default:
  415.         gl_problem(ctx, "Bad color type in gl_ArrayElement");
  416.         return;
  417.       }
  418.       ctx->VB->MonoColor = GL_FALSE;
  419.    }
  420.  
  421.    /* current color has been updated. store in vertex buffer now */
  422.    {
  423.       COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor );
  424.       if (ctx->Light.ColorMaterialEnabled) {
  425.      GLfloat color[4];
  426.      color[0] = ctx->Current.ByteColor[0] * ctx->Visual->InvRedScale;
  427.      color[1] = ctx->Current.ByteColor[1] * ctx->Visual->InvGreenScale;
  428.      color[2] = ctx->Current.ByteColor[2] * ctx->Visual->InvBlueScale;
  429.      color[3] = ctx->Current.ByteColor[3] * ctx->Visual->InvAlphaScale;
  430.      gl_set_material( ctx, ctx->Light.ColorMaterialBitmask, color );
  431.       }
  432.    }
  433.  
  434.    if (ctx->Array.IndexEnabled) {
  435.       GLbyte *p = (GLbyte*) ctx->Array.IndexPtr + i * ctx->Array.IndexStrideB;
  436.       switch (ctx->Array.IndexType) {
  437.      case GL_SHORT:
  438.         VB->Findex[count] = (GLuint) (*((GLshort*) p));
  439.         break;
  440.      case GL_INT:
  441.         VB->Findex[count] = (GLuint) (*((GLint*) p));
  442.         break;
  443.      case GL_FLOAT:
  444.         VB->Findex[count] = (GLuint) (*((GLfloat*) p));
  445.         break;
  446.      case GL_DOUBLE:
  447.         VB->Findex[count] = (GLuint) (*((GLdouble*) p));
  448.         break;
  449.      default:
  450.         gl_problem(ctx, "Bad index type in gl_ArrayElement");
  451.         return;
  452.       }
  453.       ctx->VB->MonoColor = GL_FALSE;
  454.    }
  455.    else {
  456.       VB->Findex[count] = ctx->Current.Index;
  457.    }
  458.  
  459.    if (ctx->Array.TexCoordEnabled) {
  460.       GLbyte *p = (GLbyte*) ctx->Array.TexCoordPtr
  461.           + i * ctx->Array.TexCoordStrideB;
  462.       VB->TexCoord[count][1] = 0.0F;
  463.       VB->TexCoord[count][2] = 0.0F;
  464.       VB->TexCoord[count][3] = 1.0F;
  465.       switch (ctx->Array.TexCoordType) {
  466.      case GL_SHORT:
  467.         switch (ctx->Array.TexCoordSize) {
  468.            /* FALL THROUGH! */
  469.            case 4:   VB->TexCoord[count][3] = ((GLshort*) p)[3];
  470.            case 3:   VB->TexCoord[count][2] = ((GLshort*) p)[2];
  471.            case 2:   VB->TexCoord[count][1] = ((GLshort*) p)[1];
  472.            case 1:   VB->TexCoord[count][0] = ((GLshort*) p)[0];
  473.         }
  474.         break;
  475.      case GL_INT:
  476.         switch (ctx->Array.TexCoordSize) {
  477.            /* FALL THROUGH! */
  478.            case 4:   VB->TexCoord[count][3] = ((GLint*) p)[3];
  479.            case 3:   VB->TexCoord[count][2] = ((GLint*) p)[2];
  480.            case 2:   VB->TexCoord[count][1] = ((GLint*) p)[1];
  481.            case 1:   VB->TexCoord[count][0] = ((GLint*) p)[0];
  482.         }
  483.         break;
  484.      case GL_FLOAT:
  485.         switch (ctx->Array.TexCoordSize) {
  486.            /* FALL THROUGH! */
  487.            case 4:   VB->TexCoord[count][3] = ((GLfloat*) p)[3];
  488.            case 3:   VB->TexCoord[count][2] = ((GLfloat*) p)[2];
  489.            case 2:   VB->TexCoord[count][1] = ((GLfloat*) p)[1];
  490.            case 1:   VB->TexCoord[count][0] = ((GLfloat*) p)[0];
  491.         }
  492.         break;
  493.      case GL_DOUBLE:
  494.         switch (ctx->Array.TexCoordSize) {
  495.            /* FALL THROUGH! */
  496.            case 4:   VB->TexCoord[count][3] = ((GLdouble*) p)[3];
  497.            case 3:   VB->TexCoord[count][2] = ((GLdouble*) p)[2];
  498.            case 2:   VB->TexCoord[count][1] = ((GLdouble*) p)[1];
  499.            case 1:   VB->TexCoord[count][0] = ((GLdouble*) p)[0];
  500.         }
  501.         break;
  502.      default:
  503.         gl_problem(ctx, "Bad texcoord type in gl_ArrayElement");
  504.         return;
  505.       }
  506.    }
  507.    else {
  508.       COPY_4V( VB->TexCoord[count], ctx->Current.TexCoord );
  509.    }
  510.  
  511.    if (ctx->Array.EdgeFlagEnabled) {
  512.       GLbyte *b = (GLbyte*) ctx->Array.EdgeFlagPtr
  513.           + i * ctx->Array.EdgeFlagStrideB;
  514.       VB->Edgeflag[count] = *((GLboolean*) b);
  515.    }
  516.    else {
  517.       VB->Edgeflag[count] = ctx->Current.EdgeFlag;
  518.    }
  519.  
  520.    if (ctx->Array.VertexEnabled) {
  521.       GLbyte *b = (GLbyte*) ctx->Array.VertexPtr
  522.           + i * ctx->Array.VertexStrideB;
  523.       VB->Obj[count][2] = 0.0F;
  524.       VB->Obj[count][3] = 1.0F;
  525.       switch (ctx->Array.VertexType) {
  526.      case GL_SHORT:
  527.         switch (ctx->Array.VertexSize) {
  528.            /* FALL THROUGH */
  529.            case 4:   VB->Obj[count][3] = ((GLshort*) b)[3];
  530.            case 3:   VB->Obj[count][2] = ((GLshort*) b)[2];
  531.            case 2:   VB->Obj[count][1] = ((GLshort*) b)[1];
  532.              VB->Obj[count][0] = ((GLshort*) b)[0];
  533.         }
  534.         break;
  535.      case GL_INT:
  536.         switch (ctx->Array.VertexSize) {
  537.            /* FALL THROUGH */
  538.            case 4:   VB->Obj[count][3] = ((GLint*) b)[3];
  539.            case 3:   VB->Obj[count][2] = ((GLint*) b)[2];
  540.            case 2:   VB->Obj[count][1] = ((GLint*) b)[1];
  541.              VB->Obj[count][0] = ((GLint*) b)[0];
  542.         }
  543.         break;
  544.      case GL_FLOAT:
  545.         switch (ctx->Array.VertexSize) {
  546.            /* FALL THROUGH */
  547.            case 4:   VB->Obj[count][3] = ((GLfloat*) b)[3];
  548.            case 3:   VB->Obj[count][2] = ((GLfloat*) b)[2];
  549.            case 2:   VB->Obj[count][1] = ((GLfloat*) b)[1];
  550.              VB->Obj[count][0] = ((GLfloat*) b)[0];
  551.         }
  552.         break;
  553.      case GL_DOUBLE:
  554.         switch (ctx->Array.VertexSize) {
  555.            /* FALL THROUGH */
  556.            case 4:   VB->Obj[count][3] = ((GLdouble*) b)[3];
  557.            case 3:   VB->Obj[count][2] = ((GLdouble*) b)[2];
  558.            case 2:   VB->Obj[count][1] = ((GLdouble*) b)[1];
  559.              VB->Obj[count][0] = ((GLdouble*) b)[0];
  560.         }
  561.         break;
  562.      default:
  563.         gl_problem(ctx, "Bad vertex type in gl_ArrayElement");
  564.         return;
  565.       }
  566.  
  567.       /* Only store vertex if Vertex array pointer is enabled */
  568.       count++;
  569.       VB->Count = count;
  570.       if (count==VB_MAX) {
  571.      gl_transform_vb_part1( ctx, GL_FALSE );
  572.       }
  573.  
  574.    }
  575.    else {
  576.       /* vertex array pointer not enabled: no vertex to process */
  577.    }
  578. }
  579.  
  580.  
  581.  
  582.  
  583. /*
  584.  * Save into display list
  585.  * Use external API entry points since speed isn't too important here
  586.  * and makes the code simpler.  Also, if GL_COMPILE_AND_EXECUTE then
  587.  * execute will happen too.
  588.  */
  589. void gl_save_ArrayElement( GLcontext *ctx, GLint i )
  590. {
  591.    if (ctx->Array.NormalEnabled) {
  592.       GLbyte *p = (GLbyte*) ctx->Array.NormalPtr
  593.           + i * ctx->Array.NormalStrideB;
  594.       switch (ctx->Array.NormalType) {
  595.      case GL_BYTE:
  596.         glNormal3bv( (GLbyte*) p );
  597.         break;
  598.      case GL_SHORT:
  599.         glNormal3sv( (GLshort*) p );
  600.         break;
  601.      case GL_INT:
  602.         glNormal3iv( (GLint*) p );
  603.         break;
  604.      case GL_FLOAT:
  605.         glNormal3fv( (GLfloat*) p );
  606.         break;
  607.      case GL_DOUBLE:
  608.         glNormal3dv( (GLdouble*) p );
  609.         break;
  610.      default:
  611.         gl_problem(ctx, "Bad normal type in gl_save_ArrayElement");
  612.         return;
  613.       }
  614.    }
  615.  
  616.    if (ctx->Array.ColorEnabled) {
  617.       GLbyte *p = (GLbyte*) ctx->Array.ColorPtr + i * ctx->Array.ColorStrideB;
  618.       switch (ctx->Array.ColorType) {
  619.      case GL_BYTE:
  620.         switch (ctx->Array.ColorSize) {
  621.            case 3:   glColor3bv( (GLbyte*) p );   break;
  622.            case 4:   glColor4bv( (GLbyte*) p );   break;
  623.         }
  624.         break;
  625.      case GL_UNSIGNED_BYTE:
  626.         switch (ctx->Array.ColorSize) {
  627.            case 3:   glColor3ubv( (GLubyte*) p );   break;
  628.            case 4:   glColor4ubv( (GLubyte*) p );   break;
  629.         }
  630.         break;
  631.      case GL_SHORT:
  632.         switch (ctx->Array.ColorSize) {
  633.            case 3:   glColor3sv( (GLshort*) p );   break;
  634.            case 4:   glColor4sv( (GLshort*) p );   break;
  635.         }
  636.         break;
  637.      case GL_UNSIGNED_SHORT:
  638.         switch (ctx->Array.ColorSize) {
  639.            case 3:   glColor3usv( (GLushort*) p );   break;
  640.            case 4:   glColor4usv( (GLushort*) p );   break;
  641.         }
  642.         break;
  643.      case GL_INT:
  644.         switch (ctx->Array.ColorSize) {
  645.            case 3:   glColor3iv( (GLint*) p );   break;
  646.            case 4:   glColor4iv( (GLint*) p );   break;
  647.         }
  648.         break;
  649.      case GL_UNSIGNED_INT:
  650.         switch (ctx->Array.ColorSize) {
  651.            case 3:   glColor3uiv( (GLuint*) p );   break;
  652.            case 4:   glColor4uiv( (GLuint*) p );   break;
  653.         }
  654.         break;
  655.      case GL_FLOAT:
  656.         switch (ctx->Array.ColorSize) {
  657.            case 3:   glColor3fv( (GLfloat*) p );   break;
  658.            case 4:   glColor4fv( (GLfloat*) p );   break;
  659.         }
  660.         break;
  661.      case GL_DOUBLE:
  662.         switch (ctx->Array.ColorSize) {
  663.            case 3:   glColor3dv( (GLdouble*) p );   break;
  664.            case 4:   glColor4dv( (GLdouble*) p );   break;
  665.         }
  666.         break;
  667.      default:
  668.         gl_problem(ctx, "Bad color type in gl_save_ArrayElement");
  669.         return;
  670.       }
  671.    }
  672.  
  673.    if (ctx->Array.IndexEnabled) {
  674.       GLbyte *p = (GLbyte*) ctx->Array.IndexPtr + i * ctx->Array.IndexStrideB;
  675.       switch (ctx->Array.IndexType) {
  676.      case GL_SHORT:
  677.         glIndexsv( (GLshort*) p );
  678.         break;
  679.      case GL_INT:
  680.         glIndexiv( (GLint*) p );
  681.         break;
  682.      case GL_FLOAT:
  683.         glIndexfv( (GLfloat*) p );
  684.         break;
  685.      case GL_DOUBLE:
  686.         glIndexdv( (GLdouble*) p );
  687.         break;
  688.      default:
  689.         gl_problem(ctx, "Bad index type in gl_save_ArrayElement");
  690.         return;
  691.       }
  692.    }
  693.  
  694.    if (ctx->Array.TexCoordEnabled) {
  695.       GLbyte *p = (GLbyte*) ctx->Array.TexCoordPtr
  696.           + i * ctx->Array.TexCoordStrideB;
  697.       switch (ctx->Array.TexCoordType) {
  698.      case GL_SHORT:
  699.         switch (ctx->Array.TexCoordSize) {
  700.            case 1:   glTexCoord1sv( (GLshort*) p );   break;
  701.            case 2:   glTexCoord2sv( (GLshort*) p );   break;
  702.            case 3:   glTexCoord3sv( (GLshort*) p );   break;
  703.            case 4:   glTexCoord4sv( (GLshort*) p );   break;
  704.         }
  705.         break;
  706.      case GL_INT:
  707.         switch (ctx->Array.TexCoordSize) {
  708.            case 1:   glTexCoord1iv( (GLint*) p );   break;
  709.            case 2:   glTexCoord2iv( (GLint*) p );   break;
  710.            case 3:   glTexCoord3iv( (GLint*) p );   break;
  711.            case 4:   glTexCoord4iv( (GLint*) p );   break;
  712.         }
  713.         break;
  714.      case GL_FLOAT:
  715.         switch (ctx->Array.TexCoordSize) {
  716.            case 1:   glTexCoord1fv( (GLfloat*) p );   break;
  717.            case 2:   glTexCoord2fv( (GLfloat*) p );   break;
  718.            case 3:   glTexCoord3fv( (GLfloat*) p );   break;
  719.            case 4:   glTexCoord4fv( (GLfloat*) p );   break;
  720.         }
  721.         break;
  722.      case GL_DOUBLE:
  723.         switch (ctx->Array.TexCoordSize) {
  724.            case 1:   glTexCoord1dv( (GLdouble*) p );   break;
  725.            case 2:   glTexCoord2dv( (GLdouble*) p );   break;
  726.            case 3:   glTexCoord3dv( (GLdouble*) p );   break;
  727.            case 4:   glTexCoord4dv( (GLdouble*) p );   break;
  728.         }
  729.         break;
  730.      default:
  731.         gl_problem(ctx, "Bad texcoord type in gl_save_ArrayElement");
  732.         return;
  733.       }
  734.    }
  735.  
  736.    if (ctx->Array.EdgeFlagEnabled) {
  737.       GLbyte *b = (GLbyte*) ctx->Array.EdgeFlagPtr + i * ctx->Array.EdgeFlagStrideB;
  738.       glEdgeFlagv( (GLboolean*) b );
  739.    }
  740.  
  741.    if (ctx->Array.VertexEnabled) {
  742.       GLbyte *b = (GLbyte*) ctx->Array.VertexPtr
  743.           + i * ctx->Array.VertexStrideB;
  744.       switch (ctx->Array.VertexType) {
  745.      case GL_SHORT:
  746.         switch (ctx->Array.VertexSize) {
  747.            case 2:   glVertex2sv( (GLshort*) b );   break;
  748.            case 3:   glVertex3sv( (GLshort*) b );   break;
  749.            case 4:   glVertex4sv( (GLshort*) b );   break;
  750.         }
  751.         break;
  752.      case GL_INT:
  753.         switch (ctx->Array.VertexSize) {
  754.            case 2:   glVertex2iv( (GLint*) b );   break;
  755.            case 3:   glVertex3iv( (GLint*) b );   break;
  756.            case 4:   glVertex4iv( (GLint*) b );   break;
  757.         }
  758.         break;
  759.      case GL_FLOAT:
  760.         switch (ctx->Array.VertexSize) {
  761.            case 2:   glVertex2fv( (GLfloat*) b );   break;
  762.            case 3:   glVertex3fv( (GLfloat*) b );   break;
  763.            case 4:   glVertex4fv( (GLfloat*) b );   break;
  764.         }
  765.         break;
  766.      case GL_DOUBLE:
  767.         switch (ctx->Array.VertexSize) {
  768.            case 2:   glVertex2dv( (GLdouble*) b );   break;
  769.            case 3:   glVertex3dv( (GLdouble*) b );   break;
  770.            case 4:   glVertex4dv( (GLdouble*) b );   break;
  771.         }
  772.         break;
  773.      default:
  774.         gl_problem(ctx, "Bad vertex type in gl_save_ArrayElement");
  775.         return;
  776.       }
  777.    }
  778. }
  779.  
  780.  
  781.  
  782. /*
  783.  * Execute
  784.  */
  785. void gl_DrawArrays( GLcontext *ctx,
  786.             GLenum mode, GLint first, GLsizei count )
  787. {
  788.    struct vertex_buffer* VB = ctx->VB;
  789.  
  790.    GLint i;
  791.    GLboolean need_edges;
  792.  
  793.    if (INSIDE_BEGIN_END(ctx)) {
  794.       gl_error( ctx, GL_INVALID_OPERATION, "glDrawArrays" );
  795.       return;
  796.    }
  797.    if (count<0) {
  798.       gl_error( ctx, GL_INVALID_VALUE, "glDrawArrays(count)" );
  799.       return;
  800.    }
  801.  
  802.    if (ctx->Primitive==GL_TRIANGLES || ctx->Primitive==GL_QUADS
  803.        || ctx->Primitive==GL_POLYGON) {
  804.       need_edges = GL_TRUE;
  805.    }
  806.    else {
  807.       need_edges = GL_FALSE;
  808.    }
  809.  
  810.    if (!ctx->Light.Enabled
  811.        && !ctx->Texture.Enabled
  812.        && ctx->Array.VertexEnabled && ctx->Array.VertexType==GL_FLOAT
  813.        && ctx->Array.VertexStride==0 && ctx->Array.VertexSize==3
  814.        && !ctx->Array.NormalEnabled
  815.        && !ctx->Array.ColorEnabled
  816.        && !ctx->Array.IndexEnabled
  817.        && !ctx->Array.TexCoordEnabled
  818.        && !ctx->Array.EdgeFlagEnabled) {
  819.       /*
  820.        * SPECIAL CASE:  glVertex3fv() with no lighting
  821.        */
  822. #ifndef __STORM__
  823.       GLfloat (*vptr)[3];
  824. #else
  825.       float (*vptr)[3];
  826. #endif
  827.       GLint remaining;
  828.  
  829.       gl_Begin( ctx, mode );
  830.  
  831.       remaining = count;
  832. #ifndef __STORM__
  833.       vptr = (GLfloat (*)[3]) ctx->Array.VertexPtr + 3 * first;
  834. #else
  835.       vptr = (GLfloat (*)[3]) ctx->Array.VertexPtr;
  836.       vptr += 3 * first;
  837. #endif
  838.       while (remaining>0) {
  839.      GLint vbspace, n;
  840.  
  841.      vbspace = VB_MAX - VB->Start;
  842.      n = MIN2( vbspace, remaining );
  843.  
  844.      gl_xform_points_3fv( n, VB->Eye+VB->Start, ctx->ModelViewMatrix, vptr );
  845.  
  846.      /* assign vertex colors */
  847.      {
  848.         GLint i, start = VB->Start;
  849.         for (i=0;i<n;i++) {
  850.            COPY_4UBV( VB->Fcolor[start+i], ctx->Current.ByteColor );
  851.         }
  852.      }
  853.  
  854.      /* assign polygon edgeflags */
  855.      if (need_edges) {
  856.         GLint i;
  857.         for (i=0;i<n;i++) {
  858.            VB->Edgeflag[VB->Start+i] = ctx->Current.EdgeFlag;
  859.         }
  860.      }
  861.  
  862.      remaining -= n;
  863.  
  864.      VB->MonoNormal = GL_FALSE;
  865.      VB->Count = VB->Start + n;
  866.      gl_transform_vb_part2( ctx, remaining==0 ? GL_TRUE : GL_FALSE );
  867.  
  868.      vptr += n;
  869.       }
  870.  
  871.       gl_End( ctx );
  872.    }
  873.    else if (!ctx->CompileFlag
  874.        && ctx->Light.Enabled
  875.        && !ctx->Texture.Enabled
  876.        && ctx->Array.VertexEnabled && ctx->Array.VertexType==GL_FLOAT
  877.        && ctx->Array.VertexStride==0 && ctx->Array.VertexSize==4
  878.        && ctx->Array.NormalEnabled && ctx->Array.NormalType==GL_FLOAT
  879.        && ctx->Array.NormalStride==0
  880.        && !ctx->Array.ColorEnabled
  881.        && !ctx->Array.IndexEnabled
  882.        && !ctx->Array.TexCoordEnabled
  883.        && !ctx->Array.EdgeFlagEnabled) {
  884.       /*
  885.        * SPECIAL CASE:  glNormal3fv();  glVertex4fv();  with lighting
  886.        */
  887. #ifndef __STORM__
  888.       GLfloat (*vptr)[4], (*nptr)[3];
  889. #else
  890.       float (*vptr)[4], (*nptr)[3];
  891. #endif
  892.       GLint remaining;
  893.  
  894.       gl_Begin( ctx, mode );
  895.  
  896.       remaining = count;
  897. #ifndef __STORM__
  898.       vptr = (GLfloat (*)[4]) ctx->Array.VertexPtr + 4 * first;
  899.       nptr = (GLfloat (*)[3]) ctx->Array.NormalPtr + 3 * first;
  900. #else
  901.       vptr = (GLfloat (*)[4]) ctx->Array.VertexPtr;
  902.       vptr += 4 * first;
  903.       nptr = (GLfloat (*)[3]) ctx->Array.NormalPtr;
  904.       nptr += 3 * first;
  905. #endif
  906.       while (remaining>0) {
  907.      GLint vbspace, n;
  908.  
  909.      vbspace = VB_MAX - VB->Start;
  910.      n = MIN2( vbspace, remaining );
  911.  
  912.      gl_xform_points_4fv( n, VB->Eye+VB->Start, ctx->ModelViewMatrix, vptr );
  913.      gl_xform_normals_3fv( n, VB->Normal+VB->Start, ctx->ModelViewInv, nptr,
  914.                    ctx->Transform.Normalize );
  915.  
  916.      /* assign polygon edgeflags */
  917.      if (need_edges) {
  918.         GLint i;
  919.         for (i=0;i<n;i++) {
  920.            VB->Edgeflag[VB->Start+i] = ctx->Current.EdgeFlag;
  921.         }
  922.      }
  923.  
  924.      remaining -= n;
  925.  
  926.      VB->MonoNormal = GL_FALSE;
  927.      VB->Count = VB->Start + n;
  928.      gl_transform_vb_part2( ctx, remaining==0 ? GL_TRUE : GL_FALSE );
  929.  
  930.      vptr += n;
  931.      nptr += n;
  932.       }
  933.  
  934.       gl_End( ctx );
  935.    }
  936.    else if (!ctx->CompileFlag
  937.        && ctx->Light.Enabled
  938.        && !ctx->Texture.Enabled
  939.        && ctx->Array.VertexEnabled && ctx->Array.VertexType==GL_FLOAT
  940.        && ctx->Array.VertexStride==0 && ctx->Array.VertexSize==3
  941.        && ctx->Array.NormalEnabled && ctx->Array.NormalType==GL_FLOAT
  942.        && ctx->Array.NormalStride==0
  943.        && !ctx->Array.ColorEnabled
  944.        && !ctx->Array.IndexEnabled
  945.        && !ctx->Array.TexCoordEnabled
  946.        && !ctx->Array.EdgeFlagEnabled) {
  947.       /*
  948.        * SPECIAL CASE:  glNormal3fv();  glVertex3fv();  with lighting
  949.        */
  950. #ifndef __STORM__
  951.       GLfloat (*vptr)[3], (*nptr)[3];
  952. #else
  953.       float (*vptr)[3], (*nptr)[3];
  954. #endif
  955.       GLint remaining;
  956.  
  957.       gl_Begin( ctx, mode );
  958.  
  959.       remaining = count;
  960. #ifndef __STORM__
  961.       vptr = (GLfloat (*)[3]) ctx->Array.VertexPtr + 3 * first;
  962.       nptr = (GLfloat (*)[3]) ctx->Array.NormalPtr + 3 * first;
  963. #else
  964.       vptr = (GLfloat (*)[3]) ctx->Array.VertexPtr;
  965.       vptr += 3 * first;
  966.       nptr = (GLfloat (*)[3]) ctx->Array.NormalPtr;
  967.       nptr += 3 * first;
  968. #endif
  969.       while (remaining>0) {
  970.      GLint vbspace, n;
  971.  
  972.      vbspace = VB_MAX - VB->Start;
  973.      n = MIN2( vbspace, remaining );
  974.  
  975.      gl_xform_points_3fv( n, VB->Eye+VB->Start, ctx->ModelViewMatrix, vptr );
  976.      gl_xform_normals_3fv( n, VB->Normal+VB->Start, ctx->ModelViewInv, nptr,
  977.                    ctx->Transform.Normalize );
  978.  
  979.      /* assign polygon edgeflags */
  980.      if (need_edges) {
  981.         GLint i;
  982.         for (i=0;i<n;i++) {
  983.            VB->Edgeflag[VB->Start+i] = ctx->Current.EdgeFlag;
  984.         }
  985.      }
  986.  
  987.      remaining -= n;
  988.  
  989.      VB->MonoNormal = GL_FALSE;
  990.      VB->Count = VB->Start + n;
  991.      gl_transform_vb_part2( ctx, remaining==0 ? GL_TRUE : GL_FALSE );
  992.  
  993.      vptr += n;
  994.      nptr += n;
  995.       }
  996.  
  997.       gl_End( ctx );
  998.    }
  999.    else {
  1000.       /*
  1001.        * GENERAL CASE:
  1002.        */
  1003.       gl_Begin( ctx, mode );
  1004.       for (i=0;i<count;i++) {
  1005.      gl_ArrayElement( ctx, first+i );
  1006.       }
  1007.       gl_End( ctx );
  1008.    }
  1009. }
  1010.  
  1011.  
  1012.  
  1013. /*
  1014.  * Save into a display list
  1015.  */
  1016. void gl_save_DrawArrays( GLcontext *ctx,
  1017.              GLenum mode, GLint first, GLsizei count )
  1018. {
  1019.    GLint i;
  1020.  
  1021.    if (INSIDE_BEGIN_END(ctx)) {
  1022.       gl_error( ctx, GL_INVALID_OPERATION, "glDrawArrays" );
  1023.       return;
  1024.    }
  1025.    if (count<0) {
  1026.       gl_error( ctx, GL_INVALID_VALUE, "glDrawArrays(count)" );
  1027.       return;
  1028.    }
  1029.    switch (mode) {
  1030.       case GL_POINTS:
  1031.       case GL_LINES:
  1032.       case GL_LINE_STRIP:
  1033.       case GL_LINE_LOOP:
  1034.       case GL_TRIANGLES:
  1035.       case GL_TRIANGLE_STRIP:
  1036.       case GL_TRIANGLE_FAN:
  1037.       case GL_QUADS:
  1038.       case GL_QUAD_STRIP:
  1039.       case GL_POLYGON:
  1040.      /* OK */
  1041.      break;
  1042.       default:
  1043.      gl_error( ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" );
  1044.      return;
  1045.    }
  1046.  
  1047.  
  1048.    /* Note: this will do compile AND execute if needed */
  1049.    gl_save_Begin( ctx, mode );
  1050.    for (i=0;i<count;i++) {
  1051.       gl_save_ArrayElement( ctx, first+i );
  1052.    }
  1053.    gl_save_End( ctx );
  1054. }
  1055.  
  1056.  
  1057.  
  1058.  
  1059. /*
  1060.  * Execute only
  1061.  */
  1062. void gl_DrawElements( GLcontext *ctx,
  1063.               GLenum mode, GLsizei count,
  1064.               GLenum type, const GLvoid *indices )
  1065. {
  1066.    
  1067.    if (INSIDE_BEGIN_END(ctx)) {
  1068.       gl_error( ctx, GL_INVALID_OPERATION, "glDrawElements" );
  1069.       return;
  1070.    }
  1071.    if (count<0) {
  1072.       gl_error( ctx, GL_INVALID_VALUE, "glDrawElements(count)" );
  1073.       return;
  1074.    }
  1075.    switch (mode) {
  1076.       case GL_POINTS:
  1077.       case GL_LINES:
  1078.       case GL_LINE_STRIP:
  1079.       case GL_LINE_LOOP:
  1080.       case GL_TRIANGLES:
  1081.       case GL_TRIANGLE_STRIP:
  1082.       case GL_TRIANGLE_FAN:
  1083.       case GL_QUADS:
  1084.       case GL_QUAD_STRIP:
  1085.       case GL_POLYGON:
  1086.      /* OK */
  1087.      break;
  1088.       default:
  1089.      gl_error( ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" );
  1090.      return;
  1091.    }
  1092.    switch (type) {
  1093.       case GL_UNSIGNED_BYTE:
  1094.      {
  1095.         GLubyte *ub_indices = (GLubyte *) indices;
  1096.         GLint i;
  1097.         gl_Begin( ctx, mode );
  1098.         for (i=0;i<count;i++) {
  1099.            gl_ArrayElement( ctx, (GLint) ub_indices[i] );
  1100.         }
  1101.         gl_End( ctx );
  1102.      }
  1103.      break;
  1104.       case GL_UNSIGNED_SHORT:
  1105.      {
  1106.         GLushort *us_indices = (GLushort *) indices;
  1107.         GLint i;
  1108.         gl_Begin( ctx, mode );
  1109.         for (i=0;i<count;i++) {
  1110.            gl_ArrayElement( ctx, (GLint) us_indices[i] );
  1111.         }
  1112.         gl_End( ctx );
  1113.      }
  1114.      break;
  1115.       case GL_UNSIGNED_INT:
  1116.      {
  1117.         GLuint *ui_indices = (GLuint *) indices;
  1118.         GLint i;
  1119.         gl_Begin( ctx, mode );
  1120.         for (i=0;i<count;i++) {
  1121.            gl_ArrayElement( ctx, (GLint) ui_indices[i] );
  1122.         }
  1123.         gl_End( ctx );
  1124.      }
  1125.      break;
  1126.       default:
  1127.      gl_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
  1128.      return;
  1129.    }
  1130. }
  1131.  
  1132.  
  1133.  
  1134.  
  1135. /*
  1136.  * Save (and perhaps execute)
  1137.  */
  1138. void gl_save_DrawElements( GLcontext *ctx,
  1139.                GLenum mode, GLsizei count,
  1140.                GLenum type, const GLvoid *indices )
  1141. {
  1142.    switch (type) {
  1143.       case GL_UNSIGNED_BYTE:
  1144.      {
  1145.         GLubyte *ub_indices = (GLubyte *) indices;
  1146.         GLint i;
  1147.         gl_save_Begin( ctx, mode );
  1148.         for (i=0;i<count;i++) {
  1149.            gl_save_ArrayElement( ctx, (GLint) ub_indices[i] );
  1150.         }
  1151.         gl_save_End( ctx );
  1152.      }
  1153.      break;
  1154.       case GL_UNSIGNED_SHORT:
  1155.      {
  1156.         GLushort *us_indices = (GLushort *) indices;
  1157.         GLint i;
  1158.         gl_save_Begin( ctx, mode );
  1159.         for (i=0;i<count;i++) {
  1160.            gl_save_ArrayElement( ctx, (GLint) us_indices[i] );
  1161.         }
  1162.         gl_save_End( ctx );
  1163.      }
  1164.      break;
  1165.       case GL_UNSIGNED_INT:
  1166.      {
  1167.         GLuint *ui_indices = (GLuint *) indices;
  1168.         GLint i;
  1169.         gl_save_Begin( ctx, mode );
  1170.         for (i=0;i<count;i++) {
  1171.            gl_save_ArrayElement( ctx, (GLint) ui_indices[i] );
  1172.         }
  1173.         gl_save_End( ctx );
  1174.      }
  1175.      break;
  1176.       default:
  1177.      gl_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
  1178.      return;
  1179.    }
  1180. }
  1181.  
  1182.  
  1183.  
  1184.  
  1185. void gl_InterleavedArrays( GLcontext *ctx,
  1186.                GLenum format, GLsizei stride,
  1187.                const GLvoid *pointer )
  1188. {
  1189.    GLboolean tflag, cflag, nflag;  /* enable/disable flags */
  1190.    GLint tcomps, ccomps, vcomps;   /* components per texcoord, color, vertex */
  1191.    GLenum ctype;                   /* color type */
  1192.    GLint coffset, noffset, voffset;/* color, normal, vertex offsets */
  1193.    GLint defstride;                /* default stride */
  1194.    GLint c, f;
  1195.  
  1196.    f = sizeof(GLfloat);
  1197.    c = f * ((4*sizeof(GLubyte) + (f-1)) / f);
  1198.  
  1199.    if (stride<0) {
  1200.       gl_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
  1201.       return;
  1202.    }
  1203.  
  1204.    switch (format) {
  1205.       case GL_V2F:
  1206.      tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_FALSE;
  1207.      tcomps = 0;  ccomps = 0;  vcomps = 2;
  1208.      voffset = 0;
  1209.      defstride = 2*f;
  1210.      break;
  1211.       case GL_V3F:
  1212.      tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_FALSE;
  1213.      tcomps = 0;  ccomps = 0;  vcomps = 3;
  1214.      voffset = 0;
  1215.      defstride = 3*f;
  1216.      break;
  1217.       case GL_C4UB_V2F:
  1218.      tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
  1219.      tcomps = 0;  ccomps = 4;  vcomps = 2;
  1220.      ctype = GL_UNSIGNED_BYTE;
  1221.      coffset = 0;
  1222.      voffset = c;
  1223.      defstride = c + 2*f;
  1224.      break;
  1225.       case GL_C4UB_V3F:
  1226.      tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
  1227.      tcomps = 0;  ccomps = 4;  vcomps = 3;
  1228.      ctype = GL_UNSIGNED_BYTE;
  1229.      coffset = 0;
  1230.      voffset = c;
  1231.      defstride = c + 3*f;
  1232.      break;
  1233.       case GL_C3F_V3F:
  1234.      tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
  1235.      tcomps = 0;  ccomps = 3;  vcomps = 3;
  1236.      ctype = GL_FLOAT;
  1237.      coffset = 0;
  1238.      voffset = 3*f;
  1239.      defstride = 6*f;
  1240.      break;
  1241.       case GL_N3F_V3F:
  1242.      tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_TRUE;
  1243.      tcomps = 0;  ccomps = 0;  vcomps = 3;
  1244.      noffset = 0;
  1245.      voffset = 3*f;
  1246.      defstride = 6*f;
  1247.      break;
  1248.       case GL_C4F_N3F_V3F:
  1249.      tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_TRUE;
  1250.      tcomps = 0;  ccomps = 4;  vcomps = 3;
  1251.      ctype = GL_FLOAT;
  1252.      coffset = 0;
  1253.      noffset = 4*f;
  1254.      voffset = 7*f;
  1255.      defstride = 10*f;
  1256.      break;
  1257.       case GL_T2F_V3F:
  1258.      tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_FALSE;
  1259.      tcomps = 2;  ccomps = 0;  vcomps = 3;
  1260.      voffset = 2*f;
  1261.      defstride = 5*f;
  1262.      break;
  1263.       case GL_T4F_V4F:
  1264.      tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_FALSE;
  1265.      tcomps = 4;  ccomps = 0;  vcomps = 4;
  1266.      voffset = 4*f;
  1267.      defstride = 8*f;
  1268.      break;
  1269.       case GL_T2F_C4UB_V3F:
  1270.      tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_FALSE;
  1271.      tcomps = 2;  ccomps = 4;  vcomps = 3;
  1272.      ctype = GL_UNSIGNED_BYTE;
  1273.      coffset = 2*f;
  1274.      voffset = c+2*f;
  1275.      defstride = c+5*f;
  1276.      break;
  1277.       case GL_T2F_C3F_V3F:
  1278.      tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_FALSE;
  1279.      tcomps = 2;  ccomps = 3;  vcomps = 3;
  1280.      ctype = GL_FLOAT;
  1281.      coffset = 2*f;
  1282.      voffset = 5*f;
  1283.      defstride = 8*f;
  1284.      break;
  1285.       case GL_T2F_N3F_V3F:
  1286.      tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_TRUE;
  1287.      tcomps = 2;  ccomps = 0;  vcomps = 3;
  1288.      noffset = 2*f;
  1289.      voffset = 5*f;
  1290.      defstride = 8*f;
  1291.      break;
  1292.       case GL_T2F_C4F_N3F_V3F:
  1293.      tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_TRUE;
  1294.      tcomps = 2;  ccomps = 4;  vcomps = 3;
  1295.      ctype = GL_FLOAT;
  1296.      coffset = 2*f;
  1297.      noffset = 6*f;
  1298.      voffset = 9*f;
  1299.      defstride = 12*f;
  1300.      break;
  1301.       case GL_T4F_C4F_N3F_V4F:
  1302.      tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_TRUE;
  1303.      tcomps = 4;  ccomps = 4;  vcomps = 4;
  1304.      ctype = GL_FLOAT;
  1305.      coffset = 4*f;
  1306.      noffset = 8*f;
  1307.      voffset = 11*f;
  1308.      defstride = 15*f;
  1309.      break;
  1310.       default:
  1311.      gl_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
  1312.      return;
  1313.    }
  1314.  
  1315.    if (stride==0) {
  1316.       stride = defstride;
  1317.    }
  1318.  
  1319.    gl_DisableClientState( ctx, GL_EDGE_FLAG_ARRAY );
  1320.    gl_DisableClientState( ctx, GL_INDEX_ARRAY );
  1321.  
  1322.    if (tflag) {
  1323.       gl_EnableClientState( ctx, GL_TEXTURE_COORD_ARRAY );
  1324.       gl_TexCoordPointer( ctx, tcomps, GL_FLOAT, stride, pointer );
  1325.    }
  1326.    else {
  1327.       gl_DisableClientState( ctx, GL_TEXTURE_COORD_ARRAY );
  1328.    }
  1329.  
  1330.    if (cflag) {
  1331.       gl_EnableClientState( ctx, GL_COLOR_ARRAY );
  1332.       gl_ColorPointer( ctx, ccomps, ctype, stride,
  1333.                (GLubyte*) pointer + coffset );
  1334.    }
  1335.    else {
  1336.       gl_DisableClientState( ctx, GL_COLOR_ARRAY );
  1337.    }
  1338.  
  1339.    if (nflag) {
  1340.       gl_EnableClientState( ctx, GL_NORMAL_ARRAY );
  1341.       gl_NormalPointer( ctx, GL_FLOAT, stride,
  1342.             (GLubyte*) pointer + noffset );
  1343.    }
  1344.    else {
  1345.       gl_DisableClientState( ctx, GL_NORMAL_ARRAY );
  1346.    }
  1347.  
  1348.    gl_EnableClientState( ctx, GL_VERTEX_ARRAY );
  1349.    gl_VertexPointer( ctx, vcomps, GL_FLOAT, stride,
  1350.              (GLubyte *) pointer + voffset );
  1351. }
  1352.  
  1353.  
  1354.  
  1355. void gl_save_InterleavedArrays( GLcontext *ctx,
  1356.                 GLenum format, GLsizei stride,
  1357.                 const GLvoid *pointer )
  1358. {
  1359.    /* Just execute since client-side state changes aren't put in
  1360.     * display lists.
  1361.     */
  1362.    gl_InterleavedArrays( ctx, format, stride, pointer );
  1363. }
  1364.  
  1365.