Jump to content

  • Log In with Google      Sign In   
  • Create Account

We need your feedback on a survey! Each completed response supports our community and gives you a chance to win a $25 Amazon gift card!


Possibly corrupt VBO/IBO?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
6 replies to this topic

#1 Blips   Members   -  Reputation: 122

Like
0Likes
Like

Posted 09 August 2011 - 10:26 PM

I'm currently attempting to get vertex buffer objects to work with interleaved data for indexed triangles.

I've manually confirmed that both the index data and the actual vertex data is correct prior to being loaded into their appropriate buffer objects. The array holding the index data is simply an array of unsigned shorts. The vertex array is an array of floats with the following format (with each bracket symbolizing a float):

[vect x][vect y][vect z] [texture u][texture v] [norm x][norm y][norm z] [r g b a]

In total, each vertex in array is a series of 9 floats. I have the following offsets and strides as:

newMesh.vertexOffset = 0;
newMesh.vertexStride = sizeof(GLfloat) * 6;
newMesh.uvOffset = sizeof(GLfloat) * 3;
newMesh.uvStride = sizeof(GLfloat) * 7;
newMesh.normalOffset = sizeof(GLfloat) * 5;
newMesh.normalStride = sizeof(GLfloat) * 6;
newMesh.colorOffset = sizeof(GLfloat) * 8;
newMesh.colorStride = sizeof(GLfloat) * 8;

Here is where and how I create the buffer objects. I was originally using glMapBufferOES() but replaced it with a simpler solution in an attempt to find what is wrong. The arrays being passed into the objects are allocated dynamically, but I'm unsure if I should free them after having passed them to the buffer objects.

glGenBuffers(1, &vertexBufferID);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
glBufferData(GL_ARRAY_BUFFER, vertexBufferSize, vertexBufferList, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

//creating index buffer object
glGenBuffers(1, &indexBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBufferSize, indexBufferList, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

The buffer sizes have been checked and rechecked and are correct. And here is how I actually go about attempting to render the content. It's probably safe to ignore the texture code block but I included it just in case:

glPushMatrix();

glTranslatef(tempMeshInstance.x ,tempMeshInstance.y, tempMeshInstance.z);
glRotatef(tempMeshInstance.rotX, 1.0f, 0.0f, 0.0f);
glRotatef(tempMeshInstance.rotY, 0.0f, 1.0f, 0.0f);
glRotatef(tempMeshInstance.rotZ, 0.0f, 0.0f, 1.0f);
glScalef(tempMeshInstance.scaleX, tempMeshInstance.scaleY, tempMeshInstance.scaleZ);

//binding vertices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tempMeshInstance.meshPtr.indexBufferID);
//binding vertex buffer objects
glBindBuffer(GL_ARRAY_BUFFER, tempMeshInstance.meshPtr.vertexBufferID);
//passing the mesh instance data to OpenGL
glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, tempMeshInstance.material);
glVertexPointer(3, GL_FLOAT, tempMeshInstance.meshPtr.vertexStride, ((char *)NULL + (tempMeshInstance.meshPtr.vertexOffset)));
glTexCoordPointer(2, GL_FLOAT, tempMeshInstance.meshPtr.uvStride, ((char *)NULL + (tempMeshInstance.meshPtr.uvOffset)));
glNormalPointer(GL_FLOAT, tempMeshInstance.meshPtr.normalStride, ((char *)NULL + (tempMeshInstance.meshPtr.normalOffset)));
glColorPointer(4, GL_UNSIGNED_BYTE, tempMeshInstance.meshPtr.colorStride, ((char *)NULL + (tempMeshInstance.meshPtr.colorOffset)));

//working with textures
if (tempMeshInstance.meshPtr.textureID != prevTextureID && tempMeshInstance.meshPtr.textureID != 0) {
	glBindTexture(GL_TEXTURE_2D, tempMeshInstance.meshPtr.textureID);
	//if 2d texturing is disabled, renable it
	if (!glIsEnabled(GL_TEXTURE_2D))
		glEnable(GL_TEXTURE_2D);
} else if (tempMeshInstance.meshPtr.textureID == 0 && glIsEnabled(GL_TEXTURE_2D))
	glDisable(GL_TEXTURE_2D);
prevTextureID = tempMeshInstance.meshPtr.textureID;

//rendering the mesh instance
glDrawElements(tempMeshInstance.meshPtr.renderFormat, tempMeshInstance.meshPtr.indices, GL_UNSIGNED_SHORT, ((char *)NULL + (0)));
//popping the matrix off the stack
glPopMatrix();

//continuing through list
gameObjs = gameObjs.nextNode;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);

And this is the lovely rendering I'm rewarded with:

Posted Image

Which looks nothing like what the actual object used to look like. So in summary, I don't know if the buffer objects are somehow becoming corrupted, or if I'm incorrectly using the buffer objects (strides and offsets?), or if I'm incorrectly creating the buffer objects, but something is clearly wrong.

And clues or hints as to what may be causing this would be more than welcome!

Sponsor:

#2 johnchapman   Members   -  Reputation: 550

Like
0Likes
Like

Posted 09 August 2011 - 11:41 PM

"Stride' should be the same.for each attribite; the size of a whole vertex (sizeof(float) *9 in your case.

Also, how are you counting RGBA as one float?

#3 Blips   Members   -  Reputation: 122

Like
0Likes
Like

Posted 10 August 2011 - 12:34 AM

"Stride' should be the same.for each attribite; the size of a whole vertex (sizeof(float) *9 in your case.

Also, how are you counting RGBA as one float?


Oh I thought stride was spacing in bytes between two like components (so the bytes between two repetitions of normal data for example). I tried treating the one float for the RGBA data as 4 separate bytes, and hoped that OpenGL would be able to work with it given I've specified color to be unsigned bytes. There's a good chance I'll have to change it I'm guessing though.

I'll try making your suggested changes.

#4 mhagain   Crossbones+   -  Reputation: 8287

Like
0Likes
Like

Posted 10 August 2011 - 03:26 AM

Oh I thought stride was spacing in bytes between two like components (so the bytes between two repetitions of normal data for example).


It is, but your understanding of the effect that has on your params seem to be incorrect. If you think about it, the normal data will be at the same offset for each vertex (in fact every component of the vertex will be at the same offset for each vertex - position at 0, texcoords at 12, etc) so the difference between two vertexes will always be the size of your vertex struct.

I tried treating the one float for the RGBA data as 4 separate bytes, and hoped that OpenGL would be able to work with it given I've specified color to be unsigned bytes. There's a good chance I'll have to change it I'm guessing though.

I'll try making your suggested changes.


I'd suggest not trying anything fancy when you're getting something new working for the first time. Do it the slow/more storage/predictable way instead. There's too much going on in this code and you need to be able to isolate errors to specific causes.

It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.


#5 Brother Bob   Moderators   -  Reputation: 8633

Like
1Likes
Like

Posted 10 August 2011 - 03:43 AM

Oh I thought stride was spacing in bytes between two like components (so the bytes between two repetitions of normal data for example).


It is, but your understanding of the effect that has on your params seem to be incorrect. If you think about it, the normal data will be at the same offset for each vertex (in fact every component of the vertex will be at the same offset for each vertex - position at 0, texcoords at 12, etc) so the difference between two vertexes will always be the size of your vertex struct.

Just clarifying here, because the word "between" is often the source of the confusion when misunderstanding the stride. The stride is the distance from the start of one attribute to the start of the next consecutive entry, not the "empty" space between two consecutive attributes (which would be from the end of one to the beginning of the next). If you have a tightly packed array of an interleaved vertex structure, the stride for all attributes is, as mhagain said, simply the size of the vertex itself; no need for fancy calculations with the individual attributes.

#6 mhagain   Crossbones+   -  Reputation: 8287

Like
0Likes
Like

Posted 10 August 2011 - 09:57 AM

Just clarifying here, because the word "between" is often the source of the confusion when misunderstanding the stride. The stride is the distance from the start of one attribute to the start of the next consecutive entry, not the "empty" space between two consecutive attributes (which would be from the end of one to the beginning of the next). If you have a tightly packed array of an interleaved vertex structure, the stride for all attributes is, as mhagain said, simply the size of the vertex itself; no need for fancy calculations with the individual attributes.


Said it better than I did.

It's actually easier if you use a struct for your vertexes rather than a float array - you'll see the layout in your code clearer, reduces potential for error, offsets are just a small bit of pointer arithmetic, and you can use sizeof (mystruct) for your stride param.

It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.


#7 Blips   Members   -  Reputation: 122

Like
0Likes
Like

Posted 10 August 2011 - 10:31 AM

Just clarifying here, because the word "between" is often the source of the confusion when misunderstanding the stride. The stride is the distance from the start of one attribute to the start of the next consecutive entry, not the "empty" space between two consecutive attributes (which would be from the end of one to the beginning of the next). If you have a tightly packed array of an interleaved vertex structure, the stride for all attributes is, as mhagain said, simply the size of the vertex itself; no need for fancy calculations with the individual attributes.


Said it better than I did.

It's actually easier if you use a struct for your vertexes rather than a float array - you'll see the layout in your code clearer, reduces potential for error, offsets are just a small bit of pointer arithmetic, and you can use sizeof (mystruct) for your stride param.


Yeah I'm already working on changing the small program I wrote converting Wavefront files to binary files to use structs rather than an array of floats. Then I'll do the same changes to the actual game!

Thanks guys for help and clarification. It's really appreciated.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS