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
This commit is contained in:
Alex Szpakowski
2013-04-23 23:25:45 -07:00
parent a5eaffe625
commit 3b05ec0635
7 changed files with 78 additions and 41 deletions
+10
View File
@@ -42,6 +42,7 @@ Geometry::Geometry(const std::vector<vertex> &p)
, 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)
{
@@ -61,6 +62,7 @@ Geometry::Geometry(float x, float y, float w, float h, float sw, float sh)
, 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);
@@ -79,6 +81,7 @@ Geometry::Geometry(const Geometry &other)
, 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));
@@ -97,6 +100,8 @@ Geometry &Geometry::operator=(const Geometry &other)
x_max = temp.x_max;
y_min = temp.y_min;
y_max = temp.y_max;
vertexColors = other.vertexColors;
}
return *this;
}
@@ -155,6 +160,11 @@ void Geometry::flip(bool x, bool y)
}
}
void Geometry::setVertexColors(bool on)
{
vertexColors = on;
}
void Geometry::triangulate()
{
const std::vector<Triangle> triangles = Math::instance.triangulate(polygon);
+15
View File
@@ -86,6 +86,19 @@ public:
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();
@@ -99,6 +112,8 @@ private:
float y_min;
float y_max;
bool vertexColors;
};
} // graphics
+13 -3
View File
@@ -600,10 +600,20 @@ void Canvas::drawg(love::graphics::Geometry *geom, float x, float y, float angle
}
// 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;
}
+13 -4
View File
@@ -106,13 +106,22 @@ void Image::drawg(love::graphics::Geometry *geom, float x, float y, float angle,
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()
+7 -14
View File
@@ -101,7 +101,7 @@ int SpriteBatch::add(float x, float y, float a, float sx, float sy, float ox, fl
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);
@@ -126,24 +126,17 @@ int SpriteBatch::addg(Geometry *geom, float x, float y, float a, float sx, float
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);
@@ -90,6 +90,9 @@ int w_Geometry_setVertex(lua_State *L)
return luaL_error(L, e.what());
}
if (lua_gettop(L) > 6)
geom->setVertexColors(true);
return 0;
}
+17 -20
View File
@@ -375,13 +375,14 @@ int w_newImage(lua_State *L)
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)
{
@@ -390,31 +391,25 @@ int w_newGeometry(lua_State *L)
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);
}
@@ -431,6 +426,8 @@ int w_newGeometry(lua_State *L)
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;
}