pyopenglglreadpixels在最终指针创建后导致ctypes参数错误

2024-05-03 01:23:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我对pyopengl和它的导入有一个奇怪的问题,下面是一个从一个更大的程序中剪切出来的小测试程序,但是它足以说明这个问题。您需要安装PyOpenGL,如果您按原样运行它,它会显示一个空白窗口,如果您单击并拖动它,它会打印出一些0。如果您取消注释下面的HANDLE.final = True行,那么它将停止工作,请参阅下面的回溯。你知道吗

from OpenGL.GL import *
from OpenGL.GLUT import *
from ctypes import POINTER
import sys

HANDLE = POINTER(None)
#HANDLE.final = True

def display():
    glutSwapBuffers()

glutInit(sys.argv)
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)
glutInitWindowSize(400,400)
glutCreateWindow("GLUT Window")

glutDisplayFunc(display)

def readPx(x,y):
    data_all = glReadPixels(x, y, 1, 1, GL_RGB, GL_BYTE)
    print data_all

glutMotionFunc(readPx)

glutMainLoop()

在该行未注释的情况下,它执行以下操作:

Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\OpenGL\GLUT\special.py", line 130, in safeCall
    return function( *args, **named )
  File "C:\Users\Robin\dev\ogl_bug\ogl_bug.py", line 19, in readPx
    data_all = glReadPixels(x, y, 1, 1, GL_RGB, GL_BYTE)
  File "C:\Python27\lib\site-packages\OpenGL\GL\images.py", line 371, in glReadPixels
    imageData
  File "C:\Python27\lib\site-packages\OpenGL\platform\baseplatform.py", line 402, in __call__
    return self( *args, **named )
ArgumentError: argument 7: <type 'exceptions.TypeError'>: wrong type
GLUT Motion callback <function readPx at 0x02CC5830> with (238, 190),{} failed: returning None argument 7: <type 'exceptions.TypeError'>: wrong type

在我更大的程序中,这个句柄代码在尝试导入时被深埋了5或6个导入OpenGL.raw.WGL文件.\u类型,由任何WGL Opengl扩展导入,但这是仍然导致错误的最小片段。你知道吗

我不明白为什么这一行的出现会对一个看似无关的gl调用产生影响-我如何使用load this扩展而不破坏PyOpenGL的其他部分?你知道吗


Tags: infrompyimportdatatypelinergb
1条回答
网友
1楼 · 发布于 2024-05-03 01:23:55

我找到了原因-POINTER(None)返回了ctypes.c_void_p,这是一个单例,意味着.final属性在这个导入之后是全局可见的,这可能会破坏一些类型检查机制。你知道吗

它在github版本的PyopenGL中是固定的。这是提交:

https://github.com/mcfletch/pyopengl/commit/f087200406a37fc4b99eaad701d18bc64ded2d71

通过在任何OpenGL扩展之前导入此小模块,可以在当前版本的PyOpenGL中修复此问题:

import OpenGL.raw.WGL._types as t
from ctypes import _SimpleCData, _check_size

delattr(t.HANDLE, "final")

class HANDLE(_SimpleCData):
    _type_ = "P"

_check_size(HANDLE)

HANDLE.final = True

t.HANDLE = HANDLE
t.HGLRC = HANDLE
t.HDC = HANDLE

t.HPBUFFERARB = HANDLE
t.HPBUFFEREXT = HANDLE

这将导入导致问题的PyOpenGL模块,修复对c_void_p的损坏,然后从上面的github链接将HANDLE变量及其别名重新分配给_SimpleCData解决方案。你知道吗

相关问题 更多 >