Show
Ignore:
Timestamp:
06/16/05 16:01:38 (9 years ago)
Author:
robert
Message:

Further FBO support work.

Files:
1 modified

Legend:

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

    r4332 r4340  
    2424#include <osgProducer/Viewer> 
    2525 
    26 #define USE_CAMERA_NODE 
    27  
    28 #ifndef USE_CAMERA_NODE 
    29  
    30     class MyUpdateCallback : public osg::NodeCallback 
    31     { 
    32         public: 
    33  
    34             MyUpdateCallback(osg::Node* subgraph): 
    35                 _subgraph(subgraph) {} 
    36  
    37             virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) 
    38             { 
    39                 // traverse the subgraph to update any nodes. 
    40                 if (_subgraph.valid()) _subgraph->accept(*nv); 
    41  
    42                 // must traverse the Node's subgraph             
    43                 traverse(node,nv); 
    44             } 
    45  
    46             osg::ref_ptr<osg::Node>     _subgraph; 
    47     }; 
    48  
    49  
    50     class MyCullCallback : public osg::NodeCallback 
    51     { 
    52         public: 
    53  
    54             MyCullCallback(osg::Node* subgraph,osg::Texture2D* texture): 
    55                 _subgraph(subgraph), 
    56                 _texture(texture), 
    57                 _localState(new osg::StateSet) {} 
    58  
    59             MyCullCallback(osg::Node* subgraph,osg::Image* image): 
    60                 _subgraph(subgraph), 
    61                 _image(image), 
    62                 _localState(new osg::StateSet) {} 
    63  
    64             virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) 
    65             { 
    66  
    67                 osgUtil::CullVisitor* cullVisitor = dynamic_cast<osgUtil::CullVisitor*>(nv); 
    68                 if (cullVisitor && (_texture.valid()|| _image.valid()) && _subgraph.valid()) 
    69                 {             
    70                     doPreRender(*node,*cullVisitor); 
    71  
    72                     // must traverse the subgraph             
    73                     traverse(node,nv); 
    74  
    75                 } 
    76                 else 
    77                 { 
    78                     // must traverse the subgraph             
    79                     traverse(node,nv); 
    80                 } 
    81             } 
    82  
    83             void doPreRender(osg::Node& node, osgUtil::CullVisitor& cv); 
    84  
    85             osg::ref_ptr<osg::Node>      _subgraph; 
    86             osg::ref_ptr<osg::Texture2D> _texture; 
    87             osg::ref_ptr<osg::Image>     _image; 
    88             osg::ref_ptr<osg::StateSet>  _localState; 
    89  
    90     }; 
    91  
    92     void MyCullCallback::doPreRender(osg::Node&, osgUtil::CullVisitor& cv) 
    93     {    
    94         const osg::BoundingSphere& bs = _subgraph->getBound(); 
    95         if (!bs.valid()) 
    96         { 
    97             osg::notify(osg::WARN) << "bb invalid"<<_subgraph.get()<<std::endl; 
    98             return; 
    99         } 
    100  
    101  
    102         // create the render to texture stage. 
    103         osg::ref_ptr<osgUtil::RenderToTextureStage> rtts = new osgUtil::RenderToTextureStage; 
    104  
    105         // set up lighting. 
    106         // currently ignore lights in the scene graph itself.. 
    107         // will do later. 
    108         osgUtil::RenderStage* previous_stage = cv.getCurrentRenderBin()->getStage(); 
    109  
    110         // set up the background color and clear mask. 
    111         rtts->setClearColor(osg::Vec4(0.1f,0.1f,0.3f,1.0f)); 
    112         rtts->setClearMask(previous_stage->getClearMask()); 
    113  
    114         // set up to charge the same RenderStageLighting is the parent previous stage. 
    115         rtts->setRenderStageLighting(previous_stage->getRenderStageLighting()); 
    116  
    117  
    118         // record the render bin, to be restored after creation 
    119         // of the render to text 
    120         osgUtil::RenderBin* previousRenderBin = cv.getCurrentRenderBin(); 
    121  
    122         // set the current renderbin to be the newly created stage. 
    123         cv.setCurrentRenderBin(rtts.get()); 
    124  
    125  
    126         float znear = 1.0f*bs.radius(); 
    127         float zfar  = 3.0f*bs.radius(); 
    128  
    129         // 2:1 aspect ratio as per flag geomtry below. 
    130         float top   = 0.25f*znear; 
    131         float right = 0.5f*znear; 
    132  
    133         znear *= 0.9f; 
    134         zfar *= 1.1f; 
    135  
    136         // set up projection. 
    137         osg::RefMatrix* projection = new osg::RefMatrix; 
    138         projection->makeFrustum(-right,right,-top,top,znear,zfar); 
    139  
    140         cv.pushProjectionMatrix(projection); 
    141  
    142         osg::RefMatrix* matrix = new osg::RefMatrix; 
    143         matrix->makeLookAt(bs.center()+osg::Vec3(0.0f,2.0f,0.0f)*bs.radius(),bs.center(),osg::Vec3(0.0f,0.0f,1.0f)); 
    144  
    145         cv.pushModelViewMatrix(matrix); 
    146  
    147         cv.pushStateSet(_localState.get()); 
    148  
    149         { 
    150  
    151             // traverse the subgraph 
    152             _subgraph->accept(cv); 
    153  
    154         } 
    155  
    156         cv.popStateSet(); 
    157  
    158         // restore the previous model view matrix. 
    159         cv.popModelViewMatrix(); 
    160  
    161         // restore the previous model view matrix. 
    162         cv.popProjectionMatrix(); 
    163  
    164         // restore the previous renderbin. 
    165         cv.setCurrentRenderBin(previousRenderBin); 
    166  
    167         if (rtts->getRenderGraphList().size()==0 && rtts->getRenderBinList().size()==0) 
    168         { 
    169             // getting to this point means that all the subgraph has been 
    170             // culled by small feature culling or is beyond LOD ranges. 
    171             return; 
    172         } 
    173  
    174  
    175  
    176         int height = 256; 
    177         int width  = 512; 
    178  
    179  
    180         const osg::Viewport& viewport = *cv.getViewport(); 
    181  
    182         // offset the impostor viewport from the center of the main window 
    183         // viewport as often the edges of the viewport might be obscured by 
    184         // other windows, which can cause image/reading writing problems. 
    185         int center_x = viewport.x()+viewport.width()/2; 
    186         int center_y = viewport.y()+viewport.height()/2; 
    187  
    188         osg::Viewport* new_viewport = new osg::Viewport; 
    189         new_viewport->setViewport(center_x-width/2,center_y-height/2,width,height); 
    190         rtts->setViewport(new_viewport); 
    191  
    192         _localState->setAttribute(new_viewport); 
    193  
    194         // and the render to texture stage to the current stages 
    195         // dependancy list. 
    196         cv.getCurrentRenderBin()->getStage()->addToDependencyList(rtts.get()); 
    197  
    198         // if one exist attach texture to the RenderToTextureStage. 
    199         if (_texture.valid()) rtts->setTexture(_texture.get()); 
    200  
    201         // if one exist attach image to the RenderToTextureStage. 
    202         if (_image.valid()) rtts->setImage(_image.get()); 
    203  
    204     } 
    205 #endif 
    20626 
    20727// call back which cretes a deformation field to oscilate the model. 
     
    343163    polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP,0,vertices->size())); 
    344164 
     165 
     166 
     167    unsigned int tex_width = 2048; 
     168    unsigned int tex_height = 2048; 
     169 
     170 
    345171    // new we need to add the texture to the Drawable, we do so by creating a  
    346172    // StateSet to contain the Texture StateAttribute. 
     
    348174 
    349175    osg::Texture2D* texture = new osg::Texture2D; 
     176    texture->setTextureSize(tex_width, tex_height); 
     177    texture->setInternalFormat(GL_RGBA); 
    350178    texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR); 
    351179    texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR); 
     
    359187    geode->addDrawable(polyGeom); 
    360188 
    361 #ifndef USE_CAMERA_NODE 
    362  
    363     osg::Group* parent = new osg::Group; 
    364      
    365     parent->setUpdateCallback(new MyUpdateCallback(subgraph)); 
    366      
    367     parent->setCullCallback(new MyCullCallback(subgraph,texture)); 
    368   
    369     parent->addChild(geode); 
    370      
    371     return parent; 
    372  
    373 #else 
    374  
    375189 
    376190    osg::CameraNode* camera = new osg::CameraNode; 
     
    404218 
    405219    // set viewport 
    406     camera->setViewport(0,0,1024,512); 
     220    camera->setViewport(0,0,tex_width,tex_height); 
    407221     
    408222    camera->getOrCreateStateSet()->setAttribute(camera->getViewport()); 
     
    411225    camera->setRenderOrder(osg::CameraNode::PRE_RENDER); 
    412226     
    413     camera->attach(osg::CameraNode::COLOR_BUFFER,texture); 
     227    // tell the camera to use OpenGL frame buffer object where supported. 
     228    camera->setRenderTargetImplmentation(osg::CameraNode::FRAME_BUFFER_OBJECT); 
     229     
     230    // attach the texture and use it as the color buffer. 
     231    camera->attach(osg::CameraNode::COLOR_BUFFER, texture); 
    414232 
    415233    // add subgraph to render 
     
    425243 
    426244    return parent; 
    427  
    428 #endif 
    429245} 
    430246