2
votes

I've read the documentation on glTeximage2D and am a bit confused in which case OpenGL clamps the texture values to [0,1] or not. I'm using GL_RED as format in my texture and the documentation says:

format determines the composition of each element in data. It can assume one of these symbolic values:

GL_RED Each element is a single red component. The GL converts it to floating point and assembles it into an RGBA element by attaching 0 for green and blue, and 1 for alpha. Each component is clamped to the range [0,1].

Doesn't this basically say that OpenGL always clamps the values regardless of the internal format?

However when I upload my texture as:

glTexImage2D(GL_TEXTURE_2D, 0, GL_R16F, width, height, 0, GL_RED, GL_FLOAT, data);

OpenGL does not clamp my data with GL_R16F as internal format. But if I change the internal format to GL_R16 they do get clamped. Where does the documentation say anything about clamping based on the internal format?

1
Sorry accidentally pasted the link to the old docs. Updated the link to point to OpenGL 4 - novalain
For color component groups, if the internalformat of the texture is signed or unsigned normalized fixed-point, components are clamped to [−1, 1] or [0, 1], respectively. For depth component groups, the depth value is clamped to [0, 1]. Otherwise, values are not modified. OpenGL 4.4 (Core Profile) - March 19, 2014 p183-184 - Dmitry Lachinov
So regular textures (GL_R16) store fixed-point data. GL_R16F are floating point, thus not modified - Dmitry Lachinov

1 Answers

1
votes

The OpenGL Wiki about Image Format includes more information about this.

OpenGL has a particular syntax for writing its color format enumerants. It looks like this:

GL_[components​][size​][type​]
  • : No type suffix means unsigned normalized integer format.
  • _SNORM: Signed normalized integer format.
  • F: Floating-point. Thus, GL_RGBA32F is a floating-point format where each component is a 32-bit IEEE floating-point value.
  • I: Signed integral format. Thus GL_RGBA8I gives a signed integer format where each of the four components is an integer on the range [-128, 127].
  • UI: Unsigned integral format. The values go from [0, MAX_INT] for the integer size.

In correlation to pixels transfers the OpenGL Wiki about Pixel Transfer includes that.

When data is being transferred to an image, pixel values are converted to either floating-point or integer values. If the image format is normalized, the values that are written are clamped to [0, 1] and normalized. If the image format is integral, then the integral input values are copied verbatim.