17876

opengl: adding higher resolution mipmaps to a texture

Whenever I want to use mipmaps in opengl, i need to upload the highest resolution bitmap as mipmap level 0, and then upload lower resolutions bitmaps at higher mipmap levels.

I would have liked to be able to add higher resolution mipmaps as well as lower resolution mipmaps. Presently the only hardware way I know is to start a new mipmap-ed texture and reupload all previously uploaded bitmaps.

Any other hardware way to do this?

edit: It appears GL_TEXTURE_BASE_LEVEL and GL_TEXTURE_MAX_LEVEL do not change the fact that opengl will allocate memory for all texture mipmap levels at texture creation, therefore it can't be used in this case since it's impossible to know which textures will need higher resolution mipmaps and which won't, so it would lead to extreme memory waste.

It looks that the only way to do this in hardware would be to re-create a new texture with the newly generated higher resolution mipmap at mipmap level 0, and then copy all previous lower resolution mipmaps at lower mipmap levels.

As far as I know, the only ways would be either to keep all previously generated mipmap levels in memory in case I need to reupload them (would rather not waste this much memory), regenerate all mipmap levels (won't do, way too slow), copy the previous textures mipmap levels to system memory using gltexsubimage2d and then uploading them to the new texture (that's gotta be slow), or copying them straight from the previous texture to the new texture.

So, is there a way to copy a texture's selected mipmap to a different texture's mipmap, something like "glcopytexture(texture_id_1,texture_mipmap_1,texture_id_2,texture_mipmap_2);"

edit2: It seems there is a somewhat recent extension (extension ~2009 became core in ~2012) that does this exactly (https://www.opengl.org/wiki/Texture_Storage#Texture_copy) but one of the requirements of this contract is support of computers up to 10 years old.

Answer1:

There is no requirement to upload the complete mipmap chain in order to use a texture. You can control the range of levels that are used by setting GL_TEXTURE_BASE_LEVEL and GL_TEXTURE_MAX_LEVEL.

You do have to decide what the size of the base level is [1] when you initially create the texture. But you can defer loading the data for the lowest levels, or never load them at all.

For example, say you want a texture that will at most be size 1024x1024 at full resolution, but you know that you don't need levels 0 and 1 because the object it is used for is far from the camera. You can create the texture starting at level 2 with:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 2); glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D);

Then, if you later decide that you need the texture all the way to level 0 now:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 1024, 1024, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D);

I don't think setting GL_TEXTURE_MIN_LOD is necessary, but it can't hurt. In both code sequences, you can of course provide your own mipmaps one by one instead of calling glGenerateMipmap().

The main caveat is that you need to be able to specify data of levels larger than 0. So you either need to generate your own mipmaps at runtime, or have pre-baked resources that include mipmaps.

Also, the implementation might decide to allocate the full texture up to level 0 even if you don't specify data for those levels. So you may or may not save memory this way. The only thing you can count on is that it accelerates the initial texture upload.

[1] This is not strictly true, because there are multiple valid sizes for the base level for a given size of a higher level. For example, if level 2 is size 16, level 1 can be size 32 or 33, and level 0 can be 64, 65, 66, or 67.

Recommend

  • How can I stop NetBeans 8 from deleting generated code at startup?
  • Static Publishing in Silverstripe on Large Sites
  • Eclipse 'Project > Clean…' removes my additional Android src folder. How to fix?
  • Moon orbit in relation to sun
  • Representing element as boolean with JAXB?
  • How to apply a texture to THREE.ExtrudeGeometry?
  • Having issues with creating Tile Sets in Xcode 8. Anyone have any success?
  • Using C++ templating for SFML Resource Manager
  • How to deallocate texture from memory in A-Frame?
  • Trying to use only a portion of a SKTexture using textureWithRect inTexture
  • Render face of cube map to a quad
  • Unresolved external symbol (OpenGL and c++)
  • Android multuple camera preview
  • libgdx clickable image not working
  • Create ranking for vector of double
  • Weird session behaviour in codeigniter
  • LibGdx GLES2.0 cube texel stretching
  • Reloading table causes flickering
  • Getting IIS6 to play nice with WordPress Pretty Permalinks
  • Using HTML/CSS for UI in XNA?
  • Is looping through all style sheets and classes a good idea in JavaScript?
  • Most efficient way to move table rows from one table to another
  • std::remove_copy_if_ valgrind bytes in block are possibly lost in loss record
  • Tamper-proof configuration files in .NET?
  • Ionic 2 storage is not cleaning up on uninstall - Only for signed APK
  • preg_replace Double Spaces to tab (\\t) at the beginning of a line
  • Functions in global context
  • Asynchronous UI Testing in Xcode With Swift
  • Cassandra Data Model
  • Trying to switch camera back to front but getting exception
  • Updated Ionic CLI but shows previous version (Windows)
  • Javascript + PHP Encryption with pidCrypt
  • Importing jscolor library in angular 2
  • Timeout for blocking function call, i.e., how to stop waiting for user input after X seconds?
  • WOWZA + RTMP + HTML5 Playback?
  • XCode can't find symbols for a specific iOS library/framework project
  • Windows forms listbox.selecteditem displaying “System.Data.DataRowView” instead of actual value
  • Proper folder structure for lots of source files
  • How does Linux kernel interrupt the application?
  • Conditional In-Line CSS for IE and Others?