Does draw_line() have a max width limit?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By JTJonny
:warning: Old Version Published before Godot 3 was released.

Draw_line() doesn’t seem to draw a line bigger than 5px. Is this a bug, build in limit, or am I doing something wrong?

:bust_in_silhouette: Reply From: mateusak

You’re doing something wrong. Let us see the code.

I set an array at the end of a function. Then used it as an input for drawCustonLine() (made this function for future stuff, but all it does right now is draw_line() with the array.

The thing is i can get the width to change, but only in the range of about 1 - 5.

(1) I set an array with with everything I need for draw_line()

updatePosDrawLine = [systemMapDict[myMapLocation][0], neighborPicked, 70.0, "8f1300ff"]
        	update() 
        

(2)I put that info into a function called drawCustomLine ( which basicly only has draw_line() in it

func drawCustomLine(vectorA, vectorB, lineSize, lineColor):
	draw_line(vectorA, vectorB, lineColor, lineSize)
  

        	NOTIFICATION_DRAW
        func _draw():
        	if !updatePosDrawLine == null:
        		drawCustomLine(updatePosDrawLine[0], updatePosDrawLine[1], updatePosDrawLine[2], updatePosDrawLine[3]) 
        	

    		

JTJonny | 2016-05-28 04:30

:bust_in_silhouette: Reply From: scu

I have the same results (though with a max of 7 instead of 5), but the issue seems to not be Godot-related. With OpenGL ES (Godot’s rendering API), there is a max line width dependent on implementation / graphics card, a limit which can be as small as 1 under the OpenGL ES standard.

https://www.khronos.org/opengles/sdk/docs/man/xhtml/glLineWidth.xml

If line width is important to what you’re making, you probably shouldn’t rely on that anyway, since it won’t be consistent from device to device. Maybe use a quad and rotate it instead.

This probably not the best/efficient way to replace draw_line(), but this is the function I created to replace it:

 func createPolyLine(size, posStart, posEnd, color, dump):
	# make base rectangle
	var polyLine = Polygon2D.new()
	polyLine.set_polygon([Vector2(0,-size/2),Vector2(0,size/2),Vector2(1,size/2),Vector2(1,-size/2)])
	var startScale = polyLine.get_transform()
	
	# scale poly rectangle
	var scaleX = posStart.distance_to(posEnd) - 1	
	polyLine.set_transform(Matrix32(startScale.x * scaleX, startScale.y,startScale.o))

	# set rotation
	var angle = posEnd - posStart 
	var rot = atan2(angle.y,angle.x)	
	polyLine.set_rot(-rot)
	
	# set poly pos
	polyLine.set_pos(Vector2(posStart.x, posStart.y))
	
	# set Color
	polyLine.set_color(color)
	
	# node dump 
	dump.add_child(polyLine)

JTJonny | 2016-06-09 05:30

Here’s how I’d do it on a gut reaction, but I don’t know which way is more efficient in Godot (tested and works)

func _draw():
	drawFatLine(Vector2(20,5), Vector2(1000, 300), Color(255, 0, 0), 10)
	
func drawFatLine(start, end, color, width):
	var angle = atan2((end - start).x, (end - start).y) * 180 / PI
	
	var offset = lengthDir(Vector2(0, width/2), angle)
	
	var points = Vector2Array()
	points.push_back(Vector2(start.x - offset.x, start.y - offset.y))
	points.push_back(Vector2(start.x + offset.x, start.y + offset.y))
	points.push_back(Vector2(end.x + offset.x, end.y + offset.y))
	points.push_back(Vector2(end.x - offset.x, end.y - offset.y))
	
	draw_colored_polygon(points, color)
	
func lengthDir(point, dir):
	return Vector2(point.x * cos(dir) - point.y * sin(dir), point.x * sin(dir) + point.y * cos(dir))

scu | 2016-06-09 06:30

If you use my snippet, it might be more efficient to change the function so that it just returns the points array to be stored in a variable, then you use that variable to draw the polygon as normal, that way all of that math doesn’t have to be done whenever it’s updated.

E.g. (not tested):

var linePoints = calcFatLine(Vector2(20,5), Vector2(1000, 300), 10)
	
func _draw():
	draw_colored_polygon(linePoints, Color(255, 0, 0))
	
func calcFatLine(start, end, width):
	var angle = atan2((end - start).x, (end - start).y) * 180 / PI
	
	var offset = lengthDir(Vector2(0, width/2), angle)
	
	var points = Vector2Array()
	points.push_back(Vector2(start.x - offset.x, start.y - offset.y))
	points.push_back(Vector2(start.x + offset.x, start.y + offset.y))
	points.push_back(Vector2(end.x + offset.x, end.y + offset.y))
	points.push_back(Vector2(end.x - offset.x, end.y - offset.y))
	
	return points
	
func lengthDir(point, dir):
	return Vector2(point.x * cos(dir) - point.y * sin(dir), point.x * sin(dir) + point.y * cos(dir))

scu | 2016-06-09 06:37

Thanks, that seems a lot better than mine.

JTJonny | 2016-06-09 06:58