#include "extViewer.h" #include "distortionNG.h" #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() { } 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 = true; 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* texture = new osg::TextureRectangle; texture->setTextureSize(tex_width, tex_height); texture->setInternalFormat(GL_RGB); 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); #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, texture); addSlave(camera.get(), osg::Matrixd(), osg::Matrixd()); } // distortion correction set up. { osg::Geode* geode = new osg::Geode(); //geode->addDrawable(createParoramicSphericalDisplayDistortionMesh(osg::Vec3(0.0f,0.0f,0.0f), osg::Vec3(width,0.0f,0.0f), osg::Vec3(0.0f,height,0.0f), 1, 0.45, 0, projectorMatrix)); 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, projectorMatrix); geode->addDrawable(distortionMesh); // 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 = geode->getOrCreateStateSet(); stateset->setTextureAttributeAndModes(0, texture,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 (!applyIntensityMapAsColours && intensityMap) { stateset->setTextureAttributeAndModes(1, new osg::Texture2D(intensityMap), 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,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()); // add subgraph to render //camera->addChild(geode); // 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); } } osg::Geometry* extViewer::createMesh(const osg::Vec3& origin, const osg::Vec3& widthVector, const osg::Vec3& heightVector, unsigned int columns, unsigned int rows, 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 ); // geometry osg::Vec2 texcoord = osg::Vec2((float)col/(float)(columns-1), (float)row/(float)(rows-1)); texcoords0->push_back( texcoord ); // if (intensityMap) // { // colors->push_back(intensityMap->getColor(texcoord1)); // } // else // { colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); // if (texcoords1) texcoords1->push_back( texcoord1 ); // } } } // 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) geometry->setTexCoordArray(1,texcoords1); // osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES); // geometry->addPrimitiveSet(elements); 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() ); } return geom.release(); }