| 28 | | #if 1 |
| | 32 | struct FrameOperation : public osg::GraphicsThread::Operation |
| | 33 | { |
| | 34 | FrameOperation(osg::CameraNode* camera, osg::FrameStamp* frameStamp): |
| | 35 | _camera(camera), |
| | 36 | _frameStamp(frameStamp) |
| | 37 | { |
| | 38 | _sceneView = new osgUtil::SceneView; |
| | 39 | _sceneView->setDefaults(); |
| | 40 | _sceneView->setFrameStamp(_frameStamp.get()); |
| | 41 | |
| | 42 | if (camera->getNumChildren()>=1) |
| | 43 | { |
| | 44 | _sceneView->setSceneData(camera->getChild(0)); |
| | 45 | } |
| | 46 | } |
| | 47 | |
| | 48 | virtual void operator () (osg::GraphicsContext* context) |
| | 49 | { |
| | 50 | std::cout<<"FrameOperation draw begin"<<context<<std::endl; |
| | 51 | |
| | 52 | _sceneView->setState(context->getState()); |
| | 53 | _sceneView->setProjectionMatrix(_camera->getProjectionMatrix()); |
| | 54 | _sceneView->setViewMatrix(_camera->getViewMatrix()); |
| | 55 | _sceneView->setViewport(_camera->getViewport()); |
| | 56 | |
| | 57 | _sceneView->cull(); |
| | 58 | _sceneView->draw(); |
| | 59 | |
| | 60 | std::cout<<"FrameOperation draw end"<<context<<std::endl; |
| | 61 | } |
| | 62 | |
| | 63 | osg::ref_ptr<osg::CameraNode> _camera; |
| | 64 | osg::ref_ptr<osg::FrameStamp> _frameStamp; |
| | 65 | osg::ref_ptr<osgUtil::SceneView> _sceneView; |
| | 66 | }; |
| 45 | | |
| 46 | | osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; |
| 47 | | traits->_windowName = "osgcamera"; |
| 48 | | traits->_x = 100; |
| 49 | | traits->_y = 100; |
| 50 | | traits->_width = 800; |
| 51 | | traits->_height = 800; |
| 52 | | traits->_windowDecoration = true; |
| 53 | | traits->_doubleBuffer = true; |
| 54 | | |
| 55 | | osg::ref_ptr<osg::GraphicsContext> gfxc = osg::GraphicsContext::createGraphicsContext(traits.get()); |
| 56 | | |
| 57 | | if (!gfxc) |
| 58 | | { |
| 59 | | std::cout<<"Unable to create window."<<std::endl; |
| 60 | | return 1; |
| 61 | | } |
| 62 | | |
| 63 | | // realise the window |
| 64 | | gfxc->realize(); |
| 65 | | |
| 66 | | // create the view of the scene. |
| 67 | | osg::ref_ptr<osg::CameraNode> camera = new osg::CameraNode; |
| 68 | | camera->setRenderOrder(osg::CameraNode::NESTED_RENDER); |
| 69 | | camera->setClearColor(osg::Vec4(1.0f,1.0f,0.0f,1.0f)); |
| 70 | | camera->setCullingActive(false); |
| 71 | | |
| 72 | | camera->addChild(loadedModel.get()); |
| 73 | | |
| 74 | | |
| 75 | | |
| 76 | | // initialize the view to look at the center of the scene graph |
| 77 | | const osg::BoundingSphere& bs = loadedModel->getBound(); |
| 78 | | osg::Matrix viewMatrix; |
| 79 | | viewMatrix.makeLookAt(bs.center()-osg::Vec3(0.0,2.0f*bs.radius(),0.0),bs.center(),osg::Vec3(0.0f,0.0f,1.0f)); |
| 80 | | |
| | 83 | |
| | 84 | |
| | 85 | // set up the frame stamp for current frame to record the current time and frame number so that animtion code can advance correctly |
| | 86 | osg::ref_ptr<osg::FrameStamp> frameStamp = new osg::FrameStamp; |
| | 87 | |
| | 88 | unsigned int frameNum = 0; |
| | 89 | |
| | 90 | osgUtil::UpdateVisitor updateVisitor; |
| | 91 | updateVisitor.setFrameStamp(frameStamp.get()); |
| | 92 | |
| | 93 | |
| | 94 | unsigned int numberCameras = 3; |
| | 95 | unsigned int xpos = 0; |
| | 96 | unsigned int ypos = 400; |
| | 97 | unsigned int width = 400; |
| | 98 | unsigned int height = 400; |
| | 99 | |
| | 100 | typedef std::map< osg::ref_ptr<osg::CameraNode>, osg::ref_ptr<FrameOperation> > CameraMap; |
| | 101 | typedef std::set< osg::GraphicsContext* > GraphicsContextSet; |
| | 102 | |
| | 103 | CameraMap cameraMap; |
| | 104 | GraphicsContextSet graphicsContextSet; |
| | 105 | |
| | 106 | for(unsigned int i=0; i< numberCameras; ++i) |
| | 107 | { |
| | 108 | osg::ref_ptr<osg::CameraNode> camera = new osg::CameraNode; |
| | 109 | camera->addChild(loadedModel.get()); |
| | 110 | |
| | 111 | osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; |
| | 112 | traits->_windowName = "osgcamera"; |
| | 113 | traits->_x = xpos; |
| | 114 | traits->_y = ypos; |
| | 115 | traits->_width = width; |
| | 116 | traits->_height = height; |
| | 117 | traits->_windowDecoration = true; |
| | 118 | traits->_doubleBuffer = true; |
| | 119 | |
| | 120 | xpos += width; |
| | 121 | |
| | 122 | osg::ref_ptr<osg::GraphicsContext> gfxc = osg::GraphicsContext::createGraphicsContext(traits.get()); |
| | 123 | |
| | 124 | if (!gfxc) |
| | 125 | { |
| | 126 | std::cout<<"Unable to create window."<<std::endl; |
| | 127 | return 1; |
| | 128 | } |
| | 129 | |
| | 130 | // realise the window |
| | 131 | gfxc->realize(); |
| | 132 | |
| | 133 | camera->setGraphicsContext(gfxc.get()); |
| | 134 | |
| | 135 | // initialize the view to look at the center of the scene graph |
| | 136 | const osg::BoundingSphere& bs = loadedModel->getBound(); |
| | 137 | osg::Matrix viewMatrix; |
| | 138 | viewMatrix.makeLookAt(bs.center()-osg::Vec3(0.0,2.0f*bs.radius(),0.0),bs.center(),osg::Vec3(0.0f,0.0f,1.0f)); |
| | 139 | |
| | 140 | camera->setViewport(0,0,traits->_width,traits->_height); |
| | 141 | camera->setProjectionMatrixAsPerspective(50.0f,1.4f,1.0f,10000.0f); |
| | 142 | camera->setViewMatrix(viewMatrix); |
| | 143 | |
| | 144 | |
| | 145 | gfxc->createGraphicsThread(); |
| | 146 | |
| | 147 | cameraMap[camera] = new FrameOperation(camera.get(), frameStamp.get()); |
| | 148 | } |
| | 149 | |
| | 150 | |
| | 151 | CameraMap::iterator citr; |
| | 152 | for(citr = cameraMap.begin(); |
| | 153 | citr != cameraMap.end(); |
| | 154 | ++citr) |
| | 155 | { |
| | 156 | graphicsContextSet.insert(const_cast<osg::GraphicsContext*>(citr->first->getGraphicsContext())); |
| | 157 | } |
| | 158 | |
| | 159 | osg::ref_ptr<osg::SwapBuffersOperation> swapOp = new osg::SwapBuffersOperation(); |
| | 160 | osg::ref_ptr<osg::BarrierOperation> frameEndBarrierOp = new osg::BarrierOperation(graphicsContextSet.size()+1, osg::BarrierOperation::NO_OPERATION); |
| | 161 | osg::ref_ptr<osg::BarrierOperation> preSwapBarrierOp = new osg::BarrierOperation(graphicsContextSet.size(), osg::BarrierOperation::GL_FLUSH); |
| | 162 | |
| | 163 | std::cout<<"nubmer of gfx."<<graphicsContextSet.size()<<std::endl; |
| | 164 | |
| | 165 | |
| | 166 | GraphicsContextSet::iterator gitr; |
| | 167 | for(gitr = graphicsContextSet.begin(); |
| | 168 | gitr != graphicsContextSet.end(); |
| | 169 | ++gitr) |
| | 170 | { |
| | 171 | std::cout<<"Issue swap."<<std::endl; |
| | 172 | osg::GraphicsContext* context = *gitr; |
| | 173 | context->getGraphicsThread()->add(swapOp.get(), true); |
| | 174 | } |
| | 175 | |
| 106 | | updateVisitor->reset(); |
| 107 | | |
| 108 | | // pass frame stamp to the SceneView so that the update, cull and draw traversals all use the same FrameStamp |
| 109 | | updateVisitor->setFrameStamp(frameStamp.get()); |
| 110 | | updateVisitor->setTraversalNumber(frameStamp->getFrameNumber()); |
| 111 | | |
| 112 | | |
| 113 | | // set the view |
| 114 | | camera->setViewMatrix(viewMatrix); |
| 115 | | |
| 116 | | // do the update traversal the scene graph - such as updating animations |
| 117 | | camera->accept(*updateVisitor); |
| 118 | | |
| 119 | | cullVisitor->reset(); |
| 120 | | cullVisitor->setFrameStamp(frameStamp.get()); |
| 121 | | cullVisitor->setTraversalNumber(frameStamp->getFrameNumber()); |
| 122 | | |
| 123 | | |
| 124 | | // update the viewport dimensions, incase the window has been resized. |
| 125 | | camera->setViewport(0,0,traits->_width,traits->_height); |
| 126 | | |
| 127 | | renderGraph->clean(); |
| 128 | | renderStage->reset(); |
| 129 | | renderStage->setViewport(camera->getViewport()); |
| 130 | | |
| 131 | | osg::ref_ptr<osg::RefMatrix> proj = new osg::RefMatrix(camera->getProjectionMatrix()); |
| 132 | | osg::ref_ptr<osg::RefMatrix> mv = new osg::RefMatrix(camera->getViewMatrix()); |
| 133 | | |
| 134 | | cullVisitor->pushViewport(camera->getViewport()); |
| 135 | | cullVisitor->pushProjectionMatrix(proj.get()); |
| 136 | | cullVisitor->pushModelViewMatrix(mv.get()); |
| 137 | | |
| 138 | | // do the cull traversal, collect all objects in the view frustum into a sorted set of rendering bins |
| 139 | | //camera->accept(*cullVisitor); |
| 140 | | loadedModel->accept(*cullVisitor); |
| 141 | | |
| 142 | | cullVisitor->popModelViewMatrix(); |
| 143 | | cullVisitor->popProjectionMatrix(); |
| 144 | | cullVisitor->popViewport(); |
| 145 | | |
| 146 | | renderStage->sort(); |
| 147 | | |
| 148 | | // prune out any empty RenderGraph children. |
| 149 | | // note, this would be not required if the rendergraph had been |
| 150 | | // reset at the start of each frame (see top of this method) but |
| 151 | | // a clean has been used instead to try to minimize the amount of |
| 152 | | // allocation and deleteing of the RenderGraph nodes. |
| 153 | | renderGraph->prune(); |
| 154 | | |
| 155 | | renderStage->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); |
| 156 | | |
| 157 | | gfxc->getState()->setInitialViewMatrix(mv.get()); |
| 158 | | |
| 159 | | std::cout<<"before"<<std::endl; |
| 160 | | |
| 161 | | // draw traversal |
| 162 | | osgUtil::RenderLeaf* previous = NULL; |
| 163 | | renderStage->draw(*(gfxc->getState()), previous); |
| 164 | | |
| 165 | | // Swap Buffers |
| 166 | | gfxc->swapBuffers(); |
| 167 | | |
| 168 | | std::cout<<"swap"<<std::endl; |
| | 189 | std::cout<<"Frame rate "<<(double)frameNum / frameStamp->getReferenceTime()<<std::endl; |
| | 190 | |
| | 191 | |
| | 192 | loadedModel->accept(updateVisitor); |
| | 193 | |
| | 194 | // issue the frame for each camera. |
| | 195 | for(citr = cameraMap.begin(); |
| | 196 | citr != cameraMap.end(); |
| | 197 | ++citr) |
| | 198 | { |
| | 199 | osg::CameraNode* camera = const_cast<osg::CameraNode*>(citr->first.get()); |
| | 200 | camera->getGraphicsContext()->getGraphicsThread()->add( citr->second.get(), false); |
| | 201 | } |
| | 202 | |
| | 203 | for(gitr = graphicsContextSet.begin(); |
| | 204 | gitr != graphicsContextSet.end(); |
| | 205 | ++gitr) |
| | 206 | { |
| | 207 | osg::GraphicsContext* context = *gitr; |
| | 208 | context->getGraphicsThread()->add(frameEndBarrierOp.get(), false); |
| | 209 | context->getGraphicsThread()->add(preSwapBarrierOp.get(), false); |
| | 210 | } |
| | 211 | |
| | 212 | std::cout<<"Join frameEndBarrierOp block "<<std::endl; |
| | 213 | osg::Timer_t before_tick = osg::Timer::instance()->tick(); |
| | 214 | frameEndBarrierOp->block(); |
| | 215 | osg::Timer_t after_tick = osg::Timer::instance()->tick(); |
| | 216 | std::cout<<"Leave frameEndBarrierOp block "<<osg::Timer::instance()->delta_s(before_tick,after_tick)<<std::endl; |
| | 217 | |
| | 218 | std::cout<<"Join preSwapBarrierOp block "<<std::endl; |
| | 219 | before_tick = osg::Timer::instance()->tick(); |
| | 220 | // preSwapBarrierOp->block(); |
| | 221 | after_tick = osg::Timer::instance()->tick(); |
| | 222 | std::cout<<"Leave preSwapBarrierOp block "<<osg::Timer::instance()->delta_s(before_tick,after_tick)<<std::endl; |
| | 223 | |
| | 224 | for(gitr = graphicsContextSet.begin(); |
| | 225 | gitr != graphicsContextSet.end(); |
| | 226 | ++gitr) |
| | 227 | { |
| | 228 | osg::GraphicsContext* context = *gitr; |
| | 229 | context->getGraphicsThread()->add(swapOp.get(), false); |
| | 230 | } |
| | 231 | |
| | 232 | // check if any of the windows are closed |
| | 233 | for(gitr = graphicsContextSet.begin(); |
| | 234 | gitr != graphicsContextSet.end(); |
| | 235 | ++gitr) |
| | 236 | { |
| | 237 | osg::GraphicsContext* context = *gitr; |
| | 238 | if (!context->isRealized()) done = true; |
| | 239 | } |
| | 240 | |
| 173 | | |
| 174 | | #else |
| 175 | | |
| 176 | | int main( int argc, char **argv ) |
| 177 | | { |
| 178 | | if (argc<2) |
| 179 | | { |
| 180 | | std::cout << argv[0] <<": requires filename argument." << std::endl; |
| 181 | | return 1; |
| 182 | | } |
| 183 | | |
| 184 | | // load the scene. |
| 185 | | osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(argv[1]); |
| 186 | | if (!loadedModel) |
| 187 | | { |
| 188 | | std::cout << argv[0] <<": No data loaded." << std::endl; |
| 189 | | return 1; |
| 190 | | } |
| 191 | | |
| 192 | | osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; |
| 193 | | traits->_windowName = "osgcamera"; |
| 194 | | traits->_x = 100; |
| 195 | | traits->_y = 100; |
| 196 | | traits->_width = 800; |
| 197 | | traits->_height = 800; |
| 198 | | traits->_windowDecoration = true; |
| 199 | | traits->_doubleBuffer = true; |
| 200 | | |
| 201 | | osg::ref_ptr<osg::GraphicsContext> gfxc = osg::GraphicsContext::createGraphicsContext(traits.get()); |
| 202 | | |
| 203 | | if (!gfxc) |
| 204 | | { |
| 205 | | std::cout<<"Unable to create window."<<std::endl; |
| 206 | | return 1; |
| 207 | | } |
| 208 | | |
| 209 | | // realise the window |
| 210 | | gfxc->realize(); |
| 211 | | |
| 212 | | // create the view of the scene. |
| 213 | | osg::ref_ptr<osgUtil::SceneView> sceneView = new osgUtil::SceneView; |
| 214 | | sceneView->setDefaults(); |
| 215 | | sceneView->setSceneData(loadedModel.get()); |
| 216 | | |
| 217 | | // initialize the view to look at the center of the scene graph |
| 218 | | const osg::BoundingSphere& bs = loadedModel->getBound(); |
| 219 | | osg::Matrix viewMatrix; |
| 220 | | viewMatrix.makeLookAt(bs.center()-osg::Vec3(0.0,2.0f*bs.radius(),0.0),bs.center(),osg::Vec3(0.0f,0.0f,1.0f)); |
| 221 | | |
| 222 | | // record the timer tick at the start of rendering. |
| 223 | | osg::Timer_t start_tick = osg::Timer::instance()->tick(); |
| 224 | | |
| 225 | | unsigned int frameNum = 0; |
| 226 | | |
| 227 | | // make the graphics context current |
| 228 | | gfxc->makeCurrent(); |
| 229 | | |
| 230 | | // main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.) |
| 231 | | while( gfxc->isRealized() ) |
| 232 | | { |
| 233 | | // set up the frame stamp for current frame to record the current time and frame number so that animtion code can advance correctly |
| 234 | | osg::ref_ptr<osg::FrameStamp> frameStamp = new osg::FrameStamp; |
| 235 | | frameStamp->setReferenceTime(osg::Timer::instance()->delta_s(start_tick,osg::Timer::instance()->tick())); |
| 236 | | frameStamp->setFrameNumber(frameNum++); |
| 237 | | |
| 238 | | // pass frame stamp to the SceneView so that the update, cull and draw traversals all use the same FrameStamp |
| 239 | | sceneView->setFrameStamp(frameStamp.get()); |
| 240 | | |
| 241 | | // update the viewport dimensions, incase the window has been resized. |
| 242 | | sceneView->setViewport(0,0,traits->_width,traits->_height); |
| 243 | | |
| 244 | | // set the view |
| 245 | | sceneView->setViewMatrix(viewMatrix); |
| 246 | | |
| 247 | | // do the update traversal the scene graph - such as updating animations |
| 248 | | sceneView->update(); |
| 249 | | |
| 250 | | // do the cull traversal, collect all objects in the view frustum into a sorted set of rendering bins |
| 251 | | sceneView->cull(); |
| 252 | | |
| 253 | | // draw the rendering bins. |
| 254 | | sceneView->draw(); |
| 255 | | |
| 256 | | // Swap Buffers |
| 257 | | gfxc->swapBuffers(); |
| 258 | | } |
| 259 | | |
| 260 | | return 0; |
| 261 | | } |
| 262 | | |
| 263 | | #endif |