mirror of
https://github.com/love2d/love.git
synced 2026-08-19 20:19:42 +02:00
Reorganized some Image code.
--HG-- branch : minor
This commit is contained in:
@@ -87,142 +87,32 @@ Image::Image(love::image::CompressedData *cdata, const Flags &flags)
|
|||||||
|
|
||||||
Image::~Image()
|
Image::~Image()
|
||||||
{
|
{
|
||||||
unload();
|
unloadVolatile();
|
||||||
|
|
||||||
--imageCount;
|
--imageCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
love::image::ImageData *Image::getImageData() const
|
|
||||||
{
|
|
||||||
return data.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
love::image::CompressedData *Image::getCompressedData() const
|
|
||||||
{
|
|
||||||
return cdata.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Image::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
|
|
||||||
{
|
|
||||||
Matrix t;
|
|
||||||
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
|
|
||||||
|
|
||||||
drawv(t, vertices);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Image::drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
|
|
||||||
{
|
|
||||||
Matrix t;
|
|
||||||
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
|
|
||||||
|
|
||||||
drawv(t, quad->getVertices());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Image::predraw()
|
|
||||||
{
|
|
||||||
bind();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Image::postdraw()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
GLuint Image::getGLTexture() const
|
|
||||||
{
|
|
||||||
return texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Image::setFilter(const Texture::Filter &f)
|
|
||||||
{
|
|
||||||
if (!validateFilter(f, flags.mipmaps))
|
|
||||||
{
|
|
||||||
if (f.mipmap != FILTER_NONE && !flags.mipmaps)
|
|
||||||
throw love::Exception("Non-mipmapped image cannot have mipmap filtering.");
|
|
||||||
else
|
|
||||||
throw love::Exception("Invalid texture filter.");
|
|
||||||
}
|
|
||||||
|
|
||||||
filter = f;
|
|
||||||
|
|
||||||
// We don't want filtering or (attempted) mipmaps on the default texture.
|
|
||||||
if (usingDefaultTexture)
|
|
||||||
{
|
|
||||||
filter.mipmap = FILTER_NONE;
|
|
||||||
filter.min = filter.mag = FILTER_NEAREST;
|
|
||||||
}
|
|
||||||
|
|
||||||
bind();
|
|
||||||
gl.setTextureFilter(filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Image::setWrap(const Texture::Wrap &w)
|
|
||||||
{
|
|
||||||
bool success = true;
|
|
||||||
wrap = w;
|
|
||||||
|
|
||||||
if (hasLimitedNpot() && (width != next_p2(width) || height != next_p2(height)))
|
|
||||||
{
|
|
||||||
if (wrap.s != WRAP_CLAMP || wrap.t != WRAP_CLAMP)
|
|
||||||
success = false;
|
|
||||||
|
|
||||||
// If we only have limited NPOT support then the wrap mode must be CLAMP.
|
|
||||||
wrap.s = wrap.t = WRAP_CLAMP;
|
|
||||||
}
|
|
||||||
|
|
||||||
bind();
|
|
||||||
gl.setTextureWrap(w);
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Image::setMipmapSharpness(float sharpness)
|
|
||||||
{
|
|
||||||
// OpenGL ES doesn't support LOD bias via glTexParameter.
|
|
||||||
if (!GLAD_VERSION_1_4)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// LOD bias has the range (-maxbias, maxbias)
|
|
||||||
mipmapSharpness = std::min(std::max(sharpness, -maxMipmapSharpness + 0.01f), maxMipmapSharpness - 0.01f);
|
|
||||||
|
|
||||||
bind();
|
|
||||||
|
|
||||||
// negative bias is sharper
|
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -mipmapSharpness);
|
|
||||||
}
|
|
||||||
|
|
||||||
float Image::getMipmapSharpness() const
|
|
||||||
{
|
|
||||||
return mipmapSharpness;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Image::bind() const
|
|
||||||
{
|
|
||||||
if (texture != 0)
|
|
||||||
gl.bindTexture(texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Image::preload()
|
void Image::preload()
|
||||||
{
|
{
|
||||||
// For colors.
|
// For colors.
|
||||||
memset(vertices, 255, sizeof(Vertex)*4);
|
memset(vertices, 255, sizeof(Vertex)*4);
|
||||||
|
|
||||||
vertices[0].x = 0;
|
vertices[0].x = 0.0f;
|
||||||
vertices[0].y = 0;
|
vertices[0].y = 0.0f;
|
||||||
vertices[1].x = 0;
|
vertices[1].x = 0.0f;
|
||||||
vertices[1].y = (float) height;
|
vertices[1].y = (float) height;
|
||||||
vertices[2].x = (float) width;
|
vertices[2].x = (float) width;
|
||||||
vertices[2].y = (float) height;
|
vertices[2].y = (float) height;
|
||||||
vertices[3].x = (float) width;
|
vertices[3].x = (float) width;
|
||||||
vertices[3].y = 0;
|
vertices[3].y = 0.0f;
|
||||||
|
|
||||||
vertices[0].s = 0;
|
vertices[0].s = 0.0f;
|
||||||
vertices[0].t = 0;
|
vertices[0].t = 0.0f;
|
||||||
vertices[1].s = 0;
|
vertices[1].s = 0.0f;
|
||||||
vertices[1].t = 1;
|
vertices[1].t = 1.0f;
|
||||||
vertices[2].s = 1;
|
vertices[2].s = 1.0f;
|
||||||
vertices[2].t = 1;
|
vertices[2].t = 1.0f;
|
||||||
vertices[3].s = 1;
|
vertices[3].s = 1.0f;
|
||||||
vertices[3].t = 0;
|
vertices[3].t = 0.0f;
|
||||||
|
|
||||||
if (flags.mipmaps)
|
if (flags.mipmaps)
|
||||||
filter.mipmap = defaultMipmapFilter;
|
filter.mipmap = defaultMipmapFilter;
|
||||||
@@ -233,11 +123,6 @@ bool Image::load()
|
|||||||
return loadVolatile();
|
return loadVolatile();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::unload()
|
|
||||||
{
|
|
||||||
return unloadVolatile();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Image::generateMipmaps()
|
void Image::generateMipmaps()
|
||||||
{
|
{
|
||||||
// The GL_GENERATE_MIPMAP texparameter is set in loadVolatile if we don't
|
// The GL_GENERATE_MIPMAP texparameter is set in loadVolatile if we don't
|
||||||
@@ -255,6 +140,20 @@ void Image::generateMipmaps()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Image::loadDefaultTexture()
|
||||||
|
{
|
||||||
|
usingDefaultTexture = true;
|
||||||
|
|
||||||
|
bind();
|
||||||
|
setFilter(filter);
|
||||||
|
|
||||||
|
// A nice friendly checkerboard to signify invalid textures...
|
||||||
|
GLubyte px[] = {0xFF,0xFF,0xFF,0xFF, 0xC0,0xC0,0xC0,0xFF,
|
||||||
|
0xC0,0xC0,0xC0,0xFF, 0xFF,0xFF,0xFF,0xFF};
|
||||||
|
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, px);
|
||||||
|
}
|
||||||
|
|
||||||
void Image::loadTextureFromCompressedData()
|
void Image::loadTextureFromCompressedData()
|
||||||
{
|
{
|
||||||
GLenum iformat = getCompressedFormat(cdata->getFormat());
|
GLenum iformat = getCompressedFormat(cdata->getFormat());
|
||||||
@@ -301,7 +200,7 @@ bool Image::loadVolatile()
|
|||||||
if (image::CompressedData::getConstant(cdata->getFormat(), str))
|
if (image::CompressedData::getConstant(cdata->getFormat(), str))
|
||||||
{
|
{
|
||||||
throw love::Exception("Cannot create image: "
|
throw love::Exception("Cannot create image: "
|
||||||
"%s%s compressed images are not supported on this system.", flags.sRGB ? "sRGB " : "", str);
|
"%s%s compressed images are not supported on this system.", flags.sRGB ? "sRGB " : "", str);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw love::Exception("cannot create image: format is not supported on this system.");
|
throw love::Exception("cannot create image: format is not supported on this system.");
|
||||||
@@ -397,15 +296,14 @@ bool Image::loadVolatile()
|
|||||||
|
|
||||||
void Image::unloadVolatile()
|
void Image::unloadVolatile()
|
||||||
{
|
{
|
||||||
// Delete the hardware texture.
|
if (texture == 0)
|
||||||
if (texture != 0)
|
return;
|
||||||
{
|
|
||||||
gl.deleteTexture(texture);
|
|
||||||
texture = 0;
|
|
||||||
|
|
||||||
gl.updateTextureMemorySize(textureMemorySize, 0);
|
gl.deleteTexture(texture);
|
||||||
textureMemorySize = 0;
|
texture = 0;
|
||||||
}
|
|
||||||
|
gl.updateTextureMemorySize(textureMemorySize, 0);
|
||||||
|
textureMemorySize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Image::refresh(int xoffset, int yoffset, int w, int h)
|
bool Image::refresh(int xoffset, int yoffset, int w, int h)
|
||||||
@@ -432,7 +330,7 @@ bool Image::refresh(int xoffset, int yoffset, int w, int h)
|
|||||||
{
|
{
|
||||||
thread::Lock lock(data->getMutex());
|
thread::Lock lock(data->getMutex());
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, w, h, GL_RGBA,
|
glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, w, h, GL_RGBA,
|
||||||
GL_UNSIGNED_BYTE, pdata);
|
GL_UNSIGNED_BYTE, pdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
generateMipmaps();
|
generateMipmaps();
|
||||||
@@ -441,23 +339,13 @@ bool Image::refresh(int xoffset, int yoffset, int w, int h)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Image::Flags &Image::getFlags() const
|
void Image::predraw()
|
||||||
{
|
{
|
||||||
return flags;
|
bind();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::loadDefaultTexture()
|
void Image::postdraw()
|
||||||
{
|
{
|
||||||
usingDefaultTexture = true;
|
|
||||||
|
|
||||||
bind();
|
|
||||||
setFilter(filter);
|
|
||||||
|
|
||||||
// A nice friendly checkerboard to signify invalid textures...
|
|
||||||
GLubyte px[] = {0xFF,0xFF,0xFF,0xFF, 0xC0,0xC0,0xC0,0xFF,
|
|
||||||
0xC0,0xC0,0xC0,0xFF, 0xFF,0xFF,0xFF,0xFF};
|
|
||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::drawv(const Matrix &t, const Vertex *v)
|
void Image::drawv(const Matrix &t, const Vertex *v)
|
||||||
@@ -482,6 +370,111 @@ void Image::drawv(const Matrix &t, const Vertex *v)
|
|||||||
postdraw();
|
postdraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Image::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
|
||||||
|
{
|
||||||
|
Matrix t;
|
||||||
|
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
|
||||||
|
|
||||||
|
drawv(t, vertices);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Image::drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
|
||||||
|
{
|
||||||
|
Matrix t;
|
||||||
|
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
|
||||||
|
|
||||||
|
drawv(t, quad->getVertices());
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint Image::getGLTexture() const
|
||||||
|
{
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
love::image::ImageData *Image::getImageData() const
|
||||||
|
{
|
||||||
|
return data.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
love::image::CompressedData *Image::getCompressedData() const
|
||||||
|
{
|
||||||
|
return cdata.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Image::setFilter(const Texture::Filter &f)
|
||||||
|
{
|
||||||
|
if (!validateFilter(f, flags.mipmaps))
|
||||||
|
{
|
||||||
|
if (f.mipmap != FILTER_NONE && !flags.mipmaps)
|
||||||
|
throw love::Exception("Non-mipmapped image cannot have mipmap filtering.");
|
||||||
|
else
|
||||||
|
throw love::Exception("Invalid texture filter.");
|
||||||
|
}
|
||||||
|
|
||||||
|
filter = f;
|
||||||
|
|
||||||
|
// We don't want filtering or (attempted) mipmaps on the default texture.
|
||||||
|
if (usingDefaultTexture)
|
||||||
|
{
|
||||||
|
filter.mipmap = FILTER_NONE;
|
||||||
|
filter.min = filter.mag = FILTER_NEAREST;
|
||||||
|
}
|
||||||
|
|
||||||
|
bind();
|
||||||
|
gl.setTextureFilter(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Image::setWrap(const Texture::Wrap &w)
|
||||||
|
{
|
||||||
|
bool success = true;
|
||||||
|
wrap = w;
|
||||||
|
|
||||||
|
if (hasLimitedNpot() && (width != next_p2(width) || height != next_p2(height)))
|
||||||
|
{
|
||||||
|
if (wrap.s != WRAP_CLAMP || wrap.t != WRAP_CLAMP)
|
||||||
|
success = false;
|
||||||
|
|
||||||
|
// If we only have limited NPOT support then the wrap mode must be CLAMP.
|
||||||
|
wrap.s = wrap.t = WRAP_CLAMP;
|
||||||
|
}
|
||||||
|
|
||||||
|
bind();
|
||||||
|
gl.setTextureWrap(w);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Image::setMipmapSharpness(float sharpness)
|
||||||
|
{
|
||||||
|
// OpenGL ES doesn't support LOD bias via glTexParameter.
|
||||||
|
if (!GLAD_VERSION_1_4)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// LOD bias has the range (-maxbias, maxbias)
|
||||||
|
mipmapSharpness = std::min(std::max(sharpness, -maxMipmapSharpness + 0.01f), maxMipmapSharpness - 0.01f);
|
||||||
|
|
||||||
|
bind();
|
||||||
|
|
||||||
|
// negative bias is sharper
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -mipmapSharpness);
|
||||||
|
}
|
||||||
|
|
||||||
|
float Image::getMipmapSharpness() const
|
||||||
|
{
|
||||||
|
return mipmapSharpness;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Image::bind() const
|
||||||
|
{
|
||||||
|
if (texture != 0)
|
||||||
|
gl.bindTexture(texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Image::Flags &Image::getFlags() const
|
||||||
|
{
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
void Image::setDefaultMipmapSharpness(float sharpness)
|
void Image::setDefaultMipmapSharpness(float sharpness)
|
||||||
{
|
{
|
||||||
defaultMipmapSharpness = sharpness;
|
defaultMipmapSharpness = sharpness;
|
||||||
|
|||||||
@@ -79,13 +79,13 @@ public:
|
|||||||
**/
|
**/
|
||||||
Image(love::image::CompressedData *cdata, const Flags &flags);
|
Image(love::image::CompressedData *cdata, const Flags &flags);
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor. Deletes the hardware texture and other resources.
|
|
||||||
**/
|
|
||||||
virtual ~Image();
|
virtual ~Image();
|
||||||
|
|
||||||
love::image::ImageData *getImageData() const;
|
bool load();
|
||||||
love::image::CompressedData *getCompressedData() const;
|
|
||||||
|
// Implements Volatile.
|
||||||
|
bool loadVolatile();
|
||||||
|
void unloadVolatile();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copydoc Drawable::draw()
|
* @copydoc Drawable::draw()
|
||||||
@@ -107,6 +107,9 @@ public:
|
|||||||
|
|
||||||
virtual GLuint getGLTexture() const;
|
virtual GLuint getGLTexture() const;
|
||||||
|
|
||||||
|
love::image::ImageData *getImageData() const;
|
||||||
|
love::image::CompressedData *getCompressedData() const;
|
||||||
|
|
||||||
virtual void setFilter(const Texture::Filter &f);
|
virtual void setFilter(const Texture::Filter &f);
|
||||||
virtual bool setWrap(const Texture::Wrap &w);
|
virtual bool setWrap(const Texture::Wrap &w);
|
||||||
|
|
||||||
@@ -120,13 +123,6 @@ public:
|
|||||||
|
|
||||||
void bind() const;
|
void bind() const;
|
||||||
|
|
||||||
bool load();
|
|
||||||
void unload();
|
|
||||||
|
|
||||||
// Implements Volatile.
|
|
||||||
bool loadVolatile();
|
|
||||||
void unloadVolatile();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Re-uploads the ImageData or CompressedData associated with this Image to
|
* Re-uploads the ImageData or CompressedData associated with this Image to
|
||||||
* the GPU.
|
* the GPU.
|
||||||
|
|||||||
Reference in New Issue
Block a user