[osg-users] multi threaded with slave camera and fbo

3 views
Skip to first unread message

Cedric Pinson

unread,
Jun 23, 2008, 8:09:13 PM6/23/08
to Public OpenSceneGraph Users discussion list.
Hi,

I would like to know if other found some strange issue with multi
threaded, and render slave camera to fbo. Here what i do.
In order to get screenshoot of top view and front view of a scene, i
added two slave camera (AbsoluteRF) and share the same graphiccontext.
I start from the osgprerender camera intialisation with some
adjustement. The issue is it works for the first slave camera, but not
the second (if i called twice the function i get a correct screenshoot),
so it looks like a synchronisation issue or something like that. I know
it's secure to make modification in the scene graph during in the update
traversal. So during the traversal i add an postdrawcallback to the two
slave camerao that will just save the result of the image rendered
(respective to each camera) to the disk and then the callback is removed.
When i force the setThreadingModel(osgViewer::Viewer::SingleThreaded);
everything works as it should be, so I imagine i missed something on
thread synchronisation. I thought making things in the traversal update
was good.
I tried different thread model to try to understand, in SingleThreaded
and CullDrawThreadPerContext it works, but DrawThreadPerContext and
CullThreadPerCameraDrawThreadPerContext works for the first slave
camera. Just for informations i have a dual core with nvidia system on
linux.
I use osg 2.4 and i have the same issue with the last svn version 2.5.3

Any clue ?

void MyClass::addScreenShootCamera(osgViewer::Viewer* viewer,
osg::NodeCallback* callback, const osg::Matrix& view, const std::string&
filename)
{
int tex_width = 300;
int tex_height = 200;
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
// set up the background color and clear mask.
camera->setClearColor(osg::Vec4(0.1f,0.1f,0.3f,1.0f));
camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// set viewport
camera->setGraphicsContext(viewer->getCamera()->getGraphicsContext());
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
camera->setViewport(0,0,tex_width,tex_height);
double ratio = tex_height * 1.0 /tex_width;
camera->setProjectionMatrixAsOrtho(-1, 1,-ratio, ratio, -10000, 10000);
camera->setViewMatrix(view);

osg::Camera::RenderTargetImplementation renderImplementation =
osg::Camera::FRAME_BUFFER_OBJECT;
camera->setRenderTargetImplementation(renderImplementation);
osg::Image* image = new osg::Image;
image->allocateImage(tex_width, tex_height, 1, GL_RGBA,
GL_UNSIGNED_BYTE);
image->setFileName(filename);
// attach the image so its copied on each frame.
camera->attach(osg::Camera::COLOR_BUFFER, image);
// camera->setDataVariance(osg::Object::DYNAMIC);
viewer->addSlave(camera.get());
AdaptProjectionForSceneSizeForFrontView* callback_casted =
dynamic_cast<AdaptProjectionForSceneSizeForFrontView*>(callback);
callback_casted->useImage(image);
callback_casted->setCamera(camera.get());
camera->setUpdateCallback(callback);
}

any clue ?

// boring code
struct AdaptProjectionForSceneSizeForFrontView : public osg::NodeCallback
{
osg::ref_ptr<osgViewer::Viewer> _viewer;
bool _needUpdate;
osg::ref_ptr<osg::Image> _image;
osg::ref_ptr<osg::Camera> _camera;
AdaptProjectionForSceneSizeForFrontView(osgViewer::Viewer* viewer) :
_viewer(viewer), _needUpdate (true) {}
void useImage(osg::Image* image) { _image = image; }
void setCamera(osg::Camera* camera) { _camera = camera;}
void needUpdate(bool state) { _needUpdate = state; }
virtual void updateProjection(osg::Camera* cam, const
osg::BoundingBox& sceneSize)
{
double ratio = _image->t() * 1.0/ _image->s();
float width = sceneSize._max[0] - sceneSize._min[0];
float height = sceneSize._max[2] - sceneSize._min[2];
if (height > width * ratio)
width = height / ratio;
height = width * ratio;

width *= 0.5;
height *= 0.5;
std::cout << "front" << std::endl;
std::cout << -width + sceneSize.center()[0] << " " << width +
sceneSize.center()[0] << " "
<< -height + sceneSize.center()[2] << " " << height +
sceneSize.center()[2] << std::endl;
cam->setProjectionMatrixAsOrtho(-width + sceneSize.center()[0],
width + sceneSize.center()[0],
-height + sceneSize.center()[2],
height + sceneSize.center()[2],
-10000,
10000);
}
void operator()(osg::Node* node, osg::NodeVisitor* nv) {
if (_needUpdate && nv->getVisitorType() ==
osg::NodeVisitor::UPDATE_VISITOR && _viewer->getSceneData()) {
osg::BoundingBox sceneSize;
osg::ref_ptr<osg::ComputeBoundsVisitor> bb = new
osg::ComputeBoundsVisitor;
_viewer->getSceneData()->accept(*bb);
sceneSize = bb->getBoundingBox();
osg::Camera* cam = dynamic_cast<osg::Camera*>(node);
if (cam) {
std::cout << "Scene size " << bb->getBoundingBox()._min << " "
<< bb->getBoundingBox()._max << std::endl;
updateProjection(cam, sceneSize);
_camera->setPostDrawCallback(new PSDrawCallback(_image.get()));
_needUpdate = false;
}
}
traverse(node,nv);
}
};

and the postdrawcallback core

void PSDrawCallback::operator () (osg::RenderInfo& renderInfo) const
{
osg::Camera* camera = renderInfo.getCurrentCamera();
osgDB::writeImageFile(*_image, _image->getFileName());
camera->setPostDrawCallback(0); // delete the callback
}

--
+33 (0) 6 63 20 03 56 Cedric Pinson mailto:morn...@plopbyte.net http://www.plopbyte.net


_______________________________________________
osg-users mailing list
osg-...@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

J.P. Delport

unread,
Jun 24, 2008, 3:07:31 AM6/24/08
to OpenSceneGraph Users
Hi,

Cedric Pinson wrote:
> Hi,
>
> I would like to know if other found some strange issue with multi
> threaded, and render slave camera to fbo.

Yes, there have been quite a few discussions about multithreaded and fbo
in the recent months, but AFAIK nobody has put a finger on the exact
problem yet.

Attached is a simple modded version of osgprerender that also displays
something strange in multithreaded. I'm not sure if it is related though.

run with:
./osgprerender --image

The image flashes every second frame for some reason. (Turn sync to
vblank on so it does not flash too fast.)

If, at the bottom of the .cpp, one enables the single threaded option,
the flashing disappears.

I have tried setting properties to dynamic on scene nodes, but it does
not seem to help, or I am missing a critical one.

jp

--
This message is subject to the CSIR's copyright terms and conditions, e-mail legal notice, and implemented Open Document Format (ODF) standard.
The full disclaimer details can be found at http://www.csir.co.za/disclaimer.html.

This message has been scanned for viruses and dangerous content by MailScanner,
and is believed to be clean. MailScanner thanks Transtec Computers for their support.

prerender_flash.zip

Cedric Pinson

unread,
Jun 24, 2008, 4:38:28 AM6/24/08
to OpenSceneGraph Users
What do you use to have a robust solution ? maybe i should just use
something different than fbo ?

Cedric

J.P. Delport wrote:
> Hi,
>
> Cedric Pinson wrote:
>> Hi,
>>
>> I would like to know if other found some strange issue with multi
>> threaded, and render slave camera to fbo.
>
> Yes, there have been quite a few discussions about multithreaded and
> fbo in the recent months, but AFAIK nobody has put a finger on the
> exact problem yet.
>
> Attached is a simple modded version of osgprerender that also displays
> something strange in multithreaded. I'm not sure if it is related though.
>
> run with:
> ./osgprerender --image
>
> The image flashes every second frame for some reason. (Turn sync to
> vblank on so it does not flash too fast.)
>
> If, at the bottom of the .cpp, one enables the single threaded option,
> the flashing disappears.
>
> I have tried setting properties to dynamic on scene nodes, but it does
> not seem to help, or I am missing a critical one.
>
> jp
>

> ------------------------------------------------------------------------

J.P. Delport

unread,
Jun 24, 2008, 4:55:31 AM6/24/08
to OpenSceneGraph Users
Hi,

for our current app we use singlethreaded. FBO is a requirement because
of multiple render targets.

Best would be to fix multithreaded and FBO. For this we will need small
test apps that reliably trigger errors.

Problem is that I think most people are unsure whether they are abusing
OSG (not using the library correctly, not setting dynamic correctly, not
blocking correctly...) or whether it is a bug.

jp

--

This message is subject to the CSIR's copyright terms and conditions, e-mail legal notice, and implemented Open Document Format (ODF) standard.
The full disclaimer details can be found at http://www.csir.co.za/disclaimer.html.

This message has been scanned for viruses and dangerous content by MailScanner,
and is believed to be clean. MailScanner thanks Transtec Computers for their support.

_______________________________________________

Cedric Pinson

unread,
Jun 24, 2008, 7:38:51 AM6/24/08
to OpenSceneGraph Users
I make a small program where i can reproduce the issue.
the two cow a and b are with threading model DrawThreadPerContext and
CullThreadPerCameraDrawThreadPerContext and c and d with
SingleThreaded and CullDrawThreadPerContext
to reproduce it:
run the program like that ./a.out cow.osg
then with the program is running press space to create the two file then
esc.

If someone has some clue or advise to dig it

Cedric

--

a.png
b.png
c.png
d.png
osg_bug.cpp

Wojciech Lewandowski

unread,
Jun 25, 2008, 6:47:18 AM6/25/08
to OpenSceneGraph Users
Hi Cedric,

> If someone has some clue or advise to dig it

Sorry I had no time to look at the repro you created. I looked at your
earlier modified
prerender example though. I got curious and started to debug it I think I
found some additional important circumstances and workaround that my help
you. But topic is quite mixed nad complex and I may have problems explaining
it. But here it goes:

Both DrawThreadPerContext and CullThreadPerCameraDrawThreadPerContext modes
use osgViewer::Renderer thread with double buffered SceneViews.
SingleThreaded and CullDrawThreadPerContext use single SceneView for
rendering. (CullDrawThreadPerContext also uses Renderer but only with one
SceneView see osgViewer::Rendered::cull_draw method in comparison to
osgViewer::Renderer::draw & osgViewer::Renderer::cull)

Double buffered SceneViews mean that there are two interleaved SceneViews
performing cull and draw operations for subsequent odd/even frames. These
two scene views share some resources but may also create some separate
resources. For example, if texture is attached to RTT camera, each of these
SceneViews will create two separate FBOs for
this camera but these FBOs will share camera texture. But when you attach
the image to RTT camera, each of these FBOs will create
spearate render buffer and will read pixels to the camera image from the
buffer.

What seems to be the case in your modified osgprerender looks like there is
either some problems with refreshing the image in one of these SceneViews. I
ran your example through gliIntercept and found something really weird.
First SceneView FBO creates Renderbuffer with RGBA_32F format but second
SceneView creates RenderBuffer with RGBA format. So you end up with
situation when odd RTT camera frames are rendered into float framebuffer but
even frames are rendered into ubyte framebuffer. Apparently readPixels from
float buffer fails somehow and only read pixels from ubyte work as intended.

I got curious why first SceneView FBO uses float buffer but second uses
ubyte buffer. I think the answer is following: Apparently first frame drawn
by prerender RTT camera proceeds before rendered texture is initialized and
aplied to draw final scene. When first FBO is created its render buffer is
based on initial image internal format (RGBA_32F). FBO is build and used to
render first frame and then its contents are read to the image. Then main
camera draws scene using texture initilized from updated image. When this
texture gets applied for the first time, image internal image format gets
changed to texture format (RGBA) and thus second FBO is created using this
different format

So we end up with odd prerender frames rendered into RGBA_32F buffer and
even frames rendered into RGBA byte buffer. But this does not explain why
readPixels produce so visually different results. It looks like there might
be additional bug in OSG or OpenGL in reading pixels from RGBA_32F
framebuffer.

Now time for the conclusion. I don't have much time to dig this further, and
see why readPixels fail, maybe will investigate this some other day. So I
don't have a real fix, but you may try a simple workaround. Set initial
internal image format to RGBA instead of RGBA_32F. I did that and it seemed
to remove the discrepancy. Alternatively make sure that texture build from
image has its internal format set to RGBA_32F. But I did not try this
option.

Cheers,
Wojtek


--------------------------------------------------------------------------------

Cedric Pinson

unread,
Jun 25, 2008, 7:35:44 AM6/25/08
to OpenSceneGraph Users
Well thank you for helping,
You give me a lot of imformation, i will dig it

Cedric

Wojciech Lewandowski

unread,
Jun 25, 2008, 10:47:13 AM6/25/08
to OpenSceneGraph Users
Hi Cedric,

I just have found one more bit of info. Image internalTextureFormat gets
reset by Image::allocateImage called from Image::readPixels when RTT camera
buffer contents are read into image after first draw. So this does not
happen when texture is applied for final scene draw.

I am not sure if resseting internal format from GL_RGBA32F_ARB to GL_RGBA
should not be considered as a bug ?

However, it still does not explain what happens with image during and after
readPixels got called when render buffer was GL_RGBA32F_ARB.

Cheers,
Wojtek

Wojciech Lewandowski

unread,
Jun 25, 2008, 11:16:36 AM6/25/08
to OpenSceneGraph Users
Hi again Cedric,

I think I have last piece of the puzzle. It looks like readPixels work
perfectly correct with float Renderbuffer. I was blaming it because scene
background was properly darkened by postRender camera callback but rendered
cessna model seemed unafected by image darkennig process. Image darkenning
was done by simple color scaling by 0.5.

It turned out that cessna interior was also properly scaled. But when
Renderbuffer was float, render buffer color compononts were not clamped to
0..1 range (which is obvious for float buffers, but I always forget about
it;-). Shaders were substituting colors with vertices and multiplying them
by 2 (Sine uniform) so even after scaling by 0.5 we were still having color
components much larger than 1.0. Thats why cessna interior seemed not
darkened at all.

Jeez, I learned a lot today ;-) Thanks for interesting example ;-)

Cheers,

Wojtek

Cedric Pinson

unread,
Jun 25, 2008, 12:14:14 PM6/25/08
to OpenSceneGraph Users
Cool :)
Then thinking back on my problem i think i have an issue about
synchronization (because i have rtt works it looks like it's not the
good frame renderer). It seems that the projection matrix i set (in
ortho) is not yet updated for the current frame i want to grab. In fact
for my two camera rtt, only one seems synchronized with the projection
matrix.
And because it does not work for the cull draw on a different tread, it
could makes sense. I have to dig it, but i have not the time yet, (i
changed the threading model as a work around).
Thank you to answer to this thread it was interesting to read you answers

Robert Osfield

unread,
Jun 26, 2008, 8:06:32 AM6/26/08
to OpenSceneGraph Users
Hi Guys,

I've just skimmed through this thread. Interesting issues :-)

Wojtek explanations of the double buffered SceneView is spot on, in
this case leading to two FBO's, Creation of two FBO's for RTT is
something I've been aware of since the inception of the
DrawThreadPerContext/CullThreadPerCameraDrawThreadPerContext, but as
yet haven't had the opportunity to refactor the code to avoid it.

The problem actually stems from the reuse of SceneView to do something
that it was never intended to handle, and in terms of osgViewer
implementation SceneView was used simply because it was the line of
least resistance i.e. it worked and code be adapted to help speed up
the implementation of osgViewer, and mostly it's actually worked out
ok, the stop gap has worked out pretty well.

However, it has always been my plan to rewrite the osgViewer::Renderer
so that it doesn't use SceneView at all, let alone double buffering
them, instead it's my plan to use a single CullVisitor which
alternately populates double buffered RenderStage. This approach
would be far leaner and less obfusticated, and we should be able to
clean up some of the artefacts as well. The downside is by not using
SceneView we'll loose all the stereo rendering support, so instead
we'll need to refactor osgViewer so that stereo rendering is done at
the viewer level i.e. using slave cameras - this means more coding
work, but the actually end result would be far better both design wise
as well as in flexibility and performance.

I just need to time to go off and do this work, I might be able to get
it done for 2.6, but spare time certainly isn't something that I'm
blessed with right now.

Robert.

James Killian

unread,
Jun 26, 2008, 12:19:18 PM6/26/08
to OpenSceneGraph Users
 
I too find some interesting issues with this thread. :)
 
Robert,
This proposal you mention for 2.6 will it help balance the cpu workload against the  gpu I/O bottleneck?
 
I've been doing some osg performance benchmark research on thread synchronization using the Intel Threaded compiler, and so far the results are looking really good except for a 26% over-utilization due to sleeping.  I do want to say awesome job to those responsible for threading, the amount of critical section use looked very good!  All the worker threads also had good profiling results. 
 
The ultimate test I want to try today deals with an intentional GPU bottleneck... where I have a quadcore that pipes graphics out a PCI graphics card.  If anyone is interested I'll post these test results.  I know now that using a quad core there is lack of parallelization (e.g. 25% 85% 15% 15%), but that is a different battle for a different time.
 
I do want to get to the bottom of the profiling and determine how well the workload is balanced against the gpu i/o, and see if there is some opportunity for optimization here.

Wojciech Lewandowski

unread,
Jun 26, 2008, 12:22:30 PM6/26/08
to OpenSceneGraph Users
Hi Robert,

I am not sure if you read the piece where I mentioned that
Image::allocateImage resets Image::internalTextureFormat to image pixel
format. Image::allocateImage is called from Image::readPixels. So calling
readPixels also changes internal format. This was the main culprit that
second FBO for even SceneView was created with byte renderbuffer despite the
fact that first FBO was initalized to RGBA32F. That happened because, when
an image is attached to RTT camera, FBO Renderbuffer format is selected
after this image internalTextureFormat. In our example internalTextureFormat
was initially set to RGBA32F so first FBO Renderbuffer was initialized to
float but readPixels caused reset to RGBA. So in next frame, when second FBO
was created it initilized with standard 32 bit ubyte format.

I am not sure if this is a bug, but in my opinion Image::allocateImage
should not change internalTextureFormat or at least Image::readPixels should
record and restore internalFromat after calling allocateImage.

Cheers,
Wojtek.

Robert Osfield

unread,
Jun 26, 2008, 1:09:28 PM6/26/08
to OpenSceneGraph Users
Hi Wojtek,

On Thu, Jun 26, 2008 at 5:22 PM, Wojciech Lewandowski
<lewan...@ai.com.pl> wrote:
> I am not sure if you read the piece where I mentioned that
> Image::allocateImage resets Image::internalTextureFormat to image pixel
> format. Image::allocateImage is called from Image::readPixels. So calling
> readPixels also changes internal format. This was the main culprit that
> second FBO for even SceneView was created with byte renderbuffer despite the
> fact that first FBO was initalized to RGBA32F. That happened because, when
> an image is attached to RTT camera, FBO Renderbuffer format is selected
> after this image internalTextureFormat. In our example internalTextureFormat
> was initially set to RGBA32F so first FBO Renderbuffer was initialized to
> float but readPixels caused reset to RGBA. So in next frame, when second FBO
> was created it initilized with standard 32 bit ubyte format.

I did spot this, but didn't really have anything to add. Clearly it's
a bug, but without putting time into fully understanding the failure
mechanism I can't give any guidance. With all the build problems
kicking off this week I'm a bit too stretched thinly to go chase this
up.

> I am not sure if this is a bug, but in my opinion Image::allocateImage
> should not change internalTextureFormat or at least Image::readPixels should
> record and restore internalFromat after calling allocateImage.

I don't follow, are we talking about the the format in osg::Image or
the texture?

Wojciech Lewandowski

unread,
Jun 26, 2008, 4:33:24 PM6/26/08
to OpenSceneGraph Users

Hi Robert,



>> I am not sure if this is a bug, but in my opinion Image::allocateImage
>> should not change internalTextureFormat or at least Image::readPixels should
>> record and restore internalFromat after calling allocateImage.

>I don't follow, are we talking about the the format in osg::Image or
>the texture?

Sorry for being imprecise. All the time I was talking about osg::Image::_internalTextureFormat member.

I may submit a fix but I am not sure what is desired course of action. Should I remove the line changing it from Image::allocateImage or rather modify Image::readPixels to preserve it from modification when Image::allocateImage is called ? See the bits of code that could be affected, below.


osg::Image::allocateImage is called from Image::readPixels, Line 608
[...]
void Image::readPixels(int x,int y,int width,int height,
                       GLenum format,GLenum type)
{
    allocateImage(width,height,1,format,type);

    glPixelStorei(GL_PACK_ALIGNMENT,_packing);

    glReadPixels(x,y,width,height,format,type,_data);
}
[...]

osg::Image::_internalTextureFormat modified in:
Image.cpp, Image::allocateImage( int s,int t,int r,  GLenum format,GLenum type, int packing), Line 556
[...]
    if (_data)
    {
        _s = s;
        _t = t;
        _r = r;
        _pixelFormat = format;
        _dataType = type;
        _packing = packing;
        _internalTextureFormat = format;
    }
[...]


Image::_internalTextureFormat is used (through getInternalTextureFormat accessor method) to select Renderbuffer format: 
FrameBufferObject.cpp, FrameBufferAttachment::FrameBufferAttachment(Camera::Attachment& attachment), Line 365:
[...]
    osg::Image* image = attachment._image.get();
    if (image)
    {
        if (image->s()>0 && image->t()>0)
        {
            GLenum format = attachment._image->getInternalTextureFormat();
            if (format == 0)
                format = attachment._internalFormat;
            _ximpl = new Pimpl(Pimpl::RENDERBUFFER);
            _ximpl->renderbufferTarget = new osg::RenderBuffer(image->s(), image->t(), format);
[...]


Cheers,

Wojtek 


Cedric Pinson

unread,
Jun 26, 2008, 5:33:24 PM6/26/08
to OpenSceneGraph Users
Your mails are black so i need to select the test to read it. Anyway i
am interested by all result you have. If you can post them

Cedric

James Killian wrote:
>
> I too find some interesting issues with this thread. :)
>
> Robert,
> This proposal you mention for 2.6 will it help balance the cpu
> workload against the gpu I/O bottleneck?
>
> I've been doing some osg performance benchmark research on thread
> synchronization using the Intel Threaded compiler, and so far the
> results are looking really good except for a 26% over-utilization due
> to sleeping. I do want to say awesome job to those responsible for
> threading, the amount of critical section use looked very good! All
> the worker threads also had good profiling results.
>
> The ultimate test I want to try today deals with an intentional GPU
> bottleneck... where I have a quadcore that pipes graphics out a PCI
> graphics card. If anyone is interested I'll post these test results.
> I know now that using a quad core there is lack of parallelization
> (e.g. 25% 85% 15% 15%), but that is a different battle for a different
> time.
>
> I do want to get to the bottom of the profiling and determine how well
> the workload is balanced against the gpu i/o, and see if there is some
> opportunity for optimization here.
>
>
>
> ----- Original Message -----

> *From:* Robert Osfield <mailto:robert....@gmail.com>
> *To:* OpenSceneGraph Users
> <mailto:osg-...@lists.openscenegraph.org>
> *Sent:* Thursday, June 26, 2008 7:06 AM
> *Subject:* Re: [osg-users] multi threaded with slave camera and fbo

> <mailto:osg-...@lists.openscenegraph.org>
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
> ------------------------------------------------------------------------


>
> _______________________________________________
> osg-users mailing list
> osg-...@lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>

--

James Killian

unread,
Jun 26, 2008, 6:12:40 PM6/26/08
to OpenSceneGraph Users

Thanks for pointing that out... I keep forgetting to fix my reply in plain
text... Now this would explain why Robert did not respond... and all this
time I thought it was because I made him upset. ;)

On a side note... I really really really... hope that the client code will
not have to break up the rendering into subsections like suggested in the
threaded building blocks document from intel.


----- Original Message -----
From: Cedric Pinson
To: OpenSceneGraph Users

Robert Osfield

unread,
Jun 27, 2008, 4:28:13 AM6/27/08
to OpenSceneGraph Users
Hi Wojtek,

I believe the Image::readPixels and Image::allocateImage are valid,
changes these because of some high level behaviour is going amiss due
to it relying upon a parameter that is modified on the fly suggest to
me that perhaps the high level code is at fault i.e. the Camera
attachments/FBO setup perhaps needs to be refactored slightly.

Robert.

Wojciech Lewandowski

unread,
Jun 27, 2008, 6:12:03 AM6/27/08
to OpenSceneGraph Users
Robert,

I totaly agree that high level FBO code could be modified to avoid potential
glitches with doubling resources.

But on low level discussion, I also think that indirect modification of
internalTextureFormat in readPixels may bring trouble for pieces of code
relying on Image::getInternalTextureFormat(). I did a quick scan and these
code includes initialization of FBO Renderbuffers and initilization of
Textures (obviously).

As far as I understand Image::setInternalTextureFormat is created to let
programer decide what will be internal format of the texture and
renderbuffer created from this image. Right ?

So now imagine this case. I want to create texture with RGBA32F internal
format from an Image. I create image and set its internalTextureFormat to
RGBA32. To fill image data I call readPixels from frame buffer. Then I
create Texture from this image and surpirisngly end up with RGBA ubyte
Texture. So I wanted RGBA32F texture but got RGBA. I don't think this is OK.

Cheers,
Wojtek

Robert Osfield

unread,
Jun 27, 2008, 6:18:24 AM6/27/08
to OpenSceneGraph Users
Hi Wojtek,

> So now imagine this case. I want to create texture with RGBA32F internal
> format from an Image. I create image and set its internalTextureFormat to
> RGBA32. To fill image data I call readPixels from frame buffer. Then I
> create Texture from this image and surpirisngly end up with RGBA ubyte
> Texture. So I wanted RGBA32F texture but got RGBA. I don't think this is OK.

This suggest to me that one needs to pass more info into
Image::readPixels to control the internaltextureFormat, or possible
configuring things so that allocate reuses the original setting for
internaltextureFormat if its non default setting.

Robert.

Wojciech Lewandowski

unread,
Jun 27, 2008, 6:24:50 AM6/27/08
to OpenSceneGraph Users
Hi Robert,

>> So now imagine this case. I want to create texture with RGBA32F internal
>> format from an Image. I create image and set its internalTextureFormat to
>> RGBA32. To fill image data I call readPixels from frame buffer. Then I
>> create Texture from this image and surpirisngly end up with RGBA ubyte
>> Texture. So I wanted RGBA32F texture but got RGBA. I don't think this is
>> OK.
>
> This suggest to me that one needs to pass more info into
> Image::readPixels to control the internaltextureFormat, or possible
> configuring things so that allocate reuses the original setting for
> internaltextureFormat if its non default setting.

Thats exactly what I was asking for. Lets either fix Image::readPixels to
preserve internalTextureFormat, or Image::allocateImage to not change it.

Cheers,
Wojtek

Robert Osfield

unread,
Jun 27, 2008, 6:38:35 AM6/27/08
to OpenSceneGraph Users
Hi Wojtek,

On Fri, Jun 27, 2008 at 11:24 AM, Wojciech Lewandowski
<lewan...@ai.com.pl> wrote:
>> This suggest to me that one needs to pass more info into
>> Image::readPixels to control the internaltextureFormat, or possible
>> configuring things so that allocate reuses the original setting for
>> internaltextureFormat if its non default setting.
>
> Thats exactly what I was asking for. Lets either fix Image::readPixels to
> preserve internalTextureFormat, or Image::allocateImage to not change it.

I'm uneasy about changing the existing behaviour as we may well be
fixing one problem for one set of users, but introducing problems for
users that currently rely upon the existing behaviour.

Robert.

Wojciech Lewandowski

unread,
Jun 27, 2008, 8:11:37 AM6/27/08
to OpenSceneGraph Users
Hi Robert,

> I'm uneasy about changing the existing behaviour as we may well be
> fixing one problem for one set of users, but introducing problems for
> users that currently rely upon the existing behaviour.

As I had my doubts as well, I have asked if allocateImage or readPixels is a
better place for modification. Actually if I was pushed to choose, I would
rather modify readPixels because changing internalTextureFormat as a result
of this call is completely unintuitive. Its even more unexpected if one does
not even directly call readPixels but only attaches image to the camera.

My postition is that its better to fix it now than risk that even more users
will rely on this unexpected side effect. Do as you think is appropriate.
Since I know about this I am well prepared for all endings ;-)

Cheers,
Wojtek

Robert Osfield

unread,
Jun 27, 2008, 8:18:42 AM6/27/08
to OpenSceneGraph Users
Hi Wojtek,

Attached is Image.cpp modified to not update already set _internalTextureFormat.

I haven't actually decided upon the merits of merging this yet though,
but it could at least be tested on this specific problem you guys are
seeing.

Robert.

Image.cpp

Wojciech Lewandowski

unread,
Jun 27, 2008, 8:43:29 AM6/27/08
to OpenSceneGraph Users
Thanks Robert,

> Attached is Image.cpp modified to not update already set
> _internalTextureFormat.
>
> I haven't actually decided upon the merits of merging this yet though,
> but it could at least be tested on this specific problem you guys are
> seeing.

It does the trick. I put the breakpoint in the line where Renderbuffers are
created, and now they use the the same exact pixelformat set from
Image::getInternalTextureFormat().

James Killian

unread,
Jun 27, 2008, 11:14:51 PM6/27/08
to OpenSceneGraph Users

I have started a new thread called OSG thread profiling results are in!!
This will have those test results.

James Killian

Reply all
Reply to author
Forward
0 new messages