You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Python中向glVertexAttribPointer传递偏移指针报错求助

问题:Python OpenGL中glVertexAttribPointer偏移指针传递报错

报错信息

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

需求与参考代码

需要将C语言中glVertexAttribPointer的偏移指针逻辑迁移到Python,对应的C语言实现:

// 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()")
解决方案

错误原因

  • 错误地用固定长度的GLfloat数组类型(如GL.GLfloat *3)包装整个vertices_list,数组长度远小于列表长度,解包传入时触发索引越界。
  • PyOpenGL中glVertexAttribPointer的偏移参数不需要创建数组,需传递字节偏移量对应的void指针,和C语言(void*)(偏移字节数)逻辑一致。

正确实现步骤

  1. 计算各属性的字节偏移量:
    • 顶点属性偏移为0(已用None正确处理)
    • 颜色属性偏移:3 * ctypes.sizeof(ctypes.c_float)(对应C语言3*sizeof(float))
    • 纹理坐标属性偏移:6 * ctypes.sizeof(ctypes.c_float)(3个顶点float + 3个颜色float的总字节数)
  2. 用ctypes.c_void_p(偏移量)将字节偏移量转换为PyOpenGL可识别的void指针,传入glVertexAttribPointer最后一个参数。

修改后的完整代码

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,
            GL.GL_FALSE,
            8 * ctypes.sizeof(ctypes.c_float),
            None
        )
        GL.glEnableVertexAttribArray(0)

        # 颜色属性(正确传递偏移)
        color_offset = 3 * ctypes.sizeof(ctypes.c_float)
        GL.glVertexAttribPointer(
            1,
            3,
            GL.GL_FLOAT,
            GL.GL_FALSE,
            8 * ctypes.sizeof(ctypes.c_float),
            ctypes.c_void_p(color_offset)
        )
        GL.glEnableVertexAttribArray(1)

        # 纹理坐标属性(正确传递偏移)
        tex_offset = 6 * ctypes.sizeof(ctypes.c_float)
        GL.glVertexAttribPointer(
            2,
            2,
            GL.GL_FLOAT,
            GL.GL_FALSE,
            8 * ctypes.sizeof(ctypes.c_float),
            ctypes.c_void_p(tex_offset)
        )
        GL.glEnableVertexAttribArray(2)

        print("Box()")

内容的提问来源于stack exchange,提问作者prusso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 09:55:19