2014-10-21 3 views
0

Я пытаюсь нарисовать большой граф (~ 3 000 000 вершин, ~ 5 000 000 ребер) с помощью OpenTK.Использование VBO/IBO для рисования большого графика

Однако я не могу заставить его работать.

Я создание VBO, содержащее положение всех вершин, как так

// build the coords list 
float[] coords = new float[vertices.Length * 3]; 
Dictionary<int, int> vertexIndexMap = new Dictioanry<int, int>(); 
int count = 0, i = 0; 
foreach (Vertex v in vertices) { 
    vertexIndexMap[v.Id] = i++; 
    coords[count++] = v.x; 
    coords[count++] = v.y; 
    coords[count++] = v.z; 
} 

// build the index list 
int[] indices = new int[edges.Length * 2]; 
count = 0; 
foreach (Edge e in edges) { 
    indices[count++] = vertexIndexMap[e.First.Id]; 
    indices[count++] = vertexIndexMap[e.Second.Id]; 
} 

// bind the buffers 
int[] bufferPtrs = new int[2]; 
GL.GenBuffers(2, bufferPtrs); 

GL.EnableClientState(ArrayCap.VertexArray); 
GL.EnableClientState(ArrayCap.IndexArray); 

// buffer the vertex data 
GL.BindBuffer(BufferTarget.ArrayBuffer, bufferPtrs[0]); 
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(coords.Length * sizeof(float)), coords, BufferUsageHint.StaticDraw); 
GL.VertexPointer(3, VertexPointerType.Float, 0, IntPtr.Zero); // tell opengl we have a closely packed vertex array 
GL.BindBuffer(BufferTarget.ArrayBuffer, 0); 

// buffer the index data 
GL.BindBuffer(BufferTarget.ElementArrayBuffer, bufferPtrs[1]); 
GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indices.Length * sizeof(int)), indices, BufferUsageHint.StaticDraw); 
GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); 

И я пытаюсь нарисовать буфера, как так:

// draw the vertices 
GL.BindBuffer(BufferTarget.ArrayBuffer, bufferPtrs[0]); 
GL.Color3(Color.Blue); 
GL.DrawArrays(PrimitiveType.Points, 0, coords.Length); 

// draw the edges 
GL.BindBuffer(BufferTarget.ElementArrayBuffer, bufferPtrs[1]); 
GL.Color3(Color.Red); 
GL.DrawElements(PrimitiveType.Lines, indices.Length, DrawElementsType.UnsignedInt, bufferPtrs[1]); 

Когда я запускаю это, все вершины как и ожидалось во всех их правильных местоположениях,
Однако примерно половина краев нарисована, присоединяя вершину к началу координат.

Чтобы проверить работоспособность, я попытался нарисовать края блоком Begin/End, и все они правильно нарисованы.

Не могли бы вы указать, как я злоупотребляю VBOs?

ответ

3

Последний аргумент к вашему DrawElements() вызова неправильно:

GL.DrawElements(PrimitiveType.Lines, indices.Length, DrawElementsType.UnsignedInt, 
       bufferPtrs[1]); 

Без элемента массива буфера обвалования, последний аргумент DrawElements() является указателем индексов. Если буфер массива элементов привязан (что имеет место в вашем коде), последний аргумент является смещением в буфере. Для того, чтобы использовать весь буфер, смещение 0:

GL.DrawElements(PrimitiveType.Lines, indices.Length, DrawElementsType.UnsignedInt, 0); 

Возможно, вы также хотите удалить этот вызов:

GL.EnableClientState(ArrayCap.IndexArray); 

Это не позволяет индексов вершин, но и для цветовых индексов. Это будет режим цветового индекса, который является очень устаревшей функцией.

+0

Вау, это было все, что было не так. Я пропустил это в доко! спасибо кучи. И спасибо за указание на IndexArray. –

Смежные вопросы