From 06054d95208541446f51c2883c8d0bcd8c476ac6 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 6 May 2003 13:13:31 +0000 Subject: [PATCH] Added support for multibuffering of tex coordinates. --- .../osgautotransform/osgautotransform.cpp | 32 ++- include/osg/Quat | 6 + include/osg/buffered_value | 25 +- include/osgText/String | 29 +- include/osgText/Text | 72 ++--- src/osg/AutoTransform.cpp | 4 +- src/osgPlugins/osgText/IO_Text.cpp | 8 +- src/osgText/Text.cpp | 251 +++++++++++------- 8 files changed, 268 insertions(+), 159 deletions(-) diff --git a/examples/osgautotransform/osgautotransform.cpp b/examples/osgautotransform/osgautotransform.cpp index 565681c70..2700a8d5e 100644 --- a/examples/osgautotransform/osgautotransform.cpp +++ b/examples/osgautotransform/osgautotransform.cpp @@ -62,7 +62,7 @@ osg::Node* createLabel2(const osg::Vec3& pos, float size, const std::string& lab text->setCharacterSize(size); text->setAlignment(osgText::Text::CENTER_CENTER); text->setAutoRotateToScreen(true); - text->setAutoScaleToScreen(true); + text->setAutoScaleToLimitScreenSizeToFontResolution(true); text->setDrawMode(osgText::Text::TEXT_PIXMAP); text->setText(label); @@ -87,7 +87,7 @@ osg::Node* createLabel3(const osg::Vec3& pos, float size, const std::string& lab text->setCharacterSize(size); text->setAlignment(osgText::Text::CENTER_CENTER); text->setAutoRotateToScreen(true); - text->setAutoScaleToScreen(true); + text->setAutoScaleToLimitScreenSizeToFontResolution(true); text->setText(label); } @@ -242,4 +242,32 @@ int main( int argc, char **argv ) viewer.sync(); return 0; + + +// osg::Node* obj = new osg::Node; +// cout << "obj = "<(nv); if (!cs) return false; - - if (_lastTraversalNumber!=nv->getTraversalNumber()) - { - _lastUpdateContextID = 0xffffffff; - } - - _lastTraversalNumber = nv->getTraversalNumber(); - unsigned int contextID = cs->getState() ? cs->getState()->getContextID() : 0; - if (_lastUpdateContextIDgetViewport(); if (viewport) @@ -66,61 +63,57 @@ struct TextCullCallback : public osg::Drawable::CullCallback osg::Vec3 eyePoint = cs->getEyeLocal(); - bool doUpdate = _firstTimeToInitEyePoint; - if (!_firstTimeToInitEyePoint) + bool doUpdate = positionData._traversalNumber==-1; + if (positionData._traversalNumber>=0) { - osg::Vec3 dv = _previousEyePoint-eyePoint; + osg::Vec3 dv = positionData._eyePosition-eyePoint; if (dv.length2()>_text->getAutoUpdateEyeMovementTolerance()*(eyePoint-_text->getPosition()).length2()) { doUpdate = true; } - else if (width!=_previousWidth || height!=_previousHeight) + else if (width!=positionData._previousWidth || height!=positionData._previousHeight) { doUpdate = true; } } - _firstTimeToInitEyePoint = false; + + positionData._traversalNumber = nv->getTraversalNumber(); + positionData._previousWidth = width; + positionData._previousHeight = height; if (doUpdate) { - _lastUpdateContextID = contextID; + float scale=_text->getScale(contextID); if (_text->getAutoScaleToLimitScreenSizeToFontResolution()) { float numPixels = cs->pixelSize(_text->getPosition(),_text->getCharacterHeight()); if (numPixels>_text->getFontHeight()) { - _text->setScale(_text->getFontHeight()/numPixels); + scale = _text->getFontHeight()/numPixels; } //float size = 1.0f/cs->pixelSize(_text->getPosition(),1.0f); //_text->setScale(size); } + osg::Quat rotation = _text->getRotation(contextID); if (_text->getAutoRotateToScreen()) { - osg::Quat rotation; - rotation.set(cs->getModelViewMatrix()); - _text->setRotation(rotation.inverse()); + rotation.set(cs->getModelViewMatrix()); + rotation = rotation.inverse(); } - _previousEyePoint = eyePoint; - _previousWidth = width; - _previousHeight = height; - + _text->setScaleAndRotation(contextID,scale,rotation); + } return false; } - - - mutable bool _firstTimeToInitEyePoint; - mutable osg::Vec3 _previousEyePoint; - mutable int _previousWidth; - mutable int _previousHeight; - mutable unsigned int _lastUpdateContextID; - mutable int _lastTraversalNumber; + + typedef osg::buffered_object PositionList; + mutable PositionList _positions; mutable osgText::Text* _text; }; @@ -135,8 +128,6 @@ Text::Text(): _maximumWidth(0.0f), _maximumHeight(0.0f), _alignment(BASE_LINE), - _rotation(), - _scale(1.0f), _autoUpdateEyeMovementTolerance(0.0f), _autoRotateToScreen(false), _autoScaleToLimitScreenSizeToFontResolution(false), @@ -145,6 +136,7 @@ Text::Text(): _drawMode(TEXT) { setUseDisplayList(false); + setScale(1.0f); } Text::Text(const Text& text,const osg::CopyOp& copyop): @@ -220,37 +212,46 @@ void Text::setMaximumHeight(float maximumHeight) void Text::setText(const String& text) { + if (_text==text) return; + _text = text; computeGlyphRepresentation(); } void Text::setText(const std::string& text) { - _text.set(text); - computeGlyphRepresentation(); + setText(String(text)); +// _text.set(text); +// computeGlyphRepresentation(); } void Text::setText(const std::string& text,String::Encoding encoding) { - _text.set(text,encoding); - computeGlyphRepresentation(); + setText(String(text,encoding)); +// _text.set(text,encoding); +// computeGlyphRepresentation(); } void Text::setText(const wchar_t* text) { - _text.set(text); - computeGlyphRepresentation(); + setText(String(text)); +// _text.set(text); +// computeGlyphRepresentation(); } void Text::setPosition(const osg::Vec3& pos) { + if (_position==pos) return; + _position = pos; computePositions(); } void Text::setAlignment(AlignmentType alignment) { + if (_alignment==alignment) return; + _alignment = alignment; computePositions(); } @@ -275,31 +276,65 @@ void Text::setAxisAlignment(AxisAlignment axis) } } -void Text::setAutoRotateToScreen(bool autoRotateToScreen) -{ - _autoRotateToScreen = autoRotateToScreen; - setUpAutoCallback(); -} - void Text::setRotation(const osg::Quat& quat) { - _rotation = quat; - computePositions(); + for(unsigned int i=0;i<_rotation.size();++i) + { + setRotation(i,quat); + } } -void Text::setAutoScaleToLimitScreenSizeToFontResolution(bool autoScaleToScreen) +void Text::setRotation(unsigned int contextID, const osg::Quat& quat) { - _autoScaleToLimitScreenSizeToFontResolution = autoScaleToScreen; - setUpAutoCallback(); + if (_rotation[contextID]==quat) return; + + _rotation[contextID] = quat; + computePositions(contextID); } void Text::setScale(float scale) { - _scale = scale; - setUpAutoCallback(); - computePositions(); + for(unsigned int i=0;i<_scale.size();++i) + { + setScale(i,scale); + } } +void Text::setScale(unsigned int contextID, float scale) +{ + if (_scale[contextID]==scale) return; + + _scale[contextID] = scale; + computePositions(contextID); +} + +void Text::setScaleAndRotation(unsigned int contextID, float scale,const osg::Quat& quat) +{ + if (_scale[contextID]==scale && _rotation[contextID]==quat) return; + + _scale[contextID] = scale; + _rotation[contextID] = quat; + + computePositions(contextID); +} + +void Text::setAutoScaleToLimitScreenSizeToFontResolution(bool autoScaleToScreen) +{ + if (_autoScaleToLimitScreenSizeToFontResolution==autoScaleToScreen) return; + + _autoScaleToLimitScreenSizeToFontResolution = autoScaleToScreen; + setUpAutoCallback(); +} + +void Text::setAutoRotateToScreen(bool autoRotateToScreen) +{ + if (_autoRotateToScreen==autoRotateToScreen) return; + + _autoRotateToScreen = autoRotateToScreen; + setUpAutoCallback(); +} + + void Text::setUpAutoCallback() { if (_autoRotateToScreen || _autoScaleToLimitScreenSizeToFontResolution) @@ -314,6 +349,8 @@ void Text::setUpAutoCallback() void Text::setLayout(Layout layout) { + if (_layout==layout) return; + _layout = layout; computeGlyphRepresentation(); } @@ -325,6 +362,8 @@ void Text::setColor(const osg::Vec4& color) void Text::setDrawMode(unsigned int mode) { + if (_drawMode==mode) return; + if (_drawMode&3 != mode&3) { _drawMode=mode; @@ -348,10 +387,15 @@ bool Text::computeBound() const if (_textBB.valid()) { - _bbox.expandBy(osg::Vec3(_textBB.xMin(),_textBB.yMin(),_textBB.zMin())*_matrix); - _bbox.expandBy(osg::Vec3(_textBB.xMax(),_textBB.yMin(),_textBB.zMin())*_matrix); - _bbox.expandBy(osg::Vec3(_textBB.xMax(),_textBB.yMax(),_textBB.zMin())*_matrix); - _bbox.expandBy(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMin())*_matrix); + + for(unsigned int i=0;i<_matrix.size();++i) + { + osg::Matrix& matrix = _matrix[i]; + _bbox.expandBy(osg::Vec3(_textBB.xMin(),_textBB.yMin(),_textBB.zMin())*matrix); + _bbox.expandBy(osg::Vec3(_textBB.xMax(),_textBB.yMin(),_textBB.zMin())*matrix); + _bbox.expandBy(osg::Vec3(_textBB.xMax(),_textBB.yMax(),_textBB.zMin())*matrix); + _bbox.expandBy(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMin())*matrix); + } } _bbox_computed = true; @@ -558,7 +602,16 @@ void Text::computeGlyphRepresentation() computePositions(); } + void Text::computePositions() +{ + for(unsigned int i=0;i<_matrix.size();++i) + { + computePositions(i); + } +} + +void Text::computePositions(unsigned int contextID) { switch(_alignment) @@ -578,22 +631,24 @@ void Text::computePositions() case CENTER_BASE_LINE: _offset.set((_textBB.xMax()+_textBB.xMin())*0.5f,0.0f,0.0f); break; case RIGHT_BASE_LINE: _offset.set((_textBB.xMax()+_textBB.xMin()),0.0f,0.0f); break; } + + osg::Matrix& matrix = _matrix[contextID]; - if (_scale!=1.0f || !_rotation.zeroRotation()) + if (_scale[contextID]!=1.0f || !_rotation[contextID].zeroRotation()) { - _matrix.makeTranslate(-_offset); + matrix.makeTranslate(-_offset); - if (_scale!=1.0f) - _matrix.postMult(osg::Matrix::scale(_scale,_scale,_scale)); - if (!_rotation.zeroRotation()) - _matrix.postMult(osg::Matrix::rotate(_rotation)); + if (_scale[contextID]!=1.0f) + matrix.postMult(osg::Matrix::scale(_scale[contextID],_scale[contextID],_scale[contextID])); + if (!_rotation[contextID].zeroRotation()) + matrix.postMult(osg::Matrix::rotate(_rotation[contextID])); - _matrix.postMult(osg::Matrix::translate(_position)); + matrix.postMult(osg::Matrix::translate(_position)); } else { - _matrix.makeTranslate(_position-_offset); + matrix.makeTranslate(_position-_offset); } @@ -604,7 +659,7 @@ void Text::computePositions() { GlyphQuads& glyphquad = titr->second; GlyphQuads::Coords2& coords2 = glyphquad._coords; - GlyphQuads::Coords3& transformedCoords = glyphquad._transformedCoords; + GlyphQuads::Coords3& transformedCoords = glyphquad._transformedCoords[contextID]; unsigned int numCoords = coords2.size(); if (numCoords!=transformedCoords.size()) @@ -614,11 +669,11 @@ void Text::computePositions() for(unsigned int i=0;isecond; - state.setVertexPointer( 3, GL_FLOAT, 0, &(glyphquad._transformedCoords.front())); + state.setVertexPointer( 3, GL_FLOAT, 0, &(glyphquad._transformedCoords[contextID].front())); state.setTexCoordPointer( 0, 2, GL_FLOAT, 0, &(glyphquad._texcoords.front())); glDrawArrays(GL_QUADS,0,glyphquad._coords.size()); @@ -674,7 +729,7 @@ void Text::drawImplementation(osg::State& state) const Font::Glyph* glyph = *gitr; - glRasterPos3fv(glyphquad._transformedCoords[ci].ptr()); + glRasterPos3fv(glyphquad._transformedCoords[contextID][ci].ptr()); glyph->draw(state); @@ -690,10 +745,12 @@ void Text::drawImplementation(osg::State& state) const { state.applyTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF); - osg::Vec3 c00(osg::Vec3(_textBB.xMin(),_textBB.yMin(),_textBB.zMin())*_matrix); - osg::Vec3 c10(osg::Vec3(_textBB.xMax(),_textBB.yMin(),_textBB.zMin())*_matrix); - osg::Vec3 c11(osg::Vec3(_textBB.xMax(),_textBB.yMax(),_textBB.zMin())*_matrix); - osg::Vec3 c01(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMin())*_matrix); + osg::Matrix& matrix = _matrix[contextID]; + + osg::Vec3 c00(osg::Vec3(_textBB.xMin(),_textBB.yMin(),_textBB.zMin())*matrix); + osg::Vec3 c10(osg::Vec3(_textBB.xMax(),_textBB.yMin(),_textBB.zMin())*matrix); + osg::Vec3 c11(osg::Vec3(_textBB.xMax(),_textBB.yMax(),_textBB.zMin())*matrix); + osg::Vec3 c01(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMin())*matrix); glColor4f(1.0f,1.0f,0.0f,1.0f); @@ -710,12 +767,14 @@ void Text::drawImplementation(osg::State& state) const { glColor4f(1.0f,0.0f,1.0f,1.0f); - float cursorsize = _characterHeight*0.5f*_scale; + float cursorsize = _characterHeight*0.5f*_scale[contextID]; - osg::Vec3 hl(osg::Vec3(_offset.x()-cursorsize,_offset.y(),_offset.z())*_matrix); - osg::Vec3 hr(osg::Vec3(_offset.x()+cursorsize,_offset.y(),_offset.z())*_matrix); - osg::Vec3 vt(osg::Vec3(_offset.x(),_offset.y()-cursorsize,_offset.z())*_matrix); - osg::Vec3 vb(osg::Vec3(_offset.x(),_offset.y()+cursorsize,_offset.z())*_matrix); + osg::Matrix& matrix = _matrix[contextID]; + + osg::Vec3 hl(osg::Vec3(_offset.x()-cursorsize,_offset.y(),_offset.z())*matrix); + osg::Vec3 hr(osg::Vec3(_offset.x()+cursorsize,_offset.y(),_offset.z())*matrix); + osg::Vec3 vt(osg::Vec3(_offset.x(),_offset.y()-cursorsize,_offset.z())*matrix); + osg::Vec3 vb(osg::Vec3(_offset.x(),_offset.y()+cursorsize,_offset.z())*matrix); state.applyTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF); @@ -739,7 +798,7 @@ void Text::accept(osg::Drawable::ConstAttributeFunctor& af) const ++titr) { const GlyphQuads& glyphquad = titr->second; - af.apply(osg::Drawable::VERTICES,glyphquad._transformedCoords.size(),&(glyphquad._transformedCoords.front())); + af.apply(osg::Drawable::VERTICES,glyphquad._transformedCoords[0].size(),&(glyphquad._transformedCoords[0].front())); af.apply(osg::Drawable::TEXTURE_COORDS_0,glyphquad._texcoords.size(),&(glyphquad._texcoords.front())); } } @@ -752,8 +811,8 @@ void Text::accept(osg::Drawable::PrimitiveFunctor& pf) const { const GlyphQuads& glyphquad = titr->second; - pf.setVertexArray(glyphquad._transformedCoords.size(),&(glyphquad._transformedCoords.front())); - pf.drawArrays(GL_QUADS,0,glyphquad._transformedCoords.size()); + pf.setVertexArray(glyphquad._transformedCoords[0].size(),&(glyphquad._transformedCoords[0].front())); + pf.drawArrays(GL_QUADS,0,glyphquad._transformedCoords[0].size()); // pf.begin(GL_QUADS); // for(GlyphQuads::Coords3::const_iterator itr = glyphquad._transformedCoords.begin();