#include "GL_IndexedLineSet.h" #include "X3D_IndexedLineSet.h" #include "X3D_Coordinate.h" #include "X3D_Color.h" #include "X3D_ColorRGBA.h" #include using namespace std; namespace X3DTK { namespace GL { IndexedLineSet::IndexedLineSet() : X3DGeometryNode(), _lineWidth(0.0f), _verticesDuplicated(false), _color(false) { define(Recorder::getTypeName("IndexedLineSet", "Rendering")); } IndexedLineSet::~IndexedLineSet() { } void IndexedLineSet::setLineWidth(const SFFloat &lineWidth) { _lineWidth = lineWidth; } void IndexedLineSet::setVerticesDuplicated(const SFBool &verticesDuplicated) { _verticesDuplicated = verticesDuplicated; } void IndexedLineSet::setColor(const SFBool &color) { _color = color; } void IndexedLineSet::setC4UB_V3F_vertexArray(const std::vector &C4UB_V3F_vertexArray) { _C4UB_V3F_vertexArray = C4UB_V3F_vertexArray; } void IndexedLineSet::setV3F_vertexArray(const std::vector &V3F_vertexArray) { _V3F_vertexArray = V3F_vertexArray; } void IndexedLineSet::setIndexArrayArray(const std::vector &indexArrayArray) { _indexArrayArray = indexArrayArray; } void IndexedLineSet::update() { if (x3dReference == 0) return; X3D::IndexedLineSet *I = dynamic_cast(x3dReference); //emptying the arrays _C4UB_V3F_vertexArray.clear(); _V3F_vertexArray.clear(); _indexArrayArray.clear(); X3D::Coordinate *CoordNode = dynamic_cast(I->getCoord()); if (CoordNode == 0) return; const MFVec3f &pointArray = CoordNode->getPoint(); const MFInt32 &coordIndex = I->getCoordIndex(); _lineWidth = I->getLineWidth(); if (I->getColor() != 0) { _color = true; MFColorRGBA colorRGBA; if (I->getColor()->getTypeName() == "ColorRGBA") colorRGBA = dynamic_cast(I->getColor())->getColor(); else colorRGBA = dynamic_cast(I->getColor())->getColor(); SFBool colorPerVertex = I->getColorPerVertex(); const MFInt32 &colorIndex = I->getColorIndex(); if ((colorPerVertex) && (colorIndex.empty())) { //we use linestrip but the points are duplicated because of the fact //that a same point can be of two colors //there is one array per continuous line //filling the vertex arrays setVerticesDuplicated(false); //filling the vertex array by iterating the cordinate and color MFVec3f::const_iterator itPoint = pointArray.begin(); MFColorRGBA::const_iterator itColor = colorRGBA.begin(); while (itPoint != pointArray.end()) { C4UB_V3F element; element.r = (unsigned char)floorf(255.0f*(*itColor).r); element.g = (unsigned char)floorf(255.0f*(*itColor).g); element.b = (unsigned char)floorf(255.0f*(*itColor).b); element.a = (unsigned char)floorf(255.0f*(*itColor).a); element.vertex = *itPoint; _C4UB_V3F_vertexArray.push_back(element); ++itPoint; ++itColor; } //filling the index arrays. MFInt32::const_iterator itCoordIndex = coordIndex.begin(); while (itCoordIndex != coordIndex.end()) { _indexArrayArray.push_back(MFInt32()); while (*itCoordIndex != -1) { _indexArrayArray.back().push_back(*itCoordIndex); ++itCoordIndex; } ++itCoordIndex; } } else { //Vertices are duplicated setVerticesDuplicated(true); MFInt32::const_iterator itCoordIndex = coordIndex.begin(); MFInt32::const_iterator itColorIndex; if (colorIndex.empty()) itColorIndex = coordIndex.begin(); else itColorIndex = colorIndex.begin(); unsigned int k = 0; while (itCoordIndex != coordIndex.end()) { _indexArrayArray.push_back(MFInt32()); while (*itCoordIndex != -1) { C4UB_V3F element; SFColorRGBA currentColor = colorRGBA[*itColorIndex]; element.r = (unsigned char)floorf(255.0f*currentColor.r); element.g = (unsigned char)floorf(255.0f*currentColor.g); element.b = (unsigned char)floorf(255.0f*currentColor.b); element.a = (unsigned char)floorf(255.0f*currentColor.a); element.vertex = pointArray[*itCoordIndex]; _C4UB_V3F_vertexArray.push_back(element); _indexArrayArray.back().push_back(k); ++k; ++itCoordIndex; if (colorPerVertex) ++itColorIndex; } ++itCoordIndex; ++itColorIndex; } } } else { setVerticesDuplicated(false); //filling the vertex array by iterating the cordinate and color _V3F_vertexArray = pointArray; //filling the index arrays. MFInt32::const_iterator itCoordIndex = coordIndex.begin(); while (itCoordIndex != coordIndex.end()) { _indexArrayArray.push_back(MFInt32()); while (*itCoordIndex != -1) { _indexArrayArray.back().push_back(*itCoordIndex); ++itCoordIndex; } ++itCoordIndex; } } } void IndexedLineSet::draw() const { glLineWidth(_lineWidth); glDisable(GL_LIGHTING); if (getColor()) { glEnable(GL_COLOR_MATERIAL); glInterleavedArrays(GL_C4UB_V3F, 0, &_C4UB_V3F_vertexArray.front()); for (std::vector::const_iterator itIndex = _indexArrayArray.begin(); itIndex != _indexArrayArray.end(); ++itIndex) glDrawElements(GL_LINE_STRIP, (*itIndex).size(), GL_UNSIGNED_INT, &(*itIndex).front()); glDisable(GL_COLOR_MATERIAL); } else { glInterleavedArrays(GL_V3F, 0, &_V3F_vertexArray.front()); for (std::vector::const_iterator itIndex = _indexArrayArray.begin(); itIndex != _indexArrayArray.end(); ++itIndex) glDrawElements(GL_LINE_STRIP, (*itIndex).size(), GL_UNSIGNED_INT, &(*itIndex).front()); } glEnable(GL_LIGHTING); } } }