Clearing Mipmap Images


#1

I’m currently in the process of updating some legacy code and noticed that my old version had a function:
////////////////////////////////////////////////////////////////////
// Function: Texture::clear_ram_mipmap_images_after
// Access: Published
// Description: Discards the current system-RAM image for all mip
// levels after (not including) n, and resizes the
// vector of ram images appropriately. Calling with
// an argument of 0 is equivalent to calling
// clear_ram_mipmap_images()
////////////////////////////////////////////////////////////////////
void Texture::
clear_ram_mipmap_images_after(int n)
{
CDWriter cdata(_cycler, true);
if (n >= (int)cdata->_ram_images.size() - 1) {
return;
}
cdata->_ram_images.erase(cdata->_ram_images.begin() + n + 1, cdata->_ram_images.end());
}

I’ve been looking through the panda3D 1.10 (devel) source and haven’t found anything similar. Is there a function that still does the same thing that I’m missing? I’ve found the “clear_ram_mipmap_image(int)” function but that appears to only clear the one?

Thanks for reading.


#2

I would guess that’s equivalent to doing:

for i in range(n + 1, tex.getNumRamMipmapImages()):
    tex.clearRamMipmapImage(i)

If this is inconvenient or inadequate for your purpose, we can consider adding a function like you propose to the Panda source (or perhaps we can introduce something more idiomatic like del tex.ram_mipmap_images[n:]).

Do you know what the intent of the original function was? Perhaps to have the remainder of mipmap levels be automatically generated?


#3

Unfortunately I do not. I’ve been trying to figure out why my land appears to be underwater and have just been stepping through every single line that might be rendering the water and terrain textures. The code used to be:

texture->set_wrap_u(Texture::WM_clamp);
texture->set_wrap_v(Texture::WM_clamp);
texture->clear_ram_mipmap_images_after( static_cast< int >( imgDxt5MipChain.size() ) );
texture->set_minfilter(Texture::FT_linear_mipmap_linear);
texture->set_magfilter(Texture::FT_linear);
texture->set_anisotropic_degree(8.0f);

But “clear_ram_mipmap_images_after”, “Texture::WM_clamp”, and “Texture::FT_linear” are all deprecated, so I’ve been trying to figure out what all of them do and if they could be the cause. The only thing I have to go on for this portion is a comment saying:

// Create textures. Note that we explicitly prevent higher mip levels from being loaded, as it seems each glTexImage2D() call takes at least 1ms, regardless of texture data size.

The loop isn’t terribly inconvenient, since they only used the function 4 times in ~60k lines of code.


#4

Most of those enums are just moved; so instead of Texture::WM_clamp, you should write SamplerState::WM_clamp, etc. These settings control the texture filtering. If your terrain appears underwater I would look into potential issues with render order, or perhaps with depth write/depth test.

I think one way to avoid the performance overhead of glTexImage2D for multiple mipmaps may be to set gl-immutable-texture-storage true in Config.prc. This makes Panda use glTexStorage2D instead, which allocates the memory for all the mipmaps up-front.


#5

Thanks for the recommendations!

I did find the SamplerState and changed to that and was just assuming they did the same thing. Glad to have confirmation on that one.

I’ve been walking through render order and have looked a little at “set_depth_offset”. I’ll look at write/test next. I’ll also look into the immutable-texture-storage, the config files are currently a mess as “basic-shaders-only #f” shows up 3 times from what I can tell.