Each glDraw* is a draw call.
1 glDrawArrays is 1 draw call.
1 glDrawElements is 1 draw call.
It doesn't matter (so far as draw call count is concerned) how many vertices or indices you use, 1 glDraw* is 1 draw call.
The simple cases of drawing quads (assuming the GL version you use hasn't removed quads) or triangles are not a good example for comparing ...
There are a number of different techniques for organizing the data, and many games use a mix of them.
For static geometry, it's best to have fewer individual IBs and VBs.
Traditionally games are 'level' based which means the assets for a section of play are loaded and then the game play begins. To minimize load-times, the information is ideally organized ...
The GL_ARB_vertex_buffer_object specification (which all buffer objects are based on) notes:
Note that it is expected that implementations may have different memory type requirements for efficient storage of indices and vertices. For example, some systems may prefer indices in AGP memory and vertices in video memory, or vice versa; or, on systems where ...
Multiple vertex buffers would be used when your data is non-interleaved. If your data was interleaved then you'd put it all in one vertex buffer. (You can also have vertex data partially interleaved and partially not. For instance, all the positions could be in one buffer, and all the other attributes - normals, UVs, etc. - interleaved in another buffer.)
No it is not.
The input to the shader pipeline expects a "stream" of vertices. So say you're using DRAW_TRIANGLES (or whatever it is) what actually happens is this:
Create 3 buffers (these are your varyings) of sufficient size
Fetch vertex (attributes) and put them in the input to the vertex shader
Run the vertex shader
Transfer varyings output ...
Using directx you must draw triangle meshes. If your mesh data contains quads, then create an index buffer that indexes each quad as two triangles and draw by calling DrawIndexed. For example if you have vertex1,vertex2,vertex3,vertex4 which describes a quad then index them by 0,1,2,0,2,3 or according to the desired winding order.
The example you use of a cube is a very specific, and somewhat contrived, one where indexing does not provide it's full benefit. For most real-world examples the constraints you mention do not exist, and indexing has been demonstrated - for approx 20 years - to be effective. This is something that goes back to at least Quake 3 in 1999:
Quake3’s rendering ...
If you set up an project with your idea, - what you want to archive as a final result. You also need to question yourself, how to structure different data. With the question you asked, everything can be a buffer. Just because their is no limit of what you can do, and what you what to be done as a project. A Buffer for Keyboard input or for previous mouse ...
You really don't want to read from buffers because you never know where it is in the pipeline and you will normally end up with +20ms of GPU-CPU synchronization.
Even with a copy to a staging resource marked for reading you will still have a large stall if the buffer is still in use on the GPU before you copy it to the staging resource.
If you need access ...
Basically, there is Vertex data, which is stored in one or more VBOs. Typical (3D) vertex has like: vec3 pos, vec2 uv, mat3 tbn (or vec3 normal) - maybe some other modifiers, possibly several different uv coords or something like that. Anyways, no matter if you store those to 1 or multiple VBOs, IBO will index all the buffers with same index.
So, each pos/...
This question comes up a lot in relation to the .obj model format, and the answer is that yes: you can only have a single index buffer, but it works with both interleaved and non-interleaved data.
For the non-interleaved case I'm assuming that you're thinking of a case where the data is fully de-duplicated (again, like .obj). What's important to realise ...
There is not ideal way of doing it, this is a common problem with meshes. To solve this there, are two different approaches:
Considering that you have a vertex that has to be used with two different textures coordinates here is how you can approach the problem:
1:Duplicate the vertex and assign to each one the different texture coordinates. As a result you ...
The problem is that obj files contain vertex data in parts:pos,tex,normal and indices in them point to each of these parts individually.
In OpenGL you need to combine those parts into one data object - vertex.
And have your indices point to vertices, not their parts.
My code (scala, but should be ok)
val vertexListB = new RList[vec3]()//output positions
First to ensure all vertices are rendered:
Ensure that backface culling is disabled with GlDisable(GL_CULL_FACE)
Disable depth testing glDisable(GL_DEPTH_TEST) OR ensure you are clearing the depth buffer bit before drawing glClear(GL_DEPTH_BUFFER_BIT)
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),&vertices, GL_STATIC_DRAW);
The best way I have found to do terrain texturing is using color maps to splat textures, with this method the only vertex info you need is a float3 for the vertex positon as there is no need to pass in texture cords.
First up you draw around your terrain using each color channel for a different texture.
Red = beach
Green = under water
Blue = ...
This is the idea how to upload data to gpu:
void *vbo = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
memcpy(vbo, indices, byteSize);
I think DMGregory has answered part of this, timing test of 16 vs 32 definitely needs to be done. BUT, the performance is also dependent on the needs of your scene also. The 65536 indice limitation does mean that now you may need to deal with multiple objects to composite a more complicated > 65536 indice model. Which means different different calculations ...
It could possibly make sense if you try to draw something like a huge polygon, or some sort of sphere, where the edges connect. This is really inefficient, since the index buffer is most probably going to be bigger than the saved space, but it is possible.
Conclusion: It is possible, but doesn't make sense for any to me known application.
First convert the obj mesh to a non-indexed mesh with vertex+normal+other attributes.
Then convert back to indexed by merging identical vertex entries.
The 2nd step can be made generic to be re-used for other mesh format loaders and indexing procedurally generated meshes.
glVertexAttribDivisor wouldn't help you: it is used to specify an attribute per model instance.
If you draw 10 instances of a house model of 1000 vertices, then you can use the divisor to set a value (for tranform, colour, etc.) per instance.
If I were you, I would draw my geometry non-instanced, thus use glDrawArrays() instead of glDrawElements().
Finally, I found what the problem is.
My indeces is an array which type is int, so during my render period, I should set my index buffer format 32byte such as Format.R32_UInt, rather than Format.R16_UInt. After I update the format that related to the indexbuffer and , bingo, the problem is solved.
As I have done what you are trying to do, ala quad tree and splitting into chunks. A couple of things.
For optimal performance, I have found that keep the vertex list as one buffer. Do your quadtree split on the indices. What this does is your indices dont have to be rebuilt and reflect the true index of the vertex in your mega buffer.
NOW, if you ...
You're crashing because you unbind.
If you check your creation code, you'll see that _eboBuffer is first bound. At this stage _eboBuffer is stored in your VAO and all is well. Then at the end you unbind _eboBuffer, at which stage it's no longer stored in your VAO.
Unbinding, in general, is something that's actually not necessary and I would discourage it ...
Vertices can only be merged when every single attributes are the same.
A vertex can have the same position as another without having the same UV, color, or differ in other attributes.
You can still use an index buffer to merge the vertices of triangles making up each individual hexagons (7 vertex instead of 18 to make a nice pie with a center, or 6 (...
Creating the vertices is quite easy. You already have the x and z component, the y component is the height in your heightmap with the given position. You probably want to scale this somehow as heights are often expressed as value between 0 and 1. For the indices you just have to visualize for yourself how the triangles will be made up. You need two triangles ...
You're generally better off using plain triangles and an index buffer to draw multiple fans (and other shapes) in a single draw call.
It's easier on the GPU/driver in terms of draw call and some drivers/GPUs have to break down the indexed fan into indexed triangles before drawing by regenerating the index buffer on the fly.
The small amount of memory ...
You can look at the legacy DirectX SDK Direct3D 9 sample Pick or the Direct3D 10 sample Pick10.
Generally you don't actually want to use the same geometry to render as you do for doing collision detection. Most games will first use simple bounding geometry like spheres, axis-aligned boxes, oriented-boxes or cylinders and make decisions from that.
If after ...
(Edited my question as I now read that your input is one big slab of data)
If your input is one big slab of data like [vertexvertexvertex... indexindexindex] you're better off calculating the pointers to the start of the vertex data and the start of the index data and passing those as buffers to OpenGL then to load the entire thing. OpenGL might wish to ...
You need to reindex the mesh, something like this:
for(int i = 0; i < positionIndices.size(); i++)
v.pos = ...