python - 具有多个基元的显示列表的 VBO 等价物?

标签 python opengl vbo

我有一个简单的 OpenGL 应用程序,我在其中绘制海岸线数据。数据是一长串多边形(约 41000 个),其中每个多边形都是 (x,y) 点的列表。多边形的长度各不相同(因为有些海岸线比其他海岸线长)。 现在,使用显示列表绘制起来很简单 - 这是 Python 代码,但我相信你明白了要点:

self.coastlines_dl = GL.glGenLists(1)
GL.glNewList(self.coastlines_dl, GL.GL_COMPILE)
for poly in coastline_polys:
    GL.glBegin(GL.GL_LINE_STRIP)
        for point in poly:
            GL.glVertex3f(point[0], point[1], 0.0)
    GL.glEnd()
GL.glEndList()

然后在渲染循环中:

GL.glCallList(self.coastlines_dl)

这表现得很好。

我的问题是:如何使用 VBO 进行等效操作?我最初的方法是为每个多边形创建一个 VBO,然后在渲染循环中绘制每个 VBO,例如:

for v in self.vbos:
    v.bind()
    GL.glEnableClientState(GL.GL_VERTEX_ARRAY)
    GL.glVertexPointerf(v)
    GL.glDrawArrays(GL.GL_LINE_STRIP, 0, v.data.shape[0])
    GL.glDisableClientState(GL.GL_VERTEX_ARRAY)
    v.unbind()

这是有效的,因为它绘制了数据,但帧速率令人震惊,这并不奇怪,因为我每帧绑定(bind)和绘制 41000 多次。

那么我可以将我所有的多边形放入一个大的 VBO 中,只做一个绑定(bind)和一个 glDrawArrays 吗?我不明白的是 glDrawArrays 如何知道每个多边形中有多少个点,因为每个多边形都不同?

抱歉,如果这是非常微不足道的,但我一直在读到,我可以用显示列表做的任何事情都可以用 VBO 来完成,但我找不到一个例子来说明我需要做什么。


编辑 1 - 鉴于 VBO 性能缓慢,这是我的平台详细信息

Windows 7 64 位
i5-2430M
GPU 仅板载 Intel HD Graphics 3000
4GB 内存

应用程序是 Python OpenGL。 Python 版本为 2.7.9 64 位,带有 PyOpenGL 3.1.0 amd64,并通过 PySide 1.2.2 amd64 使用 QT QGLWidget。

这是来自 gDEBugger 的转储:

General
-------
OpenGL Version           3.1
Shading Language Version 1.40  - Intel Build 8.15.10.2345
Is Backward-Compatible Yes
Is Forward-Compatible No
Is Debug Context Yes
Renderer Vendor Intel
Renderer Name Intel(R) HD Graphics Family
Renderer Version 3.1.0 - Build 8.15.10.2345
Renderer Type Installable client
Marked for Deletion      No
OpenGL Sharing Contexts  None

Pixel Format Information
------------------------
Pixel Format ID          9
Hardware Acceleration    Full
Double-Buffered          Yes
Stereographic            No
Native Rendering         No

Channel                  Bits
Red                      8
Green                    8
Blue                     8
Alpha                    8
Depth                    24
Stencil                  8
Accumulation             64

最佳答案

您可能不应该为每个多边形创建一个 VBO。这将非常缓慢,并且不是驱动程序在您的第一次实现中将在幕后做的事情。你应该有一个 VBO(当你优化时可能是几个分块的 VBO)和你需要的所有顶点数据。然后索引到 VBO 中以绘制每个图元。所以你的 glDrawArrays 将开始使用第二个参数'first'。

也没有必要在循环中每次都启用和禁用ClientState,这样做可能会导致驱动程序执行不必要的验证

请原谅我缺乏 python-gl 知识,但它看起来像这样。

v.bind()
GL.glEnableClientState(GL.GL_VERTEX_ARRAY)
GL.glVertexPointerf(v)
for v in self.vbos:
    GL.glDrawArrays(GL.GL_LINE_STRIP, vbo_offset_goes_here, v.data.shape[0])
GL.glDisableClientState(GL.GL_VERTEX_ARRAY)
v.unbind()

这仍然不是最理想的,因为它需要大量的绘制调用,而绘制调用的成本可能相当高。但这应该是您示例的简单增量改进。之后,您可以尝试 glMultiDrawArrays,因为您只有一个原始类型,所以它应该能够让您完全删除循环。

关于python - 具有多个基元的显示列表的 VBO 等价物?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27607340/

相关文章:

opengl - JOGL VBO,glDrawElements 的替代品

c++ - Qt Opengl VBO 数据损坏

python - 如何在Pygame中画一条连续的线?

python - 单元测试 Python : how to modify a source code by adding comments and decorators

open-source - 在哪里可以下载“OpenGL”的源代码?

c++ - 在 openGL 中,我如何从内存中编辑特定的顶点缓冲区属性

c++ - 在 OpenGL 中渲染 .obj 文件最终会丢失顶点

java - LWJGL VBO 在 Radeon HD 6670 上生成看似随机的顶点?

python - iOS 6 : libpython2. 7.a初始化导入错误

Python多线程和HTTP请求