# view frustum culling and determination

How can one determine if something is in the viewing volume (I am using a perspective not ortho view)?

I dont know but I would be relly interested to know… What is the process openGL uses to achive vertex culling?

OpenGL culling is not the thing you can control, sometimes you just can disable it ( GL_EXT_clip_volume_hint extension ).
Though, if you need to determin if a set of vertices lies within your frustum, there are two ways. One - mirror transforms with your own matrices, or fetch OpenGL ones, transform and project vertices, etc. Two - use feedback buffer, it may be a little tricky but it worth it. One good thing, that second way utilizes T&L for gross visibility determination, and is especially effective if you use bounding boxes. Details by mail … ( I am rare visitor )

Sorry about pointing you to Gamasutra in email

Look at these two cuts from my sources
should be pretty straitforward

D:\Dev\XIE\Engine\Src\Math\Geometry.h:
// Enums
// Vector list visibility ( return codes of Geometry_IsVisible ( ) )
enum
{
Geometry_Visibility_False, // Completely invisible ( should be zero for easy checks like “if ( ! Geometry_IsVisible ( … ) )” )
Geometry_Visibility_True, // Visible ( partially or fully )
Geometry_Visibility_Full // Completely visible
} Geometry_Visibility_e;

// Typedefs
// Bounding box typedef
typedef struct
{
Vector_t Min, Max; // Min and max coords
} Geometry_Box_t;

D:\Dev\XIE\Engine\Src\Math\Geometry.c:
// Check list of vectors to be visible using modelview and projection
// Generally computationally intensive because it uses OpenGL transformations and feedback buffer
// It is effective only with hardware transformations - so it should not be used for large vertex arrays, but bounding box test will do ok
// Returns one of the Geometry_Visibility_e members
int Geometry_IsVisibleBox ( Geometry_Box_t * Box )
{
int Return;
bool CullFace;
#ifdef Common_DebugMode
uint i;
#endif
// Some assertions
Debug_Assert ( Box );
// Setup buffer
glFeedbackBuffer ( 24, GL_2D, Buffer );
// Put OpenGL in feedback mode
glRenderMode ( GL_FEEDBACK );
// Feed vertices for fast point test
glBegin ( GL_POINTS );
glVertex3fv ( ( float * ) & Box -> Max );
glVertex3fv ( ( float * ) & Box -> Min );
glVertex3f ( Box -> Min.X, Box -> Max.Y, Box -> Min.Z );
glVertex3f ( Box -> Max.X, Box -> Max.Y, Box -> Min.Z );
glVertex3f ( Box -> Max.X, Box -> Min.Y, Box -> Min.Z );
glVertex3f ( Box -> Min.X, Box -> Min.Y, Box -> Max.Z );
glVertex3f ( Box -> Min.X, Box -> Max.Y, Box -> Max.Z );
glVertex3f ( Box -> Max.X, Box -> Min.Y, Box -> Max.Z );
glEnd ( );
Return = glRenderMode ( GL_RENDER );
#ifdef Common_DebugMode
// Paranoid checks ( it is rumored that some cards may insert color tokens for each vertex with point rendering … stupidity )
if ( Return < 0 )
Debug_Error ( “Geometry_IsVisible - invalid feedback buffer value count” );
for ( i = 0 ; i < ( size_t ) Return ; i += 3 )
if ( Buffer [ i ] != GL_POINT_TOKEN )
Debug_Error ( “Geometry_IsVisible - invalid feedback buffer contents” );
#endif
// All points inside - fully visible
if ( Return == 24 )
return Geometry_Visibility_Full;
else
// Some points inside - partially visible
if ( Return )
return Geometry_Visibility_True;
// Do a more complete test now for point test can fail if box bounds clipping faces in some plane
// Setup buffer
glFeedbackBuffer ( 1, GL_2D, Buffer );
// Put OpenGL in feedback mode
glRenderMode ( GL_FEEDBACK );
// Disable face culling, storing old mode
if ( CullFace = glIsEnabled ( GL_CULL_FACE ) )
glDisable ( GL_CULL_FACE );
// Feed vertices
glBegin ( GL_TRIANGLES );
glVertex3fv ( ( float * ) & Box -> Min );
glVertex3f ( Box -> Min.X, Box -> Max.Y, Box -> Min.Z );
glVertex3f ( Box -> Max.X, Box -> Max.Y, Box -> Min.Z );

``````glVertex3fv ( ( float * ) & Box -&gt; Min );
glVertex3f ( Box -&gt; Max.X, Box -&gt; Max.Y, Box -&gt; Min.Z );
glVertex3f ( Box -&gt; Max.X, Box -&gt; Min.Y, Box -&gt; Min.Z );

glVertex3f ( Box -&gt; Min.X, Box -&gt; Min.Y, Box -&gt; Max.Z );
glVertex3fv ( ( float * ) & Box -&gt; Max );
glVertex3f ( Box -&gt; Min.X, Box -&gt; Max.Y, Box -&gt; Max.Z );

glVertex3f ( Box -&gt; Min.X, Box -&gt; Min.Y, Box -&gt; Max.Z );
glVertex3f ( Box -&gt; Max.X, Box -&gt; Min.Y, Box -&gt; Max.Z );
glVertex3fv ( ( float * ) & Box -&gt; Max );

glVertex3fv ( ( float * ) & Box -&gt; Min );
glVertex3f ( Box -&gt; Max.X, Box -&gt; Min.Y, Box -&gt; Max.Z );
glVertex3f ( Box -&gt; Min.X, Box -&gt; Min.Y, Box -&gt; Max.Z );

glVertex3fv ( ( float * ) & Box -&gt; Min );
glVertex3f ( Box -&gt; Max.X, Box -&gt; Min.Y, Box -&gt; Min.Z );
glVertex3f ( Box -&gt; Max.X, Box -&gt; Min.Y, Box -&gt; Max.Z );

glVertex3f ( Box -&gt; Min.X, Box -&gt; Max.Y, Box -&gt; Min.Z );
glVertex3f ( Box -&gt; Min.X, Box -&gt; Max.Y, Box -&gt; Max.Z );
glVertex3fv ( ( float * ) & Box -&gt; Max );

glVertex3f ( Box -&gt; Min.X, Box -&gt; Max.Y, Box -&gt; Min.Z );
glVertex3fv ( ( float * ) & Box -&gt; Max );
glVertex3f ( Box -&gt; Max.X, Box -&gt; Max.Y, Box -&gt; Min.Z );

glVertex3fv ( ( float * ) & Box -&gt; Min );
glVertex3f ( Box -&gt; Min.X, Box -&gt; Min.Y, Box -&gt; Max.Z );
glVertex3f ( Box -&gt; Min.X, Box -&gt; Max.Y, Box -&gt; Max.Z );

glVertex3fv ( ( float * ) & Box -&gt; Min );
glVertex3f ( Box -&gt; Min.X, Box -&gt; Max.Y, Box -&gt; Max.Z );
glVertex3f ( Box -&gt; Min.X, Box -&gt; Max.Y, Box -&gt; Min.Z );

glVertex3f ( Box -&gt; Max.X, Box -&gt; Min.Y, Box -&gt; Min.Z );
glVertex3fv ( ( float * ) & Box -&gt; Max );
glVertex3f ( Box -&gt; Max.X, Box -&gt; Min.Y, Box -&gt; Max.Z );

glVertex3f ( Box -&gt; Max.X, Box -&gt; Min.Y, Box -&gt; Min.Z );
glVertex3f ( Box -&gt; Max.X, Box -&gt; Max.Y, Box -&gt; Min.Z );
glVertex3fv ( ( float * ) & Box -&gt; Max );
glEnd ( );
if ( CullFace )
glEnable ( GL_CULL_FACE );
``````

// Get back, counting values stored
// If buffer is empty - box is invisible, elseway it is partially visible
return glRenderMode ( GL_RENDER ) ? Geometry_Visibility_True : Geometry_Visibility_False;
}

[This message has been edited by onyXMaster (edited 06-07-2000).]