3
$\begingroup$

To start, this is my VBO Data Struct:

//-----------------------------------------------------------------
struct Vertex
//-----------------------------------------------------------------
{
    //-----------------------------------------------------------------
    Vertex()
    : x(0), y(0), z(0), 
      s(0), t(0)
    //-----------------------------------------------------------------
    {}

    //-----------------------------------------------------------------
    Vertex(Vertex& rhs)        
    : x(rhs.x), y(rhs.y), z(rhs.z),
      s(rhs.s), t(rhs.t)
    //-----------------------------------------------------------------
    {}

    // Position
    float x;
    float y;
    float z;

    // Texture Coords
    float s;
    float t;
};

I am reading a lot of tutorials and all seem to submit the color of their polygons with the VBO to the GPU. However, if you ever change the color, you need resubmit the data to the GPU. Why is that so common, when you can bind the color via an uniform? Isn't that heaps and bounds faster? One could argue that you need to bind the color then for each Polygon or at least Sprite or Model, depending on what you are doing, if you use the same shader for each of them, which is common practice.

So I am confused how to design my (learning) 2D Game from the ground up. Should I put the 4 floats (r,g,b,a) into the VBO and add it to the layout or simply keep changing it via glUniform4fv? Is there a best practice for this?

$\endgroup$
2
$\begingroup$

If the color needs to vary per vertex, it will need to be an attribute in the vertex buffer. If it's acceptable to have the color be constant per draw call, then by all means make it a uniform.

By the way, editing a vertex buffer and resubmitting data to the GPU, while certainly slower than updating a uniform, doesn't have to be a huge inefficiency. By using GL_DYNAMIC_DRAW when you set up the buffer, combined with using glMapBufferRange and GL_MAP_INVALIDATE_BUFFER_BIT to update it, the driver can manage the buffer memory and transfers efficiently. That's how you would typically do a particle system, for instance, with the particles' positions, colors, etc. changing every frame. Furthermore, if only one or two vertex attributes need to change, you can split those off into their own buffer to decrease the total data updated.

$\endgroup$
  • $\begingroup$ Thanks! That first part was the important information for me. I missed this information in the Tutorials. Since I use textures, I only use color to "tint" Quads (Sprites), if you know what I mean, or to alter transparency via the alpha channel. So using a uniform was a good hunch. I am still stuck on matrices and how to do them properly on the GPU, but I am getting there. $\endgroup$ – BadSnowflake May 24 '17 at 22:08
1
$\begingroup$

To have a attribute have a certain values for a subset of vertices in the draw call you need to duplicate the data. You can only change uniforms between draw calls and you will want to minimize the number of draw calls if possible.

That duplicated bit of data is likely not going to be significant overhead. Most textures will be much larger than that.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.