1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2024-11-25 09:44:02 +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;
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<TileVector> 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);
}
}

View file

@ -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;

View file

@ -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;}