The Stack Overflow podcast is back! Listen to an interview with our new CEO.
11

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 ...


11

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 ...


10

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 ...


7

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 ...


6

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 ...


5

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, ...


5

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 ...


5

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 gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer); // Pass the vertex data to ...


5

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 = ...


5

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 ...


4

You can put the data into a data uri to store the data inline in base64 format. "buffers": { "a-buffer-id": { "byteLength": 1024, "type": "arraybuffer", "uri"="data:application/octet-stream;base64,..." } }, It's still a bit bloated compared to storing the data in a binary file though.


4

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 ...


4

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. glGenBuffers(1, &VBO_xzCoord_IDs[i]); glGenBuffers(1, &VBO_yCoord_IDs[i]); glGenBuffers(1, &VBO_indices_IDs[i]); ...


4

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 ...


4

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.


3

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 ...


3

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.


3

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: //in init glBindVertexArray(vao); glVertexAttribFormat(posAttrLoc, 3, GL_FLOAT, false, offsetof(Vertex, pos)); // set the details of a single attribute glVertexAttribBinding(posAttrLoc, 0); // ...


3

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. "buffers": { "a-buffer-id": { "byteLength": 1024, "type": "arraybuffer", "uri"="data:application/octet-stream;base64,..." } },


3

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): { "accessors": { "accessor0": { "...


3

Also check out the glTF models used in Cesium: https://github.com/AnalyticalGraphicsInc/cesium/tree/master/Apps/SampleData/models https://github.com/AnalyticalGraphicsInc/cesium/tree/master/Specs/Data/Models Patrick


2

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: supermurdoc.gltf duck.gltf etc. pp.


2

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 ...


2

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 ...


2

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; glGenBuffers(1, &points_vbo); glBindBuffer(GL_ARRAY_BUFFER, points_vbo); ...


2

I don't know what language that is, but I'm going to hazard a guess that the arrays points and gl.Ptr([]float32{0.5,0.5,0.0}) are not the same size. If you intend to provide per-vertex colors, then you must provide one color for every vertex. If you want to provide a single color that all vertices share, then that would be a uniform, not a vertex shader ...


2

gl.vertexAttribPointer is used when different vertices should have different values, and gl.vertexAttrib is used when all vertices should have the same values, and you don't want to use a special shader with a uniform.


2

VAOs are essentially 'plumbing' objects that help get data from your buffers into your vertex shader ready for drawing. On the GPU this is handled by the vertex fetch stage, so a VAO is basically just a bundle of vertex fetch state corresponding to a particular model. You can think of it as a bundle of pointers, but with somewhat more complexity than CPU-...


2

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 ...


2

I think you're seeing cache effects. The GPU will begin vertex processing for each strip in sequential order, and in configuration 1 the GPU will fetch a different chunk of memory for each triangle in the strip (since, as you said, the strips themselves are not contiguous in memory in this configuration). If I understand correctly, each entry in the ring ...


Only top voted, non community-wiki answers of a minimum length are eligible