Many cubes speedup

Greetings,

I am using OpenGL to render a grid of cubes (anywhere up to 1,000,000 plus).

Currently it takes around 10 seconds for 500,000 cubes.

I am using my own cube routine, which works, but is slow (no doubt to my lack of GL knowledge). Any ideas on speeding this up?

Thanks,
Jason.

procedure CubeGL(xpos,ypos,zpos,size,rcol,gcol,bcol:double);
var hs:double;
var a,b,c,d,u,v,n oint3d;
begin
hs:=size/2;
glcolor3f(rcol,gcol,bcol);
glbegin(GL_QUADS);
//top quad
a.x:=xpos-hs;
a.y:=ypos+hs;
a.z:=zpos+hs;
b.x:=xpos+hs;
b.y:=ypos+hs;
b.z:=zpos+hs;
c.x:=xpos+hs;
c.y:=ypos+hs;
c.z:=zpos-hs;
u.x:=b.x-a.x;
u.y:=b.y-a.y;
u.z:=b.z-a.z;
v.x:=d.x-a.x;
v.y:=d.y-a.y;
v.z:=d.z-a.z;
n.x:=u.yv.z-u.zv.y;
n.y:=u.zv.x-u.xv.z;
n.z:=u.xv.y-u.yv.x;
glnormal3f(n.x,n.y,n.z);
glvertex3f(xpos-hs,ypos+hs,zpos+hs);
glvertex3f(xpos+hs,ypos+hs,zpos+hs);
glvertex3f(xpos+hs,ypos+hs,zpos-hs);
glvertex3f(xpos-hs,ypos+hs,zpos-hs);

 //right quad
 a.x:=xpos+hs;
 a.y:=ypos+hs;
 a.z:=zpos+hs;
 b.x:=xpos+hs;
 b.y:=ypos+hs;
 b.z:=zpos-hs;
 c.x:=xpos+hs;
 c.y:=ypos-hs;
 c.z:=zpos-hs;
 u.x:=b.x-a.x;
 u.y:=b.y-a.y;
 u.z:=b.z-a.z;
 v.x:=d.x-a.x;
 v.y:=d.y-a.y;
 v.z:=d.z-a.z;
 n.x:=u.y*v.z-u.z*v.y;
 n.y:=u.z*v.x-u.x*v.z;
 n.z:=u.x*v.y-u.y*v.x;
 glnormal3f(n.x,n.y,n.z);
 glvertex3f(xpos+hs,ypos+hs,zpos+hs);
 glvertex3f(xpos+hs,ypos+hs,zpos-hs);
 glvertex3f(xpos+hs,ypos-hs,zpos-hs);
 glvertex3f(xpos+hs,ypos-hs,zpos+hs);

 //left quad
 a.x:=xpos-hs;
 a.y:=ypos+hs;
 a.z:=zpos-hs;
 b.x:=xpos-hs;
 b.y:=ypos+hs;
 b.z:=zpos+hs;
 c.x:=xpos-hs;
 c.y:=ypos-hs;
 c.z:=zpos+hs;
 u.x:=b.x-a.x;
 u.y:=b.y-a.y;
 u.z:=b.z-a.z;
 v.x:=d.x-a.x;
 v.y:=d.y-a.y;
 v.z:=d.z-a.z;
 n.x:=u.y*v.z-u.z*v.y;
 n.y:=u.z*v.x-u.x*v.z;
 n.z:=u.x*v.y-u.y*v.x;
 glnormal3f(n.x,n.y,n.z);
 glvertex3f(xpos-hs,ypos+hs,zpos-hs);
 glvertex3f(xpos-hs,ypos+hs,zpos+hs);
 glvertex3f(xpos-hs,ypos-hs,zpos+hs);
 glvertex3f(xpos-hs,ypos-hs,zpos-hs);

 //bottom quad
 a.x:=xpos-hs;
 a.y:=ypos-hs;
 a.z:=zpos+hs;
 b.x:=xpos-hs;
 b.y:=ypos-hs;
 b.z:=zpos-hs;
 c.x:=xpos+hs;
 c.y:=ypos-hs;
 c.z:=zpos-hs;
 u.x:=b.x-a.x;
 u.y:=b.y-a.y;
 u.z:=b.z-a.z;
 v.x:=d.x-a.x;
 v.y:=d.y-a.y;
 v.z:=d.z-a.z;
 n.x:=u.y*v.z-u.z*v.y;
 n.y:=u.z*v.x-u.x*v.z;
 n.z:=u.x*v.y-u.y*v.x;
 glnormal3f(n.x,n.y,n.z);
 glvertex3f(xpos-hs,ypos-hs,zpos+hs);
 glvertex3f(xpos-hs,ypos-hs,zpos-hs);
 glvertex3f(xpos+hs,ypos-hs,zpos-hs);
 glvertex3f(xpos+hs,ypos-hs,zpos+hs);

 //back quad
 a.x:=xpos-hs;
 a.y:=ypos+hs;
 a.z:=zpos+hs;
 b.x:=xpos+hs;
 b.y:=ypos+hs;
 b.z:=zpos+hs;
 c.x:=xpos+hs;
 c.y:=ypos-hs;
 c.z:=zpos+hs;
 u.x:=b.x-a.x;
 u.y:=b.y-a.y;
 u.z:=b.z-a.z;
 v.x:=d.x-a.x;
 v.y:=d.y-a.y;
 v.z:=d.z-a.z;
 n.x:=u.y*v.z-u.z*v.y;
 n.y:=u.z*v.x-u.x*v.z;
 n.z:=u.x*v.y-u.y*v.x;
 glnormal3f(n.x,n.y,n.z);
 glvertex3f(xpos-hs,ypos+hs,zpos+hs);
 glvertex3f(xpos+hs,ypos+hs,zpos+hs);
 glvertex3f(xpos+hs,ypos-hs,zpos+hs);
 glvertex3f(xpos-hs,ypos-hs,zpos+hs);

 //front quad
 a.x:=xpos-hs;
 a.y:=ypos+hs;
 a.z:=zpos-hs;
 b.x:=xpos+hs;
 b.y:=ypos+hs;
 b.z:=zpos-hs;
 c.x:=xpos+hs;
 c.y:=ypos-hs;
 c.z:=zpos-hs;
 u.x:=b.x-a.x;
 u.y:=b.y-a.y;
 u.z:=b.z-a.z;
 v.x:=d.x-a.x;
 v.y:=d.y-a.y;
 v.z:=d.z-a.z;
 n.x:=u.y*v.z-u.z*v.y;
 n.y:=u.z*v.x-u.x*v.z;
 n.z:=u.x*v.y-u.y*v.x;
 glnormal3f(n.x,n.y,n.z);
 glvertex3f(xpos-hs,ypos+hs,zpos-hs);
 glvertex3f(xpos+hs,ypos+hs,zpos-hs);
 glvertex3f(xpos+hs,ypos-hs,zpos-hs);
 glvertex3f(xpos-hs,ypos-hs,zpos-hs);
 glend;

end;

Don’t use immediate mode, use Vertex Arrays or display lists, they are much faster

Display lists sounded promising. Problem is that the number and positions of the cubes can change each “frame”. So I would need to feed the cube positions into a display list every frame.

I will have a hunt for some info on Vertex Arrays. The NotSoSuperBible has no info on them.

im pretty sure the superbible (at
least the seccond edition) has stuff
on vertex arrays…

-bobert

You really should be using display lists. Just build a list with the vertices of the cube centered about the origin. Then, for each cube you want rendered, translate to the position you want to render it, and call your list. it should look something like this:

// put world-level translations and rotations here

for(count=0; count<num_cubes; count++)
{
glLoadIdentity();
glTranslatef(cubes[count].XPos, cubes[count].YPos, cubes[count].ZPos);
glCallList(cubeList);
}

that’s it. hope this helps