在 OpenTK 上绘制 10 个数据集

Plotting 10 data sets on OpenTK

我有10组数据保存在数组中。例如 A1 = [1,2 ,3], A2 = [5,6,7]...等。我正在使用 OpenTk GameWindow 来绘制它,因为我有一个大数据集(每个数据集超过 1000 万)。现在我知道如何绘制 1 个数据集如下:

  public GraphWIndow (Data Dataset[0]) : base(800, 600, default, "Data Analyzer", GameWindowFlags.Default, default,4,0, default)
        {
            test= EditVertices(Dataset[0]);
        }

        private float[] EditVertices(List<float> list)
        {
            float[] list2d = new float[2*list.Count()];
            for(int i =0; i<list.Count(); i++)
            {
                list2d[2*i]=-1+ i*(((float)2/(float)list.Count()));
                list2d[2*i +1] =((float)(list[i]-list.Min())/(float)(list.Max()-list.Min()));
            }
            return list2d;
        }

        protected override void OnLoad(EventArgs e)
        {
            CursorVisible = true;
            shader = new Shader("shader.vert", "shader.frag");
            shader.Use();
            VertexArrayObject = GL.GenVertexArray();
            VertexBufferObject = GL.GenBuffer(); 
            GL.BindVertexArray(VertexArrayObject);
            GL.BindBuffer(BufferTarget.ArrayBuffer, VertexBufferObject);
            GL.BufferData(BufferTarget.ArrayBuffer, test.Count()*sizeof(float), test, BufferUsageHint.StaticDraw);
            var vertexLocation = shader.GetAttribLocation("aPosition");
            GL.EnableVertexAttribArray(vertexLocation);
            GL.VertexAttribPointer( vertexLocation, 2, VertexAttribPointerType.Float, false, 2*sizeof(float), 0);
            GL.EnableVertexAttribArray(0);
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
            GL.BindVertexArray(0);
            base.OnLoad(e);
        }

 protected override void OnRenderFrame(FrameEventArgs e)
        {
            GL.ClearColor(Color4.DarkBlue);
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
            GL.BindVertexArray(VertexArrayObject);
            GL.DrawArrays(PrimitiveType.LineStrip, 0, test.Count());
            GL.PointSize(10);
            SwapBuffers();
            base.OnRenderFrame(e);
        }

shader.vert

#version 400 core
in vec2 aPosition;

void main()
{
    gl_Position = vec4(aPosition, 0.0f, 1.0f);
}

我有点知道我将如何绘制这 10 组。我将为每个数据集添加一个偏移量并将它们组合在一个数组(测试数组)中,然后将其传递给 shader.vert。问题是我不知道如何处理 x 坐标。我不想继续将它添加到测试数组中,这在 EditVertices 函数中显示,因为它会显着增加它的大小,尤其是当我处理大量数据时。有没有一种方法可以让我以某种方式分别传递 x 坐标,但同时将它与所有数据集相关联?因为它们都共享相同的 x 坐标但不同的 Y 值。我希望我的问题很清楚。

Is there a way where I can pass x coordinates separately somehow but at the same time relate it to all data sets?

使用 2 个 float 类型的属性,一个用于 x 坐标,另一个用于 y 坐标:

#version 400 core
in float aPositionX;
in float aPositionY;

void main()
{
    gl_Position = vec4(aPositionX, aPositionY, 0.0, 1.0);
}
var vertexLocationX = shader.GetAttribLocation("aPositionX");
var vertexLocationY = shader.GetAttribLocation("aPositionY");

现在您可以对所有数据集使用相同的 X 坐标。为 X 坐标创建 1 个顶点属性数据数组:

float[] vertexX = new float[2*list.Count()];
for(int i =0; i < list.Count(); i++)
    vertexX[i] = (float)(-1 + i * 2/list.Count());

必须为每个数据集单独创建 Y 坐标数组

float[] vertexY = new float[2*list.Count()];
for(int i =0; i < list.Count(); i++)
    vertexY[i] = (float)((vertexY[i]-list.Min() / (list.Max()-list.Min());

您必须创建 2 个单独的 Vertex Buffer Objects:

VertexBufferObjectX = GL.GenBuffer();
GL.BindBuffer(BufferTarget.ArrayBuffer, VertexBufferObjectX);
GL.BufferData(BufferTarget.ArrayBuffer, vertexX.Count()*sizeof(float), vertexX, BufferUsageHint.StaticDraw);

VertexBufferObjectY = GL.GenBuffer();
GL.BindBuffer(BufferTarget.ArrayBuffer, VertexBufferObjectY);
GL.BufferData(BufferTarget.ArrayBuffer, vertexY.Count()*sizeof(float), vertexY, BufferUsageHint.StaticDraw); 

并且您必须调整 Vertex Array Object 的规范:

VertexArrayObject = GL.GenVertexArray();            
GL.BindVertexArray(VertexArrayObject);

GL.BindBuffer(BufferTarget.ArrayBuffer, VertexBufferObjectX);
GL.VertexAttribPointer(vertexLocationX, 1, VertexAttribPointerType.Float, false, 0, 0);
GL.BindBuffer(BufferTarget.ArrayBuffer, VertexBufferObjectY);
GL.VertexAttribPointer(vertexLocationY, 1, VertexAttribPointerType.Float, false, 0, 0);

GL.EnableVertexAttribArray(vertexLocationX);
GL.EnableVertexAttribArray(vertexLocationY);

GL.BindVertexArray(0);