mirror of
https://github.com/luanti-org/luanti.git
synced 2025-07-27 17:28:41 +00:00
Implement support for FSAA in combination with post-processing (#15392)
- Actually it's MSAA I think, or perhaps the terms are equivalent - I've made it fit into the existing Irrlicht architecture, but that has resulted in code duplication compared to my original "hacky" approach - OpenGL 3.2+ and OpenGL ES 3.1+ are supported - EDT_OPENGL3 is not required, EDT_OPENGL works too - Helpful tutorial: https://learnopengl.com/Advanced-OpenGL/Anti-Aliasing, section "Off-screen MSAA" - This may be rough around the edges, but in general it works
This commit is contained in:
parent
a8ea165042
commit
9b6a399011
23 changed files with 290 additions and 42 deletions
|
@ -45,12 +45,13 @@ public:
|
|||
|
||||
COpenGLCoreTexture(const io::path &name, const std::vector<IImage *> &srcImages, E_TEXTURE_TYPE type, TOpenGLDriver *driver) :
|
||||
ITexture(name, type), Driver(driver), TextureType(GL_TEXTURE_2D),
|
||||
TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_RGBA), PixelType(GL_UNSIGNED_BYTE), Converter(0), LockReadOnly(false), LockImage(0), LockLayer(0),
|
||||
TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_RGBA), PixelType(GL_UNSIGNED_BYTE), MSAA(0), Converter(0), LockReadOnly(false), LockImage(0), LockLayer(0),
|
||||
KeepImage(false), MipLevelStored(0), LegacyAutoGenerateMipMaps(false)
|
||||
{
|
||||
_IRR_DEBUG_BREAK_IF(srcImages.empty())
|
||||
|
||||
DriverType = Driver->getDriverType();
|
||||
_IRR_DEBUG_BREAK_IF(Type == ETT_2D_MS); // not supported by this constructor
|
||||
TextureType = TextureTypeIrrToGL(Type);
|
||||
HasMipMaps = Driver->getTextureCreationFlag(ETCF_CREATE_MIP_MAPS);
|
||||
KeepImage = Driver->getTextureCreationFlag(ETCF_ALLOW_MEMORY_COPY);
|
||||
|
@ -141,10 +142,10 @@ public:
|
|||
TEST_GL_ERROR(Driver);
|
||||
}
|
||||
|
||||
COpenGLCoreTexture(const io::path &name, const core::dimension2d<u32> &size, E_TEXTURE_TYPE type, ECOLOR_FORMAT format, TOpenGLDriver *driver) :
|
||||
COpenGLCoreTexture(const io::path &name, const core::dimension2d<u32> &size, E_TEXTURE_TYPE type, ECOLOR_FORMAT format, TOpenGLDriver *driver, u8 msaa = 0) :
|
||||
ITexture(name, type),
|
||||
Driver(driver), TextureType(GL_TEXTURE_2D),
|
||||
TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_RGBA), PixelType(GL_UNSIGNED_BYTE), Converter(0), LockReadOnly(false), LockImage(0), LockLayer(0), KeepImage(false),
|
||||
TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_RGBA), PixelType(GL_UNSIGNED_BYTE), MSAA(msaa), Converter(0), LockReadOnly(false), LockImage(0), LockLayer(0), KeepImage(false),
|
||||
MipLevelStored(0), LegacyAutoGenerateMipMaps(false)
|
||||
{
|
||||
DriverType = Driver->getDriverType();
|
||||
|
@ -184,23 +185,47 @@ public:
|
|||
const COpenGLCoreTexture *prevTexture = Driver->getCacheHandler()->getTextureCache().get(0);
|
||||
Driver->getCacheHandler()->getTextureCache().set(0, this);
|
||||
|
||||
GL.TexParameteri(TextureType, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
GL.TexParameteri(TextureType, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
GL.TexParameteri(TextureType, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
GL.TexParameteri(TextureType, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
// An INVALID_ENUM error is generated by TexParameter* if target is either
|
||||
// TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any
|
||||
// sampler state from table 23.18.
|
||||
// ~ https://registry.khronos.org/OpenGL/specs/gl/glspec46.core.pdf
|
||||
if (Type != ETT_2D_MS) {
|
||||
GL.TexParameteri(TextureType, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
GL.TexParameteri(TextureType, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
GL.TexParameteri(TextureType, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
GL.TexParameteri(TextureType, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
#if defined(GL_VERSION_1_2)
|
||||
GL.TexParameteri(TextureType, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
GL.TexParameteri(TextureType, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
#endif
|
||||
|
||||
StatesCache.WrapU = ETC_CLAMP_TO_EDGE;
|
||||
StatesCache.WrapV = ETC_CLAMP_TO_EDGE;
|
||||
StatesCache.WrapW = ETC_CLAMP_TO_EDGE;
|
||||
StatesCache.WrapU = ETC_CLAMP_TO_EDGE;
|
||||
StatesCache.WrapV = ETC_CLAMP_TO_EDGE;
|
||||
StatesCache.WrapW = ETC_CLAMP_TO_EDGE;
|
||||
}
|
||||
|
||||
switch (Type) {
|
||||
case ETT_2D:
|
||||
GL.TexImage2D(GL_TEXTURE_2D, 0, InternalFormat, Size.Width, Size.Height, 0, PixelFormat, PixelType, 0);
|
||||
break;
|
||||
case ETT_2D_MS: {
|
||||
// glTexImage2DMultisample is supported by OpenGL 3.2+
|
||||
// glTexStorage2DMultisample is supported by OpenGL 4.3+ and OpenGL ES 3.1+
|
||||
#ifdef IRR_COMPILE_GL_COMMON // legacy driver
|
||||
constexpr bool use_gl_impl = true;
|
||||
#else
|
||||
const bool use_gl_impl = Driver->Version.Spec != OpenGLSpec::ES;
|
||||
#endif
|
||||
GLint max_samples = 0;
|
||||
GL.GetIntegerv(GL_MAX_SAMPLES, &max_samples);
|
||||
MSAA = std::min(MSAA, (u8)max_samples);
|
||||
|
||||
if (use_gl_impl)
|
||||
GL.TexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, MSAA, InternalFormat, Size.Width, Size.Height, GL_TRUE);
|
||||
else
|
||||
GL.TexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, MSAA, InternalFormat, Size.Width, Size.Height, GL_TRUE);
|
||||
break;
|
||||
}
|
||||
case ETT_CUBEMAP:
|
||||
GL.TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, InternalFormat, Size.Width, Size.Height, 0, PixelFormat, PixelType, 0);
|
||||
GL.TexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, InternalFormat, Size.Width, Size.Height, 0, PixelFormat, PixelType, 0);
|
||||
|
@ -595,6 +620,8 @@ protected:
|
|||
switch (type) {
|
||||
case ETT_2D:
|
||||
return GL_TEXTURE_2D;
|
||||
case ETT_2D_MS:
|
||||
return GL_TEXTURE_2D_MULTISAMPLE;
|
||||
case ETT_CUBEMAP:
|
||||
return GL_TEXTURE_CUBE_MAP;
|
||||
}
|
||||
|
@ -610,6 +637,7 @@ protected:
|
|||
GLint InternalFormat;
|
||||
GLenum PixelFormat;
|
||||
GLenum PixelType;
|
||||
u8 MSAA;
|
||||
void (*Converter)(const void *, s32, void *);
|
||||
|
||||
bool LockReadOnly;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue