1

I looked at the code in How to draw line in OpenGl? but glBegin and glEnd are marked as deprecated. How are you supposed to draw a line in the current OpenGL version? I found articles that talk about using VBO, and articles that talk about glVertexPointer and glColorPointer, but there's so much framework around building these methods with the shader program compiling and linking and the vertex attribute bit twiddling. Isn't there a simple way to draw a line without using deprecated functions?

I tried this without success:

OpenTK.Vector2[] linepts = { new Vector2(0, 0), new Vector2(1, 1), new Vector2(50, 0), new Vector2(0, 50) };
int h = GL.GenBuffer();
GL.BindBuffer(BufferTarget.ArrayBuffer, h);
GL.BufferData<Vector2>(BufferTarget.ArrayBuffer, 16, linepts, BufferUsageHint.StreamDraw);
GL.DrawArrays(PrimitiveType.LineStrip, 0, 4);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
GL.DeleteBuffer(h);

I don't know if I'm even in the right ballpark using DrawArrays or if that method requires a whole mess of framework to go along with it, so I don't necessarily want to make this code work. I just want to find the simplest code for drawing a line that's advisable to use in modern OpenGL.

Community
  • 1
  • 1
BlueMonkMN
  • 25,079
  • 9
  • 80
  • 146
  • 4
    No, there is no simple way. Compile and link a shader program, create a VAO, VBO, set them up, and then call `DrawArrays()`. – Nico Schertler Dec 07 '16 at 01:01
  • Why not check opengl's official page? – Lei Yang Dec 07 '16 at 01:19
  • Nope, that's definitely not the correct way to do this. You've fed OpenGL vertex data, but you haven't hooked that data up to vertex attributes. At minimum you also need a `GL.VertexPointer` call. If you want to avoid the fixed-function pipeline and go purely with shaders, then you need to establish attribute locations. That's your job in GL 3.0, there aren't pre-defined locations for this stuff anymore. – Andon M. Coleman Dec 07 '16 at 20:13

1 Answers1

2

This is the simplest program (using OpenTK) that I can create to draw a line.

using System;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;

namespace OpenGLLine
{
   static class Program
   {
      static OpenTK.GameWindow gw;
      static int shaderProgram;
      static int vertexInfo;
      static int lineVertexBuffer;
      static int vertexCount;

      [STAThread]
      static void Main()
      {
         gw = new OpenTK.GameWindow(800, 600, OpenTK.Graphics.GraphicsMode.Default, "Game", OpenTK.GameWindowFlags.FixedWindow);
         Initialize();
         gw.RenderFrame += Gw_RenderFrame;
         gw.Closed += Gw_Closed;
         gw.Run(60);
      }

      private static void Gw_Closed(object sender, EventArgs e)
      {
         CleanUp();
      }

      private static void Initialize()
      {
         int vshader = GL.CreateShader(ShaderType.VertexShader);
         GL.ShaderSource(vshader, @"#version 130
            in vec2 vPosition;
            void main()
            {
               gl_Position = vec4(vPosition, -1.0, 1.0);
            }");
         GL.CompileShader(vshader);
         int fshader = GL.CreateShader(ShaderType.FragmentShader);
         GL.ShaderSource(fshader, @"#version 130
            out vec4 fragColor;
            void main()
            {
               fragColor = vec4(1.0, 1.0, 1.0, 1.0);
            }");
         GL.CompileShader(fshader);
         shaderProgram = GL.CreateProgram();
         GL.AttachShader(shaderProgram, vshader);
         GL.AttachShader(shaderProgram, fshader);
         GL.LinkProgram(shaderProgram);
         GL.DetachShader(shaderProgram, vshader);
         GL.DetachShader(shaderProgram, fshader);
         GL.UseProgram(shaderProgram);
         lineVertexBuffer = GL.GenBuffer();
         Vector2[] lineVertices = { new Vector2(0, 0), new Vector2(.5f, .5f) };
         vertexCount = lineVertices.Length;
         GL.BindBuffer(BufferTarget.ArrayBuffer, lineVertexBuffer);
         GL.BufferData(BufferTarget.ArrayBuffer, System.Runtime.InteropServices.Marshal.SizeOf(lineVertices[0]) * vertexCount,
            lineVertices, BufferUsageHint.StreamDraw);
         vertexInfo = GL.GenVertexArray();
         GL.BindVertexArray(vertexInfo);
         int locVPosition = GL.GetAttribLocation(shaderProgram, "vPosition");
         GL.EnableVertexAttribArray(locVPosition);
         GL.VertexAttribPointer(locVPosition, 2, VertexAttribPointerType.Float, false,
            System.Runtime.InteropServices.Marshal.SizeOf(lineVertices[0]), 0);
         GL.BindVertexArray(0);
         GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
         GL.UseProgram(0);
      }

      static void CleanUp()
      {

         GL.DeleteProgram(shaderProgram);
         GL.DeleteVertexArray(vertexInfo);
         GL.DeleteBuffer(lineVertexBuffer);
      }

      private static void Gw_RenderFrame(object sender, OpenTK.FrameEventArgs e)
      {
         GL.ClearColor(Color4.Black);
         GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
         GL.BindBuffer(BufferTarget.ArrayBuffer, lineVertexBuffer);
         GL.UseProgram(shaderProgram);
         GL.BindVertexArray(vertexInfo);
         GL.DrawArrays(PrimitiveType.LineStrip, 0, vertexCount);
         GL.BindVertexArray(0);
         GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
         GL.UseProgram(0);
         gw.SwapBuffers();
      }
   }
}
BlueMonkMN
  • 25,079
  • 9
  • 80
  • 146