Sign in to follow this  
Jacob_

How to speed this up? (JOGL)

Recommended Posts

I'm making a level editor for the game Minecraft, in Java with JOGL. The level files consist of a 3D grid of blocks which can be different types, and are stored as serialized Java objects. The problem is that I get about 1 frame every 10 seconds just trying to do a 256x256x5 grid, while the game gets over 100fps showing a 256x256x256 map with LWJGL. This is the code I'm using (I know it's bad, I haven't used Java much before or done any 3D graphics programming):
    public void display(GLAutoDrawable drawable) {
        GL gl = drawable.getGL();
        GLUT glut = new GLUT();
        GLU glu = new GLU();
        // Clear the drawing area
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
        // Reset the current matrix to the "identity"
        gl.glLoadIdentity();
        glu.gluLookAt(MineEditor.camx, MineEditor.camy, MineEditor.camz, MineEditor.lookX, MineEditor.lookY, MineEditor.lookZ, 0f, 1f, 0f);
        // Move the "drawing cursor" around
        gl.glTranslatef(-1.5f, 0f, -6.0f);
        gl.glColor3f(1.0f, 0.0f, 0.0f);
        if(MineEditor.levelLoaded == true)
        {
            for(int x=0; x < MineEditor.sx; x++)
            {
                for(int y=MineEditor.start; y < MineEditor.stop; y++)
                {
                    for(int z=0; z < MineEditor.sz; z++)
                    {
                        int cBlock = MineEditor.le.level.getTile(x, y, z);
                        /*skip some code for setting the color*/
                        if(cBlock != 0)
                        {
                            glut.glutSolidCube(2);
                        }
                            gl.glTranslatef(0f, 0f, 2f);
                    }
                    gl.glTranslatef(0f, 2f, -2*MineEditor.sz);
                }
                gl.glTranslatef(2f, -2*MineEditor.sy, 0f);
            }
        }
        glut.glutSolidCube(2);
        // Flush all drawing operations to the graphics card
        gl.glFlush();
    }
[/java]

Display() is called through an Animator. It seems that the slowest part is just looping through the whole level. What's a better way to do this?

Share this post


Link to post
Share on other sites
I'm not sure if it will help, as its a stab in the dark, but you could compile glut.glutSolidCube(2); into a gl list and call the list instead. I'm not sure how long that is taking. Outside of that, you could remove all the translate calls and update internal position variables and draw the cube yourself. I have a feeling the less gl calls made, the better for performance here.

Share this post


Link to post
Share on other sites
You're never going to get acceptable performance with immediate mode like that, and you probably won't get acceptable performance even batching with display lists. The easiest solution is probably to bake the level into a VBO, and update it whenever tiles change.

Share this post


Link to post
Share on other sites
I'm curious about your getTile() function as its about the only thing in the nested loop aside from JOGL calls.

I've found usage of System.currentTimeMillis() to be a quick and dirty way to figure out where your time is being spent. It might be helpful to sum the time spent on each call in there to see where the majority of it is being spent.

You're probably already aware of this but that big long chain of what appears to be a fully qualified reference to a static method in a class whose name starts with a lower case, or worse, a bunch of public member variables being accessed in a static way, yeah that's kind of a no-no with java. I doubt its the cause of your performance problems, but its not going to help debugging when your project gets significantly large. 'Course you can ignore all of that if this is just an example and your project isn't going to get significantly large.

EDIT:
The suggestion in my second paragraph there ought to confirm Sneftel's suspicions.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sneftel
You're never going to get acceptable performance with immediate mode like that, and you probably won't get acceptable performance even batching with display lists. The easiest solution is probably to bake the level into a VBO, and update it whenever tiles change.
I agree on this. Just have some numbers:

256x256x5 = 32k batches per frame.

No hardware will ever be able to cope with this. On nowaday's hardware you also have no reason to not bake extensively. You'll always be strongly batch-bound, regardless of the way you'll choose to send this massive batch count.

Share this post


Link to post
Share on other sites
Quote:
Original post by zedz
VBOs wont speed it up
what is needed is to batch the data i.e. draw multiple tiles in one go
u will need to get rid of all the glTranslate(..) stuff

Yes. Hence, "bake the level into a VBO, and update it whenever tiles change."

Share this post


Link to post
Share on other sites
Matt328: Are you talking about this line?

int cBlock = MineEditor.le.level.getTile(x, y, z);

le is an instance of LevelEditor, which is an object that comes from a .jar file provided by the game creator, so I can't modify it. MineEditor is my own static class, which will perform more advanced editing functions not found in LevelEditor.

The glTranslate() stuff is probably the problem--if I comment out everything in the inner loop, it takes just about the same amount of time to render. I'll check out VBOS.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this