Use vector2 arrays instead of raw float arrays for graphics primitives. Simplifies the code a bit.

--HG--
branch : minor
This commit is contained in:
Alex Szpakowski
2017-07-23 01:49:27 -03:00
parent 72ba5080fb
commit c37e9ed6bf
5 changed files with 124 additions and 115 deletions
+44 -51
View File
@@ -951,7 +951,7 @@ void Graphics::printf(const std::vector<Font::ColoredString> &str, Font *font, f
* Primitives (points, shapes, lines).
**/
void Graphics::points(const float *coords, const Colorf *colors, size_t numpoints)
void Graphics::points(const Vector2 *positions, const Colorf *colors, size_t numpoints)
{
const Matrix4 &t = getTransform();
bool is2D = t.isAffine2DTransform();
@@ -965,9 +965,9 @@ void Graphics::points(const float *coords, const Colorf *colors, size_t numpoint
StreamVertexData data = requestStreamDraw(req);
if (is2D)
t.transformXY((Vector2 *) data.stream[0], (const Vector2 *) coords, req.vertexCount);
t.transformXY((Vector2 *) data.stream[0], positions, req.vertexCount);
else
t.transformXY0((Vector3 *) data.stream[0], (const Vector2 *) coords, req.vertexCount);
t.transformXY0((Vector3 *) data.stream[0], positions, req.vertexCount);
Color *colordata = (Color *) data.stream[1];
@@ -1008,7 +1008,7 @@ int Graphics::calculateEllipsePoints(float rx, float ry) const
return std::max(points, 8);
}
void Graphics::polyline(const float *coords, size_t count)
void Graphics::polyline(const Vector2 *vertices, size_t count)
{
float halfwidth = getLineWidth() * 0.5f;
LineJoin linejoin = getLineJoin();
@@ -1019,27 +1019,27 @@ void Graphics::polyline(const float *coords, size_t count)
if (linejoin == LINE_JOIN_NONE)
{
NoneJoinPolyline line;
line.render(coords, count, halfwidth, pixelsize, linestyle == LINE_SMOOTH);
line.render(vertices, count, halfwidth, pixelsize, linestyle == LINE_SMOOTH);
line.draw(this);
}
else if (linejoin == LINE_JOIN_BEVEL)
{
BevelJoinPolyline line;
line.render(coords, count, halfwidth, pixelsize, linestyle == LINE_SMOOTH);
line.render(vertices, count, halfwidth, pixelsize, linestyle == LINE_SMOOTH);
line.draw(this);
}
else if (linejoin == LINE_JOIN_MITER)
{
MiterJoinPolyline line;
line.render(coords, count, halfwidth, pixelsize, linestyle == LINE_SMOOTH);
line.render(vertices, count, halfwidth, pixelsize, linestyle == LINE_SMOOTH);
line.draw(this);
}
}
void Graphics::rectangle(DrawMode mode, float x, float y, float w, float h)
{
float coords[] = {x,y, x,y+h, x+w,y+h, x+w,y, x,y};
polygon(mode, coords, 5 * 2);
Vector2 coords[] = {Vector2(x,y), Vector2(x,y+h), Vector2(x+w,y+h), Vector2(x+w,y), Vector2(x,y)};
polygon(mode, coords, 5);
}
void Graphics::rectangle(DrawMode mode, float x, float y, float w, float h, float rx, float ry, int points)
@@ -1062,44 +1062,43 @@ void Graphics::rectangle(DrawMode mode, float x, float y, float w, float h, floa
const float half_pi = static_cast<float>(LOVE_M_PI / 2);
float angle_shift = half_pi / ((float) points + 1.0f);
int num_coords = (points + 2) * 8;
float *coords = getScratchBuffer<float>(num_coords + 2);
int num_coords = (points + 2) * 4;
Vector2 *coords = getScratchBuffer<Vector2>(num_coords + 1);
float phi = .0f;
for (int i = 0; i <= points + 2; ++i, phi += angle_shift)
{
coords[2 * i + 0] = x + rx * (1 - cosf(phi));
coords[2 * i + 1] = y + ry * (1 - sinf(phi));
coords[i].x = x + rx * (1 - cosf(phi));
coords[i].y = y + ry * (1 - sinf(phi));
}
phi = half_pi;
for (int i = points + 2; i <= 2 * (points + 2); ++i, phi += angle_shift)
{
coords[2 * i + 0] = x + w - rx * (1 + cosf(phi));
coords[2 * i + 1] = y + ry * (1 - sinf(phi));
coords[i].x = x + w - rx * (1 + cosf(phi));
coords[i].y = y + ry * (1 - sinf(phi));
}
phi = 2 * half_pi;
for (int i = 2 * (points + 2); i <= 3 * (points + 2); ++i, phi += angle_shift)
{
coords[2 * i + 0] = x + w - rx * (1 + cosf(phi));
coords[2 * i + 1] = y + h - ry * (1 + sinf(phi));
coords[i].x = x + w - rx * (1 + cosf(phi));
coords[i].y = y + h - ry * (1 + sinf(phi));
}
phi = 3 * half_pi;
phi = 3 * half_pi;
for (int i = 3 * (points + 2); i <= 4 * (points + 2); ++i, phi += angle_shift)
{
coords[2 * i + 0] = x + rx * (1 - cosf(phi));
coords[2 * i + 1] = y + h - ry * (1 + sinf(phi));
coords[i].x = x + rx * (1 - cosf(phi));
coords[i].y = y + h - ry * (1 + sinf(phi));
}
coords[num_coords + 0] = coords[0];
coords[num_coords + 1] = coords[1];
coords[num_coords] = coords[0];
polygon(mode, coords, num_coords + 2);
polygon(mode, coords, num_coords + 1);
}
void Graphics::rectangle(DrawMode mode, float x, float y, float w, float h, float rx, float ry)
@@ -1124,15 +1123,14 @@ void Graphics::ellipse(DrawMode mode, float x, float y, float a, float b, int po
float angle_shift = (two_pi / points);
float phi = .0f;
float *coords = getScratchBuffer<float>(2 * (points + 1));
Vector2 *coords = getScratchBuffer<Vector2>(points + 1);
for (int i = 0; i < points; ++i, phi += angle_shift)
{
coords[2*i+0] = x + a * cosf(phi);
coords[2*i+1] = y + b * sinf(phi);
coords[i].x = x + a * cosf(phi);
coords[i].y = y + b * sinf(phi);
}
coords[2*points+0] = coords[0];
coords[2*points+1] = coords[1];
coords[points] = coords[0];
polygon(mode, coords, (points + 1) * 2);
}
@@ -1173,45 +1171,43 @@ void Graphics::arc(DrawMode drawmode, ArcMode arcmode, float x, float y, float r
float phi = angle1;
float *coords = nullptr;
Vector2 *coords = nullptr;
int num_coords = 0;
const auto createPoints = [&](float *coordinates)
const auto createPoints = [&](Vector2 *coordinates)
{
for (int i = 0; i <= points; ++i, phi += angle_shift)
{
coordinates[2 * i + 0] = x + radius * cosf(phi);
coordinates[2 * i + 1] = y + radius * sinf(phi);
coordinates[i].x = x + radius * cosf(phi);
coordinates[i].y = y + radius * sinf(phi);
}
};
if (arcmode == ARC_PIE)
{
num_coords = (points + 3) * 2;
coords = getScratchBuffer<float>(num_coords);
num_coords = points + 3;
coords = getScratchBuffer<Vector2>(num_coords);
coords[0] = coords[num_coords - 2] = x;
coords[1] = coords[num_coords - 1] = y;
coords[0] = coords[num_coords - 1] = Vector2(x, y);
createPoints(coords + 2);
createPoints(coords + 1);
}
else if (arcmode == ARC_OPEN)
{
num_coords = (points + 1) * 2;
coords = getScratchBuffer<float>(num_coords);
num_coords = points + 1;
coords = getScratchBuffer<Vector2>(num_coords);
createPoints(coords);
}
else // ARC_CLOSED
{
num_coords = (points + 2) * 2;
coords = getScratchBuffer<float>(num_coords);
num_coords = points + 2;
coords = getScratchBuffer<Vector2>(num_coords);
createPoints(coords);
// Connect the ends of the arc.
coords[num_coords - 2] = coords[0];
coords[num_coords - 1] = coords[1];
coords[num_coords - 1] = coords[0];
}
polygon(drawmode, coords, num_coords);
@@ -1229,13 +1225,10 @@ void Graphics::arc(DrawMode drawmode, ArcMode arcmode, float x, float y, float r
arc(drawmode, arcmode, x, y, radius, angle1, angle2, (int) (points + 0.5f));
}
/// @param mode the draw mode
/// @param coords the coordinate array
/// @param count the number of coordinates/size of the array
void Graphics::polygon(DrawMode mode, const float *coords, size_t count)
void Graphics::polygon(DrawMode mode, const Vector2 *coords, size_t count)
{
// coords is an array of a closed loop of vertices, i.e.
// coords[count-2] = coords[0], coords[count-1] = coords[1]
// coords[count-1] == coords[0]
if (mode == DRAW_LINE)
{
polyline(coords, count);
@@ -1249,14 +1242,14 @@ void Graphics::polygon(DrawMode mode, const float *coords, size_t count)
req.formats[0] = vertex::getSinglePositionFormat(is2D);
req.formats[1] = vertex::CommonFormat::RGBAub;
req.indexMode = vertex::TriangleIndexMode::FAN;
req.vertexCount = (int)count/2 - 1;
req.vertexCount = (int)count - 1;
StreamVertexData data = requestStreamDraw(req);
if (is2D)
t.transformXY((Vector2 *) data.stream[0], (const Vector2 *) coords, req.vertexCount);
t.transformXY((Vector2 *) data.stream[0], coords, req.vertexCount);
else
t.transformXY0((Vector3 *) data.stream[0], (const Vector2 *) coords, req.vertexCount);
t.transformXY0((Vector3 *) data.stream[0], coords, req.vertexCount);
Color c = toColor(getColor());
Color *colordata = (Color *) data.stream[1];
+8 -10
View File
@@ -620,18 +620,16 @@ public:
void printf(const std::vector<Font::ColoredString> &str, Font *font, float wrap, Font::AlignMode align, const Matrix4 &m);
/**
* Draws a point at (x,y).
* @param x Point along x-axis.
* @param y Point along y-axis.
* Draws a series of points at the specified positions.
**/
void points(const float *coords, const Colorf *colors, size_t numpoints);
void points(const Vector2 *positions, const Colorf *colors, size_t numpoints);
/**
* Draws a series of lines connecting the given vertices.
* @param coords Vertex components (x1, y1, ..., xn, yn). If x1,y1 == xn,yn the line will be drawn closed.
* @param count Number of items in the array, i.e. count = 2 * n
* @param coords Vertex positions (v1, ..., vn). If v1 == vn the line will be drawn closed.
* @param count Number of vertices.
**/
void polyline(const float *coords, size_t count);
void polyline(const Vector2 *vertices, size_t count);
/**
* Draws a rectangle.
@@ -696,10 +694,10 @@ public:
/**
* Draws a polygon with an arbitrary number of vertices.
* @param mode The type of drawing (line/filled).
* @param coords Vertex components (x1, y1, x2, y2, etc.)
* @param count Coord array size
* @param coords Vertex positions.
* @param count Vertex array size.
**/
void polygon(DrawMode mode, const float *coords, size_t count);
void polygon(DrawMode mode, const Vector2 *vertices, size_t count);
/**
* Gets the graphics capabilities (feature support, limit values, and
+8 -8
View File
@@ -33,7 +33,7 @@ namespace love
namespace graphics
{
void Polyline::render(const float *coords, size_t count, size_t size_hint, float halfwidth, float pixel_size, bool draw_overdraw)
void Polyline::render(const Vector2 *coords, size_t count, size_t size_hint, float halfwidth, float pixel_size, bool draw_overdraw)
{
static std::vector<Vector2> anchors;
anchors.clear();
@@ -48,26 +48,26 @@ void Polyline::render(const float *coords, size_t count, size_t size_hint, float
halfwidth -= pixel_size * 0.3f;
// compute sleeve
bool is_looping = (coords[0] == coords[count - 2]) && (coords[1] == coords[count - 1]);
bool is_looping = (coords[0] == coords[count - 1]);
Vector2 s;
if (!is_looping) // virtual starting point at second point mirrored on first point
s = Vector2(coords[2] - coords[0], coords[3] - coords[1]);
s = coords[1] - coords[0];
else // virtual starting point at last vertex
s = Vector2(coords[0] - coords[count - 4], coords[1] - coords[count - 3]);
s = coords[0] - coords[count - 2];
float len_s = s.getLength();
Vector2 ns = s.getNormal(halfwidth / len_s);
Vector2 q, r(coords[0], coords[1]);
for (size_t i = 0; i + 3 < count; i += 2)
Vector2 q, r(coords[0]);
for (size_t i = 0; i + 1 < count; i++)
{
q = r;
r = Vector2(coords[i + 2], coords[i + 3]);
r = coords[i + 1];
renderEdge(anchors, normals, s, len_s, ns, q, r, halfwidth);
}
q = r;
r = is_looping ? Vector2(coords[2], coords[3]) : r + s;
r = is_looping ? coords[1] : r + s;
renderEdge(anchors, normals, s, len_s, ns, q, r, halfwidth);
vertex_count = normals.size();
+8 -8
View File
@@ -57,13 +57,13 @@ public:
/**
* @param vertices Vertices defining the core line segments
* @param count Number of coordinates (= size of the array vertices)
* @param count Number of vertices
* @param size_hint Expected number of vertices of the rendering sleeve around the core line.
* @param halfwidth linewidth / 2.
* @param pixel_size Dimension of one pixel on the screen in world coordinates.
* @param draw_overdraw Fake antialias the line.
*/
void render(const float *vertices, size_t count, size_t size_hint, float halfwidth, float pixel_size, bool draw_overdraw);
void render(const Vector2 *vertices, size_t count, size_t size_hint, float halfwidth, float pixel_size, bool draw_overdraw);
/** Draws the line on the screen
*/
@@ -112,9 +112,9 @@ public:
: Polyline(vertex::TriangleIndexMode::QUADS)
{}
void render(const float *vertices, size_t count, float halfwidth, float pixel_size, bool draw_overdraw)
void render(const Vector2 *vertices, size_t count, float halfwidth, float pixel_size, bool draw_overdraw)
{
Polyline::render(vertices, count, 2 * count - 4, halfwidth, pixel_size, draw_overdraw);
Polyline::render(vertices, count, 4 * count - 4, halfwidth, pixel_size, draw_overdraw);
// discard the first and last two vertices. (these are redundant)
for (size_t i = 0; i < vertex_count - 4; ++i)
@@ -149,9 +149,9 @@ class MiterJoinPolyline : public Polyline
{
public:
void render(const float *vertices, size_t count, float halfwidth, float pixel_size, bool draw_overdraw)
void render(const Vector2 *vertices, size_t count, float halfwidth, float pixel_size, bool draw_overdraw)
{
Polyline::render(vertices, count, count, halfwidth, pixel_size, draw_overdraw);
Polyline::render(vertices, count, 2 * count, halfwidth, pixel_size, draw_overdraw);
}
protected:
@@ -171,9 +171,9 @@ class BevelJoinPolyline : public Polyline
{
public:
void render(const float *vertices, size_t count, float halfwidth, float pixel_size, bool draw_overdraw)
void render(const Vector2 *vertices, size_t count, float halfwidth, float pixel_size, bool draw_overdraw)
{
Polyline::render(vertices, count, 2 * count - 4, halfwidth, pixel_size, draw_overdraw);
Polyline::render(vertices, count, 4 * count - 4, halfwidth, pixel_size, draw_overdraw);
}
protected:
+56 -38
View File
@@ -2279,23 +2279,23 @@ int w_points(lua_State *L)
if (args % 2 != 0 && !is_table_of_tables)
return luaL_error(L, "Number of vertex components must be a multiple of two");
int numpoints = args / 2;
int numpositions = args / 2;
if (is_table_of_tables)
numpoints = args;
numpositions = args;
float *coords = nullptr;
Vector2 *positions = nullptr;
Colorf *colors = nullptr;
if (is_table_of_tables)
{
size_t datasize = (sizeof(float) * 2 + sizeof(Colorf)) * numpoints;
size_t datasize = (sizeof(Vector2) + sizeof(Colorf)) * numpositions;
uint8 *data = instance()->getScratchBuffer<uint8>(datasize);
coords = (float *) data;
colors = (Colorf *) (data + sizeof(float) * numpoints * 2);
positions = (Vector2 *) data;
colors = (Colorf *) (data + sizeof(Vector2) * numpositions);
}
else
coords = instance()->getScratchBuffer<float>(numpoints * 2);
positions = instance()->getScratchBuffer<Vector2>(numpositions);
if (is_table)
{
@@ -2308,13 +2308,13 @@ int w_points(lua_State *L)
for (int j = 1; j <= 6; j++)
lua_rawgeti(L, -j, j);
coords[i * 2 + 0] = luax_tofloat(L, -6);
coords[i * 2 + 1] = luax_tofloat(L, -5);
positions[i].x = luax_tofloat(L, -6);
positions[i].y = luax_tofloat(L, -5);
colors[i].r = luaL_optnumber(L, -4, 1.0);
colors[i].g = luaL_optnumber(L, -3, 1.0);
colors[i].b = luaL_optnumber(L, -2, 1.0);
colors[i].a = luaL_optnumber(L, -1, 1.0);
colors[i].r = (float) luaL_optnumber(L, -4, 1.0);
colors[i].g = (float) luaL_optnumber(L, -3, 1.0);
colors[i].b = (float) luaL_optnumber(L, -2, 1.0);
colors[i].a = (float) luaL_optnumber(L, -1, 1.0);
lua_pop(L, 7);
}
@@ -2322,21 +2322,26 @@ int w_points(lua_State *L)
else
{
// points({x1, y1, x2, y2, ...})
for (int i = 0; i < args; i++)
for (int i = 0; i < numpositions; i++)
{
lua_rawgeti(L, 1, i + 1);
coords[i] = luax_tofloat(L, -1);
lua_pop(L, 1);
lua_rawgeti(L, 1, i * 2 + 1);
lua_rawgeti(L, 1, i * 2 + 2);
positions[i].x = luax_tofloat(L, -2);
positions[i].y = luax_tofloat(L, -1);
lua_pop(L, 2);
}
}
}
else
{
for (int i = 0; i < args; i++)
coords[i] = luax_tofloat(L, i + 1);
for (int i = 0; i < numpositions; i++)
{
positions[i].x = luax_tofloat(L, i * 2 + 1);
positions[i].y = luax_tofloat(L, i * 2 + 2);
}
}
luax_catchexcept(L, [&](){ instance()->points(coords, colors, numpoints); });
luax_catchexcept(L, [&](){ instance()->points(positions, colors, numpositions); });
return 0;
}
@@ -2355,24 +2360,31 @@ int w_line(lua_State *L)
else if (args < 4)
return luaL_error(L, "Need at least two vertices to draw a line");
float *coords = instance()->getScratchBuffer<float>(args);
int numvertices = args / 2;
Vector2 *coords = instance()->getScratchBuffer<Vector2>(numvertices);
if (is_table)
{
for (int i = 0; i < args; ++i)
for (int i = 0; i < numvertices; ++i)
{
lua_rawgeti(L, 1, i + 1);
coords[i] = luax_tofloat(L, -1);
lua_pop(L, 1);
lua_rawgeti(L, 1, (i * 2) + 1);
lua_rawgeti(L, 1, (i * 2) + 2);
coords[i].x = luax_tofloat(L, -2);
coords[i].y = luax_tofloat(L, -1);
lua_pop(L, 2);
}
}
else
{
for (int i = 0; i < args; ++i)
coords[i] = luax_tofloat(L, i + 1);
for (int i = 0; i < numvertices; ++i)
{
coords[i].x = luax_tofloat(L, (i * 2) + 1);
coords[i].y = luax_tofloat(L, (i * 2) + 2);
}
}
luax_catchexcept(L,
[&](){ instance()->polyline(coords, args); }
[&](){ instance()->polyline(coords, numvertices); }
);
return 0;
@@ -2513,28 +2525,34 @@ int w_polygon(lua_State *L)
else if (args < 6)
return luaL_error(L, "Need at least three vertices to draw a polygon");
int numvertices = args / 2;
// fetch coords
float *coords = instance()->getScratchBuffer<float>(args + 2);
Vector2 *coords = instance()->getScratchBuffer<Vector2>(numvertices + 1);
if (is_table)
{
for (int i = 0; i < args; ++i)
for (int i = 0; i < numvertices; ++i)
{
lua_rawgeti(L, 2, i + 1);
coords[i] = luax_tofloat(L, -1);
lua_pop(L, 1);
lua_rawgeti(L, 2, (i * 2) + 1);
lua_rawgeti(L, 2, (i * 2) + 2);
coords[i].x = luax_tofloat(L, -2);
coords[i].y = luax_tofloat(L, -1);
lua_pop(L, 2);
}
}
else
{
for (int i = 0; i < args; ++i)
coords[i] = luax_tofloat(L, i + 2);
for (int i = 0; i < numvertices; ++i)
{
coords[i].x = luax_tofloat(L, (i * 2) + 2);
coords[i].y = luax_tofloat(L, (i * 2) + 3);
}
}
// make a closed loop
coords[args] = coords[0];
coords[args+1] = coords[1];
coords[numvertices] = coords[0];
luax_catchexcept(L, [&](){ instance()->polygon(mode, coords, args+2); });
luax_catchexcept(L, [&](){ instance()->polygon(mode, coords, numvertices+1); });
return 0;
}