LWJGL Forum

Programming => Lightweight Java Gaming Library => Topic started by: tobiaspc on March 28, 2012, 14:41:38

Title: Frustum Culling - Scene gets culled from wrong pov!
Post by: tobiaspc on March 28, 2012, 14:41:38
Hello,

i´m currently implementing frustum culling and having problems with getting the projections matrix:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();// reset


so the matrix should be like this one: link (http://www.opengl.org/sdk/docs/man/xhtml/glLoadIdentity.xml)

but i´m printing it out and i get only null bytes:


//Get the ModelView matrix
ByteBuffer projMatrixBuffer = ByteBuffer.allocateDirect(16*4);

glGetFloat(GL_PROJECTION, projMatrixBuffer.asFloatBuffer());
//float[] modelViewMatrixArray = new float[16];
for(int i = 0;i<16*4;i++)
{
//modelViewMatrixArray[i] = projViewMatrixBuffer.getFloat(i);
System.out.println(projMatrixBuffer.get(i) + " i: " + i);
}


output:
0 i: 0
0 i: 1
0 i: 2
...
0 i: 62
0 i: 63


then, i´m setting up my frustum with
float ratio = ((float)Display.getDisplayMode().getWidth())/((float)Display.getDisplayMode().getHeight());
float fov = 45.0f;
float near = 1;
float far = 1000;
float top = (float) (near*Math.tan(Math.PI/180*fov/2));
float bottom = -top;
float right = ratio*top;
float left = -right;
glFrustum(left, right, bottom, top, near, far);


and printing out the matrix again, same as above, only zeros. After that, i look through my camera:
  public void lookThrough()
   {
   
       //roatate the pitch around the X axis
       GL11.glRotatef(pitch, 1.0f, 0.0f, 0.0f);
       //roatate the yaw around the Y axis
       GL11.glRotatef(yaw, 0.0f, 1.0f, 0.0f);
       //translate to the position vector's location
       GL11.glTranslatef(-position.x, -position.y, -position.z);
   }


and render my stuff. i can move the camera with WASD+mouse and getting a great view over my scene, but i need this matrix for frustum culling.

Any ideas?
Title: Re: Frustum Culling - projection matrix is full off zeros
Post by: Riven on March 29, 2012, 09:01:58
There are two bugs:

1. you forgot to set the byteOrder: projMatrixBuffer.byteOrder(ByteOrder.nativeOrder())
2. you passed the wrong parameter to glGetFloat(GL_PROJECTION_MATRIX not GL_PROJECTION, ...)
Title: Re: Frustum Culling - projection matrix is full off zeros
Post by: tobiaspc on March 30, 2012, 13:50:59
thank you! soo now i´m getting the matricies. this gets called every frame
projectionMatrixBuffer.order(ByteOrder.nativeOrder());
glGetFloat(GL_PROJECTION_MATRIX, projectionMatrixBuffer.asFloatBuffer());

for(int i = 0;i<16;i++)
{
projectionMatrixArray[i] = projectionMatrixBuffer.asFloatBuffer().get(i);
//System.out.println(i + " " + projectionMatrixBuffer.asFloatBuffer().get(i) );
}

modelViewMatrixBuffer.order(ByteOrder.nativeOrder());
glGetFloat(GL_MODELVIEW_MATRIX, modelViewMatrixBuffer.asFloatBuffer());

for(int i = 0;i<16;i++)
{
modelViewMatrixArray[i] = modelViewMatrixBuffer.asFloatBuffer().get(i);
//System.out.println(i + "2 " + modelViewMatrixBuffer.asFloatBuffer().get(i) );
}


and the multiply both:
  // Combine the two matrices (multiply projection by modelview)
  modelViewProjectionMatrixArray[ 0] = modelViewMatrixArray[ 0] * projectionMatrixArray[ 0] + modelViewMatrixArray[ 1] * projectionMatrixArray[ 4] + modelViewMatrixArray[ 2] * projectionMatrixArray[ 8] + modelViewMatrixArray[ 3] * projectionMatrixArray[12];
  modelViewProjectionMatrixArray[ 1] = modelViewMatrixArray[ 0] * projectionMatrixArray[ 1] + modelViewMatrixArray[ 1] * projectionMatrixArray[ 5] + modelViewMatrixArray[ 2] * projectionMatrixArray[ 9] + modelViewMatrixArray[ 3] * projectionMatrixArray[13];
  modelViewProjectionMatrixArray[ 2] = modelViewMatrixArray[ 0] * projectionMatrixArray[ 2] + modelViewMatrixArray[ 1] * projectionMatrixArray[ 6] + modelViewMatrixArray[ 2] * projectionMatrixArray[10] + modelViewMatrixArray[ 3] * projectionMatrixArray[14];
  modelViewProjectionMatrixArray[ 3] = modelViewMatrixArray[ 0] * projectionMatrixArray[ 3] + modelViewMatrixArray[ 1] * projectionMatrixArray[ 7] + modelViewMatrixArray[ 2] * projectionMatrixArray[11] + modelViewMatrixArray[ 3] * projectionMatrixArray[15];

  modelViewProjectionMatrixArray[ 4] = modelViewMatrixArray[ 4] * projectionMatrixArray[ 0] + modelViewMatrixArray[ 5] * projectionMatrixArray[ 4] + modelViewMatrixArray[ 6] * projectionMatrixArray[ 8] + modelViewMatrixArray[ 7] * projectionMatrixArray[12];
  modelViewProjectionMatrixArray[ 5] = modelViewMatrixArray[ 4] * projectionMatrixArray[ 1] + modelViewMatrixArray[ 5] * projectionMatrixArray[ 5] + modelViewMatrixArray[ 6] * projectionMatrixArray[ 9] + modelViewMatrixArray[ 7] * projectionMatrixArray[13];
  modelViewProjectionMatrixArray[ 6] = modelViewMatrixArray[ 4] * projectionMatrixArray[ 2] + modelViewMatrixArray[ 5] * projectionMatrixArray[ 6] + modelViewMatrixArray[ 6] * projectionMatrixArray[10] + modelViewMatrixArray[ 7] * projectionMatrixArray[14];
  modelViewProjectionMatrixArray[ 7] = modelViewMatrixArray[ 4] * projectionMatrixArray[ 3] + modelViewMatrixArray[ 5] * projectionMatrixArray[ 7] + modelViewMatrixArray[ 6] * projectionMatrixArray[11] + modelViewMatrixArray[ 7] * projectionMatrixArray[15];

  modelViewProjectionMatrixArray[ 8] = modelViewMatrixArray[ 8] * projectionMatrixArray[ 0] + modelViewMatrixArray[ 9] * projectionMatrixArray[ 4] + modelViewMatrixArray[10] * projectionMatrixArray[ 8] + modelViewMatrixArray[11] * projectionMatrixArray[12];
  modelViewProjectionMatrixArray[ 9] = modelViewMatrixArray[ 8] * projectionMatrixArray[ 1] + modelViewMatrixArray[ 9] * projectionMatrixArray[ 5] + modelViewMatrixArray[10] * projectionMatrixArray[ 9] + modelViewMatrixArray[11] * projectionMatrixArray[13];
  modelViewProjectionMatrixArray[10] = modelViewMatrixArray[ 8] * projectionMatrixArray[ 2] + modelViewMatrixArray[ 9] * projectionMatrixArray[ 6] + modelViewMatrixArray[10] * projectionMatrixArray[10] + modelViewMatrixArray[11] * projectionMatrixArray[14];
  modelViewProjectionMatrixArray[11] = modelViewMatrixArray[ 8] * projectionMatrixArray[ 3] + modelViewMatrixArray[ 9] * projectionMatrixArray[ 7] + modelViewMatrixArray[10] * projectionMatrixArray[11] + modelViewMatrixArray[11] * projectionMatrixArray[15];

  modelViewProjectionMatrixArray[12] = modelViewMatrixArray[12] * projectionMatrixArray[ 0] + modelViewMatrixArray[13] * projectionMatrixArray[ 4] + modelViewMatrixArray[14] * projectionMatrixArray[ 8] + modelViewMatrixArray[15] * projectionMatrixArray[12];
  modelViewProjectionMatrixArray[13] = modelViewMatrixArray[12] * projectionMatrixArray[ 1] + modelViewMatrixArray[13] * projectionMatrixArray[ 5] + modelViewMatrixArray[14] * projectionMatrixArray[ 9] + modelViewMatrixArray[15] * projectionMatrixArray[13];
  modelViewProjectionMatrixArray[14] = modelViewMatrixArray[12] * projectionMatrixArray[ 2] + modelViewMatrixArray[13] * projectionMatrixArray[ 6] + modelViewMatrixArray[14] * projectionMatrixArray[10] + modelViewMatrixArray[15] * projectionMatrixArray[14];
  modelViewProjectionMatrixArray[15] = modelViewMatrixArray[12] * projectionMatrixArray[ 3] + modelViewMatrixArray[13] * projectionMatrixArray[ 7] + modelViewMatrixArray[14] * projectionMatrixArray[11] + modelViewMatrixArray[15] * projectionMatrixArray[15];


printing out all three:
modelView
1D-Array(16) entries

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
-0.71648437 0.36998308 -0.5914074 0.0 0.0 0.8477705 0.53036326 0.0 0.69760317 0.379997 -0.6074143 0.0 1.8881226 -159.77505 66.84585 1.0
projection
1D-Array(16) entries

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1.8106601 0.0 0.0 0.0 0.0 2.4142134 0.0 0.0 0.0 0.0 -1.002002 -1.0 0.0 0.0 -2.002002 0.0
modelViewProjection
1D-Array(16) entries

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
-1.2973096 0.8932181 0.5925914 0.5914074 0.0 2.046699 -0.53142506 -0.53036326 1.2631222 0.9173938 0.60863036 0.6074143 3.4187481 -385.73108 -68.981674 -66.84585


after that, i set the matrix in my frustum class
public static void setMatrix(float[] matrix)
{
for(int i = 0;i < 4;i++)
{
for(int i2 = 0;i2 < 4;i2++)
{
//System.out.println(matrix[i*4 + i2]);
MVPMatrix[i][i2] = matrix[i*4 + i2];
//System.out.println(MVPMatrix2[i][i2]);
//System.out.println("i: " + i + " i2: " + i2 + " formula: " + ((i*4) + i2));
}
}
updatePlanes(matrix);
}


updatePlanes() extracs the planes:
public static void updatePlanes(float[] matrix)
{
// The equation for a plane is: Ax + By + Cz + D = 0, where A, B and C define the plane's normal vector, D is the distance from the origin to the plane,
// and x, y and z are any points on the plane.. You can plug any point into the equation and if the result is 0 then the point lies on the plane. If the
// result is greater than 0 then the point is in front of the plane, and if it's negative the point is behind the plane.
/* Extract the numbers for the RIGHT plane */

  frustumPlanes[0][0] = matrix[ 3] - matrix[ 0];
  frustumPlanes[0][1] = matrix[ 7] - matrix[ 4];
  frustumPlanes[0][2] = matrix[11] - matrix[ 8];
  frustumPlanes[0][3] = matrix[15] - matrix[12];

  /* Normalize the result */
  float t = (float) Math.sqrt( frustumPlanes[0][0] * frustumPlanes[0][0] + frustumPlanes[0][1] * frustumPlanes[0][1] + frustumPlanes[0][2] * frustumPlanes[0][2] );
  frustumPlanes[0][0] /= t;
  frustumPlanes[0][1] /= t;
  frustumPlanes[0][2] /= t;
  frustumPlanes[0][3] /= t;

  /* Extract the numbers for the LEFT plane */
  frustumPlanes[1][0] = matrix[ 3] + matrix[ 0];
  frustumPlanes[1][1] = matrix[ 7] + matrix[ 4];
  frustumPlanes[1][2] = matrix[11] + matrix[ 8];
  frustumPlanes[1][3] = matrix[15] + matrix[12];

  /* Normalize the result */
  t = (float) Math.sqrt( frustumPlanes[1][0] * frustumPlanes[1][0] + frustumPlanes[1][1] * frustumPlanes[1][1] + frustumPlanes[1][2] * frustumPlanes[1][2] );
  frustumPlanes[1][0] /= t;
  frustumPlanes[1][1] /= t;
  frustumPlanes[1][2] /= t;
  frustumPlanes[1][3] /= t;

  /* Extract the BOTTOM plane */
  frustumPlanes[2][0] = matrix[ 3] + matrix[ 1];
  frustumPlanes[2][1] = matrix[ 7] + matrix[ 5];
  frustumPlanes[2][2] = matrix[11] + matrix[ 9];
  frustumPlanes[2][3] = matrix[15] + matrix[13];

  /* Normalize the result */
  t = (float) Math.sqrt( frustumPlanes[2][0] * frustumPlanes[2][0] + frustumPlanes[2][1] * frustumPlanes[2][1] + frustumPlanes[2][2] * frustumPlanes[2][2] );
  frustumPlanes[2][0] /= t;
  frustumPlanes[2][1] /= t;
  frustumPlanes[2][2] /= t;
  frustumPlanes[2][3] /= t;

  /* Extract the TOP plane */
  frustumPlanes[3][0] = matrix[ 3] - matrix[ 1];
  frustumPlanes[3][1] = matrix[ 7] - matrix[ 5];
  frustumPlanes[3][2] = matrix[11] - matrix[ 9];
  frustumPlanes[3][3] = matrix[15] - matrix[13];

  /* Normalize the result */
  t = (float) Math.sqrt( frustumPlanes[3][0] * frustumPlanes[3][0] + frustumPlanes[3][1] * frustumPlanes[3][1] + frustumPlanes[3][2] * frustumPlanes[3][2] );
  frustumPlanes[3][0] /= t;
  frustumPlanes[3][1] /= t;
  frustumPlanes[3][2] /= t;
  frustumPlanes[3][3] /= t;

  /* Extract the FAR plane */
  frustumPlanes[4][0] = matrix[ 3] - matrix[ 2];
  frustumPlanes[4][1] = matrix[ 7] - matrix[ 6];
  frustumPlanes[4][2] = matrix[11] - matrix[10];
  frustumPlanes[4][3] = matrix[15] - matrix[14];

  /* Normalize the result */
  t = (float) Math.sqrt( frustumPlanes[4][0] * frustumPlanes[4][0] + frustumPlanes[4][1] * frustumPlanes[4][1] + frustumPlanes[4][2] * frustumPlanes[4][2] );
  frustumPlanes[4][0] /= t;
  frustumPlanes[4][1] /= t;
  frustumPlanes[4][2] /= t;
  frustumPlanes[4][3] /= t;

  /* Extract the NEAR plane */
  frustumPlanes[5][0] = matrix[ 3] + matrix[ 2];
  frustumPlanes[5][1] = matrix[ 7] + matrix[ 6];
  frustumPlanes[5][2] = matrix[11] + matrix[10];
  frustumPlanes[5][3] = matrix[15] + matrix[14];

  /* Normalize the result */
  t = (float) Math.sqrt( frustumPlanes[5][0] * frustumPlanes[5][0] + frustumPlanes[5][1] * frustumPlanes[5][1] + frustumPlanes[5][2] * frustumPlanes[5][2] );
  frustumPlanes[5][0] /= t;
  frustumPlanes[5][1] /= t;
  frustumPlanes[5][2] /= t;
  frustumPlanes[5][3] /= t;

}


in my render loop i test if my plane is inside:
      if(renderFrustumManager.sphereInFrustum(xloop, yloop, gameTerrainGenerator.heightmap[xloop][yloop],1))
                       {


but i get weird results:
(http://www.bilderload.com/thumb/190886/screenshot201203301539011884HO82.png) (http://www.bilderload.com/bild/190886/screenshot201203301539011884HO82.png)

EDIT: it seems that everything gets culled from a wrong point. The point is ~at x=200 y=100 z=0.
EDIT2: left & right culling is ok, but near/far/top/bottom doesnt work...
EDIT3: finally figured out what was wrong:
had to change this:
public boolean sphereInFrustum(float x, float y, float z, float radius)
{
  if( frustumPlanes[0][0] * x + frustumPlanes[0][1] * y + frustumPlanes[0][2] * z + frustumPlanes[0][3] <= -radius )
  {
        return false;
  }
...


to this:
public boolean sphereInFrustum(float x, float y, float z, float radius)
{
  if( frustumPlanes[0][0] * x + frustumPlanes[0][1] * z + frustumPlanes[0][2] * y + frustumPlanes[0][3] <= -radius )
  {
        return false;
  }
...


--> flip z/y coords