diff --git a/src/modules/graphics/Geometry.cpp b/src/modules/graphics/Geometry.cpp index 5319da0f5..dd0c36abb 100644 --- a/src/modules/graphics/Geometry.cpp +++ b/src/modules/graphics/Geometry.cpp @@ -42,6 +42,7 @@ Geometry::Geometry(const std::vector &p) , x_max(std::numeric_limits::min()) , y_min(std::numeric_limits::max()) , y_max(std::numeric_limits::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 triangles = Math::instance.triangulate(polygon); diff --git a/src/modules/graphics/Geometry.h b/src/modules/graphics/Geometry.h index 6037fdc14..1aa460503 100644 --- a/src/modules/graphics/Geometry.h +++ b/src/modules/graphics/Geometry.h @@ -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 diff --git a/src/modules/graphics/opengl/Canvas.cpp b/src/modules/graphics/opengl/Canvas.cpp index f03d66328..3c0b0fe4f 100644 --- a/src/modules/graphics/opengl/Canvas.cpp +++ b/src/modules/graphics/opengl/Canvas.cpp @@ -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; } diff --git a/src/modules/graphics/opengl/Image.cpp b/src/modules/graphics/opengl/Image.cpp index 237e87ace..532ae4313 100644 --- a/src/modules/graphics/opengl/Image.cpp +++ b/src/modules/graphics/opengl/Image.cpp @@ -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() diff --git a/src/modules/graphics/opengl/SpriteBatch.cpp b/src/modules/graphics/opengl/SpriteBatch.cpp index 8c9f6ba93..7019f94e2 100644 --- a/src/modules/graphics/opengl/SpriteBatch.cpp +++ b/src/modules/graphics/opengl/SpriteBatch.cpp @@ -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); diff --git a/src/modules/graphics/opengl/wrap_Geometry.cpp b/src/modules/graphics/opengl/wrap_Geometry.cpp index efe8a8eda..1504daef9 100644 --- a/src/modules/graphics/opengl/wrap_Geometry.cpp +++ b/src/modules/graphics/opengl/wrap_Geometry.cpp @@ -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; } diff --git a/src/modules/graphics/opengl/wrap_Graphics.cpp b/src/modules/graphics/opengl/wrap_Graphics.cpp index 1ee9c9b5d..b9c7d4ef9 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/src/modules/graphics/opengl/wrap_Graphics.cpp @@ -375,13 +375,14 @@ int w_newImage(lua_State *L) int w_newGeometry(lua_State *L) { std::vector 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; }