#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"
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);
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());
// 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 ) {
#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)
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;
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);
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);
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);
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;
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;
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;
SGStateAttributeVisitor.hxx \
SGTextureStateAttributeVisitor.hxx \
RenderConstants.hxx \
+ StateAttributeFactory.hxx \
VectorArrayAdapter.hxx
SGSceneFeatures.cxx \
SGSceneUserData.cxx \
SGStateAttributeVisitor.cxx \
- SGTextureStateAttributeVisitor.cxx
+ SGTextureStateAttributeVisitor.cxx \
+ StateAttributeFactory.cxx
INCLUDES = -I$(top_srcdir)
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
--- /dev/null
+#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();
+}
+}
--- /dev/null
+#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