【pyopenGL编程手册- 01/20】pyopenGL安装和简要说明
参看:https://zhuanlan.zhihu.com/p/92910367
目录
- 一、写给程序员
- [二 数组处理](#二 数组处理)
-
- [2.1 能处理的数组](#2.1 能处理的数组)
- [2.2 数组类型的指定函数](#2.2 数组类型的指定函数)
- 三、图像例程
- 四、扩展和条件功能
- 五、选择和反馈缓冲器
一、写给程序员
在pyopenGL的使用中,传递数据的数组、buff是需要有约定的,数据的size和数据的type以及读取的stride等需要给定。除此还有图像数据、数据反馈buff等需要操作和约定。本文仅仅记录这些约定,供编程时查阅。
二 数组处理
2.1 能处理的数组
PyOpenGL 3.x 支持多种不同平台的数组兼容、和数据类型,安装后默认支持的插件包括:
支持 | 数据类 |
---|---|
numpy | 数组 |
Python | 字符串(字节字符串) |
numbers | (单值数组的指针) |
ctypes | 数组 |
ctypes | 参数 |
ctypes | 指针 |
lists/tuples | |
vertex buffer objects | 顶点缓冲区对象 |
当 PyOpenGL 3.x 入口点需要"数组"数据类型(或 void* 数据类型)时,它将使用 PyOpenGL FormatHandler 插件 (OpenGL.arrays.formathandler) 来决定如何将数组转换为格式与低级 OpenGL API 兼容。
某些格式类型可能允许用作数组类型,但实际上不包含数据的兼容副本。 Python 列表、元组和数字都需要创建临时变量来保存其数据。因此,您通常不应将它们用于性能关键型操作。同样,如果传递具有不兼容数据类型的 numpy 数组,包装器可能必须复制数据才能将其传递到 C 级函数。对于 numpy 数组,其行为速度足够快,您可能没有意识到,但可能会对您的性能产生负面影响,您可以通过在导入任何 OpenGL 模块之前在 OpenGL 包中设置标志来防止此行为:
python
import OpenGL
OpenGL.ERROR_ON_COPY = True
from OpenGL.GL import *
-
如果 numpy 格式处理程序发现自己将数组复制到另一种数据类型,这将导致 numpy 格式处理程序引发错误。
-
请记住,对于 OpenGL 3.1,将要求所有非索引数组都作为顶点缓冲区对象(vertex buffer objects)进行管理。
2.2 数组类型的指定函数
数组这里看成buffer,是python语言定义的,因为要传递到openGL中,进而在GPU上显示数据,因此,buffer的指针,以及数据的长度(类型)需要传递过去,因此就有了类似于" glVertexPointer"的函数。这些函数大多是单向的这是一个效率问题,从显示器返回数据是很费力气的。
我们知道,函数的命名规律是:
bash
<库前缀><根命令><可选的参数个数><可选的参数类型>
每个设置数组指针的调用(例如 glVertexPointer)可能有许多变体。首先会有一个与规范相同的功能。
对于指针参数,应该传递一个字符串。另请注意,使用了步幅值。
接下来将有一组名为:
python
glXPointer{ub|b|us|s|ui|i|f|d}
这些通常将多维值数组作为单个参数。类型参数由函数的后缀控制(ub 是无符号字节,b 是字节,s是short整型,i是整型,f 是浮点型,d 是双精度型等)。大多数其他参数都源自数组的维度。
所以对于 glColorPointer 我们有几种类同于泛型的函数:
bash
glColorPointer(size, type, stride, pointer) -> None
glColorPointerub(pointer[][]) -> None
glColorPointerb(pointer[][]) -> None
glColorPointerus(pointer[][]) -> None
glColorPointers(pointer[][]) -> None
glColorPointerui(pointer[][]) -> None
glColorPointeri(pointer[][]) -> None
glColorPointerf(pointer[][]) -> None
glColorPointerd(pointer[][]) -> None
同样的修饰策略也用于其他数组函数。但glXPointer函数不可。
例如,glDrawElements 具有 Python 绑定:
python
glDrawElements(mode, count, type, indices) -> None
其中 indices 应为字符串。还有 装饰装订:
python
glDrawElementsub(mode, indices[]) -> None
glDrawElementsus(mode, indices[]) -> None
glDrawElementsui(mode, indices[]) -> None
其中"索引"现在是一维数组。
调用 glColorPointer、glVertexPointer 等时。Python 需要 分配内存以存储 OpenGL 所需的值。这个记忆是 引用计数并考虑函数调用,例如 glPushClientAttrib 和 glPopClientAttrib。强制此内存释放,只需要调用 glColorPointerub(None)。
目前,glPushClientAttrib 将始终将 GL_CLIENT_VERTEX_ARRAY_BIT标志为 glPopClientAttrib 无法 知道flag已经设置,需要知道flag的状态是否递减指针将锁定在分配的内存上。
这种情况将来可能会改变。也就是说,周围阵列的使用 glPushClientAttrib/glPopClientAttrib 是强制发布的好方法 ,但请确保对 glXPointer 的所有调用, 等,则在 ClientAttrib 块中,如果您选择使用此方案。
请注意,由于所有内存分配都是 automatic 不需要 glGetPointerv 函数,因此将其排除在外。
请注意,函数 glInterleavedArrays 也是 存在,但它没有其他人所具有的变体(即,没有 glInterleavedArraysf)。glInterleavedArrays 是非正式的 已弃用很长时间,并从 OpenGL 开始正式弃用 3.x
请注意,为了获得性能,您可能希望使用 数组处理函数的"原始"版本,因为这些函数通常具有较少的函数 应用了比"原始"版本更强的处理。
请注意,由于所有内存分配都是自动的,因此不需要 glGetPointerv 函数,因此将其排除在外。
三、图像例程
glDrawPixels 和其他图像/纹理函数有很多 与数组函数相同的装饰方案。对于 glDrawPixels,有 标准函数,它需要一个字符串作为像素数据:
python
glDrawPixels(width, height, format, type, pixels) -> None
此函数将遵循 glPixelStore{i|f} 设置的参数。
还有一系列多维的变体 数组作为数据源,并自动设置 glPixelStore{i|f}。为 例:
python
glDrawPixelsub(format, pixels) -> None
请注意,宽度和高度是从像素数据推断出来的,并且 类型为 GLubyte。
PyOpenGL的 使用成像 API 时设置"正常"像素传输模式,因为几乎 例如,所有 Python 图像感知模块/扩展都严格假设 打包数据结构,并可能导致访问错误 在标准 OpenGL 模式下运行。
四、扩展和条件功能
PyOpenGL 支持大多数 OpenGL 扩展。扩展是 可作为"普通"函数指针使用,通过导入构造的 扩展的包名称,例如:
python
from OpenGL.GL.ARB.vertex_buffer_object import *
buffer = glGenBuffersARB(1)
那里 不需要调用初始化函数等 扩展模块。如果您愿意,可以调用"init"函数 用于检索布尔值的扩展,指示本地 Machine 支持给定的扩展,如下所示:
python
if glInitVertexBufferObjectARB():
...
但是,测试布尔真值通常更清楚 您希望使用的入口点:
python
if (glGenBuffersARB):
buffers = glGenBuffersARB( 1 )
那里 通常是实现相同 API 的多个入口点,用于 您希望使用任何可用的实现 (可能有一些偏好)。OpenGL.extensions 模块 提供了一个简单的机制来支持这一点:
python
from OpenGL.extensions import alternate
glCreateProgram = alternate( 'glCreateProgram', glCreateProgram, glCreateProgramObjectARB)
glCreateProgram = alternate( glCreateProgram, glCreateProgramObjectARB)
如果 第一个元素是一个字符串,它将用作 alternate 对象,否则名称取自第一个参数。
五、选择和反馈缓冲器
请注意,选择缓冲器和反馈缓冲器都是 在 OpenGL 3.x 中已弃用。你应该更换 具有"唯一颜色"选择呈现的选择缓冲区用法 或数学生成的选择操作。
通常,在 OpenGL 中,要使用选择缓冲区,可以执行 以后:
python
GLuint buffer[SIZE];
glSelectBuffer(SIZE, buffer);
glRenderMode(GL_SELECT);
/* draw some stuff */
GLint count = glRenderMode(GL_RENDER);
/* parse the selection buffer */
在 Python 中,这是这样完成的:
python
glSelectBuffer(SIZE) # allocate a selection buffer of SIZE elements
glRenderMode(GL_SELECT)
buffer = glRenderMode(GL_RENDER)
for hit_record in buffer:
min_depth, max_depth, names = hit_record
# do something with the record
# draw some stuff
反馈缓冲区的使用方式相同,只是每个项目 缓冲区是元组(标记、值),其中值是直通 标记或顶点列表。
请注意,如果 glRenderMode 返回缓冲区,则它 还会重置 OpenGL 的指针,用于相应的 缓冲区。这意味着 glRenderMode 返回的缓冲区为 与将来对 glRenderMode 的调用无关,即它不会 被任何此类未来调用覆盖。这使得返回的缓冲区 有点线程安全。这也意味着每次调用 glRenderMode(GL_SELECT |GL_FEEDBACK) 需要在前面 由 首先调用 glSelectBuffer 或 glFeedbackBuffer,即 以下代码将不起作用:
python
### THIS DOESN'T WORK!!!
glSelectBuffer(SIZE) # allocate a selection buffer of SIZE elements
glRenderMode(GL_SELECT)
# draw some stuff
buffer = glRenderMode(GL_RENDER)
# do another selection
glRenderMode(GL_SELECT)
# draw some stuff
buffer = glRenderMode(GL_RENDER)
相反,正确代码是:
python
glSelectBuffer(SIZE) # allocate a selection buffer of SIZE elements
glRenderMode(GL_SELECT)
# draw some stuff
buffer = glRenderMode(GL_RENDER)
# do another selection
glSelectBuffer(SIZE) allocate a new selection buffer
glRenderMode(GL_SELECT)
# draw some stuff
buffer = glRenderMode(GL_RENDER)
函数别名
PyOpenGL 历史上为函数提供了许多别名。为了向后兼容,此处继续提供这些别名:
- glGetBooleanv aliases
glGetBoolean - glGetDoublev aliases
glGetDouble - glGetIntegerv aliases
glGetInteger - glColord aliases
glColor
glColor3
glColor4 - glEvalCoordd aliases
glEvalCoord
glEvalCoord1
glEvalCoord2 - glFogfv aliases
glFog - glIndexd aliases
glIndex - glLightfv aliases
glLight - glLightModelfv aliases
glLightModel - glMaterialfv aliases
glMaterial - glNormald aliases
glNormal
glNormal3
glNormal4 - glRasterPosd aliases
glRasterPos
glRasterPos2
glRasterPos3
glRasterPos4 - glRotated aliases
glRotate - glScaled aliases
glScale - glTexCoordd aliases
glTexCoord
glTexCoord1
glTexCoord2
glTexCoord3
glTexCoord4 - glTexGendv aliases
glTexGen - glTexParameterfv aliases
glTexParameter - glTranslated aliases
glTranslate - glVertexd aliases
glVertex
参考点: