PDA

View Full Version : texelFetchBuffer()



debonair
09-26-2012, 06:00 AM
Hi,
I am newbie in OpenGL and need some help in texelFetchBuffer().

The second parameter is specified as index into texel array. But i am not able to understand how to use this function and the indexes.
I goggled it, but didn't get much info how to use it.
Please help me..

thokra
09-26-2012, 06:36 AM
Well, it's a one-dimensional buffer so index is simply in [0, elements * sizeof(type) - 1].

debonair
10-01-2012, 12:02 AM
Well, it's a one-dimensional buffer so index is simply in [0, elements * sizeof(type) - 1].
Thank you so much for the reply..

Now there is one more problem. I am passing vec3 attribute array to vertex shader with z component as a index into pixel array of texture for each corresponding vertices.
GLfloat vertices[] =
{
-0.9f, -0.6f, 0.0f,
-0.9f, -0.9f, 1.0f,
-0.6f, -0.9f, 2.0f,
-0.6f, -0.6f, 3.0f
};
Here z component is index into GLfloat pixels[]={0.0f,1.0f,0.0f,1.0f, 0.0f,0.0f,1.0f,1.0f, 1.0f,1.0f,1.0f,1.0f, 1.0f,0.0f,1.0f,1.0f}; My texture is of RGBA type.
Now in vertex shader:
out int index=int(a_position.z);

and fragment shader:
vec4 offset=texelFetch(out_offset,index);
Color = offset;
Now i am drawing GL_Traingle_fan and when i execute it, it draws square with 2 triangles one with white color and second with pink color. It is taking 3rd and 4th offset in pixel array instead taking each index for each vertex.


I want to draw square with each vertex having color of each index in pixels array. Please correct me where i am going wrong above..

thokra
10-01-2012, 01:00 AM
First of all, let me correct my previous statement: [0, elements * sizeof(type) - 1] is not the range the indices will be in. Of course, it's simply [0, 1, ..., elements - 1]. It is true, however, that bufferSize = elements * sizeof(type) and that the real offset into the buffer is calculated by sizeof(type) * index.

Regarding your current issue: Why don't you simply fetch the color at the vertices where the indices are unique and uninterpolated? Simply move your fetch to the vertex shader and have the GPU interpolate the colors not the indices. I'm actually not sure at the moment how int values are interpolated but obviously they are not what you want afterwards.

debonair
10-01-2012, 01:31 AM
First of all, let me correct my previous statement: [0, elements * sizeof(type) - 1] is not the range the indices will be in. Of course, it's simply [0, 1, ..., elements - 1]. It is true, however, that bufferSize = elements * sizeof(type) and that the real offset into the buffer is calculated by sizeof(type) * index.

Regarding your current issue: Why don't you simply fetch the color at the vertices where the indices are unique and uninterpolated? Simply move your fetch to the vertex shader and have the GPU interpolate the colors not the indices. I'm actually not sure at the moment how int values are interpolated but obviously they are not what you want afterwards.

Now, i moved my texelFetch() to fragment shader and passing the fetched texel from vertex to fragment shader. But vertex shader gives compilation failure
"ERROR: 0:10: error(#202) No matching overloaded function found texelFetch
ERROR: 0:10: error(#160) Cannot convert from 'const float' to 'default out 4-component vector of float'
ERROR: error(#273) 2 compilation errors. No code generated"

My vertex shader:
in vec3 a_position;
uniform float offset_x;
uniform isamplerBuffer out_offset;
out vec4 offset;
void main()
{

offset=texelFetch(out_offset,a_position.z,0);
gl_Position = vec4(a_position.x + offset_x, a_position.y, 1.0, 1.0);

}

Let me know where i am going wrong

thokra
10-01-2012, 01:52 AM
Oh man. :)

Try the following code and compare it with your code to see how many errors slipped into your version. BTW, speaking of code, use '
...'' tags please the next time.



in vec3 a_position;
uniform float offset_x;

// that buffer has nothing to do with offsets. it stores colors, name it accordingly.
// also, your buffer stores float values, so make it a floating point sampler.
uniform samplerBuffer color_buffer;

// likewise for the vertex color
out vec4 vertex_color;

void main()
{
// texelFetch on buffer samplers takes only 2 arguments
vertex_color = texelFetch(color_buffer, int(a_position.z));

gl_Position = vec4(a_position.x + offset_x, a_position.y, 1.0, 1.0);
}


This should work. Can't test atm.

debonair
10-01-2012, 01:59 AM
Oh man. :)

Try the following code and compare it with your code to see how many errors slipped into your version. BTW, speaking of code, use '
...'' tags please the next time.



in vec3 a_position;
uniform float offset_x;

// that buffer has nothing to do with offsets. it stores colors, name it accordingly.
// also, your buffer stores float values, so make it a floating point sampler.
uniform samplerBuffer color_buffer;

// likewise for the vertex color
out vec4 vertex_color;

void main()
{
// texelFetch on buffer samplers takes only 2 arguments
vertex_color = texelFetch(color_buffer, int(a_position.z));

gl_Position = vec4(a_position.x + offset_x, a_position.y, 1.0, 1.0);
}


This should work. Can't test atm.

forgot to typecast float to int :) thanks for that ..
Now, it draws white square. Dono why does it taking index 3 for all the vertices .. :(

thokra
10-01-2012, 02:10 AM
I hope you didn't forget to adapt the fragment shader to the new vertex shader, i.e. something like that



in vec4 vertex_color;
out vec4 frag_color;

// ...

void main()
{
// ...
frag_color = vertex_color;
}

debonair
10-01-2012, 02:16 AM
I hope you didn't forget to adapt the fragment shader to the new vertex shader, i.e. something like that



in vec4 vertex_color;
out vec4 frag_color;

// ...

void main()
{
// ...
frag_color = vertex color;
}


I did check it, but still same issue.. :(

thokra
10-01-2012, 02:24 AM
Please post both your vertex and fragment shader and you buffer setup code, both for geometry and colors.

debonair
10-01-2012, 02:38 AM
Please post both your vertex and fragment shader and you buffer setup code, both for geometry and colors.

My code:
vertex shader:


in vec3 a_position;
uniform float offset_x;
uniform isamplerBuffer out_offset;
out vec4 offset;
void main()
{
offset=texelFetch(out_offset,int(a_position.z));
gl_Position = vec4(a_position.x + offset_x, a_position.y, 1.0, 1.0);

}


Fragment shader:


out vec4 Color;
in vec4 offset;
void main()
{

Color = offset;
}


buffer setup code:


GLfloat pixels[]={0.0f,1.0f,0.0f,1.0f, 0.0f,0.0f,1.0f,1.0f, 1.0f,1.0f,1.0f,1.0f, 1.0f,0.0f,1.0f,1.0f};
GLfloat vertices[] =
{
-0.9f, -0.6f, 0.0f,
-0.9f, -0.9f, 1.0f,
-0.6f, -0.9f, 2.0f,
-0.6f, -0.6f, 3.0f

};
glGenBuffers(1,&bufferid);
nResult = GL_ERROR_CHECK((GL_NO_ERROR,"glGenBuffers(1,&bufferid)"));
glBindBuffer(GL_TEXTURE_BUFFER,bufferid);
nResult = GL_ERROR_CHECK((GL_NO_ERROR,"glBindBuffer(GL_TEXTURE_BUFFER,bufferid);"));

glBufferData(GL_TEXTURE_BUFFER,sizeof(pixels),pixe ls,GL_STATIC_DRAW);
nResult = GL_ERROR_CHECK((GL_NO_ERROR,"glBufferData(GL_TEXTURE_BUFFER,sizeof(vert),vert,* value);"));


glGenTextures(1, &buffer_texture);
nResult = GL_ERROR_CHECK((GL_NO_ERROR,"glGenTextures(1, &buffer_texture);"));


glActiveTexture(GL_TEXTURE0);
nResult = GL_ERROR_CHECK((GL_NO_ERROR,"glActiveTexture(GL_TEXTURE0);"));

glBindTexture(GL_TEXTURE_BUFFER, buffer_texture);
nResult = GL_ERROR_CHECK((GL_NO_ERROR,"glBindTexture(GL_TEXTURE_BUFFER, buffer_texture);"));

glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, bufferid);
nResult = GL_ERROR_CHECK((GL_NO_ERROR,"glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, bufferid);"));


glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
nResult = GL_ERROR_CHECK((GL_NO_ERROR,"glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);"));

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
nResult = GL_ERROR_CHECK((GL_NO_ERROR,"glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);"));


attr_vertex = glGetAttribLocation(shader_data.psId, "a_position");
nResult = GL_ERROR_CHECK((GL_NO_ERROR,"glGetAttribLocation(shader_data.psId, \"a_position\");"));
glVertexAttribPointer(attr_vertex, 3 , GL_FLOAT, GL_FALSE ,0, vertices);
nResult = GL_ERROR_CHECK((GL_NO_ERROR,"glVertexAttribPointer(attr_vertex, 3 , GL_FLOAT, GL_FALSE ,0, 0);"));
glEnableVertexAttribArray(attr_vertex);
nResult = GL_ERROR_CHECK((GL_NO_ERROR,"glEnableVertexAttribArray(attr_vertex);"));


glDrawArrays(GL_TRIANGLE_FAN,0,4);

thokra
10-01-2012, 05:39 AM
Before going further, could you please clarify which of the buffer setup stuff is done in which function? The draw call appears to be right next to the setup functions. Can you please post complete functions, including headers? Or simply your whole program?

One thing I can definitely say is that you don't need filtering setup:


glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);


"Why not?" you might ask. Well, first of all, you modify state for the target GL_TEXTURE_2D but your buffer texture has its own state and target: GL_TEXTURE_BUFFER. Therefore, you do absolutely nothing for your buffer texture with the above calls. Furthermore, buffer textures aren't filtered anyway so setting up filters is useless.

Other than that, the setup of the buffer looks ok.

debonair
10-01-2012, 05:55 AM
Before going further, could you please clarify which of the buffer setup stuff is done in which function? The draw call appears to be right next to the setup functions. Can you please post complete functions, including headers? Or simply your whole program?

glBufferData(GL_TEXTURE_BUFFER,sizeof(pixels),pixe ls,GL_STATIC_DRAW);
this function is storing the bufferdata i.e. pixels[] in this case. After that glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, bufferid); attaches the buffer to texture "bufferid".



One thing I can definitely say is that you don't need filtering setup:


glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);


"Why not?" you might ask. Well, first of all, you modify state for the target GL_TEXTURE_2D but your buffer texture has its own state and target: GL_TEXTURE_BUFFER. Therefore, you do absolutely nothing for your buffer texture with the above calls. Furthermore, buffer textures aren't filtered anyway so setting up filters is useless.

Other than that, the setup of the buffer looks ok.
Also, i removed filtering modes. i was unaware that they are useless in texbuffer.
Just ignore all GL_ERROR_CHECK() calls as they are just for error checking purpose.

thokra
10-01-2012, 06:08 AM
glBufferData(GL_TEXTURE_BUFFER,sizeof(pixels),pixe ls,GL_STATIC_DRAW);
this function is storing the bufferdata i.e. pixels[] in this case. After that glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, bufferid); attaches the buffer to texture "bufferid".

I'd be in the wrong place helping you if I wasn't aware of that. :)

What I need is your actual program code, the complete functions including the headers (argument list, return type, function name etc.) so I can see what's going on in your program. Best to simply post the complete code if it fits here.