diff --git a/src/modules/graphics/opengl/Canvas.cpp b/src/modules/graphics/opengl/Canvas.cpp index b863a4dbb..262d7dd83 100644 --- a/src/modules/graphics/opengl/Canvas.cpp +++ b/src/modules/graphics/opengl/Canvas.cpp @@ -458,6 +458,18 @@ love::image::ImageData *Canvas::getImageData(love::image::Image *image) return img; } +void Canvas::getPixel(unsigned char* pixel_rgba, int x, int y) +{ + strategy->bindFBO( fbo ); + + glReadPixels(x, height - y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel_rgba); + + if (current) + strategy->bindFBO( current->fbo ); + else + strategy->bindFBO( 0 ); +} + void Canvas::setFilter(const Image::Filter &f) { bindTexture(img); diff --git a/src/modules/graphics/opengl/Canvas.h b/src/modules/graphics/opengl/Canvas.h index f874a8bae..5f7d7d67e 100644 --- a/src/modules/graphics/opengl/Canvas.h +++ b/src/modules/graphics/opengl/Canvas.h @@ -64,6 +64,8 @@ public: love::image::ImageData *getImageData(love::image::Image *image); + void getPixel(unsigned char* pixel_rgba, int x, int y); + void setFilter(const Image::Filter &f); Image::Filter getFilter() const; diff --git a/src/modules/graphics/opengl/Font.cpp b/src/modules/graphics/opengl/Font.cpp index d7f511188..a7af1eef2 100644 --- a/src/modules/graphics/opengl/Font.cpp +++ b/src/modules/graphics/opengl/Font.cpp @@ -291,8 +291,7 @@ void Font::print(const std::string &text, float x, float y, float letter_spacing // copy glyphquad (4 vertices) from original glyph to our current quad list glyphquads.push_back(glyph->quad); - // 1.25 is magic line height for true type fonts - float lineheight = (type == FONT_TRUETYPE) ? floor(getHeight() / 1.25f + 0.5f) : 0.0f; + float lineheight = getBaseline(); // set proper relative position for (int i = 0; i < 4; i++) @@ -497,8 +496,8 @@ void Font::checkMipmapsCreated() const if (!Image::hasMipmapSupport()) throw love::Exception("Mipmap filtering is not supported on this system!"); - GLboolean mipmapscreated; - glGetTexParameteriv(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, (GLint *)&mipmapscreated); + GLint mipmapscreated; + glGetTexParameteriv(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, &mipmapscreated); // generate mipmaps for this image if we haven't already if (!mipmapscreated) @@ -592,6 +591,22 @@ void Font::unloadVolatile() textures.clear(); } +int Font::getAscent() const +{ + return rasterizer->getAscent(); +} + +int Font::getDescent() const +{ + return rasterizer->getDescent(); +} + +float Font::getBaseline() const +{ + // 1.25 is magic line height for true type fonts + return (type == FONT_TRUETYPE) ? floor(getHeight() / 1.25f + 0.5f) : 0.0f; +} + } // opengl } // graphics } // love diff --git a/src/modules/graphics/opengl/Font.h b/src/modules/graphics/opengl/Font.h index 73baccd9b..c29372346 100644 --- a/src/modules/graphics/opengl/Font.h +++ b/src/modules/graphics/opengl/Font.h @@ -136,6 +136,11 @@ public: bool loadVolatile(); void unloadVolatile(); + // Extra font metrics + int getAscent() const; + int getDescent() const; + float getBaseline() const; + private: enum FontType diff --git a/src/modules/graphics/opengl/Image.cpp b/src/modules/graphics/opengl/Image.cpp index 81f17d376..e4140f05a 100644 --- a/src/modules/graphics/opengl/Image.cpp +++ b/src/modules/graphics/opengl/Image.cpp @@ -159,8 +159,8 @@ void Image::checkMipmapsCreated() const bind(); - GLboolean mipmapscreated; - glGetTexParameteriv(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, (GLint *)&mipmapscreated); + GLint mipmapscreated; + glGetTexParameteriv(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, &mipmapscreated); // generate mipmaps for this image if we haven't already if (!mipmapscreated) diff --git a/src/modules/graphics/opengl/wrap_Canvas.cpp b/src/modules/graphics/opengl/wrap_Canvas.cpp index 10ff83f6d..2f5e43b8d 100644 --- a/src/modules/graphics/opengl/wrap_Canvas.cpp +++ b/src/modules/graphics/opengl/wrap_Canvas.cpp @@ -64,6 +64,27 @@ int w_Canvas_getImageData(lua_State *L) return 1; } +int w_Canvas_getPixel(lua_State * L) +{ + Canvas * canvas = luax_checkcanvas(L, 1); + int x = luaL_checkint(L, 2); + int y = luaL_checkint(L, 3); + unsigned char c[4]; + try + { + canvas->getPixel(c, x, y); + } + catch (love::Exception & e) + { + return luaL_error(L, "%s", e.what()); + } + lua_pushnumber(L, c[0]); + lua_pushnumber(L, c[1]); + lua_pushnumber(L, c[2]); + lua_pushnumber(L, c[3]); + return 4; +} + int w_Canvas_setFilter(lua_State *L) { Canvas *canvas = luax_checkcanvas(L, 1); @@ -202,6 +223,7 @@ static const luaL_Reg functions[] = { { "renderTo", w_Canvas_renderTo }, { "getImageData", w_Canvas_getImageData }, + { "getPixel", w_Canvas_getPixel }, { "setFilter", w_Canvas_setFilter }, { "getFilter", w_Canvas_getFilter }, { "setWrap", w_Canvas_setWrap }, diff --git a/src/modules/graphics/opengl/wrap_Canvas.h b/src/modules/graphics/opengl/wrap_Canvas.h index 924fe833a..5cdd2c2a8 100644 --- a/src/modules/graphics/opengl/wrap_Canvas.h +++ b/src/modules/graphics/opengl/wrap_Canvas.h @@ -36,6 +36,7 @@ namespace opengl Canvas *luax_checkcanvas(lua_State *L, int idx); int w_Canvas_renderTo(lua_State *L); int w_Canvas_getImageData(lua_State *L); +int w_Canvas_getPixel(lua_State * L); int w_Canvas_setFilter(lua_State *L); int w_Canvas_getFilter(lua_State *L); int w_Canvas_setWrap(lua_State *L); diff --git a/src/modules/graphics/opengl/wrap_Font.cpp b/src/modules/graphics/opengl/wrap_Font.cpp index 5306a10e3..a3761690e 100644 --- a/src/modules/graphics/opengl/wrap_Font.cpp +++ b/src/modules/graphics/opengl/wrap_Font.cpp @@ -93,8 +93,7 @@ int w_Font_getLineHeight(lua_State *L) int w_Font_setFilter(lua_State *L) { Font *t = luax_checkfont(L, 1); - - Image::Filter f; + Image::Filter f = t->getFilter(); const char *minstr = luaL_checkstring(L, 2); const char *magstr = luaL_optstring(L, 3, minstr); @@ -104,15 +103,6 @@ int w_Font_setFilter(lua_State *L) if (!Image::getConstant(magstr, f.mag)) return luaL_error(L, "Invalid filter mode: %s", magstr); - if (lua_isnoneornil(L, 4)) - f.mipmap = Image::FILTER_NONE; // mipmapping is disabled unless third argument is given - else - { - const char *mipmapstr = luaL_checkstring(L, 4); - if (!Image::getConstant(mipmapstr, f.mipmap)) - return luaL_error(L, "Invalid filter mode: %s", mipmapstr); - } - try { t->setFilter(f); @@ -135,14 +125,47 @@ int w_Font_getFilter(lua_State *L) Image::getConstant(f.mag, magstr); lua_pushstring(L, minstr); lua_pushstring(L, magstr); + return 2; +} + +int w_Font_setMipmapFilter(lua_State *L) +{ + Font *t = luax_checkfont(L, 1); + Image::Filter f = t->getFilter(); + + if (lua_isnoneornil(L, 2)) + f.mipmap = Image::FILTER_NONE; // mipmapping is disabled if no argument is given + else + { + const char *mipmapstr = luaL_checkstring(L, 2); + if (!Image::getConstant(mipmapstr, f.mipmap)) + return luaL_error(L, "Invalid filter mode: %s", mipmapstr); + } + + try + { + t->setFilter(f); + } + catch(love::Exception &e) + { + return luaL_error(L, "%s", e.what()); + } + + return 0; +} + +int w_Font_getMipmapFilter(lua_State *L) +{ + Font *t = luax_checkfont(L, 1); + const Image::Filter f = t->getFilter(); const char *mipmapstr; - if (Image::getConstant(f.mipmap, mipmapstr)) - lua_pushstring(L, mipmapstr); - else - lua_pushnil(L); // only return a mipmap filter if mipmapping is enabled + if (!Image::getConstant(f.mipmap, mipmapstr)) + return 0; // only return a mipmap filter if mipmapping is enabled - return 3; + lua_pushstring(L, mipmapstr); + + return 1; } int w_Font_setMipmapSharpness(lua_State *L) @@ -162,6 +185,27 @@ int w_Font_getMipmapSharpness(lua_State *L) return 1; } +int w_Font_getAscent(lua_State *L) +{ + Font *t = luax_checkfont(L, 1); + lua_pushnumber(L, t->getAscent()); + return 1; +} + +int w_Font_getDescent(lua_State *L) +{ + Font *t = luax_checkfont(L, 1); + lua_pushnumber(L, t->getDescent()); + return 1; +} + +int w_Font_getBaseline(lua_State *L) +{ + Font *t = luax_checkfont(L, 1); + lua_pushnumber(L, t->getBaseline()); + return 1; +} + static const luaL_Reg functions[] = { { "getHeight", w_Font_getHeight }, @@ -171,8 +215,13 @@ static const luaL_Reg functions[] = { "getLineHeight", w_Font_getLineHeight }, { "setFilter", w_Font_setFilter }, { "getFilter", w_Font_getFilter }, + { "setMipmapFilter", w_Font_setMipmapFilter }, + { "getMipmapFilter", w_Font_getMipmapFilter }, { "setMipmapSharpness", w_Font_setMipmapSharpness }, { "getMipmapSharpness", w_Font_getMipmapSharpness }, + { "getAscent", w_Font_getAscent }, + { "getDescent", w_Font_getDescent }, + { "getBaseline", w_Font_getBaseline }, { 0, 0 } }; diff --git a/src/modules/graphics/opengl/wrap_Font.h b/src/modules/graphics/opengl/wrap_Font.h index a64be5863..26d1932ea 100644 --- a/src/modules/graphics/opengl/wrap_Font.h +++ b/src/modules/graphics/opengl/wrap_Font.h @@ -40,8 +40,13 @@ int w_Font_setLineHeight(lua_State *L); int w_Font_getLineHeight(lua_State *L); int w_Font_setFilter(lua_State *L); int w_Font_getFilter(lua_State *L); +int w_Font_setMipmapFilter(lua_State *L); +int w_Font_getMipmapFilter(lua_State *L); int w_Font_setMipmapSharpness(lua_State *L); int w_Font_getMipmapSharpness(lua_State *L); +int w_Font_getAscent(lua_State *L); +int w_Font_getDescent(lua_State *L); +int w_Font_getBaseline(lua_State *L); extern "C" int luaopen_font(lua_State *L); } // opengl diff --git a/src/modules/graphics/opengl/wrap_Graphics.cpp b/src/modules/graphics/opengl/wrap_Graphics.cpp index aa58399e0..f200d9c96 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/src/modules/graphics/opengl/wrap_Graphics.cpp @@ -733,14 +733,11 @@ int w_setPointSize(lua_State *L) int w_setPointStyle(lua_State *L) { - Graphics::PointStyle style = Graphics::POINT_SMOOTH; + Graphics::PointStyle style; - if (lua_gettop(L) >= 2) - { - const char *str = luaL_checkstring(L, 1); - if (!Graphics::getConstant(str, style)) - return luaL_error(L, "Invalid point style: %s", str); - } + const char *str = luaL_checkstring(L, 1); + if (!Graphics::getConstant(str, style)) + return luaL_error(L, "Invalid point style: %s", str); instance->setPointStyle(style); return 0; @@ -750,10 +747,14 @@ int w_setPoint(lua_State *L) { float size = (float)luaL_checknumber(L, 1); - Graphics::PointStyle style; - const char *str = luaL_checkstring(L, 2); - if (!Graphics::getConstant(str, style)) - return luaL_error(L, "Invalid point style: %s", str); + Graphics::PointStyle style = Graphics::POINT_SMOOTH; + + if (lua_gettop(L) >= 2) + { + const char *str = luaL_checkstring(L, 2); + if (!Graphics::getConstant(str, style)) + return luaL_error(L, "Invalid point style: %s", str); + } instance->setPoint(size, style); return 0; diff --git a/src/modules/graphics/opengl/wrap_Image.cpp b/src/modules/graphics/opengl/wrap_Image.cpp index e92c22952..c70d23e0d 100644 --- a/src/modules/graphics/opengl/wrap_Image.cpp +++ b/src/modules/graphics/opengl/wrap_Image.cpp @@ -50,8 +50,7 @@ int w_Image_getHeight(lua_State *L) int w_Image_setFilter(lua_State *L) { Image *t = luax_checkimage(L, 1); - - Image::Filter f; + Image::Filter f = t->getFilter(); const char *minstr = luaL_checkstring(L, 2); const char *magstr = luaL_optstring(L, 3, minstr); @@ -61,15 +60,6 @@ int w_Image_setFilter(lua_State *L) if (!Image::getConstant(magstr, f.mag)) return luaL_error(L, "Invalid filter mode: %s", magstr); - if (lua_isnoneornil(L, 4)) - f.mipmap = Image::FILTER_NONE; // mipmapping is disabled unless third argument is given - else - { - const char *mipmapstr = luaL_checkstring(L, 4); - if (!Image::getConstant(mipmapstr, f.mipmap)) - return luaL_error(L, "Invalid filter mode: %s", mipmapstr); - } - try { t->setFilter(f); @@ -92,14 +82,47 @@ int w_Image_getFilter(lua_State *L) Image::getConstant(f.mag, magstr); lua_pushstring(L, minstr); lua_pushstring(L, magstr); + return 2; +} + +int w_Image_setMipmapFilter(lua_State *L) +{ + Image *t = luax_checkimage(L, 1); + Image::Filter f = t->getFilter(); + + if (lua_isnoneornil(L, 2)) + f.mipmap = Image::FILTER_NONE; // mipmapping is disabled if no argument is given + else + { + const char *mipmapstr = luaL_checkstring(L, 2); + if (!Image::getConstant(mipmapstr, f.mipmap)) + return luaL_error(L, "Invalid filter mode: %s", mipmapstr); + } + + try + { + t->setFilter(f); + } + catch(love::Exception &e) + { + return luaL_error(L, "%s", e.what()); + } + + return 0; +} + +int w_Image_getMipmapFilter(lua_State *L) +{ + Image *t = luax_checkimage(L, 1); + const Image::Filter f = t->getFilter(); const char *mipmapstr; - if (Image::getConstant(f.mipmap, mipmapstr)) - lua_pushstring(L, mipmapstr); - else - lua_pushnil(L); // only return a mipmap filter if mipmapping is enabled + if (!Image::getConstant(f.mipmap, mipmapstr)) + return 0; // only return a mipmap filter if mipmapping is enabled - return 3; + lua_pushstring(L, mipmapstr); + + return 1; } int w_Image_setWrap(lua_State *L) @@ -159,6 +182,8 @@ static const luaL_Reg functions[] = { "getFilter", w_Image_getFilter }, { "setWrap", w_Image_setWrap }, { "getWrap", w_Image_getWrap }, + { "setMipmapFilter", w_Image_setMipmapFilter }, + { "getMipmapFilter", w_Image_getMipmapFilter }, { "setMipmapSharpness", w_Image_setMipmapSharpness }, { "getMipmapSharpness", w_Image_getMipmapSharpness }, { 0, 0 } diff --git a/src/modules/graphics/opengl/wrap_Image.h b/src/modules/graphics/opengl/wrap_Image.h index a6c8d5d6a..67882174c 100644 --- a/src/modules/graphics/opengl/wrap_Image.h +++ b/src/modules/graphics/opengl/wrap_Image.h @@ -37,6 +37,8 @@ int w_Image_getWidth(lua_State *L); int w_Image_getHeight(lua_State *L); int w_Image_setFilter(lua_State *L); int w_image_getFilter(lua_State *L); +int w_Image_setMipmapFilter(lua_State *L); +int w_Image_getMipmapFilter(lua_State *L); int w_Image_setWrap(lua_State *L); int w_Image_getWrap(lua_State *L); int w_Image_setMipmapSharpness(lua_State *L); diff --git a/src/modules/graphics/opengl/wrap_ParticleSystem.cpp b/src/modules/graphics/opengl/wrap_ParticleSystem.cpp index 69df1c67f..0843cc470 100644 --- a/src/modules/graphics/opengl/wrap_ParticleSystem.cpp +++ b/src/modules/graphics/opengl/wrap_ParticleSystem.cpp @@ -192,6 +192,9 @@ int w_ParticleSystem_setSizeVariation(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); float arg1 = (float)luaL_checknumber(L, 2); + if (arg1 < 0.0f || arg1 > 1.0f) + return luaL_error(L, "Size variation has to be between 0 and 1, inclusive."); + t->setSizeVariation(arg1); return 0; }