diff options
author | chai <chaifix@163.com> | 2021-12-13 00:07:19 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2021-12-13 00:07:19 +0800 |
commit | 60cbbdec07ab7a5636eac5b3c024ae44e937f4d4 (patch) | |
tree | b2c7b0a868f18159dbc43d8954e1bd7668549a88 /Client/Source/Graphics/Texture.cpp |
+init
Diffstat (limited to 'Client/Source/Graphics/Texture.cpp')
-rw-r--r-- | Client/Source/Graphics/Texture.cpp | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/Client/Source/Graphics/Texture.cpp b/Client/Source/Graphics/Texture.cpp new file mode 100644 index 0000000..79dd5ea --- /dev/null +++ b/Client/Source/Graphics/Texture.cpp @@ -0,0 +1,230 @@ +#include "../Math/Math.h" + +#include "ImageData.h" +#include "Texture.h" + +Texture::Texture(TextureSetting setting, ImageData* imgData) +{ + Init(setting, imgData); + // force not keep imgData + m_KeepPixelData = false; +} + +void Texture::Init(TextureSetting setting, ImageData* imgData) +{ + m_Width = imgData->width; + m_Height = imgData->height; + m_Type = setting.type; + m_Format = setting.format; + m_WrapMode = setting.wrapMode; + m_FilterMode = setting.filterMode; + m_KeepPixelData = setting.keepImageData; + + glGenTextures(1, &m_GPUID); + glBindTexture(GL_TEXTURE_2D, m_GPUID); + + CheckGLError( + glDeleteTextures(1, &m_GPUID); + glBindTexture(GL_TEXTURE_2D, 0); + throw TextureException(error); + ); + + switch (m_WrapMode) { + case ETextureWrapMode::Clamp: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + break; + case ETextureWrapMode::Repeat: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + break; + case ETextureWrapMode::Mirror: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); + break; + default: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + break; + } + + CheckGLError( + glDeleteTextures(1, &m_GPUID); + glBindTexture(GL_TEXTURE_2D, 0); + throw TextureException(error); + ); + + switch (m_FilterMode) { + case ETextureFilterMode::Linear: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + break; + case ETextureFilterMode::Nearest: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + break; + default: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + break; + } + + GLint srcFormat = GL_RGB; + switch (imgData->format) + { + case PixelFormat_R: srcFormat = GL_RED; break; + case PixelFormat_RGB: srcFormat = GL_RGB; break; + case PixelFormat_RGBA: srcFormat = GL_RGBA; break; + default: Assert(false); + } + GLint srcType = GL_UNSIGNED_BYTE; + switch (imgData->type) + { + case PixelType_UNSIGNED_BYTE: srcType = GL_UNSIGNED_BYTE; break; + default: Assert(false); + } + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imgData->width, imgData->height, 0, srcFormat, srcType, imgData->pixels); + + CheckGLError( + glDeleteTextures(1, &m_GPUID); + glBindTexture(GL_TEXTURE_2D, 0); + throw TextureException(error); + ); +} + +Texture::Texture(TextureSetting setting, int w, int h) +{ + m_KeepPixelData = false; + + m_Width = w; + m_Height = h; + m_Type = setting.type; + m_Format = setting.format; + m_WrapMode = setting.wrapMode; + m_FilterMode = setting.filterMode; + m_KeepPixelData = setting.keepImageData; + + WipeGLError(); + + glGenTextures(1, &m_GPUID); + glBindTexture(GL_TEXTURE_2D, m_GPUID); + + CheckGLError( + glDeleteTextures(1, &m_GPUID); + glBindTexture(GL_TEXTURE_2D, 0); + throw TextureException(error); + ); + + switch (m_WrapMode) { + case ETextureWrapMode::Clamp: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + break; + case ETextureWrapMode::Repeat: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + break; + case ETextureWrapMode::Mirror: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); + break; + default: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + break; + } + + CheckGLError( + glDeleteTextures(1, &m_GPUID); + glBindTexture(GL_TEXTURE_2D, 0); + throw TextureException(error); + ); + + switch (m_FilterMode) { + case ETextureFilterMode::Linear: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + break; + case ETextureFilterMode::Nearest: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + break; + default: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + break; + } + GLenum internalFormat = GL_RGB; + if (m_Format == ETextureFormat::R8) + { + internalFormat = GL_RED; + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + } + + glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, NULL); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + + CheckGLError( + glDeleteTextures(1, &m_GPUID); + glBindTexture(GL_TEXTURE_2D, 0); + throw TextureException(error); + ); + + glBindTexture(GL_TEXTURE_2D, 0); +} + +Texture::~Texture() +{ + glDeleteTextures(1, &m_GPUID); +} + +void Texture::UpdateSubImage(Rect rect, int format, int type, const void* data) +{ + glBindTexture(GL_TEXTURE_2D, m_GPUID); + + CheckGLError( + glBindTexture(GL_TEXTURE_2D, 0); + throw TextureException(error); + ); + + int alignment = 4; + if (m_Format == ETextureFormat::R8) + { + alignment = 1; + } + + GLenum fmt = GL_RED; + switch (format) + { + case EPixelFormat::PixelFormat_BGR: fmt = GL_BGR; break; + case EPixelFormat::PixelFormat_BGRA:fmt = GL_BGRA; break; + case EPixelFormat::PixelFormat_R: fmt = GL_RED; break; + case EPixelFormat::PixelFormat_RG: fmt = GL_RG; break; + case EPixelFormat::PixelFormat_RGB: fmt = GL_RGB; break; + case EPixelFormat::PixelFormat_RGBA: fmt = GL_RGBA; break; + } + GLenum t = GL_UNSIGNED_BYTE; + switch (type) + { + case EPixelElementType::PixelType_UNSIGNED_BYTE: t = GL_UNSIGNED_BYTE; break; + case EPixelElementType::PixelType_UNSIGNED_INT: t = GL_UNSIGNED_INT; break; + case EPixelElementType::PixelType_BYTE: t = GL_BYTE; break; + case EPixelElementType::PixelType_INT: t = GL_INT; break; + case EPixelElementType::PixelType_FLOAT: t = GL_FLOAT; break; + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); + + glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x, rect.y, rect.width, rect.height, fmt, t, data); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + + CheckGLError( + glBindTexture(GL_TEXTURE_2D, 0); + throw TextureException(error); + ); + + glBindTexture(GL_TEXTURE_2D, 0); +}
\ No newline at end of file |