From d5b7aa9500945a3ac5ca0d28c2fc502a8cef98ae Mon Sep 17 00:00:00 2001 From: falkTX Date: Fri, 23 May 2014 05:12:52 +0100 Subject: [PATCH] Optimize Image class --- dgl/Image.hpp | 16 +++++---- dgl/src/Image.cpp | 88 ++++++++++++++++++++++++++++------------------- 2 files changed, 62 insertions(+), 42 deletions(-) diff --git a/dgl/Image.hpp b/dgl/Image.hpp index 976573d2..51705cc1 100644 --- a/dgl/Image.hpp +++ b/dgl/Image.hpp @@ -41,24 +41,24 @@ public: /** Constructor for a null Image. */ - Image() noexcept; + Image(); /** Constructor using raw image data. @note @a rawData must remain valid for the lifetime of this Image. */ - Image(const char* rawData, int width, int height, GLenum format = GL_BGRA, GLenum type = GL_UNSIGNED_BYTE) noexcept; + Image(const char* rawData, int width, int height, GLenum format = GL_BGRA, GLenum type = GL_UNSIGNED_BYTE); /** Constructor using raw image data. @note @a rawData must remain valid for the lifetime of this Image. */ - Image(const char* rawData, const Size& size, GLenum format = GL_BGRA, GLenum type = GL_UNSIGNED_BYTE) noexcept; + Image(const char* rawData, const Size& size, GLenum format = GL_BGRA, GLenum type = GL_UNSIGNED_BYTE); /** Constructor using another image data. */ - Image(const Image& image) noexcept; + Image(const Image& image); /** Destructor. @@ -69,13 +69,13 @@ public: Load image data from memory. @note @a rawData must remain valid for the lifetime of this Image. */ - void loadFromMemory(const char* rawData, int width, int height, GLenum format = GL_BGRA, GLenum type = GL_UNSIGNED_BYTE) noexcept; + void loadFromMemory(const char* rawData, int width, int height, GLenum format = GL_BGRA, GLenum type = GL_UNSIGNED_BYTE); /** Load image data from memory. @note @a rawData must remain valid for the lifetime of this Image. */ - void loadFromMemory(const char* rawData, const Size& size, GLenum format = GL_BGRA, GLenum type = GL_UNSIGNED_BYTE) noexcept; + void loadFromMemory(const char* rawData, const Size& size, GLenum format = GL_BGRA, GLenum type = GL_UNSIGNED_BYTE); /** Check if this image is valid. @@ -127,7 +127,7 @@ public: */ void drawAt(const Point& pos); - Image& operator=(const Image& image) noexcept; + Image& operator=(const Image& image); bool operator==(const Image& image) const noexcept; bool operator!=(const Image& image) const noexcept; @@ -137,6 +137,8 @@ private: GLenum fFormat; GLenum fType; GLuint fTextureId; + + void _setup(); }; // ----------------------------------------------------------------------- diff --git a/dgl/src/Image.cpp b/dgl/src/Image.cpp index dec555e0..eb21031f 100644 --- a/dgl/src/Image.cpp +++ b/dgl/src/Image.cpp @@ -20,40 +20,44 @@ START_NAMESPACE_DGL // ----------------------------------------------------------------------- -Image::Image() noexcept +Image::Image() : fRawData(nullptr), fSize(0, 0), fFormat(0), fType(0), fTextureId(0) { + _setup(); } -Image::Image(const char* rawData, int width, int height, GLenum format, GLenum type) noexcept +Image::Image(const char* rawData, int width, int height, GLenum format, GLenum type) : fRawData(rawData), fSize(width, height), fFormat(format), fType(type), fTextureId(0) { + _setup(); } -Image::Image(const char* rawData, const Size& size, GLenum format, GLenum type) noexcept +Image::Image(const char* rawData, const Size& size, GLenum format, GLenum type) : fRawData(rawData), fSize(size), fFormat(format), fType(type), fTextureId(0) { + _setup(); } -Image::Image(const Image& image) noexcept +Image::Image(const Image& image) : fRawData(image.fRawData), fSize(image.fSize), fFormat(image.fFormat), fType(image.fType), fTextureId(0) { + _setup(); } Image::~Image() @@ -65,17 +69,27 @@ Image::~Image() } } -void Image::loadFromMemory(const char* rawData, int width, int height, GLenum format, GLenum type) noexcept +void Image::loadFromMemory(const char* rawData, int width, int height, GLenum format, GLenum type) { loadFromMemory(rawData, Size(width, height), format, type); } -void Image::loadFromMemory(const char* rawData, const Size& size, GLenum format, GLenum type) noexcept +void Image::loadFromMemory(const char* rawData, const Size& size, GLenum format, GLenum type) { fRawData = rawData; fSize = size; fFormat = format; fType = type; + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, fTextureId); + + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.getWidth(), size.getHeight(), 0, format, type, rawData); + + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); } bool Image::isValid() const noexcept @@ -125,35 +139,12 @@ void Image::drawAt(int x, int y) void Image::drawAt(const Point& pos) { - if (! isValid()) - return; - - if (fTextureId == 0) - glGenTextures(1, &fTextureId); - - if (fTextureId == 0) - { - // invalidate image - fSize = Size(0, 0); - // TODO print GL error + if (fTextureId == 0 || ! isValid()) return; - } glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, fTextureId); - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fSize.getWidth(), fSize.getHeight(), 0, fFormat, fType, fRawData); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - - static const float trans[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, trans); - Rectangle(pos, fSize).draw(); glBindTexture(GL_TEXTURE_2D, 0); @@ -162,12 +153,9 @@ void Image::drawAt(const Point& pos) // ----------------------------------------------------------------------- -Image& Image::operator=(const Image& image) noexcept +Image& Image::operator=(const Image& image) { - fRawData = image.fRawData; - fSize = image.fSize; - fFormat = image.fFormat; - fType = image.fType; + loadFromMemory(image.fRawData, image.fSize, image.fFormat, image.fType); return *this; } @@ -183,4 +171,34 @@ bool Image::operator!=(const Image& image) const noexcept // ----------------------------------------------------------------------- +void Image::_setup() +{ + glGenTextures(1, &fTextureId); + + DISTRHO_SAFE_ASSERT_RETURN(fTextureId != 0,); + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, fTextureId); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + + static const float trans[] = { 0.0f, 0.0f, 0.0f, 0.0f }; + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, trans); + + if (fRawData != nullptr) + { + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fSize.getWidth(), fSize.getHeight(), 0, fFormat, fType, fRawData); + } + + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); +} + +// ----------------------------------------------------------------------- + END_NAMESPACE_DGL