3
\$\begingroup\$

I'm hoping someone could look through this code for my Chunk, Mesh and ChunkManager classes and tell me what I need to do to improve.

For some reason, when I wrote it in NetBeans and transferred it to Eclipse it deleted all my comments.

I especially don't understand the buffer system. Can I use backbuffers in OpenGL?

Chunk class:

public class Chunk
{
    public static final int X_CHUNK_SIZE = 16;
    public static final int Y_CHUNK_SIZE = 64;
    public static final int Z_CHUNK_SIZE = 16;

    public int chunkXNumber;
    public int chunkZNumber;

    private Mesh mesh;
    private Shader shader;
    private Material material;
    private Texture texture;
    private Transform transform;

    private boolean chunkUpdateNeeded;

    private ArrayList<Integer> indiceList = new ArrayList<Integer>();

    private Block [][][] blocks = new Block[X_CHUNK_SIZE][Y_CHUNK_SIZE][Z_CHUNK_SIZE];

    public Chunk(int chunkXNumber, int chunkZNumber)
    {
        this.chunkXNumber = chunkXNumber;
        this.chunkZNumber = chunkZNumber;

        createBlocks(chunkXNumber, chunkZNumber);

        boolean[][][] blocksActive = getActiveBlocks();

        texture = new Texture("terrain.png");
        material = new Material(texture, new Vector3f(1.0f, 1.0f, 1.0f));   
        transform = new Transform();
        //shader = BasicShader.getInstance();
        shader = BasicShader.getInstance();



        generateChunk(blocksActive);

    }

    private void generateChunk(boolean[][][] blocksActive)
    {
        Vertex[] allVertices = createVertices(blocksActive);

        int[] indices = new int[indiceList.size()];

        for(int i = 0; i < indices.length; i++)
        {
            indices[i] = indiceList.get(i);
        }

        indiceList.clear();

        mesh = new Mesh(allVertices, indices, false);
        transform.setTranslation(chunkXNumber * X_CHUNK_SIZE, -64, chunkZNumber * Z_CHUNK_SIZE);
//      transform.setScale(new Vector3f(1, 1, 1));

    }


    private void createBlocks(int chunkXNum, int chunkZNum)
    {
        float density ;
        for(int i = 0; i < X_CHUNK_SIZE; i++)
        {
            for(int j = 0; j < Y_CHUNK_SIZE; j++)
            {
                for(int k = 0; k < Z_CHUNK_SIZE; k++)
                {
                    density = getDensity(new Vector3f(i ,j ,k ), chunkXNum, chunkZNum);
                    int material = getMaterial(density,j);
                    boolean isActive = setMaterialRules(material);

                    blocks[i][j][k] = new Block(material, isActive);
                }
            }
        }   
    }   

    public void update()
    {


            boolean[][][] blocksActive = getActiveBlocks();

            Vertex[] allChangedVertices = createVertices(blocksActive);

            int[] indices = new int[indiceList.size()];

            for(int h = 0; h < indices.length; h++)
            {
                indices[h] = indiceList.get(h);
            }

            mesh = new Mesh(allChangedVertices, indices, false);

            setChunkUpdateNeeded(false);
        }   
    }

    public void render()
    {
         shader.bind();
         shader.updateUniforms(transform.getTransformation(), transform.getProjectedTransformation(), material);
         mesh.draw();
    }

    private boolean[][][] getActiveBlocks()
    {
        boolean [][][] activeBlocks = new boolean[X_CHUNK_SIZE][Y_CHUNK_SIZE][Z_CHUNK_SIZE];

        for(int i = 0; i < X_CHUNK_SIZE; i++)
        {
            for(int j = 0; j < Y_CHUNK_SIZE; j++)
            {
                for(int k = 0; k < Z_CHUNK_SIZE; k++)
                {
                    activeBlocks[i][j][k] = blocks[i][j][k].isBlockEnabled();
                }   
            }   
        }   

        return activeBlocks;
    }

    private float getDensity(Vector3f chunkPos, int chunkXNum, int chunkZNum)
    {
        float density = 0;
        //TODO check to see if double is necessary
        for(float i = 1; i <= Game.octaveLimit; i *= 8)
        {
            density += (1/i) * (Noise. noise(((chunkPos.getX() + (chunkXNum * X_CHUNK_SIZE) + .001) / 190.0f) * i, ((chunkPos.getY() + .001) /27.0f) * i,( (chunkPos.getZ() + (chunkZNum * Z_CHUNK_SIZE) + .001) / 190.0f) * i));
            density = (density);

        }

//      density += (1/i) * (Noise.noise((x / 790.0f) * i, (y / 590.0f) * i,( z / 790.0f) * i));
//      density = Math.abs(density);

        return density;
    }

    private int getMaterial(float density, int yVal)
    {   
        int material;

        if(density > .52)
        {
            if(yVal >= 38)
            {
                material = 0;
            }

            else
            {
                material = 1;
            }
        }

        else
        {
            if(yVal >= 8)
            {
                material = 0;
            }

            else if(yVal > -12 && yVal < 8)
            {
                material = 2;
            }

            else
            {
                material = 0;
            }
        }
        return material;
    }

    private boolean setMaterialRules(int material)
    {
        if(material == 1)
        {
            return true;
        }

        else if(material == 2)
        {
            return true;
        }

        else
        {
            return false;
        }
    }


    private Vertex[] createVertices(boolean[][][] blockActive) 
    {   
        ArrayList<Vertex> vertexList = new ArrayList<Vertex> ();

        int v1 = X_CHUNK_SIZE;
        int v2 = Y_CHUNK_SIZE;
        int v3 = Z_CHUNK_SIZE;


        for(int i = 0; i < v1; i++)
        {
            for(int j = 0; j < v2; j++)
            {
                for(int k = 0; k < v3; k++)
                {
                    if(blockActive[i][j][k])
                    {
                        Vertex[] blockVerts = createBlock(i, j, k);

                        for(int h = 0; h < blockVerts.length; h++)
                        {
                            vertexList.add(blockVerts[h]);
                            indiceList.add(h);
                        }
                    }
                }
            }
        }


        Vertex[] finalVertices = new Vertex[vertexList.size()];
        finalVertices = vertexList.toArray(finalVertices);

        return finalVertices;
    }


    private Vertex[] createBlock(int x, int y, int z)
    {
        ArrayList <Vertex> vertexList = new ArrayList<Vertex> ();
        int whichTexture = blocks[x][y][z].getBlockType();



        if(z > 0)
        {
            if(!blocks[x][y][z - 1].isBlockEnabled())
            {

                //Front face
                vertexList.add(new Vertex(new Vector3f(x, y, z), getTexCoords(whichTexture, 0)));
                vertexList.add(new Vertex(new Vector3f(x, y + 1, z), getTexCoords(whichTexture, 1)));
                vertexList.add(new Vertex(new Vector3f(x + 1, y + 1, z), getTexCoords(whichTexture, 2)));

                vertexList.add(new Vertex(new Vector3f(x, y, z), getTexCoords(whichTexture, 0)));
                vertexList.add(new Vertex(new Vector3f(x + 1, y + 1, z), getTexCoords(whichTexture, 2)));
                vertexList.add(new Vertex(new Vector3f(x + 1, y, z), getTexCoords(whichTexture, 3)));
            }
        }

        else if(z == 0)
        {
            //Front face
            vertexList.add(new Vertex(new Vector3f(x, y, z), getTexCoords(whichTexture, 0)));
            vertexList.add(new Vertex(new Vector3f(x, y + 1, z), getTexCoords(whichTexture, 1)));
            vertexList.add(new Vertex(new Vector3f(x + 1, y + 1, z), getTexCoords(whichTexture, 2)));

            vertexList.add(new Vertex(new Vector3f(x, y, z), getTexCoords(whichTexture, 0)));
            vertexList.add(new Vertex(new Vector3f(x + 1, y + 1, z), getTexCoords(whichTexture, 2)));
            vertexList.add(new Vertex(new Vector3f(x + 1, y, z), getTexCoords(whichTexture, 3)));
        }

        if(z < Z_CHUNK_SIZE - 1)
        {
            if(!blocks[x][y][z + 1].isBlockEnabled())
            {
                //Back face

                vertexList.add(new Vertex(new Vector3f(x, y, z + 1), getTexCoords(whichTexture, 0)));
                vertexList.add(new Vertex(new Vector3f(x, y + 1, z + 1), getTexCoords(whichTexture, 1)));
                vertexList.add(new Vertex(new Vector3f(x + 1, y + 1, z + 1), getTexCoords(whichTexture, 2)));

                vertexList.add(new Vertex(new Vector3f(x, y, z + 1), getTexCoords(whichTexture, 0)));
                vertexList.add(new Vertex(new Vector3f(x + 1, y + 1, z + 1), getTexCoords(whichTexture, 2)));
                vertexList.add(new Vertex(new Vector3f(x + 1, y, z + 1), getTexCoords(whichTexture, 3)));
            }
        }

        else
        {
            //Back face

            vertexList.add(new Vertex(new Vector3f(x, y, z + 1), getTexCoords(whichTexture, 0)));
            vertexList.add(new Vertex(new Vector3f(x, y + 1, z + 1), getTexCoords(whichTexture, 1)));
            vertexList.add(new Vertex(new Vector3f(x + 1, y + 1, z + 1), getTexCoords(whichTexture, 2)));

            vertexList.add(new Vertex(new Vector3f(x, y, z + 1), getTexCoords(whichTexture, 0)));
            vertexList.add(new Vertex(new Vector3f(x + 1, y + 1, z + 1), getTexCoords(whichTexture, 2)));
            vertexList.add(new Vertex(new Vector3f(x + 1, y, z + 1), getTexCoords(whichTexture, 3)));
        }
        if(x > 0)
        {
            if(!blocks[x - 1][y][z].isBlockEnabled())
            {
                //Left face
                vertexList.add(new Vertex(new Vector3f(x, y, z), getTexCoords(whichTexture, 0)));
                vertexList.add(new Vertex(new Vector3f(x, y + 1, z), getTexCoords(whichTexture, 1)));
                vertexList.add(new Vertex(new Vector3f(x, y + 1, z + 1), getTexCoords(whichTexture, 2)));

                vertexList.add(new Vertex(new Vector3f(x, y, z), getTexCoords(whichTexture, 0)));
                vertexList.add(new Vertex(new Vector3f(x, y + 1, z + 1), getTexCoords(whichTexture, 2)));
                vertexList.add(new Vertex(new Vector3f(x, y, z + 1), getTexCoords(whichTexture, 3)));
            }
        }
        else if(x == 0)
        {
            //Left face
            vertexList.add(new Vertex(new Vector3f(x, y, z), getTexCoords(whichTexture, 0)));
            vertexList.add(new Vertex(new Vector3f(x, y + 1, z), getTexCoords(whichTexture, 1)));
            vertexList.add(new Vertex(new Vector3f(x, y + 1, z + 1), getTexCoords(whichTexture, 2)));

            vertexList.add(new Vertex(new Vector3f(x, y, z), getTexCoords(whichTexture, 0)));
            vertexList.add(new Vertex(new Vector3f(x, y + 1, z + 1), getTexCoords(whichTexture, 2)));
            vertexList.add(new Vertex(new Vector3f(x, y, z + 1), getTexCoords(whichTexture, 3)));
        }

        if(x < X_CHUNK_SIZE - 1)
        {
            if(!blocks[x + 1][y][z].isBlockEnabled())
            {
                //Right face
                vertexList.add(new Vertex(new Vector3f(x + 1, y, z), getTexCoords(whichTexture, 0)));
                vertexList.add(new Vertex(new Vector3f(x + 1, y + 1, z), getTexCoords(whichTexture, 1)));
                vertexList.add(new Vertex(new Vector3f(x + 1, y + 1, z + 1), getTexCoords(whichTexture, 2)));

                vertexList.add(new Vertex(new Vector3f(x + 1, y, z), getTexCoords(whichTexture, 0)));
                vertexList.add(new Vertex(new Vector3f(x + 1, y + 1, z + 1), getTexCoords(whichTexture, 2)));
                vertexList.add(new Vertex(new Vector3f(x + 1, y, z + 1), getTexCoords(whichTexture, 3)));
            }
        }

        else
        {
            //Right face
            vertexList.add(new Vertex(new Vector3f(x + 1, y, z), getTexCoords(whichTexture, 0)));
            vertexList.add(new Vertex(new Vector3f(x + 1, y + 1, z), getTexCoords(whichTexture, 1)));
            vertexList.add(new Vertex(new Vector3f(x + 1, y + 1, z + 1), getTexCoords(whichTexture, 2)));

            vertexList.add(new Vertex(new Vector3f(x + 1, y, z), getTexCoords(whichTexture, 0)));
            vertexList.add(new Vertex(new Vector3f(x + 1, y + 1, z + 1), getTexCoords(whichTexture, 2)));
            vertexList.add(new Vertex(new Vector3f(x + 1, y, z + 1), getTexCoords(whichTexture, 3)));   
        }

        if(y > 0)
        {
            if(!blocks[x][y - 1][z].isBlockEnabled())
            {
                //Bottom face
                vertexList.add(new Vertex(new Vector3f(x, y, z), getTexCoords(whichTexture, 0)));
                vertexList.add(new Vertex(new Vector3f(x, y, z + 1), getTexCoords(whichTexture, 1)));
                vertexList.add(new Vertex(new Vector3f(x + 1, y, z + 1), getTexCoords(whichTexture, 2)));

                vertexList.add(new Vertex(new Vector3f(x, y, z), getTexCoords(whichTexture, 0)));
                vertexList.add(new Vertex(new Vector3f(x + 1, y, z + 1), getTexCoords(whichTexture, 2)));
                vertexList.add(new Vertex(new Vector3f(x + 1, y, z), getTexCoords(whichTexture, 3)));
            }
        }

        else if(y == 0)
        {
            //Bottom face
            vertexList.add(new Vertex(new Vector3f(x, y, z), getTexCoords(whichTexture, 0)));
            vertexList.add(new Vertex(new Vector3f(x, y, z + 1), getTexCoords(whichTexture, 1)));
            vertexList.add(new Vertex(new Vector3f(x + 1, y, z + 1), getTexCoords(whichTexture, 2)));

            vertexList.add(new Vertex(new Vector3f(x, y, z), getTexCoords(whichTexture, 0)));
            vertexList.add(new Vertex(new Vector3f(x + 1, y, z + 1), getTexCoords(whichTexture, 2)));
            vertexList.add(new Vertex(new Vector3f(x + 1, y, z), getTexCoords(whichTexture, 3)));
        }

        if(y < Y_CHUNK_SIZE - 1)
        {
            if(!blocks[x][y + 1][z].isBlockEnabled())
            {
                    //Top face
                    vertexList.add(new Vertex(new Vector3f(x, y + 1, z), getTexCoords(whichTexture, 0)));
                    vertexList.add(new Vertex(new Vector3f(x, y + 1, z + 1), getTexCoords(whichTexture, 1)));
                    vertexList.add(new Vertex(new Vector3f(x + 1, y + 1, z + 1), getTexCoords(whichTexture, 2)));

                    vertexList.add(new Vertex(new Vector3f(x, y + 1, z), getTexCoords(whichTexture, 0)));
                    vertexList.add(new Vertex(new Vector3f(x + 1, y + 1, z + 1), getTexCoords(whichTexture, 2)));
                    vertexList.add(new Vertex(new Vector3f(x + 1, y + 1, z), getTexCoords(whichTexture, 3)));
            }
        }

        else
        {
            //Top face
            vertexList.add(new Vertex(new Vector3f(x, y + 1, z), getTexCoords(whichTexture, 0)));
            vertexList.add(new Vertex(new Vector3f(x, y + 1, z + 1), getTexCoords(whichTexture, 1)));
            vertexList.add(new Vertex(new Vector3f(x + 1, y + 1, z + 1), getTexCoords(whichTexture, 2)));

            vertexList.add(new Vertex(new Vector3f(x, y + 1, z), getTexCoords(whichTexture, 0)));
            vertexList.add(new Vertex(new Vector3f(x + 1, y + 1, z + 1), getTexCoords(whichTexture, 2)));
            vertexList.add(new Vertex(new Vector3f(x + 1, y + 1, z), getTexCoords(whichTexture, 3)));   
        }

        Vertex[] vertices = new Vertex[vertexList.size()];
        vertices = vertexList.toArray(vertices);

        return vertices;
    }


    private Vector2f getTexCoords(int whichTexture, int whichCorner)

    {

            if(whichTexture == 1)
            {
                switch(whichCorner)
                {
                    getTexture();
                }
            }

            else if(whichTexture == 2)
            {
                switch(whichCorner)
                {
                    getTexture();
                }

            }

            return null;



    }

    public Vector2f getChunkValues()
    {
        return new Vector2f(chunkXNumber, chunkZNumber);
    }

    public Transform getTransform() 
    {
        return transform;
    }

    public void setTransform(Transform transform) 
    {
        this.transform = transform;
    }

    public boolean isChunkUpdateNeeded() 
    {
        return chunkUpdateNeeded;
    }

    public void setChunkUpdateNeeded(boolean chunkUpdateNeeded)
    {
        this.chunkUpdateNeeded = chunkUpdateNeeded;
    }
}

Mesh class:

public class Mesh 
{
    private int vbo;
    private int backVbo;
    private int size;


    public Mesh(String fileName)
    {
        vbo = glGenBuffers();

        size = 0;
        loadMesh(fileName);

    }

    public Mesh(Vertex[] vertices, int[] indices)
    {
        this(vertices, indices, false);
    }


    public Mesh(Vertex[] vertices, int[] indices, boolean calcNormals)
    {
        initMeshData();
        addVertices(vertices, indices, calcNormals);    
    }

    private void initMeshData()
    {
        vbo = glGenBuffers();

        size = 0;
    }


    private void addVertices(Vertex[] vertices, int[] indices, boolean calcNormals)
    {

        if(calcNormals)
        {
            calcNormals(vertices, indices);
        }

        size = indices.length;



        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(GL_ARRAY_BUFFER, Util.createFlippedBuffer(vertices), GL_DYNAMIC_DRAW);

    }


    public void draw()
    {

        glEnableVertexAttribArray(0);
        glEnableVertexAttribArray(1);
        glEnableVertexAttribArray(2);

        glBindBuffer(GL_ARRAY_BUFFER, vbo);

        glVertexAttribPointer(0, 3, GL_FLOAT, false, Vertex.SIZE * 4, 0);
        glVertexAttribPointer(1, 2, GL_FLOAT, false, Vertex.SIZE * 4, 12);
        glVertexAttribPointer(2, 3, GL_FLOAT, false, Vertex.SIZE * 4, 20);

        glDrawArrays(GL_TRIANGLES, 0, size);

        glDisableVertexAttribArray(0);
        glDisableVertexAttribArray(1);
        glDisableVertexAttribArray(2);

    }

    private void calcNormals(Vertex[] vertices, int[] indices)
    {
        for(int i = 0; i < indices.length; i += 3)
        {
            int i0 = indices[i];
            int i1 = indices[i + 1];
            int i2 = indices[i + 2];

            Vector3f v1 = vertices[i1].getPos().sub(vertices[i0].getPos());
            Vector3f v2 = vertices[i2].getPos().sub(vertices[i0].getPos());

            Vector3f normal = v1.cross(v2).normalize();

            vertices[i0].setNormal(vertices[i0].getNormal().add(normal));
            vertices[i1].setNormal(vertices[i1].getNormal().add(normal));
            vertices[i2].setNormal(vertices[i2].getNormal().add(normal));
        }

        for(int i = 0; i < vertices.length; i++)
        {
            vertices[i].setNormal(vertices[i].getNormal().normalize());
        }
    }

    private Mesh loadMesh(String fileName)
    {
        String[] splitArray = fileName.split("\\.");
        String ext = splitArray[splitArray.length -1];

        if(!ext.equals("obj"))
        {
            System.err.println("Error: File format not supported mesh supports Obj you loaded a "+ ext);
            new Exception().printStackTrace();
            System.exit(1);
        }

        ArrayList<Vertex> vertices = new ArrayList<Vertex>();
        ArrayList<Integer> indices = new ArrayList<Integer>();

        BufferedReader meshReader = null;

        try
        {
            meshReader = new BufferedReader(new FileReader("./res/models/" + fileName));
            String line;

            while((line = meshReader.readLine()) != null)
            {
                String[] tokens = line.split(" ");
                tokens = Util.removeEmptyStrings(tokens);

                if(tokens.length == 0 || tokens[0].equals("#"))
                {
                    continue;
                }

                else if(tokens[0].equals("v"))
                {
                    vertices.add(new Vertex(new Vector3f(Float.valueOf(tokens[1]),
                                                         Float.valueOf(tokens[2]),
                                                         Float.valueOf(tokens[3]))));
                }

                else if(tokens[0].equals("f"))
                {
                    indices.add(Integer.parseInt(tokens[1].split("/")[0]) - 1);
                    indices.add(Integer.parseInt(tokens[2].split("/")[0]) - 1);
                    indices.add(Integer.parseInt(tokens[3].split("/")[0]) - 1);

                    if(tokens.length > 4)
                    {
                        indices.add(Integer.parseInt(tokens[1].split("/")[0]) - 1);
                        indices.add(Integer.parseInt(tokens[3].split("/")[0]) - 1);
                        indices.add(Integer.parseInt(tokens[4].split("/")[0]) - 1);
                    }
                }

            }

            meshReader.close();

            Vertex[] vertexData = new Vertex[vertices.size()];
            vertices.toArray(vertexData);

            Integer[] indexData = new Integer[indices.size()];
            indices.toArray(indexData);

            addVertices(vertexData, null, true);


        }
        catch(Exception e)
        {
            e.printStackTrace();
            System.exit(1);
        }



        return null;
    }
}

ChunkManager class:

public class ChunkManager 
{
    private Chunk[][] currentChunks;
    public int renderLimit;
    private int maxChunks;
    public static boolean chunkUpdateNeeded;
    public static Vector2f whichChunkUpdate;
    private boolean xBiggerTrue, zBiggerTrue, xSmallerTrue, zSmallerTrue;
    private Entity player;

    public ChunkManager(int renderLimit)
    {
        this(renderLimit, renderLimit / (Chunk.X_CHUNK_SIZE));
    }   

    public ChunkManager(int renderLimit, int maxChunks)
    {
        player = new Player("Hero", 0);
        player.setCurrentCoords(player.getCurrentCoords());
        player.setOldCoords(player.getCurrentCoords());
        player.setOldChunkCoords(player.getCurrentChunkCoords());
        this.renderLimit = renderLimit;
        this.maxChunks = maxChunks;
        currentChunks = new Chunk[(maxChunks * 2) - 1] [(maxChunks * 2) - 1];
        firstChunkGen();
    }

    public void chunkUpdates()
    {
        if(chunkUpdateNeeded == true)
        {
            currentChunks[(int) whichChunkUpdate.getX()][(int) whichChunkUpdate.getY()].setChunkUpdateNeeded(true);
            chunkUpdateNeeded = false;
        }
    }

    private void firstChunkGen()
    {
        for(int i = maxChunks - 1; i > -maxChunks; i--)
        {
            for(int j = maxChunks - 1; j > -maxChunks; j--)
            {
                if(currentChunks[i + maxChunks - 1][j + maxChunks - 1] == null)
                {
                    currentChunks[i + maxChunks - 1][j + maxChunks - 1] = new Chunk((int)player.getCurrentChunkCoords().getX() + (i), (int) player.getCurrentChunkCoords().getY() + (j));
                }
                else
                {
                    continue;
                }
            }
        }
    }

    private boolean chunkChangeNeeded()
    {
        if((int)player.getCurrentChunkCoords().getX() != (int)player.getOldChunkCoords().getX() || (int)player.getCurrentChunkCoords().getY() != (int)player.getOldChunkCoords().getY())
        {
            System.out.println(player.getCurrentChunkCoords().getY());
            System.out.println(player.getOldChunkCoords().getY());
            player.setOldChunkCoords(player.getCurrentChunkCoords());
            return true;
        }

        else
        {

            player.setOldChunkCoords(player.getCurrentChunkCoords());
            return false;
        }
    }

    private Chunk[][] getChunkChange(Chunk[][] currentChunksCopy, int whichUpdate)
    {   
        if(whichUpdate == 0)
        {
            if(xBiggerTrue)
            {
                for(int a = 0; a < currentChunksCopy.length; a++)
                {
                    for(int b = 0; b < currentChunksCopy[0].length; b++)
                    {
                        if(a == currentChunksCopy.length - 1)
                        {
                            currentChunksCopy[a][b] = new Chunk((int)player.getCurrentChunkCoords().getX() + maxChunks - 1, (int)currentChunksCopy[a][b].getChunkValues().getY());
                        }

                        else
                        {
                            currentChunksCopy[a][b] = currentChunksCopy[a + 1][b];
                        }
                    }
                }
                return currentChunksCopy;
            }
        }

        else if(whichUpdate == 1)
        {
            if(xSmallerTrue)
            {
                for(int a = currentChunksCopy.length - 1; a >= 0; a--)
                {
                    for(int b = currentChunksCopy[0].length - 1 ; b >= 0; b--)
                    {
                        if(a == 0)
                        {
                            currentChunksCopy[a][b] = new Chunk((int)player.getCurrentChunkCoords().getX() - maxChunks + 1, ((int)currentChunksCopy[a][b].getChunkValues().getY()));
                        }

                        else
                        {
                            currentChunksCopy[a][b] = currentChunksCopy[a - 1][b];
                        }
                    }
                }
                return currentChunksCopy;
            }
        }

        else if(whichUpdate == 2)
        {
            if(zBiggerTrue)
            {
                for(int a = 0; a < currentChunksCopy.length; a++)
                {
                    for(int b = 0; b < currentChunksCopy[0].length; b++)
                    {
                        if(b == currentChunksCopy[0].length - 1)
                        {
                            currentChunksCopy[a][b] = new Chunk((int)currentChunksCopy[a][b].getChunkValues().getX(), (int)player.getCurrentChunkCoords().getY() + maxChunks - 1);
                        }

                        else
                        {
                            currentChunksCopy[a][b] = currentChunksCopy[a][b + 1];
                        }
                    }
                }
                return currentChunksCopy;
            }
        }
        else if(whichUpdate == 3)
        {
            if(zSmallerTrue)
            {
                for(int a = currentChunksCopy.length - 1; a >= 0; a--)
                {
                    for(int b = currentChunksCopy.length - 1; b >= 0; b--)
                    {
                        if(b == 0)
                        {
                            currentChunksCopy[a][b] = new Chunk((int)currentChunksCopy[a][b].getChunkValues().getX(), (int)player.getCurrentChunkCoords().getY() - maxChunks + 1);
                        }

                        else
                        {
                            currentChunksCopy[a][b] = currentChunksCopy[a][b - 1];
                        }
                    }
                }
                return currentChunksCopy;
            }
        }

        return currentChunksCopy;
    }

    public void update()
    {   
        if(chunkChangeNeeded() == true)
        {       
            if((xBiggerTrue = (currentChunks[(maxChunks * 2) - 2][(maxChunks * 2) - 2].getChunkValues().getX()) < player.getCurrentChunkCoords().getX() + maxChunks - 1))
            {
                currentChunks = getChunkChange(currentChunks , 0);
            }

            if((xSmallerTrue = (currentChunks[0][0].getChunkValues().getX()) > player.getCurrentChunkCoords().getX() - maxChunks + 1))
            {
                currentChunks = getChunkChange(currentChunks, 1);
            }

            if((zBiggerTrue = (currentChunks[(maxChunks * 2) - 2][(maxChunks * 2) - 2].getChunkValues().getY()) < player.getCurrentChunkCoords().getY() + maxChunks - 1))
            {
                currentChunks = getChunkChange(currentChunks , 2);
                System.out.println("ZBIG");
            }

            if((zSmallerTrue = (currentChunks[0][0].getChunkValues().getY()) > player.getCurrentChunkCoords().getY() - maxChunks + 1))
            {
                currentChunks = getChunkChange(currentChunks, 3);
                System.out.println("ZSMALL");
            }           
        }
        chunkUpdates();
    }

    public void input()
    {
        if(Input.getKeyDown(Input.KEY_3))
        {
        for(int a = 0; a < currentChunks.length; a++)
        {
            for(int b = 0; b < currentChunks[0].length; b++)
            {
                System.out.print(" X = " + currentChunks[a][b].getChunkValues().getX() + " Z = " + currentChunks[a][b].getChunkValues().getY());
            }

            System.out.println();
        }
        }
    }


    public void render()
    {
        for(int i = -maxChunks;i < maxChunks - 1; i++)
        {
            for(int j = -maxChunks;j < maxChunks - 1; j++)
            {
                float currentChunkX = currentChunks[i + maxChunks][j + maxChunks ].getTransform().getTranslation().getX();
                float currentChunkZ = currentChunks[i + maxChunks][j + maxChunks ].getTransform().getTranslation().getZ();
                float camX = Game.camera.getPos().getX();
                float camZ = Game.camera.getPos().getZ();

                if(currentChunkX < camX + renderLimit)
                {
                    if(currentChunkZ < camZ + renderLimit)
                    {
                        if(currentChunkX > camX - renderLimit)
                        {
                            if(currentChunkZ > camZ - renderLimit)
                            {
                                currentChunks[i + maxChunks][j + maxChunks].render();
                            }
                        }
                    }
                }

                else continue;
            }
        }

    }

    public int getRenderLimit() 
    {
        return renderLimit;
    }

    public void setRenderLimit(int renderLimit) 
    {
        this.renderLimit = renderLimit;
    }

    public Chunk[][] getCurrentChunks()
    {
        return currentChunks;
    }

    public void setCurrentChunks(Chunk[][] currentChunks)
    {
        this.currentChunks = currentChunks;
    }

    public int getMaxChunks()
    {
        return maxChunks;
    }

    public void setMaxChunks(int maxChunks)
    {
        this.maxChunks = maxChunks;
    }

    public static boolean isChunkUpdateNeeded()
    {
        return chunkUpdateNeeded;
    }

    public static void setChunkUpdateNeeded(boolean chunkUpdateNeeded)
    {
        ChunkManager.chunkUpdateNeeded = chunkUpdateNeeded;
    }

    public static Vector2f getWhichChunkUpdate()
    {
        return whichChunkUpdate;
    }

    public static void setWhichChunkUpdate(Vector2f whichChunkUpdate)
    {
        ChunkManager.whichChunkUpdate = whichChunkUpdate;
    }
}
\$\endgroup\$
  • 1
    \$\begingroup\$ Your question is not exactly clear. First of all: Is your code working properly? If it is not, you should ask it on StackOverflow - but if you do, you will need to improve your question and show more effort of solving the problem first. Asking about backbuffers in OpenGL is off-topic for CodeReview. CodeReview is for reviewing working code, to improve coding style, code readability, etc. \$\endgroup\$ – Simon Forsberg Nov 8 '13 at 20:27
  • \$\begingroup\$ Well i was told to post this here instead of normal StackOverflow so im not sure what to do at this point. I'm basically asking for someone to tell me if the method i approached my classes with is correct. My code does compile and it runs decently but slow. \$\endgroup\$ – Ryland Goldstein Nov 8 '13 at 20:55
  • 2
    \$\begingroup\$ If you know your code works, I recommend you update the title to reflect this. It currently suggests that there could be something wrong with the code. \$\endgroup\$ – Jamal Nov 8 '13 at 21:06
  • \$\begingroup\$ If your code works as it should (except the slow part of course), then you've come to the right place! \$\endgroup\$ – Simon Forsberg Nov 8 '13 at 22:14
  • \$\begingroup\$ Ok good to hear! Thanks for replying I was in a temporary state of confusion haha. \$\endgroup\$ – Ryland Goldstein Nov 8 '13 at 23:30
3
\$\begingroup\$

Ok so I actually asked this question a while ago and since I've since figured it out I figured I would go ahead and answer it.

Firstly my issue was not caused by some singular defect in my code or poorly written line but moreso by a culmination of poorly written code as a whole and the specific language I was using.

I'll address the issue that was causing me the most grief first, Garbage collection. Due to the fact that I was using java and creating millions of voxels on the screen at a time from the start I was constantly plagued by issues with garbage collection. Initially the game would play smoothly and then just freeze for 5-10 seconds consistently. I alleviated this problem by switching to Java's concurrent garbage collection system. Although this removed the stop the world aspect of garbage collection it was now replaced with a more constant less severe lag. Full disclosure, I never actually resolved this problem and instead opted to port my entire engine into c++ where the problem doesn't exist in any form.

The second issue was with the way I was handling Geometry creation. I initially didn't use VAO's mostly due to naivety. After switching to VAO's my performance definitely saw a significant increase. But honestly I believe the lag issues I was experiencing can be attributed to the geometry generation itself. Looking back I was culling very few of the vertices that existed in my scene. This combined with overall bad engine design and constant lag from GC really slowed my game down.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.