PyOpenGL glReadPixels вызывает ошибку аргумента ctypes после окончательного создания POINTER - PullRequest
0 голосов
/ 07 ноября 2018

У меня странная проблема с pyopengl и его импортом, ниже приведена небольшая тестовая программа, вырезанная из гораздо большей, но ее достаточно, чтобы показать проблему. Вам нужно установить PyOpenGL, и если вы запустите его как есть, он покажет пустое окно, и если вы нажмете и перетащите его, вы получите несколько нулей. Если вы раскомментируете строку 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

В моей большой программе этот код HANDLE скрывается на глубине 5 или 6 при попытке импортировать OpenGL.raw.WGL._types, который импортируется любым расширением WGL Opengl, но это самый маленький фрагмент, который все еще вызывает ошибку.

Я не понимаю, почему присутствие этой строки влияет на, казалось бы, не связанный вызов gl - как я могу использовать загрузку этого расширения, не нарушая другие части PyOpenGL?

1 Ответ

0 голосов
/ 07 ноября 2018

Я нашел причину - POINTER(None) возвращает ctypes.c_void_p, который является одноэлементным, и означает, что атрибут .final становится видимым глобально после этого импорта, что, вероятно, нарушает некоторый механизм проверки типов позже.

Исправлено в github-версии PyopenGL. Это коммит:

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

Вы можете исправить это в текущей версии PyOpenGL, импортировав этот небольшой модуль перед любыми расширениями OpenGL:

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, затем переназначает переменную HANDLE и ее псевдонимы на решение _SimpleCData из ссылки на github выше.

...