To scale the text in my program smoothly, and in order to preserve hinting at smaller sizes, i want to store multiple atlas textures for a font in a texture as mipmaps. When a glyph is being rendered at smaller sizes, an accordingly smaller texture(mipmap) should be selected. Since these atlases do not simply become linearly smaller at smaller point sizes, but may vary in width or height due to hinting, i need to initialize each mipmap level of the texture with an individual pixel storage and texture parameters.
Since this texture will only be created once and may not be changed through the lifetime of my program, i would like to use immutable texture storages (glTextureStorage2D). how can i set individual mipmap dimensions and pixel data with these texture storages? And how can I control that the correct atlas size is chosen for a specific glyph/point size?
You can’t do it, with or without immutable storage.
glTexImage2D makes it look like you can. You can give mipmap levels whatever sizes you want. But that texture is considered incomplete unless the mipmap sizes are actually correct. That is, if a mipmap level’s size is not half the size, rounded down, of the level above it, then the texture is incomplete and cannot be fetched from.
If you need to do this, then you need to do it manually. That is, you have different regions of the same texture (or different textures if you prefer) that represent a glyph. Then you figure out which to sample from based on the visual size of the glyph, using dFdx/y in the shader.
It’s generally better to fix your font size and not scale it. Or if you’re having to do scaling (the font appears in the world), then accept that it won’t look as good scaled down.
Ok, thanks for making this clear. I think for now i will just keep my fonts fixed, its not that important for now, and this whole font rendering business is really exhausting… ^^
But what about using glTextureStorage2D with glTextureSubImage2D? It seems like you can allocate a large atlas texture to hold all mipmap levels. Will the texture still be considered mipmap incomplete if the levels are not half the size of the previous level?
But what about using glTextureStorage2D with glTextureSubImage2D? It seems like I could allocate a large texture to hold all mipmap levels with glTextureStorage2D and then define each level with an offset position in the storage using glTextureSubImage2D. Will the texture still be considered mipmap incomplete if the mipmap levels are not half the size of the previous level?