mirror of
https://github.com/love2d/love.git
synced 2026-08-19 12:14:20 +02:00
lines can render more than 65k vertices (resolves issue #1356).
This commit is contained in:
@@ -367,39 +367,63 @@ Polyline::~Polyline()
|
|||||||
|
|
||||||
void Polyline::draw(love::graphics::Graphics *gfx)
|
void Polyline::draw(love::graphics::Graphics *gfx)
|
||||||
{
|
{
|
||||||
int total_vertex_count = (int) vertex_count;
|
|
||||||
if (overdraw)
|
|
||||||
total_vertex_count = (int) (overdraw_vertex_start + overdraw_vertex_count);
|
|
||||||
|
|
||||||
const Matrix4 &t = gfx->getTransform();
|
const Matrix4 &t = gfx->getTransform();
|
||||||
bool is2D = t.isAffine2DTransform();
|
bool is2D = t.isAffine2DTransform();
|
||||||
|
|
||||||
Graphics::StreamDrawCommand cmd;
|
|
||||||
cmd.formats[0] = vertex::getSinglePositionFormat(is2D);
|
|
||||||
cmd.formats[1] = vertex::CommonFormat::RGBAub;
|
|
||||||
cmd.indexMode = triangle_mode;
|
|
||||||
cmd.vertexCount = total_vertex_count;
|
|
||||||
|
|
||||||
Graphics::StreamVertexData data = gfx->requestStreamDraw(cmd);
|
|
||||||
|
|
||||||
if (is2D)
|
|
||||||
t.transformXY((Vector2 *) data.stream[0], vertices, total_vertex_count);
|
|
||||||
else
|
|
||||||
t.transformXY0((Vector3 *) data.stream[0], vertices, total_vertex_count);
|
|
||||||
|
|
||||||
Color32 curcolor = toColor32(gfx->getColor());
|
Color32 curcolor = toColor32(gfx->getColor());
|
||||||
Color32 *colordata = (Color32 *) data.stream[1];
|
|
||||||
|
|
||||||
for (int i = 0; i < (int) vertex_count; i++)
|
int overdraw_start = (int) overdraw_vertex_start;
|
||||||
colordata[i] = curcolor;
|
int overdraw_count = (int) overdraw_vertex_count;
|
||||||
|
|
||||||
|
int total_vertex_count = (int) vertex_count;
|
||||||
if (overdraw)
|
if (overdraw)
|
||||||
fill_color_array(curcolor, colordata + overdraw_vertex_start);
|
total_vertex_count = overdraw_start + overdraw_count;
|
||||||
|
|
||||||
|
// love's automatic batching can only deal with < 65k vertices per draw.
|
||||||
|
// uint16_max - 3 is evenly divisible by 6 (needed for quads mode).
|
||||||
|
int maxvertices = LOVE_UINT16_MAX - 3;
|
||||||
|
|
||||||
|
int advance = maxvertices;
|
||||||
|
if (triangle_mode == vertex::TriangleIndexMode::STRIP)
|
||||||
|
advance -= 2;
|
||||||
|
|
||||||
|
for (int vertex_start = 0; vertex_start < total_vertex_count; vertex_start += advance)
|
||||||
|
{
|
||||||
|
const Vector2 *verts = vertices + vertex_start;
|
||||||
|
|
||||||
|
Graphics::StreamDrawCommand cmd;
|
||||||
|
cmd.formats[0] = vertex::getSinglePositionFormat(is2D);
|
||||||
|
cmd.formats[1] = vertex::CommonFormat::RGBAub;
|
||||||
|
cmd.indexMode = triangle_mode;
|
||||||
|
cmd.vertexCount = std::min(maxvertices, total_vertex_count - vertex_start);
|
||||||
|
|
||||||
|
Graphics::StreamVertexData data = gfx->requestStreamDraw(cmd);
|
||||||
|
|
||||||
|
if (is2D)
|
||||||
|
t.transformXY((Vector2 *) data.stream[0], verts, cmd.vertexCount);
|
||||||
|
else
|
||||||
|
t.transformXY0((Vector3 *) data.stream[0], verts, cmd.vertexCount);
|
||||||
|
|
||||||
|
Color32 *colordata = (Color32 *) data.stream[1];
|
||||||
|
|
||||||
|
// Constant vertex color up to the overdraw vertices.
|
||||||
|
for (int i = 0; i < std::min(cmd.vertexCount, (int) vertex_count - vertex_start); i++)
|
||||||
|
colordata[i] = curcolor;
|
||||||
|
|
||||||
|
int colorcount = 0;
|
||||||
|
if (overdraw)
|
||||||
|
colorcount = std::min(cmd.vertexCount, overdraw_count - (vertex_start - overdraw_start));
|
||||||
|
|
||||||
|
if (colorcount > 0)
|
||||||
|
{
|
||||||
|
Color32 *colors = colordata + std::max(0, (overdraw_start - vertex_start));
|
||||||
|
fill_color_array(curcolor, colors, colorcount);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Polyline::fill_color_array(Color32 constant_color, Color32 *colors)
|
void Polyline::fill_color_array(Color32 constant_color, Color32 *colors, int count)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < overdraw_vertex_count; ++i)
|
for (int i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
Color32 c = constant_color;
|
Color32 c = constant_color;
|
||||||
c.a *= (i+1) % 2; // avoids branching. equiv to if (i%2 == 1) c.a = 0;
|
c.a *= (i+1) % 2; // avoids branching. equiv to if (i%2 == 1) c.a = 0;
|
||||||
@@ -407,9 +431,9 @@ void Polyline::fill_color_array(Color32 constant_color, Color32 *colors)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NoneJoinPolyline::fill_color_array(Color32 constant_color, Color32 *colors)
|
void NoneJoinPolyline::fill_color_array(Color32 constant_color, Color32 *colors, int count)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < overdraw_vertex_count; ++i)
|
for (int i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
Color32 c = constant_color;
|
Color32 c = constant_color;
|
||||||
c.a *= (i & 3) < 2; // if (i % 4 == 2 || i % 4 == 3) c.a = 0
|
c.a *= (i & 3) < 2; // if (i % 4 == 2 || i % 4 == 3) c.a = 0
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ protected:
|
|||||||
|
|
||||||
virtual void calc_overdraw_vertex_count(bool is_looping);
|
virtual void calc_overdraw_vertex_count(bool is_looping);
|
||||||
virtual void render_overdraw(const std::vector<Vector2> &normals, float pixel_size, bool is_looping);
|
virtual void render_overdraw(const std::vector<Vector2> &normals, float pixel_size, bool is_looping);
|
||||||
virtual void fill_color_array(Color32 constant_color, Color32 *colors);
|
virtual void fill_color_array(Color32 constant_color, Color32 *colors, int count);
|
||||||
|
|
||||||
/** Calculate line boundary points.
|
/** Calculate line boundary points.
|
||||||
*
|
*
|
||||||
@@ -131,12 +131,12 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void calc_overdraw_vertex_count(bool is_looping);
|
void calc_overdraw_vertex_count(bool is_looping) override;
|
||||||
virtual void render_overdraw(const std::vector<Vector2> &normals, float pixel_size, bool is_looping);
|
void render_overdraw(const std::vector<Vector2> &normals, float pixel_size, bool is_looping) override;
|
||||||
virtual void fill_color_array(Color32 constant_color, Color32 *colors);
|
void fill_color_array(Color32 constant_color, Color32 *colors, int count) override;
|
||||||
virtual void renderEdge(std::vector<Vector2> &anchors, std::vector<Vector2> &normals,
|
void renderEdge(std::vector<Vector2> &anchors, std::vector<Vector2> &normals,
|
||||||
Vector2 &s, float &len_s, Vector2 &ns,
|
Vector2 &s, float &len_s, Vector2 &ns, const Vector2 &q,
|
||||||
const Vector2 &q, const Vector2 &r, float hw);
|
const Vector2 &r, float hw) override;
|
||||||
|
|
||||||
}; // NoneJoinPolyline
|
}; // NoneJoinPolyline
|
||||||
|
|
||||||
@@ -156,9 +156,9 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void renderEdge(std::vector<Vector2> &anchors, std::vector<Vector2> &normals,
|
void renderEdge(std::vector<Vector2> &anchors, std::vector<Vector2> &normals,
|
||||||
Vector2 &s, float &len_s, Vector2 &ns,
|
Vector2 &s, float &len_s, Vector2 &ns, const Vector2 &q,
|
||||||
const Vector2 &q, const Vector2 &r, float hw);
|
const Vector2 &r, float hw) override;
|
||||||
|
|
||||||
}; // MiterJoinPolyline
|
}; // MiterJoinPolyline
|
||||||
|
|
||||||
@@ -178,9 +178,9 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void renderEdge(std::vector<Vector2> &anchors, std::vector<Vector2> &normals,
|
void renderEdge(std::vector<Vector2> &anchors, std::vector<Vector2> &normals,
|
||||||
Vector2 &s, float &len_s, Vector2 &ns,
|
Vector2 &s, float &len_s, Vector2 &ns, const Vector2 &q,
|
||||||
const Vector2 &q, const Vector2 &r, float hw);
|
const Vector2 &r, float hw) override;
|
||||||
|
|
||||||
}; // BevelJoinPolyline
|
}; // BevelJoinPolyline
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user