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:
timoore
2007-12-21 06:24:53 +00:00
parent 182ee9d7e4
commit 4324ffccf4
6 changed files with 127 additions and 37 deletions

View File

@@ -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 ) {

View File

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

View File

@@ -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)

View File

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

View 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();
}
}

View 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