【pyopenGL编程手册- 02/20】pyopenGL库简要说明

【pyopenGL编程手册- 01/20】pyopenGL安装和简要说明

参看:https://zhuanlan.zhihu.com/p/92910367

目录

一、写给程序员

在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

参考点:

相关推荐
肥猪猪爸17 分钟前
使用卡尔曼滤波器估计pybullet中的机器人位置
数据结构·人工智能·python·算法·机器人·卡尔曼滤波·pybullet
LZXCyrus1 小时前
【杂记】vLLM如何指定GPU单卡/多卡离线推理
人工智能·经验分享·python·深度学习·语言模型·llm·vllm
Enougme1 小时前
Appium常用的使用方法(一)
python·appium
懷淰メ1 小时前
PyQt飞机大战游戏(附下载地址)
开发语言·python·qt·游戏·pyqt·游戏开发·pyqt5
hummhumm1 小时前
第 22 章 - Go语言 测试与基准测试
java·大数据·开发语言·前端·python·golang·log4j
hummhumm1 小时前
第 28 章 - Go语言 Web 开发入门
java·开发语言·前端·python·sql·golang·前端框架
每天吃饭的羊2 小时前
python里的数据结构
开发语言·python
卡卡_R-Python2 小时前
UCI Heart Disease Data Set—— UCI 心脏病数据集介绍
python·plotly·django·virtualenv·pygame
饮长安千年月2 小时前
浅谈就如何解出Reverse-迷宫题之老鼠走迷宫的一些思考
python·网络安全·逆向·ctf
好看资源平台2 小时前
网络爬虫——爬虫项目案例
爬虫·python