Having trouble with multiple VBOs with TBO in geometry shader

If you have multiple vertex buffer objects, is it possible to access them simultaneously in the geometry shader? I’m having difficulty with this, and I’ve successfully accessed a single vertex buffer object in the geometry shader by making a texture buffer object and binding it to an active texture unit and setting the samplerbuffer to that unit, but accessing a second texturebuffer on a different texture unit doesn’t work for me.

I’ve populated the buffer and generated textures below

// coordinates
glGenBuffers(1, &coord_id);
glBindBuffer(GL_ARRAY_BUFFER, coord_id);
glBufferData(GL_ARRAY_BUFFER, 3* num_coords * sizeof(float), coord_buff, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

glGenTextures(1, &coord_tex_id);
glBindTexture(GL_TEXTURE_BUFFER, coord_tex_id);
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGB32F, coord_id);
glBindBuffer(GL_TEXTURE_BUFFER, 0);

// displacements
glGenBuffers(1, &disp_id);
glBindBuffer(GL_ARRAY_BUFFER, disp_id);
glBufferData(GL_ARRAY_BUFFER, 3* num_disps * sizeof(float), disp_buff, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

glGenTextures(1, &disp_tex_id);
glBindTexture(GL_TEXTURE_BUFFER, disp_tex_id);
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGB32F, disp_id);
glBindBuffer(GL_TEXTURE_BUFFER, 0);

The output works as expected when accessing this data in the vertex shader (position = coordinates + displacements), but when I try to access the coordinates and displacements in a geometry shader, I’m only able to get valid data from the coordinate sampler and not the displacement sampler. I’m binding/drawing as follows:

// Bind
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, conn_id);

glBindBuffer(GL_ARRAY_BUFFER, coord_id);
glVertexAttribPointer(coord_attrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindTexture(GL_TEXTURE_BUFFER, coord_texture_id);

glBindBuffer(GL_ARRAY_BUFFER, disp_id);
glVertexAttribPointer(disp_attrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindTexture(GL_TEXTURE_BUFFER, disp_texture_id);

// Draw
glDrawElements(GL_TRIANGLES, conn_size, GL_UNSIGNED_INT, 0);

// Unbind...

I’m not sure why/how to properly set this up so I can access both the coordinates and displacements via a samplerbuffer in the geometry shader (only the coordinate sampler gives me any data).

I appreciate any help you may have for this!

You can definitely use multiple TBOs in a shader stage. The setup code looks fine, though I don’t have my code that does TBOs in front of me. Most of your drawing code isn’t necessary, you only need the glAcitiveTexture/glBindTexture calls (no glVertexPointer call required; the glTexBuffer call defines the sampling format). Make sure you have bound both samplers to the proper texture units, as it looks like it should work otherwise. Also, be aware that using RGB32F requires GL4 or ARB_texture_buffer_rgb32, in case you’re also targeting GL3 hardware (use RGBA32F for GL3).

Still trying to sort this out after the Christmas break. I do have GL4 hardware compatible with the RGB32F format, and I’ll try to eliminate the unnecessary drawing calls (but I have to be honest I’m not always sure about what is and isn’t required when the textures/buffers are bound). Thanks for your help, and I’ll try to post an answer if/when I figure this out.

I managed to solve my problem by changing the following code in the geometry shader from:

vec4 c3 = texelFetch(coord_sampler, v3_idx);
vec4 d3 = texelFetch(disp_sampler, v3_idx);
vec4 v3 =  mvp_matrix * (c3 + d3);

to this:

vec3 c3 = texelFetch(coord_sampler, v3_idx).xyz;
vec3 d3 = texelFetch(disp_sampler, v3_idx).xyz;
vec4 v3 =  mvp_matrix * vec4(c3 + d3, 1.0);

Apparently my w was garbage when pulling out data from the sampler.


glTexBuffer(GL_TEXTURE_BUFFER, GL_RGB32F, coord_id);

According to the specs you should get a value of 1 for a missing alpha

The components not stored by the image format are filled in automatically. Zeros are used if R, G, or B is missing, while a missing Alpha always resolves to 1.

According to the specs you should get a value of 1 for a missing alpha

That’s probably the bug then, in the first example v3.w would be 2 and not 1, messing up any perspective divide.