Преглед изворни кода

Faster editor line drawing - Path2D and draw_line

Changes the Path2D drawing to use POLYLINE instead of thick lines.
Add a path to translate thick lines (that are not using anti-aliasing) to draw as polygons instead. This should be faster because polygons can be batched.
lawnjelly пре 3 година
родитељ
комит
ab76cd6ff2
3 измењених фајлова са 52 додато и 6 уклоњено
  1. 8 6
      scene/2d/path_2d.cpp
  2. 1 0
      scene/2d/path_2d.h
  3. 43 0
      servers/visual/visual_server_canvas.cpp

+ 8 - 6
scene/2d/path_2d.cpp

@@ -101,16 +101,18 @@ void Path2D::_notification(int p_what) {
 #endif
 		const Color color = Color(1.0, 1.0, 1.0, 1.0);
 
-		for (int i = 0; i < curve->get_point_count(); i++) {
-			Vector2 prev_p = curve->get_point_position(i);
+		_cached_draw_pts.resize(curve->get_point_count() * 8);
+		int count = 0;
 
-			for (int j = 1; j <= 8; j++) {
-				real_t frac = j / 8.0;
+		for (int i = 0; i < curve->get_point_count(); i++) {
+			for (int j = 0; j < 8; j++) {
+				real_t frac = j * (1.0 / 8.0);
 				Vector2 p = curve->interpolate(i, frac);
-				draw_line(prev_p, p, color, line_width, true);
-				prev_p = p;
+				_cached_draw_pts.set(count++, p);
 			}
 		}
+
+		draw_polyline(_cached_draw_pts, color, line_width, true);
 	}
 }
 

+ 1 - 0
scene/2d/path_2d.h

@@ -38,6 +38,7 @@ class Path2D : public Node2D {
 	GDCLASS(Path2D, Node2D);
 
 	Ref<Curve2D> curve;
+	Vector<Vector2> _cached_draw_pts;
 
 	void _curve_changed();
 

+ 43 - 0
servers/visual/visual_server_canvas.cpp

@@ -448,6 +448,49 @@ void VisualServerCanvas::canvas_item_set_update_when_visible(RID p_item, bool p_
 }
 
 void VisualServerCanvas::canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width, bool p_antialiased) {
+	// Try drawing as a poly, because polys are batched and thus should run faster than thick lines,
+	// which run extremely slowly.
+	if (!p_antialiased && (p_width > 1.0)) {
+		// use poly drawing, as it is faster as it can use batching
+		static Vector<Point2> points;
+		static Vector<Color> colors;
+		static Vector<Point2> uvs;
+		if (points.size() != 4) {
+			// this should only be done once at runtime due to use of a static
+			points.resize(4);
+			colors.resize(4);
+			uvs.resize(4);
+		}
+
+		Vector2 side = p_to - p_from;
+		real_t length = side.length();
+		if (length == 0.0) {
+			// Not sure yet whether zero length is a noop operation later on,
+			// watch for visual errors. If there are visual errors, pass through
+			// to the line drawing routine below.
+			return;
+		}
+
+		// normalize
+		side /= length;
+
+		// 90 degrees
+		side = Vector2(-side.y, side.x);
+		side *= p_width;
+
+		points.set(0, p_from + side);
+		points.set(1, p_from - side);
+		points.set(2, p_to - side);
+		points.set(3, p_to + side);
+
+		for (int n = 0; n < 4; n++) {
+			colors.set(n, p_color);
+		}
+
+		canvas_item_add_polygon(p_item, points, colors, uvs, RID(), RID(), false);
+		return;
+	}
+
 	Item *canvas_item = canvas_item_owner.getornull(p_item);
 	ERR_FAIL_COND(!canvas_item);