When calling glDeleteVertexArrays(1, vao_id)
or glDeleteBuffers(1, vbo_id)
produces a type error:
Traceback (most recent call last): File "C:\Users\Ollie\AppData\Local\Programs\Python\Python39\lib\site-packages\OpenGL\latebind.py", line 43, in call return self._finalCall( *args, **named ) TypeError: 'NoneType' object is not callable
However when I change the line to glDeleteVertexArrays(1, [vao_id])
(and the same for the vbo) the error goes away. Does this method still free up the memory correctly? is there a different way to go about this? Why do i need to pass it in as a list?
my full code:
import numpy
import glfw
from OpenGL.GL import *
if not glfw.init():
raise Exception("glfw failed")
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, GL_TRUE)
glfw.window_hint(glfw.VISIBLE, GL_TRUE)
glfw.window_hint(glfw.RESIZABLE, GL_FALSE)
window = glfw.create_window(720, 480, "triangle", None, None)
if not window:
glfw.Terminate()
raise Exception("window failed to create!")
glfw.make_context_current(window)
glClearColor(0.5,0.5,0.5,1)
vertices = [
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0,
0.0, 0.5, 0.0
]
vao_id = glGenVertexArrays(1)
glBindVertexArray(vao_id)
glEnableVertexAttribArray(0)
vbo_id = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, vbo_id)
vertices = numpy.array(vertices, dtype=numpy.float32)
glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL_STATIC_DRAW)
glVertexAttribPointer(0, 3, GL_FLOAT, False, 0, 0)
while not glfw.window_should_close(window):
glfw.poll_events()
glClear(GL_COLOR_BUFFER_BIT)
glBindVertexArray(vao_id)
glDrawArrays(GL_TRIANGLES, 0, 3)
glfw.swap_buffers(window)
#no error
glDeleteVertexArrays(1, [vao_id])
glDeleteBuffers(1, [vbo_id])
#error:
#glDeleteVertexArrays(1, vao_id)
#glDeleteBuffers(1, vbo_id)
glfw.terminate()
From the C
API documentation you'll see...
void glDeleteVertexArrays(GLsizei n, const GLuint *arrays);
So the second arg needs to be a GLuint *
-- typically either a pointer to a single GLuint
or the name of an array of GLuint
.
Translated to python this means you need to provide it with a python array. If vao_id
is a single VAO id then changing the second arg from vao_id
to [vao_id]
creates a temporary array with a single element -- namely vao_id
. Similarly for glDeleteBuffers
.