0

I'm not sure that my question is clear enough so here the explanations : I'm working on a voxel engine using opengl, it's working fine but I want to improve it a bit with some optimisations. I started to use VBO for the vertices of the cube, I earn some fps so that's great. But now I want to do the same thiong with the color of the cube and I didn't find an answer that please me because I have specifics needed :

  • I only use 3 float for the color, so even if it works glVertexAttribPointer() doesn't seems to be a good way to go because if I use it I'll need to use 108 float per cube against 3.

  • I want to draw MANY cubes so use glUniform3f isn't good neither because send 3 float per cubes would be really slow with many cubes to draw.

So with the context my question is, is there a way to store values in the memory of the GPU (like a VBO) and when I draw the cube I would only tell to the shader where are those values ?

Thanks for reading, and may be answering :)

Rahotop
  • 35
  • 3
  • You could for example sort your cubes by color and then use uniforms for color/texture. – dari Sep 19 '15 at 11:16
  • First of all, a color should be 3 bytes, not 3 floats, this saves you 75%. You could sort them, but you could also do a lookup in a color table, this reduces your data to the number of different colors. For instance, if you specify just 256 colors, you can assign a color to each vertex for only 1 byte, 3 times less info than the color itself. You can also draw the cubes with instanced rendering, and then provide one color for each instance, or better yet, one index to a color for each instance. These are all possible options, question is: how much OpenGL do you know? Do the colors ever change? – Henk De Boer Sep 19 '15 at 11:31
  • Sort the cubes by color is a good idea, I didn't think about it, so thanks :). – Rahotop Sep 19 '15 at 11:44
  • Using 108 values per cube implies that you use 36 vertices. You shouldn't. You should use at most 24, and indexing. For your real problem: use instanced rendering, and only store one color value per cube. – derhass Sep 19 '15 at 11:44
  • Also I use floats because for glsl a color is defined by 3 values between 0.0 and 1.0, so use 3 bytes instead of 3 floats means that I'll need to do x/255. 3 times per vertices thus i'm not sure that increase performances. And about my knowledge of Opengl I know how to draw things but I don't know many advance functions. The color may change for some cubes but not often (may be once all the 10 seconds max). And how can I decrease 36 vertices to 24 ? – Rahotop Sep 19 '15 at 11:57

1 Answers1

0
glVertexAttribDivisor(attribute, 1)

tells OpenGL that #attribute has one value per primitive, not per vertex. If you increase the number from 1 to N you can have 1 value for every N primitives. Useful for specifying a color (or anything else) once rather than repeating.

Also glDrawArraysInstanced/glDrawElementsInstanced might be useful. Both these draw a set of points/lines/triangles N times, and in your shader you can use gl_InstanceID as an integer which will count cube/whatever #0, #1, …

Hope this helps

Hugh Fisher
  • 2,321
  • 13
  • 8
  • If I understood well this could be the best option. I'm just not sure about how I must use it, I mean what is attribute ? and like others opengl functions I think that I must bind an object but which one ? with which glBind ? – Rahotop Sep 19 '15 at 12:46
  • OK if you don't understand what an attribute is, buy yourself a copy of the OpenGL SuperBible and start reading! There is no point in trying to optimise any program if you don't understand how the underlying system works – Hugh Fisher Sep 19 '15 at 23:52
  • I read a tutorial about Opengl 3.3 but it's really incomplete I mean the author explain how to start with Opengl but that's all. So even with only the basics I know that an attribute is the index of an Opengl objet, the thing i did not understand is what object must I send his index here ? Naturally I would say that I have to send the index of the vbo of the color but I'm not sure of that, so is that right ? – Rahotop Sep 20 '15 at 08:08
  • Oh no I was misunderstanding, the index is location of the input in the shader like `in vec3 in_vertex` So to use glVertexAttribDivisor() I need to write something like : `glBindBuffer(GL_ARRAY_BUFFER, colorVBO);` `glVertexAttribDivisor(1, 1);` if the color is the second input. – Rahotop Sep 20 '15 at 08:59