Jump to content
  • Advertisement
Sign in to follow this  
mike74

OpenGL backface culling

This topic is 4700 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I was just wondering if anyone knows exactly how OpenGL performs backface culling. I'm guessing that it looks at the 2d projection and sees if the points are in clockwise or counterclockwise order. If they're counterclockwise, and it's in GL_CW mode, then I think it removes the face. What is the fastest way to tell if a set of points are clockwise or counterclockwise though? Thanks. mike http://www.coolgroups.com/

Share this post


Link to post
Share on other sites
Advertisement
I don't know but my guess would be to calculate something similar to a normal for the points and determine whether the resulting vector is pointing towards or away from the viewer.

To add to your question, is there a difference between swapping between back & front culling, or leaving culling mode as it is & swapping between GL_CW & GL_CCW modes performance-wise? Apart from having to specify the vertices in a different order I mean.

Share this post


Link to post
Share on other sites
Your guess is correct. As far I know, that's exactly how OpenGL performs backface culling.
As for your second question: I believe there is no other way than to arrange your vertices in the desired order by yourself.


//Clockwise
glBegin(GL_TRIANGLES);
glVertex3f(-1.0f,-1.0f,0);
glVertex3f( 1.0f,-1.0f,0);
glVertex3f( 1.0f, 1.0f,0);
glEnd();

//Counter Clockwise
glBegin(GL_TRIANGLES);
glVertex3f(-1.0f,-1.0f,0);
glVertex3f( 1.0f, 1.0f,0);
glVertex3f( 1.0f,-1.0f,0);
glEnd();



Greets

Chris

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Backface culling is done in hardware, not by OpenGL. I assume the rasterizer can figure out the orientation when it's calculating deltas and stuff anyway in preparations for filling the triangle.

DrewGreen: No, there is no speed difference.

Share this post


Link to post
Share on other sites
well, as far as i know, the algorithm is the same as the one used by lighting. it computest the triangle normal vector, then it computes the viewer vector and then it computes a dotproduct between them. if the angle is > 90 degrees, the triangle is invisible to the user.

Share this post


Link to post
Share on other sites
If this is true, then why is it that OpenGL makes you do normals yourself for lighting but does them for you for backface culling?

Quote:
Original post by meeshoo
well, as far as i know, the algorithm is the same as the one used by lighting. it computest the triangle normal vector, then it computes the viewer vector and then it computes a dotproduct between them. if the angle is > 90 degrees, the triangle is invisible to the user.


Share this post


Link to post
Share on other sites
Quote:
Original post by mike74
If this is true, then why is it that OpenGL makes you do normals yourself for lighting but does them for you for backface culling?

Quote:
Original post by meeshoo
well, as far as i know, the algorithm is the same as the one used by lighting. it computest the triangle normal vector, then it computes the viewer vector and then it computes a dotproduct between them. if the angle is > 90 degrees, the triangle is invisible to the user.


For flexibility, and for the fact that a single triangle can have three different normals for surface approximation, all pointing to different directions.

The winding order of the vertices - in the context of graphics API:s - is almost exclusively used for backface culling.

Share this post


Link to post
Share on other sites
The algorithm is very simple

Given a polygon A. B, C, .... you can compute the normal from the first three points.

normal = ( B-A ) ^ ( C-A )


The observer looks always in the opposite z direction ( that is after the modelview transform is like it is)

Now, if the polygon is looking toward the observer the scalar product

normal * observer_direction

is negative otherwise is positive.

// since you need only the z you can 'optimize' the code
bool back_faced = CCW ? ((B-A)^(C-A)).z > 0 : ((B-A)^(C-A)).z < 0;


It's performed by OpenGL before rasterization

EDIT: I confused the sign in back_faced (as I wrote before if the sign is <0 the polygon is front_facing...)

[Edited by - blizzard999 on September 6, 2005 4:05:34 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by blizzard999
The algorithm is very simple
Given a polygon A. B, C, .... you can compute the normal from the first three points.
The observer looks always in the opposite z direction ( that is after the modelview transform is like it is)
Now, if the polygon is looking toward the observer the scalar product
is negative otherwise is positive.


I'm sorey, but you are absolutely wrong )))
Imagine the situation: you have wide viewport with the horizontal range of about 120-150 degrees. Imagine the cube in front of you, which is oriented right to you by one of its faces. Only cube front side is visible to you, the others are got clipped by your algorithm, because they have 0 dot product (the back side has negative dot product, so, it is clipped anyway).
This is right situation and right solution, but until the cube begins to move to the right. It is moving, moving... Dot products remain the same... Now we must see it's left side!!! Imagine it, we MUST see it! But it is still clipped due to your algo.

The only right method to verify it, is to build a plane, including 3 triangle vertices, and to watch, whether the viewing point is lying in positive half-space according to this plane.

So, the algo is:
---------------

A, B, C - points of triangle after modelview transformation

calculate triangle plane:
N = (B - A) x (C - A)
d = A dot N

Now, the equation of plane is : N dot X - d = 0
Equation of positive half-space is : N dot X - d > 0


So, put here X = (0,0,0)
Now, we have -d > 0 to accomplish test, or, d < 0 - triangle is visible

So, if A dot ((B - A) x (C - A)) >= 0 - triangle is got culled.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!