Fix cloud layer - point lights visibility issue
Move point lights to render bin 8, clouds to render bin 9. Turn on AlphaFunc for cloud layers. Create a StateAttributeFactory object to create and share common state objects.
This commit is contained in:
+17
-29
@@ -45,6 +45,8 @@
|
|||||||
#include <simgear/misc/PathOptions.hxx>
|
#include <simgear/misc/PathOptions.hxx>
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
#include <simgear/scene/model/model.hxx>
|
#include <simgear/scene/model/model.hxx>
|
||||||
|
#include <simgear/scene/util/RenderConstants.hxx>
|
||||||
|
#include <simgear/scene/util/StateAttributeFactory.hxx>
|
||||||
#include <simgear/math/polar3d.hxx>
|
#include <simgear/math/polar3d.hxx>
|
||||||
|
|
||||||
#include "newcloud.hxx"
|
#include "newcloud.hxx"
|
||||||
@@ -88,31 +90,13 @@ SGMakeState(const SGPath &path, const char* colorTexture,
|
|||||||
stateSet->setTextureAttribute(0, SGLoadTexture2D(colorTexture,
|
stateSet->setTextureAttribute(0, SGLoadTexture2D(colorTexture,
|
||||||
options.get()));
|
options.get()));
|
||||||
stateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON);
|
stateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON);
|
||||||
|
StateAttributeFactory* attribFactory = StateAttributeFactory::instance();
|
||||||
osg::TexEnv* texEnv = new osg::TexEnv;
|
stateSet->setTextureAttribute(0, attribFactory->getStandardTexEnv());
|
||||||
texEnv->setMode(osg::TexEnv::MODULATE);
|
stateSet->setAttributeAndModes(attribFactory->getSmoothShadeModel());
|
||||||
stateSet->setTextureAttribute(0, texEnv);
|
|
||||||
|
|
||||||
osg::ShadeModel* shadeModel = new osg::ShadeModel;
|
|
||||||
// FIXME: TRUE??
|
|
||||||
shadeModel->setMode(osg::ShadeModel::SMOOTH);
|
|
||||||
stateSet->setAttributeAndModes(shadeModel);
|
|
||||||
|
|
||||||
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||||
stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
|
stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
|
||||||
|
stateSet->setAttributeAndModes(attribFactory->getStandardAlphaFunc());
|
||||||
// osg::AlphaFunc* alphaFunc = new osg::AlphaFunc;
|
stateSet->setAttributeAndModes(attribFactory->getStandardBlendFunc());
|
||||||
// alphaFunc->setFunction(osg::AlphaFunc::GREATER);
|
|
||||||
// alphaFunc->setReferenceValue(0.01);
|
|
||||||
// stateSet->setAttribute(alphaFunc);
|
|
||||||
// stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON);
|
|
||||||
stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::OFF);
|
|
||||||
|
|
||||||
osg::BlendFunc* blendFunc = new osg::BlendFunc;
|
|
||||||
blendFunc->setSource(osg::BlendFunc::SRC_ALPHA);
|
|
||||||
blendFunc->setDestination(osg::BlendFunc::ONE_MINUS_SRC_ALPHA);
|
|
||||||
stateSet->setAttribute(blendFunc);
|
|
||||||
stateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
|
|
||||||
|
|
||||||
// osg::Material* material = new osg::Material;
|
// osg::Material* material = new osg::Material;
|
||||||
// material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
|
// material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
|
||||||
@@ -160,11 +144,15 @@ SGCloudLayer::SGCloudLayer( const string &tex_path ) :
|
|||||||
last_lon(0.0),
|
last_lon(0.0),
|
||||||
last_lat(0.0)
|
last_lat(0.0)
|
||||||
{
|
{
|
||||||
|
// XXX
|
||||||
|
// Render bottoms before the rest of transparent objects (rendered
|
||||||
|
// in bin 10), tops after. The negative numbers on the bottoms
|
||||||
|
// RenderBins and the positive numbers on the tops enforce this
|
||||||
|
// order.
|
||||||
layer_root->addChild(group_bottom.get());
|
layer_root->addChild(group_bottom.get());
|
||||||
layer_root->addChild(group_top.get());
|
layer_root->addChild(group_top.get());
|
||||||
// Force the cloud layers into recursive bins of bin 4.
|
|
||||||
osg::StateSet *rootSet = layer_root->getOrCreateStateSet();
|
osg::StateSet *rootSet = layer_root->getOrCreateStateSet();
|
||||||
rootSet->setRenderBinDetails(4, "RenderBin");
|
rootSet->setRenderBinDetails(CLOUDS_BIN, "DepthSortedBin");
|
||||||
rootSet->setTextureAttribute(0, new osg::TexMat());
|
rootSet->setTextureAttribute(0, new osg::TexMat());
|
||||||
base = osg::Vec2(sg_random(), sg_random());
|
base = osg::Vec2(sg_random(), sg_random());
|
||||||
|
|
||||||
@@ -869,10 +857,10 @@ bool SGCloudLayer::reposition( const SGVec3f& p, const SGVec3f& up, double lon,
|
|||||||
// bottom polys should be drawn from high altitude to low, and the
|
// bottom polys should be drawn from high altitude to low, and the
|
||||||
// top polygons from low to high. The altitude can be used
|
// top polygons from low to high. The altitude can be used
|
||||||
// directly to order the polygons!
|
// directly to order the polygons!
|
||||||
layer_root->getChild(0)->getStateSet()->setRenderBinDetails(-(int)layer_asl,
|
group_bottom->getStateSet()->setRenderBinDetails(-(int)layer_asl,
|
||||||
"RenderBin");
|
"RenderBin");
|
||||||
layer_root->getChild(1)->getStateSet()->setRenderBinDetails((int)layer_asl,
|
group_top->getStateSet()->setRenderBinDetails((int)layer_asl,
|
||||||
"RenderBin");
|
"RenderBin");
|
||||||
if ( alt <= layer_asl ) {
|
if ( alt <= layer_asl ) {
|
||||||
layer_root->setSingleChildOn(0);
|
layer_root->setSingleChildOn(0);
|
||||||
} else if ( alt >= layer_asl + layer_thickness ) {
|
} else if ( alt >= layer_asl + layer_thickness ) {
|
||||||
|
|||||||
@@ -54,10 +54,13 @@
|
|||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
#include <simgear/threads/SGThread.hxx>
|
#include <simgear/threads/SGThread.hxx>
|
||||||
#include <simgear/threads/SGGuard.hxx>
|
#include <simgear/threads/SGGuard.hxx>
|
||||||
|
#include <simgear/scene/util/RenderConstants.hxx>
|
||||||
#include <simgear/scene/util/SGEnlargeBoundingBox.hxx>
|
#include <simgear/scene/util/SGEnlargeBoundingBox.hxx>
|
||||||
|
|
||||||
#include "SGVasiDrawable.hxx"
|
#include "SGVasiDrawable.hxx"
|
||||||
|
|
||||||
|
using namespace simgear;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setPointSpriteImage(unsigned char* data, unsigned log2resolution,
|
setPointSpriteImage(unsigned char* data, unsigned log2resolution,
|
||||||
unsigned charsPerPixel)
|
unsigned charsPerPixel)
|
||||||
@@ -238,7 +241,7 @@ SGLightFactory::getLight(const SGLightBin::Light& light)
|
|||||||
geometry->addPrimitiveSet(drawArrays);
|
geometry->addPrimitiveSet(drawArrays);
|
||||||
|
|
||||||
osg::StateSet* stateSet = geometry->getOrCreateStateSet();
|
osg::StateSet* stateSet = geometry->getOrCreateStateSet();
|
||||||
stateSet->setRenderBinDetails(9, "DepthSortedBin");
|
stateSet->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin");
|
||||||
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||||
|
|
||||||
osg::BlendFunc* blendFunc = new osg::BlendFunc;
|
osg::BlendFunc* blendFunc = new osg::BlendFunc;
|
||||||
@@ -291,7 +294,7 @@ SGLightFactory::getLight(const SGDirectionalLightBin::Light& light)
|
|||||||
geometry->addPrimitiveSet(drawArrays);
|
geometry->addPrimitiveSet(drawArrays);
|
||||||
|
|
||||||
osg::StateSet* stateSet = geometry->getOrCreateStateSet();
|
osg::StateSet* stateSet = geometry->getOrCreateStateSet();
|
||||||
stateSet->setRenderBinDetails(9, "DepthSortedBin");
|
stateSet->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin");
|
||||||
|
|
||||||
osg::Material* material = new osg::Material;
|
osg::Material* material = new osg::Material;
|
||||||
material->setColorMode(osg::Material::OFF);
|
material->setColorMode(osg::Material::OFF);
|
||||||
@@ -352,7 +355,7 @@ SGLightFactory::getLights(const SGLightBin& lights, unsigned inc, float alphaOff
|
|||||||
geometry->addPrimitiveSet(drawArrays);
|
geometry->addPrimitiveSet(drawArrays);
|
||||||
|
|
||||||
osg::StateSet* stateSet = geometry->getOrCreateStateSet();
|
osg::StateSet* stateSet = geometry->getOrCreateStateSet();
|
||||||
stateSet->setRenderBinDetails(9, "DepthSortedBin");
|
stateSet->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin");
|
||||||
|
|
||||||
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||||
|
|
||||||
@@ -407,7 +410,7 @@ SGLightFactory::getLights(const SGDirectionalLightBin& lights)
|
|||||||
geometry->addPrimitiveSet(drawArrays);
|
geometry->addPrimitiveSet(drawArrays);
|
||||||
|
|
||||||
osg::StateSet* stateSet = geometry->getOrCreateStateSet();
|
osg::StateSet* stateSet = geometry->getOrCreateStateSet();
|
||||||
stateSet->setRenderBinDetails(9, "DepthSortedBin");
|
stateSet->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin");
|
||||||
|
|
||||||
osg::Material* material = new osg::Material;
|
osg::Material* material = new osg::Material;
|
||||||
material->setColorMode(osg::Material::OFF);
|
material->setColorMode(osg::Material::OFF);
|
||||||
@@ -489,7 +492,7 @@ SGLightFactory::getVasi(const SGVec3f& up, const SGDirectionalLightBin& lights,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
osg::StateSet* stateSet = drawable->getOrCreateStateSet();
|
osg::StateSet* stateSet = drawable->getOrCreateStateSet();
|
||||||
stateSet->setRenderBinDetails(9, "DepthSortedBin");
|
stateSet->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin");
|
||||||
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||||
|
|
||||||
osg::BlendFunc* blendFunc = new osg::BlendFunc;
|
osg::BlendFunc* blendFunc = new osg::BlendFunc;
|
||||||
@@ -525,7 +528,7 @@ SGLightFactory::getSequenced(const SGDirectionalLightBin& lights)
|
|||||||
sequence->setSync(true);
|
sequence->setSync(true);
|
||||||
|
|
||||||
osg::StateSet* stateSet = sequence->getOrCreateStateSet();
|
osg::StateSet* stateSet = sequence->getOrCreateStateSet();
|
||||||
stateSet->setRenderBinDetails(9, "DepthSortedBin");
|
stateSet->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin");
|
||||||
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||||
|
|
||||||
osg::BlendFunc* blendFunc = new osg::BlendFunc;
|
osg::BlendFunc* blendFunc = new osg::BlendFunc;
|
||||||
@@ -577,7 +580,7 @@ SGLightFactory::getOdal(const SGLightBin& lights)
|
|||||||
sequence->setSync(true);
|
sequence->setSync(true);
|
||||||
|
|
||||||
osg::StateSet* stateSet = sequence->getOrCreateStateSet();
|
osg::StateSet* stateSet = sequence->getOrCreateStateSet();
|
||||||
stateSet->setRenderBinDetails(9, "DepthSortedBin");
|
stateSet->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin");
|
||||||
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||||
|
|
||||||
osg::BlendFunc* blendFunc = new osg::BlendFunc;
|
osg::BlendFunc* blendFunc = new osg::BlendFunc;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ include_HEADERS = \
|
|||||||
SGStateAttributeVisitor.hxx \
|
SGStateAttributeVisitor.hxx \
|
||||||
SGTextureStateAttributeVisitor.hxx \
|
SGTextureStateAttributeVisitor.hxx \
|
||||||
RenderConstants.hxx \
|
RenderConstants.hxx \
|
||||||
|
StateAttributeFactory.hxx \
|
||||||
VectorArrayAdapter.hxx
|
VectorArrayAdapter.hxx
|
||||||
|
|
||||||
|
|
||||||
@@ -23,6 +24,7 @@ libsgutil_a_SOURCES = \
|
|||||||
SGSceneFeatures.cxx \
|
SGSceneFeatures.cxx \
|
||||||
SGSceneUserData.cxx \
|
SGSceneUserData.cxx \
|
||||||
SGStateAttributeVisitor.cxx \
|
SGStateAttributeVisitor.cxx \
|
||||||
SGTextureStateAttributeVisitor.cxx
|
SGTextureStateAttributeVisitor.cxx \
|
||||||
|
StateAttributeFactory.cxx
|
||||||
|
|
||||||
INCLUDES = -I$(top_srcdir)
|
INCLUDES = -I$(top_srcdir)
|
||||||
|
|||||||
@@ -40,5 +40,26 @@ enum NodeMask {
|
|||||||
LIGHTS_BITS = (GROUNDLIGHTS0_BIT | GROUNDLIGHTS1_BIT | GROUNDLIGHTS2_BIT
|
LIGHTS_BITS = (GROUNDLIGHTS0_BIT | GROUNDLIGHTS1_BIT | GROUNDLIGHTS2_BIT
|
||||||
| RUNWAYLIGHTS_BIT)
|
| RUNWAYLIGHTS_BIT)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Theory of bin numbering:
|
||||||
|
//
|
||||||
|
// Normal opaque objects are assigned bin 0.
|
||||||
|
//
|
||||||
|
// Point lights blend with the terrain to simulate attenuation but
|
||||||
|
// should completely obscure any transparent geometry behind
|
||||||
|
// them. Also, they should be visible through semi-transparent cloud
|
||||||
|
// layers, so they are rendered before the cloud layers.
|
||||||
|
//
|
||||||
|
// Clouds layers can't be depth sorted because they are too big, so
|
||||||
|
// they are rendered before other transparent objects. The layer
|
||||||
|
// partial ordering is handled in the clouds code.
|
||||||
|
//
|
||||||
|
// OSG and its file loaders throw all transparent objects into bin 10.
|
||||||
|
|
||||||
|
enum RenderBin {
|
||||||
|
POINT_LIGHTS_BIN = 8,
|
||||||
|
CLOUDS_BIN = 9,
|
||||||
|
TRANSPARENT_BIN = 10 // assigned by OSG
|
||||||
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#include <OpenThreads/ScopedLock>
|
||||||
|
|
||||||
|
#include "StateAttributeFactory.hxx"
|
||||||
|
|
||||||
|
using namespace osg;
|
||||||
|
|
||||||
|
namespace simgear
|
||||||
|
{
|
||||||
|
StateAttributeFactory::StateAttributeFactory()
|
||||||
|
{
|
||||||
|
_standardAlphaFunc = new AlphaFunc;
|
||||||
|
_standardAlphaFunc->setFunction(osg::AlphaFunc::GREATER);
|
||||||
|
_standardAlphaFunc->setReferenceValue(0.01);
|
||||||
|
_standardAlphaFunc->setDataVariance(Object::STATIC);
|
||||||
|
_smooth = new ShadeModel;
|
||||||
|
_smooth->setMode(ShadeModel::SMOOTH);
|
||||||
|
_smooth->setDataVariance(Object::STATIC);
|
||||||
|
_flat = new ShadeModel(ShadeModel::FLAT);
|
||||||
|
_flat->setDataVariance(Object::STATIC);
|
||||||
|
_standardBlendFunc = new BlendFunc;
|
||||||
|
_standardBlendFunc->setSource(BlendFunc::SRC_ALPHA);
|
||||||
|
_standardBlendFunc->setDestination(BlendFunc::ONE_MINUS_SRC_ALPHA);
|
||||||
|
_standardBlendFunc->setDataVariance(Object::STATIC);
|
||||||
|
_standardTexEnv = new TexEnv;
|
||||||
|
_standardTexEnv->setMode(TexEnv::MODULATE);
|
||||||
|
_standardTexEnv->setDataVariance(Object::STATIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::ref_ptr<StateAttributeFactory> StateAttributeFactory::_theInstance;
|
||||||
|
OpenThreads::Mutex StateAttributeFactory::_instanceMutex;
|
||||||
|
|
||||||
|
StateAttributeFactory* StateAttributeFactory::instance()
|
||||||
|
{
|
||||||
|
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_instanceMutex);
|
||||||
|
if (!_theInstance.valid()) {
|
||||||
|
_theInstance = new StateAttributeFactory;
|
||||||
|
}
|
||||||
|
return _theInstance.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef SIMGEAR_STATEATTRIBUTEFACTORY_HXX
|
||||||
|
#define SIMGEAR_STATEATTRIBUTEFACTORY_HXX 1
|
||||||
|
|
||||||
|
#include <OpenThreads/Mutex>
|
||||||
|
#include <osg/ref_ptr>
|
||||||
|
#include <osg/AlphaFunc>
|
||||||
|
#include <osg/BlendFunc>
|
||||||
|
#include <osg/ShadeModel>
|
||||||
|
#include <osg/TexEnv>
|
||||||
|
|
||||||
|
// Return read-only instances of common OSG state attributes.
|
||||||
|
namespace simgear
|
||||||
|
{
|
||||||
|
class StateAttributeFactory : public osg::Referenced {
|
||||||
|
public:
|
||||||
|
// Alpha test > .01
|
||||||
|
osg::AlphaFunc* getStandardAlphaFunc() { return _standardAlphaFunc.get(); }
|
||||||
|
// alpha source, 1 - alpha destination
|
||||||
|
osg::BlendFunc* getStandardBlendFunc() { return _standardBlendFunc.get(); }
|
||||||
|
// modulate
|
||||||
|
osg::TexEnv* getStandardTexEnv() { return _standardTexEnv.get(); }
|
||||||
|
osg::ShadeModel* getSmoothShadeModel() { return _smooth.get(); }
|
||||||
|
osg::ShadeModel* getFlatShadeModel() { return _flat.get(); }
|
||||||
|
static StateAttributeFactory* instance();
|
||||||
|
protected:
|
||||||
|
StateAttributeFactory();
|
||||||
|
osg::ref_ptr<osg::AlphaFunc> _standardAlphaFunc;
|
||||||
|
osg::ref_ptr<osg::ShadeModel> _smooth;
|
||||||
|
osg::ref_ptr<osg::ShadeModel> _flat;
|
||||||
|
osg::ref_ptr<osg::BlendFunc> _standardBlendFunc;
|
||||||
|
osg::ref_ptr<osg::TexEnv> _standardTexEnv;
|
||||||
|
static osg::ref_ptr<StateAttributeFactory> _theInstance;
|
||||||
|
static OpenThreads::Mutex _instanceMutex;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user