Images attached below.
The right and top bounds of the frustum seem to be working correctly, however the further left/up I look, the more the cubes that are supposed to be visible are clipped.
The first image isn't clipping any visible cubes just as expected.
Right now Im using a Frustum class(slightly modified) I found online as well as a Camera class I found online.
Frustum original:
http://www.java-gaming.org/index.php?action=pastebin&hex=83b53604950Frustum Modified code
public void calculateFrustum(Camera cam)
{
float[] proj = new float[16]; // This will hold our projection matrix
float[] modl = new float[16]; // This will hold our modelview matrix
float[] clip = new float[16]; // This will hold the clipping planes
// glGetFloat() is used to extract information about our OpenGL world.
// Below, we pass in GL_PROJECTION_MATRIX to abstract our projection matrix.
// It then stores the matrix into an array of [16].
proj_b.rewind();
cam.getProjectionMatrix().store(proj_b);
//GL11.glGetFloat(GL11.GL_PROJECTION_MATRIX, proj_b);
proj_b.rewind();
proj_b.get(proj);
// By passing in GL_MODELVIEW_MATRIX, we can abstract our model view matrix.
// This also stores it in an array of [16].
modl_b.rewind();
//new Matrix4f().store(modl_b);
cam.getViewMatrix().store(modl_b);
//GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX, modl_b);
modl_b.rewind();
modl_b.get(modl);
// Now that we have our modelview and projection matrix, if we combine these 2 matrices,
// it will give us our clipping planes. To combine 2 matrices, we multiply them.
clip[ 0] = modl[ 0] * proj[ 0] + modl[ 1] * proj[ 4] + modl[ 2] * proj[ 8] + modl[ 3] * proj[12];
clip[ 1] = modl[ 0] * proj[ 1] + modl[ 1] * proj[ 5] + modl[ 2] * proj[ 9] + modl[ 3] * proj[13];
clip[ 2] = modl[ 0] * proj[ 2] + modl[ 1] * proj[ 6] + modl[ 2] * proj[10] + modl[ 3] * proj[14];
clip[ 3] = modl[ 0] * proj[ 3] + modl[ 1] * proj[ 7] + modl[ 2] * proj[11] + modl[ 3] * proj[15];
clip[ 4] = modl[ 4] * proj[ 0] + modl[ 5] * proj[ 4] + modl[ 6] * proj[ 8] + modl[ 7] * proj[12];
clip[ 5] = modl[ 4] * proj[ 1] + modl[ 5] * proj[ 5] + modl[ 6] * proj[ 9] + modl[ 7] * proj[13];
clip[ 6] = modl[ 4] * proj[ 2] + modl[ 5] * proj[ 6] + modl[ 6] * proj[10] + modl[ 7] * proj[14];
clip[ 7] = modl[ 4] * proj[ 3] + modl[ 5] * proj[ 7] + modl[ 6] * proj[11] + modl[ 7] * proj[15];
clip[ 8] = modl[ 8] * proj[ 0] + modl[ 9] * proj[ 4] + modl[10] * proj[ 8] + modl[11] * proj[12];
clip[ 9] = modl[ 8] * proj[ 1] + modl[ 9] * proj[ 5] + modl[10] * proj[ 9] + modl[11] * proj[13];
clip[10] = modl[ 8] * proj[ 2] + modl[ 9] * proj[ 6] + modl[10] * proj[10] + modl[11] * proj[14];
clip[11] = modl[ 8] * proj[ 3] + modl[ 9] * proj[ 7] + modl[10] * proj[11] + modl[11] * proj[15];
clip[12] = modl[12] * proj[ 0] + modl[13] * proj[ 4] + modl[14] * proj[ 8] + modl[15] * proj[12];
clip[13] = modl[12] * proj[ 1] + modl[13] * proj[ 5] + modl[14] * proj[ 9] + modl[15] * proj[13];
clip[14] = modl[12] * proj[ 2] + modl[13] * proj[ 6] + modl[14] * proj[10] + modl[15] * proj[14];
clip[15] = modl[12] * proj[ 3] + modl[13] * proj[ 7] + modl[14] * proj[11] + modl[15] * proj[15];
// Now we actually want to get the sides of the frustum. To do this we take
// the clipping planes we received above and extract the sides from them.
// This will extract the RIGHT side of the frustum
m_Frustum[RIGHT][A] = clip[ 3] - clip[ 0];
m_Frustum[RIGHT][B] = clip[ 7] - clip[ 4];
m_Frustum[RIGHT][C] = clip[11] - clip[ 8];
m_Frustum[RIGHT][D] = clip[15] - clip[12];
// Now that we have a normal (A,B,C) and a distance (D) to the plane,
// we want to normalize that normal and distance.
// Normalize the RIGHT side
normalizePlane(m_Frustum, RIGHT);
// This will extract the LEFT side of the frustum
m_Frustum[LEFT][A] = clip[ 3] + clip[ 0];
m_Frustum[LEFT][B] = clip[ 7] + clip[ 4];
m_Frustum[LEFT][C] = clip[11] + clip[ 8];
m_Frustum[LEFT][D] = clip[15] + clip[12];
// Normalize the LEFT side
normalizePlane(m_Frustum, LEFT);
// This will extract the BOTTOM side of the frustum
m_Frustum[BOTTOM][A] = clip[ 3] + clip[ 1];
m_Frustum[BOTTOM][B] = clip[ 7] + clip[ 5];
m_Frustum[BOTTOM][C] = clip[11] + clip[ 9];
m_Frustum[BOTTOM][D] = clip[15] + clip[13];
// Normalize the BOTTOM side
normalizePlane(m_Frustum, BOTTOM);
// This will extract the TOP side of the frustum
m_Frustum[TOP][A] = clip[ 3] - clip[ 1];
m_Frustum[TOP][B] = clip[ 7] - clip[ 5];
m_Frustum[TOP][C] = clip[11] - clip[ 9];
m_Frustum[TOP][D] = clip[15] - clip[13];
// Normalize the TOP side
normalizePlane(m_Frustum, TOP);
// This will extract the BACK side of the frustum
m_Frustum[BACK][A] = clip[ 3] - clip[ 2];
m_Frustum[BACK][B] = clip[ 7] - clip[ 6];
m_Frustum[BACK][C] = clip[11] - clip[10];
m_Frustum[BACK][D] = clip[15] - clip[14];
// Normalize the BACK side
normalizePlane(m_Frustum, BACK);
// This will extract the FRONT side of the frustum
m_Frustum[FRONT][A] = clip[ 3] + clip[ 2];
m_Frustum[FRONT][B] = clip[ 7] + clip[ 6];
m_Frustum[FRONT][C] = clip[11] + clip[10];
m_Frustum[FRONT][D] = clip[15] + clip[14];
// Normalize the FRONT side
normalizePlane(m_Frustum, FRONT);
}
}
Camera relevant code
package moonrise3d.camera;
import moonrise3d.util.MatrixUtil;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.vector.Matrix4f;
import org.lwjgl.util.vector.Vector3f;
public class Camera {
private float fov;
private float aspect;
private float zNear;
private float zFar;
private Matrix4f projection;
private Matrix4f view;
// Camera position
private Vector3f position;
private Vector3f rotation;
private Vector3f xAxis, yAxis, zAxis;
public Camera(float fov, float aspect, float zNear, float zFar)
{
this.fov = fov;
this.aspect = aspect;
this.zNear = zNear;
this.zFar = zFar;
projection = MatrixUtil.createPerspectiveProjection(fov, aspect, zNear, zFar);
view = MatrixUtil.createIdentityMatrix();
position = new Vector3f(0, 0, 0);
rotation = new Vector3f(0, 0, 0);
xAxis = new Vector3f(1, 0, 0);
yAxis = new Vector3f(0, 1, 0);
zAxis = new Vector3f(0, 0, 1);
GL11.glEnable(GL11.GL_DEPTH_TEST);
}
public void apply()
{
view.setIdentity();
Matrix4f.rotate((float) Math.toRadians(rotation.x), xAxis, view, view);
Matrix4f.rotate((float) Math.toRadians(rotation.y), yAxis, view, view);
Matrix4f.rotate((float) Math.toRadians(rotation.z), zAxis, view, view);
Matrix4f.translate(position, view, view);
}
public Matrix4f getProjectionMatrix()
{
return projection;
}
/**
* @return the view matrix
*/
public Matrix4f getViewMatrix()
{
return view;
}
}
World Rendering(camera.apply(); is being called before this as well as setting the shader)
public void draw() {
for (int x = 0; x < width(); x++)
{
for (int y = 0; y < height(); y++)
{
for (int z = 0; z < depth(); z++)
{
if (blocks[x][y][z] != null)
{
if (Window.frustum.cubeInFrustum(x * 8, y * 8, z * 8, 8))
{
Renderer3D.drawCube(x * 16, y * 16, z * 16, 16, 16, 16, BlockRegistry.getBlock(blocks[x][y][z]).texture);
}
}
}
}
}
}
I think the problem lies with the camera's view matrix but Im not entirely sure. If you need to see the shader code let me know.
EDIT: Looks like it depends on the angle im looking at it. If I look at one side, everything looks completely fine. Now Im thinking it's the projection matrix that's messed up somehow.