Added support for multibuffering of tex coordinates.

This commit is contained in:
Robert Osfield 2003-05-06 13:13:31 +00:00
parent 6c60fa233e
commit 06054d9520
8 changed files with 268 additions and 159 deletions

View File

@ -62,7 +62,7 @@ osg::Node* createLabel2(const osg::Vec3& pos, float size, const std::string& lab
text->setCharacterSize(size); text->setCharacterSize(size);
text->setAlignment(osgText::Text::CENTER_CENTER); text->setAlignment(osgText::Text::CENTER_CENTER);
text->setAutoRotateToScreen(true); text->setAutoRotateToScreen(true);
text->setAutoScaleToScreen(true); text->setAutoScaleToLimitScreenSizeToFontResolution(true);
text->setDrawMode(osgText::Text::TEXT_PIXMAP); text->setDrawMode(osgText::Text::TEXT_PIXMAP);
text->setText(label); text->setText(label);
@ -87,7 +87,7 @@ osg::Node* createLabel3(const osg::Vec3& pos, float size, const std::string& lab
text->setCharacterSize(size); text->setCharacterSize(size);
text->setAlignment(osgText::Text::CENTER_CENTER); text->setAlignment(osgText::Text::CENTER_CENTER);
text->setAutoRotateToScreen(true); text->setAutoRotateToScreen(true);
text->setAutoScaleToScreen(true); text->setAutoScaleToLimitScreenSizeToFontResolution(true);
text->setText(label); text->setText(label);
} }
@ -242,4 +242,32 @@ int main( int argc, char **argv )
viewer.sync(); viewer.sync();
return 0; return 0;
// osg::Node* obj = new osg::Node;
// cout << "obj = "<<obj<<endl;
// cout << "sizeof(obj) = "<<sizeof(*obj)<<endl;
// cout << "sizeof(osg::Object) = "<<sizeof(osg::Object)<<endl;
// cout << "sizeof(osg::Referenced) = "<<sizeof(osg::Referenced)<<endl;
// cout << "vtbl = "<<*((unsigned int*)obj)<<endl;
// cout << "next = "<<*((unsigned int*)obj+1)<<endl;
//
// osg::Node* obj2 = new osg::Node;
// obj2->ref();
// obj2->ref();
// obj2->ref();
// cout << "obj = "<<obj2<<endl;
// cout << "sizeof(obj) = "<<sizeof(*obj)<<endl;
// cout << "sizeof(osg::Object) = "<<sizeof(osg::Object)<<endl;
// cout << "sizeof(osg::Referenced) = "<<sizeof(osg::Referenced)<<endl;
// cout << "vtbl = "<<*((unsigned int*)obj2)<<endl;
// cout << "next = "<<*((unsigned int*)obj2+1)<<endl;
//
// osg::Group* obj3 = new osg::Group;
// cout << "obj = "<<obj3<<endl;
// cout << "sizeof(obj) = "<<sizeof(*obj3)<<endl;
// cout << "sizeof(osg::Object) = "<<sizeof(osg::Object)<<endl;
// cout << "sizeof(osg::Referenced) = "<<sizeof(osg::Referenced)<<endl;
// cout << "vtbl = "<<*((unsigned int*)obj3)<<endl;
// cout << "next = "<<*((unsigned int*)obj3+1)<<endl;
} }

View File

@ -54,6 +54,12 @@ class SG_EXPORT Quat
makeRotate(angle1,axis1,angle2,axis2,angle3,axis3); makeRotate(angle1,axis1,angle2,axis2,angle3,axis3);
} }
inline bool operator == (const Quat& rhs) const { return _fv==rhs._fv; }
inline bool operator != (const Quat& rhs) const { return _fv!=rhs._fv; }
inline bool operator < (const Quat& rhs) const { return _fv<rhs._fv; }
/* ---------------------------------- /* ----------------------------------
Methods to access data members Methods to access data members
---------------------------------- */ ---------------------------------- */

View File

@ -53,16 +53,19 @@ class buffered_value
return _array[pos]; return _array[pos];
} }
/* // do we implement the const version???
inline T operator[] (unsigned int pos) const inline T operator[] (unsigned int pos) const
{ {
return 0; // automatically resize array.
if (_array.size()<=pos)
_array.resize(pos+1,0);
return _array[pos];
} }
*/
protected: protected:
std::vector<T> _array; mutable std::vector<T> _array;
}; };
template<class T> template<class T>
@ -96,16 +99,20 @@ class buffered_object
return _array[pos]; return _array[pos];
} }
/* // do we implement the const version???
inline T operator[] (unsigned int pos) const inline const T& operator[] (unsigned int pos) const
{ {
return 0; // automatically resize array.
if (_array.size()<=pos)
_array.resize(pos+1);
return _array[pos];
} }
*/
protected: protected:
std::vector<T> _array; mutable std::vector<T> _array;
}; };
} }

View File

@ -29,18 +29,6 @@ class OSGTEXT_EXPORT String : public osg::Referenced, public std::vector<unsigne
{ {
public: public:
String() {}
String(const String& str);
virtual ~String() {} // public temporily while osgText is still in flux.
String& operator = (const String& str);
void set(const std::string& str);
/** Set the text using a wchar_t string,
* which is converted to an internal TextString.*/
void set(const wchar_t* text);
/** /**
* Types of string encodings supported * Types of string encodings supported
*/ */
@ -58,6 +46,23 @@ public:
ENCODING_SIGNATURE /// detect encoding from signature ENCODING_SIGNATURE /// detect encoding from signature
}; };
String() {}
String(const String& str);
String(const std::string& str) { set(str); }
String(const wchar_t* text) { set(text); }
String(const std::string& text,Encoding encoding) { set(text,encoding); }
virtual ~String() {} // public temporily while osgText is still in flux.
String& operator = (const String& str);
void set(const std::string& str);
/** Set the text using a wchar_t string,
* which is converted to an internal TextString.*/
void set(const wchar_t* text);
/** Set the text using a Unicode encoded std::string, which is converted to an internal TextString. /** Set the text using a Unicode encoded std::string, which is converted to an internal TextString.
* The encoding parameter specificies which Unicode encodeding is used in the std::string. */ * The encoding parameter specificies which Unicode encodeding is used in the std::string. */
void set(const std::string& text,Encoding encoding); void set(const std::string& text,Encoding encoding);

View File

@ -165,10 +165,14 @@ public:
void setAxisAlignment(AxisAlignment axis); void setAxisAlignment(AxisAlignment axis);
void setRotation(const osg::Quat& quat); void setRotation(const osg::Quat& quat);
const osg::Quat& getRotation() const { return _rotation; } void setRotation(unsigned int contextID, const osg::Quat& quat);
const osg::Quat& getRotation(unsigned int contextID=0) const { return _rotation[contextID]; }
void setScale(float scale); void setScale(float scale);
float getScale() const { return _scale; } void setScale(unsigned int contextID, float scale);
float getScale(unsigned int contextID=0) const { return _scale[contextID]; }
void setScaleAndRotation(unsigned int contextID, float scale,const osg::Quat& quat);
void setAutoUpdateEyeMovementTolerance(float tolerance) { _autoUpdateEyeMovementTolerance = tolerance; } void setAutoUpdateEyeMovementTolerance(float tolerance) { _autoUpdateEyeMovementTolerance = tolerance; }
float getAutoUpdateEyeMovementTolerance() const { return _autoUpdateEyeMovementTolerance; } float getAutoUpdateEyeMovementTolerance() const { return _autoUpdateEyeMovementTolerance; }
@ -176,8 +180,8 @@ public:
void setAutoRotateToScreen(bool autoRotateToScreen); void setAutoRotateToScreen(bool autoRotateToScreen);
bool getAutoRotateToScreen() const { return _autoRotateToScreen; } bool getAutoRotateToScreen() const { return _autoRotateToScreen; }
void setAutoScaleToScreen(bool autoScaleToScreen); void setAutoScaleToLimitScreenSizeToFontResolution(bool autoScaleToScreen);
bool getAutoScaleToScreen() const { return _autoScaleToScreen; } bool getAutoScaleToLimitScreenSizeToFontResolution() const { return _autoScaleToLimitScreenSizeToFontResolution; }
@ -244,10 +248,10 @@ public:
typedef std::vector<osg::Vec3> Coords3; typedef std::vector<osg::Vec3> Coords3;
typedef std::vector<osg::Vec2> TexCoords; typedef std::vector<osg::Vec2> TexCoords;
Glyphs _glyphs; Glyphs _glyphs;
Coords2 _coords; Coords2 _coords;
Coords3 _transformedCoords; osg::buffered_object<Coords3> _transformedCoords;
TexCoords _texcoords; TexCoords _texcoords;
Glyphs getGlyphs() { return _glyphs; } Glyphs getGlyphs() { return _glyphs; }
const Glyphs getGlyphs() const { return _glyphs; } const Glyphs getGlyphs() const { return _glyphs; }
@ -256,8 +260,8 @@ public:
Coords2& getCoords() { return _coords; } Coords2& getCoords() { return _coords; }
const Coords2& getCoords() const { return _coords; } const Coords2& getCoords() const { return _coords; }
Coords3& getTransformedCoords() { return _transformedCoords; } Coords3& getTransformedCoords(unsigned int contexID) { return _transformedCoords[contexID]; }
const Coords3& getTransformedCoords() const { return _transformedCoords; } const Coords3& getTransformedCoords(unsigned int contexID) const { return _transformedCoords[contexID]; }
TexCoords& getTexCoords() { return _texcoords; } TexCoords& getTexCoords() { return _texcoords; }
const TexCoords& getTexCoords() const { return _texcoords; } const TexCoords& getTexCoords() const { return _texcoords; }
@ -286,40 +290,40 @@ protected:
// members which have public access. // members which have public access.
osg::ref_ptr<Font> _font; osg::ref_ptr<Font> _font;
unsigned int _fontWidth; unsigned int _fontWidth;
unsigned int _fontHeight; unsigned int _fontHeight;
float _characterHeight; float _characterHeight;
float _characterAspectRatio; float _characterAspectRatio;
float _maximumWidth; float _maximumWidth;
float _maximumHeight; float _maximumHeight;
String _text; String _text;
osg::Vec3 _position; osg::Vec3 _position;
AlignmentType _alignment; AlignmentType _alignment;
osg::Quat _rotation; mutable osg::buffered_object<osg::Quat> _rotation;
float _scale; mutable osg::buffered_value<float> _scale;
float _autoUpdateEyeMovementTolerance; float _autoUpdateEyeMovementTolerance;
bool _autoRotateToScreen; bool _autoRotateToScreen;
bool _autoScaleToScreen; bool _autoScaleToLimitScreenSizeToFontResolution;
Layout _layout; Layout _layout;
osg::Vec4 _color; osg::Vec4 _color;
unsigned int _drawMode; unsigned int _drawMode;
// iternal map used for rendering. Set up by the computeGlyphRepresentation() method. // iternal map used for rendering. Set up by the computeGlyphRepresentation() method.
TextureGlyphQuadMap _textureGlyphQuadMap; TextureGlyphQuadMap _textureGlyphQuadMap;
void computeGlyphRepresentation(); void computeGlyphRepresentation();
// internal caches of the positioning of the text. // internal caches of the positioning of the text.
osg::Matrix _matrix; mutable osg::buffered_object<osg::Matrix> _matrix;
osg::Vec3 _offset; osg::Vec3 _offset;
osg::Vec3 _normal; osg::Vec3 _normal;
mutable osg::BoundingBox _textBB; mutable osg::BoundingBox _textBB;
void setUpAutoCallback(); void setUpAutoCallback();
void computePositions(); void computePositions();
void computePositions(unsigned int contextID);
}; };

View File

@ -30,8 +30,8 @@ AutoTransform::AutoTransform(const AutoTransform& pat,const CopyOp& copyop):
Transform(pat,copyop), Transform(pat,copyop),
_position(pat._position), _position(pat._position),
_pivotPoint(pat._pivotPoint), _pivotPoint(pat._pivotPoint),
_rotation(pat._rotation), _scale(pat._scale),
_scale(pat._scale) _rotation(pat._rotation)
{ {
// setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1); // setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1);
} }

View File

@ -152,9 +152,9 @@ bool Text_readLocalData(osg::Object &obj, osgDB::Input &fr)
itAdvanced = true; itAdvanced = true;
} }
if (fr.matchSequence("autoScaleToScreen TRUE")) if (fr.matchSequence("autoScaleToLimitScreenSizeToFontResolution TRUE"))
{ {
text.setAutoScaleToScreen(true); text.setAutoScaleToLimitScreenSizeToFontResolution(true);
fr += 2; fr += 2;
itAdvanced = true; itAdvanced = true;
} }
@ -316,9 +316,9 @@ bool Text_writeLocalData(const osg::Object &obj, osgDB::Output &fw)
fw.indent() << "autoRotateToScreen TRUE"<< std::endl; fw.indent() << "autoRotateToScreen TRUE"<< std::endl;
} }
if (text.getAutoScaleToScreen()) if (text.getAutoScaleToLimitScreenSizeToFontResolution())
{ {
fw.indent() << "autoScaleToScreen TRUE"<< std::endl; fw.indent() << "autoScaleToLimitScreenSizeToFontResolution TRUE"<< std::endl;
} }
// layout // layout

View File

@ -25,12 +25,20 @@ using namespace osgText;
struct TextCullCallback : public osg::Drawable::CullCallback struct TextCullCallback : public osg::Drawable::CullCallback
{ {
struct PositionData
{
PositionData():
_traversalNumber(-1),
_previousWidth(0),
_previousHeight(0) {}
int _traversalNumber;
int _previousWidth;
int _previousHeight;
osg::Vec3 _eyePosition;
};
TextCullCallback(osgText::Text* text): TextCullCallback(osgText::Text* text):
_firstTimeToInitEyePoint(true),
_previousWidth(0),
_previousHeight(0),
_lastUpdateContextID(0xffffffff),
_lastTraversalNumber(0xffffffff),
_text(text) {} _text(text) {}
/** do customized cull code.*/ /** do customized cull code.*/
@ -39,23 +47,12 @@ struct TextCullCallback : public osg::Drawable::CullCallback
osgUtil::CullVisitor* cs = static_cast<osgUtil::CullVisitor*>(nv); osgUtil::CullVisitor* cs = static_cast<osgUtil::CullVisitor*>(nv);
if (!cs) return false; if (!cs) return false;
if (_lastTraversalNumber!=nv->getTraversalNumber())
{
_lastUpdateContextID = 0xffffffff;
}
_lastTraversalNumber = nv->getTraversalNumber();
unsigned int contextID = cs->getState() ? cs->getState()->getContextID() : 0; unsigned int contextID = cs->getState() ? cs->getState()->getContextID() : 0;
if (_lastUpdateContextID<contextID)
{ PositionData& positionData = _positions[contextID];
// cout << "quiting early"<<endl;
return false; int width = positionData._previousWidth;
} int height = positionData._previousHeight;
int width = _previousWidth;
int height = _previousHeight;
osg::Viewport* viewport = cs->getViewport(); osg::Viewport* viewport = cs->getViewport();
if (viewport) if (viewport)
@ -66,61 +63,57 @@ struct TextCullCallback : public osg::Drawable::CullCallback
osg::Vec3 eyePoint = cs->getEyeLocal(); osg::Vec3 eyePoint = cs->getEyeLocal();
bool doUpdate = _firstTimeToInitEyePoint; bool doUpdate = positionData._traversalNumber==-1;
if (!_firstTimeToInitEyePoint) if (positionData._traversalNumber>=0)
{ {
osg::Vec3 dv = _previousEyePoint-eyePoint; osg::Vec3 dv = positionData._eyePosition-eyePoint;
if (dv.length2()>_text->getAutoUpdateEyeMovementTolerance()*(eyePoint-_text->getPosition()).length2()) if (dv.length2()>_text->getAutoUpdateEyeMovementTolerance()*(eyePoint-_text->getPosition()).length2())
{ {
doUpdate = true; doUpdate = true;
} }
else if (width!=_previousWidth || height!=_previousHeight) else if (width!=positionData._previousWidth || height!=positionData._previousHeight)
{ {
doUpdate = true; doUpdate = true;
} }
} }
_firstTimeToInitEyePoint = false;
positionData._traversalNumber = nv->getTraversalNumber();
positionData._previousWidth = width;
positionData._previousHeight = height;
if (doUpdate) if (doUpdate)
{ {
_lastUpdateContextID = contextID; float scale=_text->getScale(contextID);
if (_text->getAutoScaleToLimitScreenSizeToFontResolution()) if (_text->getAutoScaleToLimitScreenSizeToFontResolution())
{ {
float numPixels = cs->pixelSize(_text->getPosition(),_text->getCharacterHeight()); float numPixels = cs->pixelSize(_text->getPosition(),_text->getCharacterHeight());
if (numPixels>_text->getFontHeight()) if (numPixels>_text->getFontHeight())
{ {
_text->setScale(_text->getFontHeight()/numPixels); scale = _text->getFontHeight()/numPixels;
} }
//float size = 1.0f/cs->pixelSize(_text->getPosition(),1.0f); //float size = 1.0f/cs->pixelSize(_text->getPosition(),1.0f);
//_text->setScale(size); //_text->setScale(size);
} }
osg::Quat rotation = _text->getRotation(contextID);
if (_text->getAutoRotateToScreen()) if (_text->getAutoRotateToScreen())
{ {
osg::Quat rotation; rotation.set(cs->getModelViewMatrix());
rotation.set(cs->getModelViewMatrix()); rotation = rotation.inverse();
_text->setRotation(rotation.inverse());
} }
_previousEyePoint = eyePoint; _text->setScaleAndRotation(contextID,scale,rotation);
_previousWidth = width;
_previousHeight = height;
} }
return false; return false;
} }
typedef osg::buffered_object<PositionData> PositionList;
mutable bool _firstTimeToInitEyePoint; mutable PositionList _positions;
mutable osg::Vec3 _previousEyePoint;
mutable int _previousWidth;
mutable int _previousHeight;
mutable unsigned int _lastUpdateContextID;
mutable int _lastTraversalNumber;
mutable osgText::Text* _text; mutable osgText::Text* _text;
}; };
@ -135,8 +128,6 @@ Text::Text():
_maximumWidth(0.0f), _maximumWidth(0.0f),
_maximumHeight(0.0f), _maximumHeight(0.0f),
_alignment(BASE_LINE), _alignment(BASE_LINE),
_rotation(),
_scale(1.0f),
_autoUpdateEyeMovementTolerance(0.0f), _autoUpdateEyeMovementTolerance(0.0f),
_autoRotateToScreen(false), _autoRotateToScreen(false),
_autoScaleToLimitScreenSizeToFontResolution(false), _autoScaleToLimitScreenSizeToFontResolution(false),
@ -145,6 +136,7 @@ Text::Text():
_drawMode(TEXT) _drawMode(TEXT)
{ {
setUseDisplayList(false); setUseDisplayList(false);
setScale(1.0f);
} }
Text::Text(const Text& text,const osg::CopyOp& copyop): Text::Text(const Text& text,const osg::CopyOp& copyop):
@ -220,37 +212,46 @@ void Text::setMaximumHeight(float maximumHeight)
void Text::setText(const String& text) void Text::setText(const String& text)
{ {
if (_text==text) return;
_text = text; _text = text;
computeGlyphRepresentation(); computeGlyphRepresentation();
} }
void Text::setText(const std::string& text) void Text::setText(const std::string& text)
{ {
_text.set(text); setText(String(text));
computeGlyphRepresentation(); // _text.set(text);
// computeGlyphRepresentation();
} }
void Text::setText(const std::string& text,String::Encoding encoding) void Text::setText(const std::string& text,String::Encoding encoding)
{ {
_text.set(text,encoding); setText(String(text,encoding));
computeGlyphRepresentation(); // _text.set(text,encoding);
// computeGlyphRepresentation();
} }
void Text::setText(const wchar_t* text) void Text::setText(const wchar_t* text)
{ {
_text.set(text); setText(String(text));
computeGlyphRepresentation(); // _text.set(text);
// computeGlyphRepresentation();
} }
void Text::setPosition(const osg::Vec3& pos) void Text::setPosition(const osg::Vec3& pos)
{ {
if (_position==pos) return;
_position = pos; _position = pos;
computePositions(); computePositions();
} }
void Text::setAlignment(AlignmentType alignment) void Text::setAlignment(AlignmentType alignment)
{ {
if (_alignment==alignment) return;
_alignment = alignment; _alignment = alignment;
computePositions(); 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) void Text::setRotation(const osg::Quat& quat)
{ {
_rotation = quat; for(unsigned int i=0;i<_rotation.size();++i)
computePositions(); {
setRotation(i,quat);
}
} }
void Text::setAutoScaleToLimitScreenSizeToFontResolution(bool autoScaleToScreen) void Text::setRotation(unsigned int contextID, const osg::Quat& quat)
{ {
_autoScaleToLimitScreenSizeToFontResolution = autoScaleToScreen; if (_rotation[contextID]==quat) return;
setUpAutoCallback();
_rotation[contextID] = quat;
computePositions(contextID);
} }
void Text::setScale(float scale) void Text::setScale(float scale)
{ {
_scale = scale; for(unsigned int i=0;i<_scale.size();++i)
setUpAutoCallback(); {
computePositions(); 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() void Text::setUpAutoCallback()
{ {
if (_autoRotateToScreen || _autoScaleToLimitScreenSizeToFontResolution) if (_autoRotateToScreen || _autoScaleToLimitScreenSizeToFontResolution)
@ -314,6 +349,8 @@ void Text::setUpAutoCallback()
void Text::setLayout(Layout layout) void Text::setLayout(Layout layout)
{ {
if (_layout==layout) return;
_layout = layout; _layout = layout;
computeGlyphRepresentation(); computeGlyphRepresentation();
} }
@ -325,6 +362,8 @@ void Text::setColor(const osg::Vec4& color)
void Text::setDrawMode(unsigned int mode) void Text::setDrawMode(unsigned int mode)
{ {
if (_drawMode==mode) return;
if (_drawMode&3 != mode&3) if (_drawMode&3 != mode&3)
{ {
_drawMode=mode; _drawMode=mode;
@ -348,10 +387,15 @@ bool Text::computeBound() const
if (_textBB.valid()) 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); for(unsigned int i=0;i<_matrix.size();++i)
_bbox.expandBy(osg::Vec3(_textBB.xMax(),_textBB.yMax(),_textBB.zMin())*_matrix); {
_bbox.expandBy(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMin())*_matrix); 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; _bbox_computed = true;
@ -558,7 +602,16 @@ void Text::computeGlyphRepresentation()
computePositions(); computePositions();
} }
void Text::computePositions() void Text::computePositions()
{
for(unsigned int i=0;i<_matrix.size();++i)
{
computePositions(i);
}
}
void Text::computePositions(unsigned int contextID)
{ {
switch(_alignment) 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 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; 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) if (_scale[contextID]!=1.0f)
_matrix.postMult(osg::Matrix::scale(_scale,_scale,_scale)); matrix.postMult(osg::Matrix::scale(_scale[contextID],_scale[contextID],_scale[contextID]));
if (!_rotation.zeroRotation()) if (!_rotation[contextID].zeroRotation())
_matrix.postMult(osg::Matrix::rotate(_rotation)); matrix.postMult(osg::Matrix::rotate(_rotation[contextID]));
_matrix.postMult(osg::Matrix::translate(_position)); matrix.postMult(osg::Matrix::translate(_position));
} }
else else
{ {
_matrix.makeTranslate(_position-_offset); matrix.makeTranslate(_position-_offset);
} }
@ -604,7 +659,7 @@ void Text::computePositions()
{ {
GlyphQuads& glyphquad = titr->second; GlyphQuads& glyphquad = titr->second;
GlyphQuads::Coords2& coords2 = glyphquad._coords; GlyphQuads::Coords2& coords2 = glyphquad._coords;
GlyphQuads::Coords3& transformedCoords = glyphquad._transformedCoords; GlyphQuads::Coords3& transformedCoords = glyphquad._transformedCoords[contextID];
unsigned int numCoords = coords2.size(); unsigned int numCoords = coords2.size();
if (numCoords!=transformedCoords.size()) if (numCoords!=transformedCoords.size())
@ -614,11 +669,11 @@ void Text::computePositions()
for(unsigned int i=0;i<numCoords;++i) for(unsigned int i=0;i<numCoords;++i)
{ {
transformedCoords[i] = osg::Vec3(coords2[i].x(),coords2[i].y(),0.0f)*_matrix; transformedCoords[i] = osg::Vec3(coords2[i].x(),coords2[i].y(),0.0f)*matrix;
} }
} }
_normal = osg::Matrix::transform3x3(osg::Vec3(0.0f,0.0f,1.0f),_matrix); _normal = osg::Matrix::transform3x3(osg::Vec3(0.0f,0.0f,1.0f),matrix);
_normal.normalize(); _normal.normalize();
dirtyBound(); dirtyBound();
@ -626,8 +681,8 @@ void Text::computePositions()
void Text::drawImplementation(osg::State& state) const void Text::drawImplementation(osg::State& state) const
{ {
unsigned int contextID = state.getContextID();
glNormal3fv(_normal.ptr()); glNormal3fv(_normal.ptr());
glColor4fv(_color.ptr()); glColor4fv(_color.ptr());
@ -645,7 +700,7 @@ void Text::drawImplementation(osg::State& state) const
const GlyphQuads& glyphquad = titr->second; const GlyphQuads& glyphquad = titr->second;
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())); state.setTexCoordPointer( 0, 2, GL_FLOAT, 0, &(glyphquad._texcoords.front()));
glDrawArrays(GL_QUADS,0,glyphquad._coords.size()); glDrawArrays(GL_QUADS,0,glyphquad._coords.size());
@ -674,7 +729,7 @@ void Text::drawImplementation(osg::State& state) const
Font::Glyph* glyph = *gitr; Font::Glyph* glyph = *gitr;
glRasterPos3fv(glyphquad._transformedCoords[ci].ptr()); glRasterPos3fv(glyphquad._transformedCoords[contextID][ci].ptr());
glyph->draw(state); glyph->draw(state);
@ -690,10 +745,12 @@ void Text::drawImplementation(osg::State& state) const
{ {
state.applyTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF); state.applyTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF);
osg::Vec3 c00(osg::Vec3(_textBB.xMin(),_textBB.yMin(),_textBB.zMin())*_matrix); osg::Matrix& matrix = _matrix[contextID];
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 c00(osg::Vec3(_textBB.xMin(),_textBB.yMin(),_textBB.zMin())*matrix);
osg::Vec3 c01(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_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); 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); 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::Matrix& matrix = _matrix[contextID];
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 hl(osg::Vec3(_offset.x()-cursorsize,_offset.y(),_offset.z())*matrix);
osg::Vec3 vb(osg::Vec3(_offset.x(),_offset.y()+cursorsize,_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); state.applyTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF);
@ -739,7 +798,7 @@ void Text::accept(osg::Drawable::ConstAttributeFunctor& af) const
++titr) ++titr)
{ {
const GlyphQuads& glyphquad = titr->second; 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())); 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; const GlyphQuads& glyphquad = titr->second;
pf.setVertexArray(glyphquad._transformedCoords.size(),&(glyphquad._transformedCoords.front())); pf.setVertexArray(glyphquad._transformedCoords[0].size(),&(glyphquad._transformedCoords[0].front()));
pf.drawArrays(GL_QUADS,0,glyphquad._transformedCoords.size()); pf.drawArrays(GL_QUADS,0,glyphquad._transformedCoords[0].size());
// pf.begin(GL_QUADS); // pf.begin(GL_QUADS);
// for(GlyphQuads::Coords3::const_iterator itr = glyphquad._transformedCoords.begin(); // for(GlyphQuads::Coords3::const_iterator itr = glyphquad._transformedCoords.begin();