Modifications for Varrier and Alioscopy
Changes made for the implementation of varrier and alioscopy under covise on kaustalio:
Contents |
OpenSceneGraph-2.8 Files Modified
covise/extern_libs/src/OpenSceneGraph/include/osg/DisplaySettings
in class OSG_EXPORT DisplaySettings : public osg::Referenced
enum StereoMode { QUAD_BUFFER, ANAGLYPHIC, HORIZONTAL_SPLIT, VERTICAL_SPLIT, LEFT_EYE, RIGHT_EYE, HORIZONTAL_INTERLACE, VERTICAL_INTERLACE, CHECKERBOARD, VARRIER, // ADDED FOR VARRIER ALIOSCOPY // ADDED FOR ALIOSCOPY };
covise/extern_libs/src/OpenSceneGraph/include/osgUtil/SceneView
include added:
#include </home/covise/covise/extern_libs/include/VarrierCombiner.h> #include </home/covise/covise/extern_libs/include/coInterleaver.h>
in struct ComputeStereoMatricesCallback:public osg::Referenced of the SceneView Class, following functions added:
virtual osg::Matrixd computeEyeProjection(int i) const { (void)i; return osg::Matrixd(); } virtual osg::Matrixd computeEyeView(int i) const { (void)i; return osg::Matrixd(); }
in class OSGUTIL_EXPORT SceneView : public osg::Object, public osg::CullSettings
public inline functions added: inline osg::Matrixd computeEyeProjection(int i) const { if (_computeStereoMatricesCallback.valid()) return _computeStereoMatricesCallback->computeEyeProjection(i); else return osg::Matrixd(); } inline osg::Matrixd computeEyeView(int i) const { if (_computeStereoMatricesCallback.valid()) return _computeStereoMatricesCallback->computeEyeView(i); else return osg::Matrixd(); } public functions added: static void setVarrierTestPattern(bool b); static bool isVarrierTestPattern(); static void toggleAlioscopyDebug(); protected variables added: osg::ref_ptr<osgUtil::CullVisitor> * _cullVisitorAlioscopy; osg::ref_ptr<osgUtil::StateGraph> * _rendergraphAlioscopy; osg::ref_ptr<osgUtil::RenderStage> * _renderStageAlioscopy; static bool _varrierTestPattern; static VarrierCombiner** _varrier; static float _alioscopyDebug; static il_context ** _alioscopyContext; static il_display ** _alioscopyDisplay; static int _alioscopyEyes; static float _alioscopyIPD; static float _alioscopyIPDmm; static float _alioscopyViewDistance; float * _alioscopyEyePosition; int _delayCount; // HACK WARNING: why is this necessary? tried putting this in ::init() but wouldn't get called
covise/extern_libs/src/OpenSceneGraph/src/osg/DisplaySettings.cpp
Change the line:
static ApplicationUsageProxy DisplaySetting_e1(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_STEREO_MODE <mode>","QUAD_BUFFER | ANAGLYPHIC | HORIZONTAL_SPLIT | VERTICAL_SPLIT | LEFT_EYE | RIGHT_EYE | VERTICAL_INTERLACE | HORIZONTAL_INTERLACE”);
to the following:
static ApplicationUsageProxy DisplaySetting_e1(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_STEREO_MODE <mode>","QUAD_BUFFER | ANAGLYPHIC | HORIZONTAL_SPLIT | VERTICAL_SPLIT | LEFT_EYE | RIGHT_EYE | VERTICAL_INTERLACE | HORIZONTAL_INTERLACE | VARRIER | ALIOSCOPY");// VARRIER & ALIOSCOPY ADDED
in void DisplaySettings::readEnvironmentalVariables()
if( (ptr = getenv("OSG_STEREO_MODE")) != 0) { if (strcmp(ptr,"QUAD_BUFFER")==0) { _stereoMode = QUAD_BUFFER; } ...... else if (strcmp(ptr,"VARRIER")==0) { _stereoMode = VARRIER; } else if (strcmp(ptr,"ALIOSCOPY")==0) { _stereoMode = ALIOSCOPY; } }
in void DisplaySettings::readCommandLine(ArgumentParser& arguments)
if (arguments.getApplicationUsage()) { 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 <mode>","ANAGLYPHIC | QUAD_BUFFER | HORIZONTAL_SPLIT | VERTICAL_SPLIT | VARRIER | ALIOSCOPY | LEFT_EYE | RIGHT_EYE | HORIZONTAL_INTERLACE | VERTICAL_INTERLACE | CHECKERBOARD | ON | OFF "); // VARRIER & ALIOSCOPY ADDED ...... while ((pos=arguments.find("--stereo"))!=0) { if (arguments.match(pos+1,"ANAGLYPHIC")) { arguments.remove(pos,2); _stereo = true;_stereoMode = ANAGLYPHIC; } else if (arguments.match(pos+1,"QUAD_BUFFER")) { arguments.remove(pos,2); _stereo = true;_stereoMode = QUAD_BUFFER; } else if (arguments.match(pos+1,"HORIZONTAL_SPLIT")) { arguments.remove(pos,2); _stereo = true;_stereoMode = HORIZONTAL_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,"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,"VARRIER")) { arguments.remove(pos,2); _stereo = true;_stereoMode = VARRIER; } // ADDED FOR VARRIER else if (arguments.match(pos+1,"ALIOSCOPY")) { arguments.remove(pos,2); _stereo = true;_stereoMode = ALIOSCOPY; } // ADDED FOR ALIOSCOPY .....
covise/extern_libs/src/OpenSceneGraph/src/osgUtil/SceneView.cpp
Added the following includes and defines:
#include <iostream> #include <sstream> #include <sys/time.h> //#define ALIOSCOPY1X4 //#define ALIOSCOPY2X2 //#define ALIOSCOPY3X2 #define ALIOSCOPY3X3
added following declarations:
VVarrierCombiner ** SceneView::_varrier = NULL; bool SceneView::_varrierTestPattern = false; float SceneView::_alioscopyDebug = 1.0; il_context ** SceneView::_alioscopyContext = NULL; il_display ** SceneView::_alioscopyDisplay = NULL; int SceneView::_alioscopyEyes = 8; float SceneView::_alioscopyIPD = 0.208; float SceneView::_alioscopyViewDistance = 9.7; float SceneView::_alioscopyIPDmm = 63.3984;
added the following static function:
static void read_dsp_conf(const char *filename, struct il_display *D, int eyes) { /* Parse the display options from the named config file. */ FILE *fp; if ((fp = fopen(filename, "r"))) { char s[256]; char k[256]; char *v; int i; int n; float f; while (fgets(s, 256, fp)) { sscanf(s, "%s%n", k, &n); v = s + n; if (!strcmp(k, "pitch")) sscanf(v, "%f", &D->pitch); else if (!strcmp(k, "angle")) sscanf(v, "%f", &D->angle); else if (!strcmp(k, "thick")) sscanf(v, "%f", &D->thick); else if (!strcmp(k, "shift")) sscanf(v, "%f", &D->shift); else if (!strcmp(k, "cycle")) { sscanf(v, "%d %f", &i, &f); if (0 <= i && i < eyes) D->cycle[i] = f; } else if (!strcmp(k, "step0")) { sscanf(v, "%d %f", &i, &f); if (0 <= i && i < eyes) D->step0[i] = f; } else if (!strcmp(k, "step1")) { sscanf(v, "%d %f", &i, &f); if (0 <= i && i < eyes) D->step1[i] = f; } else if (!strcmp(k, "step2")) { sscanf(v, "%d %f", &i, &f); if (0 <= i && i < eyes) D->step2[i] = f; } else if (!strcmp(k, "step3")) { sscanf(v, "%d %f", &i, &f); if (0 <= i && i < eyes) D->step3[i] = f; } else if (!strcmp(k, "depth")) { sscanf(v, "%d %f", &i, &f); if (0 <= i && i < eyes) D->depth[i] = f; } else if (!strcmp(k, "screen_BL")) sscanf(v, "%f %f %f\n", D->BL+0, D->BL+1, D->BL+2); else if (!strcmp(k, "screen_BR")) sscanf(v, "%f %f %f\n", D->BR+0, D->BR+1, D->BR+2); else if (!strcmp(k, "screen_TL")) sscanf(v, "%f %f %f\n", D->TL+0, D->TL+1, D->TL+2); } fclose(fp); } }
in SceneView::SceneView(DisplaySettings* ds): at end
_varrier = NULL; _delayCount = 10; _cullVisitorAlioscopy = NULL; _rendergraphAlioscopy = NULL; _renderStageAlioscopy = NULL;
in SceneView::SceneView(const SceneView& rhs, const osg::CopyOp& copyop): at end
_varrier = rhs._varrier; _delayCount = rhs._delayCount; _cullVisitorAlioscopy = rhs._cullVisitorAlioscopy; _rendergraphAlioscopy = rhs._rendergraphAlioscopy; _renderStageAlioscopy = rhs._renderStageAlioscopy;
In void SceneView::cull(), after the following block:
else if (_displaySettings->getStereoMode()==osg::DisplaySettings::RIGHT_EYE) { // set up the right eye. _cullVisitor->setTraversalMask(_cullMaskRight); computeRightEyeViewport(getViewport()); bool computeNearFar = cullStage(computeRightEyeProjection(getProjectionMatrix()),computeRightEyeView(getViewMatrix()),_cullVisitor.get(),_stateGraph.get(),_renderStage.get(),_viewportRight.get()); if (computeNearFar) { CullVisitor::value_type zNear = _cullVisitor->getCalculatedNearPlane(); CullVisitor::value_type zFar = _cullVisitor->getCalculatedFarPlane(); _cullVisitor->clampProjectionMatrix(getProjectionMatrix(),zNear,zFar); } }
add the following else-if block:
else if(_displaySettings->getStereoMode()==osg::DisplaySettings::ALIOSCOPY) { if(_cullVisitorAlioscopy == NULL) { _cullVisitorAlioscopy = new osg::ref_ptr<osgUtil::CullVisitor>[_alioscopyEyes]; _rendergraphAlioscopy = new osg::ref_ptr<osgUtil::StateGraph>[_alioscopyEyes]; _renderStageAlioscopy = new osg::ref_ptr<osgUtil::RenderStage>[_alioscopyEyes]; for(int i = 0; i < _alioscopyEyes; i++) { _cullVisitorAlioscopy[i] = dynamic_cast<CullVisitor*>(_cullVisitor->clone()); _rendergraphAlioscopy[i] = dynamic_cast<StateGraph*>(_stateGraph->cloneType()); _renderStageAlioscopy[i] = dynamic_cast<RenderStage*>(_renderStage->clone(osg::CopyOp::DEEP_COPY_ALL)); } } bool computeNearFar = false; for(int i =0; i < _alioscopyEyes; i++) { _cullVisitorAlioscopy[i]->setDatabaseRequestHandler(_cullVisitor->getDatabaseRequestHandler()); _cullVisitorAlioscopy[i]->setClampProjectionMatrixCallback(_cullVisitor->getClampProjectionMatrixCallback()); _cullVisitorAlioscopy[i]->setTraversalMask(_cullMaskLeft); computeNearFar = cullStage(computeEyeProjection(i),computeEyeView(i),_cullVisitorAlioscopy[i].get(),_rendergraphAlioscopy[i].get(),_renderStageAlioscopy[i].get(), getViewport()); } if(computeNearFar) { CullVisitor::value_type zNear = osg::minimum(_cullVisitorAlioscopy[0]->getCalculatedNearPlane(),_cullVisitorAlioscopy[1]->getCalculatedNearPlane()); CullVisitor::value_type zFar = osg::maximum(_cullVisitorAlioscopy[0]->getCalculatedFarPlane(),_cullVisitorAlioscopy[1]->getCalculatedFarPlane()); for(int i = 2; i < _alioscopyEyes; i++) { zNear = osg::minimum(zNear,_cullVisitorAlioscopy[i]->getCalculatedNearPlane()); zFar = osg::maximum(zFar,_cullVisitorAlioscopy[i]->getCalculatedFarPlane()); } _cullVisitor->clampProjectionMatrix(getProjectionMatrix(),zNear,zFar); } if(!_cullVisitorAlioscopy[0].valid() || !_rendergraphAlioscopy[0].valid() || !_renderStageAlioscopy[0].valid()) { osg::notify(osg::ALWAYS) << "Render Invalid." << std::endl; } }
in void SceneView::draw(): case added for switch(_displaySettings->getStereoMode())
case(osg::DisplaySettings::ALIOSCOPY): { static int numberOfDisplays = 9; static float alioscopyQuality = 1.0; if (_delayCount >= 0) { if (_delayCount==0) { char * qual = getenv("OSG_ALIOSCOPY_QUALITY"); if(qual == NULL) { alioscopyQuality = 1.0; } else { alioscopyQuality = atof(qual); if(alioscopyQuality <= 0.0 || alioscopyQuality > 1.0) { alioscopyQuality = 1.0; } } if(_alioscopyContext == NULL) { int maxContext = _renderInfo.getState()->getGraphicsContext()->getMaxContextID(); _alioscopyContext = new il_context*[maxContext+1]; _alioscopyDisplay = new il_display*[numberOfDisplays]; for(int i = 0; i <= maxContext; i++) { _alioscopyContext[i] = NULL; } for(int i = 0; i < numberOfDisplays; i++) { _alioscopyDisplay[i] = NULL; } } } --_delayCount; } else // call every time once init has been called { //struct timeval start, end, end1, end2, end3; //gettimeofday(&start, NULL); //static float alioscopyQuality = 1.0; int contextid = _renderInfo.getState()->getContextID(); int vx = int(getViewport()->x()); int vy = int(getViewport()->y()); static int vwidth = int(getViewport()->width()); static int vheight = int(getViewport()->height()); int display = 0; switch(vx) { case 1920: display = 1; break; case 3840: display = 2; break; case 5760: display = 3; break; default: display = 0; break; } char hostname[33]; gethostname(hostname, 32); int node; sscanf(hostname, "kaust2d%d-10", &node); node--; display += 2 * node; #ifdef ALIOSCOPY3X2 //osg::notify(osg::ALWAYS) << "Hostname: " << hostname << std::endl; sscanf(hostname, "kaust2d%d-10", &node); //osg::notify(osg::ALWAYS) << "Node: " << node << std::endl; if(node == 1) { if(vx == 0 && vy == 1200) { display = 0; } else if(vx == 1920 && vy == 1200) { display = 1; } else if(vx == 0 && vy == 0) { display = 2; } else if(vx == 1920 && vy == 0) { display = 3; } } if(node == 2) { if(vx == 0 && vy == 0) { display = 4; } else if(vx == 1920 && vy == 0) { display = 5; } } //osg::notify(osg::ALWAYS) << "Display: " << display << std::endl; #endif #ifdef ALIOSCOPY3X3 //osg::notify(osg::ALWAYS) << "Hostname: " << hostname << std::endl; sscanf(hostname, "kaust2d%d-10", &node); //osg::notify(osg::ALWAYS) << "Node: " << node << std::endl; //osg::notify(osg::ALWAYS) << "vx: " << vx << " vy: " << vy << std::endl; if(node == 1) { if(vx == 0 && vy == 1200) { display = 0; } else if(vx == 1920 && vy == 1200) { display = 3; } else if(vx == 0 && vy == 0) { display = 6; } else if(vx == 1920 && vy == 0) { display = 7; } } if(node == 2) { if(vx == 0 && vy == 1200) { display = 1; } else if(vx == 1920 && vy == 1200) { display = 2; } else if(vx == 0 && vy == 0) { display = 4; } else if(vx == 1920 && vy == 0) { display = 5; } } if(node == 3) { display = 8; } //osg::notify(osg::ALWAYS) << "Display: " << display << std::endl; #endif if (_alioscopyContext[contextid] == NULL) { _alioscopyContext[contextid] = il_init_context(_alioscopyEyes, vwidth, vheight, alioscopyQuality, "/home/demo/covise/alioscopy/interleaver.vert", "/home/demo/covise/alioscopy/interleaver.frag"); } if(_alioscopyDisplay[display] == NULL) { osg::notify(osg::ALWAYS) << "quality for display " << display << " set to " << alioscopyQuality << std::endl; _alioscopyDisplay[display] = il_init_display(_alioscopyEyes); //osg::notify(osg::ALWAYS) << "Mark2" << std::endl; std::stringstream file; std::string extra = ""; #ifdef ALIOSCOPY2X2 extra = "-2x2"; #endif #ifdef ALIOSCOPY3X2 extra = "-3x2"; #endif #ifdef ALIOSCOPY3X3 extra = "-3x3"; #endif file << "/home/demo/covise/alioscopy/alioscopy" << display << extra << ".dat"; std::string filepath = file.str(); osg::notify(osg::ALWAYS) << "Alioscopy display: " << display << " loading file: " << file.str() << std::endl; read_dsp_conf(filepath.c_str(), _alioscopyDisplay[display], _alioscopyEyes); _alioscopyDisplay[display]->viewport_x = vx; _alioscopyDisplay[display]->viewport_y = vy; _alioscopyDisplay[display]->viewport_w = vwidth; _alioscopyDisplay[display]->viewport_h = vheight; _alioscopyDisplay[display]->quality = alioscopyQuality; _alioscopyEyePosition = new float[_alioscopyEyes * 3]; il_viewpoints(_alioscopyDisplay[display], _alioscopyIPD, _alioscopyViewDistance, _alioscopyEyePosition, _alioscopyEyes); } if( getDrawBufferValue() != GL_NONE) { for(int i = 0; i < _alioscopyEyes; i++) { _renderStageAlioscopy[i]->setDrawBuffer(getDrawBufferValue()); _renderStageAlioscopy[i]->setReadBuffer(getDrawBufferValue()); } } glDrawBuffer(GL_BACK); osg::Viewport * vport = getViewport(); vport->setViewport(vport->x(), vport->y(), vwidth * alioscopyQuality , vheight * alioscopyQuality); setViewport(vport); // 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); } for(int i = 0; i < _alioscopyEyes; i++) { _renderStageAlioscopy[i]->setColorMask(cmask); } _alioscopyDisplay[display]->debug = _alioscopyDebug; for(int i = 0; i < _alioscopyEyes; i++) { il_prep(_alioscopyContext[contextid], _alioscopyDisplay[display], i); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); _renderStageAlioscopy[i]->drawPreRenderStages(_renderInfo,previous); _renderStageAlioscopy[i]->draw(getRenderInfo(),previous); } glDepthMask(GL_FALSE); il_draw(_alioscopyContext[contextid], _alioscopyDisplay[display], _alioscopyEyePosition); glDepthMask(GL_TRUE); } break; } case(osg::DisplaySettings::VARRIER): { enum {VARRIER_LEFT_EYE = 0, VARRIER_RIGHT_EYE = 1}; float screenLoc[60][9] = // screen locations from vellum.lua FIXME: read from file instead { { -4.7547, 1.5459, 0.6620, -0.0992, -0.0000, -1.3263, -0.0000, 1.0000, -0.0000 }, { -4.8353, 1.5405, -0.7548, 0.2762, -0.0000, -1.3010, -0.0000, 1.0000, -0.0000 }, { -4.5227, 1.5454, -2.1410, 0.7438, -0.0000, -1.1026, -0.0000, 1.0000, -0.0000 }, { -3.7233, 1.5362, -3.3223, 0.9735, 0.0000, -0.9062, -0.0000, 1.0000, -0.0000 }, { -2.6867, 1.5383, -4.2895, 1.2358, 0.0000, -0.4916, -0.0000, 1.0000, -0.0000 }, { -1.3612, 1.5348, -4.7881, 1.3169, 0.0000, -0.1859, -0.0000, 1.0000, -0.0000 }, { 0.0483, 1.5439, -4.9570, 1.3081, 0.0000, 0.2402, -0.0000, 1.0000, -0.0000 }, { 1.4365, 1.5349, -4.6690, 1.2082, 0.0000, 0.5560, -0.0000, 1.0000, -0.0000 }, { 2.7175, 1.5320, -4.0578, 1.0408, 0.0000, 0.8280, -0.0000, 1.0000, -0.0000 }, { 3.8199, 1.5252, -3.1666, 0.6945, 0.0000, 1.1343, -0.0000, 1.0000, -0.0000 }, { 4.5554, 1.5322, -1.9444, 0.2977, 0.0000, 1.2962, -0.0000, 1.0000, -0.0000 }, { 4.8400, 1.5271, -0.5580, -0.0394, 0.0000, 1.3294, -0.0000, 1.0000, -0.0000 }, { -4.7413, 2.6376, 0.6630, -0.1046, -0.0000, -1.3259, -0.0000, 1.0000, -0.0000 }, { -4.8316, 2.6317, -0.7526, 0.2739, -0.0000, -1.3015, -0.0000, 1.0000, -0.0000 }, { -4.5208, 2.6346, -2.1384, 0.7318, -0.0000, -1.1105, -0.0000, 1.0000, -0.0000 }, { -3.7290, 2.6260, -3.3240, 0.9757, 0.0000, -0.9039, -0.0000, 1.0000, -0.0000 }, { -2.6899, 2.6284, -4.2915, 1.2345, 0.0000, -0.4948, -0.0000, 1.0000, -0.0000 }, { -1.3608, 2.6242, -4.7861, 1.3166, 0.0000, -0.1885, -0.0000, 1.0000, -0.0000 }, { 0.0421, 2.6326, -4.9545, 1.3059, 0.0000, 0.2518, -0.0000, 1.0000, -0.0000 }, { 1.4345, 2.6227, -4.6695, 1.2040, 0.0000, 0.5650, -0.0000, 1.0000, -0.0000 }, { 2.7151, 2.6196, -4.0544, 1.0474, 0.0000, 0.8197, -0.0000, 1.0000, -0.0000 }, { 3.8244, 2.6132, -3.1738, 0.6933, 0.0000, 1.1350, -0.0000, 1.0000, -0.0000 }, { 4.5526, 2.6203, -1.9457, 0.3029, 0.0000, 1.2950, -0.0000, 1.0000, -0.0000 }, { 4.8494, 2.6155, -0.5613, -0.0428, 0.0000, 1.3293, -0.0000, 1.0000, -0.0000 }, { -4.7359, 3.7294, 0.6636, -0.1045, -0.0000, -1.3259, -0.0000, 1.0000, -0.0000 }, { -4.8400, 3.7213, -0.7525, 0.2867, -0.0000, -1.2987, -0.0000, 1.0000, -0.0000 }, { -4.5153, 3.7251, -2.1358, 0.7265, -0.0000, -1.1140, -0.0000, 1.0000, -0.0000 }, { -3.7299, 3.7159, -3.3192, 0.9699, 0.0000, -0.9101, -0.0000, 1.0000, -0.0000 }, { -2.6939, 3.7198, -4.2908, 1.2363, 0.0000, -0.4904, -0.0000, 1.0000, -0.0000 }, { -1.3646, 3.7143, -4.7893, 1.3165, 0.0000, -0.1889, -0.0000, 1.0000, -0.0000 }, { 0.0413, 3.7216, -4.9477, 1.3064, 0.0000, 0.2494, -0.0000, 1.0000, -0.0000 }, { 1.4302, 3.7125, -4.6629, 1.2035, 0.0000, 0.5660, -0.0000, 1.0000, -0.0000 }, { 2.7136, 3.7108, -4.0478, 1.0489, 0.0000, 0.8177, -0.0000, 1.0000, -0.0000 }, { 3.8294, 3.7043, -3.1712, 0.6967, 0.0000, 1.1329, -0.0000, 1.0000, -0.0000 }, { 4.5557, 3.7101, -1.9476, 0.3013, 0.0000, 1.2954, -0.0000, 1.0000, -0.0000 }, { 4.8522, 3.7051, -0.5633, -0.0390, 0.0000, 1.3294, -0.0000, 1.0000, -0.0000 }, { -4.7318, 4.8198, 0.6652, -0.1032, -0.0000, -1.3260, -0.0000, 1.0000, -0.0000 }, { -4.8418, 4.8134, -0.7494, 0.2946, -0.0000, -1.2969, -0.0000, 1.0000, -0.0000 }, { -4.5157, 4.8145, -2.1335, 0.7232, -0.0000, -1.1162, -0.0000, 1.0000, -0.0000 }, { -3.7401, 4.8044, -3.3262, 0.9731, 0.0000, -0.9066, -0.0000, 1.0000, -0.0000 }, { -2.6974, 4.8118, -4.2907, 1.2362, 0.0000, -0.4907, -0.0000, 1.0000, -0.0000 }, { -1.3641, 4.8049, -4.7855, 1.3162, 0.0000, -0.1910, -0.0000, 1.0000, -0.0000 }, { 0.0388, 4.8109, -4.9500, 1.3032, 0.0000, 0.2654, -0.0000, 1.0000, -0.0000 }, { 1.4274, 4.8011, -4.6579, 1.2025, 0.0000, 0.5682, -0.0000, 1.0000, -0.0000 }, { 2.7140, 4.8004, -4.0516, 1.0465, 0.0000, 0.8208, -0.0000, 1.0000, -0.0000 }, { 3.8304, 4.7949, -3.1738, 0.6931, 0.0000, 1.1351, -0.0000, 1.0000, -0.0000 }, { 4.5577, 4.8000, -1.9487, 0.2982, 0.0000, 1.2961, -0.0000, 1.0000, -0.0000 }, { 4.8563, 4.7941, -0.5626, -0.0422, 0.0000, 1.3293, -0.0000, 1.0000, -0.0000 }, { -4.7225, 5.9098, 0.6635, -0.1103, -0.0000, -1.3254, -0.0000, 1.0000, -0.0000 }, { -4.8441, 5.9038, -0.7523, 0.3006, -0.0000, -1.2956, -0.0000, 1.0000, -0.0000 }, { -4.5118, 5.9038, -2.1335, 0.7080, -0.0000, -1.1259, -0.0000, 1.0000, -0.0000 }, { -3.7395, 5.8948, -3.3236, 0.9718, 0.0000, -0.9080, -0.0000, 1.0000, -0.0000 }, { -2.6990, 5.9053, -4.2860, 1.2364, 0.0000, -0.4900, -0.0000, 1.0000, -0.0000 }, { -1.3701, 5.8958, -4.7857, 1.3168, 0.0000, -0.1869, -0.0000, 1.0000, -0.0000 }, { 0.0361, 5.9009, -4.9443, 1.3020, 0.0000, 0.2713, -0.0000, 1.0000, -0.0000 }, { 1.4257, 5.8907, -4.6504, 1.2024, 0.0000, 0.5684, -0.0000, 1.0000, -0.0000 }, { 2.7117, 5.8916, -4.0457, 1.0466, 0.0000, 0.8206, -0.0000, 1.0000, -0.0000 }, { 3.8255, 5.8861, -3.1692, 0.7000, 0.0000, 1.1309, -0.0000, 1.0000, -0.0000 }, { 4.5563, 5.8899, -1.9505, 0.2948, 0.0000, 1.2969, -0.0000, 1.0000, -0.0000 }, { 4.8578, 5.8829, -0.5649, -0.0340, 0.0000, 1.3296, -0.0000, 1.0000, -0.0000 } }; float line_screen[60][5] = { //{ 536.85342, -10.46, 0.0244, -0.0004, 0.75 }, { 536.85342, -10.445, 0.0231, 0.00075, 0.75 }, { 536.85342, -10.47, 0.0226, -0.00145, 0.75 }, { 536.85342, -10.5, 0.023, -0.0011, 0.75 }, { 536.85342, -10.465, 0.023, -0.00095, 0.75 }, { 536.85342, -10.48, 0.0245, -0.00045, 0.75 }, { 536.85342, -10.51, 0.0239, -0.00015, 0.75 }, { 536.85342, -10.485, 0.0254, 0.0003, 0.75 }, { 536.85342, -10.47, 0.0234, 0.0006, 0.75 }, { 536.85342, -10.465, 0.0226, -0.0015, 0.75 }, { 536.85342, -10.445, 0.0239, -0.00105, 0.75 }, { 536.85342, -10.52, 0.025, 0.0006, 0.75 }, { 536.85342, -10.49, 0.0237, -0.0006, 0.75 }, { 536.85342, -10.43, 0.025, -0.0004, 0.75 }, { 536.85342, -10.445, 0.0227, -1e-04, 0.75 }, { 536.85342, -10.45, 0.0236, -0.0002, 0.75 }, { 536.85342, -10.48, 0.0228, -0.00045, 0.75 }, { 536.85342, -10.44, 0.0245, 0.0004, 0.75 }, { 536.85342, -10.44, 0.0235, 0.0001, 0.75 }, { 536.85342, -10.43, 0.0252, -0.0011, 0.75 }, { 536.85342, -10.42, 0.0234, -0.00095, 0.75 }, { 536.85342, -10.47, 0.0236, -0.0016, 0.75 }, { 536.85342, -10.44, 0.0244, -0.0001, 0.75 }, { 536.85342, -10.46, 0.0233, -0.0009, 0.75 }, { 536.85342, -10.46, 0.0243, 0.00045, 0.75 }, { 536.85342, -10.405, 0.0239, -0.00125, 0.75 }, { 536.85342, -10.46, 0.0221, -0.0008, 0.75 }, { 536.85342, -10.48, 0.0235, 0.00025, 0.75 }, { 536.85342, -10.475, 0.0229, -1e-04, 0.75 }, { 536.85342, -10.44, 0.024, 0.0007, 0.75 }, { 536.85342, -10.46, 0.0244, -0.0004, 0.75 }, { 536.85342, -10.445, 0.0244, 0.0005, 0.75 }, { 536.85342, -10.49, 0.0237, 5e-05, 0.75 }, { 536.85342, -10.43, 0.0234, -0.00265, 0.75 }, { 536.85342, -10.46, 0.0235, -0.0011, 0.75 }, { 536.85342, -10.46, 0.0241, 0.00055, 0.75 }, { 536.85342, -10.5, 0.0233, -0.00095, 0.75 }, { 536.85342, -10.37, 0.0224, 0.00045, 0.75 }, { 536.85342, -10.495, 0.0235, -0.00155, 0.75 }, { 536.85342, -10.45, 0.0234, -0.00085, 0.75 }, { 536.85342, -10.495, 0.0232, -0.00105, 0.75 }, { 536.85342, -10.46, 0.0234, -0.0008, 0.75 }, { 536.85342, -10.46, 0.0225, -0.0006, 0.75 }, { 536.85342, -10.46, 0.0238, -0.00235, 0.75 }, { 536.85342, -10.46, 0.0236, 0.00045, 0.75 }, { 536.85342, -10.48, 0.0241, -0.00305, 0.75 }, { 536.85342, -10.47, 0.0228, 0.00055, 0.75 }, { 536.85342, -10.46, 0.0233, -0.0027, 0.75 }, { 536.85342, -10.39, 0.0239, -0.00315, 0.75 }, { 536.85342, -10.44, 0.0226, -0.00015, 0.75 }, { 536.85342, -10.5, 0.023, -0.001, 0.75 }, { 536.85342, -10.43, 0.0232, -0.0005, 0.75 }, { 536.85342, -10.52, 0.0242, -0.00105, 0.75 }, { 536.85342, -10.54, 0.0226, 0.00035, 0.75 }, { 536.85342, -10.46, 0.0231, -0.0005, 0.75 }, { 536.85342, -10.48, 0.025, 5e-05, 0.75 }, { 536.85342, -10.49, 0.023, -0.0004, 0.75 }, { 536.85342, -10.43, 0.0254, -0.004, 0.75 }, { 536.85342, -10.46, 0.0232, -0.0016, 0.75 }, { 536.85342, -10.48, 0.0229, -0.0003, 0.75 }, { 536.83342, -10.48, 0.0233, 0.00065, 0.75 }, }; int nodeLUT[15] = {14, 11, 8, 5, 2, 13, 10, 7, 4, 1, 12, 9, 6, 3, 0}; osg::notify(osg::DEBUG_INFO) << "osgUtil::SceneView in varrier mode called" << std::endl; if (_delayCount >= 0) { --_delayCount; if (_delayCount==0) { if(_varrier == NULL) { int maxContext = _renderInfo.getState()->getGraphicsContext()->getMaxContextID(); _varrier = new VarrierCombiner*[maxContext+1]; for(int i = 0; i <= maxContext; i++) { _varrier[i] = NULL; } } } } else // call every time once init has been called { static int swidth = 0; static int sheight = 0; static float squality = 0.0; struct timeval start, end; gettimeofday(&start, NULL); int contextid = _renderInfo.getState()->getContextID(); // Initialize varrier combiner if not already initialized: if (_varrier[contextid] == NULL) { swidth = int(getViewport()->width()); sheight = int(getViewport()->height()); char * qual = getenv("OSG_VARRIER_QUALITY"); if(qual == NULL) { squality = 1.0; } else { squality = atof(qual); if(squality <= 0.0 || squality > 1.0) { squality = 1.0; } } osg::notify(osg::DEBUG_INFO) << "viewport size: " << swidth << " x " << sheight << std::endl; _varrier[contextid] = new VarrierCombiner(swidth, sheight, squality); osg::notify(osg::DEBUG_INFO) << "initializing varrier in context: " << contextid << " with quality: " << squality << std::endl; } // Varrier coordinates are like OpenGL: x=right, y=up, z=out // Get eye positions from OSG: //osg::Camera* camLeft = _renderStageLeft->getCamera(); //osg::Camera* camRight = _renderStageRight->getCamera(); Vec3 leftEye, rightEye, center, up; computeLeftEyeView(getViewMatrix()).getLookAt(leftEye,center, up); computeRightEyeView(getViewMatrix()).getLookAt(rightEye,center, up); // Rotate eyes 90 deg about x axis (Varrier uses y up coordinates): Matrixd rot; rot.makeRotate(90.0 * M_PI / 180.0, 1.0, 0.0, 0.0); leftEye = rot * leftEye; rightEye = rot * rightEye; // Translate coordinate system to floor in center of screen circle: leftEye[1] += 1120; leftEye[2] -= 1550; rightEye[1] += 1120; rightEye[2] -= 1550; // Convert eyes to float array and feet: float eyeLeft[3]; float eyeRight[3]; const double MM_IN_FEET = 0.0032808399; for (int i=0; i<3; ++i) eyeLeft[i] = leftEye[i] * MM_IN_FEET; for (int i=0; i<3; ++i) eyeRight[i] = rightEye[i] * MM_IN_FEET; osg::notify(osg::DEBUG_INFO) << "FEET: Left eye: " << eyeLeft[0] << ", " << eyeLeft[1] << ", " << eyeLeft[2] << std::endl; osg::notify(osg::DEBUG_INFO) << "FEET: Right eye: " << eyeRight[0] << ", " << eyeRight[1] << ", " << eyeRight[2] << std::endl; osg::Viewport * vport = getViewport(); vport->setViewport(vport->x(), vport->y(), swidth * squality , sheight * squality); setViewport(vport); // Get OpenGL viewport location on desktop: int x = int(getViewport()->x()); int y = int(getViewport()->y()); int width = int(swidth); int height = int(sheight); osg::notify(osg::DEBUG_INFO) << "viewport: " << x << ", " << y << ", " << width << " x " << height << std::endl; // Calculate which screen index is being rendered: char hostname[33]; gethostname(hostname, 32); int node; int screen; int quadrant; sscanf(hostname, "vellum%d-10", &node); --node; if (node<0) node = 0; // for head node else node = nodeLUT[node]; if (x==0 && y==0) quadrant = 0; else if (x==0 && y>0) quadrant = 1; else if (x>0 && y==0) quadrant = 2; else quadrant = 3; screen = node * 4 + (contextid * 2) + quadrant; osg::notify(osg::DEBUG_INFO) << "rendering using varrier combiner on " << hostname << ", node " << node << ", screen " << screen << std::endl; VarrierCombiner::Display varrierConfig; varrierConfig.viewport_x = x; varrierConfig.viewport_y = y; varrierConfig.viewport_w = width; varrierConfig.viewport_h = height; varrierConfig.quality = squality; // Create absolute points from vellum.lua values: varrierConfig.screen_BL[0] = screenLoc[screen][0]; varrierConfig.screen_BL[1] = screenLoc[screen][1]; varrierConfig.screen_BL[2] = screenLoc[screen][2]; varrierConfig.screen_BR[0] = screenLoc[screen][0] + screenLoc[screen][3]; varrierConfig.screen_BR[1] = screenLoc[screen][1] + screenLoc[screen][4]; varrierConfig.screen_BR[2] = screenLoc[screen][2] + screenLoc[screen][5]; varrierConfig.screen_TL[0] = screenLoc[screen][0] + screenLoc[screen][6]; varrierConfig.screen_TL[1] = screenLoc[screen][1] + screenLoc[screen][7]; varrierConfig.screen_TL[2] = screenLoc[screen][2] + screenLoc[screen][8]; osg::notify(osg::DEBUG_INFO) << "screen - BL: " << varrierConfig.screen_BL[0] << ", " << varrierConfig.screen_BL[1] << ", " << varrierConfig.screen_BL[2] << ", " << "BR: " << varrierConfig.screen_BR[0] << ", " << varrierConfig.screen_BR[1] << ", " << varrierConfig.screen_BR[2] << ", " << "TL: " << varrierConfig.screen_TL[0] << ", " << varrierConfig.screen_TL[1] << ", " << varrierConfig.screen_TL[2] << ", " << std::endl; varrierConfig.pitch = line_screen[screen][0]; varrierConfig.angle = line_screen[screen][1]; varrierConfig.thick = line_screen[screen][2]; varrierConfig.shift = line_screen[screen][3]; varrierConfig.cycle = line_screen[screen][4]; /* osg::notify(osg::DEBUG_INFO) << "line_screen: " << line_screen[screen][0] << ", " << line_screen[screen][1] << ", " << line_screen[screen][2] << ", " << line_screen[screen][3] << ", " << line_screen[screen][4] << std::endl; */ if( getDrawBufferValue() != GL_NONE) { _renderStageLeft->setDrawBuffer(getDrawBufferValue()); _renderStageLeft->setReadBuffer(getDrawBufferValue()); _renderStageRight->setDrawBuffer(getDrawBufferValue()); _renderStageRight->setReadBuffer(getDrawBufferValue()); } // 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); _renderInfo.getState()->getContextID(); osg::notify(osg::DEBUG_INFO) << "GL context ID: " << _renderInfo.getState()->getContextID() << std::endl; //_localStateSet->setAttribute(getViewport()); _renderStageLeft->drawPreRenderStages(_renderInfo,previous); _renderStageRight->drawPreRenderStages(_renderInfo,previous); glPushAttrib(GL_ALL_ATTRIB_BITS); gettimeofday(&end, NULL); osg::notify(osg::NOTICE) << "Time of SceneView:Draw():Header: " << (end.tv_sec - start.tv_sec) + ((end.tv_usec - start.tv_usec)/ 100000.0) << std::endl; // render left eye: _varrier[contextid]->prepare(&varrierConfig, VARRIER_RIGHT_EYE); gettimeofday(&end, NULL); osg::notify(osg::NOTICE) << "Time of SceneView:Draw():Left1: " << (end.tv_sec - start.tv_sec) + ((end.tv_usec - start.tv_usec)/ 100000.0) << std::endl; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gettimeofday(&end, NULL); osg::notify(osg::NOTICE) << "Time of SceneView:Draw():Left2: " << (end.tv_sec - start.tv_sec) + ((end.tv_usec - start.tv_usec)/ 100000.0) << std::endl; osg::notify(osg::DEBUG_INFO) << "GL context ID: " << _renderInfo.getState()->getContextID() << std::endl; _renderStageLeft->draw(getRenderInfo(),previous); osg::notify(osg::DEBUG_INFO) << "After renderleft." << std::endl; if (_varrierTestPattern) { glClearColor(0.0, 1.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); } gettimeofday(&end, NULL); osg::notify(osg::NOTICE) << "Time of SceneView:Draw():Left: " << (end.tv_sec - start.tv_sec) + ((end.tv_usec - start.tv_usec)/ 100000.0) << std::endl; // render right eye: _varrier[contextid]->prepare(&varrierConfig, VARRIER_LEFT_EYE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); _renderStageRight->draw(getRenderInfo(),previous); osg::notify(osg::DEBUG_INFO) << "After renderright." << std::endl; if (_varrierTestPattern) { glClearColor(1.0, 0.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); } gettimeofday(&end, NULL); osg::notify(osg::NOTICE) << "Time of SceneView:Draw():Right: " << (end.tv_sec - start.tv_sec) + ((end.tv_usec - start.tv_usec)/ 100000.0) << std::endl; // combine eyes: _varrier[contextid]->combine(&varrierConfig, eyeLeft, eyeRight); osg::notify(osg::DEBUG_INFO) << "After combine." << std::endl; glPopAttrib(); gettimeofday(&end, NULL); osg::notify(osg::NOTICE) << "Time of SceneView:Draw(): " << (end.tv_sec - start.tv_sec) + ((end.tv_usec - start.tv_usec)/ 100000.0) << " Context: " << contextid << " quad: " << quadrant << std::endl; } } // end varrier style break;
In SceneView::getStats(Statistics& stats) change the following block :
switch(_displaySettings->getStereoMode()) { case(osg::DisplaySettings::QUAD_BUFFER): case(osg::DisplaySettings::ANAGLYPHIC): case(osg::DisplaySettings::HORIZONTAL_SPLIT): case(osg::DisplaySettings::VERTICAL_SPLIT): case(osg::DisplaySettings::VERTICAL_INTERLACE): case(osg::DisplaySettings::HORIZONTAL_INTERLACE): { bool resultLeft = _renderStageLeft->getStats(stats); bool resultRight = _renderStageRight->getStats(stats); return resultLeft && resultRight; } case(osg::DisplaySettings::RIGHT_EYE): case(osg::DisplaySettings::LEFT_EYE): default: return _renderStage->getStats(stats); }
to the following:
switch(_displaySettings->getStereoMode()) { case(osg::DisplaySettings::QUAD_BUFFER): case(osg::DisplaySettings::ANAGLYPHIC): case(osg::DisplaySettings::HORIZONTAL_SPLIT): case(osg::DisplaySettings::VERTICAL_SPLIT): case(osg::DisplaySettings::VERTICAL_INTERLACE): case(osg::DisplaySettings::HORIZONTAL_INTERLACE): case(osg::DisplaySettings::VARRIER): // FOR VARRIER case(osg::DisplaySettings::ALIOSCOPY): // FOR ALIOSCOPY { bool resultLeft = _renderStageLeft->getStats(stats); bool resultRight = _renderStageRight->getStats(stats); return resultLeft && resultRight; } case(osg::DisplaySettings::RIGHT_EYE): case(osg::DisplaySettings::LEFT_EYE): default: return _renderStage->getStats(stats); }
Add the following functions at the end of the file:
void SceneView::setVarrierTestPattern(bool b) { _varrierTestPattern = b; } bool SceneView::isVarrierTestPattern() { return _varrierTestPattern; } void SceneView::toggleAlioscopyDebug() { _alioscopyDebug = (_alioscopyDebug > 1.0) ? 1.0 : 50.0; }
NOTE: osg needs to link against the varrier and alioscopy libraries (Varrier and coInterleaver), thus it needs to be added to the linking operation.
Linking Varrier and Alioscopy libraries with OpenSceneGraph
- Step-1: Get the [Varrier| [Image:VarrierCombiner.tar]]
.cshrc Changes
#sets varrier quality mode setenv OSG_VARRIER_QUALITY 0.5 #sets override flag for all but headnode if($HOST != "vellum") then setenv OSG_OVERRIDE_REDIRECT 1 endif