diff --git a/include/Nazara/OpenGLRenderer/Utils.hpp b/include/Nazara/OpenGLRenderer/Utils.hpp index 55f1d6cff..71c23106c 100644 --- a/include/Nazara/OpenGLRenderer/Utils.hpp +++ b/include/Nazara/OpenGLRenderer/Utils.hpp @@ -12,10 +12,24 @@ #include #include #include +#include #include namespace Nz { + struct GLTextureFormat + { + GLint internalFormat; + GLenum format; + GLenum type; + GLenum swizzleR; + GLenum swizzleG; + GLenum swizzleB; + GLenum swizzleA; + }; + + inline std::optional DescribeTextureFormat(PixelFormat pixelFormat); + inline GLenum ToOpenGL(BlendFunc blendFunc); inline GLenum ToOpenGL(FaceSide filter); inline GLenum ToOpenGL(SamplerFilter filter); diff --git a/include/Nazara/OpenGLRenderer/Utils.inl b/include/Nazara/OpenGLRenderer/Utils.inl index 6d64a18ec..621704a82 100644 --- a/include/Nazara/OpenGLRenderer/Utils.inl +++ b/include/Nazara/OpenGLRenderer/Utils.inl @@ -10,6 +10,19 @@ namespace Nz { + inline std::optional DescribeTextureFormat(PixelFormat pixelFormat) + { + switch (pixelFormat) + { + case PixelFormat_A8: return GLTextureFormat { GL_R8, GL_RED, GL_UNSIGNED_BYTE, GL_ZERO, GL_ZERO, GL_ZERO, GL_RED }; + case PixelFormat_RGB8: return GLTextureFormat { GL_SRGB8, GL_RGB, GL_UNSIGNED_BYTE, GL_RED, GL_GREEN, GL_BLUE, GL_ZERO }; + case PixelFormat_RGBA8: return GLTextureFormat { GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA }; + } + + NazaraError("Unhandled PixelFormat 0x" + String::Number(UnderlyingCast(pixelFormat), 16)); + return {}; + } + inline GLenum ToOpenGL(BlendFunc blendFunc) { switch (blendFunc) diff --git a/include/Nazara/OpenGLRenderer/Wrapper/Texture.hpp b/include/Nazara/OpenGLRenderer/Wrapper/Texture.hpp index 12b3e5c08..0b04a5e4a 100644 --- a/include/Nazara/OpenGLRenderer/Wrapper/Texture.hpp +++ b/include/Nazara/OpenGLRenderer/Wrapper/Texture.hpp @@ -29,7 +29,7 @@ namespace Nz::GL inline void SetParameterfv(GLenum pname, const GLfloat* param); inline void SetParameteriv(GLenum pname, const GLint* param); - inline void TexImage2D(GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border); + inline void TexImage2D(GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type); inline void TexImage2D(GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* data); inline void TexSubImage2D(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* data); @@ -39,6 +39,8 @@ namespace Nz::GL private: static inline GLuint CreateHelper(OpenGLDevice& device, const Context& context); static inline void DestroyHelper(OpenGLDevice& device, const Context& context, GLuint objectId); + + TextureTarget m_target; }; } diff --git a/include/Nazara/OpenGLRenderer/Wrapper/Texture.inl b/include/Nazara/OpenGLRenderer/Wrapper/Texture.inl index b63dcb0fe..b94bbe5d4 100644 --- a/include/Nazara/OpenGLRenderer/Wrapper/Texture.inl +++ b/include/Nazara/OpenGLRenderer/Wrapper/Texture.inl @@ -13,7 +13,8 @@ namespace Nz::GL assert(m_objectId); const Context& context = EnsureDeviceContext(); - context.glTexParameterf(m_objectId, pname, param); + context.BindTexture(m_target, m_objectId); + context.glTexParameterf(ToOpenGL(m_target), pname, param); } inline void Texture::SetParameteri(GLenum pname, GLint param) @@ -21,7 +22,8 @@ namespace Nz::GL assert(m_objectId); const Context& context = EnsureDeviceContext(); - context.glTexParameteri(m_objectId, pname, param); + context.BindTexture(m_target, m_objectId); + context.glTexParameteri(ToOpenGL(m_target), pname, param); } inline void Texture::SetParameterfv(GLenum pname, const GLfloat* param) @@ -29,7 +31,8 @@ namespace Nz::GL assert(m_objectId); const Context& context = EnsureDeviceContext(); - context.glTexParameterfv(m_objectId, pname, param); + context.BindTexture(m_target, m_objectId); + context.glTexParameterfv(ToOpenGL(m_target), pname, param); } inline void Texture::SetParameteriv(GLenum pname, const GLint* param) @@ -37,38 +40,39 @@ namespace Nz::GL assert(m_objectId); const Context& context = EnsureDeviceContext(); - context.glTexParameteriv(m_objectId, pname, param); + context.BindTexture(m_target, m_objectId); + context.glTexParameteriv(ToOpenGL(m_target), pname, param); } - inline void Texture::TexImage2D(GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border) + inline void Texture::TexImage2D(GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type) { - return TexImage2D(level, internalFormat, width, height, border, GL_RGB, GL_UNSIGNED_BYTE, nullptr); + return TexImage2D(level, internalFormat, width, height, border, format, type, nullptr); } inline void Texture::TexImage2D(GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* data) { - const Context& context = EnsureDeviceContext(); - context.BindTexture(TextureTarget::Target2D, m_objectId); + m_target = TextureTarget::Target2D; - context.glTexImage2D(GL_TEXTURE_2D, level, internalFormat, width, height, border, format, type, data); + const Context& context = EnsureDeviceContext(); + context.BindTexture(m_target, m_objectId); + context.glTexImage2D(ToOpenGL(m_target), level, internalFormat, width, height, border, format, type, data); //< TODO: Handle errors } inline void Texture::TexSubImage2D(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* data) { const Context& context = EnsureDeviceContext(); - context.BindTexture(TextureTarget::Target2D, m_objectId); - - context.glTexSubImage2D(GL_TEXTURE_2D, level, xoffset, yoffset, width, height, format, type, data); + context.BindTexture(m_target, m_objectId); + context.glTexSubImage2D(ToOpenGL(m_target), level, xoffset, yoffset, width, height, format, type, data); //< TODO: Handle errors } inline GLuint Texture::CreateHelper(OpenGLDevice& device, const Context& context) { - GLuint sampler = 0; - context.glGenTextures(1U, &sampler); + GLuint texture = 0; + context.glGenTextures(1U, &texture); - return sampler; + return texture; } inline void Texture::DestroyHelper(OpenGLDevice& device, const Context& context, GLuint objectId) diff --git a/src/Nazara/OpenGLRenderer/OpenGLTexture.cpp b/src/Nazara/OpenGLRenderer/OpenGLTexture.cpp index d89da0d49..8019a7d29 100644 --- a/src/Nazara/OpenGLRenderer/OpenGLTexture.cpp +++ b/src/Nazara/OpenGLRenderer/OpenGLTexture.cpp @@ -17,21 +17,9 @@ namespace Nz if (!m_texture.Create(device)) throw std::runtime_error("failed to create texture object"); - GLint internalFormat; - switch (params.pixelFormat) - { - case PixelFormat_RGB8: - { - internalFormat = GL_SRGB8; - break; - } - - case PixelFormat_RGBA8: - { - internalFormat = GL_SRGB8_ALPHA8; - break; - } - } + auto format = DescribeTextureFormat(params.pixelFormat); + if (!format) + throw std::runtime_error("unsupported texture format"); switch (params.type) { @@ -43,7 +31,7 @@ namespace Nz case ImageType_2D: for (unsigned int level = 0; level < m_params.mipmapLevel; ++level) - m_texture.TexImage2D(0, internalFormat, GetLevelSize(params.width, level), GetLevelSize(params.height, level), 0); + m_texture.TexImage2D(0, format->internalFormat, GetLevelSize(params.width, level), GetLevelSize(params.height, level), 0, format->format, format->type); break; case ImageType_2D_Array: @@ -60,6 +48,10 @@ namespace Nz } m_texture.SetParameteri(GL_TEXTURE_MAX_LEVEL, m_params.mipmapLevel); + m_texture.SetParameteri(GL_TEXTURE_SWIZZLE_R, format->swizzleR); + m_texture.SetParameteri(GL_TEXTURE_SWIZZLE_G, format->swizzleG); + m_texture.SetParameteri(GL_TEXTURE_SWIZZLE_B, format->swizzleB); + m_texture.SetParameteri(GL_TEXTURE_SWIZZLE_A, format->swizzleA); } PixelFormat OpenGLTexture::GetFormat() const @@ -84,25 +76,9 @@ namespace Nz bool OpenGLTexture::Update(const void* ptr) { - GLint format; - GLint type; - switch (m_params.pixelFormat) - { - case PixelFormat_RGB8: - { - format = GL_RGB; - type = GL_UNSIGNED_BYTE; - break; - } + auto format = DescribeTextureFormat(m_params.pixelFormat); + assert(format); - case PixelFormat_RGBA8: - { - format = GL_RGBA; - type = GL_UNSIGNED_BYTE; - break; - } - } - switch (m_params.type) { case ImageType_1D: @@ -112,7 +88,7 @@ namespace Nz break; case ImageType_2D: - m_texture.TexSubImage2D(0, 0, 0, m_params.width, m_params.height, format, type, ptr); + m_texture.TexSubImage2D(0, 0, 0, m_params.width, m_params.height, format->format, format->type, ptr); break; case ImageType_2D_Array: