Fix directional lights for AMD
Some AMD drivers do not like triangles for point sprites, which breaks directional lights. This works around this by allowing users to set /rendering/triangle-directional-lights=false which falls back to the non-directional implementation of a point.
This commit is contained in:
parent
65a20b5829
commit
f6285bc528
4 changed files with 81 additions and 78 deletions
|
@ -414,6 +414,7 @@ FGRenderer::init( void )
|
||||||
_splash_alpha = fgGetNode("/sim/startup/splash-alpha", true);
|
_splash_alpha = fgGetNode("/sim/startup/splash-alpha", true);
|
||||||
|
|
||||||
_point_sprites = fgGetNode("/sim/rendering/point-sprites", true);
|
_point_sprites = fgGetNode("/sim/rendering/point-sprites", true);
|
||||||
|
_triangle_directional_lights = fgGetNode("/sim/rendering/triangle-directional-lights", true);
|
||||||
_distance_attenuation = fgGetNode("/sim/rendering/distance-attenuation", true);
|
_distance_attenuation = fgGetNode("/sim/rendering/distance-attenuation", true);
|
||||||
_horizon_effect = fgGetNode("/sim/rendering/horizon-effect", true);
|
_horizon_effect = fgGetNode("/sim/rendering/horizon-effect", true);
|
||||||
|
|
||||||
|
@ -424,8 +425,9 @@ FGRenderer::init( void )
|
||||||
|
|
||||||
bool use_point_sprites = _point_sprites->getBoolValue();
|
bool use_point_sprites = _point_sprites->getBoolValue();
|
||||||
bool distance_attenuation = _distance_attenuation->getBoolValue();
|
bool distance_attenuation = _distance_attenuation->getBoolValue();
|
||||||
|
bool triangles = _triangle_directional_lights->getBoolValue();
|
||||||
|
|
||||||
SGConfigureDirectionalLights( use_point_sprites, distance_attenuation );
|
SGConfigureDirectionalLights( use_point_sprites, distance_attenuation, triangles );
|
||||||
|
|
||||||
if (const char* tc = fgGetString("/sim/rendering/texture-compression", NULL)) {
|
if (const char* tc = fgGetString("/sim/rendering/texture-compression", NULL)) {
|
||||||
if (strcmp(tc, "false") == 0 || strcmp(tc, "off") == 0 ||
|
if (strcmp(tc, "false") == 0 || strcmp(tc, "off") == 0 ||
|
||||||
|
@ -657,7 +659,7 @@ FGRenderer::update( ) {
|
||||||
|
|
||||||
GLint max_texture_size;
|
GLint max_texture_size;
|
||||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
|
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
|
||||||
// abritrary range change as sometimes during init the device reports somewhat dubious values, so
|
// abritrary range change as sometimes during init the device reports somewhat dubious values, so
|
||||||
// we know that the size must be greater than size and that probably 9999999 is unreasonably large
|
// we know that the size must be greater than size and that probably 9999999 is unreasonably large
|
||||||
if (max_texture_size > 0 && max_texture_size < 9999999)
|
if (max_texture_size > 0 && max_texture_size < 9999999)
|
||||||
SGSceneFeatures::instance()->setMaxTextureSize(max_texture_size);
|
SGSceneFeatures::instance()->setMaxTextureSize(max_texture_size);
|
||||||
|
|
|
@ -95,7 +95,7 @@ protected:
|
||||||
SGPropertyNode_ptr _scenery_loaded, _position_finalized;
|
SGPropertyNode_ptr _scenery_loaded, _position_finalized;
|
||||||
|
|
||||||
SGPropertyNode_ptr _splash_alpha;
|
SGPropertyNode_ptr _splash_alpha;
|
||||||
SGPropertyNode_ptr _point_sprites, _enhanced_lighting, _distance_attenuation;
|
SGPropertyNode_ptr _point_sprites, _enhanced_lighting, _distance_attenuation, _triangle_directional_lights;
|
||||||
SGPropertyNode_ptr _textures;
|
SGPropertyNode_ptr _textures;
|
||||||
SGPropertyNode_ptr _cloud_status, _visibility_m;
|
SGPropertyNode_ptr _cloud_status, _visibility_m;
|
||||||
SGPropertyNode_ptr _xsize, _ysize;
|
SGPropertyNode_ptr _xsize, _ysize;
|
||||||
|
|
|
@ -179,26 +179,26 @@ public:
|
||||||
|
|
||||||
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
||||||
glPushClientAttrib(~0u);
|
glPushClientAttrib(~0u);
|
||||||
|
|
||||||
// HUD can be NULL
|
// HUD can be NULL
|
||||||
HUD *hud = static_cast<HUD*>(globals->get_subsystem("hud"));
|
HUD *hud = static_cast<HUD*>(globals->get_subsystem("hud"));
|
||||||
if (hud) {
|
if (hud) {
|
||||||
hud->draw(state);
|
hud->draw(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
glPopClientAttrib();
|
glPopClientAttrib();
|
||||||
glPopAttrib();
|
glPopAttrib();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual osg::Object* cloneType() const { return new SGHUDDrawable; }
|
virtual osg::Object* cloneType() const { return new SGHUDDrawable; }
|
||||||
virtual osg::Object* clone(const osg::CopyOp&) const { return new SGHUDDrawable; }
|
virtual osg::Object* clone(const osg::CopyOp&) const { return new SGHUDDrawable; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|
||||||
class FGLightSourceUpdateCallback : public osg::NodeCallback {
|
class FGLightSourceUpdateCallback : public osg::NodeCallback {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param isSun true if the light is the actual sun i.e., for
|
* @param isSun true if the light is the actual sun i.e., for
|
||||||
* illuminating the moon.
|
* illuminating the moon.
|
||||||
|
@ -209,19 +209,19 @@ public:
|
||||||
: NodeCallback(nc, op), _isSun(nc._isSun)
|
: NodeCallback(nc, op), _isSun(nc._isSun)
|
||||||
{}
|
{}
|
||||||
META_Object(flightgear,FGLightSourceUpdateCallback);
|
META_Object(flightgear,FGLightSourceUpdateCallback);
|
||||||
|
|
||||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||||
{
|
{
|
||||||
assert(dynamic_cast<osg::LightSource*>(node));
|
assert(dynamic_cast<osg::LightSource*>(node));
|
||||||
osg::LightSource* lightSource = static_cast<osg::LightSource*>(node);
|
osg::LightSource* lightSource = static_cast<osg::LightSource*>(node);
|
||||||
osg::Light* light = lightSource->getLight();
|
osg::Light* light = lightSource->getLight();
|
||||||
|
|
||||||
FGLight *l = static_cast<FGLight*>(globals->get_subsystem("lighting"));
|
FGLight *l = static_cast<FGLight*>(globals->get_subsystem("lighting"));
|
||||||
if (!l) {
|
if (!l) {
|
||||||
// lighting is down during re-init
|
// lighting is down during re-init
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_isSun) {
|
if (_isSun) {
|
||||||
light->setAmbient(Vec4(0.0f, 0.0f, 0.0f, 0.0f));
|
light->setAmbient(Vec4(0.0f, 0.0f, 0.0f, 0.0f));
|
||||||
light->setDiffuse(Vec4(1.0f, 1.0f, 1.0f, 1.0f));
|
light->setDiffuse(Vec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
|
@ -364,12 +364,12 @@ FGRenderer::FGRenderer() :
|
||||||
_root->setName("fakeRoot");
|
_root->setName("fakeRoot");
|
||||||
|
|
||||||
_updateVisitor = new SGUpdateVisitor;
|
_updateVisitor = new SGUpdateVisitor;
|
||||||
|
|
||||||
// when Rembrandt is enabled, we use this group to access the whole
|
// when Rembrandt is enabled, we use this group to access the whole
|
||||||
// scene. Since the only child is the _viewerSceneRoot, we could
|
// scene. Since the only child is the _viewerSceneRoot, we could
|
||||||
// simply copy the reference, we don't need the additional group.
|
// simply copy the reference, we don't need the additional group.
|
||||||
_deferredRealRoot = new osg::Group;
|
_deferredRealRoot = new osg::Group;
|
||||||
|
|
||||||
_numCascades = 4;
|
_numCascades = 4;
|
||||||
_cascadeFar[0] = 5.f;
|
_cascadeFar[0] = 5.f;
|
||||||
_cascadeFar[1] = 50.f;
|
_cascadeFar[1] = 50.f;
|
||||||
|
@ -383,12 +383,12 @@ FGRenderer::~FGRenderer()
|
||||||
for (; i != _listeners.end(); ++i) {
|
for (; i != _listeners.end(); ++i) {
|
||||||
delete *i;
|
delete *i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// replace the viewer's scene completely
|
// replace the viewer's scene completely
|
||||||
if (getViewer()) {
|
if (getViewer()) {
|
||||||
getViewer()->setSceneData(new osg::Group);
|
getViewer()->setSceneData(new osg::Group);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete _sky;
|
delete _sky;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,7 +421,7 @@ FGRenderer::preinit( void )
|
||||||
camera->addChild(_splash);
|
camera->addChild(_splash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_frameStamp = new osg::FrameStamp;
|
_frameStamp = new osg::FrameStamp;
|
||||||
viewer->setFrameStamp(_frameStamp.get());
|
viewer->setFrameStamp(_frameStamp.get());
|
||||||
// Scene doesn't seem to pass the frame stamp to the update
|
// Scene doesn't seem to pass the frame stamp to the update
|
||||||
|
@ -429,7 +429,7 @@ FGRenderer::preinit( void )
|
||||||
_updateVisitor->setFrameStamp(_frameStamp.get());
|
_updateVisitor->setFrameStamp(_frameStamp.get());
|
||||||
viewer->setUpdateVisitor(_updateVisitor.get());
|
viewer->setUpdateVisitor(_updateVisitor.get());
|
||||||
fgSetDouble("/sim/startup/splash-alpha", 1.0);
|
fgSetDouble("/sim/startup/splash-alpha", 1.0);
|
||||||
|
|
||||||
// hide the menubar if it overlaps the window, so the splash screen
|
// hide the menubar if it overlaps the window, so the splash screen
|
||||||
// is completely visible. We reset this value when the splash screen
|
// is completely visible. We reset this value when the splash screen
|
||||||
// is fading out.
|
// is fading out.
|
||||||
|
@ -470,7 +470,7 @@ FGRenderer::addChangeListener(SGPropertyChangeListener* l, const char* path)
|
||||||
_listeners.push_back(l);
|
_listeners.push_back(l);
|
||||||
fgAddChangeListener(l, path);
|
fgAddChangeListener(l, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FGRenderer::init( void )
|
FGRenderer::init( void )
|
||||||
{
|
{
|
||||||
|
@ -507,7 +507,7 @@ FGRenderer::init( void )
|
||||||
_pipeline = makeRenderingPipeline(_renderer, 0);
|
_pipeline = makeRenderingPipeline(_renderer, 0);
|
||||||
_scenery_loaded = fgGetNode("/sim/sceneryloaded", true);
|
_scenery_loaded = fgGetNode("/sim/sceneryloaded", true);
|
||||||
_position_finalized = fgGetNode("/sim/position-finalized", true);
|
_position_finalized = fgGetNode("/sim/position-finalized", true);
|
||||||
|
|
||||||
_panel_hotspots = fgGetNode("/sim/panel-hotspots", true);
|
_panel_hotspots = fgGetNode("/sim/panel-hotspots", true);
|
||||||
_virtual_cockpit = fgGetNode("/sim/virtual-cockpit", true);
|
_virtual_cockpit = fgGetNode("/sim/virtual-cockpit", true);
|
||||||
|
|
||||||
|
@ -519,17 +519,19 @@ FGRenderer::init( void )
|
||||||
|
|
||||||
_point_sprites = fgGetNode("/sim/rendering/point-sprites", true);
|
_point_sprites = fgGetNode("/sim/rendering/point-sprites", true);
|
||||||
_distance_attenuation = fgGetNode("/sim/rendering/distance-attenuation", true);
|
_distance_attenuation = fgGetNode("/sim/rendering/distance-attenuation", true);
|
||||||
|
_triangle_directional_lights = fgGetNode("/sim/rendering/triangle-directional-lights", true);
|
||||||
_horizon_effect = fgGetNode("/sim/rendering/horizon-effect", true);
|
_horizon_effect = fgGetNode("/sim/rendering/horizon-effect", true);
|
||||||
|
|
||||||
_altitude_ft = fgGetNode("/position/altitude-ft", true);
|
_altitude_ft = fgGetNode("/position/altitude-ft", true);
|
||||||
|
|
||||||
_cloud_status = fgGetNode("/environment/clouds/status", true);
|
_cloud_status = fgGetNode("/environment/clouds/status", true);
|
||||||
_visibility_m = fgGetNode("/environment/visibility-m", true);
|
_visibility_m = fgGetNode("/environment/visibility-m", true);
|
||||||
|
|
||||||
bool use_point_sprites = _point_sprites->getBoolValue();
|
bool use_point_sprites = _point_sprites->getBoolValue();
|
||||||
bool distance_attenuation = _distance_attenuation->getBoolValue();
|
bool distance_attenuation = _distance_attenuation->getBoolValue();
|
||||||
|
bool triangles = _triangle_directional_lights->getBoolValue();
|
||||||
|
|
||||||
SGConfigureDirectionalLights( use_point_sprites, distance_attenuation );
|
SGConfigureDirectionalLights( use_point_sprites, distance_attenuation, triangles );
|
||||||
|
|
||||||
if (const char* tc = fgGetString("/sim/rendering/texture-compression", NULL)) {
|
if (const char* tc = fgGetString("/sim/rendering/texture-compression", NULL)) {
|
||||||
if (strcmp(tc, "false") == 0 || strcmp(tc, "off") == 0 ||
|
if (strcmp(tc, "false") == 0 || strcmp(tc, "off") == 0 ||
|
||||||
|
@ -550,9 +552,9 @@ FGRenderer::init( void )
|
||||||
}
|
}
|
||||||
SGSceneFeatures::instance()->setTextureCompressionPath(globals->get_texture_cache_dir());
|
SGSceneFeatures::instance()->setTextureCompressionPath(globals->get_texture_cache_dir());
|
||||||
// create sky, but can't build until setupView, since we depend
|
// create sky, but can't build until setupView, since we depend
|
||||||
// on other subsystems to be inited, eg Ephemeris
|
// on other subsystems to be inited, eg Ephemeris
|
||||||
_sky = new SGSky;
|
_sky = new SGSky;
|
||||||
|
|
||||||
SGPath texture_path(globals->get_fg_root());
|
SGPath texture_path(globals->get_fg_root());
|
||||||
texture_path.append("Textures");
|
texture_path.append("Textures");
|
||||||
texture_path.append("Sky");
|
texture_path.append("Sky");
|
||||||
|
@ -560,7 +562,7 @@ FGRenderer::init( void )
|
||||||
SGCloudLayer * layer = new SGCloudLayer(texture_path.local8BitStr());
|
SGCloudLayer * layer = new SGCloudLayer(texture_path.local8BitStr());
|
||||||
_sky->add_cloud_layer(layer);
|
_sky->add_cloud_layer(layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
_sky->texture_path( texture_path.local8BitStr() );
|
_sky->texture_path( texture_path.local8BitStr() );
|
||||||
|
|
||||||
if (!_classicalRenderer) {
|
if (!_classicalRenderer) {
|
||||||
|
@ -621,7 +623,7 @@ FGRenderer::buildClassicalPipeline(CameraGroup* cgroup, unsigned flags, osg::Cam
|
||||||
// The camera group will always update the camera
|
// The camera group will always update the camera
|
||||||
camera->setReferenceFrame(Transform::ABSOLUTE_RF);
|
camera->setReferenceFrame(Transform::ABSOLUTE_RF);
|
||||||
info->name = "classic";
|
info->name = "classic";
|
||||||
|
|
||||||
Camera* farCamera = 0;
|
Camera* farCamera = 0;
|
||||||
if ((flags & (CameraGroup::GUI | CameraGroup::ORTHO)) == 0) {
|
if ((flags & (CameraGroup::GUI | CameraGroup::ORTHO)) == 0) {
|
||||||
farCamera = new Camera;
|
farCamera = new Camera;
|
||||||
|
@ -1094,7 +1096,7 @@ FGRenderer::buildDeferredPipeline(CameraGroup* cgroup, unsigned flags, osg::Came
|
||||||
return buildCameraFromRenderingPipeline(_pipeline, cgroup, flags, camera, view, projection, gc);
|
return buildCameraFromRenderingPipeline(_pipeline, cgroup, flags, camera, view, projection, gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Camera*
|
osg::Camera*
|
||||||
FGRenderer::buildDeferredFullscreenCamera( flightgear::CameraInfo* info, const FGRenderingPipeline::Pass* pass )
|
FGRenderer::buildDeferredFullscreenCamera( flightgear::CameraInfo* info, const FGRenderingPipeline::Pass* pass )
|
||||||
{
|
{
|
||||||
osg::Camera* camera = new osg::Camera;
|
osg::Camera* camera = new osg::Camera;
|
||||||
|
@ -1149,7 +1151,7 @@ FGRenderer::buildDeferredFullscreenCamera( flightgear::CameraInfo* info, const F
|
||||||
return camera;
|
return camera;
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Camera*
|
osg::Camera*
|
||||||
FGRenderer::buildDeferredFullscreenCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc, const FGRenderingPipeline::Stage* stage )
|
FGRenderer::buildDeferredFullscreenCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc, const FGRenderingPipeline::Stage* stage )
|
||||||
{
|
{
|
||||||
osg::Camera* camera = buildDeferredFullscreenCamera(info, static_cast<const FGRenderingPipeline::Pass*>(stage));
|
osg::Camera* camera = buildDeferredFullscreenCamera(info, static_cast<const FGRenderingPipeline::Pass*>(stage));
|
||||||
|
@ -1269,7 +1271,7 @@ FGRenderer::buildLightingSkyCloudsPass(FGRenderingPipeline::Pass* pass)
|
||||||
Group* group = new Group;
|
Group* group = new Group;
|
||||||
group->setName("skyCloudsGroup");
|
group->setName("skyCloudsGroup");
|
||||||
group->setNodeMask(simgear::BACKGROUND_BIT);
|
group->setNodeMask(simgear::BACKGROUND_BIT);
|
||||||
|
|
||||||
StateSet* ss = group->getOrCreateStateSet();
|
StateSet* ss = group->getOrCreateStateSet();
|
||||||
ss->setAttributeAndModes( new osg::ColorMask( true, true, true, false ), osg::StateAttribute::ON );
|
ss->setAttributeAndModes( new osg::ColorMask( true, true, true, false ), osg::StateAttribute::ON );
|
||||||
group->addChild( _sky->getPreRoot() );
|
group->addChild( _sky->getPreRoot() );
|
||||||
|
@ -1345,7 +1347,7 @@ CameraInfo* FGRenderer::buildCameraFromRenderingPipeline(FGRenderingPipeline* rp
|
||||||
{
|
{
|
||||||
CameraInfo* info = new CameraInfo(flags);
|
CameraInfo* info = new CameraInfo(flags);
|
||||||
buildBuffers(rpipe, info);
|
buildBuffers(rpipe, info);
|
||||||
|
|
||||||
for (size_t i = 0; i < rpipe->stages.size(); ++i) {
|
for (size_t i = 0; i < rpipe->stages.size(); ++i) {
|
||||||
osg::ref_ptr<FGRenderingPipeline::Stage> stage = rpipe->stages[i];
|
osg::ref_ptr<FGRenderingPipeline::Stage> stage = rpipe->stages[i];
|
||||||
buildStage(info, stage, cgroup, camera, view, projection, gc);
|
buildStage(info, stage, cgroup, camera, view, projection, gc);
|
||||||
|
@ -1359,26 +1361,26 @@ CameraInfo* FGRenderer::buildCameraFromRenderingPipeline(FGRenderingPipeline* rp
|
||||||
void FGRenderer::setupRoot()
|
void FGRenderer::setupRoot()
|
||||||
{
|
{
|
||||||
osg::StateSet* stateSet = _root->getOrCreateStateSet();
|
osg::StateSet* stateSet = _root->getOrCreateStateSet();
|
||||||
|
|
||||||
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||||
|
|
||||||
stateSet->setAttribute(new osg::Depth(osg::Depth::LESS));
|
stateSet->setAttribute(new osg::Depth(osg::Depth::LESS));
|
||||||
stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
|
stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
|
||||||
|
|
||||||
stateSet->setAttribute(new osg::BlendFunc);
|
stateSet->setAttribute(new osg::BlendFunc);
|
||||||
stateSet->setMode(GL_BLEND, osg::StateAttribute::OFF);
|
stateSet->setMode(GL_BLEND, osg::StateAttribute::OFF);
|
||||||
|
|
||||||
stateSet->setMode(GL_FOG, osg::StateAttribute::OFF);
|
stateSet->setMode(GL_FOG, osg::StateAttribute::OFF);
|
||||||
|
|
||||||
// this will be set below
|
// this will be set below
|
||||||
stateSet->setMode(GL_NORMALIZE, osg::StateAttribute::OFF);
|
stateSet->setMode(GL_NORMALIZE, osg::StateAttribute::OFF);
|
||||||
|
|
||||||
osg::Material* material = new osg::Material;
|
osg::Material* material = new osg::Material;
|
||||||
stateSet->setAttribute(material);
|
stateSet->setAttribute(material);
|
||||||
|
|
||||||
stateSet->setTextureAttribute(0, new osg::TexEnv);
|
stateSet->setTextureAttribute(0, new osg::TexEnv);
|
||||||
stateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::OFF);
|
stateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::OFF);
|
||||||
|
|
||||||
osg::Hint* hint = new osg::Hint(GL_FOG_HINT, GL_DONT_CARE);
|
osg::Hint* hint = new osg::Hint(GL_FOG_HINT, GL_DONT_CARE);
|
||||||
hint->setUpdateCallback(new FGHintUpdateCallback("/sim/rendering/fog"));
|
hint->setUpdateCallback(new FGHintUpdateCallback("/sim/rendering/fog"));
|
||||||
stateSet->setAttribute(hint);
|
stateSet->setAttribute(hint);
|
||||||
|
@ -1395,7 +1397,7 @@ void FGRenderer::setupRoot()
|
||||||
hint->setUpdateCallback(new FGHintUpdateCallback("/sim/rendering/perspective-correction"));
|
hint->setUpdateCallback(new FGHintUpdateCallback("/sim/rendering/perspective-correction"));
|
||||||
stateSet->setAttribute(hint);
|
stateSet->setAttribute(hint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FGRenderer::setupView( void )
|
FGRenderer::setupView( void )
|
||||||
{
|
{
|
||||||
|
@ -1409,7 +1411,7 @@ FGRenderer::setupView( void )
|
||||||
osg::PolygonOffset::setFactorMultiplier(1);
|
osg::PolygonOffset::setFactorMultiplier(1);
|
||||||
|
|
||||||
setupRoot();
|
setupRoot();
|
||||||
|
|
||||||
// build the sky
|
// build the sky
|
||||||
Ephemeris* ephemerisSub = globals->get_subsystem<Ephemeris>();
|
Ephemeris* ephemerisSub = globals->get_subsystem<Ephemeris>();
|
||||||
|
|
||||||
|
@ -1427,11 +1429,11 @@ FGRenderer::setupView( void )
|
||||||
*ephemerisSub->data(),
|
*ephemerisSub->data(),
|
||||||
fgGetNode("/environment", true),
|
fgGetNode("/environment", true),
|
||||||
opt.get());
|
opt.get());
|
||||||
|
|
||||||
viewer->getCamera()
|
viewer->getCamera()
|
||||||
->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
||||||
|
|
||||||
|
|
||||||
// need to update the light on every frame
|
// need to update the light on every frame
|
||||||
// OSG LightSource objects are rather confusing. OSG only supports
|
// OSG LightSource objects are rather confusing. OSG only supports
|
||||||
// the 10 lights specified by OpenGL itself; if more than one
|
// the 10 lights specified by OpenGL itself; if more than one
|
||||||
|
@ -1441,7 +1443,7 @@ FGRenderer::setupView( void )
|
||||||
// LightSource is just a shortcut for setting up a state set that
|
// LightSource is just a shortcut for setting up a state set that
|
||||||
// has the corresponding OpenGL light enabled: a LightSource will
|
// has the corresponding OpenGL light enabled: a LightSource will
|
||||||
// affect geometry anywhere in the scene graph that has its light
|
// affect geometry anywhere in the scene graph that has its light
|
||||||
// number enabled in a state set.
|
// number enabled in a state set.
|
||||||
osg::ref_ptr<LightSource> lightSource = new LightSource;
|
osg::ref_ptr<LightSource> lightSource = new LightSource;
|
||||||
lightSource->setName("FGLightSource");
|
lightSource->setName("FGLightSource");
|
||||||
lightSource->getLight()->setDataVariance(Object::DYNAMIC);
|
lightSource->getLight()->setDataVariance(Object::DYNAMIC);
|
||||||
|
@ -1450,7 +1452,7 @@ FGRenderer::setupView( void )
|
||||||
lightSource->setLocalStateSetModes(osg::StateAttribute::ON);
|
lightSource->setLocalStateSetModes(osg::StateAttribute::ON);
|
||||||
lightSource->setUpdateCallback(new FGLightSourceUpdateCallback);
|
lightSource->setUpdateCallback(new FGLightSourceUpdateCallback);
|
||||||
_viewerSceneRoot->addChild(lightSource);
|
_viewerSceneRoot->addChild(lightSource);
|
||||||
|
|
||||||
// we need a white diffuse light for the phase of the moon
|
// we need a white diffuse light for the phase of the moon
|
||||||
osg::ref_ptr<LightSource> sunLight = new osg::LightSource;
|
osg::ref_ptr<LightSource> sunLight = new osg::LightSource;
|
||||||
sunLight->setName("sunLightSource");
|
sunLight->setName("sunLightSource");
|
||||||
|
@ -1459,23 +1461,23 @@ FGRenderer::setupView( void )
|
||||||
sunLight->setUpdateCallback(new FGLightSourceUpdateCallback(true));
|
sunLight->setUpdateCallback(new FGLightSourceUpdateCallback(true));
|
||||||
sunLight->setReferenceFrame(osg::LightSource::RELATIVE_RF);
|
sunLight->setReferenceFrame(osg::LightSource::RELATIVE_RF);
|
||||||
sunLight->setLocalStateSetModes(osg::StateAttribute::ON);
|
sunLight->setLocalStateSetModes(osg::StateAttribute::ON);
|
||||||
|
|
||||||
// Hang a StateSet above the sky subgraph in order to turn off
|
// Hang a StateSet above the sky subgraph in order to turn off
|
||||||
// light 0
|
// light 0
|
||||||
Group* skyGroup = _sky->getPreRoot();
|
Group* skyGroup = _sky->getPreRoot();
|
||||||
StateSet* skySS = skyGroup->getOrCreateStateSet();
|
StateSet* skySS = skyGroup->getOrCreateStateSet();
|
||||||
skySS->setMode(GL_LIGHT0, StateAttribute::OFF);
|
skySS->setMode(GL_LIGHT0, StateAttribute::OFF);
|
||||||
sunLight->addChild(skyGroup);
|
sunLight->addChild(skyGroup);
|
||||||
|
|
||||||
if ( _classicalRenderer ) {
|
if ( _classicalRenderer ) {
|
||||||
_root->addChild(sunLight);
|
_root->addChild(sunLight);
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Group* sceneGroup = globals->get_scenery()->get_scene_graph();
|
osg::Group* sceneGroup = globals->get_scenery()->get_scene_graph();
|
||||||
sceneGroup->setName("rendererScene");
|
sceneGroup->setName("rendererScene");
|
||||||
sceneGroup->setNodeMask(~simgear::BACKGROUND_BIT);
|
sceneGroup->setNodeMask(~simgear::BACKGROUND_BIT);
|
||||||
_root->addChild(sceneGroup);
|
_root->addChild(sceneGroup);
|
||||||
|
|
||||||
// setup state-set for main scenery (including models and aircraft)
|
// setup state-set for main scenery (including models and aircraft)
|
||||||
osg::StateSet* stateSet = sceneGroup->getOrCreateStateSet();
|
osg::StateSet* stateSet = sceneGroup->getOrCreateStateSet();
|
||||||
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON);
|
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON);
|
||||||
|
@ -1525,7 +1527,7 @@ FGRenderer::setupView( void )
|
||||||
guiCamera->insertChild(0, geode);
|
guiCamera->insertChild(0, geode);
|
||||||
guiCamera->insertChild(0, FGPanelNode::create2DPanelNode());
|
guiCamera->insertChild(0, FGPanelNode::create2DPanelNode());
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Switch* sw = new osg::Switch;
|
osg::Switch* sw = new osg::Switch;
|
||||||
sw->setName("scenerySwitch");
|
sw->setName("scenerySwitch");
|
||||||
sw->setUpdateCallback(new FGScenerySwitchCallback);
|
sw->setUpdateCallback(new FGScenerySwitchCallback);
|
||||||
|
@ -1538,7 +1540,7 @@ FGRenderer::setupView( void )
|
||||||
_viewerSceneRoot->addChild(_sky->getCloudRoot());
|
_viewerSceneRoot->addChild(_sky->getCloudRoot());
|
||||||
_viewerSceneRoot->addChild(FGCreateRedoutNode());
|
_viewerSceneRoot->addChild(FGCreateRedoutNode());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach empty program to the scene root so that shader programs
|
// Attach empty program to the scene root so that shader programs
|
||||||
// don't leak into state sets (effects) that shouldn't have one.
|
// don't leak into state sets (effects) that shouldn't have one.
|
||||||
stateSet = _viewerSceneRoot->getOrCreateStateSet();
|
stateSet = _viewerSceneRoot->getOrCreateStateSet();
|
||||||
|
@ -1612,7 +1614,7 @@ FGRenderer::update( ) {
|
||||||
flightgear::View *current__view = globals->get_current_view();
|
flightgear::View *current__view = globals->get_current_view();
|
||||||
// Force update of center dependent values ...
|
// Force update of center dependent values ...
|
||||||
current__view->set_dirty();
|
current__view->set_dirty();
|
||||||
|
|
||||||
osg::Camera *camera = viewer->getCamera();
|
osg::Camera *camera = viewer->getCamera();
|
||||||
|
|
||||||
osg::Vec4 clear_color = _altitude_ft->getDoubleValue() < 250000
|
osg::Vec4 clear_color = _altitude_ft->getDoubleValue() < 250000
|
||||||
|
@ -1625,7 +1627,7 @@ FGRenderer::update( ) {
|
||||||
camera->setClearColor(clear_color);
|
camera->setClearColor(clear_color);
|
||||||
|
|
||||||
updateSky();
|
updateSky();
|
||||||
|
|
||||||
// need to call the update visitor once
|
// need to call the update visitor once
|
||||||
_frameStamp->setCalendarTime(*globals->get_time_params()->getGmt());
|
_frameStamp->setCalendarTime(*globals->get_time_params()->getGmt());
|
||||||
_updateVisitor->setViewData(current__view->getViewPosition(),
|
_updateVisitor->setViewData(current__view->getViewPosition(),
|
||||||
|
@ -1655,18 +1657,18 @@ FGRenderer::updateSky()
|
||||||
// update fog params if visibility has changed
|
// update fog params if visibility has changed
|
||||||
double visibility_meters = _visibility_m->getDoubleValue();
|
double visibility_meters = _visibility_m->getDoubleValue();
|
||||||
_sky->set_visibility(visibility_meters);
|
_sky->set_visibility(visibility_meters);
|
||||||
|
|
||||||
double altitude_m = _altitude_ft->getDoubleValue() * SG_FEET_TO_METER;
|
double altitude_m = _altitude_ft->getDoubleValue() * SG_FEET_TO_METER;
|
||||||
_sky->modify_vis( altitude_m, 0.0 /* time factor, now unused */);
|
_sky->modify_vis( altitude_m, 0.0 /* time factor, now unused */);
|
||||||
|
|
||||||
FGLight *l = static_cast<FGLight*>(globals->get_subsystem("lighting"));
|
FGLight *l = static_cast<FGLight*>(globals->get_subsystem("lighting"));
|
||||||
|
|
||||||
// The sun and moon distances are scaled down versions
|
// The sun and moon distances are scaled down versions
|
||||||
// of the actual distance to get both the moon and the sun
|
// of the actual distance to get both the moon and the sun
|
||||||
// within the range of the far clip plane.
|
// within the range of the far clip plane.
|
||||||
// Moon distance: 384,467 kilometers
|
// Moon distance: 384,467 kilometers
|
||||||
// Sun distance: 150,000,000 kilometers
|
// Sun distance: 150,000,000 kilometers
|
||||||
|
|
||||||
double sun_horiz_eff, moon_horiz_eff;
|
double sun_horiz_eff, moon_horiz_eff;
|
||||||
if (_horizon_effect->getBoolValue()) {
|
if (_horizon_effect->getBoolValue()) {
|
||||||
sun_horiz_eff
|
sun_horiz_eff
|
||||||
|
@ -1682,7 +1684,7 @@ FGRenderer::updateSky()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SGSkyState sstate;
|
SGSkyState sstate;
|
||||||
sstate.pos = globals->get_current_view()->getViewPosition();
|
sstate.pos = globals->get_current_view()->getViewPosition();
|
||||||
sstate.pos_geod = globals->get_current_view()->getPosition();
|
sstate.pos_geod = globals->get_current_view()->getPosition();
|
||||||
|
@ -1692,7 +1694,7 @@ FGRenderer::updateSky()
|
||||||
sstate.sun_dist = 50000.0 * sun_horiz_eff;
|
sstate.sun_dist = 50000.0 * sun_horiz_eff;
|
||||||
sstate.moon_dist = 40000.0 * moon_horiz_eff;
|
sstate.moon_dist = 40000.0 * moon_horiz_eff;
|
||||||
sstate.sun_angle = l->get_sun_angle();
|
sstate.sun_angle = l->get_sun_angle();
|
||||||
|
|
||||||
SGSkyColor scolor;
|
SGSkyColor scolor;
|
||||||
scolor.sky_color = SGVec3f(l->sky_color().data());
|
scolor.sky_color = SGVec3f(l->sky_color().data());
|
||||||
scolor.adj_sky_color = SGVec3f(l->adj_sky_color().data());
|
scolor.adj_sky_color = SGVec3f(l->adj_sky_color().data());
|
||||||
|
@ -1706,7 +1708,7 @@ FGRenderer::updateSky()
|
||||||
_sky->reposition( sstate, *ephemerisSub->data(), delta_time_sec );
|
_sky->reposition( sstate, *ephemerisSub->data(), delta_time_sec );
|
||||||
_sky->repaint( scolor, *ephemerisSub->data() );
|
_sky->repaint( scolor, *ephemerisSub->data() );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FGRenderer::resize( int width, int height )
|
FGRenderer::resize( int width, int height )
|
||||||
{
|
{
|
||||||
|
@ -1799,12 +1801,12 @@ PickList FGRenderer::pick(const osg::Vec2& windowPos)
|
||||||
++hit) {
|
++hit) {
|
||||||
const osg::NodePath& np = hit->nodePath;
|
const osg::NodePath& np = hit->nodePath;
|
||||||
osg::NodePath::const_reverse_iterator npi;
|
osg::NodePath::const_reverse_iterator npi;
|
||||||
|
|
||||||
for (npi = np.rbegin(); npi != np.rend(); ++npi) {
|
for (npi = np.rbegin(); npi != np.rend(); ++npi) {
|
||||||
SGSceneUserData* ud = SGSceneUserData::getSceneUserData(*npi);
|
SGSceneUserData* ud = SGSceneUserData::getSceneUserData(*npi);
|
||||||
if (!ud || (ud->getNumPickCallbacks() == 0))
|
if (!ud || (ud->getNumPickCallbacks() == 0))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (unsigned i = 0; i < ud->getNumPickCallbacks(); ++i) {
|
for (unsigned i = 0; i < ud->getNumPickCallbacks(); ++i) {
|
||||||
SGPickCallback* pickCallback = ud->getPickCallback(i);
|
SGPickCallback* pickCallback = ud->getPickCallback(i);
|
||||||
if (!pickCallback)
|
if (!pickCallback)
|
||||||
|
@ -1821,7 +1823,7 @@ PickList FGRenderer::pick(const osg::Vec2& windowPos)
|
||||||
} // of installed pick callbacks iteration
|
} // of installed pick callbacks iteration
|
||||||
} // of reverse node path walk
|
} // of reverse node path walk
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1848,7 +1850,7 @@ FGRenderer::removeCamera(osg::Camera* camera)
|
||||||
{
|
{
|
||||||
_viewerSceneRoot->removeChild(camera);
|
_viewerSceneRoot->removeChild(camera);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FGRenderer::setPlanes( double zNear, double zFar )
|
FGRenderer::setPlanes( double zNear, double zFar )
|
||||||
{
|
{
|
||||||
|
@ -1939,7 +1941,7 @@ public:
|
||||||
}
|
}
|
||||||
cout << endl;
|
cout << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void doTraversal(Camera* camera, Node* root, Viewport* viewport)
|
void doTraversal(Camera* camera, Node* root, Viewport* viewport)
|
||||||
{
|
{
|
||||||
ref_ptr<RefMatrix> projection
|
ref_ptr<RefMatrix> projection
|
||||||
|
@ -2019,7 +2021,7 @@ public:
|
||||||
modelview = createOrReuseMatrix(*getModelViewMatrix()
|
modelview = createOrReuseMatrix(*getModelViewMatrix()
|
||||||
* camera.getViewMatrix());
|
* camera.getViewMatrix());
|
||||||
}
|
}
|
||||||
else { // pre multiply
|
else { // pre multiply
|
||||||
projection = createOrReuseMatrix(camera.getProjectionMatrix()
|
projection = createOrReuseMatrix(camera.getProjectionMatrix()
|
||||||
* (*getProjectionMatrix()));
|
* (*getProjectionMatrix()));
|
||||||
modelview = createOrReuseMatrix(camera.getViewMatrix()
|
modelview = createOrReuseMatrix(camera.getViewMatrix()
|
||||||
|
@ -2034,10 +2036,10 @@ public:
|
||||||
pushViewport(camera.getViewport());
|
pushViewport(camera.getViewport());
|
||||||
|
|
||||||
pushProjectionMatrix(projection);
|
pushProjectionMatrix(projection);
|
||||||
pushModelViewMatrix(modelview, camera.getReferenceFrame());
|
pushModelViewMatrix(modelview, camera.getReferenceFrame());
|
||||||
|
|
||||||
traverse(camera);
|
traverse(camera);
|
||||||
|
|
||||||
// restore the previous model view matrix.
|
// restore the previous model view matrix.
|
||||||
popModelViewMatrix();
|
popModelViewMatrix();
|
||||||
|
|
||||||
|
@ -2079,4 +2081,3 @@ bool printVisibleSceneInfo(FGRenderer* renderer)
|
||||||
|
|
||||||
}
|
}
|
||||||
// end of renderer.cxx
|
// end of renderer.cxx
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ public:
|
||||||
void resize(int width, int height );
|
void resize(int width, int height );
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
/** Just pick into the scene and return the pick callbacks on the way ...
|
/** Just pick into the scene and return the pick callbacks on the way ...
|
||||||
*/
|
*/
|
||||||
PickList pick(const osg::Vec2& windowPos);
|
PickList pick(const osg::Vec2& windowPos);
|
||||||
|
@ -85,7 +85,7 @@ public:
|
||||||
void addCamera(osg::Camera* camera, bool useSceneData);
|
void addCamera(osg::Camera* camera, bool useSceneData);
|
||||||
|
|
||||||
void removeCamera(osg::Camera* camera);
|
void removeCamera(osg::Camera* camera);
|
||||||
|
|
||||||
/** Add a camera to the group. The camera is added to the viewer
|
/** Add a camera to the group. The camera is added to the viewer
|
||||||
* as a slave. See osgViewer::Viewer::addSlave.
|
* as a slave. See osgViewer::Viewer::addSlave.
|
||||||
* @param flags properties of the camera; see CameraGroup::Flags
|
* @param flags properties of the camera; see CameraGroup::Flags
|
||||||
|
@ -126,20 +126,20 @@ public:
|
||||||
protected:
|
protected:
|
||||||
osg::ref_ptr<osgViewer::Viewer> viewer;
|
osg::ref_ptr<osgViewer::Viewer> viewer;
|
||||||
osg::ref_ptr<flightgear::FGEventHandler> eventHandler;
|
osg::ref_ptr<flightgear::FGEventHandler> eventHandler;
|
||||||
|
|
||||||
osg::ref_ptr<osg::FrameStamp> _frameStamp;
|
osg::ref_ptr<osg::FrameStamp> _frameStamp;
|
||||||
osg::ref_ptr<SGUpdateVisitor> _updateVisitor;
|
osg::ref_ptr<SGUpdateVisitor> _updateVisitor;
|
||||||
osg::ref_ptr<osg::Group> _viewerSceneRoot;
|
osg::ref_ptr<osg::Group> _viewerSceneRoot;
|
||||||
osg::ref_ptr<osg::Group> _deferredRealRoot;
|
osg::ref_ptr<osg::Group> _deferredRealRoot;
|
||||||
osg::ref_ptr<osg::Group> _root;
|
osg::ref_ptr<osg::Group> _root;
|
||||||
|
|
||||||
SGPropertyNode_ptr _scenery_loaded, _position_finalized;
|
SGPropertyNode_ptr _scenery_loaded, _position_finalized;
|
||||||
|
|
||||||
|
|
||||||
SGPropertyNode_ptr _splash_alpha;
|
SGPropertyNode_ptr _splash_alpha;
|
||||||
SGPropertyNode_ptr _point_sprites, _enhanced_lighting, _distance_attenuation;
|
SGPropertyNode_ptr _point_sprites, _enhanced_lighting, _distance_attenuation, _triangle_directional_lights;
|
||||||
SGPropertyNode_ptr _textures;
|
SGPropertyNode_ptr _textures;
|
||||||
SGPropertyNode_ptr _cloud_status, _visibility_m;
|
SGPropertyNode_ptr _cloud_status, _visibility_m;
|
||||||
SGPropertyNode_ptr _xsize, _ysize;
|
SGPropertyNode_ptr _xsize, _ysize;
|
||||||
SGPropertyNode_ptr _panel_hotspots, _sim_delta_sec, _horizon_effect, _altitude_ft;
|
SGPropertyNode_ptr _panel_hotspots, _sim_delta_sec, _horizon_effect, _altitude_ft;
|
||||||
SGPropertyNode_ptr _virtual_cockpit;
|
SGPropertyNode_ptr _virtual_cockpit;
|
||||||
|
@ -155,7 +155,7 @@ protected:
|
||||||
|
|
||||||
typedef std::vector<SGPropertyChangeListener*> SGPropertyChangeListenerVec;
|
typedef std::vector<SGPropertyChangeListener*> SGPropertyChangeListenerVec;
|
||||||
SGPropertyChangeListenerVec _listeners;
|
SGPropertyChangeListenerVec _listeners;
|
||||||
|
|
||||||
flightgear::CameraInfo* buildCameraFromRenderingPipeline(FGRenderingPipeline* rpipe, flightgear::CameraGroup* cgroup, unsigned flags, osg::Camera* camera,
|
flightgear::CameraInfo* buildCameraFromRenderingPipeline(FGRenderingPipeline* rpipe, flightgear::CameraGroup* cgroup, unsigned flags, osg::Camera* camera,
|
||||||
const osg::Matrix& view, const osg::Matrix& projection, osg::GraphicsContext* gc);
|
const osg::Matrix& view, const osg::Matrix& projection, osg::GraphicsContext* gc);
|
||||||
|
|
||||||
|
@ -186,11 +186,11 @@ protected:
|
||||||
osg::ref_ptr<osg::Uniform> _depthInColor;
|
osg::ref_ptr<osg::Uniform> _depthInColor;
|
||||||
|
|
||||||
osg::ref_ptr<FGRenderingPipeline> _pipeline;
|
osg::ref_ptr<FGRenderingPipeline> _pipeline;
|
||||||
|
|
||||||
void addChangeListener(SGPropertyChangeListener* l, const char* path);
|
void addChangeListener(SGPropertyChangeListener* l, const char* path);
|
||||||
|
|
||||||
void updateSky();
|
void updateSky();
|
||||||
|
|
||||||
void setupRoot();
|
void setupRoot();
|
||||||
|
|
||||||
SplashScreen* _splash;
|
SplashScreen* _splash;
|
||||||
|
|
Loading…
Add table
Reference in a new issue