1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-09-15 18:57:08 +00:00

IrrlichtMt: Implement mip-mapping for RTTs (#16434)

This can be helpful to draw fonts memory-efficiently at varying scales.

Adds ETCF_CREATE_RTT_MIP_MAPS to generate mip-maps on request.
This commit is contained in:
SmallJoker 2025-09-04 18:58:23 +02:00 committed by GitHub
parent e86d2fea8d
commit 024e1d2d27
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 43 additions and 44 deletions

View file

@ -66,6 +66,11 @@ enum E_TEXTURE_CREATION_FLAG
not recommended to enable this flag. */
ETCF_NO_ALPHA_CHANNEL = 0x00000020,
/** Creates Render Target Textures with mipmap levels.
See also: `ETCF_CREATE_MIP_MAPS` for other textures.
This is disabled by default. */
ETCF_CREATE_RTT_MIP_MAPS = 0x00000040,
//! Allow the driver to keep a copy of the texture in memory
/** Enabling this makes calls to ITexture::lock a lot faster, but costs main memory.
This is disabled by default.

View file

@ -84,9 +84,17 @@ CNullDriver::CNullDriver(io::IFileSystem *io, const core::dimension2d<u32> &scre
InitMaterial2D.AntiAliasing = video::EAAM_OFF;
InitMaterial2D.ZWriteEnable = video::EZW_OFF;
InitMaterial2D.ZBuffer = video::ECFN_DISABLED;
InitMaterial2D.UseMipMaps = false;
InitMaterial2D.forEachTexture([](auto &tex) {
InitMaterial2D.UseMipMaps = true;
InitMaterial2D.forEachTexture([](video::SMaterialLayer &tex) {
// Best preset for 2D pixel-perfect graphics
tex.MinFilter = video::ETMINF_NEAREST_MIPMAP_NEAREST;
// Best preset for downscaled 2D graphics using trilinear interpolation
//tex.MinFilter = video::ETMINF_LINEAR_MIPMAP_LINEAR;
// Lower bias -> more crisp images, more jitter
// Higher bias -> burry images, less jitter
//tex.LODBias = -1;
tex.MagFilter = video::ETMAGF_NEAREST;
tex.TextureWrapU = video::ETC_REPEAT;
tex.TextureWrapV = video::ETC_REPEAT;

View file

@ -103,14 +103,6 @@ public:
GL.TexParameteri(TextureType, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
GL.TexParameteri(TextureType, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
if (HasMipMaps) {
if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED))
GL.Hint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST);
else if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY))
GL.Hint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
else
GL.Hint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE);
}
TEST_GL_ERROR(Driver);
initTexture(tmpImages->size());
@ -147,7 +139,7 @@ public:
DriverType = Driver->getDriverType();
assert(Type != ETT_2D_ARRAY); // not supported by this constructor
TextureType = TextureTypeIrrToGL(Type);
HasMipMaps = false;
HasMipMaps = Driver->getTextureCreationFlag(ETCF_CREATE_RTT_MIP_MAPS);
IsRenderTarget = true;
if (!name.empty())
@ -189,8 +181,9 @@ public:
char lbuf[200];
snprintf_irr(lbuf, sizeof(lbuf),
"COpenGLCoreTexture: RTT Type = %d Size = %dx%d (S:%d) ColorFormat = %s -> %#06x %#06x %#06x%s",
"COpenGLCoreTexture: RTT Type = %d Size = %dx%d (S:%d) ColorFormat = %s%s -> %#06x %#06x %#06x%s",
(int)Type, Size.Width, Size.Height, (int)MSAA, ColorFormatName(ColorFormat),
HasMipMaps ? " +Mip" : "",
InternalFormat, PixelFormat, PixelType, Converter ? " (c)" : ""
);
os::Printer::log(lbuf, ELL_DEBUG);
@ -397,13 +390,21 @@ public:
if (!HasMipMaps || (Size.Width <= 1 && Size.Height <= 1))
return;
const COpenGLCoreTexture *prevTexture = Driver->getCacheHandler()->getTextureCache().get(0);
Driver->getCacheHandler()->getTextureCache().set(0, this);
auto &cache = Driver->getCacheHandler()->getTextureCache();
const COpenGLCoreTexture *prevTexture = cache.get(0);
cache.set(0, this);
if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED))
GL.Hint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST);
else if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY))
GL.Hint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
else
GL.Hint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE);
Driver->irrGlGenerateMipmap(TextureType);
TEST_GL_ERROR(Driver);
Driver->getCacheHandler()->getTextureCache().set(0, prevTexture);
cache.set(0, prevTexture);
}
GLenum getOpenGLTextureType() const

View file

@ -2614,10 +2614,6 @@ ITexture *COpenGLDriver::addRenderTargetTextureMs(const core::dimension2d<u32> &
if (IImage::isCompressedFormat(format))
return 0;
// disable mip-mapping
bool generateMipLevels = getTextureCreationFlag(ETCF_CREATE_MIP_MAPS);
setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, false);
bool supportForFBO = (Feature.ColorAttachment > 0);
core::dimension2du destSize(size);
@ -2631,9 +2627,6 @@ ITexture *COpenGLDriver::addRenderTargetTextureMs(const core::dimension2d<u32> &
addTexture(renderTargetTexture);
renderTargetTexture->drop();
// restore mip-mapping
setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, generateMipLevels);
return renderTargetTexture;
}
@ -2643,10 +2636,6 @@ ITexture *COpenGLDriver::addRenderTargetTextureCubemap(const u32 sideLen, const
if (IImage::isCompressedFormat(format))
return 0;
// disable mip-mapping
bool generateMipLevels = getTextureCreationFlag(ETCF_CREATE_MIP_MAPS);
setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, false);
bool supportForFBO = (Feature.ColorAttachment > 0);
const core::dimension2d<u32> size(sideLen, sideLen);
@ -2661,9 +2650,6 @@ ITexture *COpenGLDriver::addRenderTargetTextureCubemap(const u32 sideLen, const
addTexture(renderTargetTexture);
renderTargetTexture->drop();
// restore mip-mapping
setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, generateMipLevels);
return renderTargetTexture;
}
@ -2682,6 +2668,13 @@ bool COpenGLDriver::setRenderTargetEx(IRenderTarget *target, u16 clearFlag, SCol
return false;
}
if (CurrentRenderTarget) {
// Update mip-map of the generated texture, if enabled.
auto textures = CurrentRenderTarget->getTexture();
for (size_t i = 0; i < textures.size(); ++i)
textures[i]->regenerateMipMapLevels();
}
bool supportForFBO = (Feature.ColorAttachment > 0);
core::dimension2d<u32> destRenderTargetSize(0, 0);

View file

@ -266,7 +266,6 @@ bool COpenGL3DriverBase::genericDriverInit(const core::dimension2d<u32> &screenS
GL.ClearDepthf(1.0f);
GL.Hint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
GL.FrontFace(GL_CW);
// create material renderers
@ -1663,26 +1662,15 @@ ITexture *COpenGL3DriverBase::addRenderTargetTexture(const core::dimension2d<u32
ITexture *COpenGL3DriverBase::addRenderTargetTextureMs(const core::dimension2d<u32> &size, u8 msaa,
const io::path &name, const ECOLOR_FORMAT format)
{
// disable mip-mapping
bool generateMipLevels = getTextureCreationFlag(ETCF_CREATE_MIP_MAPS);
setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, false);
COpenGL3Texture *renderTargetTexture = new COpenGL3Texture(name, size, msaa > 0 ? ETT_2D_MS : ETT_2D, format, this, msaa);
addTexture(renderTargetTexture);
renderTargetTexture->drop();
// restore mip-mapping
setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, generateMipLevels);
return renderTargetTexture;
}
ITexture *COpenGL3DriverBase::addRenderTargetTextureCubemap(const u32 sideLen, const io::path &name, const ECOLOR_FORMAT format)
{
// disable mip-mapping
bool generateMipLevels = getTextureCreationFlag(ETCF_CREATE_MIP_MAPS);
setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, false);
bool supportForFBO = (Feature.ColorAttachment > 0);
const core::dimension2d<u32> size(sideLen, sideLen);
@ -1697,9 +1685,6 @@ ITexture *COpenGL3DriverBase::addRenderTargetTextureCubemap(const u32 sideLen, c
addTexture(renderTargetTexture);
renderTargetTexture->drop();
// restore mip-mapping
setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, generateMipLevels);
return renderTargetTexture;
}
@ -1716,6 +1701,13 @@ bool COpenGL3DriverBase::setRenderTargetEx(IRenderTarget *target, u16 clearFlag,
return false;
}
if (CurrentRenderTarget) {
// Update mip-map of the generated texture, if enabled.
auto textures = CurrentRenderTarget->getTexture();
for (size_t i = 0; i < textures.size(); ++i)
textures[i]->regenerateMipMapLevels();
}
core::dimension2d<u32> destRenderTargetSize(0, 0);
if (target) {