Difference between revisions of "Image Format"

From OpenGL.org
Jump to: navigation, search
(Legacy Image Formats: Added section on internal format queries.)
(Compressed formats: Info on ASTC.)
 
(20 intermediate revisions by 3 users not shown)
Line 5: Line 5:
 
== Color formats ==
 
== Color formats ==
  
Colors in OpenGL are stored in RGBA format. That is, each color has a Red, Green, Blue, and Alpha component. The Alpha value does not have an intrinsic meaning; it only does what the shader that uses it wants to. Usually, Alpha is used as a translucency value, but it depends on what the shader does with that value.
+
Colors in OpenGL are stored in RGBA format. That is, each color has a Red, Green, Blue, and Alpha component. The Alpha value does not have an intrinsic meaning; it only does what the shader that uses it wants to. Usually, Alpha is used as a translucency value, but do not make the mistake of confining your thinking to just that. Alpha means whatever ''you'' want it to.
  
{{note|Technically, any of the 4 color values can take on whatever meaning you give them in a shader. Shaders are arbitrary programs; they can consider a color value to represent a texture coordinate, a Fresnel index, or anything else they so desire.}}
+
{{note|Technically, any of the 4 color values can take on whatever meaning you give them in a shader. Shaders are arbitrary programs; they can consider a color value to represent a texture coordinate, a Fresnel index, a normal, or anything else they so desire. They're just numbers; it's how you ''use'' them that defines their meaning.}}
  
Color formats can be stored in one of 3 ways: normalized integers, floating-point, or integral. Both normalized integer and floating-point formats will resolve, in the shader, to a vector of floating-point values, whereas integral formats will resolve to a vector of integers.
+
Color formats can be stored in one of 3 ways: [[Normalized Integer|normalized integers]], floating-point, or integral. Both normalized integer and floating-point formats will resolve, in the shader, to a vector of floating-point values, whereas integral formats will resolve to a vector of integers.
  
Normalized integer formats themselves are broken down into 2 kinds: unsigned normalized and signed normalized. Unsigned normalized formats store floating-point values between 0 and 1 by converting them into integers on the range [0, MAX_INT], where MAX_INT is the largest integer for the bitdepth of that integers. For example, let's say you have a normalized integer color format that stores each component in 8 bits. If the value of a component is the integer 128, then the value it returns is 128/255, or 0.502.
+
Normalized integer formats themselves are broken down into 2 kinds: unsigned normalized and signed normalized. Unsigned normalized formats store floating-point values between 0 and 1 by converting them into integers on the range [0, MAX_INT], where MAX_INT is the largest integer for the bitdepth of that integer type. For example, let's say you have an unsigned normalized integer color format that stores each component in 8 bits. If the value of a component is the integer 128, then the value it returns is 128/255, or 0.502.
  
 
Signed normalized integer formats store the values [-1, 1], by mapping signed integers on the range [MIN_INT, MAX_INT], where MIN_INT is the largest negative integer for the bitdepth in 2's complement, while MAX_INT is the largest positive integer for the bitdepth in 2's complement.
 
Signed normalized integer formats store the values [-1, 1], by mapping signed integers on the range [MIN_INT, MAX_INT], where MIN_INT is the largest negative integer for the bitdepth in 2's complement, while MAX_INT is the largest positive integer for the bitdepth in 2's complement.
 +
 +
Integral formats are also divided into signed and unsigned integers. Signed integers are 2's complement integer values.
  
 
Image formats do not have to store each component. When the shader samples such a texture, it will still resolve to a 4-value RGBA vector. The components not stored by the image format are filled in automatically. Zeros are used if R, G, or B is missing, while a missing Alpha always resolves to 1.
 
Image formats do not have to store each component. When the shader samples such a texture, it will still resolve to a 4-value RGBA vector. The components not stored by the image format are filled in automatically. Zeros are used if R, G, or B is missing, while a missing Alpha always resolves to 1.
  
{{note|[[Texture#Swizzle_mask|Texture swizzling]] can change what the missing values are.}}
+
{{note|[[Texture Swizzle|Texture swizzling]] can change what the missing values are.}}
  
 
OpenGL has a particular syntax for writing its color format enumerants. It looks like this:
 
OpenGL has a particular syntax for writing its color format enumerants. It looks like this:
  
   GL_[''components''][''size''][''type'']
+
   GL_[{{param|components}}][{{param|size}}][{{param|type}}]
  
The ''components'' field is the list of components that the format stores. OpenGL only allows "R", "RG", "RGB", or "RGBA"; other combinations are not allowed as internal image formats. The ''size'' is the bitdepth for each component. The ''type'' indicates which of the 5 types mentioned above the format is stored as. No ''type'' at all means normalized unsigned integers. For other types, the following suffixes are used:
+
The {{param|components}} field is the list of components that the format stores. OpenGL only allows "R", "RG", "RGB", or "RGBA"; other combinations are not allowed as internal image formats. The {{param|size}} is the bitdepth for each component. The {{param|type}} indicates which of the 5 types mentioned above the format is stored as. The following suffixes are used:
  
 +
* "": No type suffix means unsigned normalized integer format.
 +
* "_SNORM": Signed normalized integer format.
 
* "F": Floating-point. Thus, {{enum|GL_RGBA32F}} is a floating-point format where each component is a 32-bit IEEE floating-point value.
 
* "F": Floating-point. Thus, {{enum|GL_RGBA32F}} is a floating-point format where each component is a 32-bit IEEE floating-point value.
 
* "I": Signed integral format. Thus {{enum|GL_RGBA8I}} gives a signed integer format where each of the four components is an integer on the range [-128, 127].
 
* "I": Signed integral format. Thus {{enum|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.
 
* "UI": Unsigned integral format. The values go from [0, MAX_INT] for the integer size.
* "_SNORM": Signed normalized integer format.
 
  
 
If you want a 3-component unsigned integral format, with 8 bits per component, you use {{enum|GL_RGB8UI}}. A 1-component [[Small Float Formats|floating-point format that uses 16-bits per component]] is {{enum|GL_R16F}}.
 
If you want a 3-component unsigned integral format, with 8 bits per component, you use {{enum|GL_RGB8UI}}. A 1-component [[Small Float Formats|floating-point format that uses 16-bits per component]] is {{enum|GL_R16F}}.
Line 40: Line 43:
 
|-
 
|-
 
| unsigned normalized (no suffix)
 
| unsigned normalized (no suffix)
| 2*, 4*, 5*, 8, 16
+
| 2<sup>1</sup>, 4<sup>2</sup>, 5<sup>2</sup>, 8, 10<sup>3</sup>, 12<sup>2</sup>, 16
 
|-
 
|-
 
| signed normalized
 
| signed normalized
Line 55: Line 58:
 
|}
 
|}
  
<nowiki>*</nowiki> These values are restricted to "RGB" and "RGBA" only. You cannot say "GL_RG4". In the case of 2, it is restricted to "RGBA" only.
+
1: These bitdepths are restricted to "RGBA" only. You cannot use {{enum|GL_RG2}}.</br>
 +
2: These bitdepths are restricted to "RGB" and "RGBA" only. You cannot use {{enum|GL_R4}}.</br>
 +
3: These values are restricted to "RGB" only. You cannot use {{enum|GL_RGBA10}}.
  
 
16-bit per-channel floating-point is also called "half-float". There is an [[Half Float Formats|article]] on the specifics of these formats.
 
16-bit per-channel floating-point is also called "half-float". There is an [[Half Float Formats|article]] on the specifics of these formats.
Line 66: Line 71:
  
 
* {{enum|GL_R3_G3_B2}}: Normalized integer, with 3 bits for R and G, but only 2 for B.
 
* {{enum|GL_R3_G3_B2}}: Normalized integer, with 3 bits for R and G, but only 2 for B.
* {{enum|GL_RGB5_A1}}: 5 bits each for RGB, 1 for Alpha. This format is generally trumped by compressed formats (see below), which give greater than 16-bit quality in much less than 16-bits of color.
+
* {{enum|GL_RGB5_A1}}: 5 bits each for RGB, 1 for Alpha. This format is generally trumped by [[#Compressed formats|compressed formats]] (see below), which give greater than 16-bit quality in much less storage than 16-bits of color.
 
* {{enum|GL_RGB10_A2}}: 10 bits each for RGB, 2 for Alpha. This can be a useful format for framebuffers, if you do not need a high-precision destination alpha value. It carries more color depth, thus preserving subtle gradations. They can also be used for normals, though there is no signed-normalized version, so you have to do the conversion manually. It is also a required format (see below), so you can count on it being present.
 
* {{enum|GL_RGB10_A2}}: 10 bits each for RGB, 2 for Alpha. This can be a useful format for framebuffers, if you do not need a high-precision destination alpha value. It carries more color depth, thus preserving subtle gradations. They can also be used for normals, though there is no signed-normalized version, so you have to do the conversion manually. It is also a required format (see below), so you can count on it being present.
 
* {{enum|GL_RGB10_A2UI}}: 10 bits each for RGB, 2 for Alpha, as unsigned integers. There is no signed integral version.
 
* {{enum|GL_RGB10_A2UI}}: 10 bits each for RGB, 2 for Alpha, as unsigned integers. There is no signed integral version.
Line 74: Line 79:
 
=== sRGB colorspace ===
 
=== sRGB colorspace ===
  
Normally, colorspaces are assumed to be linear. However, it is often useful to provide color values in non-linear colorspaces. OpenGL provides support for the [http://en.wikipedia.org/wiki/SRGB sRGB colorspace] with two formats:
+
Normally, color values in images are assumed to be in a linear colorspace. However, it is often useful to provide color values in non-linear colorspaces. OpenGL provides support for the [http://en.wikipedia.org/wiki/SRGB sRGB colorspace] with two formats:
  
 
* {{enum|GL_SRGB8}}: sRGB image with no alpha.
 
* {{enum|GL_SRGB8}}: sRGB image with no alpha.
Line 81: Line 86:
 
These are normalized integer formats.
 
These are normalized integer formats.
  
When used as a render target, OpenGL will automatically convert the output colors into the sRGB colorspace if, and ''only'' if, {{enum|GL_FRAMEBUFFER_SRGB}} is enabled. The alpha will be written as given.
+
What this means is that the values placed in images of this format are assumed to be stored in the sRGB colorspace. When fetching from sRGB images in [[Shader]]s, either through [[Sampler (GLSL)|Sampler]]s or [[Image Load Store|images]], the values retrieved are converted from the sRGB colors into linear colorspace. Thus, the shader only sees linear values.
 +
 
 +
Note that the alpha value, when present, is always considered linear.
 +
 
 +
Colors accessed from textures via GLSL samplers undergo filtering, based on [[Sampler Object|sampler properties]]. However, filtering is a linear process, while the sRGB colorspace is a non-linear colorspace. So filtering in the sRGB colorspace does not result in reasonable values. However, OpenGL implementations are allowed to decide on their own whether filtering happens before or after the colorspace conversion. The different, while certainly present, is usually not that great.
 +
 
 +
{{note|Most modern hardware (GL 3.0 or better) will do the colorspace conversion before filtering.}}
 +
 
 +
[[Framebuffer Colorspace|When images with this format are used as a render target]], OpenGL will automatically convert the output colors from linear to the sRGB colorspace if, and ''only'' if, {{enum|GL_FRAMEBUFFER_SRGB}} is enabled. The alpha will be written as given. When writing multiple outputs, only outputs written to sRGB image formats will undergo such conversion.
  
 
Note that there are compressed forms of sRGB image formats; see below for details.
 
Note that there are compressed forms of sRGB image formats; see below for details.
Line 89: Line 102:
 
Texture compression is a valuable memory-saving tool, one that you should use whenever it is applicable. There are two kinds of compressed formats in OpenGL: generic and specific.
 
Texture compression is a valuable memory-saving tool, one that you should use whenever it is applicable. There are two kinds of compressed formats in OpenGL: generic and specific.
  
Generic formats don't have any particular internal representation. OpenGL implementations are free to do whatever it wants to the data, including using a regular uncompressed format if it so desires. You cannot precompute compressed data in generic formats and upload it with the <code>glCompressedTexSubImage*</code> functions. Instead, these formats rely on the driver to compress the data for you. Because of this uncertainty, it is suggested that you avoid these in favor of compressed formats with a specific compression format.
+
Generic formats don't have any particular internal representation. OpenGL implementations are free to do whatever it wants to the data, including using a regular uncompressed format if it so desires. You cannot precompute compressed data in generic formats and upload it with the {{code|glCompressedTexSubImage*}} functions. Instead, these formats rely on the driver to compress the data for you. Because of this uncertainty, it is suggested that you avoid these in favor of compressed formats with a specific compression format.
  
 
The generic formats use the following form:
 
The generic formats use the following form:
Line 97: Line 110:
 
Where {{param|components}} can be "RED", "RG", "RGB", "RGBA", "SRGB" or "SRGB_ALPHA". The last two represent generic colors in the sRGB colorspace.
 
Where {{param|components}} can be "RED", "RG", "RGB", "RGBA", "SRGB" or "SRGB_ALPHA". The last two represent generic colors in the sRGB colorspace.
  
The specific compressed formats required by OpenGL are:
+
Core OpenGL defines a number of specific compressed formats. These are grouped into the following categories:
  
 +
'''[[Red Green Texture Compression|Red/Green compressed formats:]]'''
 
; {{enum|GL_COMPRESSED_RED_RGTC1}}
 
; {{enum|GL_COMPRESSED_RED_RGTC1}}
 
: Unsigned normalized 1-component only.
 
: Unsigned normalized 1-component only.
Line 104: Line 118:
 
: Signed normalized 1-component only.  
 
: Signed normalized 1-component only.  
 
; {{enum|GL_COMPRESSED_RG_RGTC2}}
 
; {{enum|GL_COMPRESSED_RG_RGTC2}}
: Unsigned normalized 2-component.
+
: Unsigned normalized 2-components.
 
; {{enum|GL_COMPRESSED_SIGNED_RG_RGTC2}}
 
; {{enum|GL_COMPRESSED_SIGNED_RG_RGTC2}}
 
: Signed normalized 2-components.
 
: Signed normalized 2-components.
  
Despite being color formats, compressed images are ''not'' color-renderable, for obvious reasons. Therefore, attaching a compressed image to a [[Framebuffer Objects|framebuffer object]] will cause that FBO to be incomplete and thus unusable. For similar reasons, no compressed formats can be used as the internal format of [[Renderbuffer Objects|renderbuffers]].
+
'''[[BPTC Texture Compression|BPTC compressed formats]] ({{require|4.2|texture_compression_bptc}} only):'''
 +
; {{enum|GL_COMPRESSED_RGBA_BPTC_UNORM}}
 +
: Unsigned normalized 4-components.
 +
; {{enum|GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM}}
 +
: Unsigned normalized 4-components in the sRGB colorspace.
 +
; {{enum|GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT}}
 +
: Signed, floating-point 3-components.
 +
; {{enum|GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT}}
 +
: Unsigned, floating-point 3-components.
 +
 
 +
'''[[ASTC Texture Compression]]''' ({{require||texture_compression_astc_hdr|KHR}} only) is a block compression encoding scheme that allows for a variable block size. It supports both floating-point and normalized integer formats, as well as sRGB encoding for normalized integers. It can even compress different channels separately, like RGTC formats.
 +
 
 +
Despite being color formats, compressed images are ''not'' color-renderable, for obvious reasons. Therefore, attaching a compressed image to a [[Framebuffer Object|framebuffer object]] will cause that FBO to be incomplete and thus unusable. For similar reasons, no compressed formats can be used as the internal format of [[Renderbuffer Object|renderbuffers]].
  
 
=== S3TC/DXT ===
 
=== S3TC/DXT ===
 
{{main|S3 Texture Compression}}
 
{{main|S3 Texture Compression}}
  
The [[OpenGL Extensions|extension]] GL_EXT_texture_compression_s3tc covers the popular DXT formats. It is not technically a core feature, but virtually every implementation of OpenGL written in the last 10 years uses it. It is thus a [[Ubiquitous Extensions|ubiquitous extension]].
+
The [[OpenGL Extensions|extension]] {{extref|texture_compression_s3tc|EXT}} covers the popular DXT formats. It is not technically a core feature, but virtually every implementation of OpenGL written in the last 10 years uses it. It is thus a [[Ubiquitous Extensions|ubiquitous extension]].
  
This extension provides 4 specific compressed formats. It implements what DirectX calls DXT1, 3, and 5. It has two versions of DXT1: one with a single-bit alpha, and one without.
+
This extension provides 4 specific compressed formats. It implements what DirectX called DXT1, 3, and 5 (and BC1, BC2, and BC3, after D3D 10). It has two versions of DXT1/BC1: one with a single-bit alpha, and one without.
  
The formats are: {{enum|GL_COMPRESSED_RGB_S3TC_DXT1_EXT}}, {{enum|GL_COMPRESSED_RGBA_S3TC_DXT1_EXT}}, {{enum|GL_COMPRESSED_RGBA_S3TC_DXT3_EXT}}, and {{enum|GL_COMPRESSED_RGBA_S3TC_DXT5_EXT}}. Texture compression can be combined with colors in the sRGB colorspace via the EXT_texture_sRGB extension. This defines SRGB versions o the above formats: {{enum|GL_COMPRESSED_SRGB_S3TC_DXT1_EXT}}, {{enum|GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT}}, {{enum|GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT}}, and {{enum|GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT}}.
+
The formats are: {{enum|GL_COMPRESSED_RGB_S3TC_DXT1_EXT}}, {{enum|GL_COMPRESSED_RGBA_S3TC_DXT1_EXT}}, {{enum|GL_COMPRESSED_RGBA_S3TC_DXT3_EXT}}, and {{enum|GL_COMPRESSED_RGBA_S3TC_DXT5_EXT}}. Texture compression can be combined with colors in the sRGB colorspace via the {{extref|texture_sRGB|EXT}} extension. This defines SRGB versions o the above formats: {{enum|GL_COMPRESSED_SRGB_S3TC_DXT1_EXT}}, {{enum|GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT}}, {{enum|GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT}}, and {{enum|GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT}}.
  
 
== Depth formats ==
 
== Depth formats ==
Line 125: Line 151:
 
What makes the 32-bit float depth texture particularly interesting is that, as a depth texture format, it can be used with the so-called "shadow" texture lookup functions. Color formats cannot be used with these texture functions.
 
What makes the 32-bit float depth texture particularly interesting is that, as a depth texture format, it can be used with the so-called "shadow" texture lookup functions. Color formats cannot be used with these texture functions.
  
The available formats are: {{enum|GL_DEPTH_COMPONENT16}}, {{enum|GL_DEPTH_COMPONENT24}}, {{enum|GL_DEPTH_COMPONENT32}} and {{enum|GL_DEPTH_COMPONENT_32F}}.
+
The available formats are: {{enum|GL_DEPTH_COMPONENT16}}, {{enum|GL_DEPTH_COMPONENT24}}, {{enum|GL_DEPTH_COMPONENT32}} and {{enum|GL_DEPTH_COMPONENT32F}}.
  
 
== Depth stencil formats ==
 
== Depth stencil formats ==
Line 131: Line 157:
 
These image formats are combined depth/stencil formats. They allow you to allocate a stencil buffer along with a depth buffer.
 
These image formats are combined depth/stencil formats. They allow you to allocate a stencil buffer along with a depth buffer.
  
This does ''not'' mean that you can access stencil values in a shader. Sampling from a depth/stencil texture works ''exactly'' as though it were a depth only texture. The stencil buffer is only there as part of the storage.
+
If {{require|4.3|stencil_texturing}} is not available, then depth/stencil textures are treated by [[Sampler (GLSL)|samplers]] exactly like depth-only textures. If that is available, then the texture object can have [[Stencil Texturing|a parameter set]] that allows the sampler to access the stencil part. When this parameter is set, the texture is accessed as though it were stencil-only.
  
 
There are only 2 depth/stencil formats, each providing 8 stencil bits: {{enum|GL_DEPTH24_STENCIL8}} and {{enum|GL_DEPTH32F_STENCIL8}}.
 
There are only 2 depth/stencil formats, each providing 8 stencil bits: {{enum|GL_DEPTH24_STENCIL8}} and {{enum|GL_DEPTH32F_STENCIL8}}.
  
{{note|OpenGL does provide stencil-only image formats, in the form of GL_STENCIL_INDEX8 and so forth. Never use these. No drivers ever supported these, and you will get {{enum|GL_FRAMEBUFFER_UNSUPPORTED}} errors if you try. Just use packed depth/stencil formats}}
+
== Stencil only ==
 +
 
 +
Image formats can store a stencil value. Stencil values are unsigned integer used by [[Stencil Test]]s for various effects. All of the stencil-only image formats take the enumerator form {{enum|GL_STENCIL_INDEX#}}, where "#" is the number of bits for the stencil value. The available bitdepths for the stencil are 1, 4, 8, and 16.
 +
 
 +
{{note|You are strongly advised to avoid using any bitdepth other than 8. Also, see the note below about combining depth and stencil images in a [[Framebuffer Object]].}}
 +
 
 +
Stencil only formats cannot be used for [[Texture]]s, unless {{require|4.4|texture_stencil8}} is available. In that case, the stencil formats can be used for textures. [[Sampler (GLSL)|Reading from a stencil-only texture]] is treated as reading from a one-component unsigned integer texture. So you must use {{code|usampler*}} types when accessing them, just as for [[Stencil Texturing|accessing the stencil component of depth/stencil textures]].
  
 
== Required formats ==
 
== Required formats ==
Line 175: Line 207:
  
 
* {{enum|GL_RGB10_A2}}
 
* {{enum|GL_RGB10_A2}}
 +
* {{enum|GL_RGB10_A2UI}}
 
* {{enum|GL_R11F_G11F_B10F}}
 
* {{enum|GL_R11F_G11F_B10F}}
 
* {{enum|GL_SRGB8_ALPHA8}}
 
* {{enum|GL_SRGB8_ALPHA8}}
Line 182: Line 215:
 
* {{enum|GL_DEPTH24_STENCIL8}}
 
* {{enum|GL_DEPTH24_STENCIL8}}
 
* {{enum|GL_DEPTH32F_STENCIL8}}
 
* {{enum|GL_DEPTH32F_STENCIL8}}
 +
* {{enum|GL_STENCIL_INDEX8}}, depending on the version and extensions. {{require|4.3|ES3_compatibility}} makes this a required format, but only for only for [[Renderbuffer Object|renderbuffers]]. {{require|4.4|texture_stencil8}} makes this required for both textures and renderbuffers. Without either of these, this isn't a requied format for textures or renderbuffers.
  
 
=== Texture only ===
 
=== Texture only ===
Line 243: Line 277:
 
; {{enum|GL_NUM_SAMPLE_COUNTS}}, {{enum|GL_SAMPLES}}
 
; {{enum|GL_NUM_SAMPLE_COUNTS}}, {{enum|GL_SAMPLES}}
 
: These two parameters are for querying what the valid values for the {{param|samples}} parameter that one can validly pass to multisample image storage creation functions like {{apifunc|glTexStorage2DMultisample}} or {{apifunc|glRenderbufferStorageMultisample}}. {{enum|GL_NUM_SAMPLE_COUNTS}} returns a single value: the number of valid sample counts. {{enum|GL_SAMPLES}} returns an array of {{enum|GL_NUM_SAMPLE_COUNTS}} in size, detailing the valid values for the {{param|samples}} parameter in those functions.
 
: These two parameters are for querying what the valid values for the {{param|samples}} parameter that one can validly pass to multisample image storage creation functions like {{apifunc|glTexStorage2DMultisample}} or {{apifunc|glRenderbufferStorageMultisample}}. {{enum|GL_NUM_SAMPLE_COUNTS}} returns a single value: the number of valid sample counts. {{enum|GL_SAMPLES}} returns an array of {{enum|GL_NUM_SAMPLE_COUNTS}} in size, detailing the valid values for the {{param|samples}} parameter in those functions.
: {{note|This is the only query that is available in 4.2 or {{extref|internalformat_query}}. All of the others require 4.3/{{extref|internalformat_query2}}.
+
: {{note|These are the only queries that are available in {{require|4.2|internalformat_query}}. All of the others require {{require|4.3|internalformat_query2}}. }}
 
; {{enum|GL_INTERNALFORMAT_PREFERRED}}
 
; {{enum|GL_INTERNALFORMAT_PREFERRED}}
 
: As previously stated, OpenGL is allowed to replace your given image format with a different one. If you use {{enum|GL_RGB8}}, OpenGL can promote it to {{enum|GL_RGBA8}} internally, with the implementation filling in a 1.0 for the alpha. By querying this, you can detect when such image format modification will happen. This will return a single value, which is the OpenGL image format enumerator that will be used internally by the implementation. If it's the same as the one you passed, then no promotion is done.
 
: As previously stated, OpenGL is allowed to replace your given image format with a different one. If you use {{enum|GL_RGB8}}, OpenGL can promote it to {{enum|GL_RGBA8}} internally, with the implementation filling in a 1.0 for the alpha. By querying this, you can detect when such image format modification will happen. This will return a single value, which is the OpenGL image format enumerator that will be used internally by the implementation. If it's the same as the one you passed, then no promotion is done.
 
; {{enum|GL_READ_PIXELS_FORMAT}}, {{enum|GL_READ_PIXELS_TYPE}}
 
; {{enum|GL_READ_PIXELS_FORMAT}}, {{enum|GL_READ_PIXELS_TYPE}}
: These return OpenGL enums defining the optimal pixel transfer [[Pixel_Transfer#Pixel_format|format]] and [[Pixel_Transfer#Pixel_type|type]] parameters to use when calling {{apifunc|glReadPixels}}. You should try to use this format and type whenever possible. This does not include the [[Pixel_Transfer#Pixel_layout|alignment]] or other pack parameters.
+
: These return OpenGL enums defining the optimal pixel transfer [[Pixel Transfer Format|format]] and [[Pixel Transfer Type|type]] parameters to use when calling {{apifunc|glReadPixels}}. You should try to use this format and type whenever possible. This does not include the [[Pixel Transfer Layout|alignment]] or other pack parameters.
 
; {{enum|GL_TEXTURE_IMAGE_FORMAT}}, {{enum|GL_TEXTURE_IMAGE_TYPE}}
 
; {{enum|GL_TEXTURE_IMAGE_FORMAT}}, {{enum|GL_TEXTURE_IMAGE_TYPE}}
: These return OpenGL enums defining the optimal pixel transfer [[Pixel_Transfer#Pixel_format|format]] and [[Pixel_Transfer#Pixel_type|type]] parameters to use when calling [[Texture_Storage#Direct_creation|glTexImage*]] and [[Texture_Storage#Pixel_upload|glTexSubImage*]] functions.
+
: These return OpenGL enums defining the optimal pixel transfer [[Pixel Transfer Format|format]] and [[Pixel Transfer Type|type]] parameters to use when calling [[Mutable Texture Storage|glTexImage*]] and [[Texture Pixel Upload|glTexSubImage*]] functions.
 
; {{enum|GL_GET_TEXTURE_IMAGE_FORMAT}}, {{enum|GL_GET_TEXTURE_IMAGE_TYPE}}
 
; {{enum|GL_GET_TEXTURE_IMAGE_FORMAT}}, {{enum|GL_GET_TEXTURE_IMAGE_TYPE}}
: These return OpenGL enums defining the optimal pixel transfer [[Pixel_Transfer#Pixel_format|format]] and [[Pixel_Transfer#Pixel_type|type]] parameters to use when calling {{apifunc|glGetTexImage​}}.
+
: These return OpenGL enums defining the optimal pixel transfer [[Pixel Transfer Format|format]] and [[Pixel Transfer Type|type]] parameters to use when calling {{apifunc|glGetTexImage}}.
 
; {{enum|GL_TEXTURE_COMPRESSED_BLOCK_WIDTH}}, {{enum|GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT}}
 
; {{enum|GL_TEXTURE_COMPRESSED_BLOCK_WIDTH}}, {{enum|GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT}}
 
: Compressed image formats tend to have their data organized into blocks, which are the smallest individual unit of a compressed texture. These enums return the width and height of a block in this compressed image format. If the format is not compressed, they return 0.
 
: Compressed image formats tend to have their data organized into blocks, which are the smallest individual unit of a compressed texture. These enums return the width and height of a block in this compressed image format. If the format is not compressed, they return 0.
Line 274: Line 308:
 
Luminance and intensity are not considered color-renderable. Therefore, you cannot bind textures of this format to a [[Framebuffer Objects|FBO]].
 
Luminance and intensity are not considered color-renderable. Therefore, you cannot bind textures of this format to a [[Framebuffer Objects|FBO]].
  
Texture objects can have [[Textures#Swizzle_mask|swizzle masks]] set on them that allows you to replicate this functionality in a more generic way.
+
Texture objects can have [[Texture Swizzle|swizzle masks]] set on them that allows you to replicate this functionality in a more generic way.
  
 
== See Also ==
 
== See Also ==

Latest revision as of 14:42, 9 May 2015

An Image Format describes the way that the images in Textures and renderbuffers store their data. They define the meaning of the image's data.

There are three basic kinds of image formats: color, depth, and depth/stencil. Unless otherwise specified, all formats can be used for textures and renderbuffers equally. Also, unless otherwise specified, all formats can be multisampled equally.

Color formats

Colors in OpenGL are stored in RGBA format. That is, each color has a Red, Green, Blue, and Alpha component. The Alpha value does not have an intrinsic meaning; it only does what the shader that uses it wants to. Usually, Alpha is used as a translucency value, but do not make the mistake of confining your thinking to just that. Alpha means whatever you want it to.

Note: Technically, any of the 4 color values can take on whatever meaning you give them in a shader. Shaders are arbitrary programs; they can consider a color value to represent a texture coordinate, a Fresnel index, a normal, or anything else they so desire. They're just numbers; it's how you use them that defines their meaning.

Color formats can be stored in one of 3 ways: normalized integers, floating-point, or integral. Both normalized integer and floating-point formats will resolve, in the shader, to a vector of floating-point values, whereas integral formats will resolve to a vector of integers.

Normalized integer formats themselves are broken down into 2 kinds: unsigned normalized and signed normalized. Unsigned normalized formats store floating-point values between 0 and 1 by converting them into integers on the range [0, MAX_INT], where MAX_INT is the largest integer for the bitdepth of that integer type. For example, let's say you have an unsigned normalized integer color format that stores each component in 8 bits. If the value of a component is the integer 128, then the value it returns is 128/255, or 0.502.

Signed normalized integer formats store the values [-1, 1], by mapping signed integers on the range [MIN_INT, MAX_INT], where MIN_INT is the largest negative integer for the bitdepth in 2's complement, while MAX_INT is the largest positive integer for the bitdepth in 2's complement.

Integral formats are also divided into signed and unsigned integers. Signed integers are 2's complement integer values.

Image formats do not have to store each component. When the shader samples such a texture, it will still resolve to a 4-value RGBA vector. The components not stored by the image format are filled in automatically. Zeros are used if R, G, or B is missing, while a missing Alpha always resolves to 1.

Note: Texture swizzling can change what the missing values are.

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

 GL_[components​][size​][type​]

The components​ field is the list of components that the format stores. OpenGL only allows "R", "RG", "RGB", or "RGBA"; other combinations are not allowed as internal image formats. The size​ is the bitdepth for each component. The type​ indicates which of the 5 types mentioned above the format is stored as. The following suffixes are used:

  • "": 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.

If you want a 3-component unsigned integral format, with 8 bits per component, you use GL_RGB8UI. A 1-component floating-point format that uses 16-bits per component is GL_R16F.

For each type of color format, there is a limit on the available bitdepths per component:

format type bitdepths per component
unsigned normalized (no suffix) 21, 42, 52, 8, 103, 122, 16
signed normalized 8, 16
unsigned integral 8, 16, 32
signed integral 8, 16, 32
floating point 16, 32

1: These bitdepths are restricted to "RGBA" only. You cannot use GL_RG2.
2: These bitdepths are restricted to "RGB" and "RGBA" only. You cannot use GL_R4.
3: These values are restricted to "RGB" only. You cannot use GL_RGBA10.

16-bit per-channel floating-point is also called "half-float". There is an article on the specifics of these formats.

The bitdepth can also be omitted as well, but only with unsigned normalized formats. Doing so gives OpenGL the freedom to pick a bitdepth. It is generally best to select one for yourself though.

Special color formats

There are a number of color formats that exist outside of the normal syntax described above.

  • GL_R3_G3_B2: Normalized integer, with 3 bits for R and G, but only 2 for B.
  • GL_RGB5_A1: 5 bits each for RGB, 1 for Alpha. This format is generally trumped by compressed formats (see below), which give greater than 16-bit quality in much less storage than 16-bits of color.
  • GL_RGB10_A2: 10 bits each for RGB, 2 for Alpha. This can be a useful format for framebuffers, if you do not need a high-precision destination alpha value. It carries more color depth, thus preserving subtle gradations. They can also be used for normals, though there is no signed-normalized version, so you have to do the conversion manually. It is also a required format (see below), so you can count on it being present.
  • GL_RGB10_A2UI: 10 bits each for RGB, 2 for Alpha, as unsigned integers. There is no signed integral version.
  • GL_R11F_G11F_B10F: This uses special 11 and 10-bit floating-point values. An 11-bit float has no sign-bit; it has 6 bits of mantissa and 5 bits of exponent. A 10-bit float has no sign-bit, 5 bits of mantissa and 5 bits of exponent. This is very economical for floating-point values (using only 32-bits per value), so long as your floating-point data will fit within the given range. And so long as you can live without the destination alpha.
  • GL_RGB9_E5: This one is complicated. It is an RGB format of type floating-point. The 3 color values have 9 bits of precision, and they share a single exponent. The computation for these values is not as simple as for GL_R11F_G11F_B10F, and they aren't appropriate for everything. But they can provide better results than that format if most of the colors in the image have approximately the same exponent, or are too small to be significant. This is a required format, but it is not required for renderbuffers; do not expect to be able to render to these.

sRGB colorspace

Normally, color values in images are assumed to be in a linear colorspace. However, it is often useful to provide color values in non-linear colorspaces. OpenGL provides support for the sRGB colorspace with two formats:

  • GL_SRGB8: sRGB image with no alpha.
  • GL_SRGB8_ALPHA8: sRGB image with a linear Alpha.

These are normalized integer formats.

What this means is that the values placed in images of this format are assumed to be stored in the sRGB colorspace. When fetching from sRGB images in Shaders, either through Samplers or images, the values retrieved are converted from the sRGB colors into linear colorspace. Thus, the shader only sees linear values.

Note that the alpha value, when present, is always considered linear.

Colors accessed from textures via GLSL samplers undergo filtering, based on sampler properties. However, filtering is a linear process, while the sRGB colorspace is a non-linear colorspace. So filtering in the sRGB colorspace does not result in reasonable values. However, OpenGL implementations are allowed to decide on their own whether filtering happens before or after the colorspace conversion. The different, while certainly present, is usually not that great.

Note: Most modern hardware (GL 3.0 or better) will do the colorspace conversion before filtering.

When images with this format are used as a render target, OpenGL will automatically convert the output colors from linear to the sRGB colorspace if, and only if, GL_FRAMEBUFFER_SRGB is enabled. The alpha will be written as given. When writing multiple outputs, only outputs written to sRGB image formats will undergo such conversion.

Note that there are compressed forms of sRGB image formats; see below for details.

Compressed formats

Texture compression is a valuable memory-saving tool, one that you should use whenever it is applicable. There are two kinds of compressed formats in OpenGL: generic and specific.

Generic formats don't have any particular internal representation. OpenGL implementations are free to do whatever it wants to the data, including using a regular uncompressed format if it so desires. You cannot precompute compressed data in generic formats and upload it with the glCompressedTexSubImage*​ functions. Instead, these formats rely on the driver to compress the data for you. Because of this uncertainty, it is suggested that you avoid these in favor of compressed formats with a specific compression format.

The generic formats use the following form:

 GL_COMPRESSED_components

Where components​ can be "RED", "RG", "RGB", "RGBA", "SRGB" or "SRGB_ALPHA". The last two represent generic colors in the sRGB colorspace.

Core OpenGL defines a number of specific compressed formats. These are grouped into the following categories:

Red/Green compressed formats:

GL_COMPRESSED_RED_RGTC1
Unsigned normalized 1-component only.
GL_COMPRESSED_SIGNED_RED_RGTC1
Signed normalized 1-component only.
GL_COMPRESSED_RG_RGTC2
Unsigned normalized 2-components.
GL_COMPRESSED_SIGNED_RG_RGTC2
Signed normalized 2-components.

BPTC compressed formats (OpenGL 4.2 or ARB_texture_compression_bptc only):

GL_COMPRESSED_RGBA_BPTC_UNORM
Unsigned normalized 4-components.
GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM
Unsigned normalized 4-components in the sRGB colorspace.
GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT
Signed, floating-point 3-components.
GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT
Unsigned, floating-point 3-components.

ASTC Texture Compression (KHR_texture_compression_astc_hdr only) is a block compression encoding scheme that allows for a variable block size. It supports both floating-point and normalized integer formats, as well as sRGB encoding for normalized integers. It can even compress different channels separately, like RGTC formats.

Despite being color formats, compressed images are not color-renderable, for obvious reasons. Therefore, attaching a compressed image to a framebuffer object will cause that FBO to be incomplete and thus unusable. For similar reasons, no compressed formats can be used as the internal format of renderbuffers.

S3TC/DXT

The extension EXT_texture_compression_s3tc covers the popular DXT formats. It is not technically a core feature, but virtually every implementation of OpenGL written in the last 10 years uses it. It is thus a ubiquitous extension.

This extension provides 4 specific compressed formats. It implements what DirectX called DXT1, 3, and 5 (and BC1, BC2, and BC3, after D3D 10). It has two versions of DXT1/BC1: one with a single-bit alpha, and one without.

The formats are: GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, and GL_COMPRESSED_RGBA_S3TC_DXT5_EXT. Texture compression can be combined with colors in the sRGB colorspace via the EXT_texture_sRGB extension. This defines SRGB versions o the above formats: GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, and GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT.

Depth formats

These image formats store depth information. There are two kinds of depth formats: normalized integer and floating-point. The normalized integer versions work similar to normalized integers for color formats; they map the integer range onto the depth values [0, 1]. The floating-point version can store any 32-bit floating-point value.

What makes the 32-bit float depth texture particularly interesting is that, as a depth texture format, it can be used with the so-called "shadow" texture lookup functions. Color formats cannot be used with these texture functions.

The available formats are: GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32 and GL_DEPTH_COMPONENT32F.

Depth stencil formats

These image formats are combined depth/stencil formats. They allow you to allocate a stencil buffer along with a depth buffer.

If OpenGL 4.3 or ARB_stencil_texturing is not available, then depth/stencil textures are treated by samplers exactly like depth-only textures. If that is available, then the texture object can have a parameter set that allows the sampler to access the stencil part. When this parameter is set, the texture is accessed as though it were stencil-only.

There are only 2 depth/stencil formats, each providing 8 stencil bits: GL_DEPTH24_STENCIL8 and GL_DEPTH32F_STENCIL8.

Stencil only

Image formats can store a stencil value. Stencil values are unsigned integer used by Stencil Tests for various effects. All of the stencil-only image formats take the enumerator form GL_STENCIL_INDEX#, where "#" is the number of bits for the stencil value. The available bitdepths for the stencil are 1, 4, 8, and 16.

Note: You are strongly advised to avoid using any bitdepth other than 8. Also, see the note below about combining depth and stencil images in a Framebuffer Object.

Stencil only formats cannot be used for Textures, unless OpenGL 4.4 or ARB_texture_stencil8 is available. In that case, the stencil formats can be used for textures. Reading from a stencil-only texture is treated as reading from a one-component unsigned integer texture. So you must use usampler*​ types when accessing them, just as for accessing the stencil component of depth/stencil textures.

Required formats

The OpenGL specification is fairly lenient about what image formats OpenGL implementations provide. It allows implementations to fall-back to other formats transparently, even when doing so would degrade the visual quality of the image due to being at a lower bitdepth.

However, the specification also provides a list of formats that must be supported exactly as is. That is, the implementation must support the number of components, and it must support the bitdepth in question, or a larger one. The implementation is forbidden to lose information from these formats. So, while an implementation may choose to turn GL_RGB4 into GL_R3_G3_B2, it is not permitted to turn GL_RGB8 into GL_RGB4 internally.

These formats should be regarded as perfectly safe for use.

Texture and Renderbuffer

These formats are required for both textures and renderbuffers. Any of the combinations presented in each row is a required format.

Base format Data type Bitdepth per component
RGBA, RG, RED unsigned normalized 8, 16
RGBA, RG, RED float 16, 32
RGBA, RG, RED signed integral 8, 16, 32
RGBA, RG, RED unsigned integral 8, 16, 32

Also, the following other formats must be supported for both textures and renderbuffers:

  • GL_RGB10_A2
  • GL_RGB10_A2UI
  • GL_R11F_G11F_B10F
  • GL_SRGB8_ALPHA8
  • GL_DEPTH_COMPONENT16
  • GL_DEPTH_COMPONENT24
  • GL_DEPTH_COMPONENT32F
  • GL_DEPTH24_STENCIL8
  • GL_DEPTH32F_STENCIL8
  • GL_STENCIL_INDEX8, depending on the version and extensions. OpenGL 4.3 or ARB_ES3_compatibility makes this a required format, but only for only for renderbuffers. OpenGL 4.4 or ARB_texture_stencil8 makes this required for both textures and renderbuffers. Without either of these, this isn't a requied format for textures or renderbuffers.

Texture only

These formats must be supported for textures. They may be supported for renderbuffers, but the OpenGL specification does not require it.

Base format Data type Bitdepth per component
RGB unsigned normalized 8, 16
RGBA, RGB, RG, RED signed normalized 8, 16
RGB float 16, 32
RGB signed integral 8, 16, 32
RGB unsigned integral 8, 16, 32
RG, RED unsigned integral Compressed with RGTC

These additional formats are required:

  • GL_SRGB8
  • GL_RGB9_E5

Image format queries

Image Format Queries
Core in version 4.5
Core since version 4.3
Core ARB extension ARB_internalformat_query, ARB_internalformat_query2

OpenGL image formats can have a number of properties associated with them that are implementation-defined. OpenGL provides a mechanism to query these properties, using these functions:

void glGetInternalFormativ(GLenum target​, GLenum internalformat​, GLenum pname​, GLsizei bufSize​, GLint *params​);
void glGetInternalFormati64v(GLenum target​, GLenum internalformat​, GLenum pname​, GLsizei bufSize​, GLint64 *params​);

The property of an image format is dependent on the texture type it is used with (or renderbuffer, for those formats that can be used with renderbuffers). Therefore, the target​ is one of the texture targets or `GL_RENDERBUFFER`. internalformat​ is the image format that you are querying a parameter for.

pname​ is one of the parameters you can query. Parameter results can be more than one value, so you must pass an array to store the result in.

There are numerous parameters, as outlined on the reference documentation page for those functions. Here are a few of the important ones and their meaning:

GL_NUM_SAMPLE_COUNTS, GL_SAMPLES
These two parameters are for querying what the valid values for the samples​ parameter that one can validly pass to multisample image storage creation functions like glTexStorage2DMultisample or glRenderbufferStorageMultisample. GL_NUM_SAMPLE_COUNTS returns a single value: the number of valid sample counts. GL_SAMPLES returns an array of GL_NUM_SAMPLE_COUNTS in size, detailing the valid values for the samples​ parameter in those functions.
Note: These are the only queries that are available in OpenGL 4.2 or ARB_internalformat_query. All of the others require OpenGL 4.3 or ARB_internalformat_query2.
GL_INTERNALFORMAT_PREFERRED
As previously stated, OpenGL is allowed to replace your given image format with a different one. If you use GL_RGB8, OpenGL can promote it to GL_RGBA8 internally, with the implementation filling in a 1.0 for the alpha. By querying this, you can detect when such image format modification will happen. This will return a single value, which is the OpenGL image format enumerator that will be used internally by the implementation. If it's the same as the one you passed, then no promotion is done.
GL_READ_PIXELS_FORMAT, GL_READ_PIXELS_TYPE
These return OpenGL enums defining the optimal pixel transfer format and type parameters to use when calling glReadPixels. You should try to use this format and type whenever possible. This does not include the alignment or other pack parameters.
GL_TEXTURE_IMAGE_FORMAT, GL_TEXTURE_IMAGE_TYPE
These return OpenGL enums defining the optimal pixel transfer format and type parameters to use when calling glTexImage* and glTexSubImage* functions.
GL_GET_TEXTURE_IMAGE_FORMAT, GL_GET_TEXTURE_IMAGE_TYPE
These return OpenGL enums defining the optimal pixel transfer format and type parameters to use when calling glGetTexImage.
GL_TEXTURE_COMPRESSED_BLOCK_WIDTH, GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT
Compressed image formats tend to have their data organized into blocks, which are the smallest individual unit of a compressed texture. These enums return the width and height of a block in this compressed image format. If the format is not compressed, they return 0.
GL_TEXTURE_COMPRESSED_BLOCK_SIZE
The size in bytes of a block in a compressed texture using this format. Or 0, if the format isn't compressed.

Legacy Image Formats

As with other deprecated functionality, it is advised that you not rely on these features.

Luminance and intensity formats are color formats. They are one or two channel formats like RED or RG, but they specify particular behavior.

When a GL_RED format is sampled in a shader, the resulting vec4 is (Red, 0, 0, 1). When a GL_INTENSITY format is sampled, the resulting vec4 is (I, I, I, I). The single intensity value is read into all four components. For GL_LUMINANCE, the result is (L, L, L, 1). There is also a two-channel GL_LUMINANCE_ALPHA format, which gives (L, L, L, A).

Intensity comes in 8 and 16-bit flavors (GL_INTENSITY8, GL_INTENSITY16). Similarly, luminance and luminance/alpha formats come in 8 and 16-bit flavors (GL_LUMINANCE8, GL_LUMINANCE_ALPHA16).

This was more useful in the pre-shader days, when converting a single-channel image into a multi-channel image was harder than doing a swizzle mask like:

 colorFromTexture.rrrr

Luminance and intensity are not considered color-renderable. Therefore, you cannot bind textures of this format to a FBO.

Texture objects can have swizzle masks set on them that allows you to replicate this functionality in a more generic way.

See Also

Retrieved from "http://www.opengl.org/wiki_132/index.php?title=Image_Format&oldid=12518"