1
\$\begingroup\$

I'm having trouble rendering some of my meshes; some display just fine, some are drawn wrong or not at all.

While troubleshooting I was looking at the openGL docs (http://www.opengl.org/sdk/docs/man3/) and on the topic of glBufferSubData the following line caught my eye:

Clients must align data elements consistent with the requirements of
the client platform, with an additional base-level requirement that an offset
within a buffer to a datum comprising N bytes be a multiple of N.

I am buffering vertex + normal and index data like this:

glGenBuffers(1, &mVBO);
glGenBuffers(1, &mIndexBuffer);
glGenVertexArrays(1, &mVAO);

// buffer vertex, normals and index data
glBindVertexArray(mVAO);
glBindBuffer(GL_ARRAY_BUFFER, mVBO);
glBufferData(GL_ARRAY_BUFFER, (vertexData.size() + normalData.size()) * sizeof(float), NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, NULL, vertexData.size() * sizeof(float), &vertexData[0]);
glBufferSubData(GL_ARRAY_BUFFER, vertexData.size() * sizeof(float), normalData.size() * sizeof(float), &normalData[0]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexData.size() * sizeof(uint32_t), &indexData[0], GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(vertexData.size() * sizeof(float)));

// unbind array buffer and VAO
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);

So for the vertex and normals I first allocate the complete buffer using glBufferData and then fill it in using glBufferSubData. My question then is, according to the docs, do I need to align the offset my normal data, and if so with what? Is this what couldve caused some meshes to draw incorrectly?

\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

First of all that quote you give doesn't really apply to glBufferSubData itself, but to the actual buffer data at a whole when used (by whatever GL functions that actually work on the buffer object, like drawing from a VBO), since glBufferSubData doesn't have any notion of any multi-byte data types yet, it just copies a bunch of bytes around. Only when doing something meaningful with the buffer data (e.g. using it as vertex attribute source) you finally give meaning (and corresponding alignment requirements) to the data.

So in your case you have a buffer that you use as an array of 3-component 32-bit float vectors (as specified by the glVertexAttribPointer calls). So both your position and normal data (and the corresponding offsets specified in glVertexAttribPointer) have to be properly aligned at GLfloat boundaries, which they already are (given that GL's GL_FLOAT type has the same size and alignment as C++'s float type, which is virtually always the case). So you don't have to worry about alignment issues in your example and your errors are caused by something else.

\$\endgroup\$
2
  • \$\begingroup\$ ah so the alignment mentioned is simply for the data type. I was worried because I recall in arcsynthesis.org/gltut/Illumination/Tutorial%2012.html the author mentions glBindBufferRange has an additional opengl-implementation alignment aswell (something like 64 bytes) \$\endgroup\$ Commented May 2, 2013 at 13:17
  • 1
    \$\begingroup\$ @KaiserJohaan That is a completely different problem and doesn't have anything to do with glBindBufferRange itself, but with uniform buffer objects specifically and how the implementation aligns multiple uniform blocks inside a uniform buffer object. So in this case using the buffer as a uniform buffer requires offsets to be properly aligned for uniform blocks, while in your case it requires the offsets (in glVertexAttribPointer) to be properly aligned for attribute data (float[3] in your particular case). \$\endgroup\$ Commented May 2, 2013 at 13:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .