From 97a4775b7eb45e5f2197433c7e1988b2b0e49b5a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 10 Dec 2002 19:56:14 +0000 Subject: [PATCH] Updates to the light points support to improve the control of the blending of light points with their background. --- include/osgSim/LightPoint | 26 +++ include/osgSim/LightPointNode | 1 - src/osgSim/LightPoint.cpp | 55 +++++- src/osgSim/LightPointDrawable.cpp | 174 +++++++++++++----- .../osgSim/LightPointDrawable.h | 35 ++-- src/osgSim/LightPointNode.cpp | 17 +- 6 files changed, 240 insertions(+), 68 deletions(-) rename include/osgSim/LightPointDrawable => src/osgSim/LightPointDrawable.h (66%) diff --git a/include/osgSim/LightPoint b/include/osgSim/LightPoint index d8310855c..8f6ab246c 100644 --- a/include/osgSim/LightPoint +++ b/include/osgSim/LightPoint @@ -24,9 +24,33 @@ class OSGSIM_EXPORT LightPoint { public: + enum BlendingMode + { + OPAQUE, + ADDITIVE, + BLENDED + }; + LightPoint(); + LightPoint(const osg::Vec3& position, + const osg::Vec4& color); + + LightPoint(bool on, + const osg::Vec3& position, + const osg::Vec4& color, + float intensity=1.0f, + float radius=1.0f, + float maxPixelSize=30, + Sector* sector=0, + BlinkSequence* blinkSequence=0, + BlendingMode blendingMode=BLENDED); + + LightPoint(const LightPoint& lp); + + LightPoint& operator = (const LightPoint& lp); + bool _on; osg::Vec3 _position; @@ -37,6 +61,8 @@ class OSGSIM_EXPORT LightPoint osg::ref_ptr _sector; osg::ref_ptr _blinkSequence; + + BlendingMode _blendingMode; }; } diff --git a/include/osgSim/LightPointNode b/include/osgSim/LightPointNode index 184c337e8..a941403e6 100644 --- a/include/osgSim/LightPointNode +++ b/include/osgSim/LightPointNode @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/src/osgSim/LightPoint.cpp b/src/osgSim/LightPoint.cpp index 08088044b..1a053aaef 100644 --- a/src/osgSim/LightPoint.cpp +++ b/src/osgSim/LightPoint.cpp @@ -18,7 +18,42 @@ LightPoint::LightPoint(): _radius(1.0f), _maxPixelSize(30), _sector(0), - _blinkSequence(0) + _blinkSequence(0), + _blendingMode(BLENDED) +{ +} + +LightPoint::LightPoint(const osg::Vec3& position,const osg::Vec4& color): + _on(true), + _position(position), + _color(color), + _intensity(1.0f), + _radius(1.0f), + _maxPixelSize(30), + _sector(0), + _blinkSequence(0), + _blendingMode(BLENDED) +{ +} + +LightPoint::LightPoint(bool on, + const osg::Vec3& position, + const osg::Vec4& color, + float intensity, + float radius, + float maxPixelSize, + Sector* sector, + BlinkSequence* blinkSequence, + BlendingMode blendingMode): + _on(on), + _position(position), + _color(color), + _intensity(intensity), + _radius(radius), + _maxPixelSize(maxPixelSize), + _sector(sector), + _blinkSequence(blinkSequence), + _blendingMode(blendingMode) { } @@ -30,6 +65,22 @@ LightPoint::LightPoint(const LightPoint& lp): _radius(lp._radius), _maxPixelSize(lp._maxPixelSize), _sector(lp._sector), - _blinkSequence(lp._blinkSequence) + _blinkSequence(lp._blinkSequence), + _blendingMode(lp._blendingMode) { } + +LightPoint& LightPoint::operator = (const LightPoint& lp) +{ + _on = lp._on; + _position = lp._position; + _color = lp._color; + _intensity = lp._intensity; + _radius = lp._radius; + _maxPixelSize = lp._maxPixelSize; + _sector = lp._sector; + _blinkSequence = lp._blinkSequence; + _blendingMode = lp._blendingMode; + + return *this; +} diff --git a/src/osgSim/LightPointDrawable.cpp b/src/osgSim/LightPointDrawable.cpp index c95bcb65b..704e50926 100644 --- a/src/osgSim/LightPointDrawable.cpp +++ b/src/osgSim/LightPointDrawable.cpp @@ -6,7 +6,7 @@ // purchase of the Open Scene Graph Professional License (OSGPL) // for further information contact robert@openscenegraph.com. -#include +#include "LightPointDrawable.h" #include @@ -15,8 +15,7 @@ using namespace osgSim; LightPointDrawable::LightPointDrawable(): osg::Drawable(), _referenceTime(0.0), - _referenceTimeInterval(0.0), - _sizedLightPointList() + _referenceTimeInterval(0.0) { setSupportsDisplayList(false); @@ -26,9 +25,11 @@ LightPointDrawable::LightPointDrawable(): _depthOn = osgNew osg::Depth; _depthOn->setWriteMask(true); - _blendOn = osgNew osg::BlendFunc; - _blendOn->setFunction(osg::BlendFunc::SRC_ALPHA,osg::BlendFunc::ONE); - //_blendOn->setFunction(osg::BlendFunc::SRC_ALPHA,osg::BlendFunc::ONE_MINUS_SRC_ALPHA); + _blendOne = osgNew osg::BlendFunc; + _blendOne->setFunction(osg::BlendFunc::SRC_ALPHA,osg::BlendFunc::ONE); + + _blendOneMinusSrcAlpha = osgNew osg::BlendFunc; + _blendOneMinusSrcAlpha->setFunction(osg::BlendFunc::SRC_ALPHA,osg::BlendFunc::ONE_MINUS_SRC_ALPHA); _colorMaskOff = osgNew osg::ColorMask; _colorMaskOff->setMask(false,false,false,false); @@ -40,63 +41,67 @@ LightPointDrawable::LightPointDrawable(const LightPointDrawable& lpd,const osg:: osg::Drawable(lpd,copyop), _referenceTime(lpd._referenceTime), _referenceTimeInterval(lpd._referenceTimeInterval), - _sizedLightPointList(lpd._sizedLightPointList) + _sizedOpaqueLightPointList(lpd._sizedOpaqueLightPointList), + _sizedAdditiveLightPointList(lpd._sizedAdditiveLightPointList), + _sizedBlendedLightPointList(lpd._sizedBlendedLightPointList) { } +void LightPointDrawable::reset() +{ + for(SizedLightPointList::iterator itr=_sizedOpaqueLightPointList.begin(); + itr!=_sizedOpaqueLightPointList.end(); + ++itr) + { + if (!itr->empty()) + itr->erase(itr->begin(),itr->end()); + } + + for(SizedLightPointList::iterator itr=_sizedAdditiveLightPointList.begin(); + itr!=_sizedAdditiveLightPointList.end(); + ++itr) + { + if (!itr->empty()) + itr->erase(itr->begin(),itr->end()); + } + + for(SizedLightPointList::iterator itr=_sizedBlendedLightPointList.begin(); + itr!=_sizedBlendedLightPointList.end(); + ++itr) + { + if (!itr->empty()) + itr->erase(itr->begin(),itr->end()); + } +} + + void LightPointDrawable::drawImplementation(osg::State& state) const { - if (_sizedLightPointList.empty()) return; - - state.applyMode(GL_POINT_SMOOTH,true); state.applyMode(GL_BLEND,true); state.applyMode(GL_LIGHTING,false); state.applyTextureMode(0,GL_TEXTURE_1D,false); state.applyTextureMode(0,GL_TEXTURE_2D,false); - glHint(GL_POINT_SMOOTH_HINT,GL_NICEST); - - state.applyAttribute(_blendOn.get()); - state.applyAttribute(_depthOff.get()); - //state.applyMode(GL_DEPTH_TEST,false); - int pointsize; - SizedLightPointList::const_iterator sitr; - for(pointsize=1,sitr=_sizedLightPointList.begin(); - sitr!=_sizedLightPointList.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()); - } - } - - // switch on depth mask to do set up depth mask. state.applyAttribute(_depthOn.get()); -// glDepthMask(GL_TRUE); - state.applyMode(GL_BLEND,false); - - state.applyAttribute(_colorMaskOff.get()); -// glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); + state.applyAttribute(_blendOneMinusSrcAlpha.get()); + state.applyMode(GL_POINT_SMOOTH,true); - for(pointsize=1,sitr=_sizedLightPointList.begin(); - sitr!=_sizedLightPointList.end(); + 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()) { + //state.applyMode(GL_POINT_SMOOTH,pointsize!=1); glPointSize(pointsize); glInterleavedArrays(GL_C4UB_V3F,0,&lpl.front()); //state.setInterleavedArrays(GL_C4UB_V3F,0,&lpl.front()); @@ -104,6 +109,66 @@ void LightPointDrawable::drawImplementation(osg::State& state) const } } + state.applyMode(GL_BLEND,true); + state.applyAttribute(_blendOne.get()); + state.applyAttribute(_depthOff.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()); + } + } + + state.applyAttribute(_blendOneMinusSrcAlpha.get()); + + for(pointsize=1,sitr=_sizedBlendedLightPointList.begin(); + sitr!=_sizedBlendedLightPointList.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()); + } + } + +// // switch on depth mask to do set up depth mask. +// state.applyAttribute(_depthOn.get()); +// +// state.applyMode(GL_BLEND,false); +// +// state.applyAttribute(_colorMaskOff.get()); +// +// for(pointsize=1,sitr=_sizedLightPointList.begin(); +// sitr!=_sizedLightPointList.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()); +// } +// } + glPointSize(1); glHint(GL_POINT_SMOOTH_HINT,GL_FASTEST); @@ -116,8 +181,33 @@ bool LightPointDrawable::computeBound() const { _bbox.init(); - for(SizedLightPointList::const_iterator sitr=_sizedLightPointList.begin(); - sitr!=_sizedLightPointList.end(); + SizedLightPointList::const_iterator sitr; + for(sitr=_sizedOpaqueLightPointList.begin(); + sitr!=_sizedOpaqueLightPointList.end(); + ++sitr) + { + const LightPointList& lpl = *sitr; + for(LightPointList::const_iterator litr=lpl.begin(); + litr!=lpl.end(); + ++litr) + { + _bbox.expandBy(litr->second); + } + } + for(sitr=_sizedAdditiveLightPointList.begin(); + sitr!=_sizedAdditiveLightPointList.end(); + ++sitr) + { + const LightPointList& lpl = *sitr; + for(LightPointList::const_iterator litr=lpl.begin(); + litr!=lpl.end(); + ++litr) + { + _bbox.expandBy(litr->second); + } + } + for(sitr=_sizedBlendedLightPointList.begin(); + sitr!=_sizedBlendedLightPointList.end(); ++sitr) { const LightPointList& lpl = *sitr; diff --git a/include/osgSim/LightPointDrawable b/src/osgSim/LightPointDrawable.h similarity index 66% rename from include/osgSim/LightPointDrawable rename to src/osgSim/LightPointDrawable.h index 4ab851818..64a547d44 100644 --- a/include/osgSim/LightPointDrawable +++ b/src/osgSim/LightPointDrawable.h @@ -48,22 +48,24 @@ class OSGSIM_EXPORT LightPointDrawable : public osg::Drawable ColorPosition(unsigned long f,const osg::Vec3& s):first(f),second(s) {} }; - void reset() - { - for(SizedLightPointList::iterator itr=_sizedLightPointList.begin(); - itr!=_sizedLightPointList.end(); - ++itr) - { - if (!itr->empty()) - itr->erase(itr->begin(),itr->end()); - } + void reset(); + inline void addOpaqueLightPoint(unsigned int pointSize,const osg::Vec3& position,const osg::Vec4& color) + { + if (pointSize>=_sizedOpaqueLightPointList.size()) _sizedOpaqueLightPointList.resize(pointSize+1); + _sizedOpaqueLightPointList[pointSize].push_back(ColorPosition(color.asRGBA(),position)); } - inline void addLightPoint(unsigned int pointSize,const osg::Vec3& position,const osg::Vec4& color) + inline void addAdditiveLightPoint(unsigned int pointSize,const osg::Vec3& position,const osg::Vec4& color) { - if (pointSize>=_sizedLightPointList.size()) _sizedLightPointList.resize(pointSize+1); - _sizedLightPointList[pointSize].push_back(ColorPosition(color.asRGBA(),position)); + if (pointSize>=_sizedAdditiveLightPointList.size()) _sizedAdditiveLightPointList.resize(pointSize+1); + _sizedAdditiveLightPointList[pointSize].push_back(ColorPosition(color.asRGBA(),position)); + } + + inline void addBlendedLightPoint(unsigned int pointSize,const osg::Vec3& position,const osg::Vec4& color) + { + if (pointSize>=_sizedBlendedLightPointList.size()) _sizedBlendedLightPointList.resize(pointSize+1); + _sizedBlendedLightPointList[pointSize].push_back(ColorPosition(color.asRGBA(),position)); } /** draw LightPoints. */ @@ -94,14 +96,17 @@ class OSGSIM_EXPORT LightPointDrawable : public osg::Drawable double _referenceTime; double _referenceTimeInterval; - typedef std::vector LightPointList; + typedef std::vector LightPointList; typedef std::vector SizedLightPointList; - SizedLightPointList _sizedLightPointList; + SizedLightPointList _sizedOpaqueLightPointList; + SizedLightPointList _sizedAdditiveLightPointList; + SizedLightPointList _sizedBlendedLightPointList; osg::ref_ptr _depthOff; osg::ref_ptr _depthOn; - osg::ref_ptr _blendOn; + osg::ref_ptr _blendOne; + osg::ref_ptr _blendOneMinusSrcAlpha; osg::ref_ptr _colorMaskOff; osg::ref_ptr _point; diff --git a/src/osgSim/LightPointNode.cpp b/src/osgSim/LightPointNode.cpp index ec259c2a9..ca2b5fd94 100644 --- a/src/osgSim/LightPointNode.cpp +++ b/src/osgSim/LightPointNode.cpp @@ -7,7 +7,8 @@ // for further information contact robert@openscenegraph.com. #include -#include + +#include "LightPointDrawable.h" #include #include @@ -260,6 +261,7 @@ void LightPointNode::traverse(osg::NodeVisitor& nv) // adjust pixel size to account for intensity. if (intensity!=1.0) pixelSize *= sqrt(intensity); + osg::Vec3 xpos(position*matrix); if (pixelSize<1.0f) { // need to use alpha blending... @@ -268,7 +270,7 @@ void LightPointNode::traverse(osg::NodeVisitor& nv) if (color[3]<=minimumIntensity) continue; - drawable->addLightPoint(0, position*matrix,color); + drawable->addBlendedLightPoint(0, xpos,color); } else if (pixelSizeaddLightPoint(lowerBoundPixelSize-1, xpos,color); +// color[3] = alpha*(1.0f-remainder); + drawable->addBlendedLightPoint(lowerBoundPixelSize-1, xpos,color); - //color[3] = osg::square(remainder); +// //color[3] = osg::square(remainder); color[3] = alpha*remainder; - drawable->addLightPoint(lowerBoundPixelSize, xpos,color); + drawable->addBlendedLightPoint(lowerBoundPixelSize, xpos,color); } else // use a billboard geometry. { - drawable->addLightPoint((unsigned int)(lp._maxPixelSize-1.0), position*matrix,color); + drawable->addOpaqueLightPoint((unsigned int)(lp._maxPixelSize-1.0), xpos,color); } }