I need to pass an offset pointer to glVertexAttribPointer in Python. Currently I have coming out of pythons console window when an instance of Box class is created:
C:\Users\phill\PycharmProjects\texturebox\venv\Scripts\python.exe C:\Users\phill\PycharmProjects\texturebox\main.py
Traceback (most recent call last):
File "C:\Users\phill\PycharmProjects\texturebox\main.py", line 29, in <module>
main()
File "C:\Users\phill\PycharmProjects\texturebox\main.py", line 18, in main
m_box = Box()
^^^^^
File "C:\Users\phill\PycharmProjects\texturebox\Box.py", line 60, in __init__
array_colors_offset(*vertices_list)
IndexError: invalid index
Process finished with exit code 1
Does anyone know how an offset pointer might be passed in Python?
The corresponding C code for the (void *) looks like this:
// color attribute
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
Box.py:
from OpenGL import GL as GL
import ctypes
class Box:
def __init__(self):
#3 floats for vertices x,y,z 3 floats for color R G B 2 floats for tex co-ords
vertices_list = [
0.5, 0.5, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0,
0.5, -0.5, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0,
-0.5, -0.5, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
-0.5, 0.5, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0
]
indices_list = [
0, 1, 3,
1, 2, 3
]
self.EBO = None
self.VBO = None
self.VAO = None
self.VAO = GL.glGenVertexArrays(1)
self.VBO = GL.glGenBuffers(1)
self.EBO = GL.glGenBuffers(1)
GL.glBindVertexArray(self.VAO)
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBO)
array_type_vertices = (GL.GLfloat * len(vertices_list))
GL.glBufferData(GL.GL_ARRAY_BUFFER, len(vertices_list) * ctypes.sizeof(ctypes.c_float),
array_type_vertices(*vertices_list), GL.GL_STATIC_DRAW)
GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, self.EBO)
array_type_indices = (GL.GLint * len(indices_list))
GL.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, len(indices_list) * ctypes.sizeof(ctypes.c_ulong),
array_type_indices(*indices_list), GL.GL_STATIC_DRAW)
GL.glVertexAttribPointer(
0,
3,
GL.GL_FLOAT,
False,
8 * ctypes.sizeof(ctypes.c_float),
None
)
GL.glEnableVertexAttribArray(0)
# attempting to pass the pointer
array_colors_offset = (GL.GLfloat * 3)
GL.glVertexAttribPointer(1,
3,
GL.GL_FLOAT,
False,
8 * ctypes.sizeof(ctypes.c_float),
array_colors_offset(*vertices_list)
)
GL.glEnableVertexAttribArray(1)
array_tex_offset = (GL.GLfloat * 6)
GL.glVertexAttribPointer(2,
2,
GL.GL_FLOAT,
GL.GL_FALSE,
8 * ctypes.sizeof(ctypes.c_float),
array_tex_offset(*vertices_list)
)
print("Box()")
So I started with code from gitlabs opengl python examples. The basic triangle does not seem to enumerate how to pass a pointer to glVertexAtribPointer. So there is an offset to pass as a (void *) according to the C code I have that I am moving over into Python.
(GL.GLfloat * 6)(*vertices_list)
does not do what you expect. It creates an array with 6 elements.
See pyopengl, glVertexAttribPointer
. The argument must be a void pointer. You can use the ctypes.c_void_p
to create a void pointer, e.g.:
GL.glVertexAttribPointer(1,
3,
GL.GL_FLOAT,
False,
8 * ctypes.sizeof(ctypes.c_float),
ctypes.c_void_p(3 * ctypes.sizeof(ctypes.c_float))
)