1

Assuming I only want to render quads and can reuse my mesh, I would like to be able to, in a single draw call, render many instances.

I would like to achieve this with a texture buffer object by placing transformation matrices into the buffer.

I understand how to setup a texture buffer object in C++, but am confused on how to grab my transformations from this in GLSL.

uniform samplerBuffer sampler;
...
... = texelFetch( sampler, index );

In the above code (in a vertex shader) I'm not sure how the samplerBuffer keyword works (and have had a lot of trouble finding documentation). I would like to know which index in the texture buffer a given vertex is associated with, this way a transformation lookup can occur. How can I do this, and what would the GLSL syntax look like?

It can be assumed that the transformation matrices are 4x4 matrices. I was hoping to be able to keep the OpenGL version requirements in the 2.XX range.

Edit: So I found this: http://www.opengl.org/registry/specs/ARB/draw_instanced.txt. I can deal with a 3.0 limitation. However I'm getting confused when looking up examples of how to use this. Using GLEW, I suppose I would call glDrawElementsInstanced, but some places on the internet are saying this requires OpenGL version 3.3 or later. How can I take advantage of the 3.0 requirement I linked?

1
  • You can also use Uniform buffers which are much more suitable for multiple vector and matrix blocks upload. Commented Dec 10, 2013 at 18:35

2 Answers 2

3

Well, a buffer texture is essentially a 1D array of data stored in a buffer object's (TEXTURE_BUFFER) data store. You provide a single integer, which is essentially an offset into the buffer and fetch a single texel with texelFetch starting at that offset. The offset always refers to a texel, not to a single component (e.g. the R-component of a vec4) of a texel. Therefore, if you setup the buffer texture with an internal format GL_R, you'll look up a single texel which only stores a single value - however, if you're using GL_RGBA a texel will consist of four components.

For instance, suppose you choose to put two normalized color vectors with RGBA components into the data store, choose the internal format GL_RGBA and index with 0 and 1, you'll get the first and the second texel from the buffer texture, as per section 8.9 of the core OpenGL 4.4 spec:

[..]the attached buffer object’s data store is interpreted as an array of elements of the GL data type corresponding to internalformat. Each texel consists of one to four elements that are mapped to texture components (R, G, B, and A).

Note that texelFetch will always return a gvec4, that is, an ivec4, uivec4 or vec4 depending on the internal format. If you choose an internal format which specifies less than four components, for instance GL_R32F, the result will be an unnormalized (<- that's important!) vec4(R, 0, 0, 1) - the remaining GB components are set to zero and A to 1. See table 8.15 of the aforementioned spec for a complete overview.

Also note that texelFetch does not perform any filtering or LOD clamping.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot for the answer. I also made a minor edit to my question at the bottom, perhaps you could help with this? I'm just confused as to version requirements.
Instanced rendering became core in GL 3.1, so anything concerning that functionality, including corresponding draw calls, are to be supported by a GL 3.1 conformant implementation. If you're stuck with GL 3.0, you can still check if GL_ARB_draw_instanced is available and simply use the ARB version. If you want to know for sure what's new in a GL version, check the appropriate appendix - for GL3 it's appendices F through I in the core GL 3.3 spec.
2

All versions of texelFetch returns gvec4 so I assume you should perform a 4 lookups, 1 for each row. But that depends on how you encoded your matrix.

uniform samplerBuffer sampler;
...
mat4 transform( texelFetch( sampler, RowIndex0 ), texelFetch( sampler, RowIndex1 ), texelFetch( sampler, RowIndex2 ), texelFetch( sampler, RowIndex3 ) ); 

Keep in mind that mat4 in GLSL takes columns in the constructor, so you need to transpose that if you are working with Column based matrices.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.