Why doesn't glDrawElements work on Nvidia?
I'm trying to use glDrawElements, and it works fine on my ATI9800 pro, and my friends X300, and some rubbish intel card at uni, but when I test my program on Nvidia cards it crashes. I tried it on two different GeForce FX 5200's and a Quadro4 380 XGL.
Anyone have any other problems with this, I don't see why it shouldn't work as it's not an extention specific to ATI.
Thanks.
Works here on GF2, with va and vbo.
VA:
VBO:
VA:
if( vertex_array ) { glEnableClientState( GL_VERTEX_ARRAY ); glVertexPointer( 3, GL_FLOAT, 0, cast(void *)vertex_array ); } if( normal_array ) { glEnableClientState( GL_NORMAL_ARRAY ); glNormalPointer( GL_FLOAT, 0, cast(void *)normal_array ); } if( texcoord_array ) { glEnableClientState( GL_TEXTURE_COORD_ARRAY ); glTexCoordPointer( 2, GL_FLOAT, 0, cast(void *)texcoord_array ); } glDrawElements( primitivetype, index_array.length, GL_UNSIGNED_SHORT, cast(void*)index_array ); glDisableClientState( GL_VERTEX_ARRAY ); glDisableClientState( GL_NORMAL_ARRAY ); glDisableClientState( GL_TEXTURE_COORD_ARRAY );
VBO:
if( vertex_buffer ) { glEnableClientState( GL_VERTEX_ARRAY ); glBindBufferARB( GL_ARRAY_BUFFER_ARB, vertex_buffer ); glVertexPointer( 3, GL_FLOAT, 0, null ); } if( normal_buffer ) { glEnableClientState( GL_NORMAL_ARRAY ); glBindBufferARB( GL_ARRAY_BUFFER_ARB, normal_buffer ); glNormalPointer( GL_FLOAT, 0, null ); } if( texcoord_buffer ) { glEnableClientState( GL_TEXTURE_COORD_ARRAY ); glBindBufferARB( GL_ARRAY_BUFFER_ARB, texcoord_buffer ); glTexCoordPointer( 2, GL_FLOAT, 0, null ); } glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, index_buffer ); glDrawElements( primitivetype, index_count, GL_UNSIGNED_SHORT, null ); glDisableClientState( GL_VERTEX_ARRAY ); glDisableClientState( GL_NORMAL_ARRAY ); glDisableClientState( GL_TEXTURE_COORD_ARRAY );
here's my code
I'm in the process of converting to VBO's, just about to test them... I'll get back to you on that.
void C3dMesh::draw(Cmaterial *mat){ if (texCoord) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, mat->tex); glTexCoordPointer(2, GL_FLOAT, 0, texCoord); } glMaterialfv(GL_FRONT, GL_AMBIENT, mat->ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat->diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, mat->specular); glMaterialf (GL_FRONT, GL_SHININESS, mat->shininess); glVertexPointer(3, GL_FLOAT, 0, vertices); glNormalPointer(GL_FLOAT, 0, normals); glDrawElements(GL_TRIANGLES, numFaces * 3, GL_UNSIGNED_INT, indices); if (texCoord) { glDisable(GL_TEXTURE_2D); } }
I'm in the process of converting to VBO's, just about to test them... I'll get back to you on that.
Are you enabling the respective client states needed for VA operation? You don't seem to be in that code. Also, are there actually num_faces * 3 indices in the array? If not, it'll cause a crash.
Yeah, I previously enable all the arrays and there are the right number of indices. Like I said, it works fine on most cards except Nvidia.
I got a VBO working on Nvidia, so just in the process of converting all to VBO's now. Which is also giving me more hassle. sigh...
I got a VBO working on Nvidia, so just in the process of converting all to VBO's now. Which is also giving me more hassle. sigh...
glDrawElements() is an absolutely vital API call, and a core part of any existing 3D rendering engine. The chances of it exhibiting such a hard bug in such a simplistic setup are very, very slim - in fact approaching the impossible. It would've been discovered a long time ago.
The chance that this is a bug in your code is something like 99.99%. Nvidia is known to be much more intolerant to invalid input than ATI. If you reference an out of range index on nvidia, for example, you will get a crash with almost 100% certainty, while ATI drivers often simply ignore it.
So I'd recommend checking the data you feed to the API.
The chance that this is a bug in your code is something like 99.99%. Nvidia is known to be much more intolerant to invalid input than ATI. If you reference an out of range index on nvidia, for example, you will get a crash with almost 100% certainty, while ATI drivers often simply ignore it.
So I'd recommend checking the data you feed to the API.
*kisses his ATI card*
wow, and i was gonna switch to nvidia... my VBO md2 code would be so screwed if it was on an nvidia card (as it still doesnt work haha)
-Dan
wow, and i was gonna switch to nvidia... my VBO md2 code would be so screwed if it was on an nvidia card (as it still doesnt work haha)
-Dan
u have somethingelse enabled
eg
perhaps this is somewhere in your code
glEnableClientState( GL_COLOR_ARRAY );
if u then call
glTexCoordPointer(2, GL_FLOAT, 0, texCoord);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glNormalPointer(GL_FLOAT, 0, normals);
it will crash in nvoglnt.dll <- this is what u see
prolly its another texcoord arry that u have enabled (to see whats enabled at the time see gldebugger/glintercept)
failing that check the arrays are large enuf,
eg
perhaps this is somewhere in your code
glEnableClientState( GL_COLOR_ARRAY );
if u then call
glTexCoordPointer(2, GL_FLOAT, 0, texCoord);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glNormalPointer(GL_FLOAT, 0, normals);
it will crash in nvoglnt.dll <- this is what u see
prolly its another texcoord arry that u have enabled (to see whats enabled at the time see gldebugger/glintercept)
failing that check the arrays are large enuf,
Thanks zedzeek and Yann. I'd fixed it by the time i read your posts but you confirmed what I had found and was confused about.
I've converted it to VBO's now, but I was still having some (i.e. loads of) problems, then I noticed that the texture array was still enabled when i wasn't using it (just like you thought zedzeek). Also, I was testing it on my machine (ATI) and it was running fine but crashing on my friends laptop (Nvidia), so thanks for clearing that up for me Yann.
I can see I'm going to have to be much more careful testing my stuff now, but at least i know where to look first when i get problems. And to think, I used to love Nvidia!
In case anyone is intersted heres my new code, and my frame rate went from ~400 to ~550..
Thanks again you guys.
I've converted it to VBO's now, but I was still having some (i.e. loads of) problems, then I noticed that the texture array was still enabled when i wasn't using it (just like you thought zedzeek). Also, I was testing it on my machine (ATI) and it was running fine but crashing on my friends laptop (Nvidia), so thanks for clearing that up for me Yann.
I can see I'm going to have to be much more careful testing my stuff now, but at least i know where to look first when i get problems. And to think, I used to love Nvidia!
In case anyone is intersted heres my new code, and my frame rate went from ~400 to ~550..
void C3dMesh::draw(Cmaterial *mat){ if (texCoord) { glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, mat->tex); glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboTexCoord); glTexCoordPointer(2, GL_FLOAT, 0, (char *)NULL); } else { glDisable(GL_TEXTURE_2D); glDisableClientState(GL_TEXTURE_COORD_ARRAY); // YOU BUGGER!!!! } glMaterialfv(GL_FRONT, GL_AMBIENT, mat->ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat->diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, mat->specular); glMaterialf (GL_FRONT, GL_SHININESS, mat->shininess); /* // Old VA code glVertexPointer(3, GL_FLOAT, 0, vertices); glNormalPointer(GL_FLOAT, 0, normals); glDrawElements(GL_TRIANGLES, numFaces * 3, GL_UNSIGNED_INT, indices);*/ // New VBOs --- VBOs --- VBOs --- VBOs --- VBOs --- VBOs --- glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboVertex); glVertexPointer( 3, GL_FLOAT, 0, (char *)NULL); glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboNormal); glNormalPointer(GL_FLOAT, 0, (char *) NULL ); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vboIndices); glDrawElements(GL_TRIANGLES, numFaces * 3, GL_UNSIGNED_INT, (char *)NULL); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);}
Thanks again you guys.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement