What data type for internalformat specified as GL_RGBA? - opengl

In the OpenGL wiki glTexImage2D, it writes:
internalFormat Specifies the number of color components in the
texture. Must be one of base internal formats given in Table 1, one of
the sized internal formats given in Table 2, or one of the compressed
internal formats given in Table 3, below.
In OpenGL Programming Guide, Chapter 9, Texture Mapping
By definition, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB, and GL_RGBA
are lenient, because they do not ask for a specific resolution.
So if we assign GL_RGBA to the internalformat, what datatype is used?
Default by the GPU processor?

The size used for GL_RGBA is specifically undefined.
From the OpenGL 4.5 spec, section "8.5 Texture Image Specification", page 153 (emphasis added):
The internal component resolution is the number of bits allocated to each value in a texture image. If internalformat is specified as a base internal format, the GL stores the resulting texture with internal component resolutions of its own choosing.
where "base internal format" refers to the formats listed in table 8.11, which includes GL_RGBA.
I would expect the chosen format to typically be GL_RGBA8, but there's really no guarantee. If you care about the size, you should use a sized format. In fact, I think you always should. The unsized formats seem to still be there to maintain backwards compatibility. I was always surprised that they were not removed in the Core Profile. For example the newer glTexStorage*() entry points, which serve as better replacements for glTexImage*() in many use cases, only accept sized internal formats.

I'm not sure what your question here is but GL_RGBA is normally a 4x8bit (4-byte/GL_BYTE type) format in the R,G,B,A order respectively but the constant is just saying that the buffer is composed of this order and not exactly how big each channel width is.
More info here
Edit: For some methods, you also need to specify this channel width (e.g. glReadPixels() or glDrawPixels())

Related

glTexImage2D - channels count as the internal format

OpenGL 2.1 documentation says that glTexImage2D accepts channels count as the internal format. How does choosing the internal format work in such scenario ? Does specyfing channels count as the internal format is an error in OpenGL > 2.1 ?
Does specyfing channels count as the internal format is an error in OpenGL > 2.1 ?
Yes, for Core Profile at least. See OpenGL 3.2 (or following) Core specifications in section "3.8.1 Texture Image Specification"
internalformat may be specified as one of the internal format symbolic constants listed in table 3.11, as one of the sized internal format symbolic constants listed in tables 3.12- 3.13, as one of the generic compressed internal format symbolic constants listed in table 3.14, or as one of the specific compressed internal format symbolic constants (if listed in table 3.14). Specifying a value for internalformat that is not one of the above values generates the error INVALID_VALUE.
Contrast this with the additional sentence in the OpenGL 2.1 specification in that same section 3.8.1 (which is omitted in the 3.2 core specification):
internalformat may (for backwards compatibility with the 1.0 version of the GL) also take on the integer values 1, 2, 3, and 4, which are equivalent to symbolic constants LUMINANCE, LUMINANCE ALPHA, RGB, and RGBA respectively.

OpenGL texture format GL_R11F_G11F_B10F - choosing data type

I would like to use a texture with internal format GL_R11F_G11F_B10F as a framebuffer attachment (postprocessing effects, HDR rendering). I'm not sure which data type I should chosse - glTexImage2D 8th parameter. Here are the possible options:
GL_HALF_FLOAT
GL_FLOAT
GL_UNSIGNED_INT_10F_11F_11F_REV
Could you please explain based on which criteria should I choose that type ?
The format and type of glTexImage2D instruct OpenGL how to interpret the image that you pass to that function through the data argument. Since you're merely allocating your texture without specifying any image (i.e. set data = NULL) the exact values of format and type do not matter. The only requirement for them is to be compatible with the internalformat, or else glTexImage2D will generate GL_INVALID_OPERATION when validating the arguments.
However, since you're not specifying an image, it's best to use glTexStorage2D here. This function has simpler semantics and you don't need to specify format, type and data at all.

glTexImage2D - GL_TEXTURE_RECTANGLE_NV and compressed internal format

I have modified a legacy code (OpenGL 2.1) which uses glTexImage2D with GL_TEXTURE_RECTANGLE_NV texture target. I have noticed that when I set some compressed internal format, for example GL_COMPRESSED_RGBA_S3TC_DXT5_EXT it doesn't work with GL_TEXTURE_RECTANGLE_NV (I get a white texture). I have tested other scenarios and everything works fine, i.e. GL_TEXTURE_2D with compressed internal format, GL_TEXTURE_RECTANGLE_NV with non-compressed internal format. Does it mean that GL_TEXTURE_RECTANGLE_NV can't be used with compressed formats ?
Here's what the spec for NV_texture_rectangle extension says about compressed formats:
Can compressed texture images be specified for a rectangular texture?
RESOLUTION: The generic texture compression internal formats
introduced by ARB_texture_compression are supported for rectangular
textures because the image is not presented as compressed data and
the ARB_texture_compression extension always permits generic texture
compression internal formats to be stored in uncompressed form.
Implementations are free to support generic compression internal
formats for rectangular textures if supported but such support is
not required.
This extensions makes a blanket statement that specific compressed
internal formats for use with CompressedTexImage<n>DARB are NOT
supported for rectangular textures. This is because several
existing hardware implementations of texture compression formats
such as S3TC are not designed for compressing rectangular textures.
This does not preclude future texture compression extensions from
supporting compressed internal formats that do work with rectangular
extensions (by relaxing the current blanket error condition).
So your specific format GL_COMPRESSED_RGBA_S3TC_DXT5_EXT is not necessarily supported as being the one mentioned to be "not designed for compressing rectangular textures".

How to create one channel 32-bit float compressed texture in OpenGL

According documentation i can create HDR compressed texture, so i do this:
funcs->glGenTextures(1, &newCompressedTexture);
funcs->glActiveTexture(GL_TEXTURE0 + g_cTileTextureUnit);
funcs->glBindTexture(GL_TEXTURE_2D, newCompressedTexture);
funcs->glTexStorage2D(GL_TEXTURE_2D, 1, oglTileInfo.m_compressedInternalFormat, g_cTileWidthWithBorder, g_cTileWidthWithBorder);
funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, g_cTileWidthWithBorder, g_cTileWidthWithBorder, GL_RED, GL_FLOAT, getUncompressedData().rData()._m_data.data());
Where oglTileInfo.m_compressedInternalFormat is GL_COMPRESSED_RED_RGTC1 or GL_COMPRESSED_RGBA_ASTC_4x4_KHR.
There is no any gl errors, shader works correctly, but value which i am getting by texture() is clamped between [0,1] and its depth only 8 bit. Everything works ok if i use GL_R32F as texture internal format, but i need compression. Thanks.
If your OpenGL implementation supports ASTC textures, you can upload pre-compressed ASTC data to the texture. However, ASTC support does not require implementations to compress texture data for you, so uploading uncompressed data is simply not allowed. You have to compress your data elsewhere before uploading it.
Also, good ASTC compression is not particularly fast, so if you're generating this floating-point data in your application, that's going to be problematic.
As for GL_COMPRESSED_RED_RGTC1, that is a normalized format. So while implementations are required to compress data for you, it's still going to clamp that data to [0, 1].
BPTC requires implementations to be able to compress such textures inline. So using one of its floating-point formats would probably be functional. However, such compression will not be particularly fast nor will it be particularly good.

How to obtain raw (unconverted) texture data in OpenGL?

I need to serialise an arbitrary OpenGL texture object to be able to restore it later with the exact same state and data.
I'm looking for a way to get the texture image data. Here's what I've found so far:
There's glGetTexImage.
It allows to gets the texture image, but it requires a specified format/type pair (like (GL_RGB, GL_HALF_FLOAT) to which it performs a conversion.
The allowed formats and types don't map 1:1 to image formats though, and won't allow to get more obscure formats like GL_R3_G3_B2 without additional conversion.
Also correctly determining the C type for base internal formats (like GL_RGB with no size) involves some non-trivial labour.
There's ARB_internalformat_query2 that allows to ask for GL_GET_TEXTURE_IMAGE_FORMAT and GL_GET_TEXTURE_IMAGE_TYPE which represent the best choices for glGetTexImage for a given texture.
Nice, but suffers from the same limitations as glGetTexImage and isn't widely available.
There's the wonderful glGetCompressedTexImage that elegantly returns the compressed texture's data as-is, but it neither works for non-compressed images nor has a counterpart that would.
None of these allows to get or set raw data for non-compressed textures. Is there a way?
The trick is, to find matches of format and type the yield the right data layout.
The allowed formats and types don't map 1:1 to image formats though, and won't allow to get more obscure formats like GL_R3_G3_B2 without additional conversion.
That would be GL_RGB, GL_UNSIGNED_BYTE_3_3_2
Also correctly determining the C type for base internal formats (like GL_RGB with no size) involves some non-trivial labour.
Yes it does. *puts on sunglasses* Deal with it! ;)
As for the internal format. I hereby refer you to
glGetTexLevelParameter(GL_TEXTURE_…, …, GL_TEXTURE_INTERNAL_FORMAT,…);
glGetTexLevelParameter(GL_TEXTURE_…, …, GL_TEXTURE_{RED,GREEN,BLUE,ALPHA,DEPTH}_TYPE, …);
glGetTexLevelParameter(GL_TEXTURE_…, …, GL_TEXTURE_{RED,GREEN,BLUE,ALPHA,DEPTH}_SIZE, …);