drawelements for many identical objects

Started by xman84, September 26, 2010, 03:44:39

Previous topic - Next topic

xman84

I would like to draw many cubes however when I get to around 1000 it starts to slow the frame rate down. Is there a way I can make a single draw call to open gl to draw them instead of making a drawelements call for every cube. The only difference between the cubes would be position and color.

broumbroum

This is a feature of gllist().  See opengl doc about it!  :D

ParticleSwarm

Can you expand on this a little bit? I'm using a display list to render but it doesn't seem to help much.

Here is where I make the list:

   static void buildLists() {
    	float x = 1;
    	float y = 1;
    	float z = 1;
    	float x2 = (float) (x + EdgeSize);
    	float y2 = (float) (y + EdgeSize);
    	float z2 = (float) (z + EdgeSize);
        box = GL11.glGenLists(1);                              
        GL11.glNewList(box,GL11.GL_COMPILE);               
            GL11.glBegin(GL11.GL_QUADS);

                GL11.glTexCoord2f(0.0f, 0.0f);GL11.glVertex3f( x2, y2,z);         // Top Right Of The Quad (Top)
                GL11.glTexCoord2f(1.0f, 0.0f);GL11.glVertex3f(x, y2,z);         // Top Left Of The Quad (Top)
                GL11.glTexCoord2f(1.0f, 1.0f);GL11.glVertex3f(x, y2, z2);         // Bottom Left Of The Quad (Top)
                GL11.glTexCoord2f(0.0f, 1.0f);GL11.glVertex3f( x2, y2, z2);         // Bottom Right Of The Quad (Top)
                
                GL11.glTexCoord2f(1.0f, 0.0f);GL11.glVertex3f( x2,y, z2);         // Top Right Of The Quad (Bottom)
                GL11.glTexCoord2f(1.0f, 1.0f);GL11.glVertex3f(x,y, z2);         // Top Left Of The Quad (Bottom)
                GL11.glTexCoord2f(0.0f, 1.0f);GL11.glVertex3f(x,y,z);         // Bottom Left Of The Quad (Bottom)
                GL11.glTexCoord2f(0.0f, 0.0f);GL11.glVertex3f( x2,y,z);         // Bottom Right Of The Quad (Bottom)
                
                GL11.glTexCoord2f(0.0f, 1.0f);GL11.glVertex3f( x2, y2, z2);         // Top Right Of The Quad (Front)
                GL11.glTexCoord2f(0.0f, 0.0f);GL11.glVertex3f(x, y2, z2);         // Top Left Of The Quad (Front)
                GL11.glTexCoord2f(1.0f, 0.0f);GL11.glVertex3f(x,y, z2);         // Bottom Left Of The Quad (Front)
                GL11.glTexCoord2f(1.0f, 1.0f);GL11.glVertex3f( x2,y, z2);         // Bottom Right Of The Quad (Front)
                
                GL11.glTexCoord2f(1.0f, 1.0f);GL11.glVertex3f( x2,y,z);         // Bottom Left Of The Quad (Back)
                GL11.glTexCoord2f(0.0f, 1.0f);GL11.glVertex3f(x,y,z);         // Bottom Right Of The Quad (Back)
                GL11.glTexCoord2f(0.0f, 0.0f);GL11.glVertex3f(x, y2,z);         // Top Right Of The Quad (Back)
                GL11.glTexCoord2f(1.0f, 0.0f);GL11.glVertex3f( x2, y2,z);         // Top Left Of The Quad (Back)
                
                GL11.glTexCoord2f(1.0f, 0.0f);GL11.glVertex3f(x, y2, z2);         // Top Right Of The Quad (Left)
                GL11.glTexCoord2f(1.0f, 1.0f);GL11.glVertex3f(x, y2,z);         // Top Left Of The Quad (Left)
                GL11.glTexCoord2f(0.0f, 1.0f);GL11.glVertex3f(x,y,z);         // Bottom Left Of The Quad (Left)
                GL11.glTexCoord2f(0.0f, 0.0f);GL11.glVertex3f(x,y, z2);         // Bottom Right Of The Quad (Left)
                
                GL11.glTexCoord2f(0.0f, 0.0f);GL11.glVertex3f( x2, y2,z);         // Top Right Of The Quad (Right)
                GL11.glTexCoord2f(1.0f, 0.0f);GL11.glVertex3f( x2, y2, z2);         // Top Left Of The Quad (Right)
                GL11.glTexCoord2f(1.0f, 1.0f);GL11.glVertex3f( x2,y, z2);         // Bottom Left Of The Quad (Right)
                GL11.glTexCoord2f(0.0f, 1.0f);GL11.glVertex3f( x2,y,z);         // Bottom Right Of The Quad (Right)
            GL11.glEnd();
        GL11.glEndList();


    }


Then, I call the cube with:

GL11.glCallList(MyGLFunctions.box);

Fool Running

Quote from: xman84 on September 26, 2010, 03:44:39
I would like to draw many cubes however when I get to around 1000 it starts to slow the frame rate down.
When you say that it starts to slow the frame rate down, how much slower are you talking about? A jump from 2000fps to 1000fps is nothing. A jump from 200 to 20 is a big jump.

Also, what graphics card are you using? That can have a big impact on the difference between being able to put 1,000 cubes and 1,000,000 cubes on screen.
Quote from: xman84 on September 26, 2010, 03:44:39
Is there a way I can make a single draw call to open gl to draw them instead of making a drawelements call for every cube. The only difference between the cubes would be position and color.
If the cubes don't move at all, you could put them all into one big display list. Otherwise, you have to draw them one at a time.

EDIT: Whoops, didn't realize that there were two different people responding. ParticleSwarm, the questions still apply, the quotes are just wrong. :P
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

ParticleSwarm

So at around 4000 cubes rendered, I'm getting 20fps. This is already low.

Each time I double the number of cubes, I cut the fps in half, so I'm getting a linear relationship with fps/cubes rendered. There has to be something seriously wrong with how I render.

I'm using a 945 intel chipset. I realize this doesn't help anything, but it doesn't account for such bad performance.

I've already posted my list code, so I'm going to post where I call it. Basically, it just renders a sector of 16x16x32 of blocks, and checks an array to see if a block exists at a particular spot. Maybe you can find something glaringly stupid?

   

    float x = 0;
    while (x <  16)
    {
    	GL11.glTranslatef(1,0,0);
        float z = 0;
        while (z < 16)
        {
            GL11.glTranslatef(0,0,1);
            float y = 0;
            while (y < 32)
            {
            	GL11.glTranslatef(0,1,0);
                //This checks an array to see if a block should be rendered at this spot
            	if (Input.Blocks[(int) x][(int) z][(int) y] == 1)
            	{      	    
           
	            	GL11.glCallList(MyGLFunctions.box);
	            	
            	}
            	y += 1;
            }

            GL11.glTranslatef(0,-y,0);
            z += MyGLFunctions.EdgeSize;
        }

    	GL11.glTranslatef(0,0,-z);
        x += MyGLFunctions.EdgeSize;
    }
	GL11.glTranslatef(-x, 0, 0);
	
    GL11.glEnd();

broumbroum

I've got the same problem with the Intel NM10 chipset (actually gma 13xx). I think the bus is overloaded with the growing fill rate (maybe increasing my ram to a dual-channel config can improve that).
E.g. I render about a 100 characters using tesselation and lists, that makes rendering sink to 5 fps. this is because Intel chipsets ain't too well designed for high def graphics.
I'm figuring out to buy a ION mainboard uses a dedicated graphics rendering pipeline.

Fool Running

Quote from: ParticleSwarm on October 23, 2010, 03:10:01
So at around 4000 cubes rendered, I'm getting 20fps. This is already low.

Each time I double the number of cubes, I cut the fps in half, so I'm getting a linear relationship with fps/cubes rendered. There has to be something seriously wrong with how I render.
I would assume that a linear relationship would be normal. Why wouldn't you expect to halve the framerate when doubling the items on screen?
Quote from: ParticleSwarm on October 23, 2010, 03:10:01
I'm using a 945 intel chipset. I realize this doesn't help anything, but it doesn't account for such bad performance.
Actually, this very well could explain your bad performance. Like broumbroum said, Intel chipsets don't make good graphics cards (I don't care what Intel says). :P

One thing you can try (if you aren't already doing it) is to make sure you are doing back face culling (keeps from drawing the backs of polygons you can't see):
glEnable(GL_CULL_FACE);

Aside from that, it looks like your cubes don't need to move, so you could combine many cubes into a display list to limit the number of calls to the OpengGL api, but you may not gain much with that approach.
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D