From 94ad07af5e103cd0e18e2034aaca134625469cf7 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 9 Jul 2005 14:35:35 +0000 Subject: [PATCH] Ported osgdistortion example across to using osg::CameraNode. --- examples/osgdistortion/osgdistortion.cpp | 349 +++++++++-------------- 1 file changed, 132 insertions(+), 217 deletions(-) diff --git a/examples/osgdistortion/osgdistortion.cpp b/examples/osgdistortion/osgdistortion.cpp index c69a8a7c5..213d62da2 100644 --- a/examples/osgdistortion/osgdistortion.cpp +++ b/examples/osgdistortion/osgdistortion.cpp @@ -16,7 +16,6 @@ #include #include -#include #include #include @@ -26,228 +25,146 @@ using namespace osg; -class DistortionNode : public osg::Group +osg::Node* createDistortionSubgraph(osg::Node* subgraph) { -public: - - DistortionNode(); + osg::Group* distortionNode = new osg::Group; - DistortionNode(const DistortionNode& rhs,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY): - osg::Group(rhs,copyop) {} - - META_Node(osgDistortion, DistortionNode); - - virtual void traverse(osg::NodeVisitor& nv); - -protected: - - void createHUDSubgraph(); - - void preRender(osgUtil::CullVisitor& nv); - - osg::ref_ptr _hudSubgraph; - osg::ref_ptr _texture; - osg::ref_ptr _localStateSet; + unsigned int tex_width = 1024; + unsigned int tex_height = 1024; -}; - - -DistortionNode::DistortionNode() -{ - setCullingActive(false); - createHUDSubgraph(); -} - -void DistortionNode::createHUDSubgraph() -{ - // 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); - - - 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 = new osg::StateSet; - osg::Texture2D* texture = new osg::Texture2D; -// texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST); -// texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST); + texture->setTextureSize(tex_width, tex_height); + texture->setInternalFormat(GL_RGBA); texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR); texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR); - stateset->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON); - stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF); - polyGeom->setStateSet(stateset); - - _texture = texture; - - osg::Geode* geode = new osg::Geode(); - geode->addDrawable(polyGeom); - - // create the hud. - osg::MatrixTransform* modelview_abs = new osg::MatrixTransform; - modelview_abs->setReferenceFrame(osg::Transform::ABSOLUTE_RF); - modelview_abs->setMatrix(osg::Matrix::identity()); - modelview_abs->addChild(geode); - - osg::Projection* projection = new osg::Projection; - projection->setMatrix(osg::Matrix::ortho2D(0,1280,0,1024)); - projection->addChild(modelview_abs); - - _hudSubgraph = projection; - - _localStateSet = new osg::StateSet; - - -} - - -void DistortionNode::traverse(osg::NodeVisitor& nv) -{ - if (nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR) + + // set up the render to texture camera. { - osgUtil::CullVisitor* cullVisitor = dynamic_cast(&nv); - if (cullVisitor && _texture.valid() && _hudSubgraph.valid()) + osg::CameraNode* camera = new osg::CameraNode; + + // just inherit the main cameras view + camera->setReferenceFrame(osg::Transform::RELATIVE_RF); + camera->setProjectionMatrix(osg::Matrixd::identity()); + camera->setViewMatrix(osg::Matrixd::identity()); + + // set viewport + camera->setViewport(0,0,tex_width,tex_height); + camera->getOrCreateStateSet()->setAttribute(camera->getViewport()); + + // set the camera to render before the main camera. + camera->setRenderOrder(osg::CameraNode::PRE_RENDER); + + // tell the camera to use OpenGL frame buffer object where supported. + camera->setRenderTargetImplmentation(osg::CameraNode::FRAME_BUFFER_OBJECT); + + // attach the texture and use it as the color buffer. + camera->attach(osg::CameraNode::COLOR_BUFFER, texture); + + // add subgraph to render + camera->addChild(subgraph); + + distortionNode->addChild(camera); + } + + // set up the render to texture camera. + { + + // 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;iaccept(nv); - - return; + osg::Vec3 cursor = bottom+dy*(float)i; + osg::Vec2 texcoord = bottom_texcoord+dy_texcoord*(float)i; + for(j=0;jpush_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); + + + 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); + + // set up the camera to render the textured quad + osg::CameraNode* camera = new osg::CameraNode; + + // just inherit the main cameras view + camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); + camera->setViewMatrix(osg::Matrix::identity()); + camera->setProjectionMatrixAsOrtho2D(0,1280,0,1024); + + // set the camera to render before the main camera. + camera->setRenderOrder(osg::CameraNode::NESTED_RENDER); + + // tell the camera to use OpenGL frame buffer object where supported. + camera->setRenderTargetImplmentation(osg::CameraNode::FRAME_BUFFER_OBJECT); + + // attach the texture and use it as the color buffer. + camera->attach(osg::CameraNode::COLOR_BUFFER, texture); + + // add subgraph to render + camera->addChild(geode); + + distortionNode->addChild(camera); } - - Group::traverse(nv); -} - -void DistortionNode::preRender(osgUtil::CullVisitor& cv) -{ - // create the render to texture stage. - osg::ref_ptr rtts = new osgUtil::RenderToTextureStage; - - // set up lighting. - // currently ignore lights in the scene graph itself.. - // will do later. - osgUtil::RenderStage* previous_stage = cv.getCurrentRenderBin()->getStage(); - - // set up the background color and clear mask. - rtts->setClearColor(osg::Vec4(0.1f,0.1f,0.3f,1.0f)); - rtts->setClearMask(previous_stage->getClearMask()); - - // set up to charge the same RenderStageLighting is the parent previous stage. - rtts->setRenderStageLighting(previous_stage->getRenderStageLighting()); - - - // record the render bin, to be restored after creation - // of the render to text - osgUtil::RenderBin* previousRenderBin = cv.getCurrentRenderBin(); - - // set the current renderbin to be the newly created stage. - cv.setCurrentRenderBin(rtts.get()); - - cv.pushStateSet(_localStateSet.get()); - - { - - // traverse the subgraph - Group::traverse(cv); - - } - - cv.popStateSet(); - - // restore the previous renderbin. - cv.setCurrentRenderBin(previousRenderBin); - - if (rtts->getRenderGraphList().size()==0 && rtts->getRenderBinList().size()==0) - { - // getting to this point means that all the subgraph has been - // culled by small feature culling or is beyond LOD ranges. - return; - } - - int height = 1024; - int width = 1024; - - - const osg::Viewport& viewport = *cv.getViewport(); - - // offset the impostor viewport from the center of the main window - // viewport as often the edges of the viewport might be obscured by - // other windows, which can cause image/reading writing problems. - int center_x = viewport.x()+viewport.width()/2; - int center_y = viewport.y()+viewport.height()/2; - - osg::Viewport* new_viewport = new osg::Viewport; - new_viewport->setViewport(center_x-width/2,center_y-height/2,width,height); - rtts->setViewport(new_viewport); - - _localStateSet->setAttribute(new_viewport); - - // and the render to texture stage to the current stages - // dependancy list. - cv.getCurrentRenderBin()->getStage()->addToDependencyList(rtts.get()); - - // if one exist attach texture to the RenderToTextureStage. - if (_texture.valid()) rtts->setTexture(_texture.get()); + return distortionNode; } @@ -302,10 +219,8 @@ int main( int argc, char **argv ) return 1; } - // create a transform to spin the model. - DistortionNode* distortionNode = new DistortionNode; - distortionNode->addChild(loadedModel); - + osg::Node* distortionNode = createDistortionSubgraph(loadedModel); + // add model to the viewer. viewer.setSceneData( distortionNode );