*BaseVertex and gl_VertexID - opengl

I've skimmed through the specs and OpenGL forum but couldn't really make sense of this:
Are the *BaseVertex version of the drawing commands supposed to add to the GLSL variable gl_VertexID? As it works, gl_VertexID contains the index taken from the the bound ELEMENT_ARRAY_BUFFER before basevertex is added to it.
So, my question is: Is this the correct behavior? I would assume that gl_VertexID should contain the index used to fetch the vertex.

Yes this is the correct bahviour. The usage scenario of BaseVertex is, that you have to switch only this one value, instead of adjusting the buffer offsets into the vertex arrays with the gl*Pointer functions.
The idea is, that you can load the data from multiple meshes (model files) into a single VBO, without the need to adjust the indices.

Your assumption is right. gl_VertexID should include BaseVertex offset.
opengl wiki about GLSL built-in vars:
Note: gl_VertexID​ will have the base vertex applied to it.
about glDrawElementsBaseVertex:
The gl_VertexID​ passed to the Vertex Shader will be the index after being offset by basevertex​, not the index fetched from the buffer.
Unfortunately, some old drivers didn't implement it correctly.

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 to pass to a vertex-shader dynamic data that should apply for all vertices?

I've a simple program that draws an object, and I want its position to ultimately respond to user-input.
I've tried to create a buffer object with just 2 GLfloats to hold the position and pass it in location 1, and learned that it only affects the first vertex (which actually makes sense, now that I think about it).
I've thought about using uniforms but it doesn't seem to be the correct way either (I've read that changing them can be slow).
What's the approach to this in OpenGL 3/4?
You can achieve this either by using uniforms or vertex attributes. I would suggest using a vertex attribute in the event that you ever want the vertices to have a unique value per-vertex. You can achieve that simply by supplying a vertex pointer instead of a constant vertex attribute.
The following command applies a constant value to every instance of a vertex attribute:
glVertexAttrib{1|2|3|4}f[v] (...)

"Empty" rendering with openGL

specs: Radeon 3870HD w/ openGL 3.3 & GLSL 1.5
I am rendering data through computational shader. Because of dependencies I had to put all my data to uniform textures and nothing left for attributes. Only value that change per primitve is index and I can get this one from gl_VertexID. But I'm having problem with setting up proper render call, looks like if there are no attribute pointers set the render doesn't even run, setting pointer but not storage results in error(ofc..). Setting storage isn't empty rendering ;). Is there any way to render this setup?
Yeah and I forgot some important things..
I render with:
glDrawArrays(GL_POINTS, 0, elements);
and the reason I think it doesn't run shader is because query on processed primitives results 0.. Setting some dummy attribute pointer with data results in right number of primitives...
I had the same issue with ATI. In order to bypass it I'm using any accessible buffer for a dummy 1-byte per vertex input array (not used by the 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.