问题描述
我正在使用 python.and 学习 opengl 并学习本课程
https://www.youtube.com/watch?v=WMiggUPst-Q&list=PLRIWtICgwaX0u7Rf9zkZhLoLuZVfUksDP&index=2
只是为了能够做到。他正在使用 LWJGL,我是 PyOpengl。我注意到他的一些方法 (glgenVertexArray
,gldeleteVertexArray
...ex) 是在没有参数的情况下使用的,即使文档另有说明。虽然我在 python 中编写了相同的代码,但它说
glGenVertexArrays 需要 1 个参数(n,数组),收到 0: ()
它需要我提供相同方法的参数。这里不是问题(我认为)给 1,但是当它来到 glDeleteVertexArrays
时,如果我不给 1 并且我保留 vao 的列表,vbo ids 它会提高这个
回溯(最近一次调用最后一次): 文件“C:\Users\TheUser\AppData\Local\Programs\Python\python38-32\lib\site-packages\OpenGL\latebind.py”,第 43 行,调用 返回 self._finalCall( *args,**named ) TypeError: 'nonetype' 对象不可调用
在处理上述异常的过程中,又发生了一个异常: 回溯(最近一次调用最后一次): 文件“C:/Users/TheUser/Desktop/MyPytonDen/ThinMatrixOpenGl/engineTester/MainGameLoop.py”,第 22 行,在 Loader.CleanUP() 文件“C:\Users\TheUser\Desktop\MyPytonDen\ThinMatrixOpenGl\renderEngine\Loader.py”,第 12 行,在 CleanUP 中 glDeleteVertexArrays() 文件“C:\Users\TheUser\AppData\Local\Programs\Python\python38-32\lib\site-packages\OpenGL\latebind.py”,第 47 行,调用 返回 self._finalCall( *args,**named ) 文件“C:\Users\TheUser\AppData\Local\Programs\Python\python38-32\lib\site-packages\OpenGL\wrapper.py”,第 689 行,在 wrapperCall pyArgs = tuple(calculate_pyArgs(args)) 文件“C:\Users\TheUser\AppData\Local\Programs\Python\python38-32\lib\site-packages\OpenGL\wrapper.py”,第 436 行,在calculate_pyArgs 引发值错误( ValueError:glDeleteVertexArrays 需要 2 个参数(n,数组),收到 0: ()
我按照我说的处理这个,但我认为它不合适。 所以我在问它到底想要什么(文档对我来说不够明确)以及为什么它需要 PyOpenGl 而不是 LWJGL
这是文件:
from ThinMatrixOpenGl.renderEngine.RawModel import RawModel
from OpenGL.GL import *
import numpy as np
VAOs = []
VBOs = []
def CleanUP():
print(VAOs,VBOs)
for vao in VAOs:
glDeleteVertexArrays(int(vao),VAOs)
for vbo in VBOs:
glDeleteBuffers(int(vbo),VBOs)
def LoadToVao(positions):
global VAOs
VAO_ID = CreateVao()
VAOs.append(VAO_ID)
storeDataInAttribList(0,positions)
unbindVao()
return RawModel(vao_id=VAO_ID,vertex_count=(len(positions) / 3))
def CreateVao():
VAO_ID = glGenVertexArrays(1)
glBindVertexArray(VAO_ID)
return VAO_ID
def storeDataInAttribList(attrib_number: int,data: float):
global VBOs
VBO_id = glGenBuffers(1)
VBOs.append(VBO_id)
glBindBuffer(GL_ARRAY_BUFFER,VBO_id)
buffer = StoreDataInFloatBuffer(data)
glBufferData(GL_ARRAY_BUFFER,buffer,GL_STATIC_DRAW)
glVertexAttribPointer(attrib_number,3,GL_FLOAT,GL_FALSE,None)
glBindBuffer(GL_ARRAY_BUFFER,0)
def unbindVao():
glBindVertexArray(0)
def StoreDataInFloatBuffer(data: float):
buffer = np.array(data,dtype=np.float32)
return buffer
解决方法
见OpenGL 4.6 API Core Profile Specification - 10.3.1 Vertex Array Objects
void DeleteVertexArrays( sizei n,const uint *arrays );
参见 PyOpneGL - glDeleteVertexArrays
:
签名
glDeleteVertexArrays( GLsizei ( n ),const GLuint *( arrays ) )-> void
def glDeleteVertexArrays( n,arrays )
第二个参数必须是元素类型为“unit”的数组:
def CleanUP():
np_vaos = np.array([vao],dtype="uint")
glDeleteVertexArrays(np_vaos.size,np_vaos)
然而,在较新的 PyOpenGL 版本中,第二个参数也可以是一个列表:
def CleanUP():
glDeleteVertexArrays(len(VAOs),VAOs)
当使用 LWJGL 时,大小参数 (n) 是从 Java 数组对象推导出来的。不同语言的不同库为 OpenGL API 函数提供了不同的重载。如果函数行为异常且与 OpenGL 规范不同,您必须查阅库的 API 文档。