GLUBUILD2DMIPMAPLEVELS(3G)

πŸ“¦ version 1.1, in centos-stream 9, fedora 43, fedora 44

✨ GLUBUILD2DMIPMAPLEVELS ✨

okay bestie, gather round, because we're talking about gluBuild2DMipmapLevels from the GLU family (that's the 3G manual, for the record πŸ’…) and honestly? it's giving "texture wizardry" and i'm obsessed.


🌸 NAME 🌸

gluBuild2DMipmapLevels β€” builds a subset of two-dimensional mipmap levels πŸ¦‹

like, not all of them. a lil slice. a curated selection. main character energy but make it a range.


πŸ’– C SPECIFICATION πŸ’–

okay so here's the signature, copy it exactly babes:

GLint gluBuild2DMipmapLevels( GLenum target,
                              GLint internalFormat,
                              GLsizei width,
                              GLsizei height,
                              GLenum format,
                              GLenum type,
                              GLint level,
                              GLint base,
                              GLint max,
                              const void *data )

πŸŽ€ PARAMETERS πŸŽ€

ten whole params. iconic. let's go one by one, no skipping, we're not that kind of girl.

  • target β€” specifies the target texture. must be GL_TEXTURE_2D. that's it. that's the whole vibe check, and only GL_TEXTURE_2D passes πŸ’€
  • internalFormat β€” requests the internal storage of the texture image. now listen, this one's lowkey messy: the most current version of the SGI implementation of GLU does not check this value for validity before passing it on to the underlying OpenGL implementation. so if you hand it a value that the OpenGL implementation doesn't accept, you're getting an OpenGL error. the upside of not checking at the GLU level? OpenGL extensions can add brand new internal texture formats without anybody having to revise the GLU implementation. slay for extensibility ✨ but the older implementations of GLU do check this value and will raise a GLU error if it's not 1, 2, 3, or 4, or one of these symbolic constants: GL_ALPHA, GL_ALPHA4, GL_ALPHA8, GL_ALPHA12, GL_ALPHA16, GL_LUMINANCE, GL_LUMINANCE4, GL_LUMINANCE8, GL_LUMINANCE12, GL_LUMINANCE16, GL_LUMINANCE_ALPHA, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE6_ALPHA2, GL_LUMINANCE8_ALPHA8, GL_LUMINANCE12_ALPHA4, GL_LUMINANCE12_ALPHA12, GL_LUMINANCE16_ALPHA16, GL_INTENSITY, GL_INTENSITY4, GL_INTENSITY8, GL_INTENSITY12, GL_INTENSITY16, GL_RGB, GL_R3_G3_B2, GL_RGB4, GL_RGB5, GL_RGB8, GL_RGB10, GL_RGB12, GL_RGB16, GL_RGBA, GL_RGBA2, GL_RGBA4, GL_RGB5_A1, GL_RGBA8, GL_RGB10_A2, GL_RGBA12 or GL_RGBA16. that's the whole list, i counted, don't @ me πŸ™ˆ
  • width, height β€” the width and height, respectively, in pixels of the texture image. these should be a power of 2. (should. not must. live your truth but like... a power of 2, bestie. it's the move.)
  • format β€” specifies the format of the pixel data. (the original page is missing a word there, so we're all just vibing with the mystery πŸ’€). must be one of GL_COLOR_INDEX, GL_DEPTH_COMPONENT, GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_RGB, GL_RGBA, GL_BGR, GL_BGRA, GL_LUMINANCE, or GL_LUMINANCE_ALPHA.
  • type β€” specifies the data type for data. must be one of GL_UNSIGNED_BYTE, GL_BYTE, GL_BITMAP, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV, GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV, GL_UNSIGNED_INT_10_10_10_2 or GL_UNSIGNED_INT_2_10_10_10_REV. yes it's a long list. yes it's a moment. we respect it 🫢
  • level β€” specifies the mipmap level of the image data.
  • base β€” specifies the minimum mipmap level to pass to glTexImage2D.
  • max β€” specifies the maximum mipmap level to pass to glTexImage2D.
  • data β€” specifies a pointer to the image data in memory. the raw stuff. the pixels. the whole point 🌈

πŸ¦‹ DESCRIPTION πŸ¦‹

so what does this thing do. gluBuild2DMipmapLevels builds a subset of prefiltered two-dimensional texture maps of decreasing resolutions β€” the whole collection is called a mipmap β€” and this is what you use for the antialiasing of texture mapped primitives. no cap ✨

a return value of zero means success πŸŽ‰ anything else and you got a GLU error code back (go check gluErrorString, she'll explain).

here's the tea on how it actually builds: a series of mipmap levels from base to max gets built by decimating data in half along both dimensions until size 1Γ—1 is reached. at each level, each texel in the halved mipmap level is an average of the corresponding four texels in the larger mipmap level. (and in the case of rectangular images β€” screaming β€” the decimation will ultimately reach an NΓ—1 or 1Γ—N configuration. here, two texels are averaged instead.) then glTexImage2D is called to load these mipmap levels from base to max. and if max is larger than the highest mipmap level for the texture of the specified size, a GLU error code is returned (again, see gluErrorString) and nothing is loaded. not a single texel. ghost town πŸ’€

okay example time, because this is the part that makes it click:

if level is 2 and width is 16 and height is 8, the following levels are possible: 16Γ—8, 8Γ—4, 4Γ—2, 2Γ—1, 1Γ—1. these correspond to levels 2 through 6 respectively. if base is 3 and max is 5, then only mipmap levels 8Γ—4, 4Γ—2 and 2Γ—1 are loaded. however, if max is 7 then an error is returned and nothing is loaded, since max is larger than the highest mipmap level which is, in this case, 6.

so like... know your ceiling. that's the lesson πŸŽ€

the highest mipmap level can be derived from the formula:

log2(max(width,height)*(2^level))

and for extra reading: see the glTexImage1D reference page for a description of the acceptable values for the format parameter, and see the glDrawPixels reference page for a description of the acceptable values for the type parameter. iykyk πŸ“š


πŸ’… NOTES πŸ’…

  • gluBuild2DMipmapLevels is only available if the GLU version is 1.3 or greater. so check your version bestie, don't get got.
  • the formats GL_BGR, and GL_BGRA, and the types GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV, GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV, GL_UNSIGNED_INT_10_10_10_2, and GL_UNSIGNED_INT_2_10_10_10_REV are only available if the GL version is 1.2 or greater. another version gate. the gates are gating πŸšͺ

😭 ERRORS 😭

the full list of ways this can go wrong. dramatic but necessary, so buckle up:

  • GLU_INVALID_VALUE is returned if level > base, base < 0, max < base or max is > the highest mipmap level for data.
  • GLU_INVALID_VALUE is returned if width or height is < 1.
  • GLU_INVALID_ENUM is returned if internalFormat, format, or type is not legal.
  • GLU_INVALID_OPERATION is returned if type is GL_UNSIGNED_BYTE_3_3_2 or GL_UNSIGNED_BYTE_2_3_3_REV and format is not GL_RGB.
  • GLU_INVALID_OPERATION is returned if type is GL_UNSIGNED_SHORT_5_6_5 or GL_UNSIGNED_SHORT_5_6_5_REV and format is not GL_RGB.
  • GLU_INVALID_OPERATION is returned if type is GL_UNSIGNED_SHORT_4_4_4_4 or GL_UNSIGNED_SHORT_4_4_4_4_REV and format is neither GL_RGBA nor GL_BGRA.
  • GLU_INVALID_OPERATION is returned if type is GL_UNSIGNED_SHORT_5_5_5_1 or GL_UNSIGNED_SHORT_1_5_5_5_REV and format is neither GL_RGBA nor GL_BGRA.
  • GLU_INVALID_OPERATION is returned if type is GL_UNSIGNED_INT_8_8_8_8 or GL_UNSIGNED_INT_8_8_8_8_REV and format is neither GL_RGBA nor GL_BGRA.
  • GLU_INVALID_OPERATION is returned if type is GL_UNSIGNED_INT_10_10_10_2 or GL_UNSIGNED_INT_2_10_10_10_REV and format is neither GL_RGBA nor GL_BGRA.
πŸ’€ the pattern: those packed types are picky about their partner format. GL_RGBA or GL_BGRA, or it's over. periodt.

πŸ‘‘ SEE ALSO πŸ‘‘

go read these too, they're all part of the lore:

  • glDrawPixels(3G)
  • glTexImage1D(3G)
  • glTexImage2D(3G)
  • glTexImage3D(3G)
  • gluBuild1DMipmaps(3G)
  • gluBuild2DMipmaps(3G)
  • gluBuild3DMipmaps(3G)
  • gluErrorString(3G)
  • glGetTexImage(3G)
  • glGetTexLevelParameter(3G)
  • gluBuild1DMipmapLevels(3G)
  • gluBuild3DMipmapLevels(3G)

and that's the whole page bestie, we ate and left no crumbs πŸ“ this was GLUBUILD2DMIPMAPLEVELS(3G), straight out of the GLUBUILD2DMIPMAPLEVELS(3G) source/version corner of the manual β€” mipmaps forever, ily, bye πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from