On 19.10.2015 16:56, Johannes wrote: > Hello Gerrit, > > below you can find my simple not finished example with the > FBOBackground. It works reasonably with a standard render context but > fails with a multisampling context. > > I have currently not figured out what exactly is going wrong, so. > > Best, > Johannes > > > // User interface: > // a) mouse => standard navigator > // b) keyboard => > // '1': toggle between static and dynamic mode > // > > #include <stdlib.h> > #include <stdio.h> > #include <string> > #include <sstream> > #include <fstream> > #include <vector> > #include <boost/tuple/tuple.hpp> > #include <boost/scoped_ptr.hpp> > #include <boost/random.hpp> > #include <boost/random/lagged_fibonacci.hpp> > > #ifdef OSG_BUILD_ACTIVE > // Headers > #include <OSGGLUT.h> > #include <OSGConfig.h> > #include <OSGSimpleGeometry.h> > #include <OSGGLUTWindow.h> > #include <OSGGradientBackground.h> > #include <OSGSimpleSceneManager.h> > #include <OSGSceneFileHandler.h> > #include <OSGAction.h> > #include <OSGFrameBufferObject.h> > #include <OSGRenderBuffer.h> > #include <OSGTextureBuffer.h> > #include <OSGSimpleStage.h> > #include <OSGPassiveViewport.h> > #include <OSGVisitSubTree.h> > #include <OSGImage.h> > #include <OSGTextureObjChunk.h> > #include <OSGFBOBackground.h> > > #else > // Headers > #include <OpenSG/OSGGLUT.h> > #include <OpenSG/OSGConfig.h> > #include <OpenSG/OSGSimpleGeometry.h> > #include <OpenSG/OSGGLUTWindow.h> > #include <OpenSG/OSGGradientBackground.h> > #include <OpenSG/OSGSimpleSceneManager.h> > #include <OpenSG/OSGSceneFileHandler.h> > #include <OpenSG/OSGAction.h> > #include <OpenSG/OSGFrameBufferObject.h> > #include <OpenSG/OSGRenderBuffer.h> > #include <OpenSG/OSGTextureBuffer.h> > #include <OpenSG/OSGSimpleStage.h> > #include <OpenSG/OSGPassiveViewport.h> > #include <OpenSG/OSGVisitSubTree.h> > #include <OpenSG/OSGImage.h> > #include <OpenSG/OSGTextureObjChunk.h> > #include <OpenSG/OSGFBOBackground.h> > > #endif > > OSG_USING_NAMESPACE; // just for convenience but not recommended > > #define USE_MULTISAMPLING > > #ifdef _DEBUG > const int max_tori = 500; > #else > const int max_tori = 10000; > #endif > > // > // Helper class for building FBO > // > class FBOBuilder > { > public: > struct TextureData { > TextureData() > : enable(true) > , pixel_format(Image::OSG_RGBA_PF) > , type(Image::OSG_UINT8_IMAGEDATA) > , main_memory(true) > , texObj(nullptr) > , image(nullptr) {} > ~TextureData() {texObj = nullptr; image = nullptr; } > > bool enable; > UInt32 pixel_format; > Int32 type; > bool main_memory; > TextureObjChunkUnrecPtr texObj; > ImageUnrecPtr image; > }; > > typedef std::vector<TextureData> VecTextureDataT; > > public: > FBOBuilder(const VecTextureDataT& buffers, bool depth, > bool stencil, const TextureData& ds_buffer) > : _buffers(buffers) , _depth(depth) , _stencil(stencil) > , _ds_buffer(ds_buffer) {} > ~FBOBuilder() {} > > public: > FrameBufferObjectTransitPtr operator()(UInt32 width, UInt32 > height) const; > > private: > VecTextureDataT _buffers; > bool _depth; > bool _stencil; > TextureData _ds_buffer; > }; > > FrameBufferObjectTransitPtr FBOBuilder::operator()( > UInt32 width, > UInt32 height) const > { > // > // Setup the FBO > // > FrameBufferObjectUnrecPtr fbo = FrameBufferObject::create(); > // > // multiple color buffers > // > for (UINT32 idx = 0; idx < _buffers.size(); ++idx) { > // > // use textures? > // > if (_buffers[idx].enable) { > ImageUnrecPtr texImg = (_buffers[idx].image == > nullptr ? Image::create() : _buffers[idx].image); > TextureObjChunkUnrecPtr texObj = (_buffers[idx].texObj == > nullptr ? TextureObjChunk::create() : _buffers[idx].texObj); > TextureBufferUnrecPtr texBuf = TextureBuffer::create(); > > if (_buffers[idx].image == nullptr) > texImg->set(_buffers[idx].pixel_format, > width, height, 1, 1, 1, 0.f, nullptr, > _buffers[idx].type, > _buffers[idx].main_memory); > > texObj->setImage(texImg); > texBuf->setTexture(texObj); > > fbo->setColorAttachment(texBuf, idx); > } else > // > // no, then use simple render buffer > // > { > RenderBufferUnrecPtr renBuf = RenderBuffer::create(); > renBuf->setInternalFormat(_buffers[idx].pixel_format); > fbo->setColorAttachment(renBuf, idx); > } > fbo->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT + > idx); > } > // > // a sole depth buffer > // > if (_depth && !_stencil) { > // > // use textures? > // > if (_ds_buffer.enable) { > ImageUnrecPtr texImg = (_ds_buffer.image == > nullptr ? Image::create() : _ds_buffer.image); > TextureObjChunkUnrecPtr texObj = (_ds_buffer.texObj == > nullptr ? TextureObjChunk::create() : _ds_buffer.texObj); > TextureBufferUnrecPtr texBuf = TextureBuffer::create(); > > if (_ds_buffer.image == nullptr) > texImg->set(_ds_buffer.pixel_format, > width, height, 1, 1, 1, 0.f, nullptr, > _ds_buffer.type, > _ds_buffer.main_memory); > > texObj->setImage(texImg); > > if (_ds_buffer.texObj == nullptr) { > texObj->setInternalFormat(GL_DEPTH_COMPONENT24); > texObj->setExternalFormat(GL_DEPTH_COMPONENT24); > } > texBuf->setTexture(texObj); > > fbo->setDepthAttachment(texBuf); > } else > // > // no, then use simple render buffer > // > { > RenderBufferUnrecPtr renBuf = RenderBuffer::create(); > renBuf->setInternalFormat(GL_DEPTH_COMPONENT24); > fbo->setDepthAttachment(renBuf); > } > } else > // > // or a combined depth/stencil buffer > // > if (_depth && _stencil) { > // > // use textures? > // > if (_ds_buffer.enable) { > ImageUnrecPtr texImg = (_ds_buffer.image == > nullptr ? Image::create() : _ds_buffer.image); > TextureObjChunkUnrecPtr texObj = (_ds_buffer.texObj == > nullptr ? TextureObjChunk::create() : _ds_buffer.texObj); > TextureBufferUnrecPtr texBuf = TextureBuffer::create(); > > if (_ds_buffer.image == nullptr) > texImg->set(GL_DEPTH_STENCIL_EXT, > width, height, 1, 1, 1, 0.f, nullptr, > GL_UNSIGNED_INT_24_8, > _ds_buffer.main_memory); > > texObj->setImage(texImg); > texObj->setInternalFormat(GL_DEPTH24_STENCIL8_EXT); > texObj->setExternalFormat(GL_DEPTH_STENCIL_EXT); > texBuf->setTexture(texObj); > > fbo->setDepthAttachment(texBuf); > fbo->setStencilAttachment(texBuf); > } else > // > // no, then use simple render buffer > // > { > RenderBufferUnrecPtr renBuf = RenderBuffer::create(); > renBuf->setInternalFormat(GL_DEPTH24_STENCIL8); > fbo->setDepthAttachment(renBuf); > fbo->setStencilAttachment(renBuf); > } > } > > fbo->setWidth (width ); > fbo->setHeight(height); > > return FrameBufferObjectTransitPtr(fbo); > } > > class SimpleFBO > { > public: > SimpleFBO(UInt32 width, > UInt32 height, > bool color_textured, > bool depth_stencil_textured, > bool read_back_color = true, > bool read_back_depth_stencil = false); > > SimpleFBO(UInt32 width, > UInt32 height, > const std::vector<FBOBuilder::TextureData>& > buffers, > bool depth, > bool stencil, > const FBOBuilder::TextureData& ds_buffer); > > ~SimpleFBO() { _fbo = nullptr; } > > public: > FrameBufferObject* fbo () const { return _fbo; } > > FrameBufferAttachment* colorBuffer (UInt32 idx = 0) const { > return _fbo ? _fbo->getColorAttachments(idx) : nullptr; } > FrameBufferAttachment* depthBuffer () const { > return _fbo ? _fbo->getDepthAttachment() : nullptr; } > FrameBufferAttachment* stencilBuffer () const { > return _fbo ? _fbo->getStencilAttachment() : nullptr;} > > TextureObjChunk* colorTexObj (UInt32 idx = 0) const; > TextureObjChunk* depthTexObj () const; > TextureObjChunk* stencilTexObj () const; > > private: > FrameBufferObjectRecPtr _fbo; > }; > > // > // Convenience class for building and wrapping a FBO. > // > SimpleFBO::SimpleFBO( > UInt32 width, > UInt32 height, > bool color_textured, > bool depth_stencil_textured, > bool read_back_color, > bool read_back_depth_stencil) > : _fbo(nullptr) > { > FBOBuilder::TextureData color_data; > color_data.enable = color_textured; > color_data.main_memory = read_back_color; > > FBOBuilder::TextureData depth_stencil_data; > depth_stencil_data.enable = depth_stencil_textured; > depth_stencil_data.main_memory = read_back_depth_stencil; > > FBOBuilder::VecTextureDataT color_vec; > color_vec.push_back(color_data); > > FBOBuilder fbo_builder(color_vec, true, true, depth_stencil_data); > > _fbo = fbo_builder(width, height); > } > > SimpleFBO::SimpleFBO( > UInt32 width, > UInt32 height, > const std::vector<FBOBuilder::TextureData>& buffers, > bool depth, > bool stencil, > const FBOBuilder::TextureData& ds_buffer) > : _fbo(nullptr) > { > FBOBuilder fbo_builder(buffers, depth, stencil, ds_buffer); > > _fbo = fbo_builder(width, height); > } > > TextureObjChunk* SimpleFBO::colorTexObj(UInt32 idx) const > { > TextureBuffer* texBuf = dynamic_cast<TextureBuffer*>(colorBuffer(idx)); > if (texBuf) > return texBuf->getTexture(); > > return nullptr; > } > > TextureObjChunk* SimpleFBO::depthTexObj() const > { > TextureBuffer* texBuf = dynamic_cast<TextureBuffer*>(depthBuffer()); > if (texBuf) > return texBuf->getTexture(); > > return nullptr; > } > > TextureObjChunk* SimpleFBO::stencilTexObj() const > { > TextureBuffer* texBuf = dynamic_cast<TextureBuffer*>(stencilBuffer()); > if (texBuf) > return texBuf->getTexture(); > > return nullptr; > } > > // > // function forward declarations > // > static void cleanup(void); > static void display(void); > static void reshape(int w, int h); > static void mouse(int button, int state, int x, int y); > static void motion(int x, int y); > static void keyboard(unsigned char k, int, int); > static int setupGLUT(int *argc, char *argv[]); > static int doMain(int argc, char *argv[]); > > > static NodeTransitPtr createStaticScene(); > static NodeTransitPtr createDynamicScene(); > static void createAcquisitionStage(); > static void createDynamicViewport(); > static void enableStaticScene(); > static Node* rootNode(Node* node); > // > // global state of example > // > SimpleSceneManagerRefPtr mgr; > NodeRefPtr staticScene; > NodeRefPtr dynamicScene; > GLUTWindowRefPtr win; > ViewportRefPtr staticVp; > ViewportRefPtr dynamicVp; > CameraRefPtr camera; > > boost::scoped_ptr<SimpleFBO> spSimpleFBO; > > static void cleanup(void) > { > mgr = nullptr; > staticScene = nullptr; > dynamicScene = nullptr; > win = nullptr; > dynamicVp = nullptr; > spSimpleFBO.reset(); > } > > static void display(void) > { > commitChanges(); > mgr->redraw(); > } > > static void reshape(int w, int h) > { > mgr->resize(w,h); > glutPostRedisplay(); > } > > static void mouse(int button, int state, int x, int y) > { > if (state) > mgr->mouseButtonRelease(button, x, y); > else > mgr->mouseButtonPress(button, x, y); > > glutPostRedisplay(); > } > > static void motion(int x, int y) > { > mgr->mouseMove(x, y); > glutPostRedisplay(); > } > > 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(); > } > > // > // initialize GLUT > // > static int setupGLUT(int *argc, char *argv[]) > { > glutInit(argc, argv); > > glutInitDisplayMode( > GLUT_RGB | GLUT_DEPTH | GLUT_STENCIL | GLUT_DOUBLE > #ifdef USE_MULTISAMPLING > | GLUT_MULTISAMPLE > #endif > ); > > int winid = glutCreateWindow("OpenSG"); > > glutReshapeFunc(reshape); > glutDisplayFunc(display); > glutIdleFunc(display); > glutMouseFunc(mouse); > glutMotionFunc(motion); > glutKeyboardFunc(keyboard); > > return winid; > } > > // > // 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; > } > > // > // create an arbitrarly complex render scene > // > static NodeTransitPtr createStaticScene() > { > NodeUnrecPtr root = makeCoredNode<Group>(); > > typedef boost::mt19937 base_generator_type; > static base_generator_type generator(0); > static boost::uniform_01<float> value; > static boost::variate_generator< base_generator_type, > boost::uniform_01<float> > die(generator, value); > > for (int i = 0; i < max_tori; ++i) { > NodeUnrecPtr scene = makeTorus(.5, 2, 32, 32); > > TransformUnrecPtr transformCore = Transform::create(); > Matrix mat; > > mat.setIdentity(); > > float x = 500.f * die(); > float y = 500.f * die(); > float z = 500.f * die(); > > float e1 = die(); > float e2 = die(); > float e3 = die(); > > Vec3f v(e1,e2,e3); > v.normalize(); > > float a = TwoPi * die(); > > Quaternion q(v, a); > > mat.setTranslate(x,y,z); > mat.setRotate(q); > > transformCore->setMatrix(mat); > > NodeUnrecPtr trafo = makeNodeFor(transformCore); > > trafo->addChild(scene); > > root->addChild(trafo); > } > > return NodeTransitPtr(root); > } > > static NodeTransitPtr createDynamicScene() > { > NodeUnrecPtr scene = makeCylinder(30, 100, 16, true, true, true); > return NodeTransitPtr(scene); > } > > // > // 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); > } > > 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(); > } > > 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 Node* rootNode(Node* node) > { > Node* root = nullptr; > while (node) { > root = node; > node = node->getParent(); > } > return root; > } > > // > // main entry point > // > int main(int argc, char *argv[]) > { > int ret = doMain(argc, argv); > > glutMainLoop(); > > cleanup(); > > osgExit(); > > return ret; > } > > > > > ------------------------------------------------------------------------------ > ping :-)
------------------------------------------------------------------------------ Presto, an open source distributed SQL query engine for big data, initially developed by Facebook, enables you to easily query your data on Hadoop in a more interactive manner. Teradata is also now providing full enterprise support for Presto. Download a free open source copy now. http://pubads.g.doubleclick.net/gampad/clk?id=250295911&iu=/4140 _______________________________________________ Opensg-users mailing list Opensg-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensg-users