In the perfect case, if the screen resolution is 1024x768, only 786432 texels are needed at a given moment, and 2 megabytes memory is enough. But in real world there is managing cost, so textures take much more memory.
Texture streaming could reduce the memory cost of texture, that is, not all the mipmaps of textures are needed at a given moment. A texture needs level 0 mipmap because it's near the camera, if it's far from the current camera, level 5 to 11 mipmaps may be enough. Camera moves in the scene a while, some mipmaps can be loaded and some mipmaps can be unloaded.
My question is how to do it effectively.
Say I have a 512x512 OpenGL texture in the scene, so it will has 10 mipmaps. From level 0 to level 9, there are: 512x512, 256x256, 128x128... and 1x1 mipmap. Simplely upload the data like this:
glBindTexture(GL_TEXTURE_2D, texId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, p1);
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, p2);
glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, p3);
...
glBindTexture(GL_TEXTURE_2D, 0);
After a while, camera goes far from this texture in the scene, 64x64 mipmap is enough, so the top 3 mipmaps are going to be unloaded:
glBindTexture(GL_TEXTURE_2D, texId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, p4);
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, p5);
glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, p6);
...
glBindTexture(GL_TEXTURE_2D, 0);
And then, camera moves towards this texture, 256x256 mipmap is needed:
glBindTexture(GL_TEXTURE_2D, texId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, p4);
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, p5);
glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, p6);
...
glBindTexture(GL_TEXTURE_2D, 0);
This is just inefficient. Basically it recreates the texture everytime although the texture id is not changed. PBOs could makes it faster but the data copying is still cost.
For a 1024x1024 OpenGL texture, can I make it uses only the lower mipmaps, say level 1 to 9, and leave the level 0 mipmap empty (do not allocate in video memory) ? In other words: Always keep a subset of mipmaps from low level to high level. Load or unload higher level mipmaps without changing the lower mipmaps of a texture. I think in hardware's perspective this might be possible.
This is what I tried: If I don't call glTexImage2D for level 0 mipmap, this texture may be in an incomplete state. But if I call glTexImage2D with a null data pointer, it will be allocated in video memory with zero data (profiling via gDEBugger).