Using textures efficiently (compression, LODs)

hi there,

my code to create textures looks like this:

/* generate new texture */
GLuint texture = 0;
glCreateTextures(GL_TEXTURE_2D, 1, &texture);
glTextureStorage2D(texture, 1, GL_RGBA8, w, h);
glTextureSubImage2D(texture, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, texture_data);

//glGenerateTextureMipmap(texture);

glTextureParameteri(texture, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTextureParameteri(texture, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTextureParameteri(texture, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTextureParameteri(texture, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

fragment shader:
vec3 Ks = material_Ks * texture(map_Ks, fs_in.texcoord).rgb;

my textures are all “static”, so they dont change in size and content. thats why i thought, that using glTextureStorage2D(…) is appropriate. i dont have experience in using LODs, never tested that.

am i right, that increasing the LOD parameter in glTextureStorage2D(…) to (lets say) 10 (for 1024x1024 textures) and uncomment the glGenerateTextureMipmap(texture); will do the job?

i assume i have to compress all my .jpg and .png files to .dds (DXT1 compression) beforehand, because i have to deliver “compressed texture data” to opengl. what tool can i use for that?

thanks in advance for any suggestions !!

Not according to the image format you gave OpenGL.

You’re talking about at least 2 orthogonal things here.

What’s your final goal? Texture compression or MIPmap-based minification filtering. You can do both, either, or neither.

There are also multiple ways to achieve both. Though for quality and efficiency, you would typically prefer one tech approach over the rest.

ok, thanks. i didnt have that in mind :roll_eyes: (last 3 params)

@ dark_photon
both.

the final goal is to use glMultidrawElementsBaseVertex(…) (for now) to render all meshes with one drawcall. i need gl_DrawID as dynamically uniform “index” (4.6) in a uniform buffered transform array + material array + bindless texture array. the textures should be compressed to save gpu memory, and they should be applied efficiently on meshes (using LODs).

Ok. So textures with texels stored in GPU compressed texel formats and MIPmaps (LODs) for fast minification and/or anisotropic texture filtering.

Yes, except for the “.dds” mention.

You’ll want to pre-generate all of the MIPmap levels (LODs), and then pre-compress all of them to your chosen GPU compressed internal format(s). Finally, write these out to a texture file format that supports MIPmaps and all required OpenGL texture types and internal formats you plan to use.

On that note, you definitely don’t have to use the old, limited, D3D-based .dds format for this. Consider using the more general KTX image format for this instead:

Unlike DDS, KTX can store any OpenGL texture you can think of (IIRC), with any texture type and internal texel format possible in GL. The mapping is very near 1-to-1 with OpenGL. And there’s a free library and tools that will read and write KTX files, so you don’t need to write any code for this either.

KTX v1 actually used the same GL internal format enums to denote the texel format. KTX v2 uses the corresponding Vulkan enums instead.

Then to upload this texel data to GL, allocate your textures with MIPmap storage (e.g. via glTexStorage2D()) and then upload the data for the MIPmap levels in their pre-GPU compressed texel format representation (e.g. via glCompressedTexSubImage2D()). Finally, make the textures GPU resident for bindless access in the shader (e.g. via glGetTextureHandleARB() + glMakeTextureResidentARB()).

Also, while you’re looking at the KTX texture file format/libs, you might also check out Basis Universal:

If I recall correctly, it supports storage in a supercompressed format as well as runtime conversion/transcode to many GPU compressed texture formats (incl DXT1/3/5 aka BC1/2/3), with support for writing the result in KTX image files among others. For more info, search for “Basis” in these presentations and man pages:

I’m curious as to what the limitations of DDS are. Last I checked, which was around the DDS 10 days, it could handle pretty much everything, even array textures.

Outside of esoteric mobile-only formats, of course (and probably ASTC).

Looking back into this, it appears either KTX v1, KTX v2, or DDS with the DX10+ extensions can handle most texture layouts you’re likely to want to use.

So it mostly comes down to which internal texel formats you want to support, and whether you want to convert from D3D enums. Whereas KTX supports pretty much anything you can represent in OpenGL, OpenGL ES, or Vulkan, DDS-DX10 is limited to those that are supported on Windows.

Or you can just use some library that supports them both. Here’s one for instance that appears to support KTX v1 and DDS with DX10 extensions: