Browse Source

Filled polygons have texture coordinates computed from their bounds.

Fixes #1951.
Sasha Szpakowski 1 year ago
parent
commit
ed6a50178c

+ 28 - 7
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<float>::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);
 	}
 }
 

+ 19 - 9
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;
 	}
 }
 

+ 2 - 2
src/modules/graphics/Polyline.h

@@ -73,7 +73,7 @@ protected:
 
 	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 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 @@ protected:
 
 	void calc_overdraw_vertex_count(bool is_looping) override;
 	void render_overdraw(const std::vector<Vector2> &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<Vector2> &anchors, std::vector<Vector2> &normals,
 	                Vector2 &s, float &len_s, Vector2 &ns, const Vector2 &q,
 	                const Vector2 &r, float hw) override;