Class attached. I don't use osgEphemeris (yet) so don't know exactly how this might interact with it. My graph from bottom to top looks like :
Sphere - DepthFunction(always), depthRange(1.0,1.0), Sky texture map, fog and lighting off
|
MoveEarthySkyTransform (or similar type thing which is probably already in osgEphemeris)
|
ExtentsCamera
|
Rest of scene
I also do
extentsCamera->setRenderOrder(osg::CameraNode::PRE_RENDER);
extentsCamera->setRenderTargetImplementation(osg::CameraNode::FRAME_BUFFER);
extentsCamera->setClearMask(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
and put a ClearNode with RequiresClear(false) off the root node to prevent the "main renderbin" from clearing the screen again.
to place the sky first. Unfortunately I think this means pixel overdraw (you're drawing the sky behind objects) which is bad if you have expensive atmosphere shaders, but I didn't find anyway around this.
Hope that's useful.
David
#include "dvsLibrary/ExtentsCamera.h" #include <osgUtil/CullVisitor>
CExtentsCamera::CExtentsCamera() : osg::CameraNode()
{
// Turn culling off (possibly duplicated statements)
this->setCullingActive(false);
this->setCullingMode(osg::CullSettings::NO_CULLING);
// We will compute the near/far planes ourselves
this->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
// Reset our store of the projection matrix
_matrix.identity();
// Default near/far ranges (to bracket a viewer centred sphere with
radius 1)
_zNear = 0.5; // Forcing the near plane to be 0.5m
_zFar = 2.0; // Forcing the far plane to be 2m
}
void CExtentsCamera::traverse(osg::NodeVisitor &nv)
{
// If the scene hasn't been defined (i.e. we have no children at all)
then don't do anything
// NB : This may be an unnecessary test (not sure).
unsigned int numChildren = _children.size();
if(numChildren == 0) return;
// If the visitor is not a cull visitor, then we are not interested
// in intercepting it, so pass it directly onto the scene.
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
if(!cv)
{
CameraNode::traverse(nv);
return;
}
// Get a reference to the Cull Visitor's projection matrix
osg::RefMatrix& projection = cv->getProjectionMatrix();
// For the purposes of minimising the work we need to do,
// compare our copy of the projection matrix with the current one. If
they
// are the same then we don't need to do anything.
// NB 1 : No speed trials have been done to determine whether this
"early out" is worth it
// NB 2 : Direct comparison of float matrices is not really a good idea
if(projection==_matrix)
{
CameraNode::traverse(nv);
return;
}
// The projection matrix has changed, one way or another (e.g. first
pass, or through
// changing the window size
double n,f,l,r,t,b; // near, far, left, right, top, bottom
projection.getFrustum(l,r,b,t,n,f);
//double a = (r-l)/(t-b);
// NB : This might be possible to simplify and hence optimise (haven't
yet checked)
double trans_near = (-_zNear*projection(2,2) + projection(3,2)) /
(-_zNear*projection(2,3) + projection(3,3));
double trans_far = ( -_zFar*projection(2,2) + projection(3,2)) /
( -_zFar*projection(2,3) + projection(3,3));
double ratio = fabs(2.0/(trans_near - trans_far));
double center = -0.5*(trans_near + trans_far);
// Set the projection matrix
projection.postMult(osg::Matrixd( 1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, ratio, 0.0,
0.0, 0.0, center*ratio, 1.0));
// Take a copy of the projection matrix
_matrix = projection;
CameraNode::traverse(nv);
}
void CExtentsCamera::SetZRange(float zNear, float zFar)
{
// NB : Should probably check that zNear!=zFar otherwise we'll get div0
in the
// traverse loop
_zNear = zNear;
_zFar = zFar;
}
#ifndef EXTENTS_CAMERA_H
#define EXTENTS_CAMERA_H
#include <osg/CameraNode>
class CExtentsCamera : public osg::CameraNode
{
public:
CExtentsCamera();
virtual void traverse(osg::NodeVisitor &nv);
// Sets the forcing range for the near and far planes
void SetZRange(float zNear, float zFar);
protected:
osg::Matrix _matrix;
float _zNear;
float _zFar;
};
#endif_______________________________________________ osg-users mailing list [email protected] http://openscenegraph.net/mailman/listinfo/osg-users http://www.openscenegraph.org/
