diff --git a/Aquaria/Game.cpp b/Aquaria/Game.cpp index e5d8177..b6ebd20 100644 --- a/Aquaria/Game.cpp +++ b/Aquaria/Game.cpp @@ -369,7 +369,7 @@ void Game::fillGrid(const GridFiller& gf) int w = 0, h = 0; size_t size = 0; - unsigned char *data = gf.texture->getBufferAndSize(&w, &h, &size); + const unsigned char *data = gf.texture->getBufferAndSize(&w, &h, &size); if (!data) { debugLog("Failed to get buffer in Game::fillGridFromQuad()"); @@ -419,8 +419,6 @@ void Game::fillGrid(const GridFiller& gf) } } - free(data); - if (gf.trim) { std::vector obsCopy; @@ -1057,7 +1055,7 @@ void Game::generateCollisionMask(Bone *q, float overrideCollideRadius /* = 0 */) int w = 0, h = 0; size_t size = 0; - unsigned char *data = q->texture->getBufferAndSize(&w, &h, &size); + const unsigned char *data = q->texture->getBufferAndSize(&w, &h, &size); if (!data) { debugLog("Failed to get buffer in Game::generateCollisionMask()"); @@ -1107,8 +1105,6 @@ void Game::generateCollisionMask(Bone *q, float overrideCollideRadius /* = 0 */) } q->collisionMaskRadius = 512; - - free(data); } } diff --git a/BBGE/Texture.cpp b/BBGE/Texture.cpp index be70df6..6f05c66 100644 --- a/BBGE/Texture.cpp +++ b/BBGE/Texture.cpp @@ -51,6 +51,7 @@ Texture::Texture() ow = oh = -1; _mipmap = false; success = false; + _pixbuf = NULL; } Texture::~Texture() @@ -81,6 +82,12 @@ void Texture::writeRGBA(int tx, int ty, int w, int h, const unsigned char *pixel ); glBindTexture(GL_TEXTURE_2D, 0); + + if(_pixbuf) + { + free(_pixbuf); + _pixbuf = NULL; // will re-fetch when needed + } } void Texture::unload() @@ -93,6 +100,16 @@ void Texture::unload() glDeleteTextures(1, &gltexid); gltexid = 0; } + if(_pixbuf) + { + free(_pixbuf); + _pixbuf = NULL; + } +} + +size_t Texture::sizeBytes() const +{ + return size_t(width) * size_t(height) * 4; } void Texture::apply() const @@ -209,18 +226,23 @@ bool Texture::upload(const ImageData& img, bool mipmap) return true; } -unsigned char * Texture::getBufferAndSize(int *wparam, int *hparam, size_t *sizeparam) const +const unsigned char * Texture::getBufferAndSize(int *wparam, int *hparam, size_t *sizeparam) const { - const size_t bytes = size_t(width) * size_t(height) * 4; - unsigned char *data = (unsigned char*)malloc(bytes); - if (!data) + unsigned char *data = _pixbuf; + const size_t bytes = sizeBytes(); + if(!_pixbuf) { - std::ostringstream os; - os << "Game::getBufferAndSize allocation failure, bytes = " << bytes; - errorLog(os.str()); - return NULL; + data = (unsigned char*)malloc(bytes); + if (!data) + { + std::ostringstream os; + os << "Game::getBufferAndSize allocation failure, bytes = " << bytes; + errorLog(os.str()); + return NULL; + } + this->readRGBA(data); + _pixbuf = data; } - this->readRGBA(data); *wparam = width; *hparam = height; diff --git a/BBGE/Texture.h b/BBGE/Texture.h index d478db7..1e2348e 100644 --- a/BBGE/Texture.h +++ b/BBGE/Texture.h @@ -65,7 +65,8 @@ public: void writeRGBA(int tx, int ty, int w, int h, const unsigned char *pixels); void readRGBA(unsigned char *pixels) const; - unsigned char *getBufferAndSize(int *w, int *h, size_t *size) const; // returned memory must be free()'d + const unsigned char *getBufferAndSize(int *w, int *h, size_t *size) const; // returned memory is owned by the Texture + size_t sizeBytes() const; std::string name, filename; bool upload(const ImageData& img, bool mipmap); @@ -76,6 +77,7 @@ protected: int ow, oh; bool _mipmap; + mutable unsigned char *_pixbuf; // retrieved when needed }; #define UNREFTEX(x) {x = NULL;}