void ViewportManager::LoadPresetCamera(int index) { dtDAL::Map* map = EditorData::GetInstance().getCurrentMap(); if (map) { dtDAL::Map::PresetCameraData data = map->GetPresetCameraData(index); if (data.isValid) { Viewport* viewport = mViewportList["Perspective View"]; if (viewport) { StageCamera* cam = viewport->getCamera(); if (cam) { cam->setPosition(data.persPosition); cam->resetRotation(); cam->rotate(data.persRotation); } } viewport = mViewportList["Top View (XY)"]; if (viewport) { StageCamera* cam = viewport->getCamera(); if (cam) { cam->setPosition(data.topPosition); cam->setZoom(data.topZoom); } } viewport = mViewportList["Side View (YZ)"]; if (viewport) { StageCamera* cam = viewport->getCamera(); if (cam) { cam->setPosition(data.sidePosition); cam->setZoom(data.sideZoom); } } viewport = mViewportList["Front View (XZ)"]; if (viewport) { StageCamera* cam = viewport->getCamera(); if (cam) { cam->setPosition(data.frontPosition); cam->setZoom(data.frontZoom); } } refreshAllViewports(); } } }
void ViewportManager::SavePresetCamera(int index) { dtDAL::Map::PresetCameraData data; data.isValid = true; Viewport* viewport = mViewportList["Perspective View"]; if (viewport) { StageCamera* cam = viewport->getCamera(); if (cam) { data.persPosition = cam->getPosition(); data.persRotation = cam->getOrientation(); } } viewport = mViewportList["Top View (XY)"]; if (viewport) { StageCamera* cam = viewport->getCamera(); if (cam) { data.topPosition = cam->getPosition(); data.topZoom = cam->getZoom(); } } viewport = mViewportList["Side View (YZ)"]; if (viewport) { StageCamera* cam = viewport->getCamera(); if (cam) { data.sidePosition = cam->getPosition(); data.sideZoom = cam->getZoom(); } } viewport = mViewportList["Front View (XZ)"]; if (viewport) { StageCamera* cam = viewport->getCamera(); if (cam) { data.frontPosition = cam->getPosition(); data.frontZoom = cam->getZoom(); } } dtDAL::Map* map = EditorData::GetInstance().getCurrentMap(); if (map) { map->SetPresetCameraData(index, data); EditorData::GetInstance().getCurrentMap()->SetModified(true); EditorEvents::GetInstance().emitProjectChanged(); } }
//----------------------------------------------------------------------- bool BillboardChain::preRender(SceneManager* sm, RenderSystem* rsys) { // Retrieve the current viewport from the scene manager. // The viewport is only valid during a viewport update. Viewport *currentViewport = sm->getCurrentViewport(); if( !currentViewport ) return false; updateVertexBuffer(currentViewport->getCamera()); return true; }
//----------------------------------------------------------------------- void RenderTarget::_notifyCameraRemoved(const Camera* cam) { ViewportList::iterator i, iend; iend = mViewportList.end(); for (i = mViewportList.begin(); i != iend; ++i) { Viewport* v = i->second; if (v->getCamera() == cam) { // disable camera link v->setCamera(0); } } }
// // setup of the image generation stage // static void createAcquisitionStage() { size_t num_ports = win->getMFPort()->size(); if (num_ports == 0) return; UInt32 width = win->getWidth(); UInt32 height = win->getHeight(); Real32 a = Real32(width) / Real32(height); width = UInt32(a*height); Viewport* vp = staticVp; Node* internalRoot = rootNode(mgr->getRoot()); // // Setup the FBO // spSimpleFBO.reset(new SimpleFBO(width, height, true, true, true, false)); //spSimpleFBO->fbo()->setPostProcessOnDeactivate(true); //spSimpleFBO->colorBuffer(0)->setReadBack(true); // // We would like to render the scene but won't detach it from its parent. // The VisitSubTree allows just that. // VisitSubTreeUnrecPtr visitor = VisitSubTree::create(); visitor->setSubTreeRoot(internalRoot); NodeUnrecPtr visit_node = makeNodeFor(visitor); // // The stage object does provide a render target for the frame buffer attachment. // SimpleStage has a camera, a background and the left, right, top, bottom // fields to let you restrict rendering to a sub-rectangle of your FBO, i.e. // they give you a viewport. // SimpleStageUnrecPtr stage = SimpleStage::create(); stage->setRenderTarget(spSimpleFBO->fbo()); stage->setCamera (vp->getCamera()); stage->setBackground (vp->getBackground()); // // Give the stage core a place to live // NodeUnrecPtr stage_node = makeNodeFor(stage); stage_node->addChild(visit_node); // // root // | // +- SimpleStage // | // +- VisitSubTree -> ApplicationScene // NodeUnrecPtr root = makeCoredNode<Group>(); root->addChild(stage_node); // // Give the root node a place to live, i.e. create a passive // viewport and add it to the window. // ViewportUnrecPtr stage_viewport = PassiveViewport::create(); stage_viewport->setRoot (stage_node); stage_viewport->setBackground(vp->getBackground()); stage_viewport->setCamera (vp->getCamera()); win->addPort(stage_viewport); mgr->update(); win->renderNoFinish(mgr->getRenderAction()); win->frameExit(); win->deactivate (); //ImageUnrecPtr col_image = Image::create(); //col_image->set(Image::OSG_RGBA_PF, width, height); //TextureObjChunk* texObj = spSimpleFBO->colorTexObj(0); //texObj->getImage()->subImage(0, 0, 0, width, height, 1, col_image); //col_image->write("d:/my_Test_opensg.png"); win->subPortByObj(stage_viewport); }
void MultiDisplayWindow::serverRender(Window *window, UInt32 id, RenderActionBase *action) { TileCameraDecoratorUnrecPtr deco; ViewportUnrecPtr serverPort; Viewport * clientPort; StereoBufferViewport *clientStereoPort; UInt32 sv,cv; Int32 l,r,t,b; Int32 cleft,cright,ctop,cbottom; if(!getHServers()) { setHServers(getMFServers()->size()); } if(!getVServers()) { setVServers(1); } UInt32 row =id/getHServers(); UInt32 column=id%getHServers(); // calculate width and height from local width and height UInt32 width = window->getWidth() ; UInt32 height = window->getHeight(); if(getWidth()==0) { setWidth( width*getHServers() ); } if(getHeight()==0) { setHeight( height*getVServers() ); } Int32 left = column * width - column * getXOverlap(); Int32 bottom = row * height - row * getYOverlap(); Int32 right = left + width - 1; Int32 top = bottom + height - 1; Real64 scaleCWidth = ((width - getXOverlap()) * (getHServers() - 1) + width) / float(getWidth()); Real64 scaleCHeight = ((height - getYOverlap())* (getVServers() - 1) + height)/ float(getHeight()); // duplicate viewports for(cv=0,sv=0; cv<getMFPort()->size(); cv++) { clientPort = getPort(cv); clientStereoPort = dynamic_cast<StereoBufferViewport *>(clientPort); cleft = Int32(clientPort->getPixelLeft() * scaleCWidth) ; cbottom = Int32(clientPort->getPixelBottom() * scaleCHeight) ; cright = Int32((clientPort->getPixelRight()+1) * scaleCWidth) -1; ctop = Int32((clientPort->getPixelTop()+1) * scaleCHeight)-1; if(cright < left || cleft > right || ctop < bottom || cbottom > top ) { // invisible on this server screen continue; } // calculate overlapping viewport l = osgMax(cleft ,left ) - left; b = osgMax(cbottom,bottom) - bottom; r = osgMin(cright ,right ) - left; t = osgMin(ctop ,top ) - bottom; if(window->getMFPort()->size() <= sv) { serverPort = dynamic_pointer_cast<Viewport>( clientPort->shallowCopy()); deco = TileCameraDecorator::create(); window->addPort(serverPort); serverPort->setCamera(deco); } else { serverPort = window->getPort(sv); deco = dynamic_cast<TileCameraDecorator *>( serverPort->getCamera()); if(window->getPort(sv)->getType() != clientPort->getType()) { // there is a viewport with the wrong type serverPort = dynamic_pointer_cast<Viewport>(clientPort->shallowCopy()); window->replacePort(sv, serverPort);//[sv] = serverPort; serverPort->setCamera(deco); } else { deco = dynamic_cast<TileCameraDecorator *>( serverPort->getCamera()); } } // update changed viewport fields updateViewport(serverPort, clientPort); // set viewport size serverPort->setSize(Real32(l),Real32(b),Real32(r),Real32(t)); // use pixel even if pixel = 1 if(serverPort->getLeft() == 1.0) serverPort->setLeft(1.0001f); if(serverPort->getRight() == 1.0) serverPort->setRight(1.0001f); if(serverPort->getTop() == 1.0) serverPort->setTop(1.0001f); if(serverPort->getBottom() == 1.0) serverPort->setBottom(1.0001f); // calculate tile parameters deco->setFullWidth ( cright-cleft ); deco->setFullHeight( ctop-cbottom ); deco->setSize( ( l+left-cleft ) / float( cright-cleft ), ( b+bottom-cbottom ) / float( ctop-cbottom ), ( r+left-cleft ) / float( cright-cleft ), ( t+bottom-cbottom ) / float( ctop-cbottom ) ); deco->setDecoratee( clientPort->getCamera() ); sv++; } // remove unused ports while(window->getMFPort()->size()>sv) { window->subPort(sv); } Inherited::serverRender(window,id,action); }
// // FBO solution // static void writeHiResScreenShotFBO(const char* name, UInt32 width, UInt32 height) { size_t num_ports = win->getMFPort()->size(); if (num_ports == 0) return; // // calc image dimensions // UInt32 winWidth = win->getWidth(); UInt32 winHeight = win->getHeight(); if (width < winWidth ) width = winWidth; if (height < winHeight) height = winHeight; Real32 a = Real32(winWidth) / Real32(winHeight); width = UInt32(a*height); // // output stream for writing the final image // std::ofstream stream(name, std::ios::binary); if (stream.good() == false) return; // // Setup the FBO // FrameBufferObjectUnrecPtr fbo = FrameBufferObject::create(); // // We use two render buffers. One for the color buffer and one for the depth and // stencil buffer. This example does not take credit of the stencil buffer. There- // fore a depth buffer would suffice. However, the use of the combined depth and // stencil buffer is useful in other contextes and hence used. // RenderBufferUnrecPtr colBuf = RenderBuffer::create(); RenderBufferUnrecPtr dsBuf = RenderBuffer::create(); // // As we would like to read back the FBO color buffer, we must provide a fitting // image. // ImageUnrecPtr buffer_image = Image::create(); buffer_image->set(Image::OSG_RGBA_PF, winWidth, winHeight); colBuf->setImage(buffer_image); // // We must setup the internal image formats of the two render buffers accordingly. // colBuf->setInternalFormat(GL_RGBA); dsBuf ->setInternalFormat(GL_DEPTH24_STENCIL8_EXT); // // we must inform the FBO about the actual used color render buffers. // fbo->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT); // // The FBO takes responsibility of the render buffers. Notice, that the shared // depth/stencil buffer is provided twice. As the depth render buffer and as the // stencil render buffer. // fbo->setColorAttachment (colBuf, 0); fbo->setDepthAttachment (dsBuf); fbo->setStencilAttachment(dsBuf); // // Also the FBO must be sized correctly. // fbo->setWidth (winWidth ); fbo->setHeight(winHeight); // // In order to read the color buffer back next two statements are necessary. // fbo->setPostProcessOnDeactivate(true); fbo->getColorAttachments(0)->setReadBack(true); // // We tile the final image and render each tile with the screen resolution // into the FBO. The more tiles we use the bigger the resolution of the // final image gets with respect to a provided measure of length. // typedef boost::tuple<TileCameraDecoratorUnrecPtr, bool, SimpleStageUnrecPtr, ViewportUnrecPtr> TupleT; std::vector<TupleT> decorators; decorators.resize(num_ports); // // Remember the stage viewports for later cleanup // std::stack<ViewportUnrecPtr> stage_viewports; // // Setup the tile camera decorators for each viewport of the window and // disable the tile property of tileable viewport backgrounds. // for (size_t i = 0; i < num_ports; ++i) { Viewport* vp = win->getPort(i); TileCameraDecoratorUnrecPtr decorator = TileCameraDecorator::create(); decorator->setFullSize (width, height); decorator->setDecoratee(vp->getCamera()); vp->setCamera(decorator); bool bTiled = false; TileableBackground* tbg = dynamic_cast<TileableBackground*>(vp->getBackground()); if (tbg) { bTiled = tbg->getTile(); tbg->setTile(false); } // // The scene manager root node does not provide the illumination of the // scene. This is governed internally by the manager. However, to take // credit of the illumination we scan to the final parent of the scene // graph. // Node* internalRoot = rootNode(mgr->getRoot()); // // We would like to render the scene but won't detach it from its parent. // The VisitSubTree allows just that. // VisitSubTreeUnrecPtr visitor = VisitSubTree::create(); visitor->setSubTreeRoot(internalRoot); NodeUnrecPtr visit_node = makeNodeFor(visitor); // // We clone the camera of the first viewport and do not swap the buffer on later // rendering. This way the image generation process is not noticable in the // window. // CameraUnrecPtr camera = dynamic_pointer_cast<Camera>(vp->getCamera()->shallowCopy()); // // The stage object does provide a render target for the frame buffer attachment. // SimpleStage has a camera, a background and the left, right, top, bottom // fields to let you restrict rendering to a sub-rectangle of your FBO, i.e. // they give you a viewport. // SimpleStageUnrecPtr stage = SimpleStage::create(); stage->setRenderTarget(fbo); stage->setCamera (decorator); stage->setBackground (vp->getBackground()); // // Give the stage core a place to live // NodeUnrecPtr stage_node = makeNodeFor(stage); stage_node->addChild(visit_node); // // root // | // +- SimpleStage // | // +- VisitSubTree -> ApplicationScene // NodeUnrecPtr root = makeCoredNode<Group>(); root->addChild(stage_node); // // Give the root node a place to live, i.e. create a passive // viewport and add it to the window. // ViewportUnrecPtr stage_viewport = PassiveViewport::create(); stage_viewport->setRoot (root); stage_viewport->setBackground(vp->getBackground()); stage_viewport->setCamera (camera); win->addPort(stage_viewport); // // remember the decorator, the background tile prop setting and the stage setup // decorators[i] = boost::make_tuple(decorator, bTiled, stage, stage_viewport); } // // We write the image in simple ppm format. This one starts with a description // header which we output once on first write. // bool write_header = true; // // Calc the max y start position (width). We process the tiles from bottom // up and from left tp right as determined by the image format. // UInt32 yPosLast = 0; for (; yPosLast < height-winHeight; yPosLast += winHeight); // // Process from bottom to top // for (Int32 yPos = yPosLast; yPos >= 0; yPos -= winHeight) { UInt32 ySize = std::min(winHeight, height - yPos); // // Collect the tile images for each row, i.e. we write the // image in row manner to disk. This way the main memory is // only moderately stressed. // std::vector<ImageUnrecPtr> vecColImages; // // Process from left to right // for (UInt32 xPos = 0; xPos < width; xPos += winWidth) { UInt32 xSize = std::min(winWidth, width - xPos); // // The current tile image // ImageUnrecPtr col_image = Image::create(); col_image->set(Image::OSG_RGBA_PF, xSize, ySize); // // Adapt the tile camera decorator boxes to the current tile // for (size_t i = 0; i < num_ports; ++i) { // // this tile does not fill the whole FBO - adjust to only render // to a part of it // decorators[i].get<2>()->setLeft (0.f); decorators[i].get<2>()->setRight (xSize / float(winWidth)); decorators[i].get<2>()->setBottom(0.f); decorators[i].get<2>()->setTop (ySize / float(winHeight)); TileCameraDecorator* decorator = decorators[i].get<0>(); decorator->setSize( xPos / float(width), yPos / float(height), (xPos + xSize) / float(width), (yPos + ySize) / float(height) ); } // // render the tile // mgr->update(); win->renderNoFinish(mgr->getRenderAction()); win->frameExit(); win->deactivate (); // // Copy the image into the tile image stored for later processing // if(fbo) { RenderBuffer* grabber = dynamic_cast<RenderBuffer*>(fbo->getColorAttachments(0)); if(grabber) { grabber->getImage()->subImage(0, 0, 0, xSize, ySize, 1, col_image); } } vecColImages.push_back(col_image); } // // Write the image format header once // if (write_header) { write_header = false; if (!writePNMImagesHeader(vecColImages, width, height, stream)) break; } // // Write the current column // if (!writePNMImagesData(vecColImages, stream)) break; // // Forget the current column images // vecColImages.clear(); } // // restore window and cleanup // for (size_t i = 0; i < num_ports; ++i) { win->subPortByObj(decorators[i].get<3>()); Viewport* vp = win->getPort(i); vp->setCamera(decorators[i].get<0>()->getDecoratee()); vp->setSize(0, 0, 1, 1); TileableBackground* tbg = dynamic_cast<TileableBackground*>(vp->getBackground()); if (tbg) tbg->setTile(decorators[i].get<1>()); } }
// // GrabForeground based solution // static void writeHiResScreenShot( const char* name, UInt32 width, UInt32 height) { size_t num_ports = win->getMFPort()->size(); if (num_ports == 0) return; // // calc image dimensions // UInt32 winWidth = win->getWidth(); UInt32 winHeight = win->getHeight(); if (width < winWidth ) width = winWidth; if (height < winHeight) height = winHeight; Real32 a = Real32(winWidth) / Real32(winHeight); width = UInt32(a*height); // // output stream for writing the final image // std::ofstream stream(name, std::ios::binary); if (stream.good() == false) return; // // Tile image used for foreground grabbing // ImageUnrecPtr grab_image = Image::create(); GrabForegroundUnrecPtr grabber = GrabForeground::create(); grabber->setImage (grab_image); grabber->setActive (true); grabber->setAutoResize(false); // // We tile the final image and render each tile with the screen resolution // into the window. The more tiles we use the bigger the resolution of the // final image gets with respect to a provided measure of length. // typedef boost::tuple<TileCameraDecoratorUnrecPtr, bool> TupleT; std::vector<TupleT> decorators; decorators.resize(num_ports); // // Setup the tile camera decorators for each viewport of the window and // disable the tile property of tileable viewport backgrounds. // for (size_t i = 0; i < num_ports; ++i) { Viewport* vp = win->getPort(i); TileCameraDecoratorUnrecPtr decorator = TileCameraDecorator::create(); decorator->setFullSize (width, height); decorator->setDecoratee(vp->getCamera()); vp->setCamera(decorator); bool bTiled = false; TileableBackground* tbg = dynamic_cast<TileableBackground*>(vp->getBackground()); if (tbg) { bTiled = tbg->getTile(); tbg->setTile(false); } // // remember the decorator and the background tile prop setting // decorators[i] = boost::make_tuple(decorator, bTiled); } // // Add the grabber to the forgrounds of the first viewport // Viewport* vp0 = win->getPort(0); vp0->addForeground(grabber); // // We write the image in simple ppm format. This one starts with a description // header which we output once on first write. // bool write_header = true; // // Calc the max y start position (width). We process the tiles from bottom // up and from left tp right as determined by the image format. // UInt32 yPosLast = 0; for (; yPosLast < height-winHeight; yPosLast += winHeight); // // Process from bottom to top // for (Int32 yPos = yPosLast; yPos >= 0; yPos -= winHeight) { UInt32 ySize = std::min(winHeight, height - yPos); // // Collect the tile images for each row, i.e. we write the // image in row manner to disk. This way the main memory is // only moderately stressed. // std::vector<ImageUnrecPtr> vecColImages; // // Process from left to right // for (UInt32 xPos = 0; xPos < width; xPos += winWidth) { UInt32 xSize = std::min(winWidth, width - xPos); // // The current tile image // ImageUnrecPtr col_image = Image::create(); col_image->set(Image::OSG_RGBA_PF, xSize, ySize); // // Adapt the tile camera decorator boxes to the current tile // for (size_t i = 0; i < num_ports; ++i) { Viewport* vp = win->getPort(i); vp->setSize(0, 0, xSize, ySize); TileCameraDecorator* decorator = decorators[i].get<0>(); decorator->setSize( xPos / float(width), yPos / float(height), (xPos + xSize) / float(width), (yPos + ySize) / float(height) ); } // // Adapt the grabber image size to the current tile dimension // grab_image->set(Image::OSG_RGBA_PF, xSize, ySize); // // render the tile // mgr->redraw(); // // Copy the image into the tile image stored for later processing // col_image->setSubData(0, 0, 0, xSize, ySize, 1, grabber->getImage()->getData()); vecColImages.push_back(col_image); } // // Write the image format header once // if (write_header) { write_header = false; if (!writePNMImagesHeader(vecColImages, width, height, stream)) break; } // // Write the current column // if (!writePNMImagesData(vecColImages, stream)) break; // // Forget the current column images // vecColImages.clear(); } // // restore window and cleanup // vp0->removeObjFromForegrounds(grabber); for (size_t i = 0; i < num_ports; ++i) { Viewport* vp = win->getPort(i); vp->setCamera(decorators[i].get<0>()->getDecoratee()); vp->setSize(0, 0, 1, 1); TileableBackground* tbg = dynamic_cast<TileableBackground*>(vp->getBackground()); if (tbg) tbg->setTile(decorators[i].get<1>()); } }
void SortLastWindow::serverRender(Window *serverWindow, UInt32 id, RenderActionBase *action ) { ViewportUnrecPtr serverPort = NULL; Viewport *clientPort = NULL; UInt32 sv = 0; UInt32 cv = 0; // duplicate viewports for(cv = 0, sv = 0; cv < getMFPort()->size(); ++cv) { clientPort = getPort(cv); if(serverWindow->getMFPort()->size() <= sv) { // create new port serverPort = Viewport::create(); serverWindow->addPort(serverPort); } else { serverPort = serverWindow->getPort(sv); } // duplicate values if(getWidth() && getHeight()) { serverPort->setSize(clientPort->calcPixelLeft (), clientPort->calcPixelBottom(), clientPort->calcPixelRight (), clientPort->calcPixelTop ()); } else { serverPort->setSize(0,0,0,0); } serverPort->setCamera (clientPort->getCamera ()); serverPort->setRoot (clientPort->getRoot ()); serverPort->setBackground(clientPort->getBackground()); // ignore statistics foreground serverPort->clearForegrounds(); for(UInt32 f = 0 ; f < serverPort->getMFForegrounds()->size(); ++f) { Foreground *fg = clientPort->getForegrounds(f); StatisticsForeground *sfg = dynamic_cast<StatisticsForeground *>(fg); if(sfg == NULL) { serverPort->addForeground(fg); } } serverPort->setTravMask(clientPort->getTravMask()); sv++; } // remove unused ports while(serverWindow->getMFPort()->size() > sv) { serverWindow->subPort(sv); } // setup visible nodes setupNodes(id); // render the viewports serverWindow->activate(); serverWindow->frameInit(); action->setWindow(serverWindow); if(getComposer() != NULL) getComposer()->startFrame(); for(sv = 0; sv < serverWindow->getMFPort()->size(); ++sv) { Viewport *vp = serverWindow->getPort(sv); if(getComposer() != NULL) getComposer()->startViewport(vp); // render vp->render(action); // compose single viewport if(getComposer() != NULL) getComposer()->composeViewport(vp); } // compose whole window if(getComposer() != NULL) getComposer()->composeWindow(); }