diff --git a/examples/osgdistortion/osgdistortion.cpp b/examples/osgdistortion/osgdistortion.cpp index f6796a043..88de1a54a 100644 --- a/examples/osgdistortion/osgdistortion.cpp +++ b/examples/osgdistortion/osgdistortion.cpp @@ -10,10 +10,13 @@ #include #include #include +#include +#include #include #include #include +#include #include @@ -21,6 +24,8 @@ #include #include +#include +#include using namespace osg; @@ -68,9 +73,8 @@ osg::Node* createDistortionSubgraph(osg::Node* subgraph, const osg::Vec4& clearC distortionNode->addChild(camera); } - // set up the render to texture camera. + // set up the hud camera { - // create the quad to visualize. osg::Geometry* polyGeom = new osg::Geometry(); @@ -155,12 +159,6 @@ osg::Node* createDistortionSubgraph(osg::Node* subgraph, const osg::Vec4& clearC // set the camera to render before the main camera. camera->setRenderOrder(osg::Camera::NESTED_RENDER); - // tell the camera to use OpenGL frame buffer object where supported. - camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); - - // attach the texture and use it as the color buffer. - camera->attach(osg::Camera::COLOR_BUFFER, texture); - // add subgraph to render camera->addChild(geode); @@ -169,7 +167,7 @@ osg::Node* createDistortionSubgraph(osg::Node* subgraph, const osg::Vec4& clearC return distortionNode; } -void setDomeCorrection(osgViewer::Viewer& viewer, osg::ArgumentParser& arguments) +void setDomeFaces(osgViewer::Viewer& viewer, osg::ArgumentParser& /*arguments*/) { osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface(); @@ -281,6 +279,281 @@ void setDomeCorrection(osgViewer::Viewer& viewer, osg::ArgumentParser& arguments viewer.assignSceneDataToCameras(); } +struct DrawCallback : public osg::Drawable::DrawCallback +{ + + DrawCallback() {} + + virtual void drawImplementation(osg::State& state,const osg::Drawable* drawable) const + { + osg::notify(osg::NOTICE)<<"I am here"<drawImplementation(state); + } +}; + + +void setDomeCorrection(osgViewer::Viewer& viewer, osg::ArgumentParser& /*arguments*/) +{ + + osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface(); + if (!wsi) + { + osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height); + + osg::ref_ptr traits = new osg::GraphicsContext::Traits; + 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::notify(osg::NOTICE)<<"GraphicsWindow has not been created successfully."<setClearColor(osg::Vec4f(0.2f,0.2f,0.6f,1.0f)); + gc->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + + int center_x = width/2; + int center_y = height/2; + int camera_width = 256; + int camera_height = 256; + + int tex_width = 256; + int tex_height = 256; + + osg::TextureCubeMap* texture = new osg::TextureCubeMap; + texture->setTextureSize(tex_width, tex_height); + texture->setInternalFormat(GL_RGB); + 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); + texture->setFilter(osg::TextureCubeMap::MIN_FILTER,osg::TextureCubeMap::LINEAR); + texture->setFilter(osg::TextureCubeMap::MAG_FILTER,osg::TextureCubeMap::LINEAR); + + // front face + { + osg::ref_ptr camera = new osg::Camera; + camera->setName("Front face camera"); + camera->setGraphicsContext(gc.get()); + camera->setViewport(new osg::Viewport(center_x-camera_width/2, center_y, camera_width, camera_height)); + GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; + camera->setDrawBuffer(buffer); + camera->setReadBuffer(buffer); + + // attach the texture and use it as the color buffer. + camera->attach(osg::Camera::COLOR_BUFFER, texture, 0, osg::TextureCubeMap::POSITIVE_Z); + + viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd()); + } + + // top face + { + osg::ref_ptr camera = new osg::Camera; + camera->setName("Top face camera"); + camera->setGraphicsContext(gc.get()); + camera->setViewport(new osg::Viewport(center_x-camera_width/2, center_y+camera_height, camera_width, camera_height)); + GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; + camera->setDrawBuffer(buffer); + camera->setReadBuffer(buffer); + + // attach the texture and use it as the color buffer. + camera->attach(osg::Camera::COLOR_BUFFER, texture, 0, osg::TextureCubeMap::POSITIVE_Y); + + viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd::rotate(osg::inDegrees(-90.0f), 1.0,0.0,0.0)); + } + + // left face + { + osg::ref_ptr camera = new osg::Camera; + camera->setName("Left face camera"); + camera->setGraphicsContext(gc.get()); + camera->setViewport(new osg::Viewport(center_x-camera_width*3/2, center_y, camera_width, camera_height)); + GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; + camera->setDrawBuffer(buffer); + camera->setReadBuffer(buffer); + + // attach the texture and use it as the color buffer. + camera->attach(osg::Camera::COLOR_BUFFER, texture, 0, osg::TextureCubeMap::NEGATIVE_X); + + viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd::rotate(osg::inDegrees(-90.0f), 0.0,1.0,0.0)); + } + + // right face + { + osg::ref_ptr camera = new osg::Camera; + camera->setName("Right face camera"); + camera->setGraphicsContext(gc.get()); + camera->setViewport(new osg::Viewport(center_x+camera_width/2, center_y, camera_width, camera_height)); + GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; + camera->setDrawBuffer(buffer); + camera->setReadBuffer(buffer); + + // attach the texture and use it as the color buffer. + camera->attach(osg::Camera::COLOR_BUFFER, texture, 0, osg::TextureCubeMap::NEGATIVE_X); + + viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd::rotate(osg::inDegrees(90.0f), 0.0,1.0,0.0)); + } + + // bottom face + { + osg::ref_ptr camera = new osg::Camera; + camera->setGraphicsContext(gc.get()); + camera->setName("Bottom face camera"); + camera->setViewport(new osg::Viewport(center_x-camera_width/2, center_y-camera_height, camera_width, camera_height)); + GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; + camera->setDrawBuffer(buffer); + camera->setReadBuffer(buffer); + + // attach the texture and use it as the color buffer. + camera->attach(osg::Camera::COLOR_BUFFER, texture, 0, osg::TextureCubeMap::NEGATIVE_Y); + + viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd::rotate(osg::inDegrees(90.0f), 1.0,0.0,0.0)); + } + + // back face + { + osg::ref_ptr camera = new osg::Camera; + camera->setName("Back face camera"); + camera->setGraphicsContext(gc.get()); + camera->setViewport(new osg::Viewport(center_x-camera_width/2, center_y-2*camera_height, camera_width, camera_height)); + GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; + camera->setDrawBuffer(buffer); + camera->setReadBuffer(buffer); + + // attach the texture and use it as the color buffer. + camera->attach(osg::Camera::COLOR_BUFFER, texture, 0, osg::TextureCubeMap::NEGATIVE_Z); + + viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd::rotate(osg::inDegrees(-180.0f), 1.0,0.0,0.0)); + } + + viewer.getCamera()->setProjectionMatrixAsPerspective(90.0f, 1.0, 1, 1000.0); + + + viewer.assignSceneDataToCameras(); + + + // distortion correction set up. + { + + // create the quad to visualize. + osg::Geometry* polyGeom = new osg::Geometry(); + + polyGeom->setSupportsDisplayList(false); + + osg::Vec3 origin(0.0f,0.0f,0.0f); + osg::Vec3 xAxis(1.0f,0.0f,0.0f); + osg::Vec3 yAxis(0.0f,1.0f,0.0f); + osg::Vec3 zAxis(0.0f,0.0f,1.0f); + float height = 1024.0f; + float width = 1280.0f; + int noSteps = 50; + + osg::Vec3Array* vertices = new osg::Vec3Array; + osg::Vec2Array* texcoords = new osg::Vec2Array; + osg::Vec4Array* colors = new osg::Vec4Array; + + osg::Vec3 bottom = origin; + osg::Vec3 dx = xAxis*(width/((float)(noSteps-1))); + osg::Vec3 dy = yAxis*(height/((float)(noSteps-1))); + + osg::Vec2 bottom_texcoord(0.0f,0.0f); + osg::Vec2 dx_texcoord(1.0f/(float)(noSteps-1),0.0f); + osg::Vec2 dy_texcoord(0.0f,1.0f/(float)(noSteps-1)); + + osg::Vec3 cursor = bottom; + osg::Vec2 texcoord = bottom_texcoord; + int i,j; + for(i=0;ipush_back(cursor); + texcoords->push_back(osg::Vec2((sin(texcoord.x()*osg::PI-osg::PI*0.5)+1.0f)*0.5f,(sin(texcoord.y()*osg::PI-osg::PI*0.5)+1.0f)*0.5f)); + colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); + + cursor += dx; + texcoord += dx_texcoord; + } + } + + // pass the created vertex array to the points geometry object. + polyGeom->setVertexArray(vertices); + + polyGeom->setColorArray(colors); + polyGeom->setColorBinding(osg::Geometry::BIND_PER_VERTEX); + + polyGeom->setTexCoordArray(0,texcoords); + + polyGeom->setDrawCallback(new DrawCallback); + + + for(i=0;ipush_back(j+(i+1)*noSteps); + elements->push_back(j+(i)*noSteps); + } + polyGeom->addPrimitiveSet(elements); + } + + + // new we need to add the texture to the Drawable, we do so by creating a + // StateSet to contain the Texture StateAttribute. + osg::StateSet* stateset = polyGeom->getOrCreateStateSet(); + stateset->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON); + stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF); + + osg::Geode* geode = new osg::Geode(); + geode->addDrawable(polyGeom); + + 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.1,0.1,1.0,1.0) ); + camera->setViewport(new osg::Viewport(0, 0, width/2, height/2)); + GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; + camera->setDrawBuffer(buffer); + camera->setReadBuffer(buffer); + camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); + //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,1280,0,1024); + camera->setViewMatrix(osg::Matrix::identity()); + + // add subgraph to render + camera->addChild(geode); + + camera->setName("DistortionCorrectionCamera"); + + osg::notify(osg::NOTICE)<<"Original Projection matrix "<getProjectionMatrix()<getViewMatrix()<getOrCreateStateSet()) ); + + // add the stats handler + viewer.addEventHandler(new osgViewer::StatsHandler); + return viewer.run(); } ;