Discussion:
[Opensg-users] OpenSG 2: FBOBackground and FBOGrabForeground
Johannes Brunen
2015-11-19 15:50:59 UTC
Permalink
Hello Carsten and Gerrit,

after Gerrit was so kind to provide a FBOBackground on my request, I have taken the time to write a FBOGrabForeground and two examples showing these in action.

The first one, named dyndrawing1.cpp uses a FBO that is created from the scene with the help of a SimpleStage, a VisitSubTree and a PassiveViewport. This FBO is then used in the new FBOBackground.

The second one, named dyndrawing2.cpp is quite similar to the first one, but the FBO is filled with the help of my new FBOGrabForeground class that I would like to see in OpenSG.

Both examples work reasonably but nevertheless some things are not perfect or need some clarifications. May I ask for some help here?

Let me enumerate the points:

1.) In the class FBOBackground Gerrit has used the following BlitFramebuffer statement in function clear:

osgGlBlitFramebuffer(
0,
0,
_sfFrameBufferObject.getValue()->getWidth (),
_sfFrameBufferObject.getValue()->getHeight(),

pEnv->getPixelLeft (),
pEnv->getPixelBottom(),
pEnv->getPixelRight (),
pEnv->getPixelTop (),

(GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT |
GL_STENCIL_BUFFER_BIT),
GL_NEAREST);

Is it not better to state the source points also from the pEnv dimensions? I'm unsure here and would like to hear your opinion.

2.) For experimentation I did put some clear buffer code into the FBOBackground clear function. I have provided a modified FBOBackground along with the new stuff in the attached zip file. In this source you can activate the buffer clearing with define DEBUG_CLEAR_BACKGROUND. With that in place and usage of the pEnv dimensions for source as well as for destination of the blit operation I always get a one black pixel seam at the top and the right of the rendered window (in both examples). However, do I add one pixel to the top and right dimension, then the rendered window seems to be ok. That can be done by enabling define ADD_PLUS_ONE_TO_TOP_AND_RIGHT in both the FBOBackground (for example 1) and FBOGrabForeground (for example 1 and 2) sources.

I have inspected other places in OpenSG at where the pEnv->getPixelLeft (),... calls are used and I found that at no place the additional pixels were added. So I'm confused. What is correct and how to explain the black edge in the window? If the additional pixel is correct, however, I have to ask about the correctness of the other code places :-(

3. Beside of these two points I would like to see the examples in OpenSG and I would like to ask for some polishing or review. This is the first foreground I have written and I'm still struggeling with the OpenGL framebuffer object. For instance, I'm still unsure about the implications of an multsampling render GL context of the window.

Anyway, I would really appreciate some help here.

Best,
Johannes
Carsten Neumann
2015-11-20 17:48:17 UTC
Permalink
Hello Johannes,
Post by Johannes Brunen
after Gerrit was so kind to provide a FBOBackground on my request, I
have taken the time to write a FBOGrabForeground and two examples
showing these in action.
nice, thank you!
Post by Johannes Brunen
1.) In the class FBOBackground Gerrit has used the following
osgGlBlitFramebuffer(
0,
0,
_sfFrameBufferObject.getValue()->getWidth (),
_sfFrameBufferObject.getValue()->getHeight(),
pEnv->getPixelLeft (),
pEnv->getPixelBottom(),
pEnv->getPixelRight (),
pEnv->getPixelTop (),
(GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT |
GL_STENCIL_BUFFER_BIT),
GL_NEAREST);
Is it not better to state the source points also from the pEnv
dimensions? I'm unsure here and would like to hear your opinion.
My feeling here is that it is more intuitive to use the entire FBO
contents by default. glBlitFramebuffer is capable of performing the
rescaling if the sizes don't match. If really needed fields could be
added to FBOBackground that describe the source region to use (the
destination region is always given by the targeted viewport).
Post by Johannes Brunen
2.) For experimentation I did put some clear buffer code into the
FBOBackground clear function. I have provided a modified FBOBackground
along with the new stuff in the attached zip file. In this source you
can activate the buffer clearing with define DEBUG_CLEAR_BACKGROUND.
I assume that is meant purely for debugging purposes? I may well be
missing something but outside of debugging I don't see a reason to clear
the buffers we are about to overwrite with the blit?
Post by Johannes Brunen
With that in place and usage of the pEnv dimensions for source as well
as for destination of the blit operation I always get a one black pixel
seam at the top and the right of the rendered window (in both examples).
However, do I add one pixel to the top and right dimension, then the
rendered window seems to be ok. That can be done by enabling define
ADD_PLUS_ONE_TO_TOP_AND_RIGHT in both the FBOBackground (for example 1)
and FBOGrabForeground (for example 1 and 2) sources.
Hmm, I think you found a bug there. glBlitFramebuffer takes x0,y0,x1,y1
with x1,y1 being exclusive, so I believe the +1 should be added.
Post by Johannes Brunen
I have inspected other places in OpenSG at where the pEnv->getPixelLeft
(),... calls are used and I found that at no place the additional pixels
were added. So I'm confused. What is correct and how to explain the
black edge in the window? If the additional pixel is correct, however, I
have to ask about the correctness of the other code places :-(
On a quick spot check most of the places that use those dimensions pass
the information to glViewport/glScissor which take x,y,width,height
arguments and DrawEnv::getPixelWidth/getPixelHeight do the correct
calculation of those.
I'll check places where glBlitFramebuffer is used, since those seem the
most likely to have a problem.
Post by Johannes Brunen
3. Beside of these two points I would like to see the examples in OpenSG
and I would like to ask for some polishing or review. This is the first
foreground I have written and I'm still struggeling with the OpenGL
framebuffer object.
I think the blit in FBOForeground should use the pEnv viewport
dimensions as source (pEnv->getPixelLeft(), ..., pEnv->getPixelRight()
+1, ...) and the entire FBO as destination (0,0, fbo->width, fbo->height).
I'm holding off adding the FBOForeground and example so we can come to
an agreement what values are best here.
Post by Johannes Brunen
For instance, I'm still unsure about the
implications of an multsampling render GL context of the window.
I'm not sure what you are asking. To the extend that I understand it
glBlitFramebuffer is capable of blitting between multisampled and
single-sampled buffers (at the very least in the direction of multi ->
single). So my hope would be that things "just work" - although there
are probably some details I'm missing... ;)

Cheers,
Carsten

------------------------------------------------------------------------------
Johannes
2015-11-23 08:12:04 UTC
Permalink
Hello Carsten,
Post by Carsten Neumann
Post by Johannes Brunen
2.) For experimentation I did put some clear buffer code into the
FBOBackground clear function. I have provided a modified FBOBackground
along with the new stuff in the attached zip file. In this source you
can activate the buffer clearing with define DEBUG_CLEAR_BACKGROUND.
I assume that is meant purely for debugging purposes? I may well be
missing something but outside of debugging I don't see a reason to clear
the buffers we are about to overwrite with the blit?
yes, only for debugging.
Post by Carsten Neumann
I'll check places where glBlitFramebuffer is used, since those seem the
most likely to have a problem.
thank you.
Post by Carsten Neumann
I think the blit in FBOForeground should use the pEnv viewport
dimensions as source (pEnv->getPixelLeft(), ..., pEnv->getPixelRight()
+1, ...) and the entire FBO as destination (0,0, fbo->width, fbo->height).
I'm holding off adding the FBOForeground and example so we can come to
an agreement what values are best here.
ok.
Post by Carsten Neumann
Post by Johannes Brunen
For instance, I'm still unsure about the
implications of an multsampling render GL context of the window.
I'm not sure what you are asking. To the extend that I understand it
glBlitFramebuffer is capable of blitting between multisampled and
single-sampled buffers (at the very least in the direction of multi ->
single).
You gave me just a new piece of information with you answer. My scenario
is that I might have a multisampled render context window and a non
multisampled framebuffer object. I was unsure whether I did have also to
use a multsampling framebuffer object when I have such a render context.
Post by Carsten Neumann
So my hope would be that things "just work" ...
That would be best :-)

Greetings,
Johannes
Johannes
2015-12-01 13:18:33 UTC
Permalink
Hello Carsten,

what is the state of affairs?
Are you waiting for me to proceed or on a response from Gerrit?

Hi Gerrit, are you listening?

I would like to finalize this topic :-)


Best,
Johannes
Post by Carsten Neumann
I think the blit in FBOForeground should use the pEnv viewport
dimensions as source (pEnv->getPixelLeft(), ..., pEnv->getPixelRight()
+1, ...) and the entire FBO as destination (0,0, fbo->width, fbo->height).
I'm holding off adding the FBOForeground and example so we can come to
an agreement what values are best here.
Carsten Neumann
2015-12-03 17:06:31 UTC
Permalink
[Back from travel]

Hello Johannes,
Post by Johannes
what is the state of affairs?
Are you waiting for me to proceed or on a response from Gerrit?
I had hoped for an opinion/reason to go one way or the other :) Thinking
some more about this now the most convenient default behavior should
perhaps be:

// Fill FBO but only up to size of viewport. This will not scale the
// captured image unless it is larger than the destination.
w = osgMin(
static_cast<Int32>(_sfFrameBufferObject.getValue()->getWidth ()),
pEnv->getPixelWidth ());
h = osgMin(
static_cast<Int32>(_sfFrameBufferObject.getValue()->getHeight()),
pEnv->getPixelHeight());

osgGlBlitFramebuffer(
pEnv->getPixelLeft (),
pEnv->getPixelBottom(),
pEnv->getPixelRight ()+1,
pEnv->getPixelTop ()+1,

0, 0, w, h,

Which is what I'm going to commit for now. If I've overlooked a use-case
where this behavior is problematic/not helpful let me know and I'm happy
to adjust it.
Thank you for your contribution,

Cheers,
Carsten
Johannes
2015-12-07 09:29:40 UTC
Permalink
Hello Carsten,

unfortunately, I have a problem that I don't understand. I have a window
which has multiple viewports. One of the viewports plays the game of
FBOGrabForeground/FBOBackground like in the example dyndrawing2.cpp.
That does not work for me.

In order to track down the origin of that problem I have modified the
dyndrawing2.cpp example a little bit. Here I can also show the problem
with just one viewport. What I see is that if I define the viewport not
just matching the window dimensions, then the resulting default
framebuffer is not completely updated in the region of the viewport in
case of the FBOBackground drawing cycle.

That sounds complicated but is quite easy to check. Insert the the
following line into the example at line position 530:

viewport->setSize(0.4, 0.4, 0.9, 0.9);

Additionally, I do have added the following block of code into the
reshape function after the resize call to allow proper window resizing
in the non static render cycle of the example. It would be fine to add
that to the dyndrawing2.cpp on the master.

if (!static_render_mode) {
static_render_mode = true;
applyRenderMode();
mgr->redraw();

static_render_mode = false;
applyRenderMode();
mgr->redraw();
}


Would you be so kind to take a look. Something I do miss but I can't
tell what it is.

Thanks,
Johannes

P.S.: With respect to the +1 missing pixel, I think that this also
belongs into the FBOBackground.
Post by Carsten Neumann
[Back from travel]
Hello Johannes,
Post by Johannes
what is the state of affairs?
Are you waiting for me to proceed or on a response from Gerrit?
I had hoped for an opinion/reason to go one way or the other :) Thinking
some more about this now the most convenient default behavior should
// Fill FBO but only up to size of viewport. This will not scale the
// captured image unless it is larger than the destination.
w = osgMin(
static_cast<Int32>(_sfFrameBufferObject.getValue()->getWidth ()),
pEnv->getPixelWidth ());
h = osgMin(
static_cast<Int32>(_sfFrameBufferObject.getValue()->getHeight()),
pEnv->getPixelHeight());
osgGlBlitFramebuffer(
pEnv->getPixelLeft (),
pEnv->getPixelBottom(),
pEnv->getPixelRight ()+1,
pEnv->getPixelTop ()+1,
0, 0, w, h,
Which is what I'm going to commit for now. If I've overlooked a use-case
where this behavior is problematic/not helpful let me know and I'm happy
to adjust it.
Thank you for your contribution,
Cheers,
Carsten
------------------------------------------------------------------------------
Go from Idea to Many App Stores Faster with Intel(R) XDK
Give your users amazing mobile app experiences with Intel(R) XDK.
Use one codebase in this all-in-one HTML5 development environment.
Design, debug & build mobile apps & 2D/3D high-impact games for multiple OSs.
http://pubads.g.doubleclick.net/gampad/clk?id=254741911&iu=/4140
Johannes
2015-12-07 11:56:48 UTC
Permalink
Hello Carsten,

I think I have found the origin of the problem. However, I'm not sure
about the validity of the solution I have implemented and that you can
find in the zip file attachment.

The problem stems from enabled scissor testing in the blit operations of
the FBOGrabForeground and of the FBOBackground. I have disabled the test
and then my code runs fine.

If this observation is correct then other parts of the OpenSG might also
be affected. Generally, the framebuffer object blit operation takes part
of the scissor testing.

Best,
Johannes

Loading...