The two functions are completely orthogonal.
The choice is between glTexImage2D
and glTexStorage2D
. Both of these allocate storage for texture images; they just do it in different ways.
glTexImage2D
is the old way of allocating storage. It creates mutable storage (there are other functions that create mutable storage too). If you want mipmaps, you have to allocate each mipmap level with a separate call to the function, manually computing the size of the mipmap image (see below for the exception to this).
glTexStorage2D
allocates immutable storage for the image data. It allocates all of the mipmaps you want all at once.
Immutable storage, as the name suggests, cannot be changed. See, you can call glTexImage2D
on the same mipmap level, with a different size. And if you do, OpenGL will destroy the original mipmap level and allocate storage for the new one. You can even change formats.
Immutable storage won't let you change any of that. You can upload new data, using functions like glTexSubImage2D
. But those functions don't change the storage; they change the contents.
glTexImage2D
and glTexStorage2D
are like malloc
. glTexSubImage2D
is like memcpy
; it only works for existing memory.
glGenerateMipmap
is a function that will take the base layer of a texture and generate the data for all of the mipmaps from that base layer (given the mipmap range). It does this one time. Think of it like a rendering function; it does its job and then it's done.
For mutable storage textures, glGenerateMipmap
will also allocate storage for any mipmaps in the mipmap range that were not previously allocated. That's why you can call glTexImage2D
once, then call glGenerateMipmap
to force it to make all of the other mipmaps without having to do it manually.