Unsolved OpenGL help
-
I'm trying to learn OpenGL using Qt5 to create the context and handle events. I thought that since I'm doing it in Qt anyway, I might as well use Qt-functions (QOpenGLExtraFunctions). I am currently a bit stuck on trying to handle instances in the shaders, and could use a bit of help. The documentation is oftentimes just for C++.
I could before-this successfully render a number of rotating cubes, but I was doing so with individual draw calls for all of them which bogged the rendering down something massively.
The code is a little bit too long for pasting here, but here's a link to my working repository, where the branch master is a stable (non-instance buffer) approach, and where the branch instancing contains my attempt at just that.
The core snippets to describe what I'm trying to do are:
(lines 160–176 in opengl.py)
for i, j, k in itertools.product( range(0, 100, 2), range(0, 100, 2), range(0, 100, 2) ): translation = pyrr.Vector3([0.0, 0.0, 0.0]) translation.x = i + self.instance_offset translation.y = j + self.instance_offset translation.z = k + self.instance_offset self.instance_array.append(translation) self.len_of_instance_array = len(self.instance_array) self.instance_array = np.array(self.instance_array, dtype=np.float32).flatten() self.instance_vbo.create() self.instance_vbo.bind() self.instance_vbo.allocate(self.instance_array, self.instance_array.nbytes)
(lines 192–196 in opengl.py)
self.glEnableVertexAttribArray(2) self.glVertexAttribPointer( 2, 3, gl.GL_FLOAT, gl.GL_FALSE, 0, VoidPtr(0) ) self.glVertexAttribDivisor(2, 1)
...with the draw call:
(lines 99–117 in opengl.py)
def render(self) -> None: self.program.bind() vao_binder = QOpenGLVertexArrayObject.Binder(self.vao) # TODO: switch to Qt functions (doesn't work) gl.glUniformMatrix4fv(self.projection_loc, 1, gl.GL_FALSE, self.projection) view = self.camera.get_view_matrix() gl.glUniformMatrix4fv(self.camera_loc, 1, gl.GL_FALSE, view) self.glDrawElementsInstanced( gl.GL_TRIANGLES, len(self.shape.indices), gl.GL_UNSIGNED_INT, VoidPtr(0), self.len_of_instance_array ) self.program.release() vao_binder = None
...and my vertex shader is quite simple:
# version 410 core layout(location = 0) in vec3 a_position; layout(location = 1) in vec3 a_color; layout(location = 2) in vec3 a_offset; uniform mat4 model; uniform mat4 projection; uniform mat4 camera; out vec3 v_color; void main() { vec3 final_pos = a_position + a_offset; gl_Position = projection * camera * model * vec4(final_pos, 1.0); v_color = a_color; }
Since I'm writing here anyway, I've also run into some other issues that people may have experience with. One of them is that I've had massive issues with null pointers (which is why I use
VoidPtr(0)
)—I've seen others use just0
and I've read thatNone
is supposed to work in Python but to no avail. And in my drawing calls, I've had to fall back to functions fromOpenGL.GL
instead of using Qt-wrapped ones.Any and all help appreciated.