From fb34f5bc9e4901379c38e4bd5a5923296389f987 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sun, 6 Oct 2013 23:25:29 -0300 Subject: [PATCH] Auto-padded NPOT images' texture coordinates are now scaled at draw time via the texture matrix (fixes auto-padded images with Meshes.) Also fixed love.graphics.newQuad. --HG-- branch : Mesh --- src/modules/graphics/opengl/Image.cpp | 52 +++++++++---------- src/modules/graphics/opengl/Image.h | 17 +++--- src/modules/graphics/opengl/Mesh.cpp | 5 +- .../graphics/opengl/ParticleSystem.cpp | 4 +- src/modules/graphics/opengl/SpriteBatch.cpp | 27 ++-------- src/modules/graphics/opengl/SpriteBatch.h | 2 - src/modules/graphics/opengl/wrap_Graphics.cpp | 10 ++-- 7 files changed, 52 insertions(+), 65 deletions(-) diff --git a/src/modules/graphics/opengl/Image.cpp b/src/modules/graphics/opengl/Image.cpp index bdcbd20c0..e475c8f36 100644 --- a/src/modules/graphics/opengl/Image.cpp +++ b/src/modules/graphics/opengl/Image.cpp @@ -42,6 +42,7 @@ Image::Image(love::image::ImageData *data) , width((float)(data->getWidth())) , height((float)(data->getHeight())) , texture(0) + , texCoordScale(1.0, 1.0) , mipmapSharpness(defaultMipmapSharpness) , mipmapsCreated(false) , compressed(false) @@ -114,25 +115,30 @@ void Image::drawq(Quad *quad, float x, float y, float angle, float sx, float sy, t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); const Vertex *v = quad->getVertices(); + drawv(t, v); +} - // Padded NPOT images require texture coordinate scaling with Quads. - if (!hasNpot()) +void Image::predraw() const +{ + bind(); + + if (texCoordScale.x < 1.0f || texCoordScale.y < 1.0f) { - Vertex w[4]; - love::Vector scale = getTexCoordScale(); - - for (int i = 0; i < 4; i++) - { - w[i] = v[i]; - w[i].s *= scale.x; - w[i].t *= scale.y; - } - - drawv(t, w); + // NPOT image but no NPOT support, so the texcoords should be scaled. + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + glScalef(texCoordScale.x, texCoordScale.y, 0.0f); + glMatrixMode(GL_MODELVIEW); } - else +} + +void Image::postdraw() const +{ + if (texCoordScale.x < 1.0f || texCoordScale.y < 1.0f) { - drawv(t, v); + glMatrixMode(GL_TEXTURE); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); } } @@ -385,10 +391,8 @@ bool Image::loadVolatilePOT() return true; } - vertices[1].t = t; - vertices[2].t = t; - vertices[2].s = s; - vertices[3].s = s; + texCoordScale.x = s; + texCoordScale.y = t; // We want this lock to potentially cover mipmap creation as well. love::thread::EmptyLock lock; @@ -577,15 +581,9 @@ void Image::uploadDefaultTexture() glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, px); } -love::Vector Image::getTexCoordScale() const -{ - // FIXME: this should be changed if Image::loadVolatilePOT changes. - return love::Vector(vertices[2].s, vertices[2].t); -} - void Image::drawv(const Matrix &t, const Vertex *v) const { - bind(); + predraw(); glPushMatrix(); @@ -603,6 +601,8 @@ void Image::drawv(const Matrix &t, const Vertex *v) const glDisableClientState(GL_VERTEX_ARRAY); glPopMatrix(); + + postdraw(); } void Image::setDefaultMipmapSharpness(float sharpness) diff --git a/src/modules/graphics/opengl/Image.h b/src/modules/graphics/opengl/Image.h index 382bf99f1..81d9d6d6d 100644 --- a/src/modules/graphics/opengl/Image.h +++ b/src/modules/graphics/opengl/Image.h @@ -88,6 +88,14 @@ public: **/ void drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const; + /** + * Call before using this Image's texture to draw. Binds the texture, + * globally scales texture coordinates if the Image has NPOT dimensions and + * NPOT isn't supported, etc. + **/ + void predraw() const; + void postdraw() const; + /** * Sets the filter mode. * @param f The filter mode. @@ -124,12 +132,6 @@ 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); @@ -172,6 +174,9 @@ private: // The source vertices of the image. Vertex vertices[4]; + // The scale applied to texcoords for NPOT images without NPOT support. + love::Vector texCoordScale; + // Mipmap texture LOD bias (sharpness) value. float mipmapSharpness; diff --git a/src/modules/graphics/opengl/Mesh.cpp b/src/modules/graphics/opengl/Mesh.cpp index 92be5bf78..32f04b371 100644 --- a/src/modules/graphics/opengl/Mesh.cpp +++ b/src/modules/graphics/opengl/Mesh.cpp @@ -211,7 +211,7 @@ void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, flo return; if (image) - image->bind(); + image->predraw(); else gl.bindTexture(0); @@ -268,6 +268,9 @@ void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, flo } glPopMatrix(); + + if (image) + image->postdraw(); } GLenum Mesh::getGLDrawMode(Mesh::DrawMode mode) const diff --git a/src/modules/graphics/opengl/ParticleSystem.cpp b/src/modules/graphics/opengl/ParticleSystem.cpp index 8cebeae7a..6b257927a 100644 --- a/src/modules/graphics/opengl/ParticleSystem.cpp +++ b/src/modules/graphics/opengl/ParticleSystem.cpp @@ -779,7 +779,7 @@ void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, flo p = p->next; } - image->bind(); + image->predraw(); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); @@ -795,6 +795,8 @@ void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, flo glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); + image->postdraw(); + glPopMatrix(); gl.setColor(curcolor); diff --git a/src/modules/graphics/opengl/SpriteBatch.cpp b/src/modules/graphics/opengl/SpriteBatch.cpp index 88dbfa4f5..0298cbbf0 100644 --- a/src/modules/graphics/opengl/SpriteBatch.cpp +++ b/src/modules/graphics/opengl/SpriteBatch.cpp @@ -116,9 +116,6 @@ 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. @@ -144,9 +141,6 @@ int SpriteBatch::addq(Quad *quad, float x, float y, float a, float sx, float sy, 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. @@ -285,7 +279,7 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); glMultMatrixf((const GLfloat *)t.getElements()); - image->bind(); + image->predraw(); VertexBuffer::Bind array_bind(*array_buf); VertexBuffer::Bind element_bind(*element_buf->getVertexBuffer()); @@ -316,26 +310,11 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float gl.setColor(curcolor); } + image->postdraw(); + 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 75d676d15..f3ac4fe5d 100644 --- a/src/modules/graphics/opengl/SpriteBatch.h +++ b/src/modules/graphics/opengl/SpriteBatch.h @@ -116,8 +116,6 @@ public: private: - void scaleNPOT(Vertex *v, size_t count); - void addv(const Vertex *v, int index); /** diff --git a/src/modules/graphics/opengl/wrap_Graphics.cpp b/src/modules/graphics/opengl/wrap_Graphics.cpp index e6e954b01..e325beb9a 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/src/modules/graphics/opengl/wrap_Graphics.cpp @@ -198,12 +198,12 @@ int w_newQuad(lua_State *L) { Quad::Viewport v; v.x = (float) luaL_checknumber(L, 1); - v.y = (float) luaL_checknumber(L, 1); - v.w = (float) luaL_checknumber(L, 1); - v.h = (float) luaL_checknumber(L, 1); + v.y = (float) luaL_checknumber(L, 2); + v.w = (float) luaL_checknumber(L, 3); + v.h = (float) luaL_checknumber(L, 4); - float sw = (float) luaL_checknumber(L, 1); - float sh = (float) luaL_checknumber(L, 1); + float sw = (float) luaL_checknumber(L, 5); + float sh = (float) luaL_checknumber(L, 6); Quad *quad = instance->newQuad(v, sw, sh); luax_pushtype(L, "Quad", GRAPHICS_QUAD_T, quad);