如何在没有 glBegin 的情况下在 OpenGL 中画一条线

How to draw a line in OpenGL without glBegin

我查看了 How to draw line in OpenGl? 中的代码,但 glBegin 和 glEnd 被标记为已弃用。你应该如何在当前的 OpenGL 版本中画一条线?我找到了谈论使用 VBO 的文章,以及谈论 glVertexPointerglColorPointer 的文章,但是有 这么多 框架围绕着使用着色器程序编译来构建这些方法和链接和顶点属性位旋转。有没有一种不使用已弃用函数的简单方法来画线?

我试过了没有成功:

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);

我不知道我是否在使用 DrawArrays 的正确范围内,或者该方法是否需要一大堆框架来配合它,所以我 不一定 想让 这个 代码工作。我只是想找到最简单的代码来绘制适合在现代 OpenGL 中使用的线条。

这是我可以创建的最简单的画线程序(使用 OpenTK)。

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();
      }
   }
}