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

Reply via email to