| 77 | | |
| 78 | | void doPreRender(osg::Node& node, osgUtil::CullVisitor& cv); |
| 79 | | |
| 80 | | osg::ref_ptr<osg::Node> _subgraph; |
| 81 | | osg::ref_ptr<osg::Texture2D> _texture; |
| 82 | | osg::ref_ptr<osg::Image> _image; |
| 83 | | osg::ref_ptr<osg::StateSet> _localState; |
| 84 | | |
| 85 | | }; |
| 86 | | |
| 87 | | void MyCullCallback::doPreRender(osg::Node&, osgUtil::CullVisitor& cv) |
| 88 | | { |
| 89 | | const osg::BoundingSphere& bs = _subgraph->getBound(); |
| 90 | | if (!bs.valid()) |
| 91 | | { |
| 92 | | osg::notify(osg::WARN) << "bb invalid"<<_subgraph.get()<<std::endl; |
| 93 | | return; |
| 94 | | } |
| 95 | | |
| 96 | | |
| 97 | | // create the render to texture stage. |
| 98 | | osg::ref_ptr<osgUtil::RenderToTextureStage> rtts = new osgUtil::RenderToTextureStage; |
| 99 | | |
| 100 | | // set up lighting. |
| 101 | | // currently ignore lights in the scene graph itself.. |
| 102 | | // will do later. |
| 103 | | osgUtil::RenderStage* previous_stage = cv.getCurrentRenderBin()->getStage(); |
| 104 | | |
| 105 | | // set up the background color and clear mask. |
| 106 | | rtts->setClearColor(osg::Vec4(0.1f,0.1f,0.3f,1.0f)); |
| 107 | | rtts->setClearMask(previous_stage->getClearMask()); |
| 108 | | |
| 109 | | // set up to charge the same RenderStageLighting is the parent previous stage. |
| 110 | | rtts->setRenderStageLighting(previous_stage->getRenderStageLighting()); |
| 111 | | |
| 112 | | |
| 113 | | // record the render bin, to be restored after creation |
| 114 | | // of the render to text |
| 115 | | osgUtil::RenderBin* previousRenderBin = cv.getCurrentRenderBin(); |
| 116 | | |
| 117 | | // set the current renderbin to be the newly created stage. |
| 118 | | cv.setCurrentRenderBin(rtts.get()); |
| 119 | | |
| 120 | | |
| 121 | | float znear = 1.0f*bs.radius(); |
| 122 | | float zfar = 3.0f*bs.radius(); |
| 123 | | |
| 124 | | // 2:1 aspect ratio as per flag geomtry below. |
| 125 | | float top = 0.25f*znear; |
| 126 | | float right = 0.5f*znear; |
| 127 | | |
| 128 | | znear *= 0.9f; |
| 129 | | zfar *= 1.1f; |
| 130 | | |
| 131 | | // set up projection. |
| 132 | | osg::RefMatrix* projection = new osg::RefMatrix; |
| 133 | | projection->makeFrustum(-right,right,-top,top,znear,zfar); |
| 134 | | |
| 135 | | cv.pushProjectionMatrix(projection); |
| 136 | | |
| 137 | | osg::RefMatrix* matrix = new osg::RefMatrix; |
| 138 | | matrix->makeLookAt(bs.center()+osg::Vec3(0.0f,2.0f,0.0f)*bs.radius(),bs.center(),osg::Vec3(0.0f,0.0f,1.0f)); |
| 139 | | |
| 140 | | cv.pushModelViewMatrix(matrix); |
| 141 | | |
| 142 | | cv.pushStateSet(_localState.get()); |
| 143 | | |
| 144 | | { |
| 145 | | |
| 146 | | // traverse the subgraph |
| 147 | | _subgraph->accept(cv); |
| 148 | | |
| 149 | | } |
| 150 | | |
| 151 | | cv.popStateSet(); |
| 152 | | |
| 153 | | // restore the previous model view matrix. |
| 154 | | cv.popModelViewMatrix(); |
| 155 | | |
| 156 | | // restore the previous model view matrix. |
| 157 | | cv.popProjectionMatrix(); |
| 158 | | |
| 159 | | // restore the previous renderbin. |
| 160 | | cv.setCurrentRenderBin(previousRenderBin); |
| 161 | | |
| 162 | | if (rtts->getRenderGraphList().size()==0 && rtts->getRenderBinList().size()==0) |
| 163 | | { |
| 164 | | // getting to this point means that all the subgraph has been |
| 165 | | // culled by small feature culling or is beyond LOD ranges. |
| 166 | | return; |
| 167 | | } |
| 168 | | |
| 169 | | |
| 170 | | |
| 171 | | int height = 256; |
| 172 | | int width = 512; |
| 173 | | |
| 174 | | |
| 175 | | const osg::Viewport& viewport = *cv.getViewport(); |
| 176 | | |
| 177 | | // offset the impostor viewport from the center of the main window |
| 178 | | // viewport as often the edges of the viewport might be obscured by |
| 179 | | // other windows, which can cause image/reading writing problems. |
| 180 | | int center_x = viewport.x()+viewport.width()/2; |
| 181 | | int center_y = viewport.y()+viewport.height()/2; |
| 182 | | |
| 183 | | osg::Viewport* new_viewport = new osg::Viewport; |
| 184 | | new_viewport->setViewport(center_x-width/2,center_y-height/2,width,height); |
| 185 | | rtts->setViewport(new_viewport); |
| 186 | | |
| 187 | | _localState->setAttribute(new_viewport); |
| 188 | | |
| 189 | | // and the render to texture stage to the current stages |
| 190 | | // dependancy list. |
| 191 | | cv.getCurrentRenderBin()->getStage()->addToDependencyList(rtts.get()); |
| 192 | | |
| 193 | | // if one exist attach texture to the RenderToTextureStage. |
| 194 | | if (_texture.valid()) rtts->setTexture(_texture.get()); |
| 195 | | |
| 196 | | // if one exist attach image to the RenderToTextureStage. |
| 197 | | if (_image.valid()) rtts->setImage(_image.get()); |
| 198 | | |
| 199 | | } |
| | 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 |
| | 372 | |
| | 373 | #else |
| | 374 | |
| | 375 | |
| | 376 | osg::CameraNode* camera = new osg::CameraNode; |
| | 377 | |
| | 378 | // set up the background color and clear mask. |
| | 379 | camera->setClearColor(osg::Vec4(0.1f,0.1f,0.3f,1.0f)); |
| | 380 | camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
| | 381 | |
| | 382 | const osg::BoundingSphere& bs = subgraph->getBound(); |
| | 383 | if (!bs.valid()) |
| | 384 | { |
| | 385 | return subgraph; |
| | 386 | } |
| | 387 | |
| | 388 | float znear = 1.0f*bs.radius(); |
| | 389 | float zfar = 3.0f*bs.radius(); |
| | 390 | |
| | 391 | // 2:1 aspect ratio as per flag geomtry below. |
| | 392 | float proj_top = 0.25f*znear; |
| | 393 | float proj_right = 0.5f*znear; |
| | 394 | |
| | 395 | znear *= 0.9f; |
| | 396 | zfar *= 1.1f; |
| | 397 | |
| | 398 | // set up projection. |
| | 399 | camera->setProjectionMatrixAsFrustum(-proj_right,proj_right,-proj_top,proj_top,znear,zfar); |
| | 400 | |
| | 401 | // set view |
| | 402 | camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); |
| | 403 | camera->setViewMatrixAsLookAt(bs.center()+osg::Vec3(0.0f,2.0f,0.0f)*bs.radius(),bs.center(),osg::Vec3(0.0f,0.0f,1.0f)); |
| | 404 | |
| | 405 | // set viewport |
| | 406 | camera->setViewport(0,0,1024,512); |
| | 407 | |
| | 408 | camera->getOrCreateStateSet()->setAttribute(camera->getViewport()); |
| | 409 | |
| | 410 | // set the camera to render before the main camera. |
| | 411 | camera->setRenderOrder(osg::CameraNode::PRE_RENDER); |
| | 412 | |
| | 413 | camera->attach(osg::CameraNode::COLOR_BUFFER,texture); |
| | 414 | |
| | 415 | // add subgraph to render |
| | 416 | camera->addChild(subgraph); |
| | 417 | |
| | 418 | |
| | 419 | // create a group to contain the flag and the pre rendering camera. |
| | 420 | osg::Group* parent = new osg::Group; |
| | 421 | |
| | 422 | parent->addChild(camera); |
| | 423 | parent->addChild(geode); |
| | 424 | |
| | 425 | |
| | 426 | return parent; |
| | 427 | |
| | 428 | #endif |