diff --git a/src/modules/graphics/opengl/Image.cpp b/src/modules/graphics/opengl/Image.cpp index 4151b8ea8..dce347c82 100644 --- a/src/modules/graphics/opengl/Image.cpp +++ b/src/modules/graphics/opengl/Image.cpp @@ -112,6 +112,11 @@ void Image::drawg(love::graphics::Geometry *geom, float x, float y, float angle, t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); const vertex *v = geom->getVertexArray(); + size_t vertcount = geom->getVertexCount(); + + // Padded NPOT images require texture coordinate scaling with Geometry. + if (!hasNpot()) + v = scaleNPOT(v, vertcount); // use colors stored in geometry (horrible, horrible hack) if (geom->hasVertexColors()) @@ -135,13 +140,17 @@ void Image::drawg(love::graphics::Geometry *geom, float x, float y, float angle, break; } - drawv(t, v, geom->getVertexCount(), glmode, geom->getElementArray(), geom->getElementCount()); + drawv(t, v, vertcount, glmode, geom->getElementArray(), geom->getElementCount()); if (geom->hasVertexColors()) { glDisableClientState(GL_COLOR_ARRAY); gl.setColor(gl.getColor()); } + + // If we made new verts with scaled texcoords then we should clean them up. + if (!hasNpot()) + delete[] v; } void Image::uploadCompressedMipmaps() @@ -551,6 +560,27 @@ bool Image::refresh() return true; } +love::Vector Image::getTexCoordScale() const +{ + // FIXME: this should be changed if Image::loadVolatilePOT changes. + return love::Vector(vertices[2].s, vertices[2].t); +} + +vertex *Image::scaleNPOT(const love::vertex *v, size_t count) const +{ + vertex *newverts = new vertex[count]; + love::Vector scale = getTexCoordScale(); + + for (size_t i = 0; i < count; i++) + { + newverts[i] = v[i]; + newverts[i].s *= scale.x; + newverts[i].t *= scale.y; + } + + return newverts; +} + void Image::drawv(const Matrix &t, const vertex *v, GLsizei count, GLenum mode, const uint16 *e, GLsizei ecount) const { bind(); diff --git a/src/modules/graphics/opengl/Image.h b/src/modules/graphics/opengl/Image.h index 5033c2f36..843c9f986 100644 --- a/src/modules/graphics/opengl/Image.h +++ b/src/modules/graphics/opengl/Image.h @@ -22,9 +22,10 @@ #define LOVE_GRAPHICS_OPENGL_IMAGE_H // LOVE -#include "common/Matrix.h" -#include "common/math.h" #include "common/config.h" +#include "common/Matrix.h" +#include "common/Vector.h" +#include "common/math.h" #include "image/ImageData.h" #include "image/CompressedData.h" #include "graphics/Image.h" @@ -123,6 +124,12 @@ public: **/ bool refresh(); + /** + * Gets the texture coordinate scale used for drawing auto-padded NPOT + * images correctly. + **/ + love::Vector getTexCoordScale() const; + static void setDefaultMipmapSharpness(float sharpness); static float getDefaultMipmapSharpness(); static void setDefaultMipmapFilter(FilterMode f); @@ -138,6 +145,7 @@ public: private: + vertex *scaleNPOT(const vertex *v, size_t count) const; void drawv(const Matrix &t, const vertex *v, GLsizei count = 4, GLenum mode = GL_QUADS, const uint16 *e = 0, GLsizei ecount = 0) const; friend class Shader; diff --git a/src/modules/graphics/opengl/SpriteBatch.cpp b/src/modules/graphics/opengl/SpriteBatch.cpp index cc0db1848..b99edc478 100644 --- a/src/modules/graphics/opengl/SpriteBatch.cpp +++ b/src/modules/graphics/opengl/SpriteBatch.cpp @@ -114,6 +114,9 @@ int SpriteBatch::add(float x, float y, float a, float sx, float sy, float ox, fl if (color) setColorv(sprite, *color); + // Auto-padded NPOT images require texcoord scaling for their vertices. + scaleNPOT(sprite, 4); + addv(sprite, (index == -1) ? next : index); // Increment counter. @@ -158,6 +161,9 @@ int SpriteBatch::addg(Geometry *geom, float x, float y, float a, float sx, float if (color && !geom->hasVertexColors()) setColorv(sprite, *color); + // Auto-padded NPOT images require texcoord scaling for their vertices. + scaleNPOT(sprite, 4); + addv(sprite, (index == -1) ? next : index); // Make sure SpriteBatch colors are enabled if the Geometry has custom colors. @@ -334,6 +340,23 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float glPopMatrix(); } +void SpriteBatch::scaleNPOT(vertex *v, size_t count) +{ + if (Image::hasNpot()) + return; + + love::Vector scale = image->getTexCoordScale(); + + if (scale.x == 1.0f && scale.y == 1.0f) + return; + + for (size_t i = 0; i < count; i++) + { + v[i].s *= scale.x; + v[i].t *= scale.y; + } +} + void SpriteBatch::addv(const vertex *v, int index) { static const int sprite_size = 4 * sizeof(vertex); // bytecount diff --git a/src/modules/graphics/opengl/SpriteBatch.h b/src/modules/graphics/opengl/SpriteBatch.h index 07d354cf7..f70c657c5 100644 --- a/src/modules/graphics/opengl/SpriteBatch.h +++ b/src/modules/graphics/opengl/SpriteBatch.h @@ -116,6 +116,8 @@ public: private: + void scaleNPOT(vertex *v, size_t count); + void addv(const vertex *v, int index); /**