Search code examples
windowsopengltexturesrendering

How is GL_CLAMP in OpenGL different from GL_CLAMP_TO_EDGE?


Depending on which documentation you refer for glTexParameteri(), clamping of textures has 2 different interpretations.
In Microsoft's documentation, you'll find GL_CLAMP, while in Khronos's documentation you'll find GL_CLAMP_TO_EDGE.

I thought that they are synonymous in function, but it doesn't seem so.
On my Ubuntu 18.04.2, I have the following.

/usr/include/GL/gl.h
#define GL_CLAMP_TO_EDGE                        0x812F
#define GL_CLAMP                                0x2900
#define GL_CLAMP_TO_BORDER                      0x812D

Whereas on my Windows 10 16299 Enterprise build, I have the following.

C:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\um\gl\GL.h
#define GL_CLAMP                          0x2900

They are mapped to different values, so one would expect different behaviour too.
I am trying to get rid of artifacts we get from using GL_REPEAT. See the green circles in the following image (image source - freepik.com).

Womain's face - freepik

GL_CLAMP does get rid of the artifacts, however I am not able to find enough details on how the various clamping modes differ, and when would one prefer one over other.

I am coding on my windows machine, and may later port the same application to GNU/Linux.

Update 1 : GL_CLAMP rid me of most artifacts, but not all, in the end I added a 10px transparent border to all my textures. The question still stands however.

Update 2 : The question isn't, how GL_CLAMP differs between the implementations, but, how GL_CLAMP differs from GL_CLAMP_TO_EDGE ?


Solution

  • If you dig into Khronos Registry different GL specifications, you'll find some explanations.

    At the very first spec (1.0 1994) CLAMP and REPEAT were the only options for TEXTURE_WRAP_x parameters.

    Spec 1.2 1998 added CLAMP_TO_EDGE. It gives the clue you need:

    GL normally clamps such that the texture coordinates are limited to exactly the range [0;1]. When a texture coordinate is clamped using this algorithm, the texture sampling filter straddles the edge of the texture image, taking half its sample values from within the texture image, and the other half from the texture border. It is sometimes desirable to clamp a texture without requiring a border, and without using the constant border color.

    A new texture clamping algorithm, CLAMP_TO_EDGE, clamps texture coordinates at all mipmap levels such that the texture filter never samples a border texel. The color returned when clamping is derived only from texels at the edge of the texture image.


    The CLAMP option was deprecated in spec 3.0 2008 and removed in spec 3.2 Core 2009. You can still use it if (and only if) you don't set a Core Profile context.


    The reason about Microsoft doc's taking about old CLAMP is that MS provides OpenGL 1.1 without the need of retrieving function pointers to GL commands. Higher versions need special headers (apart from gl.h) and other special stuff.