PDA

View Full Version : Render buffer copy



dletozeun
01-30-2008, 10:04 AM
Hello,

I would like to copy data from a render buffer where the scene is drawn, to another which size is the half of the first render buffer.(The buffer is a square which size is a power of 2)

I would want it the more efficient as possible because I need to do this until the destination buffer size is 1x1 for each frame. Moreover, I need that the destination buffer colors are the average of the source buffer.

In fact, my goal is to compute the average color in a buffer.

Thank you for any help.

-NiCo-
01-30-2008, 10:23 AM
Here's one way to do this...

First you have to get the data you rendered into a texture. You can do this by rendering directly into the base level of a mipmap texture using a framebuffer object or use glCopyTexImage with the data you rendered in a renderbuffer.

Once the data is written to the base level of the texture, call glGenerateMipmapEXT(GL_TEXTURE_2D) while the texture is bound to the GL_TEXTURE_2D target.

Finally, read back the texture data value for the mipmap level that corresponds to an image size of 1x1 -> log2(size)

Note that you will have more numerical inaccuracies when performing this operation on channels with a low bit count.

N.

dletozeun
01-30-2008, 11:20 AM
Thank you for your reply,

So, I set up the texture like this :

glGenTextures(1, &img);
glBindTexture(GL_TEXTURE_2D, img);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glGenerateMipmapEXT(GL_TEXTURE_2D);

But then, how do I get the 1x1 texture data in the last mipmap level? I need this information in a shader. I know how I can read texture data in a shader (I don't, with opengl functions), but I don't know how I can access the last mipmap level of the bound texture.

thanks

-NiCo-
01-30-2008, 11:32 AM
GLSL:

vec4 texture2DLod (sampler2D sampler, vec2 coord, float lod)
vec4 texture2DProjLod (sampler2D sampler, vec3 coord, float lod)
vec4 texture2DProjLod (sampler2D sampler, vec4 coord, float lod)

Cg:

float4 tex2Dlod(sampler,float4(coord.x,coord.y,coord.z,lo d))

lod = mipmaplevel

N.

dletozeun
01-30-2008, 11:53 AM
Ok, thank you very much!

Do you know why lod has float type? lod is 0,1,2,...N-1 for a 2^N texture. isn't it?

-NiCo-
01-30-2008, 11:56 AM
It's for performing trilinear filtering when using GL_NEAREST_MIPMAP_LINEAR or GL_LINEAR_MIPMAP_LINEAR. With these parameter settings it interpolates between two mipmaplevels.

N.

dletozeun
01-30-2008, 12:03 PM
Ok I understand! shaders are so powerful...^^

Thanks a lot.

-NiCo-
01-30-2008, 12:12 PM
You're very welcome.

Have fun shading! :)

N.

arekkusu
01-30-2008, 08:48 PM
Be warned that you need either ARB_shader_texure_lod or EXT_gpu_shader4 in order to use *Lod functions in a fragment shader.

dletozeun
02-01-2008, 11:06 AM
Thank you arekkusu for your hint, I did thought about it. I don't have any of the extensions you quoted, but theses one:

GL_EXT_texture_lod_bias
GL_SGIS_texture_lod

May it would work too...I hope. My graphic card is a ATI Radeon Mobility X1600

arekkusu
02-01-2008, 10:10 PM
If you only care about getting the 1x1 level, you can do it with SGIS_texture_lod.
Set GL_TEXTURE_BASE_LEVEL to the 1x1 level, so mipmap sampling is clamped there.
Then you can sample from it normally in the fragment shader (or fixed function, either way.)

You can't change the level per pixel though, with those older extensions. You need the new shader *Lod functions to do that.

arekkusu
02-01-2008, 10:11 PM
Also, Radeon X1600 can support ARB_shader_texture_lod. At least, we export it on Mac OS X. So complain to your driver writers if you don't have the extension.

dletozeun
02-02-2008, 04:45 AM
Thank you arekkusu, I didn't know GL_TEXTURE_BASE_LEVEL, using this is very simple because yes, I only need the 1x1 level. So I don't need any extension to do this.

Yes, I have some problem with the latest proprietary drivers on linux...I will look if this extension is available on windows.