frustum culling code?

Does anyone have some good frustum culling code? Something to take an ofTexture out of a collection when it is no longer visible on the screen (or, better yet, in front of some arbitrary rectangle) from the POV of the camera.

Okay - I’m doing this great-tutorial-on-Lighthouse-3D. I’ll post the results when I am done.

I ended up going with this tutorial in the end: http://www.crownandcutlass.com/features/technicaldetails/frustum.html

I haven’t cleaned it up or optimized it, but it works (I think – I haven’t done very rigorous testing yet), so I am happy. I will post more cleaned up code later.

The first step is to add a 2 dimensional array to your testApp. This will represent the 6 planes that make the chopped-off pyramid that is your viewing frustum.

  
float frustum[6][4];  

Then, in your draw function, after you have done all of your modelview matrix transformations, you can calculate these planes:

  
  
	float   proj[16];  
	float   modl[16];  
	float   clip[16];  
  
	/* Get the current PROJECTION matrix from OpenGL */  
	glGetFloatv( GL_PROJECTION_MATRIX, proj );  
  
	/* Get the current MODELVIEW matrix from OpenGL */  
	glGetFloatv( GL_MODELVIEW_MATRIX, modl );  
  
	/* Combine the two matrices (multiply projection by modelview) */  
	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];  
  
  
	/* Extract the numbers for the RIGHT plane */  
	frustum[0][0] = clip[ 3] - clip[ 0];  
	frustum[0][1] = clip[ 7] - clip[ 4];  
	frustum[0][2] = clip[11] - clip[ 8];  
	frustum[0][3] = clip[15] - clip[12];  
  
	/* Extract the numbers for the LEFT plane */  
	frustum[1][0] = clip[ 3] + clip[ 0];  
	frustum[1][1] = clip[ 7] + clip[ 4];  
	frustum[1][2] = clip[11] + clip[ 8];  
	frustum[1][3] = clip[15] + clip[12];  
  
  
	/* Extract the BOTTOM plane */  
	frustum[2][0] = clip[ 3] + clip[ 1];  
	frustum[2][1] = clip[ 7] + clip[ 5];  
	frustum[2][2] = clip[11] + clip[ 9];  
	frustum[2][3] = clip[15] + clip[13];  
  
	/* Extract the TOP plane */  
	frustum[3][0] = clip[ 3] - clip[ 1];  
	frustum[3][1] = clip[ 7] - clip[ 5];  
	frustum[3][2] = clip[11] - clip[ 9];  
	frustum[3][3] = clip[15] - clip[13];  
  
	/* Extract the FAR plane */  
	frustum[4][0] = clip[ 3] - clip[ 2];  
	frustum[4][1] = clip[ 7] - clip[ 6];  
	frustum[4][2] = clip[11] - clip[10];  
	frustum[4][3] = clip[15] - clip[14];  
  
	/* Extract the NEAR plane */  
	frustum[5][0] = clip[ 3] + clip[ 2];  
	frustum[5][1] = clip[ 7] + clip[ 6];  
	frustum[5][2] = clip[11] + clip[10];  
	frustum[5][3] = clip[15] + clip[14];  
  

Finally, you can use a function like this to determine whether something is inside of your viewing planes.

  
  
		bool PointInFrustum( float x, float y, float z )  
		{  
		   int p;  
  
		   for( p = 0; p < 6; p++ )  
			  if( frustum[p][0] * x + frustum[p][1] * y + frustum[p][2] * z + frustum[p][3] <= 0 )  
				 return false;  
		   return true;  
		}  
  

The idea is, in certain situations, if something is outside of the field of vision, you might want to delete it altogether to free up the resources. With this function (and others that you can find in the tutorial), you can test your objects at every cycle, and remove them if necessary.

Hope this is useful for someone!

it’s a great solution and all but it’s probably around O400 in complexity. it’s an insane amount of calculations to reach a conclusion that could have been done i say 15-20 lines. you can more easily just take the depth of the pyramid, and check for collision with the plane that is z depth from the camera and is parallel to the base of the pyramid. simple point in polygon test which requires minimal math and extraneous functions.
[/code]

I agree that this is a lot of code, and I am still exploring the other techniques (clip space approach or the radar approach) but I’m not sure that I understand what you are suggesting. You are saying I have one plane that is the back of the viewing pyramid, and another parallel plane that is at z depth. What are we checking for collision?

Please excuse me - I am new to openGL and 3D.

Yeah sometimes it’s easier to just post some code snippets or some pseudo code.

Hi,

I am currently trying to implement the geometric frustum culling approach from Lighthouse:
http://www.lighthouse3d.com/opengl/view-…-p?gaplanes

As far as I can tell I do everything correctly but for some reason it does not work, the pyramid is completely flat if I render it. Did anybody have any success with it so far?

I made this example based on the lighthouse3d examples. Not sure what is the best approach.

https://github.com/vanderlin/FrustumCulling