1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2024-11-29 03:33:48 +00:00

keep texture data in host RAM when pixel data are needed, eg. for collision calculations

This avoids downloading from the GPU *every single time*
the pixel data are needed
This commit is contained in:
fgenesis 2024-09-23 03:28:03 +02:00
parent c7aa3e2ec3
commit fef32b042c
3 changed files with 36 additions and 16 deletions

View file

@ -369,7 +369,7 @@ void Game::fillGrid(const GridFiller& gf)
int w = 0, h = 0; int w = 0, h = 0;
size_t size = 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) if (!data)
{ {
debugLog("Failed to get buffer in Game::fillGridFromQuad()"); debugLog("Failed to get buffer in Game::fillGridFromQuad()");
@ -419,8 +419,6 @@ void Game::fillGrid(const GridFiller& gf)
} }
} }
free(data);
if (gf.trim) if (gf.trim)
{ {
std::vector<TileVector> obsCopy; std::vector<TileVector> obsCopy;
@ -1057,7 +1055,7 @@ void Game::generateCollisionMask(Bone *q, float overrideCollideRadius /* = 0 */)
int w = 0, h = 0; int w = 0, h = 0;
size_t size = 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) if (!data)
{ {
debugLog("Failed to get buffer in Game::generateCollisionMask()"); debugLog("Failed to get buffer in Game::generateCollisionMask()");
@ -1107,8 +1105,6 @@ void Game::generateCollisionMask(Bone *q, float overrideCollideRadius /* = 0 */)
} }
q->collisionMaskRadius = 512; q->collisionMaskRadius = 512;
free(data);
} }
} }

View file

@ -51,6 +51,7 @@ Texture::Texture()
ow = oh = -1; ow = oh = -1;
_mipmap = false; _mipmap = false;
success = false; success = false;
_pixbuf = NULL;
} }
Texture::~Texture() 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); glBindTexture(GL_TEXTURE_2D, 0);
if(_pixbuf)
{
free(_pixbuf);
_pixbuf = NULL; // will re-fetch when needed
}
} }
void Texture::unload() void Texture::unload()
@ -93,6 +100,16 @@ void Texture::unload()
glDeleteTextures(1, &gltexid); glDeleteTextures(1, &gltexid);
gltexid = 0; 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 void Texture::apply() const
@ -209,18 +226,23 @@ bool Texture::upload(const ImageData& img, bool mipmap)
return true; 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 = _pixbuf;
unsigned char *data = (unsigned char*)malloc(bytes); const size_t bytes = sizeBytes();
if (!data) if(!_pixbuf)
{ {
std::ostringstream os; data = (unsigned char*)malloc(bytes);
os << "Game::getBufferAndSize allocation failure, bytes = " << bytes; if (!data)
errorLog(os.str()); {
return NULL; 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; *wparam = width;
*hparam = height; *hparam = height;

View file

@ -65,7 +65,8 @@ public:
void writeRGBA(int tx, int ty, int w, int h, const unsigned char *pixels); void writeRGBA(int tx, int ty, int w, int h, const unsigned char *pixels);
void readRGBA(unsigned char *pixels) const; 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; std::string name, filename;
bool upload(const ImageData& img, bool mipmap); bool upload(const ImageData& img, bool mipmap);
@ -76,6 +77,7 @@ protected:
int ow, oh; int ow, oh;
bool _mipmap; bool _mipmap;
mutable unsigned char *_pixbuf; // retrieved when needed
}; };
#define UNREFTEX(x) {x = NULL;} #define UNREFTEX(x) {x = NULL;}