Could someone ELI5 to me, what is an index buffer and how is it
related to vertex buffers
Your vertex buffer contains the X and Y coordinates of 5 vertices. They are:
index | X | Y
0 | 0.0 | 0.0
1 | 1.0 | 0.0
2 | 0.0 | 0.6
3 | 1.0 | 0.6
4 | 0.5 | 1.0
Your index buffer contains information about which lines to draw between these ...
In general, when you render an object in an immediate mode—issuing line drawing commands for instance—you build up a series of commands that you submit to the graphics card to draw. If you're drawing a lot of data, or drawing very frequently, you can waste a lot of time sending this data over and over again.
A vertex buffer allows you to produce a single ...
This will vary between implementations, but the driver I worked on did use these, mainly to decide memory layout. The optimizations enabled by these hints are much smaller than you would like, mainly because of the restriction that you can do any use whatever hints you give. e.g. it would make cache invalidation a lot cheaper if buffers hinted for read ...
There are two steps that make the VBO more efficient than immediate mode.
Immediate mode (glBegin/glEnd, glVertex*, etc.) means that at each frame, you spoon feed the vertices, attribute per attribute (position, normal, color, etc.), to the driver, which then reformats them and finally sends the whole package as a command to the GPU. That a lot of function ...
While creating a set of glTF models for a tutorial, I also intended to create THE minimal glTF file.
Update: The following referred to glTF 1.0/1.1. See below for an update of this example to glTF 2.0.
As already mentioned in the answer by 5chdn, one issue may be the material. According to the Appendix A: Default Material of the specification, an asset ...
By using an immediate mode interface (e.g. old style OpenGL glBegin()/glEnd()/glVertex()) you're effectively drip feeding data to the driver one piece at a time. It then has to take that single piece of data, reformat it and pass it on to the hardware (which these days means putting it into a command buffer).
By using a vertex buffer object, you're ...
Since you are new to computer graphics, you may be better off avoiding the complications of SIMD and sticking with the traditional 'create a CPU thread + collect results' approach, or even run in the main thread if the task is lightweight enough.
But if that approach fails to be performant and/or you are willing to dip into OpenCL / GLSL compute shaders, ...
If you have a vertex buffer like this:
var vertices = [
0.0, 0.0, 0.0,
1.0, 0.0, 0.0,
0.0, 0.6, 0.0,
1.0, 0.6, 0.0,
0.5, 1.0, 0.0
And simply draw it as it is:
// Create an empty buffer object
var vertex_buffer = gl.createBuffer();
// Bind appropriate array buffer to it
// Pass the vertex data to ...
Functionally they are the same.
The driver could use them to differentiate how to handle the buffer behind the scenes. Where for example static_draw would be copied to vram as soon as possible and left there but stream_read would have a op to date copy in RAM at all times.
This vagueness is the reason that glBufferStorage became a thing. That way you ...
Deleting an OpenGL object is merely a suggestion. Deleting an object will unbind the object from any binding point it is currently bound to. However, buffer objects are not "bound" to VAOs. They are attached to VAOs.
When you call glVertexAttrib*Pointer, you attach a buffer object to the VAO. The buffer object to be attached is the one bound to ...
Vector has a few different semantics from static arrays. For one it's a struct containing a pointer a capacity and a length (at the very least). That means that sizeof will not reflect how much data is actually stored in there (that only works on static arrays).
If you need to get the size in bytes of the data then you need
const UINT vertexBufferSize = ...
With OpenGL I would have to reload whole vertex VBO's.
No you wouldn't. You can use glBufferSubData
I suppose with Vulkan there could be a way to directly access VBO's to only change/add/remove the changed vertex data
If you know the memory layout of the vertex buffer, you can find the offset of the contents you want to change, populate a transfer ...
You can put the data into a data uri to store the data inline in base64 format.
It's still a bit bloated compared to storing the data in a binary file though.
VAO can share VBO's because they do not store vertex data itself but references to Vertex Buffer Objects.
So you can first generate your buffers and upload your buffer data (vertex data and index data) to currently bound buffers.
A VAO holds the attribute information. This means that for each attribute it has a buffer, offset, size, type, stride and whether it's normalized. Separately from those is the element buffer binding that is set by binding the GL_ELEMENT_ARRAY_BUFFER while the VAO is bound.
Yes that odd but the reason this is the case is because VAO's were added after VBO ...
How I call glVertexAttribPointer for the GL_ELEMENT_ARRAY_BUFFER buffer?
You don't. The element array buffer is used to store vertex indices, not vertex attribute data and therefore it doesn't have attribute pointers. The count, size, and offset for index data is specified in the draw call, e.g. glDrawElements.
Many game engines have texture streaming, which means that not all mip levels of each texture are loaded at all times. The game engine will track which textures are in view and how close up they are seen, and will dynamically load and unload mip levels in an attempt to provide enough detail for the current view, while staying within a fixed VRAM budget.
It depends. There are a few competing factors at work here.
First, consolidating terrain data into fewer buffers (or one) may allow you to combine multiple terrain patches together in a single draw call—assuming there aren't other state changes between patches that would prevent this. So, you may be able to reduce draw-call overhead this way, or at least ...
Yes you can, this is how deferred rendering for example would work. For that you would render to a texture in one pass, in openGL this would be via an FBO, then feed that texture as the input to the next pass/shader.
In version 4.3+ the vao layout can be set independently from the VBO buffer which allows you to rebind the vbo without having to call vertexAttribPointer every time:
glVertexAttribFormat(posAttrLoc, 3, GL_FLOAT, false, offsetof(Vertex, pos));
// set the details of a single attribute
Embedding human readable data is not supported. However you can put the data into a data uri to store the data inline in base64 format.
After spending a hard time to understand the way how the binary buffers work in the gltf files I finally managed to generate a truely minimal gltf file. It's a single yellow triangle (demo).
I tried to remove everything which is not needed from the gltf. This is what is required it seems (github):
Also check out the glTF models used in Cesium:
tl;dr The vao caches the calls to glVertexAttribPointer et. al.
Every call to glVertexAttribPointer, glEnableVertexAttribArray and the binding of gl_Element_Array will store the parameters into the currently bound vao. In the case of glVertexAttribPointer it will also store the current binding to GL_VERTEX_ARRAY in the vao.
This is a major help when ...
There is a difference between "can" and "should".
You "should" not use glBufferData to change the size of an existing non-immutable buffer. You can still do so, but don't expect this to be advantageous.
You "can" not change the size of an immutable buffer with any function.
How do I replace the whole VBO with my new data, but if my new data is smaller ...
Ok sometimes you have to ask a question to figure out the answer already.
Example datasets are available in the same repository as linked in the question already.
Here are some:
In addition to @russ' answer, I was able to decode the buffer with the gltf Utilities.
let uri = "data:application/octet-stream;base64,AAABAAIAAwACAAEABAAFAAYABwAGAAUACAAJAAoACwAKAAkADAANAA4ADwAOAA0AEAARABIAEwASABEAFAAVABYAFwAWABUAAAAAvwAAAL8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAL8AAAA/AAAAPwAAAL8AAAC/AAAAvwAAAL8AAAC/...
The information you're looking for is defined in the 'accessors' and 'bufferViews' near the top of the source file you linked.
Bufferviews simply divide the buffer up into sub ranges and define broadly what kind of data lives there using some obscure shortcodes. In this case, target 34963 means index data and 34962 means vertex data. So from the other ...
Each VAO, and shader for that matter, has a separate space of attribute locations. It's perfectly fine to have multiple shaders use the same attribute locations. Indeed, it's a good idea to do so if those attributes conceptually mean the same thing to both shaders.
A VAO can be used with a shader if that VAO's attribute locations match those the program ...
Yes, VAO state includes vertex attribute specification for multiple attributes. Each attribute has its own format information and can come from a distinct buffer object. That's part of why you can only bind one VAO at a time.
// two VBOs but one VAO
GLuint points_vbo = 0;