diff --git a/VisualStudio/osgSim/osgSim.dsp b/VisualStudio/osgSim/osgSim.dsp index 37a450eda..ff043fc6f 100644 --- a/VisualStudio/osgSim/osgSim.dsp +++ b/VisualStudio/osgSim/osgSim.dsp @@ -187,6 +187,10 @@ SOURCE=..\..\src\osgSim\LightPointDrawable.cpp # End Source File # Begin Source File +SOURCE=..\..\src\osgSim\LightPointSpriteDrawable.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\osgSim\LightPointNode.cpp # End Source File # Begin Source File @@ -267,6 +271,10 @@ SOURCE=..\..\src\osgSim\LightPointDrawable.h # End Source File # Begin Source File +SOURCE=..\..\src\osgSim\LightPointSpriteDrawable.h +# End Source File +# Begin Source File + SOURCE=..\..\include\osgSim\LightPointNode # End Source File # Begin Source File diff --git a/examples/osglightpoint/osglightpoint.cpp b/examples/osglightpoint/osglightpoint.cpp index 9f15b62f1..7f8aec75c 100644 --- a/examples/osglightpoint/osglightpoint.cpp +++ b/examples/osglightpoint/osglightpoint.cpp @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #include #include @@ -48,6 +51,8 @@ void addToLightPointNode(osgSim::LightPointNode& lpn,osgSim::LightPoint& start,o #undef INTERPOLATE +bool usePointSprites; + osg::Node* createLightPointsDatabase() { osgSim::LightPoint start; @@ -96,6 +101,26 @@ osg::Node* createLightPointsDatabase() // start._sector = sector; osgSim::LightPointNode* lpn = new osgSim::LightPointNode; + + // + osg::StateSet* set = lpn->getOrCreateStateSet(); + + if (usePointSprites) + { + lpn->setPointSprite(); + + // Set point sprite texture in LightPointNode StateSet. + osg::Texture2D *tex = new osg::Texture2D(); + tex->setImage(osgDB::readImageFile("Images/particle.rgb")); + set->setTextureAttributeAndModes(0, tex, osg::StateAttribute::ON); + } + + //set->setMode(GL_BLEND, osg::StateAttribute::ON); + //osg::BlendFunc *fn = new osg::BlendFunc(); + //fn->setFunction(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::DST_ALPHA); + //set->setAttributeAndModes(fn, osg::StateAttribute::ON); + // + addToLightPointNode(*lpn,start,end,noStepsX); start._position += start_delta; @@ -172,6 +197,7 @@ int main( int argc, char **argv ) arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use high quality light point, typically used for naviagional lights."); arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); + arguments.getApplicationUsage()->addCommandLineOption("--sprites","Point sprites."); // construct the viewer. osgProducer::Viewer viewer(arguments); @@ -189,6 +215,9 @@ int main( int argc, char **argv ) return 1; } + usePointSprites = false; + while (arguments.read("--sprites")) { usePointSprites = true; }; + // any option left unread are converted into errors to write out later. arguments.reportRemainingOptionsAsUnrecognized(); diff --git a/include/osgSim/LightPointNode b/include/osgSim/LightPointNode index 33d158a35..672731b77 100644 --- a/include/osgSim/LightPointNode +++ b/include/osgSim/LightPointNode @@ -82,6 +82,10 @@ class OSGSIM_EXPORT LightPointNode : public osg::Node osgSim::LightPointSystem* getLightPointSystem() { return _lightSystem.get(); } + void setPointSprite(bool enable=true) { _pointSprites = enable; } + + bool getPointSprite() const { return _pointSprites; } + virtual osg::BoundingSphere computeBound() const; protected: @@ -99,6 +103,8 @@ class OSGSIM_EXPORT LightPointNode : public osg::Node float _maxVisibleDistance2; osg::ref_ptr _lightSystem; + + bool _pointSprites; }; diff --git a/src/osgPlugins/OpenFlight/LightPointRecords.cpp b/src/osgPlugins/OpenFlight/LightPointRecords.cpp index 3916173f3..f5042cf21 100644 --- a/src/osgPlugins/OpenFlight/LightPointRecords.cpp +++ b/src/osgPlugins/OpenFlight/LightPointRecords.cpp @@ -5,6 +5,7 @@ // #include +#include #include "Registry.h" #include "Document.h" #include "RecordInputStream.h" @@ -271,6 +272,21 @@ protected: { _lpn->setMinPixelSize(_appearance->minPixelSize); _lpn->setMaxPixelSize(_appearance->maxPixelSize); + + if (_appearance->texturePatternIndex != -1) + { + // Use point sprites for light points. + _lpn->setPointSprite(); + + TexturePool* tp = document.getOrCreateTexturePool(); + osg::StateSet* textureStateSet = tp->get(_appearance->texturePatternIndex); + if (textureStateSet) + { + // Merge face stateset with texture stateset + osg::StateSet* stateset = _lpn->getOrCreateStateSet(); + stateset->merge(*textureStateSet); + } + } } // Add to parent diff --git a/src/osgPlugins/OpenFlight/PaletteRecords.cpp b/src/osgPlugins/OpenFlight/PaletteRecords.cpp index 0d67f81eb..9a3b91b26 100644 --- a/src/osgPlugins/OpenFlight/PaletteRecords.cpp +++ b/src/osgPlugins/OpenFlight/PaletteRecords.cpp @@ -502,7 +502,8 @@ protected: appearance->fadeOutDuration = in.readFloat32(); appearance->LODRangeRatio = in.readFloat32(); appearance->LODScale = in.readFloat32(); - appearance->texturePatternIndex = in.readInt32(-1); + appearance->texturePatternIndex = in.readInt16(-1); + // The final short is reserved; don't bother reading it. // Add to pool LightPointAppearancePool* lpaPool = document.getOrCreateLightPointAppearancePool(); diff --git a/src/osgPlugins/OpenFlight/Pools.h b/src/osgPlugins/OpenFlight/Pools.h index 3a24fed3b..3fa63774e 100644 --- a/src/osgPlugins/OpenFlight/Pools.h +++ b/src/osgPlugins/OpenFlight/Pools.h @@ -165,7 +165,7 @@ struct LPAppearance : public osg::Referenced float32 fadeOutDuration; float32 LODRangeRatio; float32 LODScale; - int32 texturePatternIndex; + int16 texturePatternIndex; }; diff --git a/src/osgSim/GNUmakefile b/src/osgSim/GNUmakefile index 155f74a0b..545b3cd26 100644 --- a/src/osgSim/GNUmakefile +++ b/src/osgSim/GNUmakefile @@ -11,6 +11,7 @@ CXXFILES = \ InsertImpostorsVisitor.cpp\ LightPoint.cpp\ LightPointDrawable.cpp\ + LightPointSpriteDrawable.cpp\ LightPointNode.cpp\ MultiSwitch.cpp\ OverlayNode.cpp\ diff --git a/src/osgSim/LightPointNode.cpp b/src/osgSim/LightPointNode.cpp index b2d3f5a1c..65b80aa8c 100644 --- a/src/osgSim/LightPointNode.cpp +++ b/src/osgSim/LightPointNode.cpp @@ -15,11 +15,13 @@ #include #include "LightPointDrawable.h" +#include "LightPointSpriteDrawable.h" #include #include #include #include +#include #include @@ -46,7 +48,8 @@ LightPointNode::LightPointNode(): _minPixelSize(0.0f), _maxPixelSize(30.0f), _maxVisibleDistance2(FLT_MAX), - _lightSystem(0) + _lightSystem(0), + _pointSprites(false) { setStateSet(getSingletonLightPointSystemSet()); } @@ -58,7 +61,8 @@ LightPointNode::LightPointNode(const LightPointNode& lpn,const osg::CopyOp& copy _minPixelSize(lpn._minPixelSize), _maxPixelSize(lpn._maxPixelSize), _maxVisibleDistance2(lpn._maxVisibleDistance2), - _lightSystem(lpn._lightSystem) + _lightSystem(lpn._lightSystem), + _pointSprites(lpn._pointSprites) { } @@ -178,6 +182,10 @@ void LightPointNode::traverse(osg::NodeVisitor& nv) drawable = static_cast(object); } + else if (typeid(*object)==typeid(LightPointSpriteDrawable)) + { + drawable = static_cast(object); + } else { // will need to replace UserData. @@ -187,8 +195,7 @@ void LightPointNode::traverse(osg::NodeVisitor& nv) if (!drawable) { - // set it for the frst time. - drawable = new LightPointDrawable; + drawable = _pointSprites ? new LightPointSpriteDrawable : new LightPointDrawable; rg->setUserData(drawable); if (cv->getFrameStamp()) diff --git a/src/osgSim/LightPointSpriteDrawable.cpp b/src/osgSim/LightPointSpriteDrawable.cpp new file mode 100644 index 000000000..fcc4f8565 --- /dev/null +++ b/src/osgSim/LightPointSpriteDrawable.cpp @@ -0,0 +1,129 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 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 "LightPointSpriteDrawable.h" + +#include + +using namespace osgSim; + +LightPointSpriteDrawable::LightPointSpriteDrawable(): + osgSim::LightPointDrawable() +{ + _sprite = new osg::PointSprite; +} + +LightPointSpriteDrawable::LightPointSpriteDrawable(const LightPointSpriteDrawable& lpsd,const osg::CopyOp& copyop): + osgSim::LightPointDrawable(lpsd,copyop) +{ +} + +void LightPointSpriteDrawable::drawImplementation(osg::State& state) const +{ + + if (!state.getModeValidity(GL_POINT_SPRITE_ARB)) + { + LightPointDrawable::drawImplementation(state); + return; + } + + state.applyMode(GL_POINT_SMOOTH,true); + state.applyMode(GL_BLEND,true); + state.applyMode(GL_LIGHTING,false); + state.applyTextureMode(0,GL_TEXTURE_2D,true); + + state.applyMode(GL_POINT_SPRITE_ARB,true); + state.applyTextureAttribute(0,_sprite.get()); + // Assume the point sprite texture map is already specified + // (typically in the owning LightPointNode StateSet). + + + glHint(GL_POINT_SMOOTH_HINT,GL_NICEST); + + state.applyAttribute(_depthOn.get()); + + state.applyAttribute(_blendOneMinusSrcAlpha.get()); + state.applyMode(GL_POINT_SMOOTH,true); + + SizedLightPointList::const_iterator sitr; + unsigned int pointsize; + for(pointsize=1,sitr=_sizedOpaqueLightPointList.begin(); + sitr!=_sizedOpaqueLightPointList.end(); + ++sitr,++pointsize) + { + + const LightPointList& lpl = *sitr; + if (!lpl.empty()) + { + glPointSize(pointsize); + //glInterleavedArrays(GL_C4UB_V3F,0,&lpl.front()); + state.setInterleavedArrays(GL_C4UB_V3F,0,&lpl.front()); + glDrawArrays(GL_POINTS,0,lpl.size()); + } + } + + state.applyMode(GL_BLEND,true); + state.applyAttribute(_depthOff.get()); + + + state.applyAttribute(_blendOneMinusSrcAlpha.get()); + + for(pointsize=1,sitr=_sizedBlendedLightPointList.begin(); + sitr!=_sizedBlendedLightPointList.end(); + ++sitr,++pointsize) + { + + const LightPointList& lpl = *sitr; + if (!lpl.empty()) + { + glPointSize(pointsize); + //glInterleavedArrays(GL_C4UB_V3F,0,&lpl.front()); + state.setInterleavedArrays(GL_C4UB_V3F,0,&lpl.front()); + glDrawArrays(GL_POINTS,0,lpl.size()); + } + } + + + state.applyAttribute(_blendOne.get()); + + for(pointsize=1,sitr=_sizedAdditiveLightPointList.begin(); + sitr!=_sizedAdditiveLightPointList.end(); + ++sitr,++pointsize) + { + + const LightPointList& lpl = *sitr; + if (!lpl.empty()) + { + //state.applyMode(GL_POINT_SMOOTH,pointsize!=1); + glPointSize(pointsize); + //glInterleavedArrays(GL_C4UB_V3F,0,&lpl.front()); + state.setInterleavedArrays(GL_C4UB_V3F,0,&lpl.front()); + glDrawArrays(GL_POINTS,0,lpl.size()); + } + } + + glPointSize(1); + + glHint(GL_POINT_SMOOTH_HINT,GL_FASTEST); + + state.haveAppliedAttribute(osg::StateAttribute::POINT); + + state.dirtyAllVertexArrays(); + state.disableAllVertexArrays(); + + // restore the state afterwards. + state.apply(); + +} + + diff --git a/src/osgSim/LightPointSpriteDrawable.h b/src/osgSim/LightPointSpriteDrawable.h new file mode 100644 index 000000000..767bf1164 --- /dev/null +++ b/src/osgSim/LightPointSpriteDrawable.h @@ -0,0 +1,51 @@ +//C++ header - Open Scene Graph Simulation - Copyright (C) 1998-2006 Robert Osfield +// Distributed under the terms of the GNU General Public License (GPL) +// as published by the Free Software Foundation. +// +// All software using osgSim must be GPL'd or excempted via the +// purchase of the Open Scene Graph Professional License (OSGPL) +// for further information contact robert@openscenegraph.com. + +#ifndef OSGSIM_LIGHTPOINTSPRITEDRAWABLE +#define OSGSIM_LIGHTPOINTSPRITEDRAWABLE 1 + +#include + +#include +#include "LightPointDrawable.h" +#include + +namespace osgSim { + + +class OSGSIM_EXPORT LightPointSpriteDrawable : public osgSim::LightPointDrawable +{ + public : + + LightPointSpriteDrawable(); + + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ + LightPointSpriteDrawable(const LightPointSpriteDrawable&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); + + virtual osg::Object* cloneType() const { return new LightPointSpriteDrawable(); } + virtual osg::Object* clone(const osg::CopyOp&) const { return new LightPointSpriteDrawable(); } + virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=NULL; } + virtual const char* className() const { return "LightPointSpriteDrawable"; } + + + /** draw LightPoints. */ + virtual void drawImplementation(osg::State& state) const; + + + protected: + + virtual ~LightPointSpriteDrawable() {} + + osg::ref_ptr _sprite; + +}; + +} + +#endif +