Updates to the light points support to improve the control of the blending of
light points with their background.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
118
src/osgSim/LightPointDrawable.h
Normal file
118
src/osgSim/LightPointDrawable.h
Normal file
@@ -0,0 +1,118 @@
|
||||
//C++ header - Open Scene Graph Simulation - Copyright (C) 1998-2002 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_LIGHTPOINTDRAWABLE
|
||||
#define OSGSIM_LIGHTPOINTDRAWABLE 1
|
||||
|
||||
#include <osgSim/Export>
|
||||
|
||||
#include <osg/Drawable>
|
||||
#include <osg/Vec3>
|
||||
#include <osg/Vec4>
|
||||
#include <osg/Depth>
|
||||
#include <osg/BlendFunc>
|
||||
#include <osg/ColorMask>
|
||||
#include <osg/Point>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace osgSim {
|
||||
|
||||
|
||||
class OSGSIM_EXPORT LightPointDrawable : public osg::Drawable
|
||||
{
|
||||
public :
|
||||
|
||||
LightPointDrawable();
|
||||
|
||||
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
|
||||
LightPointDrawable(const LightPointDrawable&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
virtual osg::Object* cloneType() const { return osgNew LightPointDrawable(); }
|
||||
virtual osg::Object* clone(const osg::CopyOp&) const { return osgNew LightPointDrawable(); }
|
||||
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const LightPointDrawable*>(obj)!=NULL; }
|
||||
virtual const char* className() const { return "LightPointDrawable"; }
|
||||
|
||||
|
||||
//typedef std::pair<unsigned long,osg::Vec3> ColorPosition;
|
||||
struct ColorPosition
|
||||
{
|
||||
unsigned long first;
|
||||
osg::Vec3 second;
|
||||
ColorPosition() {}
|
||||
ColorPosition(unsigned long f,const osg::Vec3& s):first(f),second(s) {}
|
||||
};
|
||||
|
||||
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 addAdditiveLightPoint(unsigned int pointSize,const osg::Vec3& position,const osg::Vec4& color)
|
||||
{
|
||||
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. */
|
||||
virtual void drawImplementation(osg::State& state) const;
|
||||
|
||||
|
||||
void setReferenceTime(double time)
|
||||
{
|
||||
_referenceTime = time;
|
||||
_referenceTimeInterval = 0.0;
|
||||
}
|
||||
|
||||
void updateReferenceTime(double time)
|
||||
{
|
||||
_referenceTimeInterval = osg::clampAbove(time-_referenceTime,0.0);
|
||||
_referenceTime = time;
|
||||
}
|
||||
|
||||
double getReferenceTime() const { return _referenceTime; }
|
||||
double getReferenceTimeInterval() const { return _referenceTimeInterval; }
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool computeBound() const;
|
||||
|
||||
~LightPointDrawable() {}
|
||||
|
||||
double _referenceTime;
|
||||
double _referenceTimeInterval;
|
||||
|
||||
typedef std::vector<ColorPosition> LightPointList;
|
||||
typedef std::vector<LightPointList> SizedLightPointList;
|
||||
|
||||
SizedLightPointList _sizedOpaqueLightPointList;
|
||||
SizedLightPointList _sizedAdditiveLightPointList;
|
||||
SizedLightPointList _sizedBlendedLightPointList;
|
||||
|
||||
osg::ref_ptr<osg::Depth> _depthOff;
|
||||
osg::ref_ptr<osg::Depth> _depthOn;
|
||||
osg::ref_ptr<osg::BlendFunc> _blendOne;
|
||||
osg::ref_ptr<osg::BlendFunc> _blendOneMinusSrcAlpha;
|
||||
osg::ref_ptr<osg::ColorMask> _colorMaskOff;
|
||||
osg::ref_ptr<osg::Point> _point;
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user