我试图使用OpenTK绘制一个大图(~3,000,000个顶点,~3,000,000个边)。
但我似乎无法让它发挥作用。
我创建一个包含所有顶点位置的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块绘制边缘,并且它们都正确绘制。
有人可以指出我是如何滥用维也纳国际组织的吗?
答案 0 :(得分: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);
这不是用于启用顶点索引,而是用于颜色索引。这将是颜色索引模式,这是一个非常过时的功能。