-1

I'm creating a game, in which when I render many blocks. The fps goes seriously down and everything lags. I know why it is lagging, because of many objects being rendered at once, but I can't figure out how to create and implement a frustum culling or any type of culling class to my game.

NOTE: I'm using VBOs.

I just can't find on the net; please help.

Here is some of my code:

//Render Game this were I render my game 
public void Render_GAME() {
    Update();
    if (isGameRunning == true) {
       Update();
       world.render();
       p1.Update();
       }
 }

Flat Class: where I render block

package game.terrain.biomes;

import core.camera.*;
import core.graphics.*;
import core.math.*;
import game.blocks.*;
import game.Player;

public class Flat{

//Global Variables:
private int width;
private int height;
private int depth;

private SpaceStone[][][] blocks;

public Flat(int width, int height, int depth)
{
    this.width = width;
    this.height = height;
    this.depth = depth;

    blocks = new SpaceStone[width][height][depth];

    createBlocks();
}

//Create Blocks
private void createBlocks()
{
    SpaceStone.createBlock();

    for(int x = 0; x < width; x += 5)
    {
        for(int y = 0; y < height; y += 5)
        {
            for(int z = 0; z < depth; z += 5)
            {
                blocks[x][y][z] = new SpaceStone(new Vector3f(x, y, z), new Vector3f(0, 0, 0), new Vector3f(2.5f, 2.5f, 5f));
            }
        }
    }
}

//Render Blocks
private void renderBlocks()
{   
    Shader.BLOCK.Enable();
    SpaceStone.blocktex.bindTexture();
    SpaceStone.block.Bind();

    Shader.BLOCK.setUniform1i("tex", 1);

    Matrix4f viewMatrix = Player.getViewMatrix(Player.getCamera()); 
    Shader.BLOCK.setUniformMat4f("pr_matrix", Player.getPerspective());

    for(int i = 0; i < width; i += 5)
    {
        for(int j = 0; j < height; j += 5)
        {
            for(int k = 0; k < depth; k += 5)
            {
                Matrix4f transform = new Transformation().getTransform(blocks[i][j][k], viewMatrix);
                Shader.BLOCK.setUniformMat4f("vw_matrix", transform);
                SpaceStone.block.Draw();
            }
        }
    }

    Shader.BLOCK.Disable();
    SpaceStone.blocktex.unbindTexture();
    SpaceStone.block.Unbind();
}

//Render Flat Biome
public void renderFlatBiome()
{
    //Render Blocks
    renderBlocks();
}
}

If you want more information, such as classes or the whole project please comment and notify me.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129

1 Answers1

0

OpenGL performs the frustum culling, it sounds like you need to do some processing every frame to decide which blocks to pass to OpenGL to render (or maybe not every frame, new frustum culling calculations would be required every time the geometry or the camera changes). You need to construct a representation of the frustum and test yourself which geometry to be rendered. The viewing frustum could be considered a volume and so you are looking for which cubes are contained within that volume.

First thing is to see which geometry is behind the near clipping plane and further than the far clipping plane. This can be done by simply calculating the distance to the near and far clipping planes and ensuring they are on the correct side of the plane.

The next thing to do is check which geometry is too far left or right to fit in the frustum, and this is slightly more complicated due to the nature and different projections. Orthographic projection is a lot easier to calculate since the frustum for an orthographic projection is essentially cuboid itself. Perspective is trapezoidal in shape (depending of the field of view), but the principle is the same. Construct two planes which represent the left and right clipping planes of the frustum, and cull geometry which is the 'wrong' side in relation to your camera position.

You are simply relieving GL of geometry to draw which GL will determine not to draw anyway. Depending on the scene, the size of the geometry, the way its stored in the buffers and other aspects, the overhead of binding/unbinding and the vertex processing could easily outweigh any performance hit from culling client side.

I haven't written java for years so can't provide source, however I have outlined the simplest form (and not necessarily optimized) of doing this client side (in relation to OpenGL). By spatial grouping geometry data this some form of hierarchy (bounding volume, KD-tree, AABB etc), you can reduce the amount tests required for the culling.

In a lot of cases, the most basic form of hierarchal grouping is Axis Aligned Bounding Box (AABB), which (if none of your cubes ever have a rotation) is what you already have since you are using cubes. Discrete geometry is usually grouped in some form using cuboid volumes denoted by bounding boxes or 'slabs' (two parallel planes which define a volume between them).

lfgtm
  • 1,037
  • 6
  • 19