From f4966a96d4e042b73b8b13e54b19149a726780a8 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 1 Mar 2017 11:51:27 +0000 Subject: [PATCH] Replaced hardwired glDrawArrays calls with use of osg::DrawElementsUshort. --- include/osgText/Text | 5 -- include/osgText/TextBase | 10 +++- src/osgText/Text.cpp | 91 ++++++++++++++-------------- src/osgText/Text3D.cpp | 33 ++++------- src/osgText/TextBase.cpp | 125 ++++++++++++++++++++++++++------------- 5 files changed, 150 insertions(+), 114 deletions(-) diff --git a/include/osgText/Text b/include/osgText/Text index fa270391d..20b5ee6c0 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -295,10 +295,6 @@ public: public: - typedef osg::ref_ptr Coords; - typedef osg::ref_ptr TexCoords; - typedef osg::ref_ptr ColorCoords; - Coords _coords; ColorCoords _colorCoords; TexCoords _texcoords; @@ -318,7 +314,6 @@ public: struct OSGTEXT_EXPORT GlyphQuads { typedef std::vector Glyphs; - typedef std::vector< osg::ref_ptr > Primitives; Glyphs _glyphs; Primitives _primitives; diff --git a/include/osgText/TextBase b/include/osgText/TextBase index 4a365c0d0..3bb244dd8 100644 --- a/include/osgText/TextBase +++ b/include/osgText/TextBase @@ -279,6 +279,10 @@ protected: virtual void computeGlyphRepresentation() = 0; + typedef osg::ref_ptr Coords; + typedef osg::ref_ptr TexCoords; + typedef osg::ref_ptr ColorCoords; + typedef std::vector< osg::ref_ptr > Primitives; // members which have public access. osg::Vec4 _color; @@ -311,9 +315,13 @@ protected: mutable osg::Matrix _matrix; + Coords _decorationVertices; + Primitives _decorationPrimitives; + void setupDecoration(); - osg::ref_ptr _decorationVertices; + + }; diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 2c965cdbc..2a326e8d7 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -1094,68 +1094,65 @@ void Text::drawImplementation(osg::State& state, const osg::Vec4& colorMultiplie if ((_drawMode&(~TEXT))!=0) { - state.disableNormalPointer(); - - state.Color(colorMultiplier.r()*_textBBColor.r(),colorMultiplier.g()*_textBBColor.g(),colorMultiplier.b()*_textBBColor.b(),colorMultiplier.a()*_textBBColor.a()); - if (_decorationVertices.valid() && !_decorationVertices->empty()) { + state.disableNormalPointer(); + osg::State::ApplyModeProxy applyMode(state, GL_LIGHTING, false); osg::State::ApplyTextureModeProxy applyTextureMode(state, 0, GL_TEXTURE_2D, false); state.disableAllVertexArrays(); state.setVertexPointer(_decorationVertices.get()); - unsigned int start_index = 0; - if ((_drawMode & FILLEDBOUNDINGBOX)!=0 && _textBB.valid()) + #if !defined(OSG_GLES1_AVAILABLE) && !defined(OSG_GLES2_AVAILABLE) && !defined(OSG_GL3_AVAILABLE) + switch(_backdropImplementation) { - #if !defined(OSG_GLES1_AVAILABLE) && !defined(OSG_GLES2_AVAILABLE) && !defined(OSG_GL3_AVAILABLE) - switch(_backdropImplementation) - { - case NO_DEPTH_BUFFER: - // Do nothing. The bounding box will be rendered before the text and that's all that matters. - break; - case DEPTH_RANGE: - glPushAttrib(GL_DEPTH_BUFFER_BIT); - //unsigned int backdrop_index = 0; - //unsigned int max_backdrop_index = 8; - //const double offset = double(max_backdrop_index - backdrop_index) * 0.003; - glDepthRange(0.001, 1.001); - break; - /*case STENCIL_BUFFER: - break;*/ - default: - glPushAttrib(GL_POLYGON_OFFSET_FILL); - glEnable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(0.1f * osg::PolygonOffset::getFactorMultiplier(), 10.0f * osg::PolygonOffset::getUnitsMultiplier() ); - } + case NO_DEPTH_BUFFER: + // Do nothing. The bounding box will be rendered before the text and that's all that matters. + break; + case DEPTH_RANGE: + glPushAttrib(GL_DEPTH_BUFFER_BIT); + //unsigned int backdrop_index = 0; + //unsigned int max_backdrop_index = 8; + //const double offset = double(max_backdrop_index - backdrop_index) * 0.003; + glDepthRange(0.001, 1.001); + break; + /*case STENCIL_BUFFER: + break;*/ + default: + glPushAttrib(GL_POLYGON_OFFSET_FILL); + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(0.1f * osg::PolygonOffset::getFactorMultiplier(), 10.0f * osg::PolygonOffset::getUnitsMultiplier() ); + } + #endif - glDrawArrays(GL_QUADS, 0, 4); - start_index += 4; + for(Primitives::const_iterator itr = _decorationPrimitives.begin(); + itr != _decorationPrimitives.end(); + ++itr) + { + if ((*itr)->getMode()==GL_TRIANGLES) state.Color(colorMultiplier.r()*_textBBColor.r(), colorMultiplier.g()*_textBBColor.g(), colorMultiplier.b()*_textBBColor.b(), colorMultiplier.a()*_textBBColor.a()); + else state.Color(colorMultiplier.r(), colorMultiplier.g(), colorMultiplier.b(), colorMultiplier.a()); - switch(_backdropImplementation) - { - case NO_DEPTH_BUFFER: - // Do nothing. - break; - case DEPTH_RANGE: - glDepthRange(0.0, 1.0); - glPopAttrib(); - break; - /*case STENCIL_BUFFER: - break;*/ - default: - glDisable(GL_POLYGON_OFFSET_FILL); - glPopAttrib(); - } - #endif + (*itr)->draw(state, _useVertexBufferObjects); } - if (start_index<_decorationVertices->size()) + #if !defined(OSG_GLES1_AVAILABLE) && !defined(OSG_GLES2_AVAILABLE) && !defined(OSG_GL3_AVAILABLE) + switch(_backdropImplementation) { - state.Color(colorMultiplier.r(),colorMultiplier.g(),colorMultiplier.b(),colorMultiplier.a()); - glDrawArrays(GL_LINES, start_index, _decorationVertices->size()); + case NO_DEPTH_BUFFER: + // Do nothing. + break; + case DEPTH_RANGE: + glDepthRange(0.0, 1.0); + glPopAttrib(); + break; + /*case STENCIL_BUFFER: + break;*/ + default: + glDisable(GL_POLYGON_OFFSET_FILL); + glPopAttrib(); } + #endif } } diff --git a/src/osgText/Text3D.cpp b/src/osgText/Text3D.cpp index 097e21138..7c4545395 100644 --- a/src/osgText/Text3D.cpp +++ b/src/osgText/Text3D.cpp @@ -468,18 +468,11 @@ void Text3D::drawImplementation(osg::RenderInfo& renderInfo) const state.setVertexPointer(_decorationVertices.get()); - unsigned int start_index = 0; - if ((_drawMode & FILLEDBOUNDINGBOX)!=0 && _textBB.valid()) + for(Primitives::const_iterator itr = _decorationPrimitives.begin(); + itr != _decorationPrimitives.end(); + ++itr) { - state.Color(_textBBColor.r(),_textBBColor.g(),_textBBColor.b(),_textBBColor.a()); - glDrawArrays(GL_QUADS, 0, 4); - start_index += 4; - } - - if (start_index<_decorationVertices->size()) - { - state.Color(_color.r(),_color.g(),_color.b(),_color.a()); - glDrawArrays(GL_LINES, start_index, _decorationVertices->size()); + (*itr)->draw(state, _useVertexBufferObjects); } } } @@ -602,13 +595,13 @@ void Text3D::renderPerFace(osg::State & state) const LineRenderInfo::const_iterator it, endLine = itLine->end(); for (it = itLine->begin(); it!=endLine; ++it) { + state.setVertexPointer(it->_glyphGeometry->getVertexArray()); + state.setNormalPointer(it->_glyphGeometry->getNormalArray()); + osg::Matrix matrix(original_modelview); matrix.preMultTranslate(osg::Vec3d(it->_position.x(), it->_position.y(), it->_position.z())); state.applyModelViewMatrix(matrix); - state.setVertexPointer(it->_glyphGeometry->getVertexArray()); - state.setNormalPointer(it->_glyphGeometry->getNormalArray()); - // ** render the front face of the glyph osg::Geometry::PrimitiveSetList & psl = it->_glyphGeometry->getFrontPrimitiveSetList(); for(osg::Geometry::PrimitiveSetList::const_iterator itr=psl.begin(), end=psl.end(); itr!=end; ++itr) @@ -627,13 +620,13 @@ void Text3D::renderPerFace(osg::State & state) const LineRenderInfo::const_iterator it, endLine = itLine->end(); for (it = itLine->begin(); it!=endLine; ++it) { + state.setVertexPointer(it->_glyphGeometry->getVertexArray()); + state.setNormalPointer(it->_glyphGeometry->getNormalArray()); + osg::Matrix matrix(original_modelview); matrix.preMultTranslate(osg::Vec3d(it->_position.x(), it->_position.y(), it->_position.z())); state.applyModelViewMatrix(matrix); - state.setVertexPointer(it->_glyphGeometry->getVertexArray()); - state.setNormalPointer(it->_glyphGeometry->getNormalArray()); - const osg::Geometry::PrimitiveSetList & psl = it->_glyphGeometry->getWallPrimitiveSetList(); for(osg::Geometry::PrimitiveSetList::const_iterator itr=psl.begin(), end=psl.end(); itr!=end; ++itr) { @@ -654,13 +647,13 @@ void Text3D::renderPerFace(osg::State & state) const LineRenderInfo::const_iterator it, endLine = itLine->end(); for (it = itLine->begin(); it!=endLine; ++it) { + state.setVertexPointer(it->_glyphGeometry->getVertexArray()); + state.setNormalPointer(it->_glyphGeometry->getNormalArray()); + osg::Matrix matrix(original_modelview); matrix.preMultTranslate(osg::Vec3d(it->_position.x(), it->_position.y(), it->_position.z())); state.applyModelViewMatrix(matrix); - state.setVertexPointer(it->_glyphGeometry->getVertexArray()); - state.setNormalPointer(it->_glyphGeometry->getNormalArray()); - // ** render the back face of the glyph const osg::Geometry::PrimitiveSetList & psl = it->_glyphGeometry->getBackPrimitiveSetList(); for(osg::Geometry::PrimitiveSetList::const_iterator itr=psl.begin(), end=psl.end(); itr!=end; ++itr) diff --git a/src/osgText/TextBase.cpp b/src/osgText/TextBase.cpp index 9628eaac0..20f827996 100644 --- a/src/osgText/TextBase.cpp +++ b/src/osgText/TextBase.cpp @@ -630,6 +630,7 @@ void TextBase::setupDecoration() } _decorationVertices->clear(); + _decorationPrimitives.clear(); if ((_drawMode & FILLEDBOUNDINGBOX)!=0 && _textBB.valid()) { @@ -638,10 +639,22 @@ void TextBase::setupDecoration() osg::Vec3 c110(_textBB.xMax(),_textBB.yMax(),_textBB.zMin()); osg::Vec3 c010(_textBB.xMin(),_textBB.yMax(),_textBB.zMin()); + unsigned int base = _decorationVertices->size(); + _decorationVertices->push_back(c000); _decorationVertices->push_back(c100); _decorationVertices->push_back(c110); _decorationVertices->push_back(c010); + + osg::ref_ptr primitives = new osg::DrawElementsUShort(GL_TRIANGLES); + _decorationPrimitives.push_back(primitives); + + primitives->push_back(base); + primitives->push_back(base+1); + primitives->push_back(base+2); + primitives->push_back(base); + primitives->push_back(base+1); + primitives->push_back(base+3); } if ((_drawMode & BOUNDINGBOX)!=0 && _textBB.valid()) @@ -653,17 +666,20 @@ void TextBase::setupDecoration() osg::Vec3 c110(_textBB.xMax(),_textBB.yMax(),_textBB.zMin()); osg::Vec3 c010(_textBB.xMin(),_textBB.yMax(),_textBB.zMin()); + unsigned int base = _decorationVertices->size(); + _decorationVertices->push_back(c000); _decorationVertices->push_back(c100); - - _decorationVertices->push_back(c100); - _decorationVertices->push_back(c110); - _decorationVertices->push_back(c110); _decorationVertices->push_back(c010); - _decorationVertices->push_back(c010); - _decorationVertices->push_back(c000); + osg::ref_ptr primitives = new osg::DrawElementsUShort(GL_LINE_LOOP); + _decorationPrimitives.push_back(primitives); + + primitives->push_back(base); + primitives->push_back(base+1); + primitives->push_back(base+2); + primitives->push_back(base+3); } else { @@ -677,46 +693,61 @@ void TextBase::setupDecoration() osg::Vec3 c111(_textBB.xMax(),_textBB.yMax(),_textBB.zMax()); osg::Vec3 c011(_textBB.xMin(),_textBB.yMax(),_textBB.zMax()); + unsigned int base = _decorationVertices->size(); + + _decorationVertices->push_back(c000); // +0 + _decorationVertices->push_back(c100); // +1 + _decorationVertices->push_back(c110); // +2 + _decorationVertices->push_back(c010); // +3 + + _decorationVertices->push_back(c001); // +4 + _decorationVertices->push_back(c101); // +5 + _decorationVertices->push_back(c111); // +6 + _decorationVertices->push_back(c011); // +7 + + + osg::ref_ptr primitives = new osg::DrawElementsUShort(GL_LINES); + _decorationPrimitives.push_back(primitives); + + // front loop + primitives->push_back(base+0); + primitives->push_back(base+1); + + primitives->push_back(base+1); + primitives->push_back(base+2); + + primitives->push_back(base+2); + primitives->push_back(base+3); + + primitives->push_back(base+3); + primitives->push_back(base+0); + + // back loop + primitives->push_back(base+4); + primitives->push_back(base+5); + + primitives->push_back(base+5); + primitives->push_back(base+6); + + primitives->push_back(base+6); + primitives->push_back(base+7); + + primitives->push_back(base+7); + primitives->push_back(base+4); + // edges from corner 000 - _decorationVertices->push_back(c000); - _decorationVertices->push_back(c100); + primitives->push_back(base+0); + primitives->push_back(base+4); - _decorationVertices->push_back(c000); - _decorationVertices->push_back(c001); + primitives->push_back(base+1); + primitives->push_back(base+5); - _decorationVertices->push_back(c000); - _decorationVertices->push_back(c010); + primitives->push_back(base+2); + primitives->push_back(base+6); - // edges from corner C101 - _decorationVertices->push_back(c101); - _decorationVertices->push_back(c100); + primitives->push_back(base+3); + primitives->push_back(base+7); - _decorationVertices->push_back(c101); - _decorationVertices->push_back(c001); - - _decorationVertices->push_back(c101); - _decorationVertices->push_back(c111); - - - // edges from corner C110 - _decorationVertices->push_back(c110); - _decorationVertices->push_back(c010); - - _decorationVertices->push_back(c110); - _decorationVertices->push_back(c100); - - _decorationVertices->push_back(c110); - _decorationVertices->push_back(c111); - - // edges from corner C011 - _decorationVertices->push_back(c011); - _decorationVertices->push_back(c010); - - _decorationVertices->push_back(c011); - _decorationVertices->push_back(c001); - - _decorationVertices->push_back(c011); - _decorationVertices->push_back(c111); } } @@ -729,9 +760,21 @@ void TextBase::setupDecoration() osg::Vec3 vt(osg::Vec3(_offset.x(),_offset.y()-cursorsize,_offset.z())); osg::Vec3 vb(osg::Vec3(_offset.x(),_offset.y()+cursorsize,_offset.z())); + unsigned int base = _decorationVertices->size(); + _decorationVertices->push_back(hl); _decorationVertices->push_back(hr); _decorationVertices->push_back(vt); _decorationVertices->push_back(vb); + + osg::ref_ptr primitives = new osg::DrawElementsUShort(GL_LINES); + _decorationPrimitives.push_back(primitives); + + // front loop + primitives->push_back(base+0); + primitives->push_back(base+1); + + primitives->push_back(base+1); + primitives->push_back(base+2); } }