5

I have a simple 2d triangle displayed on the screen, I want to update the color buffer data every frame, so the color of the triangle changes constantly, but im not sure how to update the data efficiently.

this is the code for the color buffer:

GLfloat colourVert[] = {
        0.0f, 1.0f, 0.0f,
        1.0f, 0.0f, 0.0f,
        0.0f, 0.0f, 1.0f
    };



GLuint colourBuffer;
glGenBuffers(1, &colourBuffer);
glBindBuffer(GL_ARRAY_BUFFER, colourBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(colourVert), colourVert, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);

Do I need to add something in these lines or do I need to modify the shaders, can someone explain please, thanks for any help.

lucasyyy
  • 63
  • 1
  • 1
  • 4
  • 1
    You should decide which type of OpenGL you want since the answer will largely depend on this. And please also state which version. For example, es 3.0 uses VAOs to store attribute bindings while 2.0 doesn't. – BDL Jan 21 '17 at 21:49
  • @BDL In IOS opengl es 2.0 fully supports VAOs but not Android – Sung Jan 22 '17 at 22:56
  • glMapBuffer seems like the correct solution: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glMapBuffer.xhtml – Asad-ullah Khan Jul 15 '20 at 03:15

1 Answers1

9

You should definitely not generate a new buffer every frame. Just reuse the already existing one. Also setting up attribute pointers can also be done just once since they are stored in the VAO. The only two lines actually necessary are glBindBuffer and glBufferData (or even better use glBufferSubData since this will reuse the allocated memory instead of allocating a new memory segment).

Note, that this answer only applies to OpenGL 3.3 Core (and newer) and OpenGL-ES 3.0 (and newer). For OpenGL versions that don't support/require VAOs, the attribute setup might also have to happen in every frame.

BDL
  • 21,052
  • 22
  • 49
  • 55
  • It doesn't matter whether using VAO or not. Either case, we need to update only VBOs not VAOs – Sung Jan 22 '17 at 23:06
  • @Sung: I never said that you have to update the VAO. I said: "If you use VAOs, you shouldn't call `glVertexAttribPointer` every frame since this settings is stored in the vao state". – BDL Jan 22 '17 at 23:09
  • you said "Also setting up attribute pointers can also be done just once since they are stored in the VAO" "Note, that this answer only applies to OpenGL 3.3 Core (and newer) and OpenGL-ES 3.0" your premise is he is using VAO which doesn't need to be mentioned. – Sung Jan 22 '17 at 23:16
  • Maybe I don't understand your point. If op is using OpenGL 3.3 Core or opengl-es 3.0, then he definitely uses VAOs since it is mandatory. If he is using, e.g., OpenGL 2.x, he might be using VAOs, but could also not use them. If VAOs are not used, then the attribute setup might have to happen every frame depending on whether the attribute points are changed during the frame (when drawing, e.g., multiple objects). – BDL Jan 22 '17 at 23:22
  • And just for completeness: iOS supports VAOs in opengl es 2.0 through the `GL_OES_vertex_array_object` extension. As you might want to check, this is not part of the [es 2.0 standard](https://www.khronos.org/registry/gles/specs/2.0/es_full_spec_2.0.25.pdf). – BDL Jan 22 '17 at 23:26
  • Ok now I got it why you asked the OGL version but still I think VAO doesn't matter because to update VBOs glVertexAttribPointer() is called and you think we must not call glVertexAttribPointer() when using VAO but I believe calling glVertexAttribPointer() whether using VAO or not, still works well to update VBOs in a VAO when using VAO . I tested it in Linux, OSX and windows OpenGL 3.3+ – Sung Jan 22 '17 at 23:32
  • No, VAO is not the extension in IOS. Apple officially supports VAO in OpenGL ES 2.0 but in Android, it is – Sung Jan 22 '17 at 23:35
  • Unless the structure of the buffer changed, for example by changing from 3d vectors to 4d vectors, the vertex attribute setup doesn't have to be changed. `glVertexAttribPointer` just describes the layout of a buffer, but has no relation to the buffers content. You might want to read [this post](http://stackoverflow.com/questions/27911630/how-should-i-update-a-vertex-array-object-when-i-update-a-vertex-buffer-object-i) which explains this quite well. – BDL Jan 22 '17 at 23:42
  • That is what I am saying. glVertexAttribPointer() is not required to update buffers when using VAOs. However, even if we use this function with VAO. it doesn't emit errors and nothing changed so VAO doesn't matter in this question. – Sung Jan 22 '17 at 23:48
  • 1
    It's worth pipelining your buffer updates if you want to avoid memory allocation. If you use the same buffer every frame it's likely that you will have queued rendering work holding references to the existing contents of the buffer, so even though there is no explicit memory allocation, you probably get one anyway because the driver will insert one. In general you want to (at least) double-buffer your VBOs between frames, so you get two frames between uses. This minimizes the chances of driver allocation. – solidpixel Jan 23 '17 at 11:19
  • 1
    See https://community.arm.com/graphics/b/blog/posts/mali-performance-6-efficiently-updating-dynamic-resources for a more detailed explaination of the above. – solidpixel Jan 23 '17 at 11:20