/**************************************************************************\ * * This file is part of the Coin 3D visualization library. * Copyright (C) 1998-2007 by Systems in Motion. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * ("GPL") version 2 as published by the Free Software Foundation. * See the file LICENSE.GPL at the root directory of this source * distribution for additional information about the GNU GPL. * * For using Coin with software that can not be combined with the GNU * GPL, and for taking advantage of the additional benefits of our * support services, please contact Systems in Motion about acquiring * a Coin Professional Edition License. * * See http://www.coin3d.org/ for more information. * * Systems in Motion, Postboks 1283, Pirsenteret, 7462 Trondheim, NORWAY. * http://www.sim.no/ sales@sim.no coin-support@coin3d.org * \**************************************************************************/ ( const SoGLCoordinateElement * coords, const SbVec3f *normals, SoMaterialBundle * mb, const SoTextureCoordinateBundle * tb, SbBool needNormals, int rowsize, int colsize, int start ) { assert(rowsize >= 0 && colsize >= 0 && start >= 0); assert(coords->getNum() - start >= rowsize * colsize); const SbVec3f * coords3d = NULL; const SbVec4f * coords4d = NULL; const SbBool is3d = coords->is3D(); if (is3d) { coords3d = coords->getArrayPtr3(); } else { coords4d = coords->getArrayPtr4(); } // This is the same code as in SoGLCoordinateElement::send(). // It is inlined here for speed (~15% speed increase). #define SEND_VERTEX(_idx_) \ if (is3d) glVertex3fv((const GLfloat*) (coords3d + (_idx_))); \ else glVertex4fv((const GLfloat*) (coords4d + (_idx_))); #if MBINDING==PER_FACE || MBINDING==PER_ROW int midx = 0; #endif SbVec3f dummynormal(0.0f, 0.0f, 1.0f); const SbVec3f * currnormal = &dummynormal; if (normals) currnormal = normals; #if NBINDING==OVERALL if (needNormals) { glNormal3fv((const GLfloat *)currnormal); } #endif int curridx; // for optimization only for (int i = 0; i < colsize-1; i++) { int j = 0; glBegin(GL_QUAD_STRIP); #if NBINDING==PER_ROW currnormal = normals++; glNormal3fv((const GLfloat *)currnormal); #endif #if MBINDING==PER_ROW mb->send(midx++,TRUE); #endif for (j = 0; j < rowsize; j++) { curridx = IDX(i,j); #if NBINDING==PER_VERTEX currnormal = &normals[curridx]; glNormal3fv((const GLfloat *)currnormal); #endif #if NBINDING==PER_FACE currnormal = normals++; glNormal3fv((const GLfloat *)currnormal); #endif #if MBINDING==PER_VERTEX mb->send(curridx, TRUE); #endif #if TEXTURES==TRUE tb->send(curridx, coords->get3(start + curridx), *currnormal); #endif SEND_VERTEX(start + curridx); curridx = IDX(i+1,j); #if NBINDING==PER_VERTEX currnormal = &normals[curridx]; glNormal3fv((const GLfloat *)currnormal); #endif #if MBINDING==PER_VERTEX mb->send(curridx, TRUE); #endif #if TEXTURES==TRUE tb->send(curridx, coords->get3(start + curridx), *currnormal); #endif #if MBINDING==PER_FACE // FIXME: optimize by moving first 2 vertices in row outside loop if (j > 0) mb->send(midx++, TRUE); #endif SEND_VERTEX(start + curridx); } glEnd(); // end of strip/row } }