glArrayElement not drawing properly.What am I doing wrong?

Hey people…

OK I finally got a model to load up in my test application and now I want to render it onto the screen.I initially did this with a display list and lotsa glVertex3f() calls after the glBegin(GL_TRIANGLES) function.Now I know this is not optimised and not the best way to do it so I decided to use the glArrayElement() instead.But when I run my app,I get some really screwed up things on screen.Here’s me code for you to look at:

void CMs3d::ConstructDList(void)
{
//This functon needs some serious optimisations!
glNewList(Model,GL_COMPILE);

  glEnableClientState(GL_VERTEX_ARRAY);
  glVertexPointer(3,GL_FLOAT,0,Vertex);
  
  glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);

  for(int i=0;i<(int)nNumTriangles;i++)
  {
  	glBegin(GL_TRIANGLES);
  		
  		glArrayElement(Triangles[i].vertexIndices[0]);
  		glArrayElement(Triangles[i].vertexIndices[1]);
  		glArrayElement(Triangles[i].vertexIndices[2]);
  		
  		/*glVertex3f(Vertex[(Triangles[i].vertexIndices[0])].vertex[0],
  			Vertex[(Triangles[i].vertexIndices[0])].vertex[1],
  			Vertex[(Triangles[i].vertexIndices[0])].vertex[2]);

  		glVertex3f(Vertex[(Triangles[i].vertexIndices[1])].vertex[0],
  			Vertex[(Triangles[i].vertexIndices[1])].vertex[1],
  			Vertex[(Triangles[i].vertexIndices[1])].vertex[2]);

  		glVertex3f(Vertex[(Triangles[i].vertexIndices[2])].vertex[0],
  			Vertex[(Triangles[i].vertexIndices[2])].vertex[1],
  			Vertex[(Triangles[i].vertexIndices[2])].vertex[2]);*/

  	glEnd();
  }

  glDisableClientState(GL_VERTEX_ARRAY);

glEndList();
}

Any ideas?I think the code is pretty self explanatory.If you still have any questions then I’ll try to answer them.

Or do you guys suggest something else I can use? I was looking at glInterleavedArrays() and I was thinking that I should use that since it includes tex coordinates,normals,vertices,colors etc.

So…yeah…help me

Oh yeah…the commented code in the body of the glBegin()-glEnd() pair is the old way I used to do it and it works fine.

[This message has been edited by TheGecko (edited 11-16-2000).]

DOH! OK nevermind…I fixed it…
But I have a new question:Is the following code recommended? Or would it be just as slow?

void CMs3d::ConstructDList(void)
{
//This functon needs some serious optimisations!
float VArray = (float)malloc(nNumVertices * 3 * sizeof(float));

int x=0;

for(int j=0;j<nNumVertices;j++)
{
VArray = Vertex[j].vertex[0];
VArray[x+1] = Vertex[j].vertex[1];
VArray[x+2] = Vertex[j].vertex[2];
x+=3;
}

glNewList(Model,GL_COMPILE);

  glEnableClientState(GL_VERTEX_ARRAY);
  glVertexPointer(3,GL_FLOAT,0,VArray);
  
  glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);

  for(int i=0;i<(int)nNumTriangles;i++)
  {
  	glBegin(GL_TRIANGLES);
  		
  		glArrayElement(Triangles[i].vertexIndices[0]);
  		glArrayElement(Triangles[i].vertexIndices[1]);
  		glArrayElement(Triangles[i].vertexIndices[2]);
  		
  	glEnd();
  }

  glDisableClientState(GL_VERTEX_ARRAY);

glEndList();
}

DrawElements is to be preferred over ArrayElement, even if it means you have to split the indices out of your Triangles structure…

I’d suggest using stride rather than that copy loop.

  • Matt

Hmm…sounds interesting…you mean like this?:

void CMs3d::ConstructDList(void)
{
//This functon needs some serious optimisations!
int IArray = (int)malloc(nNumTriangles * 3 * sizeof(int));

int y=0;

for(int k=0;k<nNumTriangles;k++)
{
IArray[y] = (int)Triangles[k].vertexIndices[0];
IArray[y+1] = (int)Triangles[k].vertexIndices[1];
IArray[y+2] = (int)Triangles[k].vertexIndices[2];

  y+=3;

}

//Create our model’s display list
glNewList(Model,GL_COMPILE);

  glEnableClientState(GL_VERTEX_ARRAY);
  glVertexPointer(3,GL_FLOAT,16,Vertex);
  
  glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
  glDrawElements(GL_TRIANGLES,nNumTriangles*3,GL_UNSIGNED_INT,IArray);
  		
  glDisableClientState(GL_VERTEX_ARRAY);

glEndList();

free(IArray);
}

Now,I’m loading up a small model so I can’t tell the difference,but when it gets more complex,will there really be that big of a difference between glDrawElements and glArrayElements?Just curious.If anybody else can think up of yet other better optimisations (if any) I’d love to hear about it!Thanx for the help too

[This message has been edited by TheGecko (edited 11-17-2000).]

Well, if you could avoid the copy of the indices, it’d be better. It’s unclear whether DrawElements with an index copy loop is faster than a loop of ArrayElement calls.

Wait, wait, wait… I am so stupid… I didn’t notice…

You’re using a display list!

Since you’re using a display list, it doesn’t matter how you specify the geometry. It all ends up the same way no matter what method you use.

So do whatever’s easiest and forget what I said before.

  • Matt

Is that like good or bad for display lists? Should I just drop the whole display list thing and keep calling the glDrawElements function over and over every frame or what?

If you can use a display list, it’s generally the best way to go. It requires static data, of course.

  • Matt

Then what’s the point of all these optimisations for static data? Or are all these optimisations only best used for non static data (animated models)?

Dynamic data, static data with very small batching, static data that won’t fit in memory, and static data but different usage modes (i.e. sometimes I want a vertex and a normal, but then sometimes I might want to use the same vertex but with a color, and sometimes I might want the vertex, normal, and a texcoord) are all good reasons to not use display lists.

  • Matt

ooooohhhhh ok! Gotcha! That clears things up for me now

Might it be good to use a display list for a model as long as it’s gemotry doesn’t change? And switch do Arrays afterwards?