Discussion:
[Opensg-users] OpenSG 2: Setting up the depth buffer
Johannes Brunen
2015-10-06 08:11:43 UTC
Permalink
Hello,



I'm looking for a method to setup the depth buffer and possibly the
stencil buffer befor starting rendering a viewport.



Suppose I have rendered a viewport with complex geometry into textures
with a FBO. I know how to do that, but now I want to initialize the
color and depth/stencil buffer from these textures for rendering a
second viewport. I have to render the second viewport a couple of times
dynamically and won't render the first viewport in this situation.



Can this be done with OpenSG? Can anyone give me an outline of such a
setup?



Best,

Johannes




------------------------------------------------------------------------------
Gerrit Voß
2015-10-07 07:27:26 UTC
Permalink
Hi,
Post by Johannes Brunen
Hello,
I'm looking for a method to setup the depth buffer and possibly the
stencil buffer befor starting rendering a viewport.
Suppose I have rendered a viewport with complex geometry into textures
with a FBO. I know how to do that, but now I want to initialize the
color and depth/stencil buffer from these textures for rendering a
second viewport. I have to render the second viewport a couple of times
dynamically and won't render the first viewport in this situation.
Can this be done with OpenSG? Can anyone give me an outline of such a
setup?
a passive background might help. It can take a clear callback
where you can do the blitting. Another option in there
is to blit the current framebuffer into an FBO (which is not directly
what you are looking for). Adding blitting from another FBO should not
be to difficult, well depending on how accurate the 'what to blit'
settings have to be. I'll have a look.

kind regards
gerrit
Johannes
2015-10-07 11:55:45 UTC
Permalink
Post by Gerrit Voß
a passive background might help. It can take a clear callback
where you can do the blitting. Another option in there
is to blit the current framebuffer into an FBO (which is not directly
what you are looking for). Adding blitting from another FBO should not
be to difficult, well depending on how accurate the 'what to blit'
settings have to be. I'll have a look.
Great :-)

I'm also playing around with an example with a PolygonBackground, but I
have problems getting it to run. What I'm trying is to create a viewport
with a PolygonBackground that is painting the texture image from a FBO
that I have rendered prior to that. In that simple setup the image is
rendered perfectly fine. However, when I add a shader program chunk to
the material of the PolygonBackground that shader code is never called.
I debugged the relevant code places where GL_COMPILE_STATUS and
GL_LINK_STATUS is checked, but the example program did not stop at these
places. Additionally, I debugged the State::activate(...) function. The
TextureObjChunk, TextureEnvChunk and the MaterialChunk get activated but
not so the ShaderProgramChunk.

The poor man's idea with the shader is, that I can adapt the depth
buffer beside of the color buffer in the fragment shader.

Below you can find part of the example. Could you take a brief look? Is
shader code in the PolygonBackground forbidden generally? In case it
helps I can post or upload the complete example code.


However, I would prefer some infrastructure that is easier to setup.
Maybe we could come up with a FancyBackground that takes a FBO and
manages the blitting (color, depth, stencil) internally. Especially, I
do not like a solution involving a shader in the first place.

Best,
Johannes


static void createDynamicViewport()
{
win->subPortByObj(staticVp);

ChunkMaterialUnrecPtr mat = ChunkMaterial::create();

MaterialChunkUnrecPtr matChunk = MaterialChunk::create();
matChunk->setDiffuse(Color4f(1.f,1.f,1.f,1.f));

TextureObjChunkUnrecPtr texObjChunk = spSimpleFBO->colorTexObj();

TextureEnvChunkUnrecPtr texEnvChunk = TextureEnvChunk::create();
texEnvChunk->setEnvMode(GL_REPLACE);

ShaderProgramChunkUnrecPtr shaderProgramChunk =
ShaderProgramChunk::create();

ShaderProgramUnrecPtr vertShader = ShaderProgram::createVertexShader();
ShaderProgramUnrecPtr fragShader =
ShaderProgram::createFragmentShader();

vertShader->setProgram(vertexShaderStr);
fragShader->setProgram(fragmentShaderStr);

fragShader->addUniformVariable("texUnit", 0);

shaderProgramChunk->addShader(vertShader);
shaderProgramChunk->addShader(fragShader);

mat->addChunk(matChunk);
mat->addChunk(texObjChunk);
mat->addChunk(texEnvChunk);
mat->addChunk(shaderProgramChunk);

PolygonBackgroundUnrecPtr polyBckgnd = PolygonBackground::create();
polyBckgnd->setMaterial(mat);
polyBckgnd->setClearColor(true);
polyBckgnd->setClearDepth(true);
polyBckgnd->setClearStencilBit(true);
polyBckgnd->setNormalizedX(true);
polyBckgnd->setNormalizedY(true);

polyBckgnd->editMFTexCoords()->push_back(Vec3f(0.f,0.f,0.f));
polyBckgnd->editMFTexCoords()->push_back(Vec3f(1.f,0.f,0.f));
polyBckgnd->editMFTexCoords()->push_back(Vec3f(1.f,1.f,0.f));
polyBckgnd->editMFTexCoords()->push_back(Vec3f(0.f,1.f,0.f));

polyBckgnd->editMFPositions()->push_back(Pnt2f(0.f,0.f));
polyBckgnd->editMFPositions()->push_back(Pnt2f(1.f,0.f));
polyBckgnd->editMFPositions()->push_back(Pnt2f(1.f,1.f));
polyBckgnd->editMFPositions()->push_back(Pnt2f(0.f,1.f));

NodeUnrecPtr root = makeCoredNode<Group>();
root->addChild(dynamicScene);

mgr->setRoot(root);

dynamicVp = Viewport::create();
dynamicVp->setRoot (rootNode(root));
dynamicVp->setBackground(polyBckgnd);
dynamicVp->setCamera (camera);
dynamicVp->setSize (0,0, 1,1);

mgr->getNavigator()->setViewport(dynamicVp);

win->addPort(dynamicVp);

mgr->update();
}
Gerrit Voß
2015-10-07 12:52:07 UTC
Permalink
Hi,
Post by Johannes
Post by Gerrit Voß
a passive background might help. It can take a clear callback
where you can do the blitting. Another option in there
is to blit the current framebuffer into an FBO (which is not directly
what you are looking for). Adding blitting from another FBO should not
be to difficult, well depending on how accurate the 'what to blit'
settings have to be. I'll have a look.
Great :-)
I'm also playing around with an example with a PolygonBackground, but I
have problems getting it to run. What I'm trying is to create a viewport
with a PolygonBackground that is painting the texture image from a FBO
that I have rendered prior to that. In that simple setup the image is
rendered perfectly fine. However, when I add a shader program chunk to
the material of the PolygonBackground that shader code is never called.
I debugged the relevant code places where GL_COMPILE_STATUS and
GL_LINK_STATUS is checked, but the example program did not stop at these
places. Additionally, I debugged the State::activate(...) function. The
TextureObjChunk, TextureEnvChunk and the MaterialChunk get activated but
not so the ShaderProgramChunk.
The poor man's idea with the shader is, that I can adapt the depth
buffer beside of the color buffer in the fragment shader.
Below you can find part of the example. Could you take a brief look? Is
shader code in the PolygonBackground forbidden generally? In case it
helps I can post or upload the complete example code.
However, I would prefer some infrastructure that is easier to setup.
Maybe we could come up with a FancyBackground that takes a FBO and
manages the blitting (color, depth, stencil) internally. Especially, I
do not like a solution involving a shader in the first place.
that might be the best solution.

For your shader problem below, that is an old issue. It boils down to
shaders being cached during the traversal and remapped to a different
object. So the frontend objects does not do any actual OpenGL calls.
The easiest way around this is to use a SimpleSHLChunk instead if one
wants to activate the shader directly.

kind regards
gerrit
Johannes
2015-10-07 14:08:09 UTC
Permalink
For your shader problem below, ...
The easiest way around this is to use a SimpleSHLChunk instead ...
I did not know about that one :-(

I took a look into the PassiveBackground implementation and it seems
that it is quite near to what is needed here if I understand correctly.
If ClearFrameBufferObject is set and no ClearCallback is defined it does
perform some blitting by

osgGlBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, 0)
osgGlBlitFramebuffer(
pEnv->getPixelLeft (),
pEnv->getPixelBottom(),
pEnv->getPixelRight (),
pEnv->getPixelTop (),
pEnv->getPixelLeft (),
pEnv->getPixelBottom(),
pEnv->getPixelRight (),
pEnv->getPixelTop (),
(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT),
GL_NEAREST);

osgGlBindFramebuffer(
GL_READ_FRAMEBUFFER_EXT,
win->getGLObjectId(pEnv->getActiveFBO()));


Am I correct that this blit from the main render buffer into the active FBO?


Assume that we store the FBO into the FancyBackground. How do we do the
opposite blit operation?

glBindFramebuffer(GL_READ_FRAMEBUFFER, my_fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

glReadBuffer(GL_COLOR_ATTACHMENT0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);

osgGlBlitFramebuffer(
pEnv->getPixelLeft (),
pEnv->getPixelBottom(),
pEnv->getPixelRight (),
pEnv->getPixelTop (),
pEnv->getPixelLeft (),
pEnv->getPixelBottom(),
pEnv->getPixelRight (),
pEnv->getPixelTop (),
(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT),
GL_NEAREST);

What is my_fbo actually, i.e. where do I get the id of the stored FBO?

I have no experience with GL framebuffer handling, so any hints are
welcomed.

Best,
Johannes
Gerrit Voß
2015-10-09 10:52:56 UTC
Permalink
Hello,

I added a new OSGFBOBackground which takes a FramebufferObject and
on clear tries to blit all color, depth and stencil buffers,
either to the active FBO or to the window framebuffer.

I only came around to do some quick testing, but it gives you
something to start with (and ideally it already does what you
need). I will do some further testing, especially on robustness.


kind regards
gerrit



------------------------------------------------------------------------------
Johannes
2015-10-09 12:20:56 UTC
Permalink
Hello Gerrit,
Post by Gerrit Voß
I added a new OSGFBOBackground which takes a FramebufferObject and
on clear tries to blit all color, depth and stencil buffers,
either to the active FBO or to the window framebuffer.
This is really great. I will immediately take an OpenSG snapshot and
look into it. However, I will be offline the next week and can not give
you direct response, so.
Post by Gerrit Voß
I only came around to do some quick testing, but it gives you
something to start with (and ideally it already does what you
need). I will do some further testing, especially on robustness.
I have started with an example as I have written. I think it can be
properly extended to be part of the OpenSG examples when finished.

One point I have in mind with respect to robustness is the support of
multisampled render context/buffers. But, I don't currently know every
nut, bolt and screw in this area.

Thanks, and best regards,
Johannes



------------------------------------------------------------------------------
Johannes
2015-10-19 09:33:43 UTC
Permalink
Hello Gerrit,

suppose we would have a corresponding FBOForeground, which manages a FBO
and would be filled from the render buffer by blit operation at the end
of the render task (probably on request only).
What I have in mind is to setup such a foreground in my first viewport
and to use the FBO in the second viewport's FBOBackground in my dynamic
case. The FBO would have to be adapted at resize and would have to
respect the multisampling settings of the underlying render context.

Do you think that this is good plan?
Do I have overseen some constraint that could not be fulfilled?

Best,
Johannes

P.S. I did already a simple example with the new FBOBackground and it
worked well.




------------------------------------------------------------------------------
Johannes
2015-10-19 12:36:47 UTC
Permalink
Hello Gerrit,

once again. I did a glance at the multisampling OpenGL technique and
compared it to the OpenSG texture/FBO usage. As I see it, multisampling
is currently not supported by OpenSG.

Following the wikipedia entry

https://www.opengl.org/wiki/Multisampling#Allocating_a_Multisample_Render_Target

OpenSG does have to use the GL_TEXTURE_2D_MULTISAMPLE flag(s) and the
glTexImage2DMultisample api(s) in order to support multisampling. Is
there any reason not to uses these on a multisampling rendering context.

What is your opinion with respect to multisampling?
Do you have experience with the multisampling in OpenGL generally?
Should we add support for proper multisampling to OpenSG?

Is multisampling used by others regularily?
Do other post process their render buffers for antialiasing instead of
hardware multisampling?

Best,
Johannes



------------------------------------------------------------------------------
Johannes
2015-10-19 14:56:45 UTC
Permalink
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;
}




------------------------------------------------------------------------------
Johannes
2015-11-09 13:02:57 UTC
Permalink
Post by Johannes
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
// 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
{
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;
FBOBuilder(const VecTextureDataT& buffers, bool depth,
bool stencil, const TextureData& ds_buffer)
: _buffers(buffers) , _depth(depth) , _stencil(stencil)
, _ds_buffer(ds_buffer) {}
~FBOBuilder() {}
FrameBufferObjectTransitPtr operator()(UInt32 width, UInt32
height) const;
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
{
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; }
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;
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)
{
{
cleanup();
osgExit();
std::exit(EXIT_SUCCESS);
}
break;
{
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 :-)

Johannes
2015-10-20 14:52:30 UTC
Permalink
Hello Gerrit,
Post by Johannes
once again. I did a glance at the multisampling OpenGL technique and
compared it to the OpenSG texture/FBO usage. As I see it, multisampling
is currently not supported by OpenSG.
sorry, but that was plainly wrong! After inspecting the OpenSG code more
carefully I must say that many multisampling things are already at the
right place :-).

What I did not find was the texture image generation for multisampling.

I think that serious work has to be done in files

System/Depreciated/State/OSGTextureChunk.cpp
System/State/Base/OSGTextureObjChunk.cpp,


some additions
(GL_TEXTURE_2D_MULTISAMPLE,GL_TEXTURE_2D_ARRAY_MULTISAMPLE)
are required in:

System/Window/FrameBufferObjects/OSGLayeredTextureBuffer.cpp
System/Window/FrameBufferObjects/OSGTextureBuffer.cpp


I do not know what is necessary for these two

System/Window/Background/OSGTextureGrabBackground.cpp
System/Window/Foreground/OSGTextureGrabForeground.cpp


and what I also do not have understood if the following files work in
case of a multisampling render context:

System/NodeCores/Groups/Effects/Projectors/OSGFishEyeProjector.cpp
System/NodeCores/Groups/Effects/ShadowStage/OSGDitherShadowMapHandler.cpp
System/NodeCores/Groups/Effects/ShadowStage/OSGPCF2ShadowMapHandler.cpp
System/NodeCores/Groups/Effects/ShadowStage/OSGPCFShadowMapHandler.cpp
System/NodeCores/Groups/Effects/ShadowStage/OSGPerspectiveShadowMapHandler.cpp
System/NodeCores/Groups/Effects/ShadowStage/OSGShadowStage.cpp
System/NodeCores/Groups/Effects/ShadowStage/OSGShadowTreeHandler.cpp
System/NodeCores/Groups/Effects/ShadowStage/OSGStdShadowMapHandler.cpp
System/NodeCores/Groups/Effects/ShadowStage/OSGVarianceShadowMapHandler.cpp
System/NodeCores/Groups/Light/Shadow/Engines/OSGShaderShadowMapEngine.cpp
System/NodeCores/Groups/Light/Shadow/Engines/OSGSimpleShadowMapEngine.cpp


Once again sorry.

Best,
Johannes



------------------------------------------------------------------------------
Loading...