diff --git a/src/modules/graphics/Graphics.cpp b/src/modules/graphics/Graphics.cpp index daf1cdf32..5a6b7a7ad 100644 --- a/src/modules/graphics/Graphics.cpp +++ b/src/modules/graphics/Graphics.cpp @@ -2589,21 +2589,42 @@ void Graphics::polygon(DrawMode mode, const Vector2 *coords, size_t count, bool BatchedDrawCommand cmd; cmd.formats[0] = getSinglePositionFormat(is2D); - cmd.formats[1] = CommonFormat::RGBAub; + cmd.formats[1] = CommonFormat::STf_RGBAub; cmd.indexMode = TRIANGLEINDEX_FAN; cmd.vertexCount = (int)count - (skipLastFilledVertex ? 1 : 0); BatchedVertexData data = requestBatchedDraw(cmd); - if (is2D) - t.transformXY((Vector2 *) data.stream[0], coords, cmd.vertexCount); - else - t.transformXY0((Vector3 *) data.stream[0], coords, cmd.vertexCount); + // Compute texture coordinates. + constexpr float inf = std::numeric_limits::infinity(); + Vector2 mincoord(inf, inf); + Vector2 maxcoord(-inf, -inf); + + for (int i = 0; i < cmd.vertexCount; i++) + { + Vector2 v = coords[i]; + mincoord.x = std::min(mincoord.x, v.x); + mincoord.y = std::min(mincoord.y, v.y); + maxcoord.x = std::max(maxcoord.x, v.x); + maxcoord.y = std::max(maxcoord.y, v.y); + } + + Vector2 invsize(1.0f / (maxcoord.x - mincoord.x), 1.0f / (maxcoord.y - mincoord.y)); + Vector2 start(mincoord.x * invsize.x, mincoord.y * invsize.y); Color32 c = toColor32(getColor()); - Color32 *colordata = (Color32 *) data.stream[1]; + STf_RGBAub *attributes = (STf_RGBAub *) data.stream[1]; for (int i = 0; i < cmd.vertexCount; i++) - colordata[i] = c; + { + attributes[i].s = coords[i].x * invsize.x - start.x; + attributes[i].t = coords[i].y * invsize.y - start.y; + attributes[i].color = c; + } + + if (is2D) + t.transformXY((Vector2*)data.stream[0], coords, cmd.vertexCount); + else + t.transformXY0((Vector3*)data.stream[0], coords, cmd.vertexCount); } } diff --git a/src/modules/graphics/Polyline.cpp b/src/modules/graphics/Polyline.cpp index 2a97893b8..f9537067d 100644 --- a/src/modules/graphics/Polyline.cpp +++ b/src/modules/graphics/Polyline.cpp @@ -424,7 +424,7 @@ void Polyline::draw(love::graphics::Graphics *gfx) Graphics::BatchedDrawCommand cmd; cmd.formats[0] = getSinglePositionFormat(is2D); - cmd.formats[1] = CommonFormat::RGBAub; + cmd.formats[1] = CommonFormat::STf_RGBAub; cmd.indexMode = triangle_mode; cmd.vertexCount = std::min(maxvertices, total_vertex_count - vertex_start); @@ -435,13 +435,19 @@ void Polyline::draw(love::graphics::Graphics *gfx) else t.transformXY0((Vector3 *) data.stream[0], verts, cmd.vertexCount); - Color32 *colordata = (Color32 *) data.stream[1]; + STf_RGBAub *attributes = (STf_RGBAub *) data.stream[1]; int draw_rough_count = std::min(cmd.vertexCount, (int) vertex_count - vertex_start); // Constant vertex color up to the overdraw vertices. + // Texture coordinates are a constant value, we only have them to keep auto-batching + // when drawing filled and line polygons together. for (int i = 0; i < draw_rough_count; i++) - colordata[i] = curcolor; + { + attributes[i].s = 0.0f; + attributes[i].t = 0.0f; + attributes[i].color = curcolor; + } if (overdraw) { @@ -456,30 +462,34 @@ void Polyline::draw(love::graphics::Graphics *gfx) if (draw_overdraw_count > 0) { - Color32 *colors = colordata + draw_overdraw_begin; - fill_color_array(curcolor, colors, draw_overdraw_count); + STf_RGBAub *c = attributes + draw_overdraw_begin; + fill_color_array(curcolor, c, draw_overdraw_count); } } } } -void Polyline::fill_color_array(Color32 constant_color, Color32 *colors, int count) +void Polyline::fill_color_array(Color32 constant_color, STf_RGBAub *attributes, int count) { for (int i = 0; i < count; ++i) { Color32 c = constant_color; c.a *= (i+1) % 2; // avoids branching. equiv to if (i%2 == 1) c.a = 0; - colors[i] = c; + attributes[i].s = 0.0f; + attributes[i].t = 0.0f; + attributes[i].color = c; } } -void NoneJoinPolyline::fill_color_array(Color32 constant_color, Color32 *colors, int count) +void NoneJoinPolyline::fill_color_array(Color32 constant_color, STf_RGBAub *attributes, int count) { for (int i = 0; i < count; ++i) { Color32 c = constant_color; c.a *= (i & 3) < 2; // if (i % 4 == 2 || i % 4 == 3) c.a = 0 - colors[i] = c; + attributes[i].s = 0.0f; + attributes[i].t = 0.0f; + attributes[i].color = c; } } diff --git a/src/modules/graphics/Polyline.h b/src/modules/graphics/Polyline.h index c33bb7068..2acf88382 100644 --- a/src/modules/graphics/Polyline.h +++ b/src/modules/graphics/Polyline.h @@ -73,7 +73,7 @@ class Polyline virtual void calc_overdraw_vertex_count(bool is_looping); virtual void render_overdraw(const std::vector &normals, float pixel_size, bool is_looping); - virtual void fill_color_array(Color32 constant_color, Color32 *colors, int count); + virtual void fill_color_array(Color32 constant_color, STf_RGBAub *attributes, int count); /** Calculate line boundary points. * @@ -133,7 +133,7 @@ class NoneJoinPolyline : public Polyline void calc_overdraw_vertex_count(bool is_looping) override; void render_overdraw(const std::vector &normals, float pixel_size, bool is_looping) override; - void fill_color_array(Color32 constant_color, Color32 *colors, int count) override; + void fill_color_array(Color32 constant_color, STf_RGBAub *attributes, int count) override; void renderEdge(std::vector &anchors, std::vector &normals, Vector2 &s, float &len_s, Vector2 &ns, const Vector2 &q, const Vector2 &r, float hw) override;