GLTEXTUREVIEW(3G)

๐ŸŒธ NAME ๐ŸŒธ

okay bestie, this is GLTEXTUREVIEW(3G) โ€” and yes, the header has a literal [FIXME: manual] placeholder in it, we love a work-in-progress moment. ๐Ÿ’… The actual function is glTextureView: it initializes a texture as a data alias, aka a view, of another texture's data store. It's giving "same storage, new outfit." โœจ

โœจ C SPECIFICATION โœจ

void glTextureView(GLuint texture, GLenum target, GLuint origtexture,
                   GLenum internalformat, GLuint minlevel,
                   GLuint numlevels, GLuint minlayer, GLuint numlayers);

๐ŸŽ€ PARAMETERS ๐ŸŽ€

  • texture โ€” the texture object you're initializing as a view. It's the one getting the glow-up.
  • target โ€” the target for that newly initialized texture. Compatible energy is required, more on that below.
  • origtexture โ€” the name of the texture object you're making a view of. The parent, the source, the main character. ๐Ÿ‘‘
  • internalformat โ€” the internal format for the brand-new view.
  • minlevel โ€” lowest level of detail included in the view.
  • numlevels โ€” how many levels of detail the view includes.
  • minlayer โ€” index of the first layer included in the view.
  • numlayers โ€” number of layers included in the view.

๐Ÿฆ‹ DESCRIPTION ๐Ÿฆ‹

glTextureView initializes a texture object as an alias โ€” a view โ€” of another texture object. The new texture shares some or all of the parent texture's data store. Yes, sharing is caring, and this is literally that. ๐Ÿซถ

The texture argument is a name previously reserved by a successful call to glGenTextures(), but that has not yet been bound or given a target. Don't skip that part, bestie, it matters. ๐Ÿ˜ญ

target is the target for the newly initialized texture, and it must be compatible with the target of the parent texture given in origtexture. The compatibility tea is exactly this:

  • GL_TEXTURE_1D โ†’ compatible new targets: GL_TEXTURE_1D, GL_TEXTURE_1D_ARRAY
  • GL_TEXTURE_2D โ†’ compatible new targets: GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY
  • GL_TEXTURE_3D โ†’ compatible new targets: GL_TEXTURE_3D
  • GL_TEXTURE_CUBE_MAP โ†’ compatible new targets: GL_TEXTURE_CUBE_MAP, GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_CUBE_MAP_ARRAY
  • GL_TEXTURE_RECTANGLE โ†’ compatible new targets: GL_TEXTURE_RECTANGLE
  • GL_TEXTURE_BUFFER โ†’ compatible new targets: none
  • GL_TEXTURE_1D_ARRAY โ†’ compatible new targets: GL_TEXTURE_1D, GL_TEXTURE_1D_ARRAY
  • GL_TEXTURE_2D_ARRAY โ†’ compatible new targets: GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY
  • GL_TEXTURE_CUBE_MAP_ARRAY โ†’ compatible new targets: GL_TEXTURE_CUBE_MAP, GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_CUBE_MAP_ARRAY
  • GL_TEXTURE_2D_MULTISAMPLE โ†’ compatible new targets: GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MULTISAMPLE_ARRAY
  • GL_TEXTURE_2D_MULTISAMPLE_ARRAY โ†’ compatible new targets: GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MULTISAMPLE_ARRAY

That's the compatibility vibe check. ๐ŸŒˆ No cap, every single mapping is right there. ๐Ÿ’–

The value of GL_TEXTURE_IMMUTABLE_FORMAT for origtexture must be GL_TRUE. Once it's initialized, texture literally inherits the data store of the parent texture, origtexture, and it's usable as a normal texture object with target target. The data in that shared store gets reinterpreted with the new internal format you passed in internalformat. ๐Ÿ’…

And internalformat has to be compatible with the parent texture's internal format, fr fr โ€” the whole compatibility situation is this iconic little chart:

  • 128-bit โ€” GL_RGBA32F, GL_RGBA32UI, GL_RGBA32I
  • 96-bit โ€” GL_RGB32F, GL_RGB32UI, GL_RGB32I
  • 64-bit โ€” GL_RGBA16F, GL_RG32F, GL_RGBA16UI, GL_RG32UI, GL_RGBA16I, GL_RG32I, GL_RGBA16, GL_RGBA16_SNORM
  • 48-bit โ€” GL_RGB16, GL_RGB16_SNORM, GL_RGB16F, GL_RGB16UI, GL_RGB16I
  • 32-bit โ€” GL_RG16F, GL_R11F_G11F_B10F, GL_R32F, GL_RGB10_A2UI, GL_RGBA8UI, GL_RG16UI, GL_R32UI, GL_RGBA8I, GL_RG16I, GL_R32I, GL_RGB10_A2, GL_RGBA8, GL_RG16, GL_RGBA8_SNORM, GL_RG16_SNORM, GL_SRGB8_ALPHA8, GL_RGB9_E5
  • 24-bit โ€” GL_RGB8, GL_RGB8_SNORM, GL_SRGB8, GL_RGB8UI, GL_RGB8I
  • 16-bit โ€” GL_R16F, GL_RG8UI, GL_R16UI, GL_RG8I, GL_R16I, GL_RG8, GL_R16, GL_RG8_SNORM, GL_R16_SNORM
  • 8-bit โ€” GL_R8UI, GL_R8I, GL_R8, GL_R8_SNORM
  • GL_RGTC1_RED โ€” GL_COMPRESSED_RED_RGTC1, GL_COMPRESSED_SIGNED_RED_RGTC1
  • GL_RGTC2_RG โ€” GL_COMPRESSED_RG_RGTC2, GL_COMPRESSED_SIGNED_RG_RGTC2
  • GL_BPTC_UNORM โ€” GL_COMPRESSED_RGBA_BPTC_UNORM, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM
  • GL_BPTC_FLOAT โ€” GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT

Okay so if the original texture is an array, or has multiple mipmap levels, then minlayer, numlayers, minlevel, and numlevels are the girlies in charge of which of those slices and levels count as part of the texture. ๐ŸŽ€ And heads up: minlevel and minlayer are relative to the view of the original texture. If numlayers or numlevels go past the edge of the original texture, they get clamped to the max extent of the original texture. No overflow drama. โœจ

If the new texture's target is GL_TEXTURE_CUBE_MAP, then that clamped numlayers must be equal to 6. Periodt. And if the new texture's target is GL_TEXTURE_CUBE_MAP_ARRAY, then numlayers counts layer-faces rather than layers, and the clamped numlayers must be a multiple of 6. Also, if the new texture's target is GL_TEXTURE_CUBE_MAP or GL_TEXTURE_CUBE_MAP_ARRAY, the width and height of the original texture's levels must be equal. ๐Ÿ’–

When the original texture's target is GL_TEXTURE_CUBE_MAP, the layer parameters are interpreted in the same order as if it were a GL_TEXTURE_CUBE_MAP_ARRAY with 6 layer-faces. Same order, different outfit. ๐Ÿฆ‹

If target is GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_RECTANGLE, or GL_TEXTURE_2D_MULTISAMPLE, then numlayers must equal 1. Like, respectfully, one layer only. ๐Ÿ™ˆ

The dimensions of the original texture must be less than or equal to the maximum supported dimensions of the new target. Example time, bestie: if the original texture has a GL_TEXTURE_2D_ARRAY target and its width is greater than GL_MAX_CUBE_MAP_TEXTURE_SIZE, an error will be generated if glTextureView is called to create a GL_TEXTURE_CUBE_MAP view. So likeโ€ฆ check your sizes before you commit. ๐Ÿ’€

Texture commands that take a level or layer parameter โ€” think glTexSubImage2D() โ€” interpret that parameter as being relative to the view of the texture. i.e. the mipmap level of the data store that would be updated via glTexSubImage2D() would be the sum of level and the value of GL_TEXTURE_VIEW_MIN_LEVEL. Math but make it fashion. ๐Ÿงฎ๐Ÿ’…


๐Ÿ’€ ERRORS ๐Ÿ’€

  • GL_INVALID_VALUE is generated if minlayer or minlevel are larger than the greatest layer or level of origtexture.
  • GL_INVALID_OPERATION is generated if target is not compatible with the target of origtexture.
  • GL_INVALID_OPERATION is generated if the dimensions of origtexture are greater than the maximum supported dimensions for target.
  • GL_INVALID_OPERATION is generated if internalformat is not compatible with the internal format of origtexture.
  • GL_INVALID_OPERATION is generated if texture has already been bound or otherwise given a target. (Not me reusing a texture name ๐Ÿ˜ญ โ€” yeah that's a whole error.)
  • GL_INVALID_OPERATION is generated if the value of GL_TEXTURE_IMMUTABLE_FORMAT for origtexture is not GL_TRUE.
  • GL_INVALID_OPERATION is generated if origtexture is not the name of an existing texture object.
  • GL_INVALID_VALUE is generated if target is GL_TEXTURE_CUBE_MAP and numlayers is not 6, or if target is GL_TEXTURE_CUBE_MAP_ARRAY and numlayers is not an integer multiple of 6.
  • GL_INVALID_VALUE is generated if target is GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_RECTANGLE, or GL_TEXTURE_2D_MULTISAMPLE and numlayers does not equal 1.
  • GL_INVALID_VALUE is generated if texture is zero or is not the name of a texture previously returned from a successful call to glGenTextures().
Ngl the error list is long, but every single one of these is a real vibe check failing. Read them. Memorize them. Slay. ๐Ÿ”ฅ

๐ŸŒˆ ASSOCIATED GETS ๐ŸŒˆ

glTexParameter() with arguments GL_TEXTURE_VIEW_MIN_LEVEL, GL_TEXTURE_VIEW_NUM_LEVELS, GL_TEXTURE_VIEW_MIN_LAYER, GL_TEXTURE_VIEW_NUM_LAYERS, or GL_TEXTURE_IMMUTABLE_LEVELS. That's the whole squad right there. ๐Ÿ‘‘

โœจ VERSION SUPPORT โœจ

okay bestie, here's the vibe check on where you can actually use this ๐Ÿ’… the table in the original is giving "which OpenGL versions even know she exists", and the answer is: she was a late bloomer, no cap.

  • Function / Feature Name: glTextureView
  • OpenGL 2.0: nope โ€” -
  • OpenGL 2.1: nope โ€” -
  • OpenGL 3.0: nope โ€” -
  • OpenGL 3.1: nope โ€” -
  • OpenGL 3.2: nope โ€” -
  • OpenGL 3.3: nope โ€” -
  • OpenGL 4.0: nope โ€” -
  • OpenGL 4.1: nope โ€” -
  • OpenGL 4.2: nope โ€” -
  • OpenGL 4.3: โœ… yes queen
  • OpenGL 4.4: โœ… yes queen
  • OpenGL 4.5: โœ… yes queen

tl;dr: she said "I'll arrive when I'm ready" and arrived in 4.3. Before that? literally not a thing. ๐Ÿซถ


๐ŸŒธ SEE ALSO ๐ŸŒธ

these are the besties in her orbit, go say hi ๐Ÿ‘‹

  • glTexStorage1D()
  • glTexStorage2D()
  • glTexStorage3D()
  • glGetTexParameter()

Copyright ยฉ 2013-2014 Khronos Group. This material may be distributed subject to the terms and conditions set forth in the Open Publication License, v 1.0, 8 June 1999. http://opencontent.org/openpub/

Copyright ยฉ 2013-2014 Khronos Group


okay that's the whole page, you made it to the end, so proud of you fr fr ๐ŸŽ€ the original footer is serving [FIXME: source] with the date 08/09/2021 and the page name GLTEXTUREVIEW(3G) โ€” yes, the source field is literally still a FIXME, iconic of them honestly ๐Ÿ’€ anyway, go forth and make texture views, bestie โœจ๐Ÿฆ‹๐Ÿ’–

๐Ÿ“ฆ where this page comes from