/**************************************************************************\ * * 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 int32_t *indices, int num_vertexindices, const SbVec3f *normals, const int32_t *normindices, SoMaterialBundle *const materials, const int32_t *matindices, const SoTextureCoordinateBundle * const texcoords, const int32_t *texindices, const int drawAsPoints) { const SbVec3f * coords3d = NULL; const SbVec4f * coords4d = NULL; const SbBool is3d = coords->is3D(); if (is3d) { coords3d = coords->getArrayPtr3(); } else { coords4d = coords->getArrayPtr4(); } int numcoords = coords->getNum(); // 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_VERTEX_INDEXED if (matindices == NULL) matindices = indices; #endif #if NBINDING==PER_VERTEX_INDEXED if (normindices == NULL) normindices = indices; #endif #if MBINDING==PER_VERTEX || MBINDING==PER_LINE || MBINDING==PER_SEGMENT int matnr = 0; #endif #if TEXTURES==TRUE int texidx = 0; #endif int32_t i; const int32_t *end = indices + num_vertexindices; SbVec3f dummynormal(0.0f, 0.0f, 1.0f); const SbVec3f *currnormal = &dummynormal; if (normals) currnormal = normals; #if NBINDING==OVERALL glNormal3fv((const GLfloat*)currnormal); #endif #if MBINDING==PER_SEGMENT || MBINDING==PER_SEGMENT_INDEXED || NBINDING==PER_SEGMENT || NBINDING==PER_SEGMENT_INDEXED int previ; if (drawAsPoints) glBegin(GL_POINTS); else glBegin(GL_LINES); while (indices < end) { previ = *indices++; // Variable used for counting errors and make sure not a bunch of // errormessages flood the screen. static uint32_t current_errors = 0; // This test is for robustness upon buggy data sets if (previ < 0 || previ >= numcoords) { if (current_errors < 1) { SoDebugError::postWarning("[indexedlineset]::GLRender", "Erroneous coordinate " "index: %d (Should be within [0, %d]). Aborting " "rendering. This message will be shown once, but " "there might be more errors", previ, numcoords - 1); } current_errors++; glEnd(); return; } #if MBINDING==PER_LINE || MBINDING==PER_VERTEX materials->send(matnr++, TRUE); #elif MBINDING==PER_LINE_INDEXED || MBINDING==PER_VERTEX_INDEXED materials->send(*matindices++, TRUE); #endif #if NBINDING==PER_LINE || NBINDING==PER_VERTEX currnormal = normals++; glNormal3fv((const GLfloat*) currnormal); #elif NBINDING==PER_LINE_INDEXED || NBINDING==PER_VERTEX_INDEXED currnormal = &normals[*normindices++]; glNormal3fv((const GLfloat*) currnormal); #endif #if TEXTURES==TRUE texcoords->send(texindices ? *texindices++ : texidx++,coords->get3(previ), *currnormal); #endif i = (indices < end) ? *indices++ : -1; while (i >= 0) { // For robustness upon buggy data sets if (i >= numcoords) { if (current_errors < 1) { SoDebugError::postWarning("[indexedlineset]::GLRender", "Erroneous coordinate " "index: %d (Should be within [0, %d]). Aborting " "rendering. This message will be shown once, but " "there might be more errors", i, numcoords - 1); } current_errors++; break; } #if MBINDING==PER_SEGMENT materials->send(matnr++, TRUE); #elif MBINDING==PER_SEGMENT_INDEXED materials->send(*matindices++, TRUE); #endif #if NBINDING==PER_SEGMENT currnormal = normals++; glNormal3fv((const GLfloat*) currnormal); #elif NBINDING==PER_SEGMENT_INDEXED currnormal = &normals[*normindices++]; glNormal3fv((const GLfloat*)currnormal); #endif SEND_VERTEX(previ); #if MBINDING==PER_VERTEX materials->send(matnr++, TRUE); #elif MBINDING==PER_VERTEX_INDEXED materials->send(*matindices++, TRUE); #endif #if NBINDING==PER_VERTEX currnormal = normals++; glNormal3fv((const GLfloat*)currnormal); #elif NBINDING==PER_VERTEX_INDEXED currnormal = &normals[*normindices++]; glNormal3fv((const GLfloat*)currnormal); #endif #if TEXTURES==TRUE texcoords->send(texindices ? *texindices++ : texidx++, coords->get3(i), *currnormal); #endif SEND_VERTEX(i); previ = i; i = indices < end ? *indices++ : -1; } #if MBINDING==PER_VERTEX_INDEXED matindices++; #endif #if NBINDING==PER_VERTEX_INDEXED normindices++; #endif #if TEXTURES==TRUE if (texindices) texindices++; #endif } glEnd(); #else // no per_segment binding code below if (drawAsPoints) glBegin(GL_POINTS); while (indices < end) { if (!drawAsPoints) glBegin(GL_LINE_STRIP); i = *indices++; // Variable used for counting errors and make sure not a bunch of // errormessages flood the screen. static uint32_t current_errors = 0; // This test is for robustness upon buggy data sets if (i < 0 || i >= numcoords) { if (current_errors < 1) { SoDebugError::postWarning("[indexedlineset]::GLRender", "Erroneous coordinate " "index: %d (Should be within [0, %d]). Aborting " "rendering. This message will be shown once, but " "there might be more errors", i, numcoords - 1); } current_errors++; glEnd(); return; } #if MBINDING==PER_VERTEX_INDEXED || MBINDING==PER_LINE_INDEXED materials->send(*matindices++, TRUE); #elif MBINDING==PER_VERTEX || MBINDING==PER_LINE materials->send(matnr++, TRUE); #endif #if NBINDING==PER_VERTEX_INDEXED || NBINDING==PER_LINE_INDEXED currnormal = &normals[*normindices++]; glNormal3fv((const GLfloat*) currnormal); #elif NBINDING==PER_VERTEX || NBINDING==PER_LINE currnormal = normals++; glNormal3fv((const GLfloat*) currnormal); #endif #if TEXTURES==TRUE texcoords->send(texindices ? *texindices++ : texidx++, coords->get3(i), *currnormal); #endif SEND_VERTEX(i); i = indices < end ? *indices++ : -1; while (i >= 0) { // For robustness upon buggy data sets if (i >= numcoords) { if (current_errors < 1) { SoDebugError::postWarning("[indexedlineset]::GLRender", "Erroneous coordinate " "index: %d (Should be within [0, %d]). Aborting " "rendering. This message will be shown once, but " "there might be more errors", i, numcoords - 1); } current_errors++; break; } #if MBINDING==PER_VERTEX materials->send(matnr++, TRUE); #elif MBINDING==PER_VERTEX_INDEXED materials->send(*matindices++, TRUE); #endif #if NBINDING==PER_VERTEX currnormal = normals++; glNormal3fv((const GLfloat*) currnormal); #elif NBINDING==PER_VERTEX_INDEXED currnormal = &normals[*normindices++]; glNormal3fv((const GLfloat*) currnormal); #endif #if TEXTURES==TRUE texcoords->send(texindices ? *texindices++ : texidx++, coords->get3(i), *currnormal); #endif SEND_VERTEX(i); i = indices < end ? *indices++ : -1; } if (!drawAsPoints) glEnd(); // end of line strip #if MBINDING==PER_VERTEX_INDEXED matindices++; #endif #if NBINDING==PER_VERTEX_INDEXED normindices++; #endif #if TEXTURES==TRUE if (texindices) texindices++; #endif } if (drawAsPoints) glEnd(); #endif } #undef SEND_VERTEX