Browse Source

Merge pull request #20191 from jvdnbus/line2d-stretch

Line2D texture stretch mode
Max Hilbrunner 7 years ago
parent
commit
1f1b45c7ec
4 changed files with 17 additions and 6 deletions
  1. 3 0
      doc/classes/Line2D.xml
  2. 2 1
      scene/2d/line_2d.cpp
  3. 2 2
      scene/2d/line_2d.h
  4. 10 3
      scene/2d/line_builder.cpp

+ 3 - 0
doc/classes/Line2D.xml

@@ -117,5 +117,8 @@
 		<constant name="LINE_TEXTURE_TILE" value="1" enum="LineTextureMode">
 			Tiles the texture over the line. The texture need to be imported with Repeat Enabled for it to work properly.
 		</constant>
+		<constant name="LINE_TEXTURE_STRETCH" value="2" enum="LineTextureMode">
+			Stretches the texture across the line. Import the texture with Repeat Disabled for best results.
+		</constant>
 	</constants>
 </class>

+ 2 - 1
scene/2d/line_2d.cpp

@@ -349,7 +349,7 @@ void Line2D::_bind_methods() {
 	ADD_GROUP("Fill", "");
 	ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient");
 	ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
-	ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "texture_mode", PROPERTY_HINT_ENUM, "None,Tile"), "set_texture_mode", "get_texture_mode");
+	ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "texture_mode", PROPERTY_HINT_ENUM, "None,Tile,Stretch"), "set_texture_mode", "get_texture_mode");
 	ADD_GROUP("Capping", "");
 	ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "joint_mode", PROPERTY_HINT_ENUM, "Sharp,Bevel,Round"), "set_joint_mode", "get_joint_mode");
 	ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "begin_cap_mode", PROPERTY_HINT_ENUM, "None,Box,Round"), "set_begin_cap_mode", "get_begin_cap_mode");
@@ -368,6 +368,7 @@ void Line2D::_bind_methods() {
 
 	BIND_ENUM_CONSTANT(LINE_TEXTURE_NONE);
 	BIND_ENUM_CONSTANT(LINE_TEXTURE_TILE);
+	BIND_ENUM_CONSTANT(LINE_TEXTURE_STRETCH);
 
 	ClassDB::bind_method(D_METHOD("_gradient_changed"), &Line2D::_gradient_changed);
 }

+ 2 - 2
scene/2d/line_2d.h

@@ -52,8 +52,8 @@ public:
 
 	enum LineTextureMode {
 		LINE_TEXTURE_NONE = 0,
-		LINE_TEXTURE_TILE
-		// TODO STRETCH mode
+		LINE_TEXTURE_TILE,
+		LINE_TEXTURE_STRETCH
 	};
 
 	Line2D();

+ 10 - 3
scene/2d/line_builder.cpp

@@ -146,7 +146,9 @@ void LineBuilder::build() {
 	float current_distance1 = 0.f;
 	float total_distance = 0.f;
 	_interpolate_color = gradient != NULL;
-	bool distance_required = _interpolate_color || texture_mode == Line2D::LINE_TEXTURE_TILE;
+	bool distance_required = _interpolate_color ||
+							 texture_mode == Line2D::LINE_TEXTURE_TILE ||
+							 texture_mode == Line2D::LINE_TEXTURE_STRETCH;
 	if (distance_required)
 		total_distance = calculate_total_distance(points);
 	if (_interpolate_color)
@@ -170,7 +172,7 @@ void LineBuilder::build() {
 		if (texture_mode == Line2D::LINE_TEXTURE_TILE) {
 			uvx0 = 0.5f / tile_aspect;
 		}
-		new_arc(pos0, pos_up0 - pos0, -Math_PI, color0, Rect2(0.f, 0.f, 1.f, 1.f));
+		new_arc(pos0, pos_up0 - pos0, -Math_PI, color0, Rect2(0.f, 0.f, fmin(uvx0 * 2, 1.f), 1.f));
 		total_distance += width;
 		current_distance0 += hw;
 		current_distance1 = current_distance0;
@@ -292,6 +294,9 @@ void LineBuilder::build() {
 		if (texture_mode == Line2D::LINE_TEXTURE_TILE) {
 			uvx0 = current_distance0 / (width * tile_aspect);
 			uvx1 = current_distance1 / (width * tile_aspect);
+		} else if (texture_mode == Line2D::LINE_TEXTURE_STRETCH) {
+			uvx0 = current_distance0 / total_distance;
+			uvx1 = current_distance1 / total_distance;
 		}
 
 		strip_add_quad(pos_up1, pos_down1, color1, uvx1);
@@ -378,6 +383,8 @@ void LineBuilder::build() {
 	}
 	if (texture_mode == Line2D::LINE_TEXTURE_TILE) {
 		uvx1 = current_distance1 / (width * tile_aspect);
+	} else if (texture_mode == Line2D::LINE_TEXTURE_STRETCH) {
+		uvx1 = current_distance1 / total_distance;
 	}
 
 	strip_add_quad(pos_up1, pos_down1, color1, uvx1);
@@ -386,7 +393,7 @@ void LineBuilder::build() {
 	if (end_cap_mode == Line2D::LINE_CAP_ROUND) {
 		// Note: color is not used in case we don't interpolate...
 		Color color = _interpolate_color ? gradient->get_color(gradient->get_points_count() - 1) : Color(0, 0, 0);
-		new_arc(pos1, pos_up1 - pos1, Math_PI, color, Rect2(uvx1 - 0.5f, 0.f, 1.f, 1.f));
+		new_arc(pos1, pos_up1 - pos1, Math_PI, color, Rect2(uvx1 - 0.5f / tile_aspect, 0.f, 1.0f / tile_aspect, 1.f));
 	}
 }