I’m trying to create a one_component floating point texture buffer (aka GL_R32F), but the FBO created is not at all what I expected.
When I print the FBProperties I used to create the texture buffer (using buffer.get_fb_properties()) I got what I configured :
float_color color_bits=32 red_bits=32 2d_texture generatorBuffer
However once the buffer is actually used, the actual FBProperties (and the actual texture format) is completely wrong, I get a three-components buffer and with half-float values :
float_color color_bits=48 red_bits=16 green_bits=16 blue_bits=16 force_hardware force_software 2d_texture
Looking at the code, my interpretation is that the GraphicStateGuardian looks only at the total number of bits to configure the FBO and not the number of color channels, and so when one request a total number of 32 bits the code allocate a 48 bits FBO with three components as it fits the bill. But I could also be doing something completely wrong
This may be a fairly easy one to fix. Could you show the code using which you are creating the buffer? Thanks!
This code should the the same thing as my application (I’m not home and my laptop does not seem to like floating point texture buffers).
from panda3d.core import FrameBufferProperties, GraphicsPipe, WindowProperties, NodePath, loadPrcFileData
from direct.task import Task
texture = mybuffer.get_texture()
print("Got:", mybuffer.get_fb_properties(), texture)
props = FrameBufferProperties()
props.set_rgba_bits(32, 0, 0, 0)
mybuffer = base.win.make_texture_buffer("generatorBuffer", size, size, to_ram=True, fbp=props)
mycamera = base.makeCamera(mybuffer)
myscene = NodePath("My Scene")
taskMgr.add(check_generation, 'check_generation', sort = -10000)
All right, this problem occurs due to the
to_ram flag which causes a renderbuffer to be created instead of a texture, which uses a different format selection mechanism.
I’ve checked in a fix:
Thanks a lot for the clear test case!
It works nice, at least for the buffer
If I print the texture just after creating the buffer, I get a 1-component texture :
Requested: float_color color_bits=32 red_bits=32 2d_texture generatorBuffer
2-d, 256 x 256 pixels, each 1 floats, r32, compression off
sampler wrap(u=clamp, v=clamp, w=repeat, border=0 0 0 1) filter(min=default, mag=default, aniso=0) lod(min=-1000, max=1000, bias=0) no ram image
Then, once the texture is uploaded to ram, the actual buffer is indeed a R32F buffer, but the texture has been switched to a 3-components texture :
Got: float_color color_bits=32 red_bits=32 force_hardware force_software 2d_texture
2-d, 256 x 256 pixels, each 3 floats, rgb, compression off
sampler wrap(u=clamp, v=clamp, w=repeat, border=0 0 0 1) filter(min=linear, mag=linear, aniso=0) lod(min=-1000, max=1000, bias=0) 786432 bytes in ram, compression off
And the texture size is indeed 256x256x3 32bits float
Even stranger, the output of
Which does not match with the texture size.
It’s probably missing something in framebuffer_copy_to_ram. I’ll take a look.
I think I’ve fixed this one as well:
Please give it a try!
The texture has the right format and size in memory, in my application I get now the correct values and there are no longer huge rounding errors that were caused, I guess, by the hidden conversion to rgb.
But, for the sake of completeness, I tried RG32F and RGB32F buffer and in those cases I get an error when I try to read the texture values using TexturePeeker :
:gobj(error): Unsupported texture peeker format: rgb32
Thanks for your patience! I think I’ve got a fix for that one as well.
Tested all four possibilities and they all work fine Thank you for your really fast support !