From 6831e072e4dc1fd83d97ffc46f6e859f9d5c4501 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 11 Nov 2020 14:32:28 +0000 Subject: [PATCH 1/3] Moved osgmultiviewpaging to osgcustompager to avoid name confusion with new multiview extension example --- examples/CMakeLists.txt | 2 +- examples/osgcustompager/CMakeLists.txt | 4 ++++ .../osgcustompager.cpp} | 0 examples/osgmultiviewpaging/CMakeLists.txt | 4 ---- src/osg/CMakeLists.txt | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 examples/osgcustompager/CMakeLists.txt rename examples/{osgmultiviewpaging/osgmultiviewpaging.cpp => osgcustompager/osgcustompager.cpp} (100%) delete mode 100644 examples/osgmultiviewpaging/CMakeLists.txt diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 788e5075f..0cbfa9b7d 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -39,6 +39,7 @@ IF(DYNAMIC_OPENSCENEGRAPH) ADD_SUBDIRECTORY(osgcubemap) ADD_SUBDIRECTORY(osgdeferred) ADD_SUBDIRECTORY(osgcluster) + ADD_SUBDIRECTORY(osgcustompager) ADD_SUBDIRECTORY(osgdatabaserevisions) ADD_SUBDIRECTORY(osgdepthpartition) ADD_SUBDIRECTORY(osgdepthpeeling) @@ -76,7 +77,6 @@ IF(DYNAMIC_OPENSCENEGRAPH) ADD_SUBDIRECTORY(osgmultitexture) ADD_SUBDIRECTORY(osgmultitexturecontrol) ADD_SUBDIRECTORY(osgmultitouch) - ADD_SUBDIRECTORY(osgmultiviewpaging) ADD_SUBDIRECTORY(osgobjectcache) ADD_SUBDIRECTORY(osgoccluder) ADD_SUBDIRECTORY(osgocclusionquery) diff --git a/examples/osgcustompager/CMakeLists.txt b/examples/osgcustompager/CMakeLists.txt new file mode 100644 index 000000000..7ba227525 --- /dev/null +++ b/examples/osgcustompager/CMakeLists.txt @@ -0,0 +1,4 @@ +SET(TARGET_SRC osgcustompager.cpp ) + +#### end var setup ### +SETUP_EXAMPLE(osgcustompager) diff --git a/examples/osgmultiviewpaging/osgmultiviewpaging.cpp b/examples/osgcustompager/osgcustompager.cpp similarity index 100% rename from examples/osgmultiviewpaging/osgmultiviewpaging.cpp rename to examples/osgcustompager/osgcustompager.cpp diff --git a/examples/osgmultiviewpaging/CMakeLists.txt b/examples/osgmultiviewpaging/CMakeLists.txt deleted file mode 100644 index d8d1a8514..000000000 --- a/examples/osgmultiviewpaging/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -SET(TARGET_SRC osgmultiviewpaging.cpp ) - -#### end var setup ### -SETUP_EXAMPLE(osgmultiviewpaging) diff --git a/src/osg/CMakeLists.txt b/src/osg/CMakeLists.txt index 31b88cfe0..9deed7af9 100644 --- a/src/osg/CMakeLists.txt +++ b/src/osg/CMakeLists.txt @@ -386,7 +386,7 @@ SET(TARGET_SRC TexMat.cpp Texture1D.cpp Texture2DArray.cpp - Texture2DMultisampleArray.cpp + Texture2DMultisampleArray.cpp Texture2D.cpp Texture2DMultisample.cpp Texture3D.cpp From d6ce7550e318c36e0608be1f6f906c2d2e2e4ab6 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 12 Nov 2020 12:22:40 +0000 Subject: [PATCH 2/3] Added standard side by side stereo config to use as a comparison to multviewOVR implementation --- examples/CMakeLists.txt | 1 + examples/osgmultiviewOVR/StandardStereo.cpp | 267 ++++++++++++++++++++ examples/osgmultiviewOVR/StandardStereo.h | 45 ++++ examples/osgmultiviewOVR/standard.frag | 9 + examples/osgmultiviewOVR/standard.vert | 7 + 5 files changed, 329 insertions(+) create mode 100644 examples/osgmultiviewOVR/StandardStereo.cpp create mode 100644 examples/osgmultiviewOVR/StandardStereo.h create mode 100644 examples/osgmultiviewOVR/standard.frag create mode 100644 examples/osgmultiviewOVR/standard.vert diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 0cbfa9b7d..d499d05b6 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -77,6 +77,7 @@ IF(DYNAMIC_OPENSCENEGRAPH) ADD_SUBDIRECTORY(osgmultitexture) ADD_SUBDIRECTORY(osgmultitexturecontrol) ADD_SUBDIRECTORY(osgmultitouch) + ADD_SUBDIRECTORY(osgmultiviewOVR) ADD_SUBDIRECTORY(osgobjectcache) ADD_SUBDIRECTORY(osgoccluder) ADD_SUBDIRECTORY(osgocclusionquery) diff --git a/examples/osgmultiviewOVR/StandardStereo.cpp b/examples/osgmultiviewOVR/StandardStereo.cpp new file mode 100644 index 000000000..c7acff347 --- /dev/null +++ b/examples/osgmultiviewOVR/StandardStereo.cpp @@ -0,0 +1,267 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#include "StandardStereo.h" + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace osgViewer; + +osg::ref_ptr StandardStereo::createStereoMesh(const osg::Vec3& origin, const osg::Vec3& widthVector, const osg::Vec3& heightVector) const +{ + osg::Vec3d center(0.0,0.0,0.0); + osg::Vec3d eye(0.0,0.0,0.0); + + // create the quad to visualize. + osg::Geometry* geometry = new osg::Geometry(); + + geometry->setSupportsDisplayList(false); + + osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES); + osg::Vec3Array* vertices = new osg::Vec3Array; + osg::Vec3Array* texcoords = new osg::Vec3Array; + osg::Vec4Array* colors = new osg::Vec4Array; + colors->push_back(osg::Vec4(1.0, 1.0, 0.0, 1.0)); + + // left hand side + vertices->push_back(origin); texcoords->push_back(osg::Vec3(0.0f, 0.0f, 0.0f)); + vertices->push_back(origin + widthVector*0.5f); texcoords->push_back(osg::Vec3(1.0f, 0.0f, 0.0f)); + vertices->push_back(origin + widthVector*0.5f +heightVector); texcoords->push_back(osg::Vec3(1.0f, 1.0f, 0.0f)); + vertices->push_back(origin + heightVector); texcoords->push_back(osg::Vec3(0.0f, 1.0f, 0.0f)); + + elements->push_back(0); + elements->push_back(1); + elements->push_back(2); + elements->push_back(2); + elements->push_back(3); + elements->push_back(0); + + // right hand side + vertices->push_back(origin + widthVector*0.5f); texcoords->push_back(osg::Vec3(0.0f, 0.0f, 1.0f)); + vertices->push_back(origin + widthVector); texcoords->push_back(osg::Vec3(1.0f, 0.0f, 1.0f)); + vertices->push_back(origin + widthVector +heightVector); texcoords->push_back(osg::Vec3(1.0f, 1.0f, 1.0f)); + vertices->push_back(origin + widthVector*0.5f + heightVector); texcoords->push_back(osg::Vec3(0.0f, 1.0f, 1.0f)); + + elements->push_back(4); + elements->push_back(5); + elements->push_back(6); + elements->push_back(6); + elements->push_back(7); + elements->push_back(4); + + geometry->setVertexArray(vertices); + geometry->setColorArray(colors, osg::Array::BIND_OVERALL); + geometry->setTexCoordArray(0, texcoords); + geometry->addPrimitiveSet(elements); + + return geometry; +} + +void StandardStereo::configure(osgViewer::View& view) const +{ + osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface(); + if (!wsi) + { + OSG_NOTICE<<"Error, no WindowSystemInterface available, cannot create windows."<getScreenResolution(si, width, height); + + osg::ref_ptr traits = new osg::GraphicsContext::Traits; + traits->hostName = si.hostName; + traits->displayNum = si.displayNum; + traits->screenNum = si.screenNum; + traits->x = 0; + traits->y = 0; + traits->width = width; + traits->height = height; + traits->windowDecoration = false; + traits->doubleBuffer = true; + traits->sharedContext = 0; + + osg::ref_ptr gc = osg::GraphicsContext::createGraphicsContext(traits.get()); + if (!gc) + { + OSG_NOTICE<<"GraphicsWindow has not been created successfully."<setTextureSize(tex_width, tex_height, 2); + texture->setInternalFormat(GL_RGBA); + texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR); + texture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR); + texture->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_EDGE); + texture->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_EDGE); + texture->setWrap(osg::Texture::WRAP_R,osg::Texture::CLAMP_TO_EDGE); + +#if 0 + osg::Camera::RenderTargetImplementation renderTargetImplementation = osg::Camera::SEPERATE_WINDOW; + GLenum buffer = GL_FRONT; +#else + osg::Camera::RenderTargetImplementation renderTargetImplementation = osg::Camera::FRAME_BUFFER_OBJECT; + GLenum buffer = GL_FRONT; +#endif + + // left eye + { + osg::ref_ptr camera = new osg::Camera; + camera->setName("Left eye camera"); + camera->setGraphicsContext(gc.get()); + camera->setViewport(new osg::Viewport(0,0,camera_width, camera_height)); + camera->setDrawBuffer(buffer); + camera->setReadBuffer(buffer); + camera->setAllowEventFocus(false); + + // tell the camera to use OpenGL frame buffer object where supported. + camera->setRenderTargetImplementation(renderTargetImplementation); + + // attach the texture and use it as the color buffer. + camera->attach(osg::Camera::COLOR_BUFFER, texture, 0, 0); + + // set up the projection and view matrices + osg::Matrixd projectionOffset = displaySettings->computeLeftEyeProjectionImplementation(osg::Matrixd()); + osg::Matrixd viewOffset = displaySettings->computeLeftEyeViewImplementation(osg::Matrixd()); + + std::cout<<"left projectionOffset = "<setGraphicsContext(gc.get()); + camera->setViewport(new osg::Viewport(0,0,camera_width, camera_height)); + camera->setDrawBuffer(buffer); + camera->setReadBuffer(buffer); + camera->setAllowEventFocus(false); + camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.2f, 1.0f)); + + // tell the camera to use OpenGL frame buffer object where supported. + camera->setRenderTargetImplementation(renderTargetImplementation); + + // attach the texture and use it as the color buffer. + camera->attach(osg::Camera::COLOR_BUFFER, texture, 0, 1); + + // set up the projection and view matrices + osg::Matrixd projectionOffset = displaySettings->computeRightEyeProjectionImplementation(osg::Matrixd()); + osg::Matrixd viewOffset = displaySettings->computeRightEyeViewImplementation(osg::Matrixd()); + + std::cout<<"right projectionOffset = "< vertexShader = osgDB::readRefShaderFile( osg::Shader::VERTEX, vsFileName) ; + if (vertexShader.get()) program->addShader( vertexShader.get() ); + + osg::ref_ptr fragmentShader = osgDB::readRefShaderFile( osg::Shader::FRAGMENT, fsFileName) ; + if (fragmentShader.get()) program->addShader( fragmentShader.get() ); + } + + osg::ref_ptr camera = new osg::Camera; + camera->setGraphicsContext(gc.get()); + camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ); + camera->setClearColor( osg::Vec4(0.0,0.0,0.0,1.0) ); + camera->setViewport(new osg::Viewport(0, 0, width, height)); + + GLenum window_buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; + camera->setDrawBuffer(window_buffer); + camera->setReadBuffer(window_buffer); + camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); + camera->setAllowEventFocus(true); + camera->setInheritanceMask(camera->getInheritanceMask() & ~osg::CullSettings::CLEAR_COLOR & ~osg::CullSettings::COMPUTE_NEAR_FAR_MODE); + //camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR); + + camera->setProjectionMatrixAsOrtho2D(0,width,0,height); + camera->setViewMatrix(osg::Matrix::identity()); + + // add subgraph to render + camera->addChild(mesh.get()); + + camera->setName("DistortionCorrectionCamera"); + + osgDB::writeNodeFile(*mesh, "mesh.osgt"); + + view.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd(), false); + } + + view.getCamera()->setNearFarRatio(0.0001f); + + if (view.getLightingMode()==osg::View::HEADLIGHT) + { + // set a local light source for headlight to ensure that lighting is consistent across sides of cube. + view.getLight()->setPosition(osg::Vec4(0.0f,0.0f,0.0f,1.0f)); + } +} diff --git a/examples/osgmultiviewOVR/StandardStereo.h b/examples/osgmultiviewOVR/StandardStereo.h new file mode 100644 index 000000000..db187abcf --- /dev/null +++ b/examples/osgmultiviewOVR/StandardStereo.h @@ -0,0 +1,45 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef OSGVIEWER_StandardStereo +#define OSGVIEWER_StandardStereo 1 + +#include + +/** spherical display using 6 slave cameras rendering the 6 sides of a cube map, and 7th camera doing distortion correction to present on a spherical display.*/ +class StandardStereo : public osgViewer::ViewConfig +{ + public: + + StandardStereo(unsigned int screenNum=0): + _screenNum(screenNum) {} + + StandardStereo(const StandardStereo& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY): + ViewConfig(rhs,copyop), + _screenNum(rhs._screenNum) {} + + META_Object(osgViewer,StandardStereo); + + virtual void configure(osgViewer::View& view) const; + + void setScreenNum(unsigned int n) { _screenNum = n; } + unsigned int getScreenNum() const { return _screenNum; } + + protected: + + osg::ref_ptr createStereoMesh(const osg::Vec3& origin, const osg::Vec3& widthVector, const osg::Vec3& heightVector) const; + + unsigned int _screenNum; +}; + +#endif diff --git a/examples/osgmultiviewOVR/standard.frag b/examples/osgmultiviewOVR/standard.frag new file mode 100644 index 000000000..d8e1924fd --- /dev/null +++ b/examples/osgmultiviewOVR/standard.frag @@ -0,0 +1,9 @@ +#extension GL_EXT_texture_array : enable + +uniform sampler2DArray texture; +varying vec3 texcoord; + +void main(void) +{ + gl_FragColor = texture2DArray( texture, texcoord.xyz); +} diff --git a/examples/osgmultiviewOVR/standard.vert b/examples/osgmultiviewOVR/standard.vert new file mode 100644 index 000000000..8b1e0892a --- /dev/null +++ b/examples/osgmultiviewOVR/standard.vert @@ -0,0 +1,7 @@ +varying vec3 texcoord; + +void main(void) +{ + texcoord = gl_MultiTexCoord0.xyz; + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; +} From c1b3a30e7c24af092c4991a1e03462ac92f322e9 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 12 Nov 2020 12:36:24 +0000 Subject: [PATCH 3/3] Copied StandardStereo class renamed to MultivewOVR to use as base of multiviewOVR work. --- examples/osgmultiviewOVR/MultiviewOVR.cpp | 259 ++++++++++++++++++++ examples/osgmultiviewOVR/MultiviewOVR.h | 45 ++++ examples/osgmultiviewOVR/StandardStereo.cpp | 8 - examples/osgmultiviewOVR/multiviewOVR.frag | 9 + examples/osgmultiviewOVR/multiviewOVR.vert | 7 + 5 files changed, 320 insertions(+), 8 deletions(-) create mode 100644 examples/osgmultiviewOVR/MultiviewOVR.cpp create mode 100644 examples/osgmultiviewOVR/MultiviewOVR.h create mode 100644 examples/osgmultiviewOVR/multiviewOVR.frag create mode 100644 examples/osgmultiviewOVR/multiviewOVR.vert diff --git a/examples/osgmultiviewOVR/MultiviewOVR.cpp b/examples/osgmultiviewOVR/MultiviewOVR.cpp new file mode 100644 index 000000000..e814adfda --- /dev/null +++ b/examples/osgmultiviewOVR/MultiviewOVR.cpp @@ -0,0 +1,259 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#include "MultiviewOVR.h" + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace osgViewer; + +osg::ref_ptr MultiviewOVR::createStereoMesh(const osg::Vec3& origin, const osg::Vec3& widthVector, const osg::Vec3& heightVector) const +{ + osg::Vec3d center(0.0,0.0,0.0); + osg::Vec3d eye(0.0,0.0,0.0); + + // create the quad to visualize. + osg::Geometry* geometry = new osg::Geometry(); + + geometry->setSupportsDisplayList(false); + + osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES); + osg::Vec3Array* vertices = new osg::Vec3Array; + osg::Vec3Array* texcoords = new osg::Vec3Array; + osg::Vec4Array* colors = new osg::Vec4Array; + colors->push_back(osg::Vec4(1.0, 1.0, 0.0, 1.0)); + + // left hand side + vertices->push_back(origin); texcoords->push_back(osg::Vec3(0.0f, 0.0f, 0.0f)); + vertices->push_back(origin + widthVector*0.5f); texcoords->push_back(osg::Vec3(1.0f, 0.0f, 0.0f)); + vertices->push_back(origin + widthVector*0.5f +heightVector); texcoords->push_back(osg::Vec3(1.0f, 1.0f, 0.0f)); + vertices->push_back(origin + heightVector); texcoords->push_back(osg::Vec3(0.0f, 1.0f, 0.0f)); + + elements->push_back(0); + elements->push_back(1); + elements->push_back(2); + elements->push_back(2); + elements->push_back(3); + elements->push_back(0); + + // right hand side + vertices->push_back(origin + widthVector*0.5f); texcoords->push_back(osg::Vec3(0.0f, 0.0f, 1.0f)); + vertices->push_back(origin + widthVector); texcoords->push_back(osg::Vec3(1.0f, 0.0f, 1.0f)); + vertices->push_back(origin + widthVector +heightVector); texcoords->push_back(osg::Vec3(1.0f, 1.0f, 1.0f)); + vertices->push_back(origin + widthVector*0.5f + heightVector); texcoords->push_back(osg::Vec3(0.0f, 1.0f, 1.0f)); + + elements->push_back(4); + elements->push_back(5); + elements->push_back(6); + elements->push_back(6); + elements->push_back(7); + elements->push_back(4); + + geometry->setVertexArray(vertices); + geometry->setColorArray(colors, osg::Array::BIND_OVERALL); + geometry->setTexCoordArray(0, texcoords); + geometry->addPrimitiveSet(elements); + + return geometry; +} + +void MultiviewOVR::configure(osgViewer::View& view) const +{ + osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface(); + if (!wsi) + { + OSG_NOTICE<<"Error, no WindowSystemInterface available, cannot create windows."<getScreenResolution(si, width, height); + + osg::ref_ptr traits = new osg::GraphicsContext::Traits; + traits->hostName = si.hostName; + traits->displayNum = si.displayNum; + traits->screenNum = si.screenNum; + traits->x = 0; + traits->y = 0; + traits->width = width; + traits->height = height; + traits->windowDecoration = false; + traits->doubleBuffer = true; + traits->sharedContext = 0; + + osg::ref_ptr gc = osg::GraphicsContext::createGraphicsContext(traits.get()); + if (!gc) + { + OSG_NOTICE<<"GraphicsWindow has not been created successfully."<setTextureSize(tex_width, tex_height, 2); + texture->setInternalFormat(GL_RGBA); + texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR); + texture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR); + texture->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_EDGE); + texture->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_EDGE); + texture->setWrap(osg::Texture::WRAP_R,osg::Texture::CLAMP_TO_EDGE); + +#if 0 + osg::Camera::RenderTargetImplementation renderTargetImplementation = osg::Camera::SEPERATE_WINDOW; + GLenum buffer = GL_FRONT; +#else + osg::Camera::RenderTargetImplementation renderTargetImplementation = osg::Camera::FRAME_BUFFER_OBJECT; + GLenum buffer = GL_FRONT; +#endif + + // left eye + { + osg::ref_ptr camera = new osg::Camera; + camera->setName("Left eye camera"); + camera->setGraphicsContext(gc.get()); + camera->setViewport(new osg::Viewport(0,0,camera_width, camera_height)); + camera->setDrawBuffer(buffer); + camera->setReadBuffer(buffer); + camera->setAllowEventFocus(false); + + // tell the camera to use OpenGL frame buffer object where supported. + camera->setRenderTargetImplementation(renderTargetImplementation); + + // attach the texture and use it as the color buffer. + camera->attach(osg::Camera::COLOR_BUFFER, texture, 0, 0); + + // set up the projection and view matrices + osg::Matrixd projectionOffset = displaySettings->computeLeftEyeProjectionImplementation(osg::Matrixd()); + osg::Matrixd viewOffset = displaySettings->computeLeftEyeViewImplementation(osg::Matrixd()); + + view.addSlave(camera.get(), projectionOffset, viewOffset); + } + + // right eye + { + osg::ref_ptr camera = new osg::Camera; + camera->setName("Right eyecamera"); + camera->setGraphicsContext(gc.get()); + camera->setViewport(new osg::Viewport(0,0,camera_width, camera_height)); + camera->setDrawBuffer(buffer); + camera->setReadBuffer(buffer); + camera->setAllowEventFocus(false); + camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.5f, 1.0f)); + + // tell the camera to use OpenGL frame buffer object where supported. + camera->setRenderTargetImplementation(renderTargetImplementation); + + // attach the texture and use it as the color buffer. + camera->attach(osg::Camera::COLOR_BUFFER, texture, 0, 1); + + // set up the projection and view matrices + osg::Matrixd projectionOffset = displaySettings->computeRightEyeProjectionImplementation(osg::Matrixd()); + osg::Matrixd viewOffset = displaySettings->computeRightEyeViewImplementation(osg::Matrixd()); + + view.addSlave(camera.get(), projectionOffset, viewOffset); + } + + view.getCamera()->setProjectionMatrixAsPerspective(90.0f, 1.0, 1, 1000.0); + + // distortion correction set up. + { + osg::ref_ptr mesh = createStereoMesh(osg::Vec3(0.0f,0.0f,0.0f), osg::Vec3(width,0.0f,0.0f), osg::Vec3(0.0f,height,0.0f)); + + // new we need to add the texture to the mesh, we do so by creating a + // StateSet to contain the Texture StateAttribute. + osg::StateSet* stateset = mesh->getOrCreateStateSet(); + stateset->setTextureAttribute(0, texture, osg::StateAttribute::ON); + stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + + { + osg::ref_ptr program = new osg::Program(); + stateset->setAttribute(program.get(), osg::StateAttribute::ON); + + std::string vsFileName("multiviewOVR.vert"); + std::string fsFileName("multiviewOVR.frag"); + + osg::ref_ptr vertexShader = osgDB::readRefShaderFile( osg::Shader::VERTEX, vsFileName) ; + if (vertexShader.get()) program->addShader( vertexShader.get() ); + + osg::ref_ptr fragmentShader = osgDB::readRefShaderFile( osg::Shader::FRAGMENT, fsFileName) ; + if (fragmentShader.get()) program->addShader( fragmentShader.get() ); + } + + osg::ref_ptr camera = new osg::Camera; + camera->setGraphicsContext(gc.get()); + camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ); + camera->setClearColor( osg::Vec4(0.0,0.0,0.0,1.0) ); + camera->setViewport(new osg::Viewport(0, 0, width, height)); + + GLenum window_buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; + camera->setDrawBuffer(window_buffer); + camera->setReadBuffer(window_buffer); + camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); + camera->setAllowEventFocus(true); + camera->setInheritanceMask(camera->getInheritanceMask() & ~osg::CullSettings::CLEAR_COLOR & ~osg::CullSettings::COMPUTE_NEAR_FAR_MODE); + //camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR); + + camera->setProjectionMatrixAsOrtho2D(0,width,0,height); + camera->setViewMatrix(osg::Matrix::identity()); + + // add subgraph to render + camera->addChild(mesh.get()); + + camera->setName("DistortionCorrectionCamera"); + + osgDB::writeNodeFile(*mesh, "mesh.osgt"); + + view.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd(), false); + } + + view.getCamera()->setNearFarRatio(0.0001f); + + if (view.getLightingMode()==osg::View::HEADLIGHT) + { + // set a local light source for headlight to ensure that lighting is consistent across sides of cube. + view.getLight()->setPosition(osg::Vec4(0.0f,0.0f,0.0f,1.0f)); + } +} diff --git a/examples/osgmultiviewOVR/MultiviewOVR.h b/examples/osgmultiviewOVR/MultiviewOVR.h new file mode 100644 index 000000000..04a71f500 --- /dev/null +++ b/examples/osgmultiviewOVR/MultiviewOVR.h @@ -0,0 +1,45 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef OSGVIEWER_MultiviewOVR +#define OSGVIEWER_MultiviewOVR 1 + +#include + +/** spherical display using 6 slave cameras rendering the 6 sides of a cube map, and 7th camera doing distortion correction to present on a spherical display.*/ +class MultiviewOVR : public osgViewer::ViewConfig +{ + public: + + MultiviewOVR(unsigned int screenNum=0): + _screenNum(screenNum) {} + + MultiviewOVR(const MultiviewOVR& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY): + ViewConfig(rhs,copyop), + _screenNum(rhs._screenNum) {} + + META_Object(osgViewer,MultiviewOVR); + + virtual void configure(osgViewer::View& view) const; + + void setScreenNum(unsigned int n) { _screenNum = n; } + unsigned int getScreenNum() const { return _screenNum; } + + protected: + + osg::ref_ptr createStereoMesh(const osg::Vec3& origin, const osg::Vec3& widthVector, const osg::Vec3& heightVector) const; + + unsigned int _screenNum; +}; + +#endif diff --git a/examples/osgmultiviewOVR/StandardStereo.cpp b/examples/osgmultiviewOVR/StandardStereo.cpp index c7acff347..b620ffc53 100644 --- a/examples/osgmultiviewOVR/StandardStereo.cpp +++ b/examples/osgmultiviewOVR/StandardStereo.cpp @@ -169,10 +169,6 @@ void StandardStereo::configure(osgViewer::View& view) const osg::Matrixd projectionOffset = displaySettings->computeLeftEyeProjectionImplementation(osg::Matrixd()); osg::Matrixd viewOffset = displaySettings->computeLeftEyeViewImplementation(osg::Matrixd()); - std::cout<<"left projectionOffset = "<