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()) , x_max(std::numeric_limits<float>::min())
, y_min(std::numeric_limits<float>::max()) , y_min(std::numeric_limits<float>::max())
, y_max(std::numeric_limits<float>::min()) , y_max(std::numeric_limits<float>::min())
, vertexColors(false)
{ {
for (size_t i = 0; i < polygon.size(); ++i) 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) , x_max(x+w)
, y_min(y) , y_min(y)
, y_max(y+h) , y_max(y+h)
, vertexColors(false)
{ {
float s0 = x/sw, s1 = (x+w)/sw, t0 = y/sh, t1 = (y+h)/sh; float s0 = x/sw, s1 = (x+w)/sw, t0 = y/sh, t1 = (y+h)/sh;
polygon.resize(4); polygon.resize(4);
@@ -79,6 +81,7 @@ Geometry::Geometry(const Geometry &other)
, x_max(other.x_max) , x_max(other.x_max)
, y_min(other.y_min) , y_min(other.y_min)
, y_max(other.y_max) , y_max(other.y_max)
, vertexColors(other.vertexColors)
{ {
vertexArray = new vertex[vertexCount]; vertexArray = new vertex[vertexCount];
memcpy(vertexArray, other.vertexArray, vertexCount * sizeof(vertex)); memcpy(vertexArray, other.vertexArray, vertexCount * sizeof(vertex));
@@ -97,6 +100,8 @@ Geometry &Geometry::operator=(const Geometry &other)
x_max = temp.x_max; x_max = temp.x_max;
y_min = temp.y_min; y_min = temp.y_min;
y_max = temp.y_max; y_max = temp.y_max;
vertexColors = other.vertexColors;
} }
return *this; return *this;
} }
@@ -155,6 +160,11 @@ void Geometry::flip(bool x, bool y)
} }
} }
void Geometry::setVertexColors(bool on)
{
vertexColors = on;
}
void Geometry::triangulate() void Geometry::triangulate()
{ {
const std::vector<Triangle> triangles = Math::instance.triangulate(polygon); const std::vector<Triangle> triangles = Math::instance.triangulate(polygon);
+15
View File
@@ -86,6 +86,19 @@ public:
return vertexCount; 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: private:
void triangulate(); void triangulate();
@@ -99,6 +112,8 @@ private:
float y_min; float y_min;
float y_max; float y_max;
bool vertexColors;
}; };
} // graphics } // graphics
+10
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) // use colors stored in geometry (horrible, horrible hack)
if (geom->hasVertexColors())
{
glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vertex), (GLvoid *)&v->r); glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vertex), (GLvoid *)&v->r);
}
drawv(t, v, vcount, GL_TRIANGLES); drawv(t, v, vcount, GL_TRIANGLES);
if (geom->hasVertexColors())
{
glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_COLOR_ARRAY);
gl.setColor(gl.getColor());
}
delete[] v; delete[] v;
} }
+11 -2
View File
@@ -106,13 +106,22 @@ void Image::drawg(love::graphics::Geometry *geom, float x, float y, float angle,
static Matrix t; static Matrix t;
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
// use colors stored in geometry (horrible, horrible hack)
const vertex *v = geom->getVertexArray(); const vertex *v = geom->getVertexArray();
// use colors stored in geometry (horrible, horrible hack)
if (geom->hasVertexColors())
{
glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vertex), (GLvoid *)&v->r); glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vertex), (GLvoid *) &v[0].r);
}
drawv(t, v, geom->getVertexArraySize(), GL_TRIANGLES); drawv(t, v, geom->getVertexArraySize(), GL_TRIANGLES);
if (geom->hasVertexColors())
{
glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_COLOR_ARRAY);
gl.setColor(gl.getColor());
}
} }
void Image::uploadCompressedMipmaps() 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); memcpy(sprite, image->getVertices(), sizeof(vertex)*4);
// Transform. // Transform.
Matrix t; static Matrix t;
t.setTransformation(x, y, a, sx, sy, ox, oy, kx, ky); t.setTransformation(x, y, a, sx, sy, ox, oy, kx, ky);
t.transform(sprite, sprite, 4); 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) if (geom->getNumVertices() != 4)
throw love::Exception("Can only add quadliteral geometries to SpriteBatch"); throw love::Exception("Can only add quadliteral geometries to SpriteBatch");
sprite[0] = geom->getVertex(0); for (size_t i = 0; i < 4; i++)
sprite[1] = geom->getVertex(1); sprite[i] = geom->getVertex(i);
sprite[2] = geom->getVertex(2);
sprite[3] = geom->getVertex(3);
// Transform. // Transform.
Matrix t; static Matrix t;
t.setTransformation(x, y, a, sx, sy, ox, oy, kx, ky); t.setTransformation(x, y, a, sx, sy, ox, oy, kx, ky);
t.transform(sprite, sprite, 4); t.transform(sprite, sprite, 4);
// color modulation // Set vertex colors to the constant color, if Geometry has no custom colors.
for (size_t i = 0; color && (i < 4); ++i) if (color && !geom->hasVertexColors())
{ setColorv(sprite, *color);
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.);
}
addv(sprite, (index == -1) ? next : index); addv(sprite, (index == -1) ? next : index);
@@ -90,6 +90,9 @@ int w_Geometry_setVertex(lua_State *L)
return luaL_error(L, e.what()); return luaL_error(L, e.what());
} }
if (lua_gettop(L) > 6)
geom->setVertexColors(true);
return 0; return 0;
} }
+17 -20
View File
@@ -375,13 +375,14 @@ int w_newImage(lua_State *L)
int w_newGeometry(lua_State *L) int w_newGeometry(lua_State *L)
{ {
std::vector<vertex> vertices; std::vector<vertex> vertices;
if (!lua_istable(L, 1)) luaL_checktype(L, 1, LUA_TTABLE);
return luaL_typerror(L, 1, "table");
size_t n = lua_objlen(L, 1); size_t n = lua_objlen(L, 1);
if (n < 3) if (n < 3)
return luaL_error(L, "Need at least three points to construct a geometry."); return luaL_error(L, "Need at least three points to construct a geometry.");
bool hasvertexcolors = false;
vertices.reserve(n); vertices.reserve(n);
for (size_t i = 0; i < n; ++i) for (size_t i = 0; i < n; ++i)
{ {
@@ -390,31 +391,25 @@ int w_newGeometry(lua_State *L)
if (!lua_istable(L, -1)) if (!lua_istable(L, -1))
return luaL_typerror(L, 1, "table of tables"); return luaL_typerror(L, 1, "table of tables");
lua_rawgeti(L, -1, 1); if (lua_objlen(L, -1) > 4)
v.x = luaL_checknumber(L, -1); hasvertexcolors = true;
lua_rawgeti(L, -2, 2); for (int j = 1; j <= 8; j++)
v.y = luaL_checknumber(L, -1); lua_rawgeti(L, -j, j);
lua_rawgeti(L, -3, 3); v.x = luaL_checknumber(L, -8);
v.s = luaL_checknumber(L, -1); v.y = luaL_checknumber(L, -7);
lua_rawgeti(L, -4, 4); v.s = luaL_checknumber(L, -6);
v.t = luaL_checknumber(L, -1); v.t = luaL_checknumber(L, -5);
lua_rawgeti(L, -5, 5); v.r = luaL_optint(L, -4, 255);
v.r = luaL_optint(L, -1, 255); v.g = luaL_optint(L, -3, 255);
v.b = luaL_optint(L, -2, 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.a = luaL_optint(L, -1, 255); v.a = luaL_optint(L, -1, 255);
lua_pop(L, 9); lua_pop(L, 9);
vertices.push_back(v); vertices.push_back(v);
} }
@@ -431,6 +426,8 @@ int w_newGeometry(lua_State *L)
if (geom == 0) if (geom == 0)
return luaL_error(L, "Could not create geometry."); return luaL_error(L, "Could not create geometry.");
geom->setVertexColors(hasvertexcolors);
luax_newtype(L, "Geometry", GRAPHICS_GEOMETRY_T, (void *)geom); luax_newtype(L, "Geometry", GRAPHICS_GEOMETRY_T, (void *)geom);
return 1; return 1;
} }