What's going on with Polygon rasterization?

specification says (3.5.1):
Front facing polygons are rasterized if either culling is disabled or the CullFace mode is BACK while back facing polygons are rasterized only if either culling is disabled or the CullFace mode is FRONT.

Then what’s the rule for choosing which face to rasterize when culling is disabled? The front face? or the back one?

Choosing which face to rasterize has little to do with that part of specs.

When vertices are transformed to screen you get some polygon that is clock-wise or counter-clock-wise. Then, depending on current face winding it is decided if this is front face or back face, and then these two rules apply to determine if this front or back face should be rasterized or not.

Note that you have:
glFrontFace - this one is responsible for deciding if face is front or back
glCullFace - this one tells if front or back faces are to be rasterized

Does glCullFace help even if GL_CULL_FACE is disabled?

I mean, if I disable GL_CULL_FACE, will glCullFace still tell me if front or back faces are to be rasterized?

If you have GL_CULL_FACE disabled, then no matter what you pass to glCullFace you will always see both front and back face.
Which is which is controlled by glFrontFace.

And what about one special polygon? It has both front face and back face, which one should be chosen? I believe there’s only one is used at a time.

Usually only one kind of face is visible, as models are closed surfaces (i.e. if modelled properly, one type of faces will always point inwards). Therefore, culling will increase performance as you draw only such faces that really have the potential to be visible. If you want to have polygons that are visible from both sides (infinite thin planes), then you want to disable the culling.

You mean, if I disable CULL_FACE, both colors will be calculated and both be chosen, and which one will finally show on the screen depends on depth comparing?

No. Which face will be chosen depends ONLY on glFrontFace. What will be done with it depends on glCullFace.

Face choosen  |glCullFace|isEnabled    | face visible
by glFrontFace|          |(GL_CULLFACE)|
front         | GL_FRONT | GL_TRUE     | none
front         | GL_BACK  | GL_TRUE     | front
front         |   any    | GL_FALSE    | front
back          | GL_FRONT | GL_TRUE     | back
back          | GL_BACK  | GL_TRUE     | none
back          |   any    | GL_FALSE    | back

As you can see, face visible is always equal to what glFrontFace setting has resulted in or none.

I try to describe the process as far as I can, please correct me if necessary:

  1. a triangle is issued and mapped to screen

  2. a value is calculated, if the triangle is issued CCW and it also turns out CCW on screen and glFrontFace(GL_CCW), or all with CW instead, then the value is finally positive, otherwise is negative. the positive stands for GL_FRONT, and negative stands for GL_BACK.

  3. if glDisable(GL_CULL_FACE), select GL_FRONT for rasterization and skip 4.

  4. glEnable(GL_CULL_FACE) is set. Then if glCullFace(GL_FRONT), discard GL_FRONT and select GL_BACK for rasterization. if glCullFace(GL_BACK), discard GL_BACK and select GL_FRONT for rasterization.

  5. if GL_FRONT face is selected, use GL_FRONT material and user-issued normal to calculate color. Else if GL_BACK face is selected, use GL_BACK material; as for the normal, if GL_LIGHT_MODEL_TWO_SIDE is set to TRUE, select the direction-opposite of user-issued normal, else select user-issued normal; then to calculate color.


  1. Doesn’t matter how triangle is issued - it only matters how it turns out on the screen after transformations

  2. No, face for rasterization has allready been selected in #2

  3. No, face for rasterization has allready been selected in #2

  4. GL_BACK material is only applied if GL_LIGHT_MODEL_TWO_SIDE is set to true. Otherwise both faces use GL_FRONT material.

I’ll quote myself here, please read it carefully:

Which face will be chosen depends ONLY on glFrontFace. What will be done with it depends on glCullFace.

So this is how it works:

  1. triangle is transformed and clipped
  2. if polygon winding after transformation is equal to glFrontFace then we are looking at the front face, otherwise we’re looking at back face
  3. if GL_CULL_FACE is disabled, then we can render this face. Otherwise face culling test must be performed:
    -if it’s front face and glCullFace is GL_BACK then we can render it
    -if it’s back face and glCullFace is GL_FRONT then we can render it
  4. now we select material:
    -if we see front face then we use front material
    -if we see back face then we use front material if GL_LIGHT_MODEL_TWO_SIDE is set to GL_FALSE, but back material if it’s set to GL_TRUE

I think I’m now less confused about the front face. Thanks a lot to you all. Specially to k_szczech, thanks for your patience. :slight_smile:

You issued a triangle in the order of vertex A, B and C.

The triangle is then transformed to screen. And you can count the screen order of the three vertices in the order of A,B,C.

If the order is CCW, and glFrontFace(GL_CCW), or both CW, then you’re meeting the GL_FRONT face. Otherwise, it’s GL_BACK face.

Afterwise, cull the face and coloring it.


Another question for normal:
The normal is just like material. The issued normal is always for GL_FRONT face. Right?

Yes, you got it.
As for normal - yes, it’s always issued for front face but if you use GL_LIGHT_MODEL_TWO_SIDE then for back face normal is inversed and back material is used.

It’s hard for me without your help. :slight_smile:

OpenGL is just that complicated, even for us to study it with some books at hand and many tutorials available on the internet, let alone the design and implementation on the hardware.The specification has many details, but it’s more precisely and less easyly understandable from a coder’s view. I believe it would be easier to study had there be such kind of book just like <<Programming Applications for Microsoft Windows>>.