I was reading: Dissecting Display, Chapter 1. Hello, Triangle!.
What exactly does glEnableVertexAttribArray do? I think it enables the use of a given VBO, but I am not sure.
I thought that is what glEnableClientState(GL_VERTEX_ARRAY) did.
I have been reading: Dissecting Display, Chapter 1. Hello, Triangle!.
Then please read the next page; I explain exactly what it does there ;)
If I may quote myself:
We assigned the attribute index of the position attribute to 0 in the vertex shader, so the call to glEnableVertexAttribArray(0) enables the attribute index for the position attribute. [...] If the attribute is not enabled, it will not be used during rendering.
It's similar to a vertex array but stores additional extra values for each point rather than it's coordinates. You might want to store a temperature, density, signal strength at each point in a modelling app for example, or perhaps a damage value for a game
There is another way to specify data for a vertex attribute, the non-array way:
khronos: glVertexAttrib
In this way, we specify data for only one vertex, this data will be replicated for all vertices.
To use non-array data, call glDisableVertexAttribArray.
To use array data, call glEnableVertexAttribArray.
Related
I'm writing an OpenGL application, and the problem I'm facing now is as follows:
Let us say I have a Vertex Array, with its ID. However, I do not have its bound vertex buffer ID at hand. I am in need of the Buffer ID for an operation. SO, is it possible to retrieve current buffer binding from vertex array?
Note that I have come across glGetIntegerv, however I think it only retrieves current buffer binding, NOT vertex array binding
Let us say I have a Vertex Array, with its ID. However, I do not have its bound vertex buffer ID at hand.
In a well-behaved application, that should not be possible. It was your application that put that buffer into that VAO. Therefore, you should already know what buffer is attached to it. It's a question you don't need to ask.
However, if you have no other choice but to ask OpenGL a question that you ought to know the answer to, you must first bind the VAO to the context. If you're not using the separate attribute format API, then you can use glGetVertexAttribiv with GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, specifying the attribute index you're interested in querying. If you want to use the separate attribute format API, you need to use glGetIntegeri_v with GL_VERTEX_BINDING_BUFFER, specifying the binding index to query.
If you're using DSA (which requires using the separate attribute format), then you can use glGetVertexArrayIndexediv, with GL_VERTEX_BINDING_BUFFER and the appropriate binding index.
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.
Refer to "Explicit vs Automatic attribute location binding for OpenGL shaders"
If I do not explicitly bind the attributes using glVertexAttribPointer, what default locations will be used?
Where can I find the official link for it?
Are you asking how generic attributes in a GLSL shader will be assigned to attribute slots (locations)?
That is completely implementation defined if you do not do it yourself. Some will scan the vertex shader and assign them locations in alphabetical order, others will assign them slots based on the order they appear in, but none of this behavior is required. It could be completely random and change every time you run your program for all you know.
That is why you either explicitly bind vertex attributes to a location before linking, or query the location afterwards.
I think you might be mixing up a couple of different concepts. The question you link is about how locations are assigned to attributes in the vertex shader. glBindAttribLocation() or glGetAttribLocation() are used for that purpose.
glVertexAttribPointer() on the other hand specifies where the data for a attribute comes from, together with some related state of the attribute (type, stride, etc). The specific attribute it works on is given by its location, which is passed as the first argument of the call.
Now, if you never call glVertexAttribPointer() for an attribute, there are a few possible scenarios:
An attribute array is not enabled for the attribute. This happens if glEnableVertexAttribArray() was never called for the attribute, or glDisableVertexAttribArray() was last called. In this case, the current value of the attribute is used, which is the value set with calls like glVertexAttrib4f(), with a default value of (0.0f, 0.0f, 0.0f, 1.0f).
If the attribute array is enabled, the default values correspond to a call of:
glVertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE, 0, NULL);
If you have a VBO bound, this could be valid, since the last argument is a relative offset into the buffer.
If you don't have a VBO bound, the draw call will most likely crash, since it will try to source vertex data from the given pointer address, which is NULL.
All of this can be found in the official OpenGL spec documents, which are accessible at https://www.opengl.org/registry/.
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] (...)
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.