- Home /
Why does GL not render a line when I attach all my vertices in one go?
I want to draw several lines that are related to one game object. So I can't use LineRenderer since you can only have one of it attached to an object. I opted to use GL instead. I have working code, but I don't understand why a particular modification breaks it?
This code works and draws my line as desired. However, it seems wasteful to begin and end for every pair in my line, which can be thousands of points long.
// Loop through each point and connect it to the previous one
for (int i = 1; i < line.points.Length; i++)
{
Vector3 start = line.points[i - 1];
Vector3 end = line.points[i];
GL.Begin(GL.LINES);
line.lineMat.SetPass(0);
GL.Color(line.lineMat.color);
GL.Vertex3(start.x, start.y, start.z);
GL.Vertex3(end.x, end.y, end.z);
GL.End();
}
So I changed to this. Which doubled my framerate in my simple scene from ~600 to ~1200 fps. So I got the improvement that I was expecting. However, this made my lines dashed.
GL.Begin(GL.LINES);
line.lineMat.SetPass(0);
GL.Color(line.lineMat.color);
foreach (Vector3 point in line.points)
{
GL.Vertex3(point.x, point.y, point.z);
}
GL.End();
I did some googling and I found this nearly decade old post that showed a fix. https://answers.unity.com/questions/155803/gllines-dashed-stippled-why.html
However, when I make that modification I get no line at all! No modifications I make fix this. Below is the final attempt at this. It still does not render anything. Can anyone point me to why that might be?
GL.PushMatrix();
GL.LoadOrtho();
line.lineMat.SetPass(0);
GL.Color(line.lineMat.color);
GL.Begin(GL.LINES);
int i = 0;
foreach (Vector3 point in line.points)
{
GL.Vertex(point);
if (i > 0 && i < line.points.Length - 1)
{
GL.Vertex(point);
}
i++;
}
GL.End();
GL.PopMatrix();
Answer by Bunny83 · Jun 21, 2020 at 04:12 AM
The drawing mode "LINES" will draw several line segments. Each segment requires TWO vertices. However you only emit all your points once. So the first and second point will form a line and the third and forth will form another line. However you would have a gap every second segment that way. You should do something like this:
GL.Begin(GL.LINES);
line.lineMat.SetPass(0);
GL.Color(line.lineMat.color);
for (int i = 1; i < line.points.Length; i++)
{
Vector3 start = line.points[i - 1];
Vector3 end = line.points[i];
GL.Vertex3(start.x, start.y, start.z);
GL.Vertex3(end.x, end.y, end.z);
}
GL.End();
This is your original code just with the begin and end lines outside the loop. However since Unity also supports a line strip you could use:
GL.Begin(GL.LINES);
line.lineMat.SetPass(0);
GL.Color(line.lineMat.color);
foreach(var p in line.points)
{
GL.Vertex(p);
}
GL.End();
Note that GL:LoadOrtho will change the projection to a 0 to 1 range for x and y and -1 to 100 on z. It's not clear in which space you want to specify your points. Keep in mind that drawing with GL directly draws to the screen. There is no camera involved. You have to setup all wanted transformations yourself, including the projection.
Your answer
Follow this Question
Related Questions
Texture lookup in Surface Shader in pixel space 0 Answers
GL.LINES renders in a single quadrant of the screen 0 Answers
OpenGL ES 1/2 Jagged edges issue 1 Answer
general question regarding flexibility of unity3d rendering 0 Answers
OpenGL ES 3 VR 1 Answer