From the documentation of glDrawArrays:
Vertex attributes that are modified by glDrawArrays have an
unspecified value after glDrawArrays returns. Attributes that aren't
modified remain well defined.
I understand that glDrawArrays uses buffer data and some information about how to interpret the data as vertices in order to draw graphics. What I don't understand is how this can result in modifiying vertex attributes.
I am seeing some strange values in my vertex buffer data, after I map it with glMapBufferRange, and I'm trying to track down where the unexpected values could be originating from.
Related
I have a Sphere class that generate the VBO for creating given input radius and some more parameters.
Each Sphere VBO share the same memory layout (let's say vertex indice 0 = vertices, 1 = colors).
I may getting wrong, but if a understand correctly, state is what VAO store. But I don't know if VAO reminds which VBO was bound or use the currently bound VBO. But I think it use the VBO bound when modifying it (so it imply that reconfiguring the VAO for each Sphere render)
Question #1
Is it possible to store on VAO for all of the spheres? Sharing one VAO for multiple VBO.
Question #2
Can we set up the VAO independently from the VBO ? I wanna say, before even creating the VBO and without VBO bound, for example in a static function before even creating Spheres.
Question #3
This question may have non sens and be case-specific, but should I use one VAO and one VBO for each Sphere or share one VAO for all the Spheres (if it's possible) ?
Using the separate attribute format API, it is easy to set up a VAO independently from any particular set of source buffer objects. The vertex format information (component type, count, etc) can all be established via glVertexAttribFormat without a buffer object. You can even set up the relationship between attribute indices and buffer binding points, so that you can read interleaved attributes from a single buffer binding. All without ever binding a buffer object.
Now at the end of the data, you will have to attach buffer objects to the VAO when it comes time to render (via glBindVertexBuffer(s)). And the VAO will store the buffers it was last set with. But you should essentially ignore this. Treat a VAO as if it were just the vertex format state, with buffer binding being something that you do right before you render with it.
And yes, having one VAO and multiple potential buffers that get read with that vertex format (or better yet, just one buffer with multiple mesh data in it that all share the same vertex format, with mesh selection being done via the baseVertex parameter of glDrawElementsBaseVertex) is the right way to go.
All that being said, you also should remember that all spheres are the same mesh. They may appear in different locations with different sizes, but that's just a matter of providing a different transform of a unit sphere. The only reason to use more than one sphere mesh is if you need different resolutions of spheres (more polygons vs. fewer).
I send a VertexBuffer+IndexBuffer of GL_TRIANGLES via glDrawElements() to the GPU.
In the vertex shader I wanted snap some vertices to the same coordinates to simplify a large mesh on-the-fly.
As result I expeceted a major performance boost because a lot of triangle are collapsing to the same point and would be degenerated.
But I don't get any fps gain.
Due testing I set my vertex shader just to gl_Position(vec4(0)) to degenerate ALL triangles, but still no difference...
Is there any flag to "activate" the degeneration or what am I'm missing?
glQuery of GL_PRIMITIVES_GENERATED also prints always the number of all mesh faces.
What you're missing is how the optimization you're trying to use actually works.
The particular optimization you're talking about is post-caching of T&L. That is, if the same vertex is going to get processed twice, you only process it once and use the results twice.
What you don't understand is how "the same vertex" is actually determined. It isn't determined by anything your vertex shader could compute. Why? Well, the whole point of caching is to avoid running the vertex shader. If the vertex shader was used to determine if the value was already cached... you've saved nothing since you had to recompute it to determine that.
"The same vertex" is actually determined by matching the vertex index and vertex instance. Each vertex in the vertex array has a unique index associated with it. If you use the same index twice (only possible with indexed rendering of course), then the vertex shader would receive the same input data. And therefore, it would produce the same output data. So you can use the cached output data.
Instance ids also play into this, since when doing instanced rendering, the same vertex index does not necessarily mean the same inputs to the VS. But even then, if you get the same vertex index and the same instance id, then you would get the same VS inputs, and therefore the same VS outputs. So within an instance, the same vertex index represents the same value.
Both the instance count and the vertex indices are part of the rendering process. They don't come from anything the vertex shader can compute. The vertex shader could generate the same positions, normals, or anything else, but the actual post-transform cache is based on the vertex index and instance.
So if you want to "snap some vertices to the same coordinates to simplify a large mesh", you have to do that before your rendering command. If you want to do it "on the fly" in a shader, then you're going to need some kind of compute shader or geometry shader/transform feedback process that will compute the new mesh. Then you need to render this new mesh.
You can discard a primitive in a geometry shader. But you still had to do T&L on it. Plus, using a GS at all slows things down, so I highly doubt you'll gain much performance by doing this.
I'm starting to learn modern OpenGL, and as the title says, I just wanted to be sure of the purpose of VAO's in the rendering pipeline.
When rendering we use VBO to store datas, and then we use OpenGL functions like: glAttribe to say to the GPU that we are going to use this datas "in That way", like: the first 3 floats in the vertices that we passes through vbo are in fact positions, and the next 3 floats are colors etc... So then I readed that we need some VAO that stores the descriptions of the vertices but what's the goal there ?
Thanks in advance.
Vertex array objects store a set of buffer names (usually vertex and index buffers) to get vertex data from, as well as how the vertices are layed out in the vertex buffers.
Their main purpose is so that when you want to render a different model from a different set of buffers, instead of binding each buffer and then setting the vertex attribute formats each time, you just bind a different VAO, and all the buffers and attributes are set up for you.
Not only is this more convenient for the programmer, it reduces the number of OpenGL calls required and thus CPU usage, which can clear up a CPU bottleneck.
Is there a method for binding only a single attribute of a VBO to a texture buffer object?
Problem is, I use an interleaved VBO for drawing spheres with the attributes position, radius and another one. Now, I want to use another shader which draws other stuff using instanced geometry at the positions in my sphere VBO.
What I could do is just texelFetch() the data I need which is really ugly concerning the needed alignment (VBO attributes have different size) and the unused space, which is bad because of the limited size of a texture buffer. Another way could be copying only the data I need from one VBO to a separate VBO, but that's not really satisfying either.
So... is there another possibility?
Buffer textures do not have attributes. So what you're talking about doesn't make sense.
Also, VBOs are not a thing; there is no such thing as a "VBO". There are simply buffer objects and different uses for them. glVertexAttribPointer does not modify the buffer object. It just tells OpenGL's vertex reading system how to fetch data from it. Other systems that fetch data from buffer objects use their own mechanisms for doing so, which are entirely separate.
Like buffer textures.
If you want to "draws other stuff using instanced geometry", why don't you just use instancing? Apply a divisor (presumably of 1) to those attributes, so that they will only get different values for different instances.
I got code working which uses a VBO and an IBO: as I parse my geometry I build vertex and index arrays for triangles and then call glDrawElements with GL_TRIANGLES.
I read about being able to signal primitive restart in the index buffer, here, about halfway down the page. This is good, but I'm wondering if it's possible to forego the index buffer entirely, and just signal a primitive restart by sending in a specific vertex value (like have the first attribute zero value be infinity)?
Then I'd only need to send one buffer to the GPU before I draw with GL_TRIANGLE_FAN for instance to draw a set of convex polygons.
If you don't want to use index buffer then you can use glDrawArrays. It will render primitive from just the vertex buffer. Combine that with instancing and you'll be able to draw multiple triangle fans without index buffer.
But for performance reasons if your mesh triangles share vertices you should be using index buffer.
As clearly stated on that page:
It is technically legal to use this with non-indexed rendering. You should not do this, as it will not give you a useful result.
Primitive restart is for indexed rendering. There is no way to restart a primitive based on the value of a vertex attribute.