user2919973
user2919973

Reputation: 43

Speeding up lwjgl rendering?

I wanted to make the Minecraft block rendering using OpenGl(lwjgl).

Anyway I kind of did it but I'm having FPS problems. I wish somebody could tell me how to optimize it so i can render faster more chunks.I will show you the code which shows how i did render the simple map so far based on 0 and 1 values.

CODE:

Chunk Calculation:

public void calculate(){
for(int x=0;x<w;x++)
    for(int y=0;y<d;y++)
        for(int z=0;z<h;z++){
            for(int i=0;i<6;i++){
                Vector3 d =dir[i];
                if(isVisible(x,y,z)==false)continue;
                if(!isVisible(-(int)d.x+x,-(int)d.y+y,-(int)d.z+z) ){
                    pList.add(new Point4B((byte)x,(byte)y,(byte)z,(byte) i));
                }
            }
        }

thats the way i do calculations based on 3D Bit Array: Point4B simply has arguments position x,y,z and side s Thats how i render the chunk:

public void draw(){
for(Point4B a : pList){
    glPushMatrix();
    glTranslatef(a.x,a.y,a.z);
    glBegin(GL_QUADS);
    DrawSide((int)a.s);
    glEnd();
    glPopMatrix();
}

pList is list of all rects i need to render Here is the code i render all the chunks:

for(float x=0;x<16;x++){
for(float z=0;z<16;z++){
    glPushMatrix();
    glTranslatef((float)x*16,0f,(float)z*16);
    chunks[(int)x][(int)z].draw();
    glPopMatrix();
}

here i render 16x16 chunks and this is extremly slow.

I know that there is an optimization that i can do for rendering sides between chunks but i belive even if so i will still not be able to render about 50 chunks with no huge FPS damage

Here i draw Side:

    switch(side){
    case B_UP:
        glColor3f(0.1333f,0.54509f,0.1333f);
         glVertex3f(-1,1,-1);
         glVertex3f(1,1,-1);
         glVertex3f(1,1,1);
         glVertex3f(-1,1,1);
        break;

and so on for all cases for the 6 sides

Pls note if i have missed something to explain

Upvotes: 0

Views: 1184

Answers (2)

Lee Fogg
Lee Fogg

Reputation: 795

Your code is pretty well organised, the problem is that of simply scalability, as Csoki said, you should avoid using immediate mode when doing anything but small prototypes.

Immediate mode is that of creating too many matrices, as you can see you are pushing and poping a new matrix for each chunk and what looks like for each face? (DrawSide in your second code body). I'm sure you can imagine in real game engines the matrix is only changed once per object, this is done by assuming the vertices are local to that object's position (in your case the chunk) so I recommend changing this code

glPushMatrix();
glTranslatef(block.X, block.Y, block.z);
glVertex3f(-1,1,-1);
glVertex3f(1,1,-1);
glVertex3f(1,1,1);
glVertex3f(-1,1,1);
glPopMatrix();

into simply

glVertex3f(-1+block.X, 1+block.Y, -1+block.Z);
glVertex3f(1+block.X,  1+block.Y, -1+block.Z);
glVertex3f(1+block.X,  1+block.Y, 1+block.Z);
glVertex3f(-1+block.X, 1+block.Y, 1+block.Z);

This will enable you not to have to create a new matrix for each block or face which just leaves you with a giant GL_QUADS list of each face in a chunk which is much simpler for more advanced features which I also highly recommend you use such as display-lists and Vertex Buffered Objects (VBOs). These allow the model to be stored in the GPU or at least closer to it along with taking much of the load off your code.

For mode information check out a similar question I answered here, or my implementation of MineCraft here

Upvotes: 0

Csoki
Csoki

Reputation: 139

You should Use backface culling, and there are algorithms wich combine the block's sides to the biggest available faces. And you should'nt use immediate mode rather modern opengl. Try to search for voxel engine tutorials they are useful.

Upvotes: 1

Related Questions