diff --git a/src/Graphics/Context.cpp b/src/Graphics/Context.cpp index 6686b6a5..02de7e29 100644 --- a/src/Graphics/Context.cpp +++ b/src/Graphics/Context.cpp @@ -39,3 +39,9 @@ void Context::init2DTexture(ObjectName _name, u32 _msaaLevel, u32 _width, u32 _h return m_impl->init2DTexture(_name, _msaaLevel, _width, _height, _mipMapLevel, _format, _internalFormat, _dataType, _data); } + +bool Context::isMultisamplingSupported() const +{ + // TODO + return true; +} diff --git a/src/Graphics/Context.h b/src/Graphics/Context.h index f700c4f6..7fa56f10 100644 --- a/src/Graphics/Context.h +++ b/src/Graphics/Context.h @@ -4,6 +4,8 @@ #include "ObjectName.h" #include "Parameter.h" +#define GRAPHICS_CONTEXT + namespace graphics { class ContextImpl; @@ -25,6 +27,8 @@ namespace graphics { void init2DTexture(ObjectName _name, u32 _msaaLevel, u32 _width, u32 _height, u32 _mipMapLevel, Parameter _format, Parameter _internalFormat, Parameter _dataType, const void * _data); + bool isMultisamplingSupported() const; + private: std::unique_ptr m_impl; }; diff --git a/src/Graphics/OpenGLContext/GLFunctions.cpp b/src/Graphics/OpenGLContext/GLFunctions.cpp index 050c2fde..2aad50ec 100644 --- a/src/Graphics/OpenGLContext/GLFunctions.cpp +++ b/src/Graphics/OpenGLContext/GLFunctions.cpp @@ -87,6 +87,9 @@ PFNGLPROGRAMBINARYPROC glProgramBinary; PFNGLPROGRAMPARAMETERIPROC glProgramParameteri; PFNGLTEXSTORAGE2DPROC glTexStorage2D; +PFNGLTEXTURESTORAGE2DPROC glTextureStorage2D; +PFNGLTEXTURESUBIMAGE2DPROC glTextureSubImage2D; +PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC glTextureStorage2DMultisample; #define GL_GET_PROC_ADR(proc_type, proc_name) proc_name = (proc_type) glGetProcAddress(#proc_name) @@ -171,4 +174,7 @@ void initGLFunctions() GL_GET_PROC_ADR(PFNGLPROGRAMPARAMETERIPROC, glProgramParameteri); GL_GET_PROC_ADR(PFNGLTEXSTORAGE2DPROC, glTexStorage2D); + GL_GET_PROC_ADR(PFNGLTEXTURESTORAGE2DPROC, glTextureStorage2D); + GL_GET_PROC_ADR(PFNGLTEXTURESUBIMAGE2DPROC, glTextureSubImage2D); + GL_GET_PROC_ADR(PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC, glTextureStorage2DMultisample); } diff --git a/src/Graphics/OpenGLContext/GLFunctions.h b/src/Graphics/OpenGLContext/GLFunctions.h index 028e5162..63c2d86d 100644 --- a/src/Graphics/OpenGLContext/GLFunctions.h +++ b/src/Graphics/OpenGLContext/GLFunctions.h @@ -90,6 +90,9 @@ extern PFNGLPROGRAMBINARYPROC glProgramBinary; extern PFNGLPROGRAMPARAMETERIPROC glProgramParameteri; extern PFNGLTEXSTORAGE2DPROC glTexStorage2D; +extern PFNGLTEXTURESTORAGE2DPROC glTextureStorage2D; +extern PFNGLTEXTURESUBIMAGE2DPROC glTextureSubImage2D; +extern PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC glTextureStorage2DMultisample; void initGLFunctions(); diff --git a/src/Graphics/OpenGLContext/opengl_Parameters.cpp b/src/Graphics/OpenGLContext/opengl_Parameters.cpp index e47ce598..c988988f 100644 --- a/src/Graphics/OpenGLContext/opengl_Parameters.cpp +++ b/src/Graphics/OpenGLContext/opengl_Parameters.cpp @@ -11,9 +11,9 @@ namespace graphics { } namespace internalcolor { - Parameter RGBA(GL_RGBA); - Parameter RG(GL_RG); - Parameter RED(GL_RED); + Parameter RGBA(GL_RGBA8); + Parameter RG(GL_RG8UI); + Parameter RED(GL_R8UI); Parameter DEPTH(GL_DEPTH_COMPONENT); } diff --git a/src/Graphics/OpenGLContext/opengl_TextureManipulationObjectFactory.cpp b/src/Graphics/OpenGLContext/opengl_TextureManipulationObjectFactory.cpp index 4339cad6..f21ca9fd 100644 --- a/src/Graphics/OpenGLContext/opengl_TextureManipulationObjectFactory.cpp +++ b/src/Graphics/OpenGLContext/opengl_TextureManipulationObjectFactory.cpp @@ -21,12 +21,21 @@ namespace opengl { graphics::Parameter _format, graphics::Parameter _internalFormat, graphics::Parameter _dataType, const void * _data) override { + if (_msaaLevel == 0) { + glBindTexture(GL_TEXTURE_2D, GLuint(_name)); + glTexImage2D(GL_TEXTURE_2D, _mipMapLevel, GLuint(_internalFormat), _width, _height, 0, GLenum(_format), GLenum(_dataType), _data); + } else { + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, GLuint(_name)); + glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, _msaaLevel, GLenum(_internalFormat), _width, _height, false); + } + } }; class Init2DTexStorage : public Init2DTexture { public: static bool Check(const GLVersion & _version) { +// return (_version.majorVersion > 4) || (_version.majorVersion == 4 && _version.minorVersion >= 2); return false; } @@ -35,20 +44,37 @@ namespace opengl { graphics::Parameter _format, graphics::Parameter _internalFormat, graphics::Parameter _dataType, const void * _data) override { + if (_msaaLevel == 0) { + glBindTexture(GL_TEXTURE_2D, GLuint(_name)); + glTexStorage2D(GL_TEXTURE_2D, _mipMapLevel, GLenum(_internalFormat), _width, _height); + if (_data != nullptr) + glTexSubImage2D(GL_TEXTURE_2D, _mipMapLevel, 0, 0, _width, _height, GLuint(_format), GLenum(_dataType), _data); + } else { + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, GLuint(_name)); + glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, _msaaLevel, GLenum(_internalFormat), _width, _height, false); + } + } }; class Init2DTextureStorage : public Init2DTexture { public: static bool Check(const GLVersion & _version) { +// return (_version.majorVersion > 4) || (_version.majorVersion == 4 && _version.minorVersion >= 5); return false; } - void init2DTexture(graphics::ObjectName _name, u32 _msaaLevel, u32 _width, u32 _height, u32 _mipMapLevel, graphics::Parameter _format, graphics::Parameter _internalFormat, graphics::Parameter _dataType, const void * _data) override { + if (_msaaLevel == 0) { + glTextureStorage2D(GLuint(_name), _mipMapLevel, GLenum(_internalFormat), _width, _height); + if (_data != nullptr) + glTextureSubImage2D(GLuint(_name), _mipMapLevel, 0, 0, _width, _height, GLuint(_format), GLenum(_dataType), _data); + } else { + glTexStorage2DMultisample(GLuint(_name), _msaaLevel, GLenum(_internalFormat), _width, _height, false); + } } }; diff --git a/src/Textures.cpp b/src/Textures.cpp index 633e1adf..f40b5e19 100644 --- a/src/Textures.cpp +++ b/src/Textures.cpp @@ -18,6 +18,7 @@ #include "GLideNHQ/Ext_TxFilter.h" #include "TextureFilterHandler.h" #include "Graphics/Context.h" +#include "Graphics/Parameters.h" using namespace std; @@ -475,14 +476,22 @@ void TextureCache::init() m_pDummy = addFrameBufferTexture(); // we don't want to remove dummy texture _initDummyTexture(m_pDummy); +#ifndef GRAPHICS_CONTEXT glBindTexture(GL_TEXTURE_2D, m_pDummy->glName); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, dummyTexture ); +#else + gfxContext.init2DTexture(graphics::ObjectName(m_pDummy->glName), 0, m_pDummy->realWidth, m_pDummy->realHeight, 0, + graphics::color::RGBA, graphics::internalcolor::RGBA, graphics::type::UNSIGNED_BYTE, dummyTexture); +#endif m_cachedBytes = m_pDummy->textureBytes; activateDummy( 0 ); - activateDummy( 1 ); + activateDummy(1); current[0] = current[1] = nullptr; + +#ifndef GRAPHICS_CONTEXT + #ifdef GL_MULTISAMPLING_SUPPORT if (config.video.multisampling != 0) { m_pMSDummy = addFrameBufferTexture(); // we don't want to remove dummy texture @@ -497,12 +506,28 @@ void TextureCache::init() glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, config.video.multisampling, GL_RGBA8, m_pMSDummy->realWidth, m_pMSDummy->realHeight, false); #endif + activateMSDummy(0); + activateMSDummy(1); + } + else +#endif + m_pMSDummy = nullptr; + +#else + m_pMSDummy = nullptr; + if (config.video.multisampling != 0 && gfxContext.isMultisamplingSupported()) { + m_pMSDummy = addFrameBufferTexture(); // we don't want to remove dummy texture + _initDummyTexture(m_pMSDummy); + + gfxContext.init2DTexture(graphics::ObjectName(m_pMSDummy->glName), config.video.multisampling, + m_pMSDummy->realWidth, m_pMSDummy->realHeight, 0, + graphics::color::RGBA, graphics::internalcolor::RGBA, graphics::type::UNSIGNED_BYTE, nullptr); activateMSDummy(0); activateMSDummy(1); - } else + } #endif - m_pMSDummy = nullptr; + assert(!isGLError()); } @@ -556,7 +581,7 @@ CachedTexture * TextureCache::_addTexture(u32 _crc32) if (m_curUnpackAlignment == 0) glGetIntegerv(GL_UNPACK_ALIGNMENT, &m_curUnpackAlignment); _checkCacheSize(); - m_textures.emplace_front(gfxContext.createTexture()); + m_textures.emplace_front(u32(gfxContext.createTexture())); Textures::iterator new_iter = m_textures.begin(); new_iter->crc = _crc32; m_lruTextureLocations.insert(std::pair(_crc32, new_iter));