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.
Related
Let's say I create two vertex buffers, for two different meshes.
(I'm assuming creating separate buffers for separate meshes is how it's usually done)
Now, let's say I want to draw one of the meshes using an index buffer.
Looking at the book Practical Rendering and Computation with Direct3D 11 it doesnt seem like the creation of an index buffer in any way references a vertex buffer, so how does the index buffer know (during input assembly) what vertex buffer to act on?
I've done some googling without answers, which leads me to assume there's something obvious about it that I'm missing.
You are right, index buffers do not reference specific vertex buffers. During DrawIndexed active index buffer is used to supply indices into active vertex buffers (the ones you set using SetIndexBuffer/SetVertexBuffers).
Indeed, Index Buffers and Vertex Buffers are completely independent.
Index buffer will know about VertexBuffer at draw time (eg: when both as bound to the pipeline)
You can think of Index Buffer as a "Lookup Table", where you keep a list or elements indices to draw.
That also means you can attach two completely "logically unrelated" buffers to the pipeline and draw it, nothing will prevent you from doing that, but you will of course have some strange visual results.
Decoupling both has many advantages, here are a few examples:
You can reuse an index buffer (for example, two displaced grids with identical resolution can share the same index buffer). That can be a decent memory gain.
You can draw your Vertex buffer on it's own and do some processing per vertex (draw a point list for sprites for example, or apply skinning/displacement into a Stream Output buffer , then draw the resulting vertex buffer using DrawIndexed)
Both Vertex/Index buffers can also be bound as ByteAddressBuffer, so you can also process your geometry in Compute Shader, and build another optimized index buffer, with culled triangles for example, then process the Indexed Draw with the optimized buffer. Applying those culls in with indices instead of vertices is often faster than vertex, as you will move much less memory.
This is a niche case, but sometimes I have to draw a mesh as a set of triangles, but then draw as a set of lines (some form of wireframe). If as example, you take a single Box, you will not want to draw the diagonals as lines, so I have a shared Vertexbuffer with box vertices, then one IndexBuffer dedicated to draw triangle list, and another to draw line list. In case of large models, this can also be an effective memory gain.
I know it is very basic question but I have array of vertices and texture coordinates and corresponding buffers:
glBindBuffer(GL_ARRAY_BUFFER,vertexbuffer);
glBufferData(GL_ARRAY_BUFFER,sizeof(float)*Loader.verticesFixed.size(),&Loader.verticesFixed[0],GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER,texturebuffer);
glBufferData(GL_ARRAY_BUFFER,sizeof(float)*Loader.texturesFixed.size(),&Loader.texturesFixed[0],GL_STATIC_DRAW);
and I wonder how to send data for rendering.
I know that I can merge array of vertices and textures so that I have one array that has x1,y1,z1,u1,v1,x2,y2,z2,u2,v2... then create buffer for this array, bind it and use glVertexAttribPointer with particular stride and offset and attributes 0 and 1 for vertices and texture coordinates and glDrawArrays. However I wonder if it is possible to send data from multiple buffers without merging arrays.
I am asking this because I want to add textures to 3d model and if I understood everything correctly to do it efficiently I need to send data to shader using glVertexAttribPointer with different indices (locations) together with uniform texture.
I'm guessing you want to send your data like this : x1,y1,z1,x2,y2,z2....u1,v1,u2,v2...
I actually don't really know if that's possible but I think it would be rather inefficient anyway. When you have your data interleaved, you have everything you need for one vertex in one place, you have the position and right next to it you have the texture information, you dont have to "jump" to find the texture coordinates. I don't know if openGL actually works this way, it's just an assumption.
However, for sending texture information to a shader, using the "normal interleaved" way is just fine. You would then have to bind your texture with
glBindTexture(GL_TEXTURE_2D,texture_id); before making you draw call.
In the vertex shader you would then access the texture position of the vertex just like you would access the position information with layout (location = 1) in vec2 TexCoord;
For example if your data is arranged like x1,y1,z1,u1,v1,x2,y2... then you set the "location" yourself when you call
glVertexAttribPointer(location,2,GL_FLOAT,GL_FALSE,stride,(GLvoid*)(3*sizeof(GLfloat)));
glEnableVertexAttribArray(location);
I hope I cleared some things up. If you are new to texturing in OpenGL, or OpenGL in general, I recommend http://learnopengl.com/#!Getting-started/Textures
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.
I'm currently wrapping my head around how to efficiently render polygons within a vertex buffer in back-to-front order to get transparency working..
I got my vertex buffers and index buffers set up, doing glDrawElements rendering and everything works nicely except transparency cause i currently render in arbitrary (the order the objects were created) order..
I will later implement octree rendering, but this will only help in the overall vertex-buffer-rendering order (what vertex buffer to render first), but not the order WITHIN the vertex buffer..
The only thing I can think of is reorder my index buffers every time i do a camera position change, which feels terrible inefficient since i store around 65.000 vertexes per vbo (using a GLushort for the indexes to achieve an optimal vbo size of around 1-4MB)..
Is there a better way to order vertexes in the vertex buffer object (or better phrased the corresponding indexes in the index buffer object)?
There are two methods for that (I have not used any of them myself though)
Peeling (dual peeling) http://developer.download.nvidia.com/SDK/10/opengl/src/dual_depth_peeling/doc/DualDepthPeeling.pdf
Stochastic Transparency
http://www.cse.chalmers.se/~d00sint/StochasticTransparency_I3D2010.pdf
Also if your objects are convex peeling can be easily implemented by first drawing back faces and front faces (using GL_CULL_FACE and inverting normals for correct lighting in a shader)