diff --git a/src/modules/graphics/opengl/Canvas.cpp b/src/modules/graphics/opengl/Canvas.cpp index a802efea6..b863a4dbb 100644 --- a/src/modules/graphics/opengl/Canvas.cpp +++ b/src/modules/graphics/opengl/Canvas.cpp @@ -313,7 +313,7 @@ Canvas::Canvas(int width, int height, TextureType texture_type) vertices[2].t = 1; vertices[3].s = 1; vertices[3].t = 0; - + settings.filter = Image::getDefaultFilter(); getStrategy(); diff --git a/src/modules/graphics/opengl/Font.cpp b/src/modules/graphics/opengl/Font.cpp index 3fd65f899..e8caac22e 100644 --- a/src/modules/graphics/opengl/Font.cpp +++ b/src/modules/graphics/opengl/Font.cpp @@ -49,12 +49,10 @@ Font::Font(love::font::Rasterizer *r, const Image::Filter &filter) , mSpacing(1) , filter(filter) { - r->retain(); - love::font::GlyphData *gd = r->getGlyphData(32); type = (gd->getFormat() == love::font::GlyphData::FORMAT_LUMINANCE_ALPHA ? FONT_TRUETYPE : FONT_IMAGE); delete gd; - + // try to find the best texture size match for the font size // default to the largest texture size if no rough match is found texture_size_index = NUM_TEXTURE_SIZES - 1; @@ -68,19 +66,13 @@ Font::Font(love::font::Rasterizer *r, const Image::Filter &filter) break; } } - + texture_width = TEXTURE_WIDTHS[texture_size_index]; texture_height = TEXTURE_HEIGHTS[texture_size_index]; - - try - { - createTexture(); - } - catch (love::Exception &e) - { - r->release(); - throw; - } + + createTexture(); + + r->retain(); } Font::~Font() @@ -92,10 +84,10 @@ Font::~Font() bool Font::initializeTexture(GLint format) { GLint internalformat = (format == GL_LUMINANCE_ALPHA) ? GL_LUMINANCE8_ALPHA8 : GL_RGBA8; - + // clear errors before initializing while (glGetError() != GL_NO_ERROR); - + glTexImage2D(GL_TEXTURE_2D, 0, internalformat, @@ -105,49 +97,49 @@ bool Font::initializeTexture(GLint format) format, GL_UNSIGNED_BYTE, NULL); - + return glGetError() == GL_NO_ERROR; } void Font::createTexture() { texture_x = texture_y = rowHeight = TEXTURE_PADDING; - + GLuint t; glGenTextures(1, &t); textures.push_back(t); - + bindTexture(t); - + setTextureFilter(filter); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - + GLint format = (type == FONT_TRUETYPE ? GL_LUMINANCE_ALPHA : GL_RGBA); - + // try to initialize the texture, attempting smaller sizes if initialization fails bool initialized = false; while (texture_size_index >= 0) { texture_width = TEXTURE_WIDTHS[texture_size_index]; texture_height = TEXTURE_HEIGHTS[texture_size_index]; - + initialized = initializeTexture(format); - + if (initialized || texture_size_index <= 0) break; - + --texture_size_index; } - + if (!initialized) { // cleanup before throwing deleteTexture(t); bindTexture(0); textures.pop_back(); - + throw love::Exception("Could not create font texture!"); } @@ -183,17 +175,17 @@ Font::Glyph *Font::addGlyph(const int glyph) } Glyph *g = new Glyph; - + g->texture = 0; g->spacing = gd->getAdvance(); - + memset(&g->quad, 0, sizeof(GlyphQuad)); // don't waste space for empty glyphs. also fixes a division by zero bug with ati drivers if (w > 0 && h > 0) { const GLuint t = textures.back(); - + bindTexture(t); glTexSubImage2D(GL_TEXTURE_2D, 0, @@ -211,10 +203,10 @@ Font::Glyph *Font::addGlyph(const int glyph) v.y = (float) texture_y; v.w = (float) w; v.h = (float) h; - + Quad q = Quad(v, (const float) texture_width, (const float) texture_height); const vertex *verts = q.getVertices(); - + // copy vertex data to the glyph and set proper bearing for (int i = 0; i < 4; i++) { @@ -230,9 +222,9 @@ Font::Glyph *Font::addGlyph(const int glyph) rowHeight = std::max(rowHeight, h + TEXTURE_PADDING); delete gd; - + glyphs[glyph] = g; - + return g; } @@ -241,7 +233,7 @@ Font::Glyph *Font::findGlyph(const int glyph) Glyph *g = glyphs[glyph]; if (!g) g = addGlyph(glyph); - + return g; } @@ -254,15 +246,15 @@ void Font::print(const std::string &text, float x, float y, float letter_spacing { float dx = 0.0f; // spacing counter for newline handling float dy = 0.0f; - + // keeps track of when we need to switch textures in our vertex array std::vector glyphinfolist; - + std::vector glyphquads; glyphquads.reserve(text.size()); // pre-allocate space for the maximum possible number of quads - + int quadindex = 0; - + glPushMatrix(); Matrix t; @@ -273,11 +265,11 @@ void Font::print(const std::string &text, float x, float y, float letter_spacing { utf8::iterator i(text.begin(), text.begin(), text.end()); utf8::iterator end(text.end(), text.begin(), text.end()); - + while (i != end) { int g = *i++; - + if (g == '\n') { // wrap newline, but do not print it @@ -285,27 +277,27 @@ void Font::print(const std::string &text, float x, float y, float letter_spacing dx = 0.0f; continue; } - + Glyph *glyph = findGlyph(g); - + // we only care about the vertices of glyphs which have a texture if (glyph->texture != 0) { // 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; - + // set proper relative position for (int i = 0; i < 4; i++) { glyphquads[quadindex].vertices[i].x += dx; glyphquads[quadindex].vertices[i].y += dy + lineheight; } - + size_t listsize = glyphinfolist.size(); - + // check if current glyph texture has changed since the previous iteration if (listsize == 0 || glyphinfolist[listsize-1].texture != glyph->texture) { @@ -316,11 +308,11 @@ void Font::print(const std::string &text, float x, float y, float letter_spacing glyphdrawinfo.texture = glyph->texture; glyphinfolist.push_back(glyphdrawinfo); } - + ++quadindex; ++glyphinfolist[glyphinfolist.size()-1].numquads; } - + // advance the x position for the next glyph dx += glyph->spacing + letter_spacing; } @@ -337,32 +329,32 @@ void Font::print(const std::string &text, float x, float y, float letter_spacing } if (quadindex > 0 && glyphinfolist.size() > 0) - { + { // sort glyph draw info list by texture first, and quad position in memory second (using the struct's < operator) std::sort(glyphinfolist.begin(), glyphinfolist.end()); - + glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - + glVertexPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid *)&glyphquads[0].vertices[0].x); glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid *)&glyphquads[0].vertices[0].s); - + // we need to draw a new vertex array for every section of the string that uses a different texture than the previous section std::vector::const_iterator it; for (it = glyphinfolist.begin(); it != glyphinfolist.end(); ++it) { bindTexture(it->texture); - + int startvertex = it->startquad * 4; int numvertices = it->numquads * 4; - + glDrawArrays(GL_QUADS, startvertex, numvertices); } - + glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); } - + glPopMatrix(); } @@ -510,7 +502,7 @@ Image::Filter Font::getFilter() bindTexture(*it); return getTextureFilter(); } - + return Image::getDefaultFilter(); } diff --git a/src/modules/graphics/opengl/Font.h b/src/modules/graphics/opengl/Font.h index 6b35b8b51..299836cdd 100644 --- a/src/modules/graphics/opengl/Font.h +++ b/src/modules/graphics/opengl/Font.h @@ -125,14 +125,14 @@ public: * Returns the spacing modifier. **/ float getSpacing() const; - + void setFilter(const Image::Filter &f); Image::Filter getFilter(); // Implements Volatile. bool loadVolatile(); void unloadVolatile(); - + private: enum FontType @@ -154,13 +154,13 @@ private: int spacing; GlyphQuad quad; }; - + // used to determine when to change textures in the vertex array generated when printing text struct GlyphArrayDrawInfo { GLuint texture; int startquad, numquads; - + // used when sorting with std::sort // sorts by texture first (binding textures is expensive) and relative position in memory second bool operator < (const GlyphArrayDrawInfo &other) const @@ -177,16 +177,16 @@ private: int height; float lineHeight; float mSpacing; // modifies the spacing by multiplying it with this value - + int texture_size_index; int texture_width; int texture_height; - + std::vector textures; // vector of packed textures std::map glyphs; // maps glyphs to quad information FontType type; Image::Filter filter; - + static const int NUM_TEXTURE_SIZES = 7; static const int TEXTURE_WIDTHS[NUM_TEXTURE_SIZES]; static const int TEXTURE_HEIGHTS[NUM_TEXTURE_SIZES]; diff --git a/src/modules/graphics/opengl/OpenGL.cpp b/src/modules/graphics/opengl/OpenGL.cpp index 28b64cbdd..d931b8ead 100644 --- a/src/modules/graphics/opengl/OpenGL.cpp +++ b/src/modules/graphics/opengl/OpenGL.cpp @@ -55,7 +55,7 @@ void deleteTexture(GLuint texture) void setTextureFilter(const graphics::Image::Filter &f) { GLint gmin, gmag; - + if (f.mipmap == Image::FILTER_NONE) { if (f.min == Image::FILTER_NEAREST) @@ -76,8 +76,8 @@ void setTextureFilter(const graphics::Image::Filter &f) else gmin = GL_LINEAR; } - - + + switch (f.mag) { case Image::FILTER_NEAREST: @@ -88,7 +88,7 @@ void setTextureFilter(const graphics::Image::Filter &f) gmag = GL_LINEAR; break; } - + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gmin); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gmag); } @@ -98,9 +98,9 @@ graphics::Image::Filter getTextureFilter() GLint gmin, gmag; glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, &gmin); glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, &gmag); - + Image::Filter f; - + switch (gmin) { case GL_NEAREST: @@ -127,7 +127,7 @@ graphics::Image::Filter getTextureFilter() f.mipmap = Image::FILTER_NONE; break; } - + switch (gmag) { case GL_NEAREST: @@ -138,14 +138,14 @@ graphics::Image::Filter getTextureFilter() f.mag = Image::FILTER_LINEAR; break; } - + return f; } void setTextureWrap(const graphics::Image::Wrap &w) { GLint gs, gt; - + switch (w.s) { case Image::WRAP_CLAMP: @@ -156,7 +156,7 @@ void setTextureWrap(const graphics::Image::Wrap &w) gs = GL_REPEAT; break; } - + switch (w.t) { case Image::WRAP_CLAMP: @@ -167,7 +167,7 @@ void setTextureWrap(const graphics::Image::Wrap &w) gt = GL_REPEAT; break; } - + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gs); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gt); } @@ -175,12 +175,12 @@ void setTextureWrap(const graphics::Image::Wrap &w) graphics::Image::Wrap getTextureWrap() { GLint gs, gt; - + glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, &gs); glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, >); - + Image::Wrap w; - + switch (gs) { case GL_CLAMP_TO_EDGE: @@ -191,7 +191,7 @@ graphics::Image::Wrap getTextureWrap() w.s = Image::WRAP_REPEAT; break; } - + switch (gt) { case GL_CLAMP_TO_EDGE: @@ -202,7 +202,7 @@ graphics::Image::Wrap getTextureWrap() w.t = Image::WRAP_REPEAT; break; } - + return w; } diff --git a/src/modules/graphics/opengl/wrap_Canvas.cpp b/src/modules/graphics/opengl/wrap_Canvas.cpp index 9a7853802..10ff83f6d 100644 --- a/src/modules/graphics/opengl/wrap_Canvas.cpp +++ b/src/modules/graphics/opengl/wrap_Canvas.cpp @@ -67,19 +67,19 @@ int w_Canvas_getImageData(lua_State *L) int w_Canvas_setFilter(lua_State *L) { Canvas *canvas = luax_checkcanvas(L, 1); - + Image::Filter f; - + const char *minstr = luaL_checkstring(L, 2); const char *magstr = luaL_optstring(L, 3, minstr); - + if (!Image::getConstant(minstr, f.min)) return luaL_error(L, "Invalid filter mode: %s", minstr); if (!Image::getConstant(magstr, f.mag)) return luaL_error(L, "Invalid filter mode: %s", magstr); - + canvas->setFilter(f); - + return 0; } @@ -103,19 +103,19 @@ int w_Canvas_getFilter(lua_State *L) int w_Canvas_setWrap(lua_State *L) { Canvas *canvas = luax_checkcanvas(L, 1); - + Image::Wrap w; - + const char *sstr = luaL_checkstring(L, 2); const char *tstr = luaL_optstring(L, 3, sstr); - + if (!Image::getConstant(sstr, w.s)) return luaL_error(L, "Invalid wrap mode: %s", sstr); if (!Image::getConstant(tstr, w.t)) return luaL_error(L, "Invalid wrap mode, %s", tstr); - + canvas->setWrap(w); - + return 0; } diff --git a/src/modules/graphics/opengl/wrap_Font.cpp b/src/modules/graphics/opengl/wrap_Font.cpp index 5dd7021ad..cc71ec88b 100644 --- a/src/modules/graphics/opengl/wrap_Font.cpp +++ b/src/modules/graphics/opengl/wrap_Font.cpp @@ -93,19 +93,19 @@ int w_Font_getLineHeight(lua_State *L) int w_Font_setFilter(lua_State *L) { Font *t = luax_checkfont(L, 1); - + Image::Filter f; - + const char *minstr = luaL_checkstring(L, 2); const char *magstr = luaL_optstring(L, 3, minstr); - + if (!Image::getConstant(minstr, f.min)) return luaL_error(L, "Invalid filter mode: %s", minstr); if (!Image::getConstant(magstr, f.mag)) return luaL_error(L, "Invalid filter mode: %s", magstr); - + t->setFilter(f); - + return 0; } diff --git a/src/modules/graphics/opengl/wrap_Image.cpp b/src/modules/graphics/opengl/wrap_Image.cpp index 3abffa7c1..e92c22952 100644 --- a/src/modules/graphics/opengl/wrap_Image.cpp +++ b/src/modules/graphics/opengl/wrap_Image.cpp @@ -137,7 +137,7 @@ int w_Image_getWrap(lua_State *L) int w_Image_setMipmapSharpness(lua_State *L) { Image *i = luax_checkimage(L, 1); - + float sharpness = (float) luaL_checknumber(L, 2); i->setMipmapSharpness(sharpness);