mirror of
https://github.com/love2d/love.git
synced 2026-08-21 05:00:08 +02:00
Added anisotropic filtering functionality for images, consolidated mipmap methods into Image:setMipmapFilter(filtermode, sharpness, anisotropy), added love.graphics.setDefaultMipmapFilter(filtermode, sharpness, anisotropy)
This commit is contained in:
@@ -639,6 +639,18 @@ const Image::Filter &Graphics::getDefaultImageFilter() const
|
|||||||
return Image::getDefaultFilter();
|
return Image::getDefaultFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Graphics::setDefaultMipmapFilter(Image::FilterMode filter, float sharpness, float anisotropy)
|
||||||
|
{
|
||||||
|
Image::setDefaultMipmapFilter(filter);
|
||||||
|
Image::setDefaultMipmapSharpness(sharpness, anisotropy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Graphics::getDefaultMipmapFilter(Image::FilterMode *filter, float *sharpness, float *anisotropy) const
|
||||||
|
{
|
||||||
|
*filter = Image::getDefaultMipmapFilter();
|
||||||
|
Image::getDefaultMipmapSharpness(sharpness, anisotropy);
|
||||||
|
}
|
||||||
|
|
||||||
void Graphics::setLineWidth(float width)
|
void Graphics::setLineWidth(float width)
|
||||||
{
|
{
|
||||||
lineWidth = width;
|
lineWidth = width;
|
||||||
|
|||||||
@@ -319,6 +319,12 @@ public:
|
|||||||
**/
|
**/
|
||||||
const Image::Filter &getDefaultImageFilter() const;
|
const Image::Filter &getDefaultImageFilter() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default Image mipmap filtermode, sharpness, and anisotropy values.
|
||||||
|
**/
|
||||||
|
void setDefaultMipmapFilter(Image::FilterMode filter, float sharpness, float anisotropy);
|
||||||
|
void getDefaultMipmapFilter(Image::FilterMode *filter, float *sharpness, float *anisotropy) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the line width.
|
* Sets the line width.
|
||||||
* @param width The new width of the line.
|
* @param width The new width of the line.
|
||||||
|
|||||||
@@ -33,11 +33,19 @@ namespace graphics
|
|||||||
namespace opengl
|
namespace opengl
|
||||||
{
|
{
|
||||||
|
|
||||||
|
float Image::maxMipmapSharpness = 0.0f;
|
||||||
|
float Image::maxMipmapAnisotropy = 0.0f;
|
||||||
|
|
||||||
|
Image::FilterMode Image::defaultMipmapFilter = Image::FILTER_NONE;
|
||||||
|
float Image::defaultMipmapSharpness = 0.0f;
|
||||||
|
float Image::defaultMipmapAnisotropy = 0.0f;
|
||||||
|
|
||||||
Image::Image(love::image::ImageData *data)
|
Image::Image(love::image::ImageData *data)
|
||||||
: width((float)(data->getWidth()))
|
: width((float)(data->getWidth()))
|
||||||
, height((float)(data->getHeight()))
|
, height((float)(data->getHeight()))
|
||||||
, texture(0)
|
, texture(0)
|
||||||
, mipmapSharpness(0.0f)
|
, mipmapSharpness(defaultMipmapSharpness)
|
||||||
|
, mipmapAnisotropy(defaultMipmapAnisotropy)
|
||||||
, mipmapsCreated(false)
|
, mipmapsCreated(false)
|
||||||
{
|
{
|
||||||
data->retain();
|
data->retain();
|
||||||
@@ -64,6 +72,7 @@ Image::Image(love::image::ImageData *data)
|
|||||||
vertices[3].t = 0;
|
vertices[3].t = 0;
|
||||||
|
|
||||||
filter = getDefaultFilter();
|
filter = getDefaultFilter();
|
||||||
|
filter.mipmap = defaultMipmapFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
Image::~Image()
|
Image::~Image()
|
||||||
@@ -222,21 +231,34 @@ const Image::Wrap &Image::getWrap() const
|
|||||||
return wrap;
|
return wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::setMipmapSharpness(float sharpness)
|
void Image::setMipmapSharpness(float sharpness, float anisotropy)
|
||||||
|
{
|
||||||
|
if (hasMipmapSharpnessSupport())
|
||||||
{
|
{
|
||||||
if (!hasMipmapSharpnessSupport())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// LOD bias has the range (-maxbias, maxbias)
|
// LOD bias has the range (-maxbias, maxbias)
|
||||||
mipmapSharpness = std::min(std::max(sharpness, -maxMipmapSharpness + 0.01f), maxMipmapSharpness - 0.01f);
|
mipmapSharpness = std::min(std::max(sharpness, -maxMipmapSharpness + 0.01f), maxMipmapSharpness - 0.01f);
|
||||||
|
|
||||||
bind();
|
bind();
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -mipmapSharpness); // negative bias is sharper
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -mipmapSharpness); // negative bias is sharper
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
mipmapSharpness = 0.0f;
|
||||||
|
|
||||||
float Image::getMipmapSharpness() const
|
if (hasMipmapAnisotropySupport())
|
||||||
{
|
{
|
||||||
return mipmapSharpness;
|
mipmapAnisotropy = std::min(std::max(anisotropy, 0.0f), maxMipmapAnisotropy);
|
||||||
|
|
||||||
|
bind();
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, mipmapAnisotropy);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mipmapAnisotropy = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Image::getMipmapSharpness(float *sharpness, float *anisotropy) const
|
||||||
|
{
|
||||||
|
*sharpness = mipmapSharpness;
|
||||||
|
*anisotropy = mipmapAnisotropy;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::bind() const
|
void Image::bind() const
|
||||||
@@ -259,9 +281,12 @@ void Image::unload()
|
|||||||
|
|
||||||
bool Image::loadVolatile()
|
bool Image::loadVolatile()
|
||||||
{
|
{
|
||||||
if (hasMipmapSharpnessSupport())
|
if (hasMipmapSharpnessSupport() && maxMipmapSharpness == 0.0f)
|
||||||
glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &maxMipmapSharpness);
|
glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &maxMipmapSharpness);
|
||||||
|
|
||||||
|
if (hasMipmapAnisotropySupport() && maxMipmapAnisotropy == 0.0f)
|
||||||
|
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxMipmapAnisotropy);
|
||||||
|
|
||||||
if (hasNpot())
|
if (hasNpot())
|
||||||
return loadVolatileNPOT();
|
return loadVolatileNPOT();
|
||||||
else
|
else
|
||||||
@@ -313,7 +338,7 @@ bool Image::loadVolatilePOT()
|
|||||||
|
|
||||||
mipmapsCreated = false;
|
mipmapsCreated = false;
|
||||||
checkMipmapsCreated();
|
checkMipmapsCreated();
|
||||||
setMipmapSharpness(mipmapSharpness);
|
setMipmapSharpness(mipmapSharpness, mipmapAnisotropy);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -343,7 +368,7 @@ bool Image::loadVolatileNPOT()
|
|||||||
|
|
||||||
mipmapsCreated = false;
|
mipmapsCreated = false;
|
||||||
checkMipmapsCreated();
|
checkMipmapsCreated();
|
||||||
setMipmapSharpness(mipmapSharpness);
|
setMipmapSharpness(mipmapSharpness, mipmapAnisotropy);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -377,6 +402,28 @@ void Image::drawv(const Matrix &t, const vertex *v) const
|
|||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Image::setDefaultMipmapSharpness(float sharpness, float anisotropy)
|
||||||
|
{
|
||||||
|
defaultMipmapSharpness = sharpness;
|
||||||
|
defaultMipmapAnisotropy = anisotropy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Image::getDefaultMipmapSharpness(float *sharpness, float *anisotropy)
|
||||||
|
{
|
||||||
|
*sharpness = defaultMipmapSharpness;
|
||||||
|
*anisotropy = defaultMipmapAnisotropy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Image::setDefaultMipmapFilter(Image::FilterMode f)
|
||||||
|
{
|
||||||
|
defaultMipmapFilter = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image::FilterMode Image::getDefaultMipmapFilter()
|
||||||
|
{
|
||||||
|
return defaultMipmapFilter;
|
||||||
|
}
|
||||||
|
|
||||||
bool Image::hasNpot()
|
bool Image::hasNpot()
|
||||||
{
|
{
|
||||||
return GLEE_VERSION_2_0 || GLEE_ARB_texture_non_power_of_two;
|
return GLEE_VERSION_2_0 || GLEE_ARB_texture_non_power_of_two;
|
||||||
@@ -392,6 +439,11 @@ bool Image::hasMipmapSharpnessSupport()
|
|||||||
return GLEE_VERSION_1_4 || GLEE_EXT_texture_lod_bias;
|
return GLEE_VERSION_1_4 || GLEE_EXT_texture_lod_bias;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Image::hasMipmapAnisotropySupport()
|
||||||
|
{
|
||||||
|
return GLEE_EXT_texture_filter_anisotropic;
|
||||||
|
}
|
||||||
|
|
||||||
} // opengl
|
} // opengl
|
||||||
} // graphics
|
} // graphics
|
||||||
} // love
|
} // love
|
||||||
|
|||||||
@@ -104,9 +104,8 @@ public:
|
|||||||
|
|
||||||
const Image::Wrap &getWrap() const;
|
const Image::Wrap &getWrap() const;
|
||||||
|
|
||||||
void setMipmapSharpness(float sharpness);
|
void setMipmapSharpness(float sharpness, float anisotropy);
|
||||||
|
void getMipmapSharpness(float *sharpness, float *anisotropy) const;
|
||||||
float getMipmapSharpness() const;
|
|
||||||
|
|
||||||
void bind() const;
|
void bind() const;
|
||||||
|
|
||||||
@@ -117,9 +116,15 @@ public:
|
|||||||
bool loadVolatile();
|
bool loadVolatile();
|
||||||
void unloadVolatile();
|
void unloadVolatile();
|
||||||
|
|
||||||
|
static void setDefaultMipmapSharpness(float sharpness, float anisotropy);
|
||||||
|
static void getDefaultMipmapSharpness(float *sharpness, float *anisotropy);
|
||||||
|
static void setDefaultMipmapFilter(FilterMode f);
|
||||||
|
static FilterMode getDefaultMipmapFilter();
|
||||||
|
|
||||||
static bool hasNpot();
|
static bool hasNpot();
|
||||||
static bool hasMipmapSupport();
|
static bool hasMipmapSupport();
|
||||||
static bool hasMipmapSharpnessSupport();
|
static bool hasMipmapSharpnessSupport();
|
||||||
|
static bool hasMipmapAnisotropySupport();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -145,8 +150,8 @@ private:
|
|||||||
// Mipmap texture LOD bias (sharpness) value.
|
// Mipmap texture LOD bias (sharpness) value.
|
||||||
float mipmapSharpness;
|
float mipmapSharpness;
|
||||||
|
|
||||||
// Implementation-dependent min/max mipmap sharpness values.
|
// Mipmap texture anisotropic filtering value.
|
||||||
float maxMipmapSharpness;
|
float mipmapAnisotropy;
|
||||||
|
|
||||||
// True if mipmaps have been created for this Image.
|
// True if mipmaps have been created for this Image.
|
||||||
bool mipmapsCreated;
|
bool mipmapsCreated;
|
||||||
@@ -162,6 +167,13 @@ private:
|
|||||||
|
|
||||||
void checkMipmapsCreated();
|
void checkMipmapsCreated();
|
||||||
|
|
||||||
|
static float maxMipmapSharpness;
|
||||||
|
static float maxMipmapAnisotropy;
|
||||||
|
|
||||||
|
static FilterMode defaultMipmapFilter;
|
||||||
|
static float defaultMipmapSharpness;
|
||||||
|
static float defaultMipmapAnisotropy;
|
||||||
|
|
||||||
}; // Image
|
}; // Image
|
||||||
|
|
||||||
} // opengl
|
} // opengl
|
||||||
|
|||||||
@@ -772,6 +772,43 @@ int w_getDefaultImageFilter(lua_State *L)
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int w_setDefaultMipmapFilter(lua_State *L)
|
||||||
|
{
|
||||||
|
Image::FilterMode filter = Image::FILTER_NONE;
|
||||||
|
if (!lua_isnoneornil(L, 1))
|
||||||
|
{
|
||||||
|
const char *str = luaL_checkstring(L, 1);
|
||||||
|
if (!Image::getConstant(str, filter))
|
||||||
|
return luaL_error(L, "Invalid filter mode: %s", str);
|
||||||
|
}
|
||||||
|
|
||||||
|
float sharpness = luaL_optnumber(L, 2, 0);
|
||||||
|
float anisotropy = luaL_optnumber(L, 3, 0);
|
||||||
|
|
||||||
|
instance->setDefaultMipmapFilter(filter, sharpness, anisotropy);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int w_getDefaultMipmapFilter(lua_State *L)
|
||||||
|
{
|
||||||
|
Image::FilterMode filter;
|
||||||
|
float sharpness, anisotropy;
|
||||||
|
|
||||||
|
instance->getDefaultMipmapFilter(&filter, &sharpness, &anisotropy);
|
||||||
|
|
||||||
|
const char *str;
|
||||||
|
if (Image::getConstant(filter, str))
|
||||||
|
lua_pushstring(L, str);
|
||||||
|
else
|
||||||
|
lua_pushnil(L);
|
||||||
|
|
||||||
|
lua_pushnumber(L, sharpness);
|
||||||
|
lua_pushnumber(L, anisotropy);
|
||||||
|
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
int w_setLineWidth(lua_State *L)
|
int w_setLineWidth(lua_State *L)
|
||||||
{
|
{
|
||||||
float width = (float)luaL_checknumber(L, 1);
|
float width = (float)luaL_checknumber(L, 1);
|
||||||
@@ -1373,6 +1410,8 @@ static const luaL_Reg functions[] =
|
|||||||
{ "setDefaultImageFilter", w_setDefaultImageFilter },
|
{ "setDefaultImageFilter", w_setDefaultImageFilter },
|
||||||
{ "getBlendMode", w_getBlendMode },
|
{ "getBlendMode", w_getBlendMode },
|
||||||
{ "getDefaultImageFilter", w_getDefaultImageFilter },
|
{ "getDefaultImageFilter", w_getDefaultImageFilter },
|
||||||
|
{ "setDefaultMipmapFilter", w_setDefaultMipmapFilter },
|
||||||
|
{ "getDefaultMipmapFilter", w_getDefaultMipmapFilter },
|
||||||
{ "setLineWidth", w_setLineWidth },
|
{ "setLineWidth", w_setLineWidth },
|
||||||
{ "setLineStyle", w_setLineStyle },
|
{ "setLineStyle", w_setLineStyle },
|
||||||
{ "setLine", w_setLine },
|
{ "setLine", w_setLine },
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ int w_setBlendMode(lua_State *L);
|
|||||||
int w_setDefaultImageFilter(lua_State *L);
|
int w_setDefaultImageFilter(lua_State *L);
|
||||||
int w_getBlendMode(lua_State *L);
|
int w_getBlendMode(lua_State *L);
|
||||||
int w_getDefaultImageFilter(lua_State *L);
|
int w_getDefaultImageFilter(lua_State *L);
|
||||||
|
int w_setDefaultMipmapFilter(lua_State *L);
|
||||||
|
int w_getDefaultMipmapFilter(lua_State *L);
|
||||||
int w_setLineWidth(lua_State *L);
|
int w_setLineWidth(lua_State *L);
|
||||||
int w_setLineStyle(lua_State *L);
|
int w_setLineStyle(lua_State *L);
|
||||||
int w_setLine(lua_State *L);
|
int w_setLine(lua_State *L);
|
||||||
|
|||||||
@@ -116,21 +116,33 @@ int w_Image_setMipmapFilter(lua_State *L)
|
|||||||
return luaL_error(L, "%s", e.what());
|
return luaL_error(L, "%s", e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float sharpness = luaL_optnumber(L, 3, 0);
|
||||||
|
float anisotropy = luaL_optnumber(L, 4, 0);
|
||||||
|
|
||||||
|
t->setMipmapSharpness(sharpness, anisotropy);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int w_Image_getMipmapFilter(lua_State *L)
|
int w_Image_getMipmapFilter(lua_State *L)
|
||||||
{
|
{
|
||||||
Image *t = luax_checkimage(L, 1);
|
Image *t = luax_checkimage(L, 1);
|
||||||
const Image::Filter f = t->getFilter();
|
|
||||||
|
const Image::Filter &f = t->getFilter();
|
||||||
|
|
||||||
|
float sharpness, anisotropy;
|
||||||
|
t->getMipmapSharpness(&sharpness, &anisotropy);
|
||||||
|
|
||||||
const char *mipmapstr;
|
const char *mipmapstr;
|
||||||
if (!Image::getConstant(f.mipmap, mipmapstr))
|
if (Image::getConstant(f.mipmap, mipmapstr))
|
||||||
return 0; // only return a mipmap filter if mipmapping is enabled
|
|
||||||
|
|
||||||
lua_pushstring(L, mipmapstr);
|
lua_pushstring(L, mipmapstr);
|
||||||
|
else
|
||||||
|
lua_pushnil(L); // only return a mipmap filter if mipmapping is enabled
|
||||||
|
|
||||||
return 1;
|
lua_pushnumber(L, sharpness);
|
||||||
|
lua_pushnumber(L, anisotropy);
|
||||||
|
|
||||||
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
int w_Image_setWrap(lua_State *L)
|
int w_Image_setWrap(lua_State *L)
|
||||||
@@ -165,23 +177,6 @@ int w_Image_getWrap(lua_State *L)
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int w_Image_setMipmapSharpness(lua_State *L)
|
|
||||||
{
|
|
||||||
Image *i = luax_checkimage(L, 1);
|
|
||||||
|
|
||||||
float sharpness = (float) luaL_checknumber(L, 2);
|
|
||||||
i->setMipmapSharpness(sharpness);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int w_Image_getMipmapSharpness(lua_State *L)
|
|
||||||
{
|
|
||||||
Image *i = luax_checkimage(L, 1);
|
|
||||||
lua_pushnumber(L, i->getMipmapSharpness());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const luaL_Reg functions[] =
|
static const luaL_Reg functions[] =
|
||||||
{
|
{
|
||||||
{ "getWidth", w_Image_getWidth },
|
{ "getWidth", w_Image_getWidth },
|
||||||
@@ -193,8 +188,6 @@ static const luaL_Reg functions[] =
|
|||||||
{ "getWrap", w_Image_getWrap },
|
{ "getWrap", w_Image_getWrap },
|
||||||
{ "setMipmapFilter", w_Image_setMipmapFilter },
|
{ "setMipmapFilter", w_Image_setMipmapFilter },
|
||||||
{ "getMipmapFilter", w_Image_getMipmapFilter },
|
{ "getMipmapFilter", w_Image_getMipmapFilter },
|
||||||
{ "setMipmapSharpness", w_Image_setMipmapSharpness },
|
|
||||||
{ "getMipmapSharpness", w_Image_getMipmapSharpness },
|
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -42,8 +42,6 @@ int w_Image_setMipmapFilter(lua_State *L);
|
|||||||
int w_Image_getMipmapFilter(lua_State *L);
|
int w_Image_getMipmapFilter(lua_State *L);
|
||||||
int w_Image_setWrap(lua_State *L);
|
int w_Image_setWrap(lua_State *L);
|
||||||
int w_Image_getWrap(lua_State *L);
|
int w_Image_getWrap(lua_State *L);
|
||||||
int w_Image_setMipmapSharpness(lua_State *L);
|
|
||||||
int w_Image_getMipmapSharpness(lua_State *L);
|
|
||||||
extern "C" int luaopen_image(lua_State *L);
|
extern "C" int luaopen_image(lua_State *L);
|
||||||
|
|
||||||
} // opengl
|
} // opengl
|
||||||
|
|||||||
Reference in New Issue
Block a user