static void keyboard(unsigned char k, int, int) { switch(k) { case 27: case 'q': case 'Q': { cleanup(); osgExit(); std::exit(EXIT_SUCCESS); } break; case '1': { UInt32 width = win->getWidth(); UInt32 height = win->getHeight(); std::cout << "Creating acquisition stage " << width << "x" << height << std::endl; if (!dynamicVp) { createAcquisitionStage(); createDynamicViewport(); } else { enableStaticScene(); } } break; } glutPostRedisplay(); }
// // setup scene // static int doMain(int argc, char *argv[]) { preloadSharedObject("OSGFileIO"); preloadSharedObject("OSGImageFileIO"); osgInit(argc,argv); int winid = setupGLUT(&argc, argv); win = GLUTWindow::create(); win->setGlutId(winid); win->init(); if(argc < 2) { FWARNING(("No file given!\n")); FWARNING(("Supported file formats:\n")); std::list<const char*> suffixes; SceneFileHandler::the()->getSuffixList(suffixes); for(std::list<const char*>::iterator it = suffixes.begin(); it != suffixes.end(); ++it) { FWARNING(("%s\n", *it)); } staticScene = createStaticScene(); } else { staticScene = SceneFileHandler::the()->read(argv[1]); } dynamicScene = createDynamicScene(); commitChanges(); mgr = SimpleSceneManager::create(); NodeUnrecPtr root = makeCoredNode<Group>(); root->addChild(staticScene); mgr->setWindow(win); mgr->setRoot (root); GradientBackgroundUnrecPtr background = GradientBackground::create(); background->addLine(Color3f(0,0,0), 0); background->addLine(Color3f(1,1,1), 1); staticVp = win->getPort(0); staticVp->setBackground(background); camera = staticVp->getCamera(); mgr->showAll(); return 0; }
// // setup scene // static int doMain(int argc, char *argv[]) { preloadSharedObject("OSGFileIO"); preloadSharedObject("OSGImageFileIO"); osgInit(argc,argv); int winid = setupGLUT(&argc, argv); win = GLUTWindow::create(); win->setGlutId(winid); win->init(); if(argc < 2) { FWARNING(("No file given!\n")); FWARNING(("Supported file formats:\n")); std::list<const char*> suffixes; SceneFileHandler::the()->getSuffixList(suffixes); for(std::list<const char*>::iterator it = suffixes.begin(); it != suffixes.end(); ++it) { FWARNING(("%s\n", *it)); } scene = makeTorus(.5, 2, 16, 16); } else { scene = SceneFileHandler::the()->read(argv[1]); } commitChanges(); mgr = new SimpleSceneManager; mgr->setWindow(win); mgr->setRoot (scene); GradientBackgroundUnrecPtr background = GradientBackground::create(); background->addLine(Color3f(0,0,0), 0); background->addLine(Color3f(1,1,1), 1); Viewport* viewport = win->getPort(0); viewport->setBackground(background); mgr->showAll(); return 0; }
static void enableStaticScene() { win->subPortByObj(dynamicVp); dynamicVp = nullptr; NodeUnrecPtr root = makeCoredNode<Group>(); root->addChild(staticScene); mgr->setRoot(root); mgr->getNavigator()->setViewport(staticVp); staticVp->setCamera(camera); win->addPort(staticVp); }
static void keyboard(unsigned char k, int, int) { UInt32 winWidth = win->getWidth(); UInt32 winHeight = win->getHeight(); UInt32 width = fw * winWidth; UInt32 height = fh * winHeight; switch(k) { case 27: case 'q': case 'Q': { cleanup(); osgExit(); std::exit(EXIT_SUCCESS); } break; case '1': { std::cout << "Creating screenshot (Grab FG) " << width << "x" << height << " in '" << output_file << std::endl; writeHiResScreenShot(output_file, width, height); } break; case '2': { std::cout << "Creating screenshot (FBO) " << width << "x" << height << " in '" << output_file_fbo << std::endl; writeHiResScreenShotFBO(output_file_fbo, width, height); } break; } glutPostRedisplay(); }
static void createDynamicViewport() { win->subPortByObj(staticVp); FBOBackgroundUnrecPtr fboBckgnd = FBOBackground::create(); fboBckgnd->setFrameBufferObject(spSimpleFBO->fbo()); NodeUnrecPtr root = makeCoredNode<Group>(); root->addChild(dynamicScene); mgr->setRoot(root); dynamicVp = Viewport::create(); dynamicVp->setRoot (rootNode(root)); dynamicVp->setBackground(fboBckgnd); dynamicVp->setCamera (camera); dynamicVp->setSize (0,0, 1,1); mgr->getNavigator()->setViewport(dynamicVp); win->addPort(dynamicVp); mgr->update(); }
// // 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); }
// Initialize GLUT & OpenSG and set up the scene int main(int argc, char **argv) { // OSG init osgInit(argc,argv); // GLUT init int winid = setupGLUT(&argc, argv); if(argc >= 2) scene = SceneFileHandler::the()->read(argv[1]); else scene = SceneFileHandler::the()->read("Data/tie.wrl"); if(scene == NULL) scene = makeTorus(0.3, 4, 16, 64); // init material phong_chunk = createPhongShaderMaterial(); // get all the Materials of the current scene getAllMaterials(scene, materials); // add the phong material chunk to every found material for(int i = 0; i < materials.size(); ++i) { (materials[i])->addChunk(phong_chunk); } phong_active = true; // open a new scope, because the pointers below should go out of scope // before entering glutMainLoop. // Otherwise OpenSG will complain about objects being alive after shutdown. { // the connection between GLUT and OpenSG GLUTWindowRefPtr gwin = GLUTWindow::create(); gwin->setGlutId(winid); gwin->init ( ); // create the SimpleSceneManager helper _mgr = new SimpleSceneManager; // tell the manager what to manage _mgr->setWindow (gwin ); _mgr->setRoot (scene); _mgr->turnHeadlightOn( ); commitChanges(); // show the whole scene _mgr->showAll(); // create a gradient background. GradientBackgroundRefPtr gbg = GradientBackground::create(); gbg->clearLines(); gbg->addLine(Color3f(0.7, 0.7, 0.8), 0); gbg->addLine(Color3f(0.0, 0.1, 0.3), 1); //set gradient background ViewportRefPtr vp = gwin->getPort(0); vp->setBackground(gbg); commitChanges(); } // GLUT main loop glutMainLoop(); return 0; }
// // 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>()); } }