/* osgVisual test. distortionNG, experimental. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include "extViewer.h" #include #include #include #include #include #include #include #include #include #include #include extViewer::extViewer() : Viewer() { } extViewer::extViewer(osg::ArgumentParser& arguments) : Viewer(arguments) { // Add help for command-line options here arguments.getApplicationUsage()->addCommandLineOption("--distort","load distortion file and set up geometrical distortion for viewer. This includes blending"); arguments.getApplicationUsage()->addCommandLineOption("--blend","Set up viewer for simple intensity map blending."); std::string distortionSetFilename = ""; std::string intensityMapFilename = ""; while( arguments.read("--blend",intensityMapFilename) ) {} while( arguments.read("--distort",distortionSetFilename) ) {} if( !intensityMapFilename.empty() ) { OSG_ALWAYS<<"Pure blendmap setup with : "<(distSet)); } else { OSG_ALWAYS<<"read distortionSet failed"< geom = new osg::Geometry; geom->setUseDisplayList( false ); osg::Vec3 xAxis(widthVector); float width = widthVector.length(); xAxis /= width; osg::Vec3 yAxis(heightVector); float height = heightVector.length(); yAxis /= height; osg::Vec3 dx = xAxis*(width/((float)(columns-1))); osg::Vec3 dy = yAxis*(height/((float)(rows-1))); // Create vertices and coordinates osg::Vec3Array* vertices = new osg::Vec3Array; osg::Vec2Array* texcoords0 = new osg::Vec2Array; osg::Vec4Array* colors = new osg::Vec4Array; geom->getOrCreateStateSet()->setMode(GL_CULL_FACE, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED); for ( unsigned int row=0; rowpush_back( vertex ); // Set Coordinates for RTT-Texture (scene rendering) texcoords0->push_back( osg::Vec2( vertex.x(), vertex.y()) ); // Set Color of the mesh node colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); } } // Pass the created vertex array to the points geometry object. geom->setUseVertexBufferObjects( true ); geom->setVertexArray(vertices); geom->setColorArray(colors); geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX); geom->setTexCoordArray(0,texcoords0); // Quads grid for ( unsigned int row=0; row de = new osg::DrawElementsUInt(osg::PrimitiveSet::QUAD_STRIP, columns*2); // columns*2 = number of involved vertices for this strip. for ( unsigned int col=0; coladdPrimitiveSet( de.get() ); } //// Triangle grid //for ( unsigned int row=0; row de = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP, columns * 2 ); // for ( unsigned int col=0; coladdPrimitiveSet( de.get() ); //} return geom.release(); } void extViewer::setUpViewForManualDistortion(osgViewer::DistortionSet* distSet, unsigned int screenNum, const osg::Matrixd& projectorMatrix) { OSG_INFO<<"View::setUpViewForManualDistortion(sn="<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."<getProjectionMatrixAsPerspective(fovy, aspectRatio, zNear, zFar); double newAspectRatio = double(traits->width) / double(traits->height); double aspectRatioChange = newAspectRatio / aspectRatio; if (aspectRatioChange != 1.0) { _camera->getProjectionMatrix() *= osg::Matrix::scale(1.0/aspectRatioChange,1.0,1.0); } int tex_width = width; int tex_height = height; int camera_width = tex_width; int camera_height = tex_height; osg::TextureRectangle* sceneTexture = new osg::TextureRectangle; sceneTexture->setTextureSize(tex_width, tex_height); sceneTexture->setInternalFormat(GL_RGB); sceneTexture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR); sceneTexture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR); sceneTexture->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_EDGE); sceneTexture->setWrap(osg::Texture::WRAP_T,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 // Scene camera { osg::ref_ptr camera = new osg::Camera; camera->setName("Scene cam"); 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, sceneTexture); addSlave(camera.get(), _distortionSet->getProjectionOffset(), _distortionSet->getViewOffset() ); } // distortion correction set up. { osg::ref_ptr root = _distortionSet->getDistortionInternals(); osg::Geode* meshGeode = new osg::Geode(); root->addChild(meshGeode, true); // Child #0 (adds mesh,shader,.. so camera renders mesh (and thus render the scene)) // new we need to add the scene texture to the mesh, we do so by creating a // Modify StateSet to contain the Texture StateAttribute. osg::StateSet* stateset = meshGeode->getOrCreateStateSet(); stateset->setTextureAttributeAndModes(_distortionSet->getTexUnitScene(), sceneTexture,osg::StateAttribute::ON); stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF); // Modify StateSet to protectit against state changes by the stateset Manipulator osg::PolygonMode* polyModeObj = new osg::PolygonMode; stateset->setAttribute(polyModeObj, osg::StateAttribute::PROTECTED|osg::StateAttribute::ON); osg::TexMat* texmat = new osg::TexMat; texmat->setScaleByTextureRectangleSize(true); stateset->setTextureAttributeAndModes(_distortionSet->getTexUnitScene(), texmat, osg::StateAttribute::ON); osg::Geometry* distortionMesh = createMesh(osg::Vec3(0.0f,0.0f,0.0f), osg::Vec3(width,0.0f,0.0f), osg::Vec3(0.0f,height,0.0f), _distortionSet->getDistortionMeshColumns(), _distortionSet->getDistortionMeshColumns(), projectorMatrix); meshGeode->addDrawable(distortionMesh); setUpIntensityMapBlending(_distortionSet, screenNum); 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 buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; camera->setDrawBuffer(buffer); camera->setReadBuffer(buffer); camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); camera->setAllowEventFocus(false); 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()); camera->addChild(root); _distortionSet->setDistortionCamera( camera ); // Ensure selector is visible: meshGeode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); meshGeode->getOrCreateStateSet()->setAttributeAndModes( new osg::PolygonOffset(1.0f, 1.0f) ); camera->setName("Dist Cam"); addSlave(camera.get(), osg::Matrixd(), osg::Matrixd(), false); } } void extViewer::setUpIntensityMapBlending(osgViewer::DistortionSet* distSet, unsigned int screenNum) { osg::Image* intensityMap = _distortionSet->getIntensityMap(); osg::StateSet* stateset = _distortionSet->getDistortionInternals()->getChild(osgViewer::DistortionSet::MESH)->getOrCreateStateSet(); if(intensityMap == NULL) return; if(stateset == NULL) { OSG_NOTICE<<"Error, no intensityMap or stateset for intensityMapBlending specified."<getScreenResolution(si, width, height); // Resize intensityMap if the dimensions are wrong if(intensityMap->s()!=width || intensityMap->t()!=height) intensityMap->scaleImage(width, height, intensityMap->r()); osg::TextureRectangle* intensityMapTexture = new osg::TextureRectangle(intensityMap); intensityMapTexture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR); intensityMapTexture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR); intensityMapTexture->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_EDGE); intensityMapTexture->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_EDGE); stateset->setTextureAttributeAndModes(_distortionSet->getTexUnitIntensityMap(), intensityMapTexture, osg::StateAttribute::ON); // create shader for blending osg::Program* IntensityMapProgram = new osg::Program; IntensityMapProgram->setName( "intensityMapBlending" ); osg::Shader* shaderVert = osg::Shader::readShaderFile( osg::Shader::VERTEX, "shader.vert" ); shaderVert->setName("shaderVert"); osg::Shader* shaderIntensityMap = osg::Shader::readShaderFile( osg::Shader::FRAGMENT, "shaderIntensityMap.frag" ); shaderIntensityMap->setName("shaderIntensityMap"); _distortionSet->setShaderIntensityMap( shaderIntensityMap ); if ( shaderVert && shaderIntensityMap ) { IntensityMapProgram->addShader( shaderVert ); IntensityMapProgram->addShader( shaderIntensityMap ); stateset->addUniform( new osg::Uniform("sceneTexture", (int)_distortionSet->getTexUnitScene()) ); stateset->addUniform( new osg::Uniform("intensityMapTexture", (int)_distortionSet->getTexUnitIntensityMap()) ); stateset->setAttributeAndModes(IntensityMapProgram, osg::StateAttribute::ON); } } void extViewer::setUpIntensityMapBlending(std::string intensityMap) { // Try to load intensityMap osg::Image* intMap = osgDB::readImageFile(intensityMap); if (!intMap) { osg::notify(osg::WARN) << "Quitting, couldn't find intensity map: " << intensityMap << std::endl; return; } // Create DistortionSet osgViewer::DistortionSet* ds = new osgViewer::DistortionSet(); ds->setIntensityMap( intMap ); ds->setDistortionMeshRows( 2 ); ds->setDistortionMeshColumns( 2 ); ds->setTexUnitScene( 0 ); ds->setTexUnitIntensityMap( 1 ); setUpViewForManualDistortion(ds); }