Open SunSerega opened 1 year ago
This is from page 524 (546 in the pdf):
Unsigned normalized fixed-point and signed normalized fixed-point RGBA
color buffers are cleared to color values derived by clamping each component of the
clear color to the range [0, 1] or [−1, 1] respectively, then converting the (possibly
sRGB converted and/or dithered) color to fixed-point using equations 2.3 or 2.4,
respectively. The result of clearing integer color buffers is undefined.
Doesn't say anything about non-normalized color buffers, which would imply they are not clamped.
This is also the behavior I observe in my applications, normalized formats get clamped to [0, 1]
while non-normalized formats use the floats without clamping.
I agree with @NogginBops, this is how I would expect my implementation to behave. Values are clamped only when they reach the framebuffer and only if the framebuffer is in a normalised format (so can't represent the input colours). If you have a floating-point colour buffer then clears and rendering results will just write out-of-range values without clamping them.
I expect a line between two points with colors (2.0; 2.0; 2.0) and (0.0; 0.0; 0.0) to have a fully white point in the middle and descend to full black towards the second point. However, what I observe is a gradient starting at the first point
I agree with your expectation here, although if you're using floating-point framebuffers then how they are interpreted by the underlying window system is not defined by GL.
Ok, so basically clamping I see is a behavior of the default windows framebuffer implementation. In other words [4] is correct because that's what Microsoft says about its own code, but [2] is wrong because it's different from original PDF?
And, as I understand, [1] and [3] behave the same, but are described differently in PDF: [3] promises the values will not be clamped, but in the end, it is effectively implementation-defined; meanwhile [1] doesn't say anything, which at least isn't wrong, but... No less confusing.
Ok, so basically clamping I see is a behavior of the default windows framebuffer implementation.
Not necessarily the default windows framebuffer, but rather a behaviour of all GL framebuffers. If the framebuffer is stored in a normalised format then it can only represent values in the range [0, 1], so all values that are stored into that kind of buffer are in the range [0, 1] by definition, so GL clamps those writes. This isn't implementation dependent but it is format dependent. I think this is what MS are trying to describe in [4], but since it's information about some other command, not the one being specified, is imprecise and has ended up confusing.
[1] and [3] are consistent, but in [1] it is assumed that if no clamp is mentioned then no clamp is done. Given the profusion of different descriptions here (and the fact that I think the behaviour may have changed from older GL versions, maybe), this does seem quite confusing. [2] seems just to be wrong, I think.
Yeah [2] is definitely wrong, and should be updated to match the OpenGL specs. Clamping at the glClearColor time was removed in OpenGL 3.0.
@SunSerega would you want to create a PR to fix the refpage at https://github.com/KhronosGroup/OpenGL-Refpages/blob/main/gl4/glClearColor.xml?
This comment has a file that mentions all the cases I found but with links to related spec/extension.
So nothing is said about values, not in the
[0; 1]
range.But in HTML pages for the same spec version, they are clamped?
Even more confusing in the case of
glColor4f
:Now it's explicitly not clamped. But then Microsoft walks in and:
Well, isn't this an implementation detail? (I mean when the clamping is done, as long as before interpolation) And OpenGL API is supposed to only care about the apparent behavior...
Generally, from a few experiences with old OpenGL I remember - all the floating point color values seemed to be clamped. So it was quite a revelation to learn, for some functions none of the original .pdf specs define how out-of-range color values should behave.
I would understand if
glClearColor
with out-of-range values was implementation defined... But sinceglColor4f
is explicitly said to not be clamped, I expect a line between two points with colors (2.0; 2.0; 2.0) and (0.0; 0.0; 0.0) to have a fully white point in the middle and descend to full black towards the second point. However, what I observe is a gradient starting at the first point - as if values passed toglColor4f
are in fact clamped to be (1.0; 1.0; 1.0).