This is varray.c in view mode; [Download] [Up]
/* $Id: varray.c,v 1.5 1996/10/08 00:05:06 brianp Exp $ */ /* * Mesa 3-D graphics library * Version: 2.0 * Copyright (C) 1995-1996 Brian Paul * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * $Log: varray.c,v $ * Revision 1.5 1996/10/08 00:05:06 brianp * added some missing stuff to gl_ArrayElement() * * Revision 1.4 1996/10/04 02:37:06 brianp * gl_ArrayElement() wasn't always initializing vertex Z and W values * * Revision 1.3 1996/10/03 00:47:56 brianp * added #include <stdlib.h> for abort() * * Revision 1.2 1996/09/27 01:33:07 brianp * added missing default cases to switches * * Revision 1.1 1996/09/13 01:38:16 brianp * Initial revision * */ /* * NOTE: At this time, only three vertex array configurations are optimized: * 1. glVertex3fv(), zero stride * 2. glNormal3fv() with glVertex3fv(), zero stride * 3. glNormal3fv() with glVertex4fv(), zero stride * * More optimized array configurations can be added. */ #include <stdlib.h> #include <string.h> #include "draw.h" #include "context.h" #include "enable.h" #include "dlist.h" #include "light.h" #include "macros.h" #include "types.h" #include "varray.h" #include "vb.h" #include "xform.h" void gl_VertexPointer( GLcontext *ctx, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr ) { if (size<2 || size>4) { gl_error( ctx, GL_INVALID_VALUE, "glVertexPointer(size)" ); return; } if (stride<0) { gl_error( ctx, GL_INVALID_VALUE, "glVertexPointer(stride)" ); return; } switch (type) { case GL_SHORT: ctx->Array.VertexStrideB = stride ? stride : size*sizeof(GLshort); break; case GL_INT: ctx->Array.VertexStrideB = stride ? stride : size*sizeof(GLint); break; case GL_FLOAT: ctx->Array.VertexStrideB = stride ? stride : size*sizeof(GLfloat); break; case GL_DOUBLE: ctx->Array.VertexStrideB = stride ? stride : size*sizeof(GLdouble); break; default: gl_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" ); return; } ctx->Array.VertexSize = size; ctx->Array.VertexType = type; ctx->Array.VertexStride = stride; ctx->Array.VertexPtr = (void *) ptr; } void gl_NormalPointer( GLcontext *ctx, GLenum type, GLsizei stride, const GLvoid *ptr ) { if (stride<0) { gl_error( ctx, GL_INVALID_VALUE, "glNormalPointer(stride)" ); return; } switch (type) { case GL_BYTE: ctx->Array.NormalStrideB = stride ? stride : 3*sizeof(GLbyte); break; case GL_SHORT: ctx->Array.NormalStrideB = stride ? stride : 3*sizeof(GLshort); break; case GL_INT: ctx->Array.NormalStrideB = stride ? stride : 3*sizeof(GLint); break; case GL_FLOAT: ctx->Array.NormalStrideB = stride ? stride : 3*sizeof(GLfloat); break; case GL_DOUBLE: ctx->Array.NormalStrideB = stride ? stride : 3*sizeof(GLdouble); break; default: gl_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" ); return; } ctx->Array.NormalType = type; ctx->Array.NormalStride = stride; ctx->Array.NormalPtr = (void *) ptr; } void gl_ColorPointer( GLcontext *ctx, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr ) { if (size<3 || size>4) { gl_error( ctx, GL_INVALID_VALUE, "glColorPointer(size)" ); return; } if (stride<0) { gl_error( ctx, GL_INVALID_VALUE, "glColorPointer(stride)" ); return; } switch (type) { case GL_BYTE: ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLbyte); break; case GL_UNSIGNED_BYTE: ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLubyte); break; case GL_SHORT: ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLshort); break; case GL_UNSIGNED_SHORT: ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLushort); break; case GL_INT: ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLint); break; case GL_UNSIGNED_INT: ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLuint); break; case GL_FLOAT: ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLfloat); break; case GL_DOUBLE: ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLdouble); break; default: gl_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" ); return; } ctx->Array.ColorSize = size; ctx->Array.ColorType = type; ctx->Array.ColorStride = stride; ctx->Array.ColorPtr = (void *) ptr; } void gl_IndexPointer( GLcontext *ctx, GLenum type, GLsizei stride, const GLvoid *ptr ) { if (stride<0) { gl_error( ctx, GL_INVALID_VALUE, "glIndexPointer(stride)" ); return; } switch (type) { case GL_SHORT: ctx->Array.IndexStrideB = stride ? stride : sizeof(GLbyte); break; case GL_INT: ctx->Array.IndexStrideB = stride ? stride : sizeof(GLint); break; case GL_FLOAT: ctx->Array.IndexStrideB = stride ? stride : sizeof(GLfloat); break; case GL_DOUBLE: ctx->Array.IndexStrideB = stride ? stride : sizeof(GLdouble); break; default: gl_error( ctx, GL_INVALID_ENUM, "glIndexPointer(type)" ); return; } ctx->Array.IndexType = type; ctx->Array.IndexStride = stride; ctx->Array.IndexPtr = (void *) ptr; } void gl_TexCoordPointer( GLcontext *ctx, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr ) { if (size<1 || size>4) { gl_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(size)" ); return; } switch (type) { case GL_SHORT: ctx->Array.TexCoordStrideB = stride ? stride : size*sizeof(GLshort); break; case GL_INT: ctx->Array.TexCoordStrideB = stride ? stride : size*sizeof(GLint); break; case GL_FLOAT: ctx->Array.TexCoordStrideB = stride ? stride : size*sizeof(GLfloat); break; case GL_DOUBLE: ctx->Array.TexCoordStrideB = stride ? stride : size*sizeof(GLdouble); break; default: gl_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" ); return; } if (stride<0) { gl_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(stride)" ); return; } ctx->Array.TexCoordSize = size; ctx->Array.TexCoordType = type; ctx->Array.TexCoordStride = stride; ctx->Array.TexCoordPtr = (void *) ptr; } void gl_EdgeFlagPointer( GLcontext *ctx, GLsizei stride, const GLboolean *ptr ) { if (stride<0) { gl_error( ctx, GL_INVALID_VALUE, "glEdgeFlagPointer(stride)" ); return; } ctx->Array.EdgeFlagStride = stride; ctx->Array.EdgeFlagStrideB = stride ? stride : sizeof(GLboolean); ctx->Array.EdgeFlagPtr = (GLboolean *) ptr; } /* * Eventually, this may be moved into get.c */ void gl_GetPointerv( GLcontext *ctx, GLenum pname, GLvoid **params ) { switch (pname) { case GL_VERTEX_ARRAY_POINTER: *params = ctx->Array.VertexPtr; break; case GL_NORMAL_ARRAY_POINTER: *params = ctx->Array.NormalPtr; break; case GL_COLOR_ARRAY_POINTER: *params = ctx->Array.ColorPtr; break; case GL_INDEX_ARRAY_POINTER: *params = ctx->Array.IndexPtr; break; case GL_TEXTURE_COORD_ARRAY_POINTER: *params = ctx->Array.TexCoordPtr; break; case GL_EDGE_FLAG_ARRAY_POINTER: *params = ctx->Array.EdgeFlagPtr; break; default: gl_error( ctx, GL_INVALID_ENUM, "glGetPointerv" ); return; } } /* * Execute */ void gl_ArrayElement( GLcontext *ctx, GLint i ) { struct vertex_buffer *VB = ctx->VB; GLint count = VB->Count; /* copy vertex data into the Vertex Buffer */ if (ctx->Array.NormalEnabled) { GLbyte *p = (GLbyte*) ctx->Array.NormalPtr + i * ctx->Array.NormalStrideB; switch (ctx->Array.NormalType) { case GL_BYTE: VB->Normal[count][0] = BYTE_TO_FLOAT( p[0] ); VB->Normal[count][1] = BYTE_TO_FLOAT( p[1] ); VB->Normal[count][2] = BYTE_TO_FLOAT( p[2] ); break; case GL_SHORT: VB->Normal[count][0] = SHORT_TO_FLOAT( ((GLshort*)p)[0] ); VB->Normal[count][1] = SHORT_TO_FLOAT( ((GLshort*)p)[1] ); VB->Normal[count][2] = SHORT_TO_FLOAT( ((GLshort*)p)[2] ); break; case GL_INT: VB->Normal[count][0] = INT_TO_FLOAT( ((GLint*)p)[0] ); VB->Normal[count][1] = INT_TO_FLOAT( ((GLint*)p)[1] ); VB->Normal[count][2] = INT_TO_FLOAT( ((GLint*)p)[2] ); break; case GL_FLOAT: VB->Normal[count][0] = ((GLfloat*)p)[0]; VB->Normal[count][1] = ((GLfloat*)p)[1]; VB->Normal[count][2] = ((GLfloat*)p)[2]; break; case GL_DOUBLE: VB->Normal[count][0] = ((GLdouble*)p)[0]; VB->Normal[count][1] = ((GLdouble*)p)[1]; VB->Normal[count][2] = ((GLdouble*)p)[2]; break; default: abort(); } } else { VB->Normal[count][0] = ctx->Current.Normal[0]; VB->Normal[count][1] = ctx->Current.Normal[0]; VB->Normal[count][2] = ctx->Current.Normal[0]; } /* TODO: directly set VB->Fcolor instead of calling a glColor command */ if (ctx->Array.ColorEnabled) { GLbyte *p = (GLbyte*) ctx->Array.ColorPtr + i * ctx->Array.ColorStrideB; switch (ctx->Array.ColorType) { case GL_BYTE: switch (ctx->Array.ColorSize) { case 4: glColor4bv( (GLbyte*) p ); break; case 3: glColor3bv( (GLbyte*) p ); break; } break; case GL_UNSIGNED_BYTE: switch (ctx->Array.ColorSize) { case 3: glColor3ubv( (GLubyte*) p ); break; case 4: glColor4ubv( (GLubyte*) p ); break; } break; case GL_SHORT: switch (ctx->Array.ColorSize) { case 3: glColor3sv( (GLshort*) p ); break; case 4: glColor4sv( (GLshort*) p ); break; } break; case GL_UNSIGNED_SHORT: switch (ctx->Array.ColorSize) { case 3: glColor3usv( (GLushort*) p ); break; case 4: glColor4usv( (GLushort*) p ); break; } break; case GL_INT: switch (ctx->Array.ColorSize) { case 3: glColor3iv( (GLint*) p ); break; case 4: glColor4iv( (GLint*) p ); break; } break; case GL_UNSIGNED_INT: switch (ctx->Array.ColorSize) { case 3: glColor3uiv( (GLuint*) p ); break; case 4: glColor4uiv( (GLuint*) p ); break; } break; case GL_FLOAT: switch (ctx->Array.ColorSize) { case 3: glColor3fv( (GLfloat*) p ); break; case 4: glColor4fv( (GLfloat*) p ); break; } break; case GL_DOUBLE: switch (ctx->Array.ColorSize) { case 3: glColor3dv( (GLdouble*) p ); break; case 4: glColor4dv( (GLdouble*) p ); break; } break; default: abort(); } ctx->VB->MonoColor = GL_FALSE; } else { GLint shift = ctx->ColorShift; VB->Fcolor[count][0] = ctx->Current.IntColor[0] << shift; VB->Fcolor[count][1] = ctx->Current.IntColor[1] << shift; VB->Fcolor[count][2] = ctx->Current.IntColor[2] << shift; VB->Fcolor[count][3] = ctx->Current.IntColor[3] << shift; if (ctx->Light.ColorMaterialEnabled) { GLfloat color[4]; color[0] = ctx->Current.IntColor[0] * ctx->Visual->InvRedScale; color[1] = ctx->Current.IntColor[1] * ctx->Visual->InvGreenScale; color[2] = ctx->Current.IntColor[2] * ctx->Visual->InvBlueScale; color[3] = ctx->Current.IntColor[3] * ctx->Visual->InvAlphaScale; gl_Materialfv( ctx, ctx->Light.ColorMaterialFace, ctx->Light.ColorMaterialMode, color ); } } if (ctx->Array.IndexEnabled) { GLbyte *p = (GLbyte*) ctx->Array.IndexPtr + i * ctx->Array.IndexStrideB; switch (ctx->Array.IndexType) { case GL_SHORT: VB->Findex[count] = (GLuint) (*((GLshort*) p)); break; case GL_INT: VB->Findex[count] = (GLuint) (*((GLint*) p)); break; case GL_FLOAT: VB->Findex[count] = (GLuint) (*((GLfloat*) p)); break; case GL_DOUBLE: VB->Findex[count] = (GLuint) (*((GLdouble*) p)); break; default: abort(); } ctx->VB->MonoColor = GL_FALSE; } else { VB->Findex[count] = ctx->Current.Index; } if (ctx->Array.TexCoordEnabled) { GLbyte *p = (GLbyte*) ctx->Array.TexCoordPtr + i * ctx->Array.TexCoordStrideB; VB->TexCoord[count][1] = 0.0F; VB->TexCoord[count][2] = 0.0F; VB->TexCoord[count][3] = 1.0F; switch (ctx->Array.TexCoordType) { case GL_SHORT: switch (ctx->Array.TexCoordSize) { /* FALL THROUGH! */ case 4: VB->TexCoord[count][3] = ((GLshort*) p)[3]; case 3: VB->TexCoord[count][2] = ((GLshort*) p)[2]; case 2: VB->TexCoord[count][1] = ((GLshort*) p)[1]; case 1: VB->TexCoord[count][0] = ((GLshort*) p)[0]; } break; case GL_INT: switch (ctx->Array.TexCoordSize) { /* FALL THROUGH! */ case 4: VB->TexCoord[count][3] = ((GLint*) p)[3]; case 3: VB->TexCoord[count][2] = ((GLint*) p)[2]; case 2: VB->TexCoord[count][1] = ((GLint*) p)[1]; case 1: VB->TexCoord[count][0] = ((GLint*) p)[0]; } break; case GL_FLOAT: switch (ctx->Array.TexCoordSize) { /* FALL THROUGH! */ case 4: VB->TexCoord[count][3] = ((GLfloat*) p)[3]; case 3: VB->TexCoord[count][2] = ((GLfloat*) p)[2]; case 2: VB->TexCoord[count][1] = ((GLfloat*) p)[1]; case 1: VB->TexCoord[count][0] = ((GLfloat*) p)[0]; } break; case GL_DOUBLE: switch (ctx->Array.TexCoordSize) { /* FALL THROUGH! */ case 4: VB->TexCoord[count][3] = ((GLdouble*) p)[3]; case 3: VB->TexCoord[count][2] = ((GLdouble*) p)[2]; case 2: VB->TexCoord[count][1] = ((GLdouble*) p)[1]; case 1: VB->TexCoord[count][0] = ((GLdouble*) p)[0]; } break; default: abort(); } } else { COPY_4V( VB->TexCoord[count], ctx->Current.TexCoord ); } if (ctx->Array.EdgeFlagEnabled) { GLbyte *b = (GLbyte*) ctx->Array.EdgeFlagPtr + i * ctx->Array.EdgeFlagStrideB; VB->Edgeflag[count] = *((GLboolean*) b); } else { VB->Edgeflag[count] = ctx->Current.EdgeFlag; } if (ctx->Array.VertexEnabled) { GLbyte *b = (GLbyte*) ctx->Array.VertexPtr + i * ctx->Array.VertexStrideB; VB->Obj[count][2] = 0.0F; VB->Obj[count][3] = 1.0F; switch (ctx->Array.VertexType) { case GL_SHORT: switch (ctx->Array.VertexSize) { /* FALL THROUGH */ case 4: VB->Obj[count][3] = ((GLshort*) b)[3]; case 3: VB->Obj[count][2] = ((GLshort*) b)[2]; case 2: VB->Obj[count][1] = ((GLshort*) b)[1]; VB->Obj[count][0] = ((GLshort*) b)[0]; } break; case GL_INT: switch (ctx->Array.VertexSize) { /* FALL THROUGH */ case 4: VB->Obj[count][3] = ((GLint*) b)[3]; case 3: VB->Obj[count][2] = ((GLint*) b)[2]; case 2: VB->Obj[count][1] = ((GLint*) b)[1]; VB->Obj[count][0] = ((GLint*) b)[0]; } break; case GL_FLOAT: switch (ctx->Array.VertexSize) { /* FALL THROUGH */ case 4: VB->Obj[count][3] = ((GLfloat*) b)[3]; case 3: VB->Obj[count][2] = ((GLfloat*) b)[2]; case 2: VB->Obj[count][1] = ((GLfloat*) b)[1]; VB->Obj[count][0] = ((GLfloat*) b)[0]; } break; case GL_DOUBLE: switch (ctx->Array.VertexSize) { /* FALL THROUGH */ case 4: VB->Obj[count][3] = ((GLdouble*) b)[3]; case 3: VB->Obj[count][2] = ((GLdouble*) b)[2]; case 2: VB->Obj[count][1] = ((GLdouble*) b)[1]; VB->Obj[count][0] = ((GLdouble*) b)[0]; } break; default: abort(); } /* Only store vertex if Vertex array pointer is enabled */ count++; VB->Count = count; if (count==VB_MAX) { gl_transform_vb_part1( ctx, GL_FALSE ); } } else { /* vertex array pointer not enabled: no vertex to process */ } } /* * Save into display list * Use external API entry points since speed isn't too important here * and makes the code simpler. Also, if GL_COMPILE_AND_EXECUTE then * execute will happen too. */ void gl_save_ArrayElement( GLcontext *ctx, GLint i ) { if (ctx->Array.NormalEnabled) { GLbyte *p = (GLbyte*) ctx->Array.NormalPtr + i * ctx->Array.NormalStrideB; switch (ctx->Array.NormalType) { case GL_BYTE: glNormal3bv( (GLbyte*) p ); break; case GL_SHORT: glNormal3sv( (GLshort*) p ); break; case GL_INT: glNormal3iv( (GLint*) p ); break; case GL_FLOAT: glNormal3fv( (GLfloat*) p ); break; case GL_DOUBLE: glNormal3dv( (GLdouble*) p ); break; default: abort(); } } if (ctx->Array.ColorEnabled) { GLbyte *p = (GLbyte*) ctx->Array.ColorPtr + i * ctx->Array.ColorStrideB; switch (ctx->Array.ColorType) { case GL_BYTE: switch (ctx->Array.ColorSize) { case 3: glColor3bv( (GLbyte*) p ); break; case 4: glColor4bv( (GLbyte*) p ); break; } break; case GL_UNSIGNED_BYTE: switch (ctx->Array.ColorSize) { case 3: glColor3ubv( (GLubyte*) p ); break; case 4: glColor4ubv( (GLubyte*) p ); break; } break; case GL_SHORT: switch (ctx->Array.ColorSize) { case 3: glColor3sv( (GLshort*) p ); break; case 4: glColor4sv( (GLshort*) p ); break; } break; case GL_UNSIGNED_SHORT: switch (ctx->Array.ColorSize) { case 3: glColor3usv( (GLushort*) p ); break; case 4: glColor4usv( (GLushort*) p ); break; } break; case GL_INT: switch (ctx->Array.ColorSize) { case 3: glColor3iv( (GLint*) p ); break; case 4: glColor4iv( (GLint*) p ); break; } break; case GL_UNSIGNED_INT: switch (ctx->Array.ColorSize) { case 3: glColor3uiv( (GLuint*) p ); break; case 4: glColor4uiv( (GLuint*) p ); break; } break; case GL_FLOAT: switch (ctx->Array.ColorSize) { case 3: glColor3fv( (GLfloat*) p ); break; case 4: glColor4fv( (GLfloat*) p ); break; } break; case GL_DOUBLE: switch (ctx->Array.ColorSize) { case 3: glColor3dv( (GLdouble*) p ); break; case 4: glColor4dv( (GLdouble*) p ); break; } break; default: abort(); } } if (ctx->Array.IndexEnabled) { GLbyte *p = (GLbyte*) ctx->Array.IndexPtr + i * ctx->Array.IndexStrideB; switch (ctx->Array.IndexType) { case GL_SHORT: glIndexsv( (GLshort*) p ); break; case GL_INT: glIndexiv( (GLint*) p ); break; case GL_FLOAT: glIndexfv( (GLfloat*) p ); break; case GL_DOUBLE: glIndexdv( (GLdouble*) p ); break; default: abort(); } } if (ctx->Array.TexCoordEnabled) { GLbyte *p = (GLbyte*) ctx->Array.TexCoordPtr + i * ctx->Array.TexCoordStrideB; switch (ctx->Array.TexCoordType) { case GL_SHORT: switch (ctx->Array.TexCoordSize) { case 1: glTexCoord1sv( (GLshort*) p ); break; case 2: glTexCoord2sv( (GLshort*) p ); break; case 3: glTexCoord3sv( (GLshort*) p ); break; case 4: glTexCoord4sv( (GLshort*) p ); break; } break; case GL_INT: switch (ctx->Array.TexCoordSize) { case 1: glTexCoord1iv( (GLint*) p ); break; case 2: glTexCoord2iv( (GLint*) p ); break; case 3: glTexCoord3iv( (GLint*) p ); break; case 4: glTexCoord4iv( (GLint*) p ); break; } break; case GL_FLOAT: switch (ctx->Array.TexCoordSize) { case 1: glTexCoord1fv( (GLfloat*) p ); break; case 2: glTexCoord2fv( (GLfloat*) p ); break; case 3: glTexCoord3fv( (GLfloat*) p ); break; case 4: glTexCoord4fv( (GLfloat*) p ); break; } break; case GL_DOUBLE: switch (ctx->Array.TexCoordSize) { case 1: glTexCoord1dv( (GLdouble*) p ); break; case 2: glTexCoord2dv( (GLdouble*) p ); break; case 3: glTexCoord3dv( (GLdouble*) p ); break; case 4: glTexCoord4dv( (GLdouble*) p ); break; } break; default: abort(); } } if (ctx->Array.EdgeFlagEnabled) { GLbyte *b = (GLbyte*) ctx->Array.EdgeFlagPtr + i * ctx->Array.EdgeFlagStrideB; glEdgeFlagv( (GLboolean*) b ); } if (ctx->Array.VertexEnabled) { GLbyte *b = (GLbyte*) ctx->Array.VertexPtr + i * ctx->Array.VertexStrideB; switch (ctx->Array.VertexType) { case GL_SHORT: switch (ctx->Array.VertexSize) { case 2: glVertex2sv( (GLshort*) b ); break; case 3: glVertex3sv( (GLshort*) b ); break; case 4: glVertex4sv( (GLshort*) b ); break; } break; case GL_INT: switch (ctx->Array.VertexSize) { case 2: glVertex2iv( (GLint*) b ); break; case 3: glVertex3iv( (GLint*) b ); break; case 4: glVertex4iv( (GLint*) b ); break; } break; case GL_FLOAT: switch (ctx->Array.VertexSize) { case 2: glVertex2fv( (GLfloat*) b ); break; case 3: glVertex3fv( (GLfloat*) b ); break; case 4: glVertex4fv( (GLfloat*) b ); break; } break; case GL_DOUBLE: switch (ctx->Array.VertexSize) { case 2: glVertex2dv( (GLdouble*) b ); break; case 3: glVertex3dv( (GLdouble*) b ); break; case 4: glVertex4dv( (GLdouble*) b ); break; } break; default: abort(); } } } /* * Execute */ void gl_DrawArrays( GLcontext *ctx, GLenum mode, GLint first, GLsizei count ) { struct vertex_buffer* VB = ctx->VB; GLint i; GLboolean need_edges; if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glDrawArrays" ); return; } if (count<0) { gl_error( ctx, GL_INVALID_VALUE, "glDrawArrays(count)" ); return; } if (ctx->Primitive==GL_TRIANGLES || ctx->Primitive==GL_QUADS || ctx->Primitive==GL_POLYGON) { need_edges = GL_TRUE; } else { need_edges = GL_FALSE; } if (!ctx->Light.Enabled && !ctx->Texture.Enabled && ctx->Array.VertexEnabled && ctx->Array.VertexType==GL_FLOAT && ctx->Array.VertexStride==0 && ctx->Array.VertexSize==3 && !ctx->Array.NormalEnabled && !ctx->Array.ColorEnabled && !ctx->Array.IndexEnabled && !ctx->Array.TexCoordEnabled && !ctx->Array.EdgeFlagEnabled) { /* * SPECIAL CASE: glVertex3fv() with no lighting */ GLfloat (*vptr)[3]; GLint remaining; gl_Begin( ctx, mode ); remaining = count; vptr = (GLfloat (*)[3]) ctx->Array.VertexPtr + 3 * first; while (remaining>0) { GLint vbspace, n; vbspace = VB_MAX - VB->Start; n = MIN2( vbspace, remaining ); gl_xform_points_3fv( n, VB->Eye+VB->Start, ctx->ModelViewMatrix, vptr ); /* assign vertex colors */ { GLint r = ctx->Current.IntColor[0] << ctx->ColorShift; GLint g = ctx->Current.IntColor[1] << ctx->ColorShift; GLint b = ctx->Current.IntColor[2] << ctx->ColorShift; GLint a = ctx->Current.IntColor[3] << ctx->ColorShift; GLint i, start = VB->Start; for (i=0;i<n;i++) { ASSIGN_4V( VB->Fcolor[start+i], r, g, b, a ); } } /* assign polygon edgeflags */ if (need_edges) { GLint i; for (i=0;i<n;i++) { VB->Edgeflag[VB->Start+i] = ctx->Current.EdgeFlag; } } remaining -= n; VB->Count = VB->Start + n; gl_transform_vb_part2( ctx, remaining==0 ? GL_TRUE : GL_FALSE ); vptr += n; } gl_End( ctx ); } else if (!ctx->CompileFlag && ctx->Light.Enabled && !ctx->Texture.Enabled && ctx->Array.VertexEnabled && ctx->Array.VertexType==GL_FLOAT && ctx->Array.VertexStride==0 && ctx->Array.VertexSize==4 && ctx->Array.NormalEnabled && ctx->Array.NormalType==GL_FLOAT && ctx->Array.NormalStride==0 && !ctx->Array.ColorEnabled && !ctx->Array.IndexEnabled && !ctx->Array.TexCoordEnabled && !ctx->Array.EdgeFlagEnabled) { /* * SPECIAL CASE: glNormal3fv(); glVertex4fv(); with lighting */ GLfloat (*vptr)[4], (*nptr)[3]; GLint remaining; gl_Begin( ctx, mode ); remaining = count; vptr = (GLfloat (*)[4]) ctx->Array.VertexPtr + 4 * first; nptr = (GLfloat (*)[3]) ctx->Array.NormalPtr + 3 * first; while (remaining>0) { GLint vbspace, n; vbspace = VB_MAX - VB->Start; n = MIN2( vbspace, remaining ); gl_xform_points_4fv( n, VB->Eye+VB->Start, ctx->ModelViewMatrix, vptr ); gl_xform_normals_3fv( n, VB->Normal+VB->Start, ctx->ModelViewInv, nptr, ctx->Transform.Normalize ); /* assign polygon edgeflags */ if (need_edges) { GLint i; for (i=0;i<n;i++) { VB->Edgeflag[VB->Start+i] = ctx->Current.EdgeFlag; } } remaining -= n; VB->Count = VB->Start + n; gl_transform_vb_part2( ctx, remaining==0 ? GL_TRUE : GL_FALSE ); vptr += n; nptr += n; } gl_End( ctx ); } else if (!ctx->CompileFlag && ctx->Light.Enabled && !ctx->Texture.Enabled && ctx->Array.VertexEnabled && ctx->Array.VertexType==GL_FLOAT && ctx->Array.VertexStride==0 && ctx->Array.VertexSize==3 && ctx->Array.NormalEnabled && ctx->Array.NormalType==GL_FLOAT && ctx->Array.NormalStride==0 && !ctx->Array.ColorEnabled && !ctx->Array.IndexEnabled && !ctx->Array.TexCoordEnabled && !ctx->Array.EdgeFlagEnabled) { /* * SPECIAL CASE: glNormal3fv(); glVertex3fv(); with lighting */ GLfloat (*vptr)[3], (*nptr)[3]; GLint remaining; gl_Begin( ctx, mode ); remaining = count; vptr = (GLfloat (*)[3]) ctx->Array.VertexPtr + 3 * first; nptr = (GLfloat (*)[3]) ctx->Array.NormalPtr + 3 * first; while (remaining>0) { GLint vbspace, n; vbspace = VB_MAX - VB->Start; n = MIN2( vbspace, remaining ); gl_xform_points_3fv( n, VB->Eye+VB->Start, ctx->ModelViewMatrix, vptr ); gl_xform_normals_3fv( n, VB->Normal+VB->Start, ctx->ModelViewInv, nptr, ctx->Transform.Normalize ); /* assign polygon edgeflags */ if (need_edges) { GLint i; for (i=0;i<n;i++) { VB->Edgeflag[VB->Start+i] = ctx->Current.EdgeFlag; } } remaining -= n; VB->Count = VB->Start + n; gl_transform_vb_part2( ctx, remaining==0 ? GL_TRUE : GL_FALSE ); vptr += n; nptr += n; } gl_End( ctx ); } else { /* * GENERAL CASE: */ gl_Begin( ctx, mode ); for (i=0;i<count;i++) { gl_ArrayElement( ctx, first+i ); } gl_End( ctx ); } } /* * Save into a display list */ void gl_save_DrawArrays( GLcontext *ctx, GLenum mode, GLint first, GLsizei count ) { GLint i; if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glDrawArrays" ); return; } if (count<0) { gl_error( ctx, GL_INVALID_VALUE, "glDrawArrays(count)" ); return; } switch (mode) { case GL_POINTS: case GL_LINES: case GL_LINE_STRIP: case GL_LINE_LOOP: case GL_TRIANGLES: case GL_TRIANGLE_STRIP: case GL_TRIANGLE_FAN: case GL_QUADS: case GL_QUAD_STRIP: case GL_POLYGON: /* OK */ break; default: gl_error( ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" ); return; } /* Note: this will do compile AND execute if needed */ gl_save_Begin( ctx, mode ); for (i=0;i<count;i++) { gl_save_ArrayElement( ctx, first+i ); } gl_save_End( ctx ); } /* * Execute only */ void gl_DrawElements( GLcontext *ctx, GLenum mode, GLsizei count, GLenum type, const GLvoid *indices ) { if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glDrawElements" ); return; } if (count<0) { gl_error( ctx, GL_INVALID_VALUE, "glDrawElements(count)" ); return; } switch (mode) { case GL_POINTS: case GL_LINES: case GL_LINE_STRIP: case GL_LINE_LOOP: case GL_TRIANGLES: case GL_TRIANGLE_STRIP: case GL_TRIANGLE_FAN: case GL_QUADS: case GL_QUAD_STRIP: case GL_POLYGON: /* OK */ break; default: gl_error( ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" ); return; } switch (type) { case GL_UNSIGNED_BYTE: { GLubyte *ub_indices = (GLubyte *) indices; GLint i; gl_Begin( ctx, mode ); for (i=0;i<count;i++) { gl_ArrayElement( ctx, (GLint) ub_indices[i] ); } gl_End( ctx ); } break; case GL_UNSIGNED_SHORT: { GLushort *us_indices = (GLushort *) indices; GLint i; gl_Begin( ctx, mode ); for (i=0;i<count;i++) { gl_ArrayElement( ctx, (GLint) us_indices[i] ); } gl_End( ctx ); } break; case GL_UNSIGNED_INT: { GLuint *ui_indices = (GLuint *) indices; GLint i; gl_Begin( ctx, mode ); for (i=0;i<count;i++) { gl_ArrayElement( ctx, (GLint) ui_indices[i] ); } gl_End( ctx ); } break; default: gl_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); return; } } /* * Save (and perhaps execute) */ void gl_save_DrawElements( GLcontext *ctx, GLenum mode, GLsizei count, GLenum type, const GLvoid *indices ) { switch (type) { case GL_UNSIGNED_BYTE: { GLubyte *ub_indices = (GLubyte *) indices; GLint i; gl_save_Begin( ctx, mode ); for (i=0;i<count;i++) { gl_save_ArrayElement( ctx, (GLint) ub_indices[i] ); } gl_save_End( ctx ); } break; case GL_UNSIGNED_SHORT: { GLushort *us_indices = (GLushort *) indices; GLint i; gl_save_Begin( ctx, mode ); for (i=0;i<count;i++) { gl_save_ArrayElement( ctx, (GLint) us_indices[i] ); } gl_save_End( ctx ); } break; case GL_UNSIGNED_INT: { GLuint *ui_indices = (GLuint *) indices; GLint i; gl_save_Begin( ctx, mode ); for (i=0;i<count;i++) { gl_save_ArrayElement( ctx, (GLint) ui_indices[i] ); } gl_save_End( ctx ); } break; default: gl_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); return; } } void gl_InterleavedArrays( GLcontext *ctx, GLenum format, GLsizei stride, const GLvoid *pointer ) { GLboolean tflag, cflag, nflag; /* enable/disable flags */ GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */ GLenum ctype; /* color type */ GLint coffset, noffset, voffset;/* color, normal, vertex offsets */ GLint defstride; /* default stride */ GLint c, f; f = sizeof(GLfloat); c = f * ((4*sizeof(GLubyte) + (f-1)) / f); if (stride<0) { gl_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" ); return; } switch (format) { case GL_V2F: tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE; tcomps = 0; ccomps = 0; vcomps = 2; voffset = 0; defstride = 2*f; break; case GL_V3F: tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE; tcomps = 0; ccomps = 0; vcomps = 3; voffset = 0; defstride = 3*f; break; case GL_C4UB_V2F: tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; tcomps = 0; ccomps = 4; vcomps = 2; ctype = GL_UNSIGNED_BYTE; coffset = 0; voffset = c; defstride = c + 2*f; break; case GL_C4UB_V3F: tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; tcomps = 0; ccomps = 4; vcomps = 3; ctype = GL_UNSIGNED_BYTE; coffset = 0; voffset = c; defstride = c + 3*f; break; case GL_C3F_V3F: tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; tcomps = 0; ccomps = 3; vcomps = 3; ctype = GL_FLOAT; coffset = 0; voffset = 3*f; defstride = 6*f; break; case GL_N3F_V3F: tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE; tcomps = 0; ccomps = 0; vcomps = 3; noffset = 0; voffset = 3*f; defstride = 6*f; break; case GL_C4F_N3F_V3F: tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE; tcomps = 0; ccomps = 4; vcomps = 3; ctype = GL_FLOAT; coffset = 0; noffset = 4*f; voffset = 7*f; defstride = 10*f; break; case GL_T2F_V3F: tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE; tcomps = 2; ccomps = 0; vcomps = 3; voffset = 2*f; defstride = 5*f; break; case GL_T4F_V4F: tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE; tcomps = 4; ccomps = 0; vcomps = 4; voffset = 4*f; defstride = 8*f; break; case GL_T2F_C4UB_V3F: tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE; tcomps = 2; ccomps = 4; vcomps = 3; ctype = GL_UNSIGNED_BYTE; coffset = 2*f; voffset = c+2*f; defstride = c+5*f; break; case GL_T2F_C3F_V3F: tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE; tcomps = 2; ccomps = 3; vcomps = 3; ctype = GL_FLOAT; coffset = 2*f; voffset = 5*f; defstride = 8*f; break; case GL_T2F_N3F_V3F: tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE; tcomps = 2; ccomps = 0; vcomps = 3; noffset = 2*f; voffset = 5*f; defstride = 8*f; break; case GL_T2F_C4F_N3F_V3F: tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE; tcomps = 2; ccomps = 4; vcomps = 3; ctype = GL_FLOAT; coffset = 2*f; noffset = 6*f; voffset = 9*f; defstride = 12*f; break; case GL_T4F_C4F_N3F_V4F: tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE; tcomps = 4; ccomps = 4; vcomps = 4; ctype = GL_FLOAT; coffset = 4*f; noffset = 8*f; voffset = 11*f; defstride = 15*f; break; default: gl_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" ); return; } if (stride==0) { stride = defstride; } gl_DisableClientState( ctx, GL_EDGE_FLAG_ARRAY ); gl_DisableClientState( ctx, GL_INDEX_ARRAY ); if (tflag) { gl_EnableClientState( ctx, GL_TEXTURE_COORD_ARRAY ); gl_TexCoordPointer( ctx, tcomps, GL_FLOAT, stride, pointer ); } else { gl_DisableClientState( ctx, GL_TEXTURE_COORD_ARRAY ); } if (cflag) { gl_EnableClientState( ctx, GL_COLOR_ARRAY ); gl_ColorPointer( ctx, ccomps, ctype, stride, (GLubyte*) pointer + coffset ); } else { gl_DisableClientState( ctx, GL_COLOR_ARRAY ); } if (nflag) { gl_EnableClientState( ctx, GL_NORMAL_ARRAY ); gl_NormalPointer( ctx, GL_FLOAT, stride, (GLubyte*) pointer + noffset ); } else { gl_DisableClientState( ctx, GL_NORMAL_ARRAY ); } gl_EnableClientState( ctx, GL_VERTEX_ARRAY ); gl_VertexPointer( ctx, vcomps, GL_FLOAT, stride, (GLubyte *) pointer + voffset ); } void gl_save_InterleavedArrays( GLcontext *ctx, GLenum format, GLsizei stride, const GLvoid *pointer ) { /* Just execute since client-side state changes aren't put in * display lists. */ gl_InterleavedArrays( ctx, format, stride, pointer ); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.