Commits

Alex Szpakowski  committed 4239308

Geometries now automatically use per-vertex colors when drawing if any vertex has a custom color set, otherwise the constant color is used.
Still not a perfect solution, but it works better than before

  • Participants
  • Parent commits 80195a8

Comments (0)

Files changed (7)

File src/modules/graphics/Geometry.cpp

 	, x_max(std::numeric_limits<float>::min())
 	, y_min(std::numeric_limits<float>::max())
 	, y_max(std::numeric_limits<float>::min())
+	, vertexColors(false)
 {
 	for (size_t i = 0; i < polygon.size(); ++i)
 	{
 	, x_max(x+w)
 	, y_min(y)
 	, y_max(y+h)
+	, vertexColors(false)
 {
 	float s0 = x/sw, s1 = (x+w)/sw, t0 = y/sh, t1 = (y+h)/sh;
 	polygon.resize(4);
 	, x_max(other.x_max)
 	, y_min(other.y_min)
 	, y_max(other.y_max)
+	, vertexColors(other.vertexColors)
 {
 	vertexArray = new vertex[vertexCount];
 	memcpy(vertexArray, other.vertexArray, vertexCount * sizeof(vertex));
 		x_max       = temp.x_max;
 		y_min       = temp.y_min;
 		y_max       = temp.y_max;
+
+		vertexColors = other.vertexColors;
 	}
 	return *this;
 }
 	}
 }
 
+void Geometry::setVertexColors(bool on)
+{
+	vertexColors = on;
+}
+
 void Geometry::triangulate()
 {
 	const std::vector<Triangle> triangles = Math::instance.triangulate(polygon);

File src/modules/graphics/Geometry.h

 		return vertexCount;
 	}
 
+	/**
+	 * Sets whether this Geometry will use custom per-vertex colors.
+	 **/
+	void setVertexColors(bool on);
+
+	/**
+	 * Returns whether this Geometry is using custom per-vertex colors.
+	 **/
+	bool hasVertexColors() const
+	{
+		return vertexColors;
+	};
+
 private:
 	void triangulate();
 
 
 	float y_min;
 	float y_max;
+
+	bool vertexColors;
 };
 
 } // graphics

File src/modules/graphics/opengl/Canvas.cpp

 	}
 
 	// use colors stored in geometry (horrible, horrible hack)
-	glEnableClientState(GL_COLOR_ARRAY);
-	glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vertex), (GLvoid *)&v->r);
+	if (geom->hasVertexColors())
+	{
+		glEnableClientState(GL_COLOR_ARRAY);
+		glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vertex), (GLvoid *)&v->r);
+	}
+
 	drawv(t, v, vcount, GL_TRIANGLES);
-	glDisableClientState(GL_COLOR_ARRAY);
+
+	if (geom->hasVertexColors())
+	{
+		glDisableClientState(GL_COLOR_ARRAY);
+		gl.setColor(gl.getColor());
+	}
+
 	delete[] v;
 }
 

File src/modules/graphics/opengl/Image.cpp

 	static Matrix t;
 	t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
 
-	// use colors stored in geometry (horrible, horrible hack)
 	const vertex *v = geom->getVertexArray();
 
-	glEnableClientState(GL_COLOR_ARRAY);
-	glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vertex), (GLvoid *)&v->r);
+	// use colors stored in geometry (horrible, horrible hack)
+	if (geom->hasVertexColors())
+	{
+		glEnableClientState(GL_COLOR_ARRAY);
+		glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vertex), (GLvoid *) &v[0].r);
+	}
+
 	drawv(t, v, geom->getVertexArraySize(), GL_TRIANGLES);
-	glDisableClientState(GL_COLOR_ARRAY);
+
+	if (geom->hasVertexColors())
+	{
+		glDisableClientState(GL_COLOR_ARRAY);
+		gl.setColor(gl.getColor());
+	}
 }
 
 void Image::uploadCompressedMipmaps()

File src/modules/graphics/opengl/SpriteBatch.cpp

 	memcpy(sprite, image->getVertices(), sizeof(vertex)*4);
 
 	// Transform.
-	Matrix t;
+	static Matrix t;
 	t.setTransformation(x, y, a, sx, sy, ox, oy, kx, ky);
 	t.transform(sprite, sprite, 4);
 
 	if (geom->getNumVertices() != 4)
 		throw love::Exception("Can only add quadliteral geometries to SpriteBatch");
 
-	sprite[0] = geom->getVertex(0);
-	sprite[1] = geom->getVertex(1);
-	sprite[2] = geom->getVertex(2);
-	sprite[3] = geom->getVertex(3);
+	for (size_t i = 0; i < 4; i++)
+		sprite[i] = geom->getVertex(i);
 
 	// Transform.
-	Matrix t;
+	static Matrix t;
 	t.setTransformation(x, y, a, sx, sy, ox, oy, kx, ky);
 	t.transform(sprite, sprite, 4);
 
-	// color modulation
-	for (size_t i = 0; color && (i < 4); ++i)
-	{
-		sprite[i].r = (unsigned char)(double(sprite[i].r) * color->r / 255.);
-		sprite[i].g = (unsigned char)(double(sprite[i].g) * color->g / 255.);
-		sprite[i].b = (unsigned char)(double(sprite[i].b) * color->b / 255.);
-		sprite[i].a = (unsigned char)(double(sprite[i].a) * color->a / 255.);
-	}
+	// Set vertex colors to the constant color, if Geometry has no custom colors.
+	if (color && !geom->hasVertexColors())
+		setColorv(sprite, *color);
 
 	addv(sprite, (index == -1) ? next : index);
 

File src/modules/graphics/opengl/wrap_Geometry.cpp

 		return luaL_error(L, e.what());
 	}
 
+	if (lua_gettop(L) > 6)
+		geom->setVertexColors(true);
+
 	return 0;
 }
 

File src/modules/graphics/opengl/wrap_Graphics.cpp

 int w_newGeometry(lua_State *L)
 {
 	std::vector<vertex> vertices;
-	if (!lua_istable(L, 1))
-		return luaL_typerror(L, 1, "table");
+	luaL_checktype(L, 1, LUA_TTABLE);
 
 	size_t n = lua_objlen(L, 1);
 	if (n < 3)
 		return luaL_error(L, "Need at least three points to construct a geometry.");
 
+	bool hasvertexcolors = false;
+
 	vertices.reserve(n);
 	for (size_t i = 0; i < n; ++i)
 	{
 		if (!lua_istable(L, -1))
 			return luaL_typerror(L, 1, "table of tables");
 
-		lua_rawgeti(L, -1, 1);
-		v.x = luaL_checknumber(L, -1);
+		if (lua_objlen(L, -1) > 4)
+			hasvertexcolors = true;
 
-		lua_rawgeti(L, -2, 2);
-		v.y = luaL_checknumber(L, -1);
+		for (int j = 1; j <= 8; j++)
+			lua_rawgeti(L, -j, j);
 
-		lua_rawgeti(L, -3, 3);
-		v.s = luaL_checknumber(L, -1);
+		v.x = luaL_checknumber(L, -8);
+		v.y = luaL_checknumber(L, -7);
 
-		lua_rawgeti(L, -4, 4);
-		v.t = luaL_checknumber(L, -1);
+		v.s = luaL_checknumber(L, -6);
+		v.t = luaL_checknumber(L, -5);
 
-		lua_rawgeti(L, -5, 5);
-		v.r = luaL_optint(L, -1, 255);
-
-		lua_rawgeti(L, -6, 6);
-		v.g = luaL_optint(L, -1, 255);
-
-		lua_rawgeti(L, -7, 7);
-		v.b = luaL_optint(L, -1, 255);
-
-		lua_rawgeti(L, -8, 8);
+		v.r = luaL_optint(L, -4, 255);
+		v.g = luaL_optint(L, -3, 255);
+		v.b = luaL_optint(L, -2, 255);
 		v.a = luaL_optint(L, -1, 255);
 
 		lua_pop(L, 9);
+
 		vertices.push_back(v);
 	}
 
 	if (geom == 0)
 		return luaL_error(L, "Could not create geometry.");
 
+	geom->setVertexColors(hasvertexcolors);
+
 	luax_newtype(L, "Geometry", GRAPHICS_GEOMETRY_T, (void *)geom);
 	return 1;
 }