Создание 10 наборов данных на OpenTK - PullRequest
1 голос
/ 11 апреля 2020

У меня есть 10 наборов данных, сохраненных в массивах. Например, A1 = [1,2,3], A2 = [5,6,7] ... et c. Я использую OpenTk GameWindow для построения графика, так как у меня большой набор данных (10 миллионов + на набор данных). Сейчас я знаю, как построить 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. Дело в том, что я не знаю, что делать с координатами х. Я не хочу продолжать добавлять его в тестовый массив, который показан в функции EditVertices, так как это значительно увеличит его размер, особенно если я имею дело с огромным размером данных. Есть ли способ, где я могу как-то передать координаты x отдельно, но в то же время связать его со всеми наборами данных? так как все они имеют одинаковые координаты х, но разные значения Y. Я надеюсь, что мой вопрос ясен.

1 Ответ

1 голос
/ 11 апреля 2020

Есть ли способ, где я могу как-то отдельно передать координаты x, но в то же время связать его со всеми наборами данных?

Использовать 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 для всех наборов данных. Создайте 1 массив данных атрибута вершины для координат X:

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 :

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