Buffer binding using OpenGL and GLSL - opengl

I wonder if there is a way to bind a Texture Buffer (TBO) Object directly on a certain range of data like it's possible to do using Uniform Buffer object (UBO -> glBindBufferRange).
Actually, I store my matrices within a TBO and to recover each of them within my vertex shader I need to send an 'GLUint' offset as Uniform variable. So, I wonder if it's possible to make a "kind of glBindBufferRange" applied on my TBO. This way I won't need to send each time for each vertex shader the offset where my matrices are stored.
I did a lot of researches on the subject and I did not found any concluding information (just glTexBufferRange but this function does not seem to be used for this purpose...).
Thanks a lot in advance for your help!

Related

Open GL Shader Storage Buffer Objects to replace Vertex Attributes

I basically got the same question as the guy who asked here:
Dynamically sized arrays in OpenGL ES vertex shader; used for blend shapes/morph targets .
Especially his last unanswered question bothers me too.
So I also want to use an arbitrary number of blendshapes for each mesh I'm processing. At the moment I'm using a fixed number and treat the shapes as vertex attribute. The advantage here is that I always have the relevant data for the current vertex availiable. Now, if I want to use an arbitrary number of shapes, I figured I'd use SSBOs since their clue is exactly what I want: Dynamically sized data.
However SSBOs are, as far as I understand it, static and for each processed vertex in the shader I have the blendshape data for the whole mesh availiable. That means I would have to introduce some kind of counter and try to pick the correct data piece out of my SSBO for each vertex.
Is this understanding correct?
I'm really not sure whether this is the optimal solution, maybe you can give me some hints.
Yes your understanding is correct.
You can use gl_VertexID or just pass some 'vertex number' as attribute to know what data to load in your SSBO for the particular vertex you're processing.

Custom Vertex Attributes GLSL

I want to make a couple of vec4 vertex attributes in my shaders. I've done quite a bit of googling, but I can't seem to find consistent information for specifically what I want to do.
My goal here is to move skinning to the GPU, so I need a list of bones and weights per vertex, hence why I want to use vertex attributes. I have 2 arrays of floats that represent this data. Basically this:
weightsBuffer = new float[vSize*4];
indexesBuffer = new int[vSize*4];
The part that I can't consistently find is how to upload these and use them in the shader. To be clear, I don't want to upload all the position, normal and texture coordinate data, I'm already using display lists and have decided to keep using them for a few reasons that aren't relevant. How can I create the buffers and bind them properly so I can use them?
Thanks.
Binding your bone weights and indices is no different of a process than binding your position data. Assuming the data is generated properly in your buffers, you use glBindAttribLocation to bind the attribute index in your vertex stream to your shader variable, and glVertexAttribPointer to define your vertex array (and don't forget glEnableVertexAttribArray).
The exact code may vary, depending on whether you're using VAOs and VBOs (or just client buffers). If you want a more specific answer, you should provide your code and shader.

How do I efficiently handle a large number of per vertex attributes in OpenGL?

The number of per vertex attributes that I need to calculate my vertex shader output is bigger than GL_MAX_VERTEX_ATTRIBS. Is there an efficient way to e.g. point to a number of buffers using a uniform array of indices and to access the per vertex data this way?
This is a hardware limitation so the short answer is no.
If you consider workarounds for other ways, like using uniforms that also got limitations so that is a no way to go either.
One possible way I can think of which is rather hackish is to get the extra data from a texture. Since you can access textures from the vertex shader, but texture filtering is not supported ( you wont need it so it doesn't matter for you ).
With the newer OpenGLs its possible to store rather large amount of data in textures and access them without limitation even in the vertex shader, it seems to be one way to go.
Altho with this approach there is a problem you need to face, how do you know the current index, i.e. which vertex it is?
You can check out gl_VertexID built-in for that.
You could bypass the input assembler and bind the extra attributes in an SSBO or texture. Then you can use gl_VertexID in the vertex shader to get the value of index buffer entry you are currently rendering (eg: the index in the vertex data you need to read from)
So for example in a VS the following code is essentially identical (it may however have different performance characteristics depending on your hardware)
in vec3 myAttr;
void main() {
vec3 vertexValue = myAttr;
//etc
}
vs.
buffer myAttrBuffer {
vec3 myAttr[];
};
void main() {
vec3 vertexValue = myAttr[gl_VertexID];
//etc
}
The CPU-side binding code is different, but generally that's the concept. myAttr counts towards GL_MAX_VERTEX_ATTRIBS, but myAttrBuffer does not since it is loaded explicitly by the shader.
You could even use the same buffer object in both cases by binding with a different target.
If you can not absolutely limit yourself to GL_MAX_VERTEX_ATTRIBS attributes, I would advise using multi pass shaders. Redesign your code to work with data with half set of attributes in first pass, and the remaining in second pass.

Storing per-object data for fragment shader

I have a fragment shader that uses a few uniforms which are set on a per-object basis. Is there a way to store these uniforms on the graphics card somehow? I've heard of (but cannot find a tutorial for) vertex buffer objects--is there a trick to storing the information in there, so that I don't need to re-set the variables every time I draw a new object?
Each object has very few vertices, but they are completely static.
There are indeed Uniform Buffer Objects in later versions of OpenGL http://www.opengl.org/wiki/Uniform_Buffer_Object
If you use the same shader program ID for all the objects, then you can just set the uniforms once before you render your objects as their value will stay the same until you set them again. So e.g. in your code where you load and compile the shader source, set the uniform variables that are common for all the objects, then render your objects, only setting the per-object uniforms.
The uniform buffer idea in one of the answers can be used if you have different shaders for different objects but you want to share some data between them. This is not necessary in your case as you mention a single shader.

OpenGL 3.3, GLSL 1.5: How to setup a Texture Buffer Object containing various texture2D?

I've been wondering whether it is possible to have an array of sampler2D in a GLSL 1.5 vertex shader.
I need to access 30 different 2d-textures from my vertex shader. I read that it is not possible to have a structure like:
uniform sampler2d texture[30];
However, having 30 different uniforms is a bit exaggerated and fairly hard to manage...
So, that brought me to the idea of having a texture buffer object. TBO's are supported since OpenGL 3.0. However, I couldn't find a good tutorial or example, respectively, which shows how to initialize a TBO with not only one texture, but several textures.
This website shows an example on how to initialize a TBO with a single texture. No big deal at all. I think the most important method is
void createTBO(GLuint* tbo, GLuint* tex)
By executing the method
glTexBufferEXT(GL_TEXTURE_BUFFER_EXT, GL_RGBA32F_ARB, *tbo);
one can actually attach the texture to the buffer. This is also mentioned here. I assume calling glTexBuffer 30 times one after the other wouldn't do the trick.
So, I've been thinking if there might be another way of getting the very same result. I came up with two ideas:
Adding the 30 2d-textures to a 3d-texture and attach that directly to the vertex shader. However, that would be a big waste of memory since most of the 3d-texture's layers wouldn't be used.
Using a structure called sampler2DArray. It is mentioned in the specs. However, I searched the web and couldn't find any valuable information about how to implement that.
So, my questions are:
How do I setup a TBO containing more than only 1 texture?
Is that possible at all?
Do you know sources where I could find information about adding 2d-textures to a 3d-texture?
Do you know websites where I could find information about the initializing, binding and usage of sampler2DArray?
I'd be grateful if you could advice me. I'm really a newbie in terms of OpenGL.
Thanks
Walter
I believe you misunderstood what a Texture Buffer Object (TBO) is. A TBO is used to access a buffer object inside a shader, nothing more. It doesn't hold multiple textures or anything like that.
If the textures are of the same size, you can use a 3D texture or a Texture array. A TBO is no use for your problem.
You could use sampler2DArray uniforms. You can use them to pass multiple textures to your shader.
http://www.opengl.org/registry/specs/EXT/texture_array.txt
An alternative solution would be to use a very large tbo and store all textures within the tbo. A Texture can be as large as 11585x11585 texels (2^27)
texture_buffer_object.txt
As Jotschi suggested use one very large texture and adjust texture coordinates accordingly. (or: write a shader that maps standard coordinates to the right place)
This is what's called a texture atlas. I'd guess you can find some implementations by searching for the term.