mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-10-04 13:27:14 +00:00
Moved most uses of glGetTexImage() into a single function with better error checking.
Also small config addition to optionally increase memory allocation size for temporary texture pixel data; the nouveau drivers seem notoriously awkward and keep writing over the buffer.
This commit is contained in:
parent
5b7757530f
commit
063b1c0dfc
6 changed files with 123 additions and 72 deletions
|
@ -1903,6 +1903,7 @@ bool Core::initGraphicsLibrary(int width, int height, bool fullscreen, int vsync
|
|||
// putenv(), which takes a (char *), and freaks out newer GCC releases
|
||||
// when you try to pass a (const!) string literal here... --ryan.
|
||||
SDL_putenv((char *) "SDL_VIDEO_CENTERED=1");
|
||||
SDL_putenv((char *) "LIBGL_DEBUG=verbose"); // temp, to track errors on linux with nouveau drivers.
|
||||
|
||||
if (recreate)
|
||||
{
|
||||
|
|
108
BBGE/Texture.cpp
108
BBGE/Texture.cpp
|
@ -56,6 +56,8 @@ bool Texture::useMipMaps = true;
|
|||
|
||||
TexErr Texture::textureError = TEXERR_OK;
|
||||
|
||||
int Texture::textureMemoryMultiplier = 1;
|
||||
|
||||
Texture::Texture() : Resource()
|
||||
{
|
||||
#ifdef BBGE_BUILD_OPENGL
|
||||
|
@ -195,22 +197,10 @@ int Texture::getPixelWidth()
|
|||
{
|
||||
#ifdef BBGE_BUILD_OPENGL
|
||||
int w = 0, h = 0;
|
||||
glBindTexture(GL_TEXTURE_2D, textures[0]);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
|
||||
//glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPONENTS, &c);// assume 4
|
||||
unsigned int size = w*h*4;
|
||||
if (!size || w <= 0 || h <= 0)
|
||||
return 0;
|
||||
|
||||
unsigned char *data = (unsigned char*)malloc(size*sizeof(char));
|
||||
unsigned int size = 0;
|
||||
unsigned char *data = getBufferAndSize(&w, &h, &size);
|
||||
if (!data)
|
||||
{
|
||||
debugLog("Texture::getPixelWidth() malloc failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
|
||||
int smallestx = -1, largestx = -1;
|
||||
for (unsigned int x = 0; x < unsigned(w); x++)
|
||||
|
@ -227,7 +217,6 @@ int Texture::getPixelWidth()
|
|||
}
|
||||
}
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
free(data);
|
||||
return largestx - smallestx;
|
||||
#elif defined(BBGE_BUILD_DIRECTX)
|
||||
|
@ -239,20 +228,11 @@ int Texture::getPixelHeight()
|
|||
{
|
||||
#ifdef BBGE_BUILD_OPENGL
|
||||
int w = 0, h = 0;
|
||||
glBindTexture(GL_TEXTURE_2D, textures[0]);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
|
||||
//glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPONENTS, &c);// assume 4
|
||||
unsigned int size = w*h*4;
|
||||
if (!size || w <= 0 || h <= 0)
|
||||
return 0;
|
||||
unsigned char *data = (unsigned char*)malloc(size*sizeof(char));
|
||||
unsigned int size = 0;
|
||||
unsigned char *data = getBufferAndSize(&w, &h, &size);
|
||||
if (!data)
|
||||
{
|
||||
debugLog("Texture::getPixelHeight() malloc failed");
|
||||
return 0;
|
||||
}
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
|
||||
int smallesty = -1, largesty = -1;
|
||||
for (unsigned int x = 0; x < unsigned(w); x++)
|
||||
{
|
||||
|
@ -268,7 +248,6 @@ int Texture::getPixelHeight()
|
|||
}
|
||||
}
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
free(data);
|
||||
return largesty - smallesty;
|
||||
#elif defined(BBGE_BUILD_DIRECTX)
|
||||
|
@ -827,3 +806,76 @@ ImageTGA *Texture::TGAloadMem(void *mem, int size)
|
|||
return pImageData;
|
||||
}
|
||||
|
||||
// ceil to next power of 2
|
||||
static unsigned int clp2(unsigned int x)
|
||||
{
|
||||
--x;
|
||||
x |= (x >> 1);
|
||||
x |= (x >> 2);
|
||||
x |= (x >> 4);
|
||||
x |= (x >> 8);
|
||||
x |= (x >> 16);
|
||||
return x + 1;
|
||||
}
|
||||
|
||||
unsigned char * Texture::getBufferAndSize(int *wparam, int *hparam, unsigned int *sizeparam)
|
||||
{
|
||||
// This can't happen. If it does we're doomed.
|
||||
if(width <= 0 || height <= 0)
|
||||
goto fail;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, textures[0]);
|
||||
|
||||
// As returned by graphics driver
|
||||
int w = 0, h = 0;
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
|
||||
|
||||
// As we know it - but round to nearest power of 2 OpenGL does this internally anyways.
|
||||
int tw = clp2(width); // known to be > 0.
|
||||
int th = clp2(height);
|
||||
|
||||
if (w != tw || h != th)
|
||||
{
|
||||
debugLog("Texture::getBufferAndSize() WARNING: width/height disagree");
|
||||
// choose max. for size calculation
|
||||
w = w > tw ? w : tw;
|
||||
h = h > th ? h : th;
|
||||
}
|
||||
|
||||
unsigned int size = w * h * 4 * textureMemoryMultiplier;
|
||||
if (!size)
|
||||
goto fail;
|
||||
|
||||
unsigned char *data = (unsigned char*)malloc(size + 32);
|
||||
memcpy(data + size, "SAFE", 5);
|
||||
if (!data)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "Game::fillGridFromQuad allocation failure, size = " << size;
|
||||
errorLog(os.str());
|
||||
goto fail;
|
||||
}
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
// Not sure but this might be the case with nouveau drivers on linux... still investigating. -- fg
|
||||
if(memcmp(data + size, "SAFE", 5))
|
||||
{
|
||||
errorLog("Texture::getBufferAndSize(): Broken graphics driver! Wrote past end of buffer!");
|
||||
free(data); // in case we are here, this will most likely cause a crash.
|
||||
goto fail;
|
||||
}
|
||||
|
||||
*wparam = w;
|
||||
*hparam = h;
|
||||
*sizeparam = size;
|
||||
return data;
|
||||
|
||||
|
||||
fail:
|
||||
*wparam = 0;
|
||||
*hparam = 0;
|
||||
*sizeparam = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -80,6 +80,10 @@ public:
|
|||
|
||||
void write(int tx, int ty, int w, int h, const unsigned char *pixels);
|
||||
void read(int tx, int ty, int w, int h, unsigned char *pixels);
|
||||
|
||||
unsigned char *getBufferAndSize(int *w, int *h, unsigned int *size); // returned memory must be free()'d
|
||||
static int textureMemoryMultiplier; // 1. More for buggy drivers.
|
||||
|
||||
protected:
|
||||
std::string loadName;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue