diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index e65fe6985..ed27fdd3c 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -342,7 +342,7 @@ Image *Graphics::newImage(love::image::ImageData *data) catch(love::Exception &e) { image->release(); - throw love::Exception(e.what()); + throw; } if (!success) { diff --git a/src/modules/graphics/opengl/Image.cpp b/src/modules/graphics/opengl/Image.cpp index 4efc2b9c2..470902cd8 100644 --- a/src/modules/graphics/opengl/Image.cpp +++ b/src/modules/graphics/opengl/Image.cpp @@ -143,41 +143,46 @@ void Image::drawq(love::graphics::Quad *quad, float x, float y, float angle, flo drawv(t, v); } +void Image::checkMipmapsCreated() const +{ + if (filter.mipmap != FILTER_NEAREST && filter.mipmap != FILTER_LINEAR) + return; + + if (!hasMipmapSupport()) + throw love::Exception("Mipmap filtering is not supported on this system!"); + + // some old GPUs/systems claim support for NPOT textures, but fail when generating mipmaps + // we can't detect which systems will do this, so we fail gracefully for all NPOT images + int w = int(width), h = int(height); + if (w != next_p2(w) || h != next_p2(h)) + throw love::Exception("Could not generate mipmaps: image does not have power of two dimensions!"); + + bind(); + + GLboolean mipmapscreated; + glGetTexParameteriv(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, (GLint *)&mipmapscreated); + + // generate mipmaps for this image if we haven't already + if (!mipmapscreated) + { + glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); + + if (GLEE_VERSION_3_0 || GLEE_ARB_framebuffer_object) + glGenerateMipmap(GL_TEXTURE_2D); + else if (GLEE_EXT_framebuffer_object) + glGenerateMipmapEXT(GL_TEXTURE_2D); + else + // modify single texel to trigger mipmap chain generation + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data->getData()); + } +} + void Image::setFilter(const Image::Filter &f) { filter = f; bind(); - - if (f.mipmap == FILTER_NEAREST || f.mipmap == FILTER_LINEAR) - { - if (!hasMipmapSupport()) - throw love::Exception("Mipmap filtering is not supported on this system!"); - - // some old GPUs/systems claim support for NPOT textures, but fail when generating mipmaps for them - // we can't detect which systems will do this, so it's better to fail gracefully for all NPOT images - int w = int(width), h = int(height); - if (w != next_p2(w) || h != next_p2(h)) - throw love::Exception("Could not generate mipmaps: image does not have power of two dimensions!"); - - GLboolean mipmapscreated; - glGetTexParameteriv(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, (GLint *)&mipmapscreated); - - // generate mipmaps for this image if we haven't already - if (!mipmapscreated) - { - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); - - if (GLEE_VERSION_3_0 || GLEE_ARB_framebuffer_object) - glGenerateMipmap(GL_TEXTURE_2D); - else if (GLEE_EXT_framebuffer_object) - glGenerateMipmapEXT(GL_TEXTURE_2D); - else - // modify single texel in texture to trigger mipmap chain generation - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data->getData()); - } - } - + checkMipmapsCreated(); setTextureFilter(f); } @@ -186,7 +191,7 @@ const Image::Filter &Image::getFilter() const return filter; } -void Image::setWrap(Image::Wrap &w) +void Image::setWrap(const Image::Wrap &w) { wrap = w; @@ -201,7 +206,7 @@ const Image::Wrap &Image::getWrap() const void Image::setMipmapSharpness(float sharpness) { - if (!(GLEE_VERSION_1_4 || GLEE_EXT_texture_lod_bias)) + if (!hasMipmapSharpnessSupport()) return; // LOD bias has the range (-maxbias, maxbias) @@ -236,7 +241,7 @@ void Image::unload() bool Image::loadVolatile() { - if (GLEE_VERSION_1_4 || GLEE_EXT_texture_lod_bias) + if (hasMipmapSharpnessSupport()) glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &maxmipmapsharpness); if (hasNpot()) @@ -360,6 +365,11 @@ bool Image::hasMipmapSupport() return (GLEE_VERSION_1_4 || GLEE_SGIS_generate_mipmap) != 0; } +bool Image::hasMipmapSharpnessSupport() +{ + return (GLEE_VERSION_1_4 || GLEE_EXT_texture_lod_bias) != 0; +} + } // opengl } // graphics } // love diff --git a/src/modules/graphics/opengl/Image.h b/src/modules/graphics/opengl/Image.h index d9fc83602..cbe2d38b3 100644 --- a/src/modules/graphics/opengl/Image.h +++ b/src/modules/graphics/opengl/Image.h @@ -96,14 +96,13 @@ public: /** * Sets the filter mode. - * * @param f The filter mode. **/ void setFilter(const Image::Filter &f); const Image::Filter &getFilter() const; - void setWrap(Image::Wrap &w); + void setWrap(const Image::Wrap &w); const Image::Wrap &getWrap() const; @@ -122,6 +121,7 @@ public: static bool hasNpot(); static bool hasMipmapSupport(); + static bool hasMipmapSharpnessSupport(); private: @@ -147,7 +147,7 @@ private: // Mipmap texture LOD bias value float mipmapsharpness; - // Implementation-dependent maximum/minimum sharpness values + // Implementation-dependent maximum/minimum mipmap sharpness values float maxmipmapsharpness; // The image's filter mode @@ -158,6 +158,8 @@ private: bool loadVolatilePOT(); bool loadVolatileNPOT(); + + void checkMipmapsCreated() const; }; // Image diff --git a/src/modules/graphics/opengl/wrap_Canvas.cpp b/src/modules/graphics/opengl/wrap_Canvas.cpp index 1be14facb..9a7853802 100644 --- a/src/modules/graphics/opengl/wrap_Canvas.cpp +++ b/src/modules/graphics/opengl/wrap_Canvas.cpp @@ -68,21 +68,16 @@ int w_Canvas_setFilter(lua_State *L) { Canvas *canvas = luax_checkcanvas(L, 1); - Image::FilterMode min; - Image::FilterMode mag; + Image::Filter f; const char *minstr = luaL_checkstring(L, 2); const char *magstr = luaL_optstring(L, 3, minstr); - if (!Image::getConstant(minstr, min)) + if (!Image::getConstant(minstr, f.min)) return luaL_error(L, "Invalid filter mode: %s", minstr); - if (!Image::getConstant(magstr, mag)) + if (!Image::getConstant(magstr, f.mag)) return luaL_error(L, "Invalid filter mode: %s", magstr); - Image::Filter f; - f.min = min; - f.mag = mag; - canvas->setFilter(f); return 0; @@ -92,7 +87,7 @@ int w_Canvas_setFilter(lua_State *L) int w_Canvas_getFilter(lua_State *L) { Canvas *canvas = luax_checkcanvas(L, 1); - Image::Filter f = canvas->getFilter(); + const Image::Filter f = canvas->getFilter(); const char *minstr; const char *magstr; @@ -109,21 +104,16 @@ int w_Canvas_setWrap(lua_State *L) { Canvas *canvas = luax_checkcanvas(L, 1); - Image::WrapMode s; - Image::WrapMode t; + Image::Wrap w; const char *sstr = luaL_checkstring(L, 2); const char *tstr = luaL_optstring(L, 3, sstr); - if (!Image::getConstant(sstr, s)) + if (!Image::getConstant(sstr, w.s)) return luaL_error(L, "Invalid wrap mode: %s", sstr); - if (!Image::getConstant(tstr, t)) + if (!Image::getConstant(tstr, w.t)) return luaL_error(L, "Invalid wrap mode, %s", tstr); - Image::Wrap w; - w.s = s; - w.t = t; - canvas->setWrap(w); return 0; @@ -132,7 +122,7 @@ int w_Canvas_setWrap(lua_State *L) int w_Canvas_getWrap(lua_State *L) { Canvas *canvas = luax_checkcanvas(L, 1); - Image::Wrap w = canvas->getWrap(); + const Image::Wrap w = canvas->getWrap(); const char *wrap_s; const char *wrap_t; diff --git a/src/modules/graphics/opengl/wrap_Font.cpp b/src/modules/graphics/opengl/wrap_Font.cpp index 2b76a393f..5dd7021ad 100644 --- a/src/modules/graphics/opengl/wrap_Font.cpp +++ b/src/modules/graphics/opengl/wrap_Font.cpp @@ -94,21 +94,16 @@ int w_Font_setFilter(lua_State *L) { Font *t = luax_checkfont(L, 1); - Image::FilterMode min; - Image::FilterMode mag; + Image::Filter f; const char *minstr = luaL_checkstring(L, 2); const char *magstr = luaL_optstring(L, 3, minstr); - if (!Image::getConstant(minstr, min)) + if (!Image::getConstant(minstr, f.min)) return luaL_error(L, "Invalid filter mode: %s", minstr); - if (!Image::getConstant(magstr, mag)) + if (!Image::getConstant(magstr, f.mag)) return luaL_error(L, "Invalid filter mode: %s", magstr); - Image::Filter f; - f.min = min; - f.mag = mag; - t->setFilter(f); return 0; @@ -117,13 +112,11 @@ int w_Font_setFilter(lua_State *L) int w_Font_getFilter(lua_State *L) { Font *t = luax_checkfont(L, 1); - Image::Filter f = t->getFilter(); - Image::FilterMode min = f.min; - Image::FilterMode mag = f.mag; + const Image::Filter f = t->getFilter(); const char *minstr; const char *magstr; - Image::getConstant(min, minstr); - Image::getConstant(mag, magstr); + Image::getConstant(f.min, minstr); + Image::getConstant(f.mag, magstr); lua_pushstring(L, minstr); lua_pushstring(L, magstr); return 2; diff --git a/src/modules/graphics/opengl/wrap_Image.cpp b/src/modules/graphics/opengl/wrap_Image.cpp index 6e286fd0c..a843c1f37 100644 --- a/src/modules/graphics/opengl/wrap_Image.cpp +++ b/src/modules/graphics/opengl/wrap_Image.cpp @@ -88,12 +88,12 @@ int w_Image_getFilter(lua_State *L) const Image::Filter f = t->getFilter(); const char *minstr; const char *magstr; - const char *mipmapstr; Image::getConstant(f.min, minstr); Image::getConstant(f.mag, magstr); lua_pushstring(L, minstr); lua_pushstring(L, magstr); + const char *mipmapstr; if (Image::getConstant(f.mipmap, mipmapstr)) lua_pushstring(L, mipmapstr); else @@ -147,10 +147,7 @@ int w_Image_setMipmapSharpness(lua_State *L) int w_Image_getMipmapSharpness(lua_State *L) { Image *i = luax_checkimage(L, 1); - - float sharpness = i->getMipmapSharpness(); - lua_pushnumber(L, sharpness); - + lua_pushnumber(L, i->getMipmapSharpness()); return 1; }