Updates to the light points support to improve the control of the blending of

light points with their background.
This commit is contained in:
Robert Osfield
2002-12-10 19:56:14 +00:00
parent c259cadd6d
commit 97a4775b7e
6 changed files with 240 additions and 68 deletions

View File

@@ -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> _sector;
osg::ref_ptr<BlinkSequence> _blinkSequence;
BlendingMode _blendingMode;
};
}

View File

@@ -11,7 +11,6 @@
#include <osgSim/Export>
#include <osgSim/LightPoint>
#include <osgSim/LightPointDrawable>
#include <osg/Node>
#include <osg/NodeVisitor>

View File

@@ -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;
}

View File

@@ -6,7 +6,7 @@
// purchase of the Open Scene Graph Professional License (OSGPL)
// for further information contact robert@openscenegraph.com.
#include <osgSim/LightPointDrawable>
#include "LightPointDrawable.h"
#include <osg/Point>
@@ -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;

View File

@@ -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<ColorPosition> LightPointList;
typedef std::vector<ColorPosition> LightPointList;
typedef std::vector<LightPointList> SizedLightPointList;
SizedLightPointList _sizedLightPointList;
SizedLightPointList _sizedOpaqueLightPointList;
SizedLightPointList _sizedAdditiveLightPointList;
SizedLightPointList _sizedBlendedLightPointList;
osg::ref_ptr<osg::Depth> _depthOff;
osg::ref_ptr<osg::Depth> _depthOn;
osg::ref_ptr<osg::BlendFunc> _blendOn;
osg::ref_ptr<osg::BlendFunc> _blendOne;
osg::ref_ptr<osg::BlendFunc> _blendOneMinusSrcAlpha;
osg::ref_ptr<osg::ColorMask> _colorMaskOff;
osg::ref_ptr<osg::Point> _point;

View File

@@ -7,7 +7,8 @@
// for further information contact robert@openscenegraph.com.
#include <osgSim/LightPointNode>
#include <osgSim/LightPointDrawable>
#include "LightPointDrawable.h"
#include <osg/Timer>
#include <osg/BoundingBox>
@@ -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 (pixelSize<lp._maxPixelSize)
{
@@ -276,18 +278,17 @@ void LightPointNode::traverse(osg::NodeVisitor& nv)
unsigned int lowerBoundPixelSize = (unsigned int)pixelSize;
//float remainder = pixelSize-(float)lowerBoundPixelSize;
float remainder = osg::square(pixelSize-(float)lowerBoundPixelSize);
osg::Vec3 xpos = position*matrix;
float alpha = color[3];
color[3] = alpha*(1.0f-remainder);
drawable->addLightPoint(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);
}
}