Browse Source

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
Alex Szpakowski 12 years ago
parent
commit
fb34f5bc9e

+ 26 - 26
src/modules/graphics/opengl/Image.cpp

@@ -42,6 +42,7 @@ Image::Image(love::image::ImageData *data)
 	, width((float)(data->getWidth()))
 	, width((float)(data->getWidth()))
 	, height((float)(data->getHeight()))
 	, height((float)(data->getHeight()))
 	, texture(0)
 	, texture(0)
+	, texCoordScale(1.0, 1.0)
 	, mipmapSharpness(defaultMipmapSharpness)
 	, mipmapSharpness(defaultMipmapSharpness)
 	, mipmapsCreated(false)
 	, mipmapsCreated(false)
 	, compressed(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);
 	t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
 
 
 	const Vertex *v = quad->getVertices();
 	const Vertex *v = quad->getVertices();
+	drawv(t, v);
+}
 
 
-	// Padded NPOT images require texture coordinate scaling with Quads.
-	if (!hasNpot())
-	{
-		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;
-		}
+void Image::predraw() const
+{
+	bind();
 
 
-		drawv(t, w);
+	if (texCoordScale.x < 1.0f || texCoordScale.y < 1.0f)
+	{
+		// 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;
 		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.
 	// We want this lock to potentially cover mipmap creation as well.
 	love::thread::EmptyLock lock;
 	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);
 	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
 void Image::drawv(const Matrix &t, const Vertex *v) const
 {
 {
-	bind();
+	predraw();
 
 
 	glPushMatrix();
 	glPushMatrix();
 
 
@@ -603,6 +601,8 @@ void Image::drawv(const Matrix &t, const Vertex *v) const
 	glDisableClientState(GL_VERTEX_ARRAY);
 	glDisableClientState(GL_VERTEX_ARRAY);
 
 
 	glPopMatrix();
 	glPopMatrix();
+
+	postdraw();
 }
 }
 
 
 void Image::setDefaultMipmapSharpness(float sharpness)
 void Image::setDefaultMipmapSharpness(float sharpness)

+ 11 - 6
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;
 	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.
 	 * Sets the filter mode.
 	 * @param f The filter mode.
 	 * @param f The filter mode.
@@ -124,12 +132,6 @@ public:
 	 **/
 	 **/
 	bool refresh();
 	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 void setDefaultMipmapSharpness(float sharpness);
 	static float getDefaultMipmapSharpness();
 	static float getDefaultMipmapSharpness();
 	static void setDefaultMipmapFilter(FilterMode f);
 	static void setDefaultMipmapFilter(FilterMode f);
@@ -172,6 +174,9 @@ private:
 	// The source vertices of the image.
 	// The source vertices of the image.
 	Vertex vertices[4];
 	Vertex vertices[4];
 
 
+	// The scale applied to texcoords for NPOT images without NPOT support.
+	love::Vector texCoordScale;
+
 	// Mipmap texture LOD bias (sharpness) value.
 	// Mipmap texture LOD bias (sharpness) value.
 	float mipmapSharpness;
 	float mipmapSharpness;
 
 

+ 4 - 1
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;
 		return;
 
 
 	if (image)
 	if (image)
-		image->bind();
+		image->predraw();
 	else
 	else
 		gl.bindTexture(0);
 		gl.bindTexture(0);
 
 
@@ -268,6 +268,9 @@ void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, flo
 	}
 	}
 
 
 	glPopMatrix();
 	glPopMatrix();
+
+	if (image)
+		image->postdraw();
 }
 }
 
 
 GLenum Mesh::getGLDrawMode(Mesh::DrawMode mode) const
 GLenum Mesh::getGLDrawMode(Mesh::DrawMode mode) const

+ 3 - 1
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;
 		p = p->next;
 	}
 	}
 
 
-	image->bind();
+	image->predraw();
 
 
 	glEnableClientState(GL_COLOR_ARRAY);
 	glEnableClientState(GL_COLOR_ARRAY);
 	glEnableClientState(GL_VERTEX_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_VERTEX_ARRAY);
 	glDisableClientState(GL_COLOR_ARRAY);
 	glDisableClientState(GL_COLOR_ARRAY);
 
 
+	image->postdraw();
+
 	glPopMatrix();
 	glPopMatrix();
 
 
 	gl.setColor(curcolor);
 	gl.setColor(curcolor);

+ 3 - 24
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)
 	if (color)
 		setColorv(sprite, *color);
 		setColorv(sprite, *color);
 
 
-	// Auto-padded NPOT images require texcoord scaling for their vertices.
-	scaleNPOT(sprite, 4);
-
 	addv(sprite, (index == -1) ? next : index);
 	addv(sprite, (index == -1) ? next : index);
 
 
 	// Increment counter.
 	// Increment counter.
@@ -144,9 +141,6 @@ int SpriteBatch::addq(Quad *quad, float x, float y, float a, float sx, float sy,
 	if (color)
 	if (color)
 		setColorv(sprite, *color);
 		setColorv(sprite, *color);
 
 
-	// Auto-padded NPOT images require texcoord scaling for their vertices.
-	scaleNPOT(sprite, 4);
-
 	addv(sprite, (index == -1) ? next : index);
 	addv(sprite, (index == -1) ? next : index);
 
 
 	// Increment counter.
 	// 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);
 	t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
 	glMultMatrixf((const GLfloat *)t.getElements());
 	glMultMatrixf((const GLfloat *)t.getElements());
 
 
-	image->bind();
+	image->predraw();
 
 
 	VertexBuffer::Bind array_bind(*array_buf);
 	VertexBuffer::Bind array_bind(*array_buf);
 	VertexBuffer::Bind element_bind(*element_buf->getVertexBuffer());
 	VertexBuffer::Bind element_bind(*element_buf->getVertexBuffer());
@@ -316,24 +310,9 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float
 		gl.setColor(curcolor);
 		gl.setColor(curcolor);
 	}
 	}
 
 
-	glPopMatrix();
-}
-
-void SpriteBatch::scaleNPOT(Vertex *v, size_t count)
-{
-	if (Image::hasNpot())
-		return;
+	image->postdraw();
 
 
-	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;
-	}
+	glPopMatrix();
 }
 }
 
 
 void SpriteBatch::addv(const Vertex *v, int index)
 void SpriteBatch::addv(const Vertex *v, int index)

+ 0 - 2
src/modules/graphics/opengl/SpriteBatch.h

@@ -116,8 +116,6 @@ public:
 
 
 private:
 private:
 
 
-	void scaleNPOT(Vertex *v, size_t count);
-
 	void addv(const Vertex *v, int index);
 	void addv(const Vertex *v, int index);
 
 
 	/**
 	/**

+ 5 - 5
src/modules/graphics/opengl/wrap_Graphics.cpp

@@ -198,12 +198,12 @@ int w_newQuad(lua_State *L)
 {
 {
 	Quad::Viewport v;
 	Quad::Viewport v;
 	v.x = (float) luaL_checknumber(L, 1);
 	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);
 	Quad *quad = instance->newQuad(v, sw, sh);
 	luax_pushtype(L, "Quad", GRAPHICS_QUAD_T, quad);
 	luax_pushtype(L, "Quad", GRAPHICS_QUAD_T, quad);