#include "extViewer.h" #include "distortionNG.h" #include #include #include #include #include #include #include #include #include extViewer::extViewer() : Viewer() { } extViewer::extViewer(osg::ArgumentParser& arguments) : Viewer(arguments) { } extViewer::extViewer(const osgViewer::Viewer& viewer, const osg::CopyOp& copyop) : Viewer(viewer, copyop) { } extViewer::~extViewer() { } static osg::Texture* loadTexture( const std::string& fileName ) { std::string foundFileName = osgDB::findDataFile(fileName); if (foundFileName.length() != 0 ) { // load distortion map texture file osg::Image* image = osgDB::readImageFile(foundFileName); if (image) { osg::Texture2D* texture = new osg::Texture2D; texture->setImage(image); texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST); texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::NEAREST); texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_EDGE); texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_EDGE); return texture; } } OSG_NOTIFY(osg::WARN) << "File \"" << fileName << "\" not found." << std::endl; return NULL; } static osg::Geometry* createMesh(const osg::Vec3& origin, const osg::Vec3& widthVector, const osg::Vec3& heightVector, unsigned int columns, unsigned int rows, osg::Image* intensityMap, bool applyIntensityMapAsColours, const osg::Matrix& projectorMatrix) { // Create Quad to render on osg::ref_ptr 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::Vec2Array* texcoords1 = intensityMap==0 ? new osg::Vec2Array : 0; 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( origin+dy*row+dx*col ); // Create tex coordinates osg::Vec2 texcoord = osg::Vec2((float)col/(float)(columns-1), (float)row/(float)(rows-1)); // Set Coordinates for RTT-Texture (scene rendering) texcoords0->push_back( texcoord ); // Set Color of the mesh node if (intensityMap && applyIntensityMapAsColours) { colors->push_back(intensityMap->getColor(texcoord)); } else { colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); } // Set coordinates for second texcoords array (if applyIntensityMapAsColours==true) if (texcoords1) texcoords1->push_back( texcoord ); } } // 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); if (texcoords1) geom->setTexCoordArray(1,texcoords1); for ( unsigned int row=0; row de = new osg::DrawElementsUInt(GL_QUAD_STRIP, columns*2); // columns*2 = number of involved vertices for this strip. for ( unsigned int col=0; coladdPrimitiveSet( de.get() ); } //if (intensityMap && !applyIntensityMapAsColours) //{ // // create shaders for distortion // osg::Program* distortProgram = new osg::Program; // distortProgram->setName( "distortion" ); // osg::Shader* vShader = osg::Shader::readShaderFile( osg::Shader::VERTEX, "shader.vert" ); // vShader->setName("intensityMapVertShader"); // osg::Shader* fShader = osg::Shader::readShaderFile( osg::Shader::FRAGMENT, "shader.frag" ); // fShader->setName("intensityMapFragShader"); // if ( vShader && fShader ) // { // //distortProgram->addShader( vShader ); // distortProgram->addShader( fShader ); // geom->getOrCreateStateSet()->addUniform( new osg::Uniform("sceneTexture", 0) ); // geom->getOrCreateStateSet()->addUniform( new osg::Uniform("intensityMapTexture", 1) ); // geom->getOrCreateStateSet()->setAttributeAndModes(distortProgram, osg::StateAttribute::ON); // } //} return geom.release(); } void extViewer::setUpViewForManualDistortion(unsigned int screenNum, osg::Image* intensityMap, 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; bool applyIntensityMapAsColours = false; 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(), osg::Matrixd(), osg::Matrixd()); } // distortion correction set up. { osg::Geode* geode = new osg::Geode(); // new we need to add the scene texture to the mesh, we do so by creating a // StateSet to contain the Texture StateAttribute. osg::StateSet* stateset = geode->getOrCreateStateSet(); //stateset->setTextureAttributeAndModes(0, sceneTexture,osg::StateAttribute::ON); //stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF); //osg::TexMat* texmat = new osg::TexMat; // texmat->setScaleByTextureRectangleSize(true); // stateset->setTextureAttributeAndModes(0, texmat, osg::StateAttribute::ON); // If the intensityMap is used but not applyIntensityMapAsColours: Apply intensityMap as intensityMapTexture on unit 1 if (!applyIntensityMapAsColours && intensityMap) { osg::Texture2D* intensityMapTexture = new osg::Texture2D(intensityMap); intensityMapTexture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST); intensityMapTexture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::NEAREST); intensityMapTexture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_EDGE); intensityMapTexture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_EDGE); stateset->setTextureAttributeAndModes(1, intensityMapTexture, osg::StateAttribute::ON); osg::Texture* tmp = loadTexture( "test.jpg" ); if(tmp) { stateset->setTextureAttributeAndModes(0, tmp,osg::StateAttribute::ON); osg::TexMat* texmat = new osg::TexMat; texmat->setScaleByTextureRectangleSize(true); stateset->setTextureAttributeAndModes(0, 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), 20, 20, intensityMap, applyIntensityMapAsColours, projectorMatrix); geode->addDrawable(distortionMesh); if (intensityMap && !applyIntensityMapAsColours) { // create shaders for distortion osg::Program* distortProgram = new osg::Program; distortProgram->setName( "distortion" ); osg::Shader* vShader = osg::Shader::readShaderFile( osg::Shader::VERTEX, "shader.vert" ); vShader->setName("intensityMapVertShader"); osg::Shader* fShader = osg::Shader::readShaderFile( osg::Shader::FRAGMENT, "shader.frag" ); fShader->setName("intensityMapFragShader"); if ( vShader && fShader ) { //distortProgram->addShader( vShader ); distortProgram->addShader( fShader ); stateset->addUniform( new osg::Uniform("sceneTexture", 0) ); stateset->addUniform( new osg::Uniform("intensityMapTexture", 1) ); stateset->setAttributeAndModes(distortProgram, osg::StateAttribute::ON); } } 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,1.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()); //// selector //geode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); //geode->getOrCreateStateSet()->setAttributeAndModes( new osg::PolygonOffset(1.0f, 1.0f) ); //osg::ref_ptr selector = new distortionHandler( camera, distortionMesh ); osg::ref_ptr root = new osg::Group; root->addChild(geode); //root->addChild(selector->createVertexHighlighter()); //addEventHandler( selector.get() ); camera->addChild(root); //// Avoid that the highlighter is culled away //osg::CullSettings::CullingMode mode = camera->getCullingMode(); //camera->setCullingMode( mode & (~osg::CullSettings::SMALL_FEATURE_CULLING) ); camera->setName("Dist Cam"); addSlave(camera.get(), osg::Matrixd(), osg::Matrixd(), false); } }