/* * Copyright (C) 1997-2005, R3vis Corporation. * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA, or visit http://www.gnu.org/copyleft/lgpl.html. * * Original Contributor: * Wes Bethel, R3vis Corporation, Marin County, California * Additional Contributor(s): * * The OpenRM project is located at http://openrm.sourceforge.net/. */ /* * $Id: rmdraw1.c,v 1.17 2005/06/26 16:28:49 wes Exp $ * Version: $Name: OpenRM-1-6-0-RC5 $ * $Revision: 1.17 $ * $Log: rmdraw1.c,v $ * Revision 1.17 2005/06/26 16:28:49 wes * Repaired buglet in rmTrianglesDisjoint to accommodate per-face colors or norms. * * Revision 1.16 2005/06/12 21:48:44 wes * Minor tweaks to avoid compiler warnings. * * Revision 1.15 2005/06/06 02:04:29 wes * Lots of small additions to clean up compiler warnings. * * Revision 1.14 2005/05/16 01:01:37 wes * Update some primitive draw routines to use private_rmSetGLTexCoordFunc * to obtain the correct OpenGL texture coordinate function. * * Revision 1.13 2005/05/07 15:39:49 wes * To the rmLinesDisjoint draw code: (1) add support for texture coords, * (2) add support for normals, (3) refactor code to be cleaner about * handling the case where there is per-segment data, (4) general code * clean-up. * * Revision 1.12 2005/05/06 16:34:40 wes * Minor code cleanup in rmLineStrip draw code. rmLineStrip only supports * per-vertex everything. * * Revision 1.11 2005/05/06 15:43:46 wes * Add support for normals data in linestrip primitives. * * Revision 1.10 2005/02/19 16:23:56 wes * Distro sync and consolidation. * Added support for multitexturing. * * Revision 1.9 2005/02/12 00:54:50 wes * Preliminary multitexturing support for RMprimitives: qmesh, quads, tstrip, * triangles, and indexed triangles. * * Revision 1.8 2005/01/23 17:00:22 wes * Copyright updated to 2005. * * Revision 1.7 2004/09/28 00:44:07 wes * Modified rmQuads to support per-face colors and/or normals. When per-face * data is present, we don't use vertex arrays. * * Revision 1.6 2004/04/09 14:48:03 wes * Fix some compile warnings about unused variables. * * Revision 1.5 2004/02/23 03:04:32 wes * New primitives: RM_QUAD_STRIP, RM_INDEXED_TRIANGLES, RM_INDEXED_QUADS, * RM_INDEXED_TRIANGLE_STRIP. * * Revision 1.4 2004/01/16 16:44:05 wes * Updated copyright line for 2004. * * Revision 1.3 2003/07/20 14:44:09 wes * Enabled per-line color data in rmLinesDisjoint rendering function. * * Revision 1.2 2003/02/02 02:07:15 wes * Updated copyright to 2003. * * Revision 1.1.1.1 2003/01/28 02:15:23 wes * Manual rebuild of rm150 repository. * * Revision 1.14 2003/01/16 22:21:17 wes * Updated all source files to reflect new organization of header files: * all header files formerly located in include/rmaux, include/rmi, include/rmv * are now located in include/rm. * * Revision 1.13 2002/06/02 15:14:18 wes * * Added RMstateCache code to help eliminate the number of state changes * made during the render traversal. The RMstateCache tracks * the actual OpenGL rendering state w/o the need for querying OpenGL * directly, and is queried by draw code that then decides if any * real state changes are required given the configuration of data * within an RMprimitive. * * Revision 1.12 2002/04/30 19:29:18 wes * Updated copyright dates. * * Revision 1.11 2001/03/31 17:12:38 wes * v1.4.0-alpha-2 checkin. * * Revision 1.10 2000/12/03 22:34:37 wes * Mods for thread safety- RMpipe added as parm to display list * calls. * * Revision 1.9 2000/08/31 02:06:57 wes * No significant changes. * * Revision 1.8 2000/08/28 01:36:18 wes * In rmLinesDisjoint, ifdef'ed out the display list code. On some * platforms (nVidia 0.9-4 drivers, to be specific), there appear * to be some combinations of render state changes combined with * vertex arrays that cause the driver to barf when encapsulated * into an OpenGL display list. * * Revision 1.7 2000/08/23 23:24:20 wes * DO_LISTS define moved from rmogl.c to rmprivat.h. All display * list code removed from rmBitmap (will be reinserted later). * * Revision 1.6 2000/08/19 14:58:28 wes * Culled unused code. * * Revision 1.5 2000/05/17 14:22:06 wes * Added rmPolys draw routine (thanks to Matt & Todd from VRCO). * * Revision 1.4 2000/04/27 03:13:34 wes * rmPoints state management tweaks. * * Revision 1.3 2000/04/20 16:29:47 wes * Documentation additions/enhancements, some code rearragement. * * Revision 1.2 2000/02/29 23:43:53 wes * Compile warning cleanups. * * Revision 1.1.1.1 2000/02/28 21:29:40 wes * OpenRM 1.2 Checkin * * Revision 1.1.1.1 2000/02/28 17:18:48 wes * Initial entry - pre-RM120 release, source base for OpenRM 1.2. * */ #include #include "rmprivat.h" #include "rmprivatps.h" /* * this file contains RMprimitive "draw" routines for those * primitives that easily map to OpenGL vertex arrays. */ /*#define Z_ADJUST_VALUE .0005F */ #define Z_ADJUST_VALUE 0.0F static float lzadjust; /* macros */ #define LINE_Z_ADJUST_BEGIN(a) \ { \ lzadjust = ((a) == 2) ? (-1.0 * Z_ADJUST_VALUE) : Z_ADJUST_VALUE; \ glMatrixMode(GL_PROJECTION); \ glTranslatef(0.0F, 0.0F, ((s->focal_length) * lzadjust)); \ glMatrixMode(GL_MODELVIEW); \ } #define LINE_Z_ADJUST_END() \ { \ glMatrixMode(GL_PROJECTION); \ glTranslatef(0.0F, 0.0, (-1.0 * (s->focal_length) * lzadjust)); \ glMatrixMode(GL_MODELVIEW); \ } /* PRIVATE */ void private_rmGetBlobData (int tag, RMprimitive *p, int *stride, int *nverts, void **data, int *veclen) { RMprimitiveDataBlob *blob; void *blobData; blob = private_rmBlobFromIndex(p, tag); blobData = (void *)private_rmBlobGetData(blob); if (blobData != NULL) { if (stride != NULL) *stride = private_rmBlobGetStride(blob) / sizeof(float); if (nverts != NULL) *nverts = private_rmBlobGetNthings(blob); if (veclen != NULL) *veclen = private_rmBlobGetVeclen(blob); if (data != NULL) *data = blobData; } else { if (stride != NULL) *stride = 0; if (nverts != NULL) *nverts = 0; if (veclen != NULL) *veclen = 0; if (data != NULL) *data = NULL; } } /* PRIVATE */ void private_rmEnableVertexArrays (int verts, int colors, int normals, int textureCoords, int indices, int edgeFlags) { if (verts != 0) glEnableClientState(GL_VERTEX_ARRAY); else glDisableClientState(GL_VERTEX_ARRAY); if (colors != 0) glEnableClientState(GL_COLOR_ARRAY); else glDisableClientState(GL_COLOR_ARRAY); if (normals != 0) glEnableClientState(GL_NORMAL_ARRAY); else glDisableClientState(GL_NORMAL_ARRAY); if (textureCoords != 0) glEnableClientState(GL_TEXTURE_COORD_ARRAY); else glDisableClientState(GL_TEXTURE_COORD_ARRAY); if (indices != 0) glEnableClientState(GL_INDEX_ARRAY); else glDisableClientState(GL_INDEX_ARRAY); if (edgeFlags != 0) glEnableClientState(GL_EDGE_FLAG_ARRAY); else glDisableClientState(GL_EDGE_FLAG_ARRAY); } /* PRIVATE */ void rmLineStrip OGLPRIMPARMLIST() { /* * for linestrip primitives, we enforce per-vertex data. */ int dataError=0; /* for verts */ int vstride, nverts, vveclen; float *v; /* color data */ float *c=NULL; int cstride, ncolors, cveclen; /* normals */ int nstride, nnormals, nveclen; float *n=NULL; /* texture coord data */ float *tc=NULL; int tcstride; int ntc,tcveclen; int listStat=1; private_colorMaterialStateManip(p, s, rsc); private_lightingStateManip(p, s, rsc, RM_FALSE); if (s->rendermode != GL_FEEDBACK) { listStat = private_rmPrimitiveDisplayListBegin(renderPipe, p); if (listStat == 0) return; } else { listStat = 0; r = NULL; /* foil compiler warning */ } /* get vertex data */ private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen); /* get color data */ private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen); if ((ncolors != 0) && (ncolors != nverts)) { rmWarning("rmLineStrip error: your RM_LINES primitive contains color data, but the number of color data values that is not equal to the number of geometric vertices. This primitive will not be rendered. "); dataError = 1; } /* get normals info */ private_rmGetBlobData(BLOB_NORMAL_INDEX, p, &nstride, &nnormals, (void **)&n, &nveclen); if ((nnormals != 0) && (nnormals != nverts)) { rmWarning("rmLineStrip error: your RM_LINES primitive contains normals data, but the number of normals data values that is not equal to the number of geometric vertices. This primitive will not be rendered. "); dataError = 1; } /* get texture coord data */ private_rmGetBlobData(BLOB_TC_INDEX, p, &tcstride, &ntc, (void **)&tc, &tcveclen); if ((ntc != 0) && (ntc != nverts)) { rmWarning("rmLineStrip error: your RM_LINES primitive contains texture coordinates data, but the number of texture coordinate data values that is not equal to the number of geometric vertices. This primitive will not be rendered. "); dataError = 1; } /* for now, use different loops depending upon color layout. we may want to do something more sophisticated later on...*/ LINE_Z_ADJUST_BEGIN(vveclen); if (dataError == 0) /* assume per-vertex everything */ { /* when we have per-vertex everything, then use vertex arrays */ private_rmEnableVertexArrays(nverts, ncolors, nnormals, ntc, 0, 0); glVertexPointer(vveclen, GL_FLOAT, (sizeof(float) * vstride), (const GLvoid *)v); if (ncolors != 0) glColorPointer(cveclen, GL_FLOAT, sizeof(float) * cstride, (const GLvoid *)c); if (nnormals != 0) glNormalPointer(GL_FLOAT, sizeof(float)*nstride, (const GLvoid *)n); if (ntc != 0) glTexCoordPointer(tcveclen, GL_FLOAT, sizeof(float) * tcstride, (const GLvoid *)tc); glDrawArrays(GL_LINE_STRIP, 0, nverts); } LINE_Z_ADJUST_END(); private_rmPrimitiveDisplayListEnd(renderPipe, p, listStat); } /* PRIVATE */ void rmLinesDisjoint OGLPRIMPARMLIST() { int i; /* for verts */ float *v; int vstride=0, nverts=0, vveclen=0; /* color data */ float *c=NULL; int cstride=0, ncolors=0, cveclen=0; int perVertexColors=1; /* normals */ int nstride=0, nnormals=0, nveclen=0; int perVertexNormals=1; float *n=NULL; /* texture coord data */ float *tc=NULL; int tcstride=0; int ntc=0,tcveclen=0; int perVertexTCs=1; int perVertexData=1; int listStat=0; private_colorMaterialStateManip(p, s, rsc); private_lightingStateManip(p, s, rsc, RM_FALSE); if (s->rendermode != GL_FEEDBACK) { listStat = private_rmPrimitiveDisplayListBegin(renderPipe,p); if (listStat == 0) return; } else { r = NULL; /* foil compiler warning */ listStat = 0; } /* get vertex data */ private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen); /* get color data */ private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen); if ((ncolors != 0) && (ncolors != nverts)) { perVertexData = 0; perVertexColors = 0; } /* get texture coord data */ private_rmGetBlobData(BLOB_TC_INDEX, p, &tcstride, &ntc, (void **)&tc, &tcveclen); if ((ntc != 0) && (ntc != nverts)) { perVertexData = 0; perVertexTCs = 0; } /* get normals info */ private_rmGetBlobData(BLOB_NORMAL_INDEX, p, &nstride, &nnormals, (void **)&n, &nveclen); if ((nnormals != 0) && (nnormals != nverts)) { perVertexData = 0; perVertexNormals = 0; } /* for now, use different loops depending upon color layout. we may want to do something more sophisticated later on...*/ i = vveclen; LINE_Z_ADJUST_BEGIN(i); /* * we don't want to use display listing if we're in feedback * mode (PS generation) because we generate additional tokens * for PS that say something about linestyle & width. */ if (perVertexData == 1) /* have per-vertex everything */ { /* when we have per-vertex everything, then use vertex arrays. */ private_rmEnableVertexArrays(nverts, ncolors, nnormals, ntc, 0, 0); glVertexPointer(vveclen, GL_FLOAT, sizeof(float) * vstride, (const GLvoid *)v); if (ncolors != 0) glColorPointer(cveclen, GL_FLOAT, sizeof(float) * cstride, (const GLvoid *)c); if (nnormals != 0) glNormalPointer(GL_FLOAT, sizeof(float)*nstride, (const GLvoid *)n); if (ntc != 0) glTexCoordPointer(tcveclen, GL_FLOAT, sizeof(float) * tcstride, (const GLvoid *)tc); glDrawArrays(GL_LINES, 0, nverts); } else /* assume per-segment data for one or more data items */ { void (*vertexfunc)(const float *); void (*colorfunc)(const float *); void (*normalfunc)(const float *); void (*tcfunc)(const float *); if (nnormals != 0) normalfunc = rmglNormal3fv; else normalfunc = glNoOp; if (vveclen == 3) vertexfunc = rmglVertex3fv; else vertexfunc = rmglVertex2fv; if (ncolors == 0) colorfunc = glNoOp; else private_rmSetGLColorFunc(cveclen, ncolors, &colorfunc); if (ntc == 0) tcfunc = glNoOp; else private_rmSetGLTexCoordFunc(tcveclen, ntc, &tcfunc); glBegin(GL_LINES); for (i = 0; i < (nverts / 2); i++, v += vstride, c += cstride, tc += tcstride, n += nstride) { /* do the first segment vertex */ (*colorfunc)(c); (*tcfunc)(tc); (*normalfunc)(n); (*vertexfunc)(v); v += vstride; /* do the second segment vertex */ if ((c != NULL) && (perVertexColors == 1)) { c += cstride; (*colorfunc)(c); } if ((tc != NULL) && (perVertexTCs == 1)) { tc += tcstride; (*tcfunc)(tc); } if ((n != NULL) && (perVertexNormals == 1)) { n += nstride; (*normalfunc)(n); } (*vertexfunc)(v); } glEnd(); } LINE_Z_ADJUST_END(); private_rmPrimitiveDisplayListEnd(renderPipe, p, listStat); } /* PRIVATE */ void rmPoints OGLPRIMPARMLIST() { /* for verts */ float *v; int vstride, nverts, vveclen; /* color data */ float *c = NULL; int cstride, ncolors, cveclen; /* texture coord data */ float *tc = NULL; int tcstride; int ntc, tcveclen; /* normals */ float *n; int nstride, nveclen, nnormals; int listStat; private_colorMaterialStateManip(p, s, rsc); private_lightingStateManip(p, s, rsc, RM_FALSE); listStat = private_rmPrimitiveDisplayListBegin(renderPipe,p); if (listStat == 0) return; r = NULL; /* foil compiler warning */ /* get vertex data */ private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen); /* get color data */ private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen); /* get texture coord data - NOTE: (2/2000) tc's & points not tested */ private_rmGetBlobData(BLOB_TC_INDEX, p, &tcstride, &ntc, (void **)&tc, &tcveclen); /* get normals info */ private_rmGetBlobData(BLOB_NORMAL_INDEX, p, &nstride, &nnormals, (void **)&n, &nveclen); private_rmEnableVertexArrays(nverts, ncolors, nnormals, ntc, 0, 0); glVertexPointer(vveclen, GL_FLOAT, sizeof(float) * vstride, (const GLvoid *)v); if (ncolors != 0) glColorPointer(cveclen, GL_FLOAT, sizeof(float) * cstride, (const GLvoid *)c); if (ntc != 0) glTexCoordPointer(tcveclen, GL_FLOAT, sizeof(float) * tcstride, (const GLvoid *)tc); if (nnormals != 0) glNormalPointer(GL_FLOAT, sizeof(float) * nstride, (const GLvoid *)n); glDrawArrays(GL_POINTS, 0, nverts); private_rmPrimitiveDisplayListEnd(renderPipe, p, listStat); } /* PRIVATE */ void rmTrianglesDisjoint OGLPRIMPARMLIST() { /* this code is written assuming per-vertex everything */ /* for verts */ float *v; int vstride, nverts, vveclen; /* color data */ float *c = NULL; int cstride, ncolors, cveclen; /* texture coord data */ float *tc = NULL; int tcstride; int ntc, tcveclen; /* normals */ float *n; int nstride, nveclen, nnormals; int haveMTCs = 0; int useVertexArrays = 1; int perVertexColor=0, perFaceColor=0; int perFaceNormals=0; int listStat; private_lightingStateManip(p,s, rsc, RM_FALSE); private_colorMaterialStateManip(p,s, rsc); listStat = private_rmPrimitiveDisplayListBegin(renderPipe,p); if (listStat == 0) return; r = NULL; /* foil compiler warning */ /* get vertex data */ private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen); /* get color data */ private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen); if (ncolors != 0) { if (ncolors == nverts) perVertexColor = 1; else if (ncolors == nverts / 3) { perFaceColor = 1; useVertexArrays = 0; } } private_rmGetBlobData(BLOB_TC_INDEX, p, &tcstride, &ntc, (void **)&tc, &tcveclen); if ((ntc != 0) && (ntc != nverts)) rmWarning("rmTrianglesDisjoint() warning - the number of input texture coordinates is not the same as the number of vertices. "); /* get normals info */ private_rmGetBlobData(BLOB_NORMAL_INDEX, p, &nstride, &nnormals, (void **)&n, &nveclen); if (nnormals != 0) { if (nnormals == nverts / 3) { perFaceNormals = 1; useVertexArrays = 0; } /* else assume per vertex normals */ } if (p->multiTextureCoordBlobsMask != 0) { useVertexArrays = 0; /* slow path until we figure out how to use vertex arrays with MTCs. */ haveMTCs = 1; } if (useVertexArrays == 0) { /* vertex, normal, color, tc functions */ void (*vertexfunc)(const float *); void (*normalfunc)(const float *); void (*colorfunc)(const float *); void (*tcfunc)(const float *); int i; if (vveclen == 3) vertexfunc = rmglVertex3fv; else vertexfunc = rmglVertex2fv; if (nnormals != 0) normalfunc = rmglNormal3fv; else normalfunc = glNoOp; if (ncolors != 0) private_rmSetGLColorFunc(cveclen, ncolors, &colorfunc); else colorfunc = glNoOp; if (ntc == 0) tcfunc = glNoOp; else private_rmSetGLTexCoordFunc(tcveclen, ntc, &tcfunc); glBegin(GL_TRIANGLES); for (i=0; i < nverts; ) { if (nnormals != 0) (*normalfunc)(n), n += nstride; if (ncolors != 0) (*colorfunc)(c), c += cstride; if (ntc != 0) (*tcfunc)(tc), tc += tcstride; if (haveMTCs) private_dispatchMTCs(renderPipe, p, i); (*vertexfunc)(v); i++; v += vstride; if ((nnormals != 0) && (perFaceNormals == 0)) (*normalfunc)(n), n += nstride; if ((perVertexColor) && (perFaceColor == 0)) (*colorfunc)(c), c += cstride; if (ntc != 0) (*tcfunc)(tc), tc += tcstride; if (haveMTCs) private_dispatchMTCs(renderPipe, p, i); (*vertexfunc)(v); i++; v += vstride; if ((nnormals != 0) && (perFaceNormals == 0)) (*normalfunc)(n), n += nstride; if ((perVertexColor) && (perFaceColor == 0)) (*colorfunc)(c), c += cstride; if (ntc != 0) (*tcfunc)(tc), tc += tcstride; if (haveMTCs) private_dispatchMTCs(renderPipe, p, i); (*vertexfunc)(v); i++; v += vstride; } glEnd(); } else { private_rmEnableVertexArrays(nverts, ncolors, nnormals, ntc, 0, 0); glVertexPointer(vveclen, GL_FLOAT, sizeof(float) * vstride, (const GLvoid *)v); if (ncolors != 0) glColorPointer(cveclen, GL_FLOAT, sizeof(float) * cstride, (const GLvoid *)c); if (ntc != 0) glTexCoordPointer(tcveclen, GL_FLOAT,sizeof(float) * tcstride, (const GLvoid *)tc); if (nnormals != 0) glNormalPointer(GL_FLOAT, sizeof(float)*nstride, (const GLvoid *)n); glDrawArrays(GL_TRIANGLES, 0, nverts); } private_rmPrimitiveDisplayListEnd(renderPipe, p, listStat); } /* PRIVATE */ void rmTrianglesConnected OGLPRIMPARMLIST() { /* this code is written assuming per-vertex everything */ /* for verts */ float *v; int vstride, nverts, vveclen; /* color data */ float *c = NULL; int cstride, ncolors, cveclen; /* texture coord data */ float *tc = NULL; int tcstride; int ntc, tcveclen; /* normals */ float *n; int nstride, nveclen, nnormals; /* multitexture coords */ int haveMTCs = 0; int listStat; private_lightingStateManip(p,s, rsc, RM_FALSE); private_colorMaterialStateManip(p,s, rsc); listStat = private_rmPrimitiveDisplayListBegin(renderPipe,p); if (listStat == 0) return; r = NULL; /* foil compiler warning */ /* get vertex data */ private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen); /* get color data */ private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen); /* get texture coord data - NOTE: (2/2000) tc's & points not tested */ private_rmGetBlobData(BLOB_TC_INDEX, p, &tcstride, &ntc, (void **)&tc, &tcveclen); /* get normals info */ private_rmGetBlobData(BLOB_NORMAL_INDEX, p, &nstride, &nnormals, (void **)&n, &nveclen); if (p->multiTextureCoordBlobsMask != 0) haveMTCs = 1; if (haveMTCs == 1) /* slow path until MTCs are supported in vertex arrays*/ { /* vertex, normal, color, tc functions */ void (*vertexfunc)(const float *); void (*normalfunc)(const float *); void (*colorfunc)(const float *); void (*tcfunc)(const float *); int i; if (vveclen == 3) vertexfunc = rmglVertex3fv; else vertexfunc = rmglVertex2fv; if (nnormals != 0) normalfunc = rmglNormal3fv; else normalfunc = glNoOp; if (ncolors != 0) private_rmSetGLColorFunc(cveclen, ncolors, &colorfunc); else colorfunc = glNoOp; if (ntc == 0) tcfunc = glNoOp; else private_rmSetGLTexCoordFunc(tcveclen, ntc, &tcfunc); glBegin(GL_TRIANGLE_STRIP); for (i=0; i < nverts; i++) { if (nnormals != 0) (*normalfunc)(n), n += nstride; if (ncolors != 0) (*colorfunc)(c), c += cstride; if (ntc != 0) (*tcfunc)(tc), tc += tcstride; if (haveMTCs) private_dispatchMTCs(renderPipe, p, i); (*vertexfunc)(v); v += vstride; } glEnd(); } else /* fast path */ { private_rmEnableVertexArrays(nverts, ncolors, nnormals, ntc, 0, 0); glVertexPointer(vveclen, GL_FLOAT, sizeof(float) * vstride, (const GLvoid *)v); if (ncolors != 0) glColorPointer(cveclen, GL_FLOAT, sizeof(float) * cstride, (const GLvoid *)c); if (ntc != 0) glTexCoordPointer(tcveclen, GL_FLOAT,sizeof(float) * tcstride, (const GLvoid *)tc); if (nnormals != 0) glNormalPointer(GL_FLOAT, sizeof(float) * nstride, (const GLvoid *)n); glDrawArrays(GL_TRIANGLE_STRIP, 0, nverts); } private_rmPrimitiveDisplayListEnd(renderPipe, p, listStat); } /* PRIVATE */ void rmTriangleFan OGLPRIMPARMLIST() { /* this code is written assuming per-vertex everything */ /* for verts */ float *v; int vstride, nverts, vveclen; /* color data */ float *c = NULL; int cstride, ncolors, cveclen; /* texture coord data */ float *tc = NULL; int tcstride; int ntc, tcveclen; /* normals */ float *n; int nstride, nveclen, nnormals; int listStat; private_lightingStateManip(p,s, rsc, RM_FALSE); private_colorMaterialStateManip(p,s, rsc); listStat = private_rmPrimitiveDisplayListBegin(renderPipe,p); if (listStat == 0) return; r = NULL; /* foil compiler warning */ /* get vertex data */ private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen); /* get color data */ private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen); /* get texture coord data */ private_rmGetBlobData(BLOB_TC_INDEX, p, &tcstride, &ntc, (void **)&tc, &tcveclen); /* get normals info */ private_rmGetBlobData(BLOB_NORMAL_INDEX, p, &nstride, &nnormals, (void **)&n, &nveclen); private_rmEnableVertexArrays(nverts, ncolors, nnormals, ntc, 0, 0); glVertexPointer(vveclen, GL_FLOAT, sizeof(float) * vstride, (const GLvoid *)v); if (ncolors != 0) glColorPointer(cveclen, GL_FLOAT, sizeof(float) * cstride, (const GLvoid *)c); if (ntc != 0) glTexCoordPointer(tcveclen, GL_FLOAT, sizeof(float) * tcstride, (const GLvoid *)tc); if (nnormals != 0) glNormalPointer(GL_FLOAT, sizeof(float) * nstride, (const GLvoid *)n); glDrawArrays(GL_TRIANGLE_FAN, 0, nverts); private_rmPrimitiveDisplayListEnd(renderPipe, p, listStat); } /* PRIVATE * Note: this code assumes per-vertex everything */ void rmQuadStrip OGLPRIMPARMLIST() { /* this code is written assuming per-vertex everything */ /* for verts */ float *v; int vstride, nverts, vveclen; /* color data */ float *c = NULL; int cstride, ncolors, cveclen; /* texture coord data */ float *tc = NULL; int tcstride; int ntc, tcveclen; /* normals */ float *n; int nstride, nveclen, nnormals; int listStat; private_lightingStateManip(p,s, rsc, RM_FALSE); private_colorMaterialStateManip(p,s, rsc); listStat = private_rmPrimitiveDisplayListBegin(renderPipe,p); if (listStat == 0) return; r = NULL; /* foil compiler warning */ /* get vertex data */ private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen); /* get color data */ private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen); /* get texture coord data - NOTE: (2/2000) tc's & points not tested */ private_rmGetBlobData(BLOB_TC_INDEX, p, &tcstride, &ntc, (void **)&tc, &tcveclen); /* get normals info */ private_rmGetBlobData(BLOB_NORMAL_INDEX, p, &nstride, &nnormals, (void **)&n, &nveclen); private_rmEnableVertexArrays(nverts, ncolors, nnormals, ntc, 0, 0); glVertexPointer(vveclen, GL_FLOAT, sizeof(float) * vstride, (const GLvoid *)v); if (ncolors != 0) glColorPointer(cveclen, GL_FLOAT, sizeof(float) * cstride, (const GLvoid *)c); if (ntc != 0) glTexCoordPointer(tcveclen, GL_FLOAT,sizeof(float) * tcstride, (const GLvoid *)tc); if (nnormals != 0) glNormalPointer(GL_FLOAT, sizeof(float) * nstride, (const GLvoid *)n); glDrawArrays(GL_QUAD_STRIP, 0, nverts); private_rmPrimitiveDisplayListEnd(renderPipe, p, listStat); } void rmPolys OGLPRIMPARMLIST() { /* * this code assumes per-vertex everything. */ /* for verts */ float *v; int vstride, nverts, vveclen; /* color data */ float *c=NULL; int cstride, ncolors, cveclen; /* texture coord data */ float *tc=NULL; int tcstride; int ntc,tcveclen; /* normals */ float *n; int nstride, nveclen, nnormals; /* lengths */ int *l; int lstride, lveclen, nlengths; int first = 0,i; int listStat; private_lightingStateManip(p,s, rsc, RM_FALSE); private_colorMaterialStateManip(p,s, rsc); listStat = private_rmPrimitiveDisplayListBegin(renderPipe,p); if (listStat == 0) return; r = NULL; /* foil compile warning */ /* get vertex data */ private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen); /* get color data */ private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen); /* get texture coord data - NOTE: (2/2000) tc's & points not tested */ private_rmGetBlobData(BLOB_TC_INDEX, p, &tcstride, &ntc, (void **)&tc, &tcveclen); /* get normals info */ private_rmGetBlobData(BLOB_NORMAL_INDEX, p, &nstride, &nnormals, (void **)&n, &nveclen); /* get lengths as index data */ private_rmGetBlobData(BLOB_INDEX_INDEX, p, &lstride, &nlengths, (void **)&l, &lveclen); private_rmEnableVertexArrays(nverts,ncolors,nnormals,ntc,0,0); glVertexPointer(vveclen, GL_FLOAT, sizeof(float)*vstride, (const GLvoid *)v); if (ncolors != 0) glColorPointer(cveclen, GL_FLOAT, sizeof(float)*cstride, (const GLvoid *)c); if (ntc != 0) glTexCoordPointer(tcveclen, GL_FLOAT,sizeof(float)*tcstride, (const GLvoid *)tc); if (nnormals != 0) glNormalPointer(GL_FLOAT, sizeof(float)*nstride, (const GLvoid *)n); for(i=0;i