mirror of
https://github.com/love2d/love.git
synced 2026-08-19 20:19:42 +02:00
Improved performance of Image:refresh
This commit is contained in:
@@ -39,10 +39,11 @@ float Image::defaultMipmapSharpness = 0.0f;
|
|||||||
Image::Image(love::image::ImageData *data)
|
Image::Image(love::image::ImageData *data)
|
||||||
: data(data)
|
: data(data)
|
||||||
, cdata(0)
|
, cdata(0)
|
||||||
, width((float)(data->getWidth()))
|
, width(data->getWidth())
|
||||||
, height((float)(data->getHeight()))
|
, height(data->getHeight())
|
||||||
|
, paddedWidth(width)
|
||||||
|
, paddedHeight(height)
|
||||||
, texture(0)
|
, texture(0)
|
||||||
, texCoordScale(1.0, 1.0)
|
|
||||||
, mipmapSharpness(defaultMipmapSharpness)
|
, mipmapSharpness(defaultMipmapSharpness)
|
||||||
, mipmapsCreated(false)
|
, mipmapsCreated(false)
|
||||||
, compressed(false)
|
, compressed(false)
|
||||||
@@ -55,10 +56,11 @@ Image::Image(love::image::ImageData *data)
|
|||||||
Image::Image(love::image::CompressedData *cdata)
|
Image::Image(love::image::CompressedData *cdata)
|
||||||
: data(0)
|
: data(0)
|
||||||
, cdata(cdata)
|
, cdata(cdata)
|
||||||
, width((float)(cdata->getWidth(0)))
|
, width(cdata->getWidth(0))
|
||||||
, height((float)(cdata->getHeight(0)))
|
, height(cdata->getHeight(0))
|
||||||
|
, paddedWidth(width)
|
||||||
|
, paddedHeight(height)
|
||||||
, texture(0)
|
, texture(0)
|
||||||
, texCoordScale(1.0, 1.0)
|
|
||||||
, mipmapSharpness(defaultMipmapSharpness)
|
, mipmapSharpness(defaultMipmapSharpness)
|
||||||
, mipmapsCreated(false)
|
, mipmapsCreated(false)
|
||||||
, compressed(true)
|
, compressed(true)
|
||||||
@@ -77,12 +79,12 @@ Image::~Image()
|
|||||||
unload();
|
unload();
|
||||||
}
|
}
|
||||||
|
|
||||||
float Image::getWidth() const
|
int Image::getWidth() const
|
||||||
{
|
{
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Image::getHeight() const
|
int Image::getHeight() const
|
||||||
{
|
{
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
@@ -122,19 +124,19 @@ void Image::predraw() const
|
|||||||
{
|
{
|
||||||
bind();
|
bind();
|
||||||
|
|
||||||
if (texCoordScale.x < 1.0f || texCoordScale.y < 1.0f)
|
if (width != paddedWidth || height != paddedHeight)
|
||||||
{
|
{
|
||||||
// NPOT image padded to POT size, so the texcoords should be scaled.
|
// NPOT image padded to POT size, so the texcoords should be scaled.
|
||||||
glMatrixMode(GL_TEXTURE);
|
glMatrixMode(GL_TEXTURE);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glScalef(texCoordScale.x, texCoordScale.y, 0.0f);
|
glScalef(float(width) / float(paddedWidth), float(height) / float(paddedHeight), 0.0f);
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::postdraw() const
|
void Image::postdraw() const
|
||||||
{
|
{
|
||||||
if (texCoordScale.x < 1.0f || texCoordScale.y < 1.0f)
|
if (width != paddedWidth || height != paddedHeight)
|
||||||
{
|
{
|
||||||
glMatrixMode(GL_TEXTURE);
|
glMatrixMode(GL_TEXTURE);
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
@@ -310,10 +312,10 @@ void Image::preload()
|
|||||||
vertices[0].x = 0;
|
vertices[0].x = 0;
|
||||||
vertices[0].y = 0;
|
vertices[0].y = 0;
|
||||||
vertices[1].x = 0;
|
vertices[1].x = 0;
|
||||||
vertices[1].y = height;
|
vertices[1].y = (float) height;
|
||||||
vertices[2].x = width;
|
vertices[2].x = (float) width;
|
||||||
vertices[2].y = height;
|
vertices[2].y = (float) height;
|
||||||
vertices[3].x = width;
|
vertices[3].x = (float) width;
|
||||||
vertices[3].y = 0;
|
vertices[3].y = 0;
|
||||||
|
|
||||||
vertices[0].s = 0;
|
vertices[0].s = 0;
|
||||||
@@ -363,26 +365,23 @@ bool Image::loadVolatile()
|
|||||||
gl.setTextureWrap(wrap);
|
gl.setTextureWrap(wrap);
|
||||||
setMipmapSharpness(mipmapSharpness);
|
setMipmapSharpness(mipmapSharpness);
|
||||||
|
|
||||||
float texwidth = width;
|
paddedWidth = width;
|
||||||
float texheight = height;
|
paddedHeight = height;
|
||||||
|
|
||||||
if (!hasNpot())
|
if (!hasNpot())
|
||||||
{
|
{
|
||||||
// NPOT textures will be padded to POT dimensions if necessary.
|
// NPOT textures will be padded to POT dimensions if necessary.
|
||||||
texwidth = next_p2(width);
|
paddedWidth = next_p2(width);
|
||||||
texheight = next_p2(height);
|
paddedHeight = next_p2(height);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use a default texture if the size is too big for the system.
|
// Use a default texture if the size is too big for the system.
|
||||||
if (texwidth > gl.getMaxTextureSize() || texheight > gl.getMaxTextureSize())
|
if (paddedWidth > gl.getMaxTextureSize() || paddedHeight > gl.getMaxTextureSize())
|
||||||
{
|
{
|
||||||
uploadDefaultTexture();
|
uploadDefaultTexture();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
texCoordScale.x = width / texwidth;
|
|
||||||
texCoordScale.y = height / texheight;
|
|
||||||
|
|
||||||
// Mutex lock will potentially cover texture loading and mipmap creation.
|
// Mutex lock will potentially cover texture loading and mipmap creation.
|
||||||
love::thread::EmptyLock lock;
|
love::thread::EmptyLock lock;
|
||||||
if (data)
|
if (data)
|
||||||
@@ -390,10 +389,10 @@ bool Image::loadVolatile()
|
|||||||
|
|
||||||
while (glGetError() != GL_NO_ERROR); // Clear errors.
|
while (glGetError() != GL_NO_ERROR); // Clear errors.
|
||||||
|
|
||||||
if (hasNpot() || (texwidth == width && texheight == height))
|
if (hasNpot() || (width == paddedWidth && height == paddedHeight))
|
||||||
uploadTexture();
|
uploadTexture();
|
||||||
else
|
else
|
||||||
uploadTexturePadded(texwidth, texheight);
|
uploadTexturePadded();
|
||||||
|
|
||||||
GLenum glerr = glGetError();
|
GLenum glerr = glGetError();
|
||||||
if (glerr != GL_NO_ERROR)
|
if (glerr != GL_NO_ERROR)
|
||||||
@@ -406,7 +405,7 @@ bool Image::loadVolatile()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::uploadTexturePadded(float p2width, float p2height)
|
void Image::uploadTexturePadded()
|
||||||
{
|
{
|
||||||
if (isCompressed() && cdata)
|
if (isCompressed() && cdata)
|
||||||
{
|
{
|
||||||
@@ -419,8 +418,8 @@ void Image::uploadTexturePadded(float p2width, float p2height)
|
|||||||
glTexImage2D(GL_TEXTURE_2D,
|
glTexImage2D(GL_TEXTURE_2D,
|
||||||
0,
|
0,
|
||||||
GL_RGBA8,
|
GL_RGBA8,
|
||||||
(GLsizei)p2width,
|
(GLsizei)paddedWidth,
|
||||||
(GLsizei)p2height,
|
(GLsizei)paddedHeight,
|
||||||
0,
|
0,
|
||||||
GL_RGBA,
|
GL_RGBA,
|
||||||
GL_UNSIGNED_BYTE,
|
GL_UNSIGNED_BYTE,
|
||||||
@@ -481,37 +480,26 @@ bool Image::refresh()
|
|||||||
if (texture == 0)
|
if (texture == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
while (glGetError() != GL_NO_ERROR); // clear errors
|
if (usingDefaultTexture)
|
||||||
|
{
|
||||||
|
uploadDefaultTexture();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// We want this lock to potentially cover mipmap creation as well.
|
// We want this lock to potentially cover mipmap creation as well.
|
||||||
love::thread::EmptyLock lock;
|
love::thread::EmptyLock lock;
|
||||||
|
|
||||||
bind();
|
bind();
|
||||||
|
|
||||||
if (isCompressed() && cdata)
|
if (data && !isCompressed())
|
||||||
{
|
|
||||||
GLenum format = getCompressedFormat(cdata->getFormat());
|
|
||||||
glCompressedTexSubImage2DARB(GL_TEXTURE_2D,
|
|
||||||
0,
|
|
||||||
0, 0,
|
|
||||||
cdata->getWidth(0),
|
|
||||||
cdata->getHeight(0),
|
|
||||||
format,
|
|
||||||
GLsizei(cdata->getSize(0)),
|
|
||||||
cdata->getData(0));
|
|
||||||
}
|
|
||||||
else if (data)
|
|
||||||
{
|
|
||||||
lock.setLock(data->getMutex());
|
lock.setLock(data->getMutex());
|
||||||
glTexSubImage2D(GL_TEXTURE_2D,
|
|
||||||
0,
|
while (glGetError() != GL_NO_ERROR); // Clear errors.
|
||||||
0, 0,
|
|
||||||
(GLsizei)width,
|
if (hasNpot() || (width == paddedWidth && height == paddedHeight))
|
||||||
(GLsizei)height,
|
uploadTexture();
|
||||||
GL_RGBA,
|
else
|
||||||
GL_UNSIGNED_BYTE,
|
uploadTexturePadded();
|
||||||
data->getData());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (glGetError() != GL_NO_ERROR)
|
if (glGetError() != GL_NO_ERROR)
|
||||||
uploadDefaultTexture();
|
uploadDefaultTexture();
|
||||||
|
|||||||
@@ -70,8 +70,8 @@ public:
|
|||||||
**/
|
**/
|
||||||
virtual ~Image();
|
virtual ~Image();
|
||||||
|
|
||||||
float getWidth() const;
|
int getWidth() const;
|
||||||
float getHeight() const;
|
int getHeight() const;
|
||||||
|
|
||||||
const Vertex *getVertices() const;
|
const Vertex *getVertices() const;
|
||||||
|
|
||||||
@@ -166,7 +166,10 @@ private:
|
|||||||
love::image::CompressedData *cdata;
|
love::image::CompressedData *cdata;
|
||||||
|
|
||||||
// Width and height of the hardware texture.
|
// Width and height of the hardware texture.
|
||||||
float width, height;
|
int width, height;
|
||||||
|
|
||||||
|
// Real dimensions of the texture, if it was auto-padded to POT size.
|
||||||
|
int paddedWidth, paddedHeight;
|
||||||
|
|
||||||
// OpenGL texture identifier.
|
// OpenGL texture identifier.
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
@@ -174,9 +177,6 @@ private:
|
|||||||
// The source vertices of the image.
|
// The source vertices of the image.
|
||||||
Vertex vertices[4];
|
Vertex vertices[4];
|
||||||
|
|
||||||
// The scale applied to texcoords for NPOT images without NPOT support.
|
|
||||||
love::Vector texCoordScale;
|
|
||||||
|
|
||||||
// Mipmap texture LOD bias (sharpness) value.
|
// Mipmap texture LOD bias (sharpness) value.
|
||||||
float mipmapSharpness;
|
float mipmapSharpness;
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ private:
|
|||||||
|
|
||||||
void preload();
|
void preload();
|
||||||
|
|
||||||
void uploadTexturePadded(float p2width, float p2height);
|
void uploadTexturePadded();
|
||||||
void uploadTexture();
|
void uploadTexture();
|
||||||
|
|
||||||
void uploadCompressedMipmaps();
|
void uploadCompressedMipmaps();
|
||||||
|
|||||||
@@ -107,8 +107,8 @@ ParticleSystem::ParticleSystem(Image *image, uint32 size)
|
|||||||
, spinStart(0)
|
, spinStart(0)
|
||||||
, spinEnd(0)
|
, spinEnd(0)
|
||||||
, spinVariation(0)
|
, spinVariation(0)
|
||||||
, offsetX(image->getWidth()*0.5f)
|
, offsetX(float(image->getWidth())*0.5f)
|
||||||
, offsetY(image->getHeight()*0.5f)
|
, offsetY(float(image->getHeight())*0.5f)
|
||||||
{
|
{
|
||||||
if (size == 0 || size > MAX_PARTICLES)
|
if (size == 0 || size > MAX_PARTICLES)
|
||||||
throw love::Exception("Invalid ParticleSystem size.");
|
throw love::Exception("Invalid ParticleSystem size.");
|
||||||
|
|||||||
Reference in New Issue
Block a user