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:
parent
e86d2fea8d
commit
024e1d2d27
5 changed files with 43 additions and 44 deletions
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue