Show
Ignore:
Timestamp:
07/09/05 16:35:35 (9 years ago)
Author:
robert
Message:

Ported osgdistortion example across to using osg::CameraNode?.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/osgdistortion/osgdistortion.cpp

    r3528 r4377  
    1717 
    1818#include <osgUtil/TransformCallback> 
    19 #include <osgUtil/RenderToTextureStage> 
    2019#include <osgUtil/SmoothingVisitor> 
    2120 
     
    2726using namespace osg; 
    2827 
    29 class DistortionNode : public osg::Group 
     28osg::Node* createDistortionSubgraph(osg::Node* subgraph) 
    3029{ 
    31 public: 
    32  
    33     DistortionNode(); 
    34      
    35     DistortionNode(const DistortionNode& rhs,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY): 
    36         osg::Group(rhs,copyop) {} 
    37  
    38     META_Node(osgDistortion, DistortionNode); 
    39  
    40     virtual void traverse(osg::NodeVisitor& nv); 
    41  
    42 protected: 
    43  
    44     void createHUDSubgraph(); 
    45  
    46     void preRender(osgUtil::CullVisitor& nv);    
    47  
    48     osg::ref_ptr<osg::Node>         _hudSubgraph; 
    49     osg::ref_ptr<osg::Texture2D>    _texture;     
    50     osg::ref_ptr<osg::StateSet>     _localStateSet; 
    51      
    52 }; 
    53  
    54  
    55 DistortionNode::DistortionNode() 
    56 { 
    57     setCullingActive(false); 
    58     createHUDSubgraph(); 
    59 } 
    60  
    61 void DistortionNode::createHUDSubgraph() 
    62 { 
    63     // create the quad to visualize. 
    64     osg::Geometry* polyGeom = new osg::Geometry(); 
    65  
    66     polyGeom->setSupportsDisplayList(false); 
    67  
    68     osg::Vec3 origin(0.0f,0.0f,0.0f); 
    69     osg::Vec3 xAxis(1.0f,0.0f,0.0f); 
    70     osg::Vec3 yAxis(0.0f,1.0f,0.0f); 
    71     osg::Vec3 zAxis(0.0f,0.0f,1.0f); 
    72     float height = 1024.0f; 
    73     float width = 1280.0f; 
    74     int noSteps = 50; 
    75      
    76     osg::Vec3Array* vertices = new osg::Vec3Array; 
    77     osg::Vec2Array* texcoords = new osg::Vec2Array; 
    78     osg::Vec4Array* colors = new osg::Vec4Array; 
    79  
    80     osg::Vec3 bottom = origin; 
    81     osg::Vec3 dx = xAxis*(width/((float)(noSteps-1))); 
    82     osg::Vec3 dy = yAxis*(height/((float)(noSteps-1))); 
    83      
    84     osg::Vec2 bottom_texcoord(0.0f,0.0f); 
    85     osg::Vec2 dx_texcoord(1.0f/(float)(noSteps-1),0.0f); 
    86     osg::Vec2 dy_texcoord(0.0f,1.0f/(float)(noSteps-1)); 
    87      
    88     osg::Vec3 cursor = bottom; 
    89     osg::Vec2 texcoord = bottom_texcoord; 
    90     int i,j; 
    91     for(i=0;i<noSteps;++i) 
    92     { 
    93         osg::Vec3 cursor = bottom+dy*(float)i; 
    94         osg::Vec2 texcoord = bottom_texcoord+dy_texcoord*(float)i; 
    95         for(j=0;j<noSteps;++j) 
    96         { 
    97             vertices->push_back(cursor); 
    98             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)); 
    99             colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); 
    100              
    101             cursor += dx; 
    102             texcoord += dx_texcoord; 
    103         } 
    104     } 
    105  
    106     // pass the created vertex array to the points geometry object. 
    107     polyGeom->setVertexArray(vertices); 
    108  
    109     polyGeom->setColorArray(colors); 
    110     polyGeom->setColorBinding(osg::Geometry::BIND_PER_VERTEX); 
    111  
    112     polyGeom->setTexCoordArray(0,texcoords); 
    113      
    114  
    115     for(i=0;i<noSteps-1;++i) 
    116     { 
    117         osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(osg::PrimitiveSet::QUAD_STRIP); 
    118         for(j=0;j<noSteps;++j) 
    119         { 
    120             elements->push_back(j+(i+1)*noSteps); 
    121             elements->push_back(j+(i)*noSteps); 
    122         } 
    123         polyGeom->addPrimitiveSet(elements); 
    124     } 
    125  
    126  
    127     // new we need to add the texture to the Drawable, we do so by creating a  
    128     // StateSet to contain the Texture StateAttribute. 
    129     osg::StateSet* stateset = new osg::StateSet; 
    130  
     30    osg::Group* distortionNode = new osg::Group; 
     31     
     32    unsigned int tex_width = 1024; 
     33    unsigned int tex_height = 1024; 
     34     
    13135    osg::Texture2D* texture = new osg::Texture2D; 
    132 //     texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST); 
    133 //     texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST); 
     36    texture->setTextureSize(tex_width, tex_height); 
     37    texture->setInternalFormat(GL_RGBA); 
    13438    texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR); 
    13539    texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR); 
    136     stateset->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON); 
    137     stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF); 
    138     polyGeom->setStateSet(stateset); 
    139      
    140     _texture = texture; 
    141  
    142     osg::Geode* geode = new osg::Geode(); 
    143     geode->addDrawable(polyGeom); 
    144  
    145     // create the hud. 
    146     osg::MatrixTransform* modelview_abs = new osg::MatrixTransform; 
    147     modelview_abs->setReferenceFrame(osg::Transform::ABSOLUTE_RF); 
    148     modelview_abs->setMatrix(osg::Matrix::identity()); 
    149     modelview_abs->addChild(geode); 
    150  
    151     osg::Projection* projection = new osg::Projection; 
    152     projection->setMatrix(osg::Matrix::ortho2D(0,1280,0,1024)); 
    153     projection->addChild(modelview_abs); 
    154  
    155     _hudSubgraph = projection; 
    156      
    157     _localStateSet = new osg::StateSet; 
    158  
    159  
    160 } 
    161  
    162  
    163 void DistortionNode::traverse(osg::NodeVisitor& nv) 
    164 { 
    165     if (nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR) 
    166     { 
    167         osgUtil::CullVisitor* cullVisitor = dynamic_cast<osgUtil::CullVisitor*>(&nv); 
    168         if (cullVisitor && _texture.valid() && _hudSubgraph.valid()) 
     40    
     41    // set up the render to texture camera. 
     42    { 
     43        osg::CameraNode* camera = new osg::CameraNode; 
     44 
     45        // just inherit the main cameras view 
     46        camera->setReferenceFrame(osg::Transform::RELATIVE_RF); 
     47        camera->setProjectionMatrix(osg::Matrixd::identity()); 
     48        camera->setViewMatrix(osg::Matrixd::identity()); 
     49 
     50        // set viewport 
     51        camera->setViewport(0,0,tex_width,tex_height); 
     52        camera->getOrCreateStateSet()->setAttribute(camera->getViewport()); 
     53 
     54        // set the camera to render before the main camera. 
     55        camera->setRenderOrder(osg::CameraNode::PRE_RENDER); 
     56 
     57        // tell the camera to use OpenGL frame buffer object where supported. 
     58        camera->setRenderTargetImplmentation(osg::CameraNode::FRAME_BUFFER_OBJECT); 
     59 
     60        // attach the texture and use it as the color buffer. 
     61        camera->attach(osg::CameraNode::COLOR_BUFFER, texture); 
     62 
     63        // add subgraph to render 
     64        camera->addChild(subgraph); 
     65         
     66        distortionNode->addChild(camera); 
     67   } 
     68     
     69    // set up the render to texture camera. 
     70    { 
     71 
     72        // create the quad to visualize. 
     73        osg::Geometry* polyGeom = new osg::Geometry(); 
     74 
     75        polyGeom->setSupportsDisplayList(false); 
     76 
     77        osg::Vec3 origin(0.0f,0.0f,0.0f); 
     78        osg::Vec3 xAxis(1.0f,0.0f,0.0f); 
     79        osg::Vec3 yAxis(0.0f,1.0f,0.0f); 
     80        osg::Vec3 zAxis(0.0f,0.0f,1.0f); 
     81        float height = 1024.0f; 
     82        float width = 1280.0f; 
     83        int noSteps = 50; 
     84 
     85        osg::Vec3Array* vertices = new osg::Vec3Array; 
     86        osg::Vec2Array* texcoords = new osg::Vec2Array; 
     87        osg::Vec4Array* colors = new osg::Vec4Array; 
     88 
     89        osg::Vec3 bottom = origin; 
     90        osg::Vec3 dx = xAxis*(width/((float)(noSteps-1))); 
     91        osg::Vec3 dy = yAxis*(height/((float)(noSteps-1))); 
     92 
     93        osg::Vec2 bottom_texcoord(0.0f,0.0f); 
     94        osg::Vec2 dx_texcoord(1.0f/(float)(noSteps-1),0.0f); 
     95        osg::Vec2 dy_texcoord(0.0f,1.0f/(float)(noSteps-1)); 
     96 
     97        osg::Vec3 cursor = bottom; 
     98        osg::Vec2 texcoord = bottom_texcoord; 
     99        int i,j; 
     100        for(i=0;i<noSteps;++i) 
    169101        { 
    170             preRender(*cullVisitor); 
    171              
    172             _hudSubgraph->accept(nv); 
    173              
    174             return; 
     102            osg::Vec3 cursor = bottom+dy*(float)i; 
     103            osg::Vec2 texcoord = bottom_texcoord+dy_texcoord*(float)i; 
     104            for(j=0;j<noSteps;++j) 
     105            { 
     106                vertices->push_back(cursor); 
     107                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)); 
     108                colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); 
     109 
     110                cursor += dx; 
     111                texcoord += dx_texcoord; 
     112            } 
    175113        } 
    176     } 
    177      
    178     Group::traverse(nv); 
    179 } 
    180  
    181 void DistortionNode::preRender(osgUtil::CullVisitor& cv) 
    182 {    
    183     // create the render to texture stage. 
    184     osg::ref_ptr<osgUtil::RenderToTextureStage> rtts = new osgUtil::RenderToTextureStage; 
    185  
    186     // set up lighting. 
    187     // currently ignore lights in the scene graph itself.. 
    188     // will do later. 
    189     osgUtil::RenderStage* previous_stage = cv.getCurrentRenderBin()->getStage(); 
    190  
    191     // set up the background color and clear mask. 
    192     rtts->setClearColor(osg::Vec4(0.1f,0.1f,0.3f,1.0f)); 
    193     rtts->setClearMask(previous_stage->getClearMask()); 
    194  
    195     // set up to charge the same RenderStageLighting is the parent previous stage. 
    196     rtts->setRenderStageLighting(previous_stage->getRenderStageLighting()); 
    197  
    198  
    199     // record the render bin, to be restored after creation 
    200     // of the render to text 
    201     osgUtil::RenderBin* previousRenderBin = cv.getCurrentRenderBin(); 
    202  
    203     // set the current renderbin to be the newly created stage. 
    204     cv.setCurrentRenderBin(rtts.get()); 
    205  
    206     cv.pushStateSet(_localStateSet.get()); 
    207  
    208     { 
    209  
    210         // traverse the subgraph 
    211         Group::traverse(cv); 
    212  
    213     } 
    214  
    215     cv.popStateSet(); 
    216  
    217     // restore the previous renderbin. 
    218     cv.setCurrentRenderBin(previousRenderBin); 
    219  
    220     if (rtts->getRenderGraphList().size()==0 && rtts->getRenderBinList().size()==0) 
    221     { 
    222         // getting to this point means that all the subgraph has been 
    223         // culled by small feature culling or is beyond LOD ranges. 
    224         return; 
    225     } 
    226  
    227     int height = 1024; 
    228     int width  = 1024; 
    229  
    230  
    231     const osg::Viewport& viewport = *cv.getViewport(); 
    232  
    233     // offset the impostor viewport from the center of the main window 
    234     // viewport as often the edges of the viewport might be obscured by 
    235     // other windows, which can cause image/reading writing problems. 
    236     int center_x = viewport.x()+viewport.width()/2; 
    237     int center_y = viewport.y()+viewport.height()/2; 
    238  
    239     osg::Viewport* new_viewport = new osg::Viewport; 
    240     new_viewport->setViewport(center_x-width/2,center_y-height/2,width,height); 
    241     rtts->setViewport(new_viewport); 
    242      
    243     _localStateSet->setAttribute(new_viewport); 
    244  
    245     // and the render to texture stage to the current stages 
    246     // dependancy list. 
    247     cv.getCurrentRenderBin()->getStage()->addToDependencyList(rtts.get()); 
    248  
    249     // if one exist attach texture to the RenderToTextureStage. 
    250     if (_texture.valid()) rtts->setTexture(_texture.get()); 
     114 
     115        // pass the created vertex array to the points geometry object. 
     116        polyGeom->setVertexArray(vertices); 
     117 
     118        polyGeom->setColorArray(colors); 
     119        polyGeom->setColorBinding(osg::Geometry::BIND_PER_VERTEX); 
     120 
     121        polyGeom->setTexCoordArray(0,texcoords); 
     122 
     123 
     124        for(i=0;i<noSteps-1;++i) 
     125        { 
     126            osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(osg::PrimitiveSet::QUAD_STRIP); 
     127            for(j=0;j<noSteps;++j) 
     128            { 
     129                elements->push_back(j+(i+1)*noSteps); 
     130                elements->push_back(j+(i)*noSteps); 
     131            } 
     132            polyGeom->addPrimitiveSet(elements); 
     133        } 
     134 
     135 
     136        // new we need to add the texture to the Drawable, we do so by creating a  
     137        // StateSet to contain the Texture StateAttribute. 
     138        osg::StateSet* stateset = polyGeom->getOrCreateStateSet(); 
     139        stateset->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON); 
     140        stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF); 
     141 
     142        osg::Geode* geode = new osg::Geode(); 
     143        geode->addDrawable(polyGeom); 
     144 
     145        // set up the camera to render the textured quad 
     146        osg::CameraNode* camera = new osg::CameraNode; 
     147 
     148        // just inherit the main cameras view 
     149        camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); 
     150        camera->setViewMatrix(osg::Matrix::identity()); 
     151        camera->setProjectionMatrixAsOrtho2D(0,1280,0,1024); 
     152 
     153        // set the camera to render before the main camera. 
     154        camera->setRenderOrder(osg::CameraNode::NESTED_RENDER); 
     155 
     156        // tell the camera to use OpenGL frame buffer object where supported. 
     157        camera->setRenderTargetImplmentation(osg::CameraNode::FRAME_BUFFER_OBJECT); 
     158 
     159        // attach the texture and use it as the color buffer. 
     160        camera->attach(osg::CameraNode::COLOR_BUFFER, texture); 
     161 
     162        // add subgraph to render 
     163        camera->addChild(geode); 
     164         
     165        distortionNode->addChild(camera); 
     166    } 
     167    return distortionNode; 
    251168} 
    252169 
     
    303220    } 
    304221     
    305     // create a transform to spin the model. 
    306     DistortionNode* distortionNode = new DistortionNode; 
    307     distortionNode->addChild(loadedModel); 
    308  
     222    osg::Node* distortionNode = createDistortionSubgraph(loadedModel); 
     223     
    309224    // add model to the viewer. 
    310225    viewer.setSceneData( distortionNode );