From Galen Faidley," Please find attached the modifications to get the new checkerboard

stereo format to work.  It's a good thing I tested these on a TV
before submitting them since I did indeed have a bug.  One thing I
did not test was to see how this would work in windowed mode.  Does
the interlaced stereo code have support for 'absolute' positions?
For example a given pixel on the screen is always shown in a given
eye no matter where the graphics context is placed?
"
This commit is contained in:
Robert Osfield 2007-08-23 14:31:23 +00:00
parent 616f64cf2c
commit 6827104532
5 changed files with 130 additions and 14 deletions

View File

@ -94,7 +94,8 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced
LEFT_EYE, LEFT_EYE,
RIGHT_EYE, RIGHT_EYE,
HORIZONTAL_INTERLACE, HORIZONTAL_INTERLACE,
VERTICAL_INTERLACE VERTICAL_INTERLACE,
CHECKERBOARD
}; };
void setStereoMode(StereoMode mode) { _stereoMode = mode; } void setStereoMode(StereoMode mode) { _stereoMode = mode; }

View File

@ -230,6 +230,10 @@ void DisplaySettings::readEnvironmentalVariables()
{ {
_stereoMode = VERTICAL_INTERLACE; _stereoMode = VERTICAL_INTERLACE;
} }
else if (strcmp(ptr,"CHECKERBOARD")==0)
{
_stereoMode = CHECKERBOARD;
}
} }
if( (ptr = getenv("OSG_STEREO")) != 0) if( (ptr = getenv("OSG_STEREO")) != 0)
@ -357,7 +361,7 @@ void DisplaySettings::readCommandLine(ArgumentParser& arguments)
{ {
arguments.getApplicationUsage()->addCommandLineOption("--display <type>","MONITOR | POWERWALL | REALITY_CENTER | HEAD_MOUNTED_DISPLAY"); arguments.getApplicationUsage()->addCommandLineOption("--display <type>","MONITOR | POWERWALL | REALITY_CENTER | HEAD_MOUNTED_DISPLAY");
arguments.getApplicationUsage()->addCommandLineOption("--stereo","Use default stereo mode which is ANAGLYPHIC if not overriden by environmental variable"); arguments.getApplicationUsage()->addCommandLineOption("--stereo","Use default stereo mode which is ANAGLYPHIC if not overriden by environmental variable");
arguments.getApplicationUsage()->addCommandLineOption("--stereo <mode>","ANAGLYPHIC | QUAD_BUFFER | HORIZONTAL_SPLIT | VERTICAL_SPLIT | LEFT_EYE | RIGHT_EYE | ON | OFF "); arguments.getApplicationUsage()->addCommandLineOption("--stereo <mode>","ANAGLYPHIC | QUAD_BUFFER | HORIZONTAL_SPLIT | VERTICAL_SPLIT | LEFT_EYE | RIGHT_EYE | HORIZONTAL_INTERLACE | VERTICAL_INTERLACE | CHECKERBOARD | ON | OFF ");
arguments.getApplicationUsage()->addCommandLineOption("--rgba","Request a RGBA color buffer visual"); arguments.getApplicationUsage()->addCommandLineOption("--rgba","Request a RGBA color buffer visual");
arguments.getApplicationUsage()->addCommandLineOption("--stencil","Request a stencil buffer visual"); arguments.getApplicationUsage()->addCommandLineOption("--stencil","Request a stencil buffer visual");
arguments.getApplicationUsage()->addCommandLineOption("--accum-rgb","Request a rgb accumulator buffer visual"); arguments.getApplicationUsage()->addCommandLineOption("--accum-rgb","Request a rgb accumulator buffer visual");
@ -385,6 +389,7 @@ void DisplaySettings::readCommandLine(ArgumentParser& arguments)
else if (arguments.match(pos+1,"VERTICAL_SPLIT")) { arguments.remove(pos,2); _stereo = true;_stereoMode = VERTICAL_SPLIT; } else if (arguments.match(pos+1,"VERTICAL_SPLIT")) { arguments.remove(pos,2); _stereo = true;_stereoMode = VERTICAL_SPLIT; }
else if (arguments.match(pos+1,"HORIZONTAL_INTERLACE")) { arguments.remove(pos,2); _stereo = true;_stereoMode = HORIZONTAL_INTERLACE; } else if (arguments.match(pos+1,"HORIZONTAL_INTERLACE")) { arguments.remove(pos,2); _stereo = true;_stereoMode = HORIZONTAL_INTERLACE; }
else if (arguments.match(pos+1,"VERTICAL_INTERLACE")) { arguments.remove(pos,2); _stereo = true;_stereoMode = VERTICAL_INTERLACE; } else if (arguments.match(pos+1,"VERTICAL_INTERLACE")) { arguments.remove(pos,2); _stereo = true;_stereoMode = VERTICAL_INTERLACE; }
else if (arguments.match(pos+1,"CHECKERBOARD")) { arguments.remove(pos,2); _stereo = true;_stereoMode = CHECKERBOARD; }
else if (arguments.match(pos+1,"LEFT_EYE")) { arguments.remove(pos,2); _stereo = true;_stereoMode = LEFT_EYE; } else if (arguments.match(pos+1,"LEFT_EYE")) { arguments.remove(pos,2); _stereo = true;_stereoMode = LEFT_EYE; }
else if (arguments.match(pos+1,"RIGHT_EYE")) { arguments.remove(pos,2); _stereo = true;_stereoMode = RIGHT_EYE; } else if (arguments.match(pos+1,"RIGHT_EYE")) { arguments.remove(pos,2); _stereo = true;_stereoMode = RIGHT_EYE; }
else if (arguments.match(pos+1,"ON")) { arguments.remove(pos,2); _stereo = true; } else if (arguments.match(pos+1,"ON")) { arguments.remove(pos,2); _stereo = true; }

View File

@ -84,8 +84,44 @@ static const GLubyte patternHorzEven[] = {
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00}; 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00};
SceneView::SceneView(DisplaySettings* ds): // 32 x 32 bit array every row is a horizontal line of pixels
osg::Object(true) // and the (bitwise) columns a vertical line
// The following is a checkerboard pattern
static const GLubyte patternCheckerboard[] = {
0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA,
0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA,
0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA,
0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA,
0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA,
0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA,
0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA,
0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA,
0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA,
0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA,
0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA,
0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA,
0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA,
0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA,
0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA,
0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA};
SceneView::SceneView(DisplaySettings* ds)
{ {
_displaySettings = ds; _displaySettings = ds;
@ -132,16 +168,8 @@ SceneView::SceneView(const SceneView& rhs, const osg::CopyOp& copyop):
_prioritizeTextures = rhs._prioritizeTextures; _prioritizeTextures = rhs._prioritizeTextures;
if (rhs._camera.valid()) _camera = rhs._camera;
{ _cameraWithOwnership = rhs._cameraWithOwnership;
setCamera(new osg::Camera(*rhs._camera,copyop), rhs._camera.get()==rhs._cameraWithOwnership.get());
}
else
{
setCamera(new Camera);
_camera->setViewport(new Viewport);
_camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f));
}
_initCalled = false; _initCalled = false;
@ -1308,6 +1336,83 @@ void SceneView::draw()
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
} }
break; break;
case(osg::DisplaySettings::CHECKERBOARD):
{
if( getDrawBufferValue() != GL_NONE)
{
_renderStageLeft->setDrawBuffer(getDrawBufferValue());
_renderStageLeft->setReadBuffer(getDrawBufferValue());
_renderStageRight->setDrawBuffer(getDrawBufferValue());
_renderStageRight->setReadBuffer(getDrawBufferValue());
}
_localStateSet->setAttribute(getViewport());
// ensure that all color planes are active.
osg::ColorMask* cmask = static_cast<osg::ColorMask*>(_localStateSet->getAttribute(osg::StateAttribute::COLORMASK));
if (cmask)
{
cmask->setMask(true,true,true,true);
}
else
{
cmask = new osg::ColorMask(true,true,true,true);
_localStateSet->setAttribute(cmask);
}
_renderStageLeft->setColorMask(cmask);
_renderStageRight->setColorMask(cmask);
_renderStageLeft->drawPreRenderStages(_renderInfo,previous);
_renderStageRight->drawPreRenderStages(_renderInfo,previous);
glEnable(GL_STENCIL_TEST);
if(_redrawInterlacedStereoStencilMask ||
_interlacedStereoStencilWidth != getViewport()->width() ||
_interlacedStereoStencilHeight != getViewport()->height() )
{
getViewport()->apply(*state);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(getViewport()->x(), getViewport()->width(), getViewport()->y(), getViewport()->height(), -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
glStencilMask(~0u);
glClear(GL_STENCIL_BUFFER_BIT);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
glStencilFunc(GL_ALWAYS, 1, ~0u);
glPolygonStipple(patternCheckerboard);
glEnable(GL_POLYGON_STIPPLE);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glRecti(static_cast<GLint>(getViewport()->x()),
static_cast<GLint>(getViewport()->y()),
static_cast<GLint>(getViewport()->width()),
static_cast<GLint>(getViewport()->height()) );
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDisable(GL_POLYGON_STIPPLE);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
_redrawInterlacedStereoStencilMask = false;
_interlacedStereoStencilWidth = static_cast<int>(getViewport()->width());
_interlacedStereoStencilHeight = static_cast<int>(getViewport()->height());
}
_renderStageLeft->setClearMask(_renderStageLeft->getClearMask() & ~(GL_STENCIL_BUFFER_BIT));
_renderStageRight->setClearMask(_renderStageRight->getClearMask() & ~(GL_STENCIL_BUFFER_BIT|GL_COLOR_BUFFER_BIT));
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glStencilFunc(GL_EQUAL, 0, ~0u);
_renderStageLeft->draw(_renderInfo,previous);
glStencilFunc(GL_NOTEQUAL, 0, ~0u);
_renderStageRight->draw(_renderInfo,previous);
glDisable(GL_STENCIL_TEST);
}
break;
default: default:
{ {
osg::notify(osg::NOTICE)<<"Warning: stereo mode not implemented yet."<< std::endl; osg::notify(osg::NOTICE)<<"Warning: stereo mode not implemented yet."<< std::endl;

View File

@ -370,6 +370,7 @@ void View::setUpViewAcrossAllScreens()
{ {
case(osg::DisplaySettings::QUAD_BUFFER): traits->quadBufferStereo = true; break; case(osg::DisplaySettings::QUAD_BUFFER): traits->quadBufferStereo = true; break;
case(osg::DisplaySettings::VERTICAL_INTERLACE): case(osg::DisplaySettings::VERTICAL_INTERLACE):
case(osg::DisplaySettings::CHECKERBOARD):
case(osg::DisplaySettings::HORIZONTAL_INTERLACE): traits->stencil = 8; break; case(osg::DisplaySettings::HORIZONTAL_INTERLACE): traits->stencil = 8; break;
default: break; default: break;
} }
@ -450,6 +451,7 @@ void View::setUpViewAcrossAllScreens()
{ {
case(osg::DisplaySettings::QUAD_BUFFER): traits->quadBufferStereo = true; break; case(osg::DisplaySettings::QUAD_BUFFER): traits->quadBufferStereo = true; break;
case(osg::DisplaySettings::VERTICAL_INTERLACE): case(osg::DisplaySettings::VERTICAL_INTERLACE):
case(osg::DisplaySettings::CHECKERBOARD):
case(osg::DisplaySettings::HORIZONTAL_INTERLACE): traits->stencil = 8; break; case(osg::DisplaySettings::HORIZONTAL_INTERLACE): traits->stencil = 8; break;
default: break; default: break;
} }
@ -529,6 +531,7 @@ void View::setUpViewInWindow(int x, int y, int width, int height, unsigned int s
{ {
case(osg::DisplaySettings::QUAD_BUFFER): traits->quadBufferStereo = true; break; case(osg::DisplaySettings::QUAD_BUFFER): traits->quadBufferStereo = true; break;
case(osg::DisplaySettings::VERTICAL_INTERLACE): case(osg::DisplaySettings::VERTICAL_INTERLACE):
case(osg::DisplaySettings::CHECKERBOARD):
case(osg::DisplaySettings::HORIZONTAL_INTERLACE): traits->stencil = 8; break; case(osg::DisplaySettings::HORIZONTAL_INTERLACE): traits->stencil = 8; break;
default: break; default: break;
} }
@ -610,6 +613,7 @@ void View::setUpViewOnSingleScreen(unsigned int screenNum)
{ {
case(osg::DisplaySettings::QUAD_BUFFER): traits->quadBufferStereo = true; break; case(osg::DisplaySettings::QUAD_BUFFER): traits->quadBufferStereo = true; break;
case(osg::DisplaySettings::VERTICAL_INTERLACE): case(osg::DisplaySettings::VERTICAL_INTERLACE):
case(osg::DisplaySettings::CHECKERBOARD):
case(osg::DisplaySettings::HORIZONTAL_INTERLACE): traits->stencil = 8; break; case(osg::DisplaySettings::HORIZONTAL_INTERLACE): traits->stencil = 8; break;
default: break; default: break;
} }

View File

@ -39,6 +39,7 @@ BEGIN_ENUM_REFLECTOR(osg::DisplaySettings::StereoMode)
I_EnumLabel(osg::DisplaySettings::RIGHT_EYE); I_EnumLabel(osg::DisplaySettings::RIGHT_EYE);
I_EnumLabel(osg::DisplaySettings::HORIZONTAL_INTERLACE); I_EnumLabel(osg::DisplaySettings::HORIZONTAL_INTERLACE);
I_EnumLabel(osg::DisplaySettings::VERTICAL_INTERLACE); I_EnumLabel(osg::DisplaySettings::VERTICAL_INTERLACE);
I_EnumLabel(osg::DisplaySettings::CHECKERBOARD);
END_REFLECTOR END_REFLECTOR
BEGIN_ENUM_REFLECTOR(osg::DisplaySettings::SplitStereoHorizontalEyeMapping) BEGIN_ENUM_REFLECTOR(osg::DisplaySettings::SplitStereoHorizontalEyeMapping)