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:
@@ -45,6 +45,8 @@
|
||||
#include <simgear/misc/PathOptions.hxx>
|
||||
#include <simgear/debug/logstream.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 "newcloud.hxx"
|
||||
@@ -88,31 +90,13 @@ SGMakeState(const SGPath &path, const char* colorTexture,
|
||||
stateSet->setTextureAttribute(0, SGLoadTexture2D(colorTexture,
|
||||
options.get()));
|
||||
stateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON);
|
||||
|
||||
osg::TexEnv* texEnv = new osg::TexEnv;
|
||||
texEnv->setMode(osg::TexEnv::MODULATE);
|
||||
stateSet->setTextureAttribute(0, texEnv);
|
||||
|
||||
osg::ShadeModel* shadeModel = new osg::ShadeModel;
|
||||
// FIXME: TRUE??
|
||||
shadeModel->setMode(osg::ShadeModel::SMOOTH);
|
||||
stateSet->setAttributeAndModes(shadeModel);
|
||||
|
||||
StateAttributeFactory* attribFactory = StateAttributeFactory::instance();
|
||||
stateSet->setTextureAttribute(0, attribFactory->getStandardTexEnv());
|
||||
stateSet->setAttributeAndModes(attribFactory->getSmoothShadeModel());
|
||||
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||
stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
|
||||
|
||||
// osg::AlphaFunc* alphaFunc = new osg::AlphaFunc;
|
||||
// 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);
|
||||
stateSet->setAttributeAndModes(attribFactory->getStandardAlphaFunc());
|
||||
stateSet->setAttributeAndModes(attribFactory->getStandardBlendFunc());
|
||||
|
||||
// osg::Material* material = new osg::Material;
|
||||
// material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
|
||||
@@ -160,11 +144,15 @@ SGCloudLayer::SGCloudLayer( const string &tex_path ) :
|
||||
last_lon(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_top.get());
|
||||
// Force the cloud layers into recursive bins of bin 4.
|
||||
osg::StateSet *rootSet = layer_root->getOrCreateStateSet();
|
||||
rootSet->setRenderBinDetails(4, "RenderBin");
|
||||
rootSet->setRenderBinDetails(CLOUDS_BIN, "DepthSortedBin");
|
||||
rootSet->setTextureAttribute(0, new osg::TexMat());
|
||||
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
|
||||
// top polygons from low to high. The altitude can be used
|
||||
// directly to order the polygons!
|
||||
layer_root->getChild(0)->getStateSet()->setRenderBinDetails(-(int)layer_asl,
|
||||
"RenderBin");
|
||||
layer_root->getChild(1)->getStateSet()->setRenderBinDetails((int)layer_asl,
|
||||
"RenderBin");
|
||||
group_bottom->getStateSet()->setRenderBinDetails(-(int)layer_asl,
|
||||
"RenderBin");
|
||||
group_top->getStateSet()->setRenderBinDetails((int)layer_asl,
|
||||
"RenderBin");
|
||||
if ( alt <= layer_asl ) {
|
||||
layer_root->setSingleChildOn(0);
|
||||
} else if ( alt >= layer_asl + layer_thickness ) {
|
||||
|
||||
@@ -54,10 +54,13 @@
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/threads/SGThread.hxx>
|
||||
#include <simgear/threads/SGGuard.hxx>
|
||||
#include <simgear/scene/util/RenderConstants.hxx>
|
||||
#include <simgear/scene/util/SGEnlargeBoundingBox.hxx>
|
||||
|
||||
#include "SGVasiDrawable.hxx"
|
||||
|
||||
using namespace simgear;
|
||||
|
||||
static void
|
||||
setPointSpriteImage(unsigned char* data, unsigned log2resolution,
|
||||
unsigned charsPerPixel)
|
||||
@@ -238,7 +241,7 @@ SGLightFactory::getLight(const SGLightBin::Light& light)
|
||||
geometry->addPrimitiveSet(drawArrays);
|
||||
|
||||
osg::StateSet* stateSet = geometry->getOrCreateStateSet();
|
||||
stateSet->setRenderBinDetails(9, "DepthSortedBin");
|
||||
stateSet->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin");
|
||||
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||
|
||||
osg::BlendFunc* blendFunc = new osg::BlendFunc;
|
||||
@@ -291,7 +294,7 @@ SGLightFactory::getLight(const SGDirectionalLightBin::Light& light)
|
||||
geometry->addPrimitiveSet(drawArrays);
|
||||
|
||||
osg::StateSet* stateSet = geometry->getOrCreateStateSet();
|
||||
stateSet->setRenderBinDetails(9, "DepthSortedBin");
|
||||
stateSet->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin");
|
||||
|
||||
osg::Material* material = new osg::Material;
|
||||
material->setColorMode(osg::Material::OFF);
|
||||
@@ -352,7 +355,7 @@ SGLightFactory::getLights(const SGLightBin& lights, unsigned inc, float alphaOff
|
||||
geometry->addPrimitiveSet(drawArrays);
|
||||
|
||||
osg::StateSet* stateSet = geometry->getOrCreateStateSet();
|
||||
stateSet->setRenderBinDetails(9, "DepthSortedBin");
|
||||
stateSet->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin");
|
||||
|
||||
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||
|
||||
@@ -407,7 +410,7 @@ SGLightFactory::getLights(const SGDirectionalLightBin& lights)
|
||||
geometry->addPrimitiveSet(drawArrays);
|
||||
|
||||
osg::StateSet* stateSet = geometry->getOrCreateStateSet();
|
||||
stateSet->setRenderBinDetails(9, "DepthSortedBin");
|
||||
stateSet->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin");
|
||||
|
||||
osg::Material* material = new osg::Material;
|
||||
material->setColorMode(osg::Material::OFF);
|
||||
@@ -489,7 +492,7 @@ SGLightFactory::getVasi(const SGVec3f& up, const SGDirectionalLightBin& lights,
|
||||
return 0;
|
||||
|
||||
osg::StateSet* stateSet = drawable->getOrCreateStateSet();
|
||||
stateSet->setRenderBinDetails(9, "DepthSortedBin");
|
||||
stateSet->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin");
|
||||
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||
|
||||
osg::BlendFunc* blendFunc = new osg::BlendFunc;
|
||||
@@ -525,7 +528,7 @@ SGLightFactory::getSequenced(const SGDirectionalLightBin& lights)
|
||||
sequence->setSync(true);
|
||||
|
||||
osg::StateSet* stateSet = sequence->getOrCreateStateSet();
|
||||
stateSet->setRenderBinDetails(9, "DepthSortedBin");
|
||||
stateSet->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin");
|
||||
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||
|
||||
osg::BlendFunc* blendFunc = new osg::BlendFunc;
|
||||
@@ -577,7 +580,7 @@ SGLightFactory::getOdal(const SGLightBin& lights)
|
||||
sequence->setSync(true);
|
||||
|
||||
osg::StateSet* stateSet = sequence->getOrCreateStateSet();
|
||||
stateSet->setRenderBinDetails(9, "DepthSortedBin");
|
||||
stateSet->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin");
|
||||
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||
|
||||
osg::BlendFunc* blendFunc = new osg::BlendFunc;
|
||||
|
||||
@@ -15,6 +15,7 @@ include_HEADERS = \
|
||||
SGStateAttributeVisitor.hxx \
|
||||
SGTextureStateAttributeVisitor.hxx \
|
||||
RenderConstants.hxx \
|
||||
StateAttributeFactory.hxx \
|
||||
VectorArrayAdapter.hxx
|
||||
|
||||
|
||||
@@ -23,6 +24,7 @@ libsgutil_a_SOURCES = \
|
||||
SGSceneFeatures.cxx \
|
||||
SGSceneUserData.cxx \
|
||||
SGStateAttributeVisitor.cxx \
|
||||
SGTextureStateAttributeVisitor.cxx
|
||||
SGTextureStateAttributeVisitor.cxx \
|
||||
StateAttributeFactory.cxx
|
||||
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
|
||||
@@ -40,5 +40,26 @@ enum NodeMask {
|
||||
LIGHTS_BITS = (GROUNDLIGHTS0_BIT | GROUNDLIGHTS1_BIT | GROUNDLIGHTS2_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
|
||||
|
||||
40
simgear/scene/util/StateAttributeFactory.cxx
Normal file
40
simgear/scene/util/StateAttributeFactory.cxx
Normal file
@@ -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();
|
||||
}
|
||||
}
|
||||
36
simgear/scene/util/StateAttributeFactory.hxx
Normal file
36
simgear/scene/util/StateAttributeFactory.hxx
Normal file
@@ -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