Modern (4.0 and up) glEnable/glDisable states

So I was browsing glEnable/glDisable states
https://www.opengl.org/sdk/docs/man2/xhtml/glEnable.xml
and checked GL_CLIP_PLANE out. To me it seems to work the same way as you would provide projection matrix for your shader which would clip the geometry accordingly. So if you base your program on shaders this would make GL_CLIP_PLANE state redundant since the projection matrix handles that.
Am I correct?
If I was correct then which GL states are redundant due to shader use. Is GL_FOG one of these?

If you’re looking for “Modern (4.0 and up)” stuff, why are you looking at documentation for OpenGL 2.1? If you look in the actual 4.5 documentation, you’ll see that there is no GL_CLIP_PLANE.

However, as to your specific question, no, GL_CLIP_PLANE has nothing to do with projection matrices. Fixed function GL has a projection matrix too, so simply having one has nothing to do with clipping. Also, shaders don’t have to have matrices of any kind, yet clipping (both hard-coded and user-defined) can still happen. So there seems to be a lack of understanding on your part about how that works.

As to what GL_CLIP_PLANE is for, it allows you to specify additional planes for clipping geometry against. So not only do you get the regular 6 planes, you can specify other planes to clip against too.

In 3.x+, there is GL_CLIP_DISTANCEi, which can do a similar thing. But the shader defines what the function is, rather than a fixed plane. Thus shaders get to decide where things get clipped.

My bad. Just searched for glEnable and the first link lead me to that page. The page doesn’t specify which version those states are from and if they are valid/proper when it comes to newer versions of OpenGL.

But if you were to provide projection matrix as uniform to the shader then that uniform would be used to clip the geometry right? If not provided then what would OpenGL do then? Default values used?

And if you would enable GL_CLIP_PLANE then those would be taken into account when clipping.

The page doesn’t specify which version those states are from and if they are valid/proper when it comes to newer versions of OpenGL.

Sadly, the owners of this site refuse to remove outdated, misleading, and/or dangerously inaccurate information (just like OpenGL. :wink: ).

I would suggest sticking with the OpenGL Wiki’s search functionality if you’re looking for function documentation. Granted, it’s only current through GL 4.4, but I’ll update it when I get time. And figure out how to do it.

But if you were to provide projection matrix as uniform to the shader then that uniform would be used to clip the geometry right?

No. Projection has nothing to do with clipping (directly). The page I linked you to explains how clipping works, and it doesn’t involve projection.

If not provided then what would OpenGL do then? Default values used?

Default values of what? You’re thinking too much in terms of perspective projection and so forth. Think of it as a process, where perspective projection is an effect you create by using the pipeline. Clipping is a part of that process; it happens no matter how your vertex shader generated its data.

[QUOTE=Alfonse Reinheart;1264158]
No. Projection has nothing to do with clipping (directly). The page I linked you to explains how clipping works, and it doesn’t involve projection.

Default values of what? You’re thinking too much in terms of perspective projection and so forth. Think of it as a process, where perspective projection is an effect you create by using the pipeline. Clipping is a part of that process; it happens no matter how your vertex shader generated its data.[/QUOTE]
But how would OpenGL know how to clip if no clipping values are provided? On what it creates its clipping decisions if no reference is provided? OpenGL can take glViewPort’s values and use those to determine if the triangle is inside the viewing area by XY plane but that doesn’t take into account depth and field of view. The depth one should mean that no clipping in Z plane. The wiki link doesn’t explain that at all.

So on what OpenGL bases its clipping decisions if there is too little to work with as far as I see it.

But how would OpenGL know how to clip if no clipping values are provided? On what it creates its clipping decisions if no reference is provided?

What do you mean by “clipping values” and “reference” here? The only thing clipping needs is a 4D clip-space position, which is what must be provided by the appropriate shader if you want to do any rendering at all. Please follow the link to understand more.

OpenGL can take glViewPort’s values and use those to determine if the triangle is inside the viewing area by XY plane

The viewport transform happens well after any clipping. Clipping is not and cannot be affected by the viewport transform. Again, see the link; the steps are processed in that order.

but that doesn’t take into account depth and field of view. The depth one should mean that no clipping in Z plane. The wiki link doesn’t explain that at all.

Yes it does. Clipping happens first, viewport happens much later.

“Field of view” is nothing more than a scaling effect on the X and Y components performed by a perspective projection matrix. That has nothing to do with clipping; it’s just a clever trick to shrink/stretch the world in a way to make it look like a camera’s FOV.

The Z component of the position gets clipped just like the X and Y components. It’s clipped to between [-Wc, Wc], using the same math as any other component.

EmJayJay, OpenGL clipping takes 4-dimensional vectors in homogenous coordinates, and it clips them to the 4-D region defined by:

-w <= x,y,z <= +w

where [x,y,z,w] are the components of a 4-D clip-space vector. That is, it performs primitive clipping in this 4-D space, restricting the primitive’s extent so that it lies within this 4D region.

The reason it does this is to avoid the singularity introduced by the perspective divide (for the case that w == 0). Consider that after clipping and the perspective divide (i.e. divide by w), clipping can be expressed as:

-1 <= X,Y,Z <= 1

where X=(x/w), Y = (y/w), and Z = (z/w), [X,Y,Z] being the vector in NDC space, and you can intuitively see what this clip-space clipping is doing. It’s just clipping the primitives so that, in the end, they lie with -1…1 in NDC space.

Positions and vectors are typically transformed into this 4-D “clip space” (aka clip coordinates) by the PROJECTION transform. However, there’s nothing about clipping that requires this to be the case.

Dark Photon: That might be it. I guess I missed/forgot the part where the coordinates are transformed into NDC space and thats what the projection matrix does when applied to vertices in world space right? After that the clipping happens right? So if I were to have a vertex at 0.0, 0.0, 2.0 coodinates, it wouldn’t be rendered without moving it straight to NDC space or transformed to NDC space with projection matrix with, say 5.0 view distance.
So the GL_CLIP_PLANE would be used to just define extra clipping plane(s?) within the NDC coordinate space which would be between -1.0 - 1.0, -1.0 - 1.0, 0.0 - 1.0.

I guess I missed/forgot the part where the coordinates are transformed into NDC space and thats what the projection matrix does when applied to vertices in world space right? After that the clipping happens right?

No. Transformation to NDC space happens after clipping. Neither of these processes involve the projection matrix.

I keep linking to the page that explains this entire process, and you just keep not reading it. First you have clipping, then the transform to NDC space, then the viewport transform. In that order.

The projection matrix does not interact directly with clipping. You can use the results of multiplying a position by a perspective projection matrix as a vertex’s position. But that is not the only way to generate a vertex’s position. Therefore, clipping and so forth do not require a projection matrix.

So if I were to have a vertex at 0.0, 0.0, 2.0 coodinates, it wouldn’t be rendered without moving it straight to NDC space or transformed to NDC space with projection matrix with, say 5.0 view distance.

(0.0, 0.0, 2.0) is not a valid clip-space coordinate; clip-space positions are 4-dimensional. So your statement doesn’t make sense. And again, NDC space is not achieved by using a projection matrix.

I have read the link multiple times and I’m trying to see the way you see it.
Ok, define view volume which is described in the link. Is it a cube or frustum or just a plane along X- and Y-axis with depth ignored or saved in depth buffer? What is the range of w? As far as I understand w, its the 4th component of the 4D vector, xyzw. Is the w -1 to 1 or can it be smaller/bigger? The section speaks of clipping but on what space and dimensions its decided. The vertex gets transformed from model space to world space to view space and to NDC space (I think I missed 1 space before NDC). Between view space and NDC space the clipping is done but what defines the space which the clipping is done. Is the clipping space always between -1 to 1 in X axis, -1 to 1 in Y axis and 0 to 1 in Z axis?

Ok, define view volume which is described in the link.

The link described it adequately; it’s the region of space bounded by +/-Wc.

Is it a cube or frustum or just a plane along X- and Y-axis with depth ignored or saved in depth buffer?

Oh, you mean visually describe it.

I can’t do that. The view volume is defined by equations. The vertex shader decides what those equations means, and therefore it defines how to visually interpret it. Since a vertex shader could potentially do many things, there is no one description which works for any vertex shader.

There is only the math behind it.

The view volume, as seen from world space, could be a cube. Or a frustum. Or something else, so long as the clip-space values represent a coherent view of the world as defined by clipping and the clip->NDC transform.

What makes the view volume a cube (in world-space) is the use of a constant Wc, where every vertex has the same Wc coordinate. You would call that an orthographic projection.

To make the view volume a frustum, you would use a Wc in accordance with the perspective projection equation (ie: the negation of the camera-space Z, for the traditional equation). That is, you compute a clip-space position such that, once you apply the NDC transform (division by Wc), you have effectively done perspective projection.

All of those things are controlled by the vertex shader; namely, how it generates the clip-space position. Since that is what defines how to visually interpret the viewing volume, I cannot give a single picture that represents all possible cases.

I can only provide the math; it’s up to you what to do with it.

Think of it like this. Let’s say I ask you for two numbers, A and B. And I tell you that, no matter what those numbers are, I’m going to compute a third number C = A/B. So if you want me to get a specific result, you must give me two numbers which, when combined by my operation, will give you that result. If you want me to get 0.5 as the answer, you would give me 2 and 4. Or 3 and 6. You’re using your knowledge of my operation to compute what you want me to.

The same goes here. Perspective projection requires a division by the camera-space Z. The conversion from clip space to NDC space will divide the clip-space XYZ by the clip-space W. Therefore, you stick the camera-space Z in the clip-space W, and presto: you get a frustum and perspective projection (assuming you’ve done the XYZ part of the math).

That is what the perspective projection matrix you’ve been using does. It computes a clip-space position such that, when the clip-to-NDC transform is performed, will result in perspective projection.

Visualizing clip space directly is difficult, since it’s a 4D space. So it’s best to look at it in terms of math than visuals.

Clipping happens in this intermediate clip space (rather than NDC space) for many reasons, but one of the big ones is that Wc might be zero or something equally bad. Division by zero doesn’t work, so you clip out any triangles before they get to a Wc of zero.

What is the range of w?

The set of all actual numbers representable in a 32-bit IEEE-754 floating-point value.

The section speaks of clipping but on what space and dimensions its decided. The vertex gets transformed from model space to world space to view space and to NDC space (I think I missed 1 space before NDC).

Yes, you missed clip space. Clip space is what is output by the vertex shader. It’s the space clipping happens in; hence the name.

Also, all of those transforms (save the NDC-space one) are optional, defined entirely and only by what your vertex shader wants to do. All OpenGL itself cares about is the clip-space position your shader spits out. The only spaces that are required are model space (conceptually, the space of the vertices that the vertex shader takes, but even then vertex shaders can create positions from whole cloth), clip space (the space of the vertex shader’s output), NDC space, and window space (the result of the viewport transform).

So when you have done all your transforms on your vertices from world space to clip space, you can apply different kind of clipping with GL_CLIP_PLANE(s), in order to produce different result from the rendered geometry from normal clipping values since I still assume that the default clip space’s dimensions are defined in range of -1 to 1 on all axis except with Z which is from x > 0 to 1 and this space is reached with the projection matrix when using shaders on vertices that have been translated into view space. So for my original question about the GL_CLIP_PLANE being replaced by projection matrices when it comes to defining which vertices get cut out is right in a way. Projection matrix deals with transformations to clip space and GL_CLIP_PLANE defines which get cut in the clip space’s range.

And even though numbers and results vary when it comes to math equations you can always make 1 or 3 examples and just say that this will vary with different values to just demonstrate the result. Visualizing is a great way to teach people in my opinion.

since I still assume that the default clip space’s dimensions are defined in range of -1 to 1 on all axis except with Z which is from x > 0 to 1 and this space is reached with the projection matrix when using shaders on vertices that have been translated into view space.

You can assume whatever you want; that doesn’t make it true. And it’s not. The dimensions of clip space are +/-Wc, full stop. Any vertices outside this range will be clipped (unless depth clamping is on, then only the XY will be clipped).

Also, there is no space in OpenGL which has the description you suggest. NDC space is the closest space, and there, the Z goes from [-1, 1].

So for my original question about the GL_CLIP_PLANE being replaced by projection matrices when it comes to defining which vertices get cut out is right in a way.

No, there is no way in which that is correct. Projection matrices don’t do clipping, therefore, they cannot replace something that does do clipping.

The purpose of the clipping planes is to specify additional clipping planes. As in, in addition to the +/-Wc clipping that will always be done.

Visualizing is a great way to teach people in my opinion.

That’s why we have math; not everything can be visualized. Or at least not accurately. While failing to teach someone something is bad, it’s far worse to give someone the illusion that they understand something when they don’t.

It’s always easier to teach someone something when they know nothing than to unteach something they learned incorrectly.

Here’s the diagram of the process, if pictures work better for you (as they do for me):

Ok, define view volume which is described in the link. Is it a cube or frustum or just a plane along X- and Y-axis with depth ignored or saved in depth buffer? What is the range of w? As far as I understand w, its the 4th component of the 4D vector, xyzw. Is the w -1 to 1 or can it be smaller/bigger? The section speaks of clipping but on what space and dimensions its decided. The vertex gets transformed from model space to world space to view space and to NDC space (I think I missed 1 space before NDC). Between view space and NDC space the clipping is done but what defines the space which the clipping is done.

See the pictures for the answers to most of your questions.

Typically:

Object-space = 3D
World-space = 3D
Eye-space = 3D (perspective view frustum looks like a frustum in this space; orthographic view frustum is a cube)
Clip-space = 4D (clipping happens here)
NDC-space = 3D (perspective view frustum squeezed into a cube shape in this space; orthographic and perspective frustum are both cube shapes in -1…1 here)

The only space where you explicitly “have” a w coordinate is clip-space (4D). Its range, in general, is unlimited. In perspective, the w component is typically set to the eye-space -Z value. In orthographic, it is typically set to 1. You can see this by looking at the bottom row of the projection matrices (see second link above).

Re space and transform order, see the diagram on the first link.

Is the clipping space always between -1 to 1 in X axis, -1 to 1 in Y axis and 0 to 1 in Z axis?

No. Clip space (where clipping occurs) is 4D, and as I said, the region within the view frustum is defined by: -w <= x,y,z <= +w

Only after clipping, and after the perspective divide, do we end up in a space (NDC-space) where the component limits are all defined by constants. There, the area within the view frustum is: -1 <= X,Y,Z <= 1, regardless whether you used a perspective or an orthographic projection earlier in the transform chain.

Ok, I think I have mixed NDC space values with clip space which cause my confusion.

The reasoning I have with the projection matrix replacing GL_CLIP_PLANE is that, normally, when you have applied the projection matrix to the vertex in order to transform it into clip space is that the values stored in that clip space coordinate are used to determine if the vertex is clipped or not. The GL_CLIP_PLANE just provides extra clipping test if I understood its use correctly (Though it being old and not to be used in conjunction with shaders that use projection matrix). But you can achieve the same result as the GL_CLIP_PLANE with the projection matrix if you apply the necessary values in it to enforce it.

[QUOTE=EmJayJay;1264199]Ok, I think I have mixed NDC space values with clip space which cause my confusion.

The reasoning I have with the projection matrix replacing GL_CLIP_PLANE is that, normally, when you have applied the projection matrix to the vertex in order to transform it into clip space is that the values stored in that clip space coordinate are used to determine if the vertex is clipped or not. The GL_CLIP_PLANE just provides extra clipping test if I understood its use correctly (Though it being old and not to be used in conjunction with shaders that use projection matrix). But you can achieve the same result as the GL_CLIP_PLANE with the projection matrix if you apply the necessary values in it to enforce it.[/QUOTE]

I understand what you’re saying, but from what I can tell, the frustum clip planes and the ol’ user-defined clip-planes are/were implemented differently.

The frustum clip planes are used to define the region of space that is squeezed into -w <= x,y,z <= +w in CLIP SPACE, and clipping is applied to those 6 planes (x=+w, x=-w, etc.) in that space.

However, it appears that user-defined clip planes are immediately transformed to and stored in EYE SPACE. Then as vertices are sent down the pipe, they are also transformed to EYE SPACE via the ModelView transform, plugged into the clip plane equations, and a “clip distance” is computed (see the modern gl_ClipDistance). These distances are interpolated across the triangle, and then during clipping, used to reject or accept fragments (based on whether they are behind the clip plane or not – i.e. have a plane distance that is negative or not).

In legacy OpenGL, all of those are homogeneous (4D) except NDC (and world-space, which doesn’t exist), even if w is almost always 1. In modern OpenGL, everything prior to clip space is up to the application; even so, vertex attributes always have 4 components (with y,z,w defaulting to 0,0,1 if the attribute array has fewer than 4 components).

Fixed-function lighting relies upon eye-space being affine to world-space for correct results (i.e. eye-space coordinates should all have w=1).

While object-space coordinates are usually 3D, using 4D coordinates is quite common for describing curves and curved surfaces (evaluators in legacy OpenGL, tessellation shaders in modern OpenGL). 4D coordinates can also be used for defining a non-affine texture mapping, although it’s more common to make the texture coordinates homogeneous rather than the vertex coordinates.