Adding support for controlling visual settings via environmental variables

and command line paramters.  Including support for stereo and stencil buffer.
This commit is contained in:
Robert Osfield
2001-12-19 00:38:23 +00:00
parent a3fe8ebb18
commit 296865e250
24 changed files with 825 additions and 300 deletions

View File

@@ -1,7 +1,3 @@
#ifdef USE_MEM_CHECK
#include <mcheck.h>
#endif
#include <osg/Transform>
#include <osg/Billboard>
#include <osg/Geode>
@@ -21,88 +17,9 @@
#include <osgUtil/Optimizer>
/*
* Function to read several files (typically one) as specified on the command
* line, and return them in an osg::Node
*/
osg::Node* getNodeFromFiles(int argc,char **argv)
{
osg::Node *rootnode = new osg::Node;
int i;
typedef std::vector<osg::Node*> NodeList;
NodeList nodeList;
for( i = 1; i < argc; i++ )
{
if (argv[i][0]=='-')
{
switch(argv[i][1])
{
case('l'):
++i;
if (i<argc)
{
osgDB::Registry::instance()->loadLibrary(argv[i]);
}
break;
case('e'):
++i;
if (i<argc)
{
std::string libName = osgDB::Registry::instance()->createLibraryNameForExt(argv[i]);
osgDB::Registry::instance()->loadLibrary(libName);
}
break;
}
} else
{
osg::Node *node = osgDB::readNodeFile( argv[i] );
if( node != (osg::Node *)0L )
{
if (node->getName().empty()) node->setName( argv[i] );
nodeList.push_back(node);
}
}
}
if (nodeList.size()==0)
{
osg::notify(osg::WARN) << "No data loaded."<< std::endl;
exit(0);
}
if (nodeList.size()==1)
{
rootnode = nodeList.front();
}
else // size >1
{
osg::Group* group = new osg::Group();
for(NodeList::iterator itr=nodeList.begin();
itr!=nodeList.end();
++itr)
{
group->addChild(*itr);
}
rootnode = group;
}
return rootnode;
}
int main( int argc, char **argv )
{
#ifdef USE_MEM_CHECK
mtrace();
#endif
// initialize the GLUT
glutInit( &argc, argv );
@@ -125,39 +42,46 @@ int main( int argc, char **argv )
return 0;
}
osg::Timer timer;
osg::Timer_t before_load = timer.tick();
// comment out right now, but the following allos users to pass option data to
// create the commandline args.
std::vector<std::string> commandLine;
for(int i=1;i<argc;++i) commandLine.push_back(argv[i]);
// initialize the viewer.
osgGLUT::Viewer viewer;
// configure the viewer from the commandline arguments.
viewer.readCommandLine(commandLine);
// configure the plguin registry from the commandline arguments.
osgDB::readCommandLine(commandLine);
// comment out right now, but the following allows users to pass option data to
// the ReaderWriter plugins. By default the options are set to NULL. The basic
// osgDB::ReaderWriter::Options stucture has just a string, but this can be
// subclassed to extend it to handle any options that a user desires.
// osgDB::Registry::instance()->setOptions(new osgDB::ReaderWriter::Options("test options"));
osg::Node* rootnode = getNodeFromFiles( argc, argv);
osg::Timer_t after_load = timer.tick();
std::cout << "Time for load = "<<timer.delta_s(before_load,after_load)<<" seconds"<< std::endl;
// load the nodes from the commandline arguments.
osg::Node* rootnode = osgDB::readNodeFiles(commandLine);
// run optimization over the scene graph
osgUtil::Optimizer optimzer;
optimzer.optimize(rootnode);
// initialize the viewer.
osgGLUT::Viewer viewer;
// add a viewport to the viewer and attah the scene graph.
viewer.addViewport( rootnode );
// osgUtil::SceneView* sceneview = viewer.getViewportSceneView(0);
// sceneview->setStereoMode(osgUtil::SceneView::ANAGLYPHIC_STEREO);
// register trackball, flight and drive.
viewer.registerCameraManipulator(new osgUtil::TrackballManipulator);
viewer.registerCameraManipulator(new osgUtil::FlightManipulator);
viewer.registerCameraManipulator(new osgUtil::DriveManipulator);
// open the viewer window.
viewer.open();
// fire up the event loop.
viewer.run();
return 0;

22
src/osg/ColorMatrix.cpp Normal file
View File

@@ -0,0 +1,22 @@
#include <osg/GL>
#include <osg/ColorMatrix>
using namespace osg;
ColorMatrix::ColorMatrix()
{
}
ColorMatrix::~ColorMatrix()
{
}
void ColorMatrix::apply(State&) const
{
// std::cout<<"applying matrix"<<_matrix<<std::endl;
glMatrixMode( GL_COLOR );
glLoadMatrixf( _matrix.ptr() );
glMatrixMode( GL_MODELVIEW );
}

View File

@@ -9,6 +9,7 @@ C++FILES = \
Camera.cpp\
ClipPlane.cpp \
ColorMask.cpp \
ColorMatrix.cpp \
CullFace.cpp\
Depth.cpp \
Drawable.cpp\
@@ -52,6 +53,7 @@ C++FILES = \
Transparency.cpp\
Version.cpp\
Viewport.cpp\
VisualsSettings.cpp\
TARGET_BASENAME = osg
@@ -68,6 +70,7 @@ TARGET_INCLUDE_FILES = \
osg/ClipPlane\
osg/ClippingVolume\
osg/ColorMask\
osg/ColorMatrix\
osg/CullFace\
osg/Depth\
osg/Drawable\
@@ -123,6 +126,7 @@ TARGET_INCLUDE_FILES = \
osg/Vec4\
osg/Version\
osg/Viewport\
osg/VisualsSettings\
osg/mem_ptr\
osg/ref_ptr\

178
src/osg/VisualsSettings.cpp Normal file
View File

@@ -0,0 +1,178 @@
#include <osg/VisualsSettings>
#include <algorithm>
using namespace osg;
VisualsSettings::VisualsSettings(const VisualsSettings& vs):Referenced()
{
copy(vs);
}
VisualsSettings::~VisualsSettings()
{
}
VisualsSettings& VisualsSettings::operator = (const VisualsSettings& vs)
{
if (this==&vs) return *this;
copy(vs);
return *this;
}
void VisualsSettings::copy(const VisualsSettings& vs)
{
_stereoMode = vs._stereoMode;
_eyeSeperation = vs._eyeSeperation;
_screenDistance = vs._screenDistance;
_doubleBuffer = vs._doubleBuffer;
_RGB = vs._RGB;
_depthBuffer = vs._depthBuffer;
_minimumNumberAlphaBits = vs._minimumNumberAlphaBits;
_minimumNumberStencilBits = vs._minimumNumberStencilBits;
}
void VisualsSettings::merge(const VisualsSettings& vs)
{
if (_stereo || vs._stereo) _stereo = true;
// need to think what to do about merging the stereo mode.
if (_doubleBuffer || vs._doubleBuffer) _doubleBuffer = true;
if (_RGB || vs._RGB) _RGB = true;
if (_depthBuffer || vs._depthBuffer) _depthBuffer = true;
if (vs._minimumNumberAlphaBits>_minimumNumberAlphaBits) _minimumNumberAlphaBits = vs._minimumNumberAlphaBits;
if (vs._minimumNumberStencilBits>_minimumNumberStencilBits) _minimumNumberStencilBits = vs._minimumNumberStencilBits;
}
void VisualsSettings::setDefaults()
{
_stereo = false;
_stereoMode = ANAGLYPHIC;
_eyeSeperation = 0.05f;
_screenDistance = 1.0f;
_doubleBuffer = true;
_RGB = true;
_depthBuffer = true;
_minimumNumberAlphaBits = 0;
_minimumNumberStencilBits = 0;
}
void VisualsSettings::readEnvironmentalVariables()
{
char *ptr;
if( (ptr = getenv("OSG_STEREO_MODE")) )
{
if (strcmp(ptr,"QUAD_BUFFER")==0)
{
_stereoMode = QUAD_BUFFER;
}
else
if (strcmp(ptr,"ANAGLYPHIC")==0)
{
_stereoMode = ANAGLYPHIC;
}
else
if (strcmp(ptr,"HORIZONTAL_SPLIT")==0)
{
_stereoMode = HORIZONTAL_SPLIT;
}
else
if (strcmp(ptr,"VERTICAL_SPLIT")==0)
{
_stereoMode = VERTICAL_SPLIT;
}
}
if( (ptr = getenv("OSG_STEREO")) )
{
if (strcmp(ptr,"OFF")==0)
{
_stereo = false;
}
else
if (strcmp(ptr,"ON")==0)
{
_stereo = true;
}
}
if( (ptr = getenv("OSG_EYE_SEPERATION")) )
{
_eyeSeperation = atof(ptr);
}
}
void VisualsSettings::readCommandLine(std::vector<std::string>& commandLine)
{
bool found = true;
while (found)
{
found = false;
// check for stereo based options.
std::vector<std::string>::iterator itr = commandLine.begin();
for(;itr!=commandLine.end();++itr)
{
if (*itr=="-stereo") break;
}
if (itr!=commandLine.end())
{
std::cout << "stereo turned on"<<endl;
_stereo = true;
std::vector<std::string>::iterator start = itr;
++itr;
if (itr!=commandLine.end())
{
if (*itr=="ANAGLYPHIC") { _stereo = true;_stereoMode = ANAGLYPHIC; ++itr; }
else if (*itr=="QUAD_STEREO") { _stereo = true;_stereoMode = QUAD_BUFFER; ++itr; }
else if (*itr=="HORIZONTAL_SPLIT") { _stereo = true;_stereoMode = HORIZONTAL_SPLIT; ++itr; }
else if (*itr=="VERITCAL_SPLIT") { _stereo = true;_stereoMode = VERTICAL_SPLIT; ++itr; }
else if (*itr=="ON") { _stereo = true; ++itr; }
else if (*itr=="OFF") { _stereo = false; ++itr; }
}
commandLine.erase(start,itr);
found = true;
}
// check destination alpha
itr = commandLine.begin();
for(;itr!=commandLine.end();++itr)
{
if (*itr=="-rgba") break;
}
if (itr!=commandLine.end())
{
_RGB = true;
_minimumNumberAlphaBits = 1;
commandLine.erase(itr);
found = true;
}
// check stencil buffer
itr = commandLine.begin();
for(;itr!=commandLine.end();++itr)
{
if (*itr=="-stencil") break;
}
if (itr!=commandLine.end())
{
_minimumNumberStencilBits = 1;
commandLine.erase(itr);
found = true;
}
}
}

View File

@@ -2,6 +2,7 @@
#include <osg/Object>
#include <osg/Image>
#include <osg/Node>
#include <osg/Group>
#include <osgDB/Registry>
#include <osgDB/ReadFile>
@@ -34,3 +35,52 @@ Node* osgDB::readNodeFile(const std::string& filename)
if (rr.error()) notify(WARN) << rr.message() << std::endl;
return NULL;
}
Node* osgDB::readNodeFiles(std::vector<std::string>& commandLine)
{
typedef std::vector<osg::Node*> NodeList;
NodeList nodeList;
// note currently doesn't delete the loaded files yet...
for(std::vector<std::string>::iterator itr=commandLine.begin();
itr!=commandLine.end();
++itr)
{
if ((*itr)[0]!='-')
{
// not an option so assume string is a filename.
osg::Node *node = osgDB::readNodeFile( *itr );
if( node != (osg::Node *)0L )
{
if (node->getName().empty()) node->setName( *itr );
nodeList.push_back(node);
}
}
}
if (nodeList.empty())
{
return NULL;
}
if (nodeList.size()==1)
{
return nodeList.front();
}
else // size >1
{
osg::Group* group = new osg::Group();
for(NodeList::iterator itr=nodeList.begin();
itr!=nodeList.end();
++itr)
{
group->addChild(*itr);
}
return group;
}
}

View File

@@ -69,6 +69,58 @@ Registry* Registry::instance()
return s_nodeFactory.get();
}
void Registry::readCommandLine(std::vector<std::string>& commandLine)
{
bool found = true;
while (found)
{
found = false;
// load library option.
std::vector<std::string>::iterator itr = commandLine.begin();
for(;itr!=commandLine.end();++itr)
{
if (*itr=="-l") break;
}
if (itr!=commandLine.end())
{
std::vector<std::string>::iterator start = itr;
++itr;
if (itr!=commandLine.end())
{
loadLibrary(*itr);
}
commandLine.erase(start,itr);
found = true;
}
// load library for extension
itr = commandLine.begin();
for(;itr!=commandLine.end();++itr)
{
if (*itr=="-e") break;
}
if (itr!=commandLine.end())
{
std::vector<std::string>::iterator start = itr;
++itr;
if (itr!=commandLine.end())
{
std::string libName = osgDB::Registry::instance()->createLibraryNameForExt(*itr);
loadLibrary(libName);
}
commandLine.erase(start,itr);
found = true;
}
}
}
void Registry::addDotOsgWrapper(DotOsgWrapper* wrapper)
{
if (wrapper==0L) return;

View File

@@ -128,6 +128,7 @@ Viewer::Viewer()
_frameStamp = new osg::FrameStamp;
_visualsSettings = new osg::VisualsSettings;
}
@@ -135,6 +136,11 @@ Viewer::~Viewer()
{
}
/** read the command line string list, removing any matched control sequences.*/
void Viewer::readCommandLine(std::vector<std::string>& commandLine)
{
_visualsSettings->readCommandLine(commandLine);
}
/**
* Configure and open the GLUT window for this Viewer
@@ -177,6 +183,8 @@ bool Viewer::open()
bool needQuadBufferStereo = false;
// do we need quad buffer stereo?
// Set the absolute viewport for each SceneView based on the
// relative viewport coordinates given to us
for(itr=_viewportList.begin();
@@ -199,9 +207,21 @@ bool Viewer::open()
// osg::notify(osg::INFO) << "Handled reshape "<< std::endl;
}
if (sceneView->getStereoMode()==osgUtil::SceneView::QUAD_BUFFER_STEREO) needQuadBufferStereo = true;
const osg::VisualsSettings* vs = sceneView->getVisualsSettings();
if (vs)
{
_visualsSettings->merge(*vs);
}
else
{
// one does not already exist so attach the viewers visualsSettins to the SceneView
sceneView->setVisualsSettings(_visualsSettings.get());
}
}
if (_visualsSettings->getStereo() &&
_visualsSettings->getStereoMode()==osg::VisualsSettings::QUAD_BUFFER) needQuadBufferStereo = true;
//glutInit( &argc, argv ); // I moved this into main to avoid passing
// argc and argv to the Viewer
@@ -211,6 +231,7 @@ bool Viewer::open()
// traverse the scene graphs gathering the requirements of the OpenGL buffers.
osgUtil::VisualsRequirementsVisitor vrv;
vrv.setVisualsSettings(_visualsSettings.get());
for(itr=_viewportList.begin();
itr!=_viewportList.end();
++itr)
@@ -219,13 +240,13 @@ bool Viewer::open()
if (node) node->accept(vrv);
}
#ifdef _DEBUG
vrv.setMinimumNumStencilBits(8); //gwm 12.8.01 to force stencils available for DC test
_visualsSettings->setMinimumNumStencilBits(8); //gwm 12.8.01 to force stencils available for DC test
#endif
// set up each render stage to clear the appropriate buffers.
GLbitfield clear_mask=0;
if (vrv.requiresRGB()) clear_mask |= GL_COLOR_BUFFER_BIT;
if (vrv.requiresDepthBuffer()) clear_mask |= GL_DEPTH_BUFFER_BIT;
if (vrv.requiresStencilBuffer()) clear_mask |= GL_STENCIL_BUFFER_BIT;
if (_visualsSettings->getRGB()) clear_mask |= GL_COLOR_BUFFER_BIT;
if (_visualsSettings->getDepthBuffer()) clear_mask |= GL_DEPTH_BUFFER_BIT;
if (_visualsSettings->getStencilBuffer()) clear_mask |= GL_STENCIL_BUFFER_BIT;
for(itr=_viewportList.begin();
itr!=_viewportList.end();
@@ -238,13 +259,13 @@ bool Viewer::open()
// set the GLUT display mode bit mask up to handle it.
unsigned int displayMode=0;
if (vrv.requiresDoubleBuffer()) displayMode |= GLUT_DOUBLE;
else displayMode |= GLUT_SINGLE;
if (vrv.requiresRGB()) displayMode |= GLUT_RGB;
if (vrv.requiresDepthBuffer()) displayMode |= GLUT_DEPTH;
if (vrv.requiresAlphaBuffer()) displayMode |= GLUT_ALPHA;
if (vrv.requiresStencilBuffer()) displayMode |= GLUT_STENCIL;
if (needQuadBufferStereo) displayMode |= GLUT_STEREO;
if (_visualsSettings->getDoubleBuffer()) displayMode |= GLUT_DOUBLE;
else displayMode |= GLUT_SINGLE;
if (_visualsSettings->getRGB()) displayMode |= GLUT_RGB;
if (_visualsSettings->getDepthBuffer()) displayMode |= GLUT_DEPTH;
if (_visualsSettings->getAlphaBuffer()) displayMode |= GLUT_ALPHA;
if (_visualsSettings->getStencilBuffer()) displayMode |= GLUT_STENCIL;
if (needQuadBufferStereo) displayMode |= GLUT_STEREO;
// and we'll add in multisample so that on systems like Onyx's can
// go ahead and use there loverly anti-aliasing. This is ignored

View File

@@ -0,0 +1,67 @@
#include <osg/ColorMatrix>
#include <osgDB/Registry>
#include <osgDB/Input>
#include <osgDB/Output>
using namespace osg;
using namespace osgDB;
// forward declare functions to use later.
bool ColorMatrix_readLocalData(Object& obj, Input& fr);
bool ColorMatrix_writeLocalData(const Object& obj, Output& fw);
// register the read and write functions with the osgDB::Registry.
RegisterDotOsgWrapperProxy g_ColorMatrixProxy
(
new osg::ColorMatrix,
"ColorMatrix",
"Object StateAttribute ColorMatrix",
&ColorMatrix_readLocalData,
&ColorMatrix_writeLocalData
);
bool ColorMatrix_readLocalData(Object& obj, Input& fr)
{
bool iteratorAdvanced = false;
ColorMatrix& colorMatrix = static_cast<ColorMatrix&>(obj);
bool matched = true;
for(int k=0;k<16 && matched;++k)
{
matched = fr[k].isFloat();
}
if (matched)
{
Matrix& matrix = colorMatrix.getMatrix();
int k=0;
for(int i=0;i<4;++i)
{
for(int j=0;j<4;++j)
{
fr[k].getFloat(matrix(i,j));
k++;
}
}
fr += 16;
iteratorAdvanced = true;
}
return iteratorAdvanced;
}
bool ColorMatrix_writeLocalData(const Object& obj, Output& fw)
{
const ColorMatrix& colorMatrix = static_cast<const ColorMatrix&>(obj);
const Matrix& matrix = colorMatrix.getMatrix();
fw.indent() << matrix(0,0) << " " << matrix(0,1) << " " << matrix(0,2) << " " << matrix(0,3) << std::endl;
fw.indent() << matrix(1,0) << " " << matrix(1,1) << " " << matrix(1,2) << " " << matrix(1,3) << std::endl;
fw.indent() << matrix(2,0) << " " << matrix(2,1) << " " << matrix(2,2) << " " << matrix(2,3) << std::endl;
fw.indent() << matrix(3,0) << " " << matrix(3,1) << " " << matrix(3,2) << " " << matrix(3,3) << std::endl;
return true;
}

View File

@@ -6,6 +6,7 @@ C++FILES = \
Billboard.cpp\
ClipPlane.cpp\
ColorMask.cpp\
ColorMatrix.cpp\
CullFace.cpp\
Depth.cpp\
Drawable.cpp\

View File

@@ -1,8 +1,8 @@
#include "osg/TexMat"
#include <osg/TexMat>
#include "osgDB/Registry"
#include "osgDB/Input"
#include "osgDB/Output"
#include <osgDB/Registry>
#include <osgDB/Input>
#include <osgDB/Output>
using namespace osg;
using namespace osgDB;

View File

@@ -6,6 +6,7 @@
#include <osg/Texture>
#include <osg/AlphaFunc>
#include <osg/TexEnv>
#include <osg/ColorMatrix>
#include <osg/GLU>
@@ -52,15 +53,6 @@ void SceneView::setDefaults()
_state = new State;
_camera = new Camera;
_stereoMode = MONO;
_leftEye.set(-0.03f,0.0f,0.0f);
_rightEye.set(0.03f,0.0f,0.0f);
_focalLength = 1.0f;
_screenDistance = 1.0f;
_rendergraph = new RenderGraph;
_renderStage = new RenderStage;
@@ -143,7 +135,7 @@ void SceneView::app()
void SceneView::cull()
{
if (!_sceneData) return;
if (!_sceneData || !_viewport->valid()) return;
if (!_initCalled) init();
@@ -276,7 +268,7 @@ void SceneView::cull()
void SceneView::draw()
{
if (!_sceneData) return;
if (!_sceneData || !_viewport->valid()) return;
if (!_state)
{
@@ -290,6 +282,7 @@ void SceneView::draw()
_state->reset();
_state->setFrameStamp(_frameStamp.get());
_state->setVisualsSettings(_visualsSettings.get());
// note, to support multi-pipe systems the deletion of OpenGL display list
// and texture objects is deferred until the OpenGL context is the correct
@@ -299,67 +292,84 @@ void SceneView::draw()
osg::Texture::flushDeletedTextureObjects(_state->getContextID());
RenderLeaf* previous = NULL;
switch(getStereoMode())
{
case(MONO):
{
_renderStage->draw(*_state,previous);
}
break;
case(QUAD_BUFFER_STEREO):
{
osg::ref_ptr<osg::Camera> left_camera = new osg::Camera(*_camera);
osg::ref_ptr<osg::Camera> right_camera = new osg::Camera(*_camera);
float iod = 0.05f;
left_camera->adjustEyeOffsetForStereo(osg::Vec3(-iod*0.5,0.0f,0.0f),_screenDistance);
right_camera->adjustEyeOffsetForStereo(osg::Vec3(iod*0.5,0.0f,0.0f),_screenDistance);
glDrawBuffer(GL_BACK_LEFT);
_renderStage->setCamera(left_camera.get());
_renderStage->draw(*_state,previous);
glDrawBuffer(GL_BACK_RIGHT);
_renderStage->setCamera(right_camera.get());
_renderStage->_stageDrawnThisFrame = false;
_renderStage->draw(*_state,previous);
}
break;
case(ANAGLYPHIC_STEREO):
{
osg::ref_ptr<osg::Camera> left_camera = new osg::Camera(*_camera);
osg::ref_ptr<osg::Camera> right_camera = new osg::Camera(*_camera);
float iod = 0.05f;
left_camera->adjustEyeOffsetForStereo(osg::Vec3(-iod*0.5,0.0f,0.0f),_screenDistance);
right_camera->adjustEyeOffsetForStereo(osg::Vec3(iod*0.5,0.0f,0.0f),_screenDistance);
osg::ColorMask* red = new osg::ColorMask;
osg::ColorMask* green = new osg::ColorMask;
red->setMask(true,false,false,true);
_renderStage->setColorMask(red);
_renderStage->setCamera(left_camera.get());
_renderStage->draw(*_state,previous);
green->setMask(false,true,true,true);
_renderStage->setColorMask(green);
_renderStage->_stageDrawnThisFrame = false;
_renderStage->setCamera(right_camera.get());
_renderStage->draw(*_state,previous);
}
break;
default:
{
osg::notify(osg::NOTICE)<<"Warning: stereo camera mode not implemented yet."<< std::endl;
_renderStage->draw(*_state,previous);
}
break;
}
if (_visualsSettings.valid() && _visualsSettings->getStereo())
{
switch(_visualsSettings->getStereoMode())
{
case(osg::VisualsSettings::QUAD_BUFFER):
{
osg::ref_ptr<osg::Camera> left_camera = new osg::Camera(*_camera);
osg::ref_ptr<osg::Camera> right_camera = new osg::Camera(*_camera);
float iod = _visualsSettings->getEyeSeperation();
float screenDistance = _visualsSettings->getEyeSeperation();
left_camera->adjustEyeOffsetForStereo(osg::Vec3(-iod*0.5,0.0f,0.0f),screenDistance);
right_camera->adjustEyeOffsetForStereo(osg::Vec3(iod*0.5,0.0f,0.0f),screenDistance);
glDrawBuffer(GL_BACK_LEFT);
_renderStage->setCamera(left_camera.get());
_renderStage->draw(*_state,previous);
glDrawBuffer(GL_BACK_RIGHT);
_renderStage->setCamera(right_camera.get());
_renderStage->_stageDrawnThisFrame = false;
_renderStage->draw(*_state,previous);
}
break;
case(osg::VisualsSettings::ANAGLYPHIC):
{
osg::ref_ptr<osg::Camera> left_camera = new osg::Camera(*_camera);
osg::ref_ptr<osg::Camera> right_camera = new osg::Camera(*_camera);
float iod = _visualsSettings->getEyeSeperation();
float screenDistance = _visualsSettings->getScreenDistance();
left_camera->adjustEyeOffsetForStereo(osg::Vec3(-iod*0.5,0.0f,0.0f),screenDistance);
right_camera->adjustEyeOffsetForStereo(osg::Vec3(iod*0.5,0.0f,0.0f),screenDistance);
osg::ColorMatrix* cm = new osg::ColorMatrix;
cm->setMatrix(osg::Matrix(0.3,0.3,0.3,0.0,
0.6,0.6,0.6,0.0,
0.1,0.1,0.1,0.0,
0.0,0.0,0.0,1.0));
_globalState->setAttribute(cm);
osg::ColorMask* red = new osg::ColorMask;
osg::ColorMask* green = new osg::ColorMask;
red->setMask(true,false,false,true);
_renderStage->setColorMask(red);
_renderStage->setCamera(left_camera.get());
_renderStage->draw(*_state,previous);
green->setMask(false,true,true,true);
_renderStage->setColorMask(green);
_renderStage->_stageDrawnThisFrame = false;
_renderStage->setCamera(right_camera.get());
_renderStage->draw(*_state,previous);
}
break;
default:
{
osg::notify(osg::NOTICE)<<"Warning: stereo camera mode not implemented yet."<< std::endl;
_renderStage->draw(*_state,previous);
}
break;
}
}
else
{
// bog standard draw.
_renderStage->draw(*_state,previous);
}
GLenum errorNo = glGetError();
if (errorNo!=GL_NO_ERROR)
{

View File

@@ -16,25 +16,29 @@ using namespace osgUtil;
VisualsRequirementsVisitor::VisualsRequirementsVisitor()
{
setTraversalMode(NodeVisitor::TRAVERSE_ALL_CHILDREN);
_requiresDoubleBuffer = true;
_requiresRBG = true;
_requiresDepthBuffer = true;
_minimumNumberAlphaBits = 0;
_minimumNumberStencilBits = 0;
}
void VisualsRequirementsVisitor::applyStateSet(StateSet& stateset)
{
if (!_vs) _vs = new osg::VisualsSettings;
unsigned int min = 0; // assume stencil not needed by this stateset.
if (stateset.getMode(GL_STENCIL_TEST) & StateAttribute::ON)
{
_minimumNumberStencilBits = 1;
min = 1; // number stencil bits we need at least.
}
if (stateset.getAttribute(StateAttribute::STENCIL))
{
_minimumNumberStencilBits = 1;
min = 1; // number stencil bits we need at least.
}
if (min>_vs->getMinimumNumStencilBits())
{
// only update if new minimum exceeds previous minimum.
_vs->setMinimumNumStencilBits(min);
}
}
void VisualsRequirementsVisitor::apply(Node& node)
@@ -59,6 +63,14 @@ void VisualsRequirementsVisitor::apply(Geode& geode)
void VisualsRequirementsVisitor::apply(Impostor& impostor)
{
_minimumNumberAlphaBits = 1;
if (!_vs) _vs = new osg::VisualsSettings;
unsigned int min = 1; // number alpha bits we need at least.
if (min>_vs->getMinimumNumAlphaBits())
{
// only update if new minimum exceeds previous minimum.
_vs->setMinimumNumAlphaBits(min);
}
apply((Node&)impostor);
}