From 895a7228424a1a5e5cdf693729e6125095fba2f1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 1 May 2003 21:06:18 +0000 Subject: [PATCH] Addd support for maximum screen text size into osgText when auto scale to screen is active. Added osgautotransform demo. --- Make/makedirdefs | 4 +- .../osgautotransform/osgautotransform.dsp | 190 ++++++++++++++ examples/osgautotransform/GNUmakefile | 19 ++ examples/osgautotransform/GNUmakefile.inst | 14 + .../osgautotransform/osgautotransform.cpp | 245 ++++++++++++++++++ include/osg/AutoTransform | 103 ++++++++ include/osgText/Font | 5 + include/osgText/Text | 13 +- src/osg/AutoTransform.cpp | 155 +++++++++++ src/osgText/Font.cpp | 24 ++ src/osgText/Text.cpp | 73 +++++- 11 files changed, 836 insertions(+), 9 deletions(-) create mode 100644 VisualStudio/examples/osgautotransform/osgautotransform.dsp create mode 100644 examples/osgautotransform/GNUmakefile create mode 100644 examples/osgautotransform/GNUmakefile.inst create mode 100644 examples/osgautotransform/osgautotransform.cpp create mode 100644 include/osg/AutoTransform create mode 100644 src/osg/AutoTransform.cpp diff --git a/Make/makedirdefs b/Make/makedirdefs index 0b3dd7b72..348f6fcc9 100644 --- a/Make/makedirdefs +++ b/Make/makedirdefs @@ -48,7 +48,7 @@ PLUGIN_DIRS = \ zip # comment in if you have Performer installed. -# PLUGIN_DIRS += pfb +PLUGIN_DIRS += pfb # comment in if have freetype2.x installed, provides type type font support to osgText. @@ -101,6 +101,7 @@ endif EXAMPLE_DIRS = \ osganimate\ + osgautotransform\ osgbillboard\ osgcallback\ osgcameragroup\ @@ -140,7 +141,6 @@ EXAMPLE_DIRS = \ osgvertexprogram\ osgviewer\ -# osgautotransform\ # osgprerendercubemap\ # osgjigsaw\ diff --git a/VisualStudio/examples/osgautotransform/osgautotransform.dsp b/VisualStudio/examples/osgautotransform/osgautotransform.dsp new file mode 100644 index 000000000..c8337e606 --- /dev/null +++ b/VisualStudio/examples/osgautotransform/osgautotransform.dsp @@ -0,0 +1,190 @@ +# Microsoft Developer Studio Project File - Name="Example osgautotransform" - Package Owner=<4> + +# Microsoft Developer Studio Generated Build File, Format Version 6.00 + +# ** DO NOT EDIT ** + + + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + + + +CFG=Example osgautotransform - Win32 Release + +!MESSAGE This is not a valid makefile. To build this project using NMAKE, + +!MESSAGE use the Export Makefile command and run + +!MESSAGE + +!MESSAGE NMAKE /f "osgautotransformdemo.mak". + +!MESSAGE + +!MESSAGE You can specify a configuration when running NMAKE + +!MESSAGE by defining the macro CFG on the command line. For example: + +!MESSAGE + +!MESSAGE NMAKE /f "osgautotransformdemo.mak" CFG="Example osgautotransform - Win32 Release" + +!MESSAGE + +!MESSAGE Possible choices for configuration are: + +!MESSAGE + +!MESSAGE "Example osgautotransform - Win32 Release" (based on "Win32 (x86) Console Application") + +!MESSAGE "Example osgautotransform - Win32 Debug" (based on "Win32 (x86) Console Application") + +!MESSAGE + + + +# Begin Project + +# PROP AllowPerConfigDependencies 0 + +# PROP Scc_ProjName "" + +# PROP Scc_LocalPath "" + +CPP=cl.exe + +RSC=rc.exe + + + +!IF "$(CFG)" == "Example osgautotransform - Win32 Release" + + + +# PROP BASE Use_MFC 0 + +# PROP BASE Use_Debug_Libraries 0 + +# PROP BASE Output_Dir "Release" + +# PROP BASE Intermediate_Dir "Release" + +# PROP BASE Target_Dir "" + +# PROP Use_MFC 0 + +# PROP Use_Debug_Libraries 0 + +# PROP Output_Dir "Release" + +# PROP Intermediate_Dir "Release" + +# PROP Ignore_Export_Lib 0 + +# PROP Target_Dir "" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c + +# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c + +# ADD BASE RSC /l 0x809 /d "NDEBUG" + +# ADD RSC /l 0x809 /d "NDEBUG" + +BSC32=bscmake.exe + +# ADD BASE BSC32 /nologo + +# ADD BSC32 /nologo + +LINK32=link.exe + +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +# ADD LINK32 /nologo /subsystem:console /pdb:none /machine:I386 /out:"../../../bin/osgautotransform.exe" /libpath:"../../../lib" + + + +!ELSEIF "$(CFG)" == "Example osgautotransform - Win32 Debug" + + + +# PROP BASE Use_MFC 0 + +# PROP BASE Use_Debug_Libraries 1 + +# PROP BASE Output_Dir "Debug" + +# PROP BASE Intermediate_Dir "Debug" + +# PROP BASE Target_Dir "" + +# PROP Use_MFC 0 + +# PROP Use_Debug_Libraries 1 + +# PROP Output_Dir "Debug" + +# PROP Intermediate_Dir "Debug" + +# PROP Ignore_Export_Lib 0 + +# PROP Target_Dir "" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c + +# ADD CPP /nologo /MDd /W3 /Gm /vd0 /GR /GX /Zi /Od /I "../../../include" /D "_CONSOLE" /D "_MBCS" /D "FL_DLL" /D "WIN32" /D "_DEBUG" /FR /YX /FD /c + +# ADD BASE RSC /l 0x809 /d "_DEBUG" + +# ADD RSC /l 0x809 /d "_DEBUG" + +BSC32=bscmake.exe + +# ADD BASE BSC32 /nologo + +# ADD BSC32 /nologo + +LINK32=link.exe + +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +# ADD LINK32 glu32.lib opengl32.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"libcmt" /out:"../../../bin/osgautotransformd.exe" /pdbtype:sept /libpath:"../../../lib" + +# SUBTRACT LINK32 /incremental:no + + + +!ENDIF + + + +# Begin Target + + + +# Name "Example osgautotransform - Win32 Release" + +# Name "Example osgautotransform - Win32 Debug" + +# Begin Source File + + + +SOURCE=..\..\..\examples\osgautotransform\osgautotransform.cpp + +# End Source File + +# End Target + +# Begin Group "Resource Files" + + + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" + +# End Group + +# End Project + diff --git a/examples/osgautotransform/GNUmakefile b/examples/osgautotransform/GNUmakefile new file mode 100644 index 000000000..eb748967c --- /dev/null +++ b/examples/osgautotransform/GNUmakefile @@ -0,0 +1,19 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgautotransform.cpp\ + +LIBS += -losgProducer -lProducer -losgText -losgProducer -lProducer -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +INSTFILES = \ + $(CXXFILES)\ + GNUmakefile.inst=GNUmakefile + +EXEC = osgautotransform + +INC += $(PRODUCER_INCLUDE_DIR) -I/usr/X11R6/include +LDFLAGS += $(PRODUCER_LIB_DIR) + +include $(TOPDIR)/Make/makerules + diff --git a/examples/osgautotransform/GNUmakefile.inst b/examples/osgautotransform/GNUmakefile.inst new file mode 100644 index 000000000..665e22ee2 --- /dev/null +++ b/examples/osgautotransform/GNUmakefile.inst @@ -0,0 +1,14 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgautotransform.cpp\ + +LIBS += -losgProducer -lProducer -losgText -losgProducer -lProducer -losgDB -losgText -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +EXEC = osgautotransform + +INC += $(PRODUCER_INCLUDE_DIR) -I/usr/X11R6/include +LDFLAGS += $(PRODUCER_LIB_DIR) + +include $(TOPDIR)/Make/makerules diff --git a/examples/osgautotransform/osgautotransform.cpp b/examples/osgautotransform/osgautotransform.cpp new file mode 100644 index 000000000..565681c70 --- /dev/null +++ b/examples/osgautotransform/osgautotransform.cpp @@ -0,0 +1,245 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +osg::Node* createLabel(const osg::Vec3& pos, float size, const std::string& label) +{ + osg::Geode* geode = new osg::Geode(); + + std::string timesFont("fonts/arial.ttf"); + + { + osgText::Text* text = new osgText::Text; + geode->addDrawable( text ); + + text->setFont(timesFont); + text->setPosition(pos); + text->setCharacterSize(size); + text->setAlignment(osgText::Text::CENTER_CENTER); + text->setText(label); + + } + + return geode; +} + +osg::Node* createLabel2(const osg::Vec3& pos, float size, const std::string& label) +{ + osg::Geode* geode = new osg::Geode(); + + std::string timesFont("fonts/arial.ttf"); + + { + osgText::Text* text = new osgText::Text; + geode->addDrawable( text ); + + text->setFont(timesFont); + text->setPosition(pos); + text->setFontResolution(40,40); + text->setCharacterSize(size); + text->setAlignment(osgText::Text::CENTER_CENTER); + text->setAutoRotateToScreen(true); + text->setAutoScaleToScreen(true); + text->setDrawMode(osgText::Text::TEXT_PIXMAP); + text->setText(label); + + } + + return geode; +} + +osg::Node* createLabel3(const osg::Vec3& pos, float size, const std::string& label) +{ + osg::Geode* geode = new osg::Geode(); + + std::string timesFont("fonts/arial.ttf"); + + { + osgText::Text* text = new osgText::Text; + geode->addDrawable( text ); + + text->setFont(timesFont); + text->setPosition(pos); + text->setFontResolution(40,40); + text->setCharacterSize(size); + text->setAlignment(osgText::Text::CENTER_CENTER); + text->setAutoRotateToScreen(true); + text->setAutoScaleToScreen(true); + text->setText(label); + + } + + return geode; +} + +osg::Node* createAxis(const osg::Vec3& s, const osg::Vec3& e, int numReps) +{ + osg::Group* group = new osg::Group; + + osg::Vec3 dv = e-s; + dv /= float(numReps-1); + + osg::Vec3 pos = s; + + bool useAuto = false; + if (useAuto) + { + osg::Vec3Array* vertices = new osg::Vec3Array; + + for(int i=0;isetPosition(pos); + at->setAutoRotateToScreen(true); + at->setAutoScaleToScreen(true); + at->addChild(createLabel(osg::Vec3(0.0f,0.0f,0.0f),40.0f,"Test 2")); + vertices->push_back(pos); + pos += dv; + + + group->addChild(at); + } + + osg::Vec4Array* colors = new osg::Vec4Array; + colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); + + osg::Geometry* geom = new osg::Geometry; + geom->setVertexArray(vertices); + geom->setColorArray(colors); + geom->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP,0,vertices->size())); + + osg::Geode* geode = new osg::Geode; + geode->addDrawable(geom); + + group->addChild(geode); + } + else + { + osg::Vec3Array* vertices = new osg::Vec3Array; + + for(int i=0;iaddChild(createLabel3(osg::Vec3(pos),dv.length()*0.5f,"Test 2")); + vertices->push_back(pos); + pos += dv; + + + } + + osg::Vec4Array* colors = new osg::Vec4Array; + colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); + + osg::Geometry* geom = new osg::Geometry; + geom->setVertexArray(vertices); + geom->setColorArray(colors); + geom->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP,0,vertices->size())); + + osg::Geode* geode = new osg::Geode; + geode->addDrawable(geom); + + group->addChild(geode); + } + + return group; +} + +osg::Node* createScene() +{ + osg::Group* root = new osg::Group; + + int numReps = 3333; +// int numReps = 10; + root->addChild(createAxis(osg::Vec3(0.0,0.0,0.0),osg::Vec3(1000.0,0.0,0.0),numReps)); + root->addChild(createAxis(osg::Vec3(0.0,0.0,0.0),osg::Vec3(0.0,1000.0,0.0),numReps)); + root->addChild(createAxis(osg::Vec3(0.0,0.0,0.0),osg::Vec3(0.0,0.0,1000.0),numReps)); + + return root; +} + +int main( int argc, char **argv ) +{ + + // use an ArgumentParser object to manage the program arguments. + osg::ArgumentParser arguments(&argc,argv); + + // set up the usage document, in case we need to print out how to use this program. + arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates how to do Head Up Displays."); + arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] [filename] ..."); + arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); + + + // construct the viewer. + osgProducer::Viewer viewer(arguments); + + // set up the value with sensible default event handlers. + viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS); + + // get details on keyboard and mouse bindings used by the viewer. + viewer.getUsage(*arguments.getApplicationUsage()); + + // if user request help write it out to cout. + if (arguments.read("-h") || arguments.read("--help")) + { + arguments.getApplicationUsage()->write(std::cout); + return 1; + } + + // any option left unread are converted into errors to write out later. + arguments.reportRemainingOptionsAsUnrecognized(); + + // report any errors if they have occured when parsing the program aguments. + if (arguments.errors()) + { + arguments.writeErrorMessages(std::cout); + return 1; + } + + + // set the scene to render + viewer.setSceneData(createScene()); + + // create the windows and run the threads. + viewer.realize(); + + while( !viewer.done() ) + { + // wait for all cull and draw threads to complete. + viewer.sync(); + + // update the scene by traversing it with the the update visitor which will + // call all node update callbacks and animations. + viewer.update(); + + // fire off the cull and draw traversals of the scene. + viewer.frame(); + + } + + // wait for all cull and draw threads to complete before exit. + viewer.sync(); + + return 0; +} diff --git a/include/osg/AutoTransform b/include/osg/AutoTransform new file mode 100644 index 000000000..64960d3ae --- /dev/null +++ b/include/osg/AutoTransform @@ -0,0 +1,103 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef OSG_AUTOTRANSFORM +#define OSG_AUTOTRANSFORM 1 + +#include +#include +#include +#include + +namespace osg { + +/** AutoTransform - is Transform the automatically scales or rotates + * to keep its children relative to screen space coordinates. +*/ +class SG_EXPORT AutoTransform : public Transform +{ + public : + AutoTransform(); + + AutoTransform(const AutoTransform& pat,const CopyOp& copyop=CopyOp::SHALLOW_COPY); + + virtual osg::Object* cloneType() const { return new AutoTransform (); } + virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new AutoTransform (*this,copyop); } + virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=NULL; } + virtual const char* className() const { return "AutoTransform"; } + virtual const char* libraryName() const { return "osg"; } + + virtual void accept(NodeVisitor& nv); + + virtual AutoTransform* asAutoTransform() { return this; } + virtual const AutoTransform* asAutoTransform() const { return this; } + + inline void setPosition(const Vec3& pos) { _position = pos; dirtyBound(); } + inline const Vec3& getPosition() const { return _position; } + + + inline void setRotation(const Quat& quat) { _rotation = quat; dirtyBound(); } + inline const Quat& getRotation() const { return _rotation; } + + inline void setScale(float scale) { _scale.set(scale,scale,scale); dirtyBound(); } + inline void setScale(const Vec3& scale) { _scale = scale; dirtyBound(); } + inline const Vec3& getScale() const { return _scale; } + + inline void setPivotPoint(const Vec3& pivot) { _pivotPoint = pivot; dirtyBound(); } + inline const Vec3& getPivotPoint() const { return _pivotPoint; } + + + void setAutoUpdateEyeMovementTolerance(float tolerance) { _autoUpdateEyeMovementTolerance = tolerance; } + float getAutoUpdateEyeMovementTolerance() const { return _autoUpdateEyeMovementTolerance; } + + void setAutoRotateToScreen(bool autoRotateToScreen) { _autoRotateToScreen = autoRotateToScreen; } + bool getAutoRotateToScreen() const { return _autoRotateToScreen; } + + void setAutoScaleToScreen(bool autoScaleToScreen) { _autoScaleToScreen = autoScaleToScreen; } + bool getAutoScaleToScreen() const { return _autoScaleToScreen; } + + + virtual bool computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor* nv) const; + + virtual bool computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor* nv) const; + + + + protected : + + virtual ~AutoTransform() {} + + + Vec3 _position; + Vec3 _pivotPoint; + float _autoUpdateEyeMovementTolerance; + bool _autoRotateToScreen; + bool _autoScaleToScreen; + + mutable Quat _rotation; + mutable Vec3 _scale; + mutable bool _firstTimeToInitEyePoint; + mutable osg::Vec3 _previousEyePoint; + mutable int _previousWidth; + mutable int _previousHeight; + + void computeMatrix() const; + + mutable bool _matrixDirty; + mutable osg::Matrix _cachedMatrix; + +}; + +} + +#endif diff --git a/include/osgText/Font b/include/osgText/Font index 4283dc946..431894f09 100644 --- a/include/osgText/Font +++ b/include/osgText/Font @@ -252,6 +252,8 @@ public: const osg::Vec2& getMaxTexCoord() const; void subload() const; + + void draw(osg::State& state) const; protected: @@ -269,6 +271,9 @@ public: int _texturePosY; osg::Vec2 _minTexCoord; osg::Vec2 _maxTexCoord; + + typedef osg::buffered_value GLObjectList; + mutable GLObjectList _globjList; }; diff --git a/include/osgText/Text b/include/osgText/Text index 68ab1107c..32ea3f25e 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -202,11 +202,12 @@ public: enum DrawModeMask { TEXT = 1, /// default - BOUNDINGBOX = 2, - ALIGNMENT = 4 + TEXT_PIXMAP = 2, + BOUNDINGBOX = 4, + ALIGNMENT = 8 }; - void setDrawMode(unsigned int mode) { _drawMode=mode; } + void setDrawMode(unsigned int mode); unsigned int getDrawMode() const { return _drawMode; } @@ -238,14 +239,20 @@ public: // internal structures, variable and methods used for rendering of characters. struct OSGTEXT_EXPORT GlyphQuads { + typedef std::vector Glyphs; typedef std::vector Coords2; typedef std::vector Coords3; typedef std::vector TexCoords; + Glyphs _glyphs; Coords2 _coords; Coords3 _transformedCoords; TexCoords _texcoords; + Glyphs getGlyphs() { return _glyphs; } + const Glyphs getGlyphs() const { return _glyphs; } + + Coords2& getCoords() { return _coords; } const Coords2& getCoords() const { return _coords; } diff --git a/src/osg/AutoTransform.cpp b/src/osg/AutoTransform.cpp new file mode 100644 index 000000000..03075742d --- /dev/null +++ b/src/osg/AutoTransform.cpp @@ -0,0 +1,155 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ +#include +#include + +using namespace osg; + +AutoTransform::AutoTransform(): + _scale(1.0f,1.0f,1.0f), + _autoUpdateEyeMovementTolerance(0.0f), + _autoRotateToScreen(false), + _autoScaleToScreen(false), + _firstTimeToInitEyePoint(true), + _matrixDirty(true) +{ +// setNumChildrenRequiringUpdateTraversal(1); +} + +AutoTransform::AutoTransform(const AutoTransform& pat,const CopyOp& copyop): + Transform(pat,copyop), + _position(pat._position), + _pivotPoint(pat._pivotPoint), + _rotation(pat._rotation), + _scale(pat._scale) +{ +// setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1); +} + +bool AutoTransform::computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor*) const +{ + if (_matrixDirty) computeMatrix(); + + if (_referenceFrame==RELATIVE_TO_PARENTS) + { + matrix.preMult(_cachedMatrix); + } + else // absolute + { + matrix = _cachedMatrix; + } + return true; +} + + +bool AutoTransform::computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor*) const +{ + if (_referenceFrame==RELATIVE_TO_PARENTS) + { + matrix.postMult(osg::Matrix::translate(-_position)* + osg::Matrix::rotate(_rotation.inverse())* + osg::Matrix::scale(1.0f/_scale.x(),1.0f/_scale.y(),1.0f/_scale.z())* + osg::Matrix::translate(_pivotPoint)); + } + else // absolute + { + matrix = osg::Matrix::translate(-_position)* + osg::Matrix::rotate(_rotation.inverse())* + osg::Matrix::scale(1.0f/_scale.x(),1.0f/_scale.y(),1.0f/_scale.z())* + osg::Matrix::translate(_pivotPoint); + } + return true; +} + +void AutoTransform::computeMatrix() const +{ + if (!_matrixDirty) return; + + _cachedMatrix.set(osg::Matrix::translate(-_pivotPoint)* + osg::Matrix::scale(_scale)* + osg::Matrix::rotate(_rotation)* + osg::Matrix::translate(_position)); + + _matrixDirty = false; +} + +void AutoTransform::accept(NodeVisitor& nv) +{ + // if app traversal update the frame count. + if (nv.getVisitorType()==NodeVisitor::UPDATE_VISITOR) + { + } + else + if (nv.getVisitorType()==NodeVisitor::CULL_VISITOR) + { + + CullStack* cs = dynamic_cast(&nv); + if (cs) + { + + int width = _previousWidth; + int height = _previousHeight; + + osg::Viewport* viewport = cs->getViewport(); + if (viewport) + { + width = viewport->width(); + height = viewport->height(); + } + + osg::Vec3 eyePoint = cs->getEyeLocal(); + + bool doUpdate = _firstTimeToInitEyePoint; + if (!_firstTimeToInitEyePoint) + { + osg::Vec3 dv = _previousEyePoint-eyePoint; + if (dv.length2()>getAutoUpdateEyeMovementTolerance()*(eyePoint-getPosition()).length2()) + { + doUpdate = true; + } + else if (width!=_previousWidth || height!=_previousHeight) + { + doUpdate = true; + } + } + _firstTimeToInitEyePoint = false; + + if (doUpdate) + { + + if (getAutoScaleToScreen()) + { + float size = 1.0f/cs->pixelSize(getPosition(),1.0f); + setScale(size); + } + + if (getAutoRotateToScreen()) + { + osg::Quat rotation; + rotation.set(cs->getModelViewMatrix()); + setRotation(rotation.inverse()); + } + + _previousEyePoint = eyePoint; + _previousWidth = width; + _previousHeight = height; + + _matrixDirty = true; + } + + } + } + + // now do the proper accept + Transform::accept(nv); +} diff --git a/src/osgText/Font.cpp b/src/osgText/Font.cpp index 577a1ab1b..62d66137e 100644 --- a/src/osgText/Font.cpp +++ b/src/osgText/Font.cpp @@ -559,3 +559,27 @@ void Font::Glyph::subload() const "\t 0x"<<(unsigned int)data()<<");"< #include #include +#include #include #include "DefaultFont.h" @@ -68,8 +69,14 @@ struct TextCullCallback : public osg::Drawable::CullCallback if (_text->getAutoScaleToScreen()) { - float size = 1.0f/cs->pixelSize(_text->getPosition(),1.0f); - _text->setScale(size); + float numPixels = cs->pixelSize(_text->getPosition(),_text->getCharacterHeight()); + if (numPixels>_text->getFontHeight()) + { + _text->setScale(_text->getFontHeight()/numPixels); + } + + //float size = 1.0f/cs->pixelSize(_text->getPosition(),1.0f); + //_text->setScale(size); } if (_text->getAutoRotateToScreen()) @@ -295,6 +302,25 @@ void Text::setColor(const osg::Vec4& color) _color = color; } +void Text::setDrawMode(unsigned int mode) +{ + if (_drawMode&3 != mode&3) + { + _drawMode=mode; + if (_drawMode&TEXT_PIXMAP) + { + setAutoScaleToScreen(true); + setAutoRotateToScreen(true); + } + computeGlyphRepresentation(); + } + else + { + _drawMode=mode; + } +} + + bool Text::computeBound() const { _bbox.init(); @@ -436,7 +462,7 @@ void Text::computeGlyphRepresentation() local.x() += bearing.x() * wr; local.y() += bearing.y() * hr; } - } +; } break; } case VERTICAL: @@ -458,6 +484,8 @@ void Text::computeGlyphRepresentation() GlyphQuads& glyphquad = _textureGlyphQuadMap[glyph->getTexture()->getStateSet()]; + glyphquad._glyphs.push_back(glyph); + // set up the coords of the quad glyphquad._coords.push_back(local+osg::Vec2(0.0f,height)); glyphquad._coords.push_back(local+osg::Vec2(0.0f,0.0f)); @@ -575,6 +603,13 @@ void Text::computePositions() dirtyBound(); } +static unsigned char local_data[] = { 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255 }; + + +static osg::Image* loaded_image = osgDB::readImageFile("lz.rgb"); void Text::drawImplementation(osg::State& state) const { @@ -583,7 +618,7 @@ void Text::drawImplementation(osg::State& state) const glNormal3fv(_normal.ptr()); glColor4fv(_color.ptr()); - if (_drawMode & TEXT) + if (_drawMode & TEXT && !(_drawMode & TEXT_PIXMAP)) { state.disableAllVertexArrays(); @@ -605,6 +640,36 @@ void Text::drawImplementation(osg::State& state) const } } + if (_drawMode & TEXT_PIXMAP) + { + + state.applyTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF); + + for(TextureGlyphQuadMap::const_iterator titr=_textureGlyphQuadMap.begin(); + titr!=_textureGlyphQuadMap.end(); + ++titr) + { + const GlyphQuads& glyphquad = titr->second; + + int ci=1; + + for(GlyphQuads::Glyphs::const_iterator gitr=glyphquad._glyphs.begin(); + gitr!=glyphquad._glyphs.end(); + ++gitr, ci+=4) + { + + Font::Glyph* glyph = *gitr; + + + glRasterPos3fv(glyphquad._transformedCoords[ci].ptr()); + + glyph->draw(state); + + } + + } + } + if (_drawMode & BOUNDINGBOX) {