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

使用PyOpenGL与GLFW绘制单点时glVertexAttribPointer报1282错误求助

OpenGL glVertexAttribPointer调用错误排查与修复

问题概述

使用Python 3.10.8开发OpenGL程序,拆分为3个文件后,执行glVertexAttribPointer(main.py第70行)时出现错误,调试未定位到有效原因,参考相关解决方案后需针对性修复建议。

相关代码

main.py

import glfw
import Shaders
from OpenGL.GL import *
from OpenGL.GLUT import *
from Math_3d import Vector2f


class Window:
    def __init__(self, width: int, height: int, title: str):
        if not glfw.init():
            raise Exception("glfw can not be initialized")
        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)

        self._win = glfw.create_window(width, height, title, None, None)

        if not self._win:
            glfw.terminate()
            raise Exception("glfw window can not be created")

        glfw.set_window_pos(self._win, 400, 200)
        glfw.make_context_current(self._win)

    def createshaders(self):
        # Request program and shader slots from the GPU
        program = glCreateProgram()
        vertex = glCreateShader(GL_VERTEX_SHADER)
        fragment = glCreateShader(GL_FRAGMENT_SHADER)
        # Set shader sources
        glShaderSource(vertex, Shaders.vertex_code)
        glShaderSource(fragment, Shaders.fragment_code)
        # Compile shaders
        glCompileShader(vertex)
        glCompileShader(fragment)
        if not glGetShaderiv(vertex, GL_COMPILE_STATUS):
            report_shader = glGetShaderInfoLog(vertex)
            print(report_shader)
            raise RuntimeError("Vertex shader compilation error")

        if not glGetShaderiv(fragment, GL_COMPILE_STATUS):
            report_frag = glGetShaderInfoLog(fragment)
            print(report_frag)
            raise RuntimeError("Fragment shader compilation error")

        # Link objects to program
        glAttachShader(program, vertex)
        glAttachShader(program, fragment)
        glLinkProgram(program)

        if not glGetProgramiv(program, GL_LINK_STATUS):
            print(glGetProgramInfoLog(program))
            raise RuntimeError('Linking error')
        # Get rid of shaders
        glDetachShader(program, vertex)
        glDetachShader(program, fragment)
        # Make default program to run
        glUseProgram(program)

        # Vertex Buffer Object
        # Create point vertex data
        v2f_1 = Vector2f(0.0, 0.0)
        # Request a buffer slot from GPU
        buffer = glGenBuffers(1)
        # Make this buffer the default one
        glBindBuffer(GL_ARRAY_BUFFER, buffer)
        strides = v2f_1.data.strides[0]
        loc = glGetAttribLocation(program, 'position')
        glEnableVertexAttribArray(loc)
        glVertexAttribPointer(loc, 2, GL_FLOAT, False, strides, None)
        # glBufferData(GL_ARRAY_BUFFER, v2f_1, v2f_1, GL_DYNAMIC_DRAW)

    def renderscene(self):
        while not glfw.window_should_close(self._win):
            glfw.poll_events()
            glClear(GL_COLOR_BUFFER_BIT)
            glDrawArrays(GL_POINTS, 0, 1)
            glfw.swap_buffers(self._win)

        glfw.terminate()


if __name__ == '__main__':
    win = Window(1024, 768, "GLFW Window")
    win.createshaders()  # Create and initialize shaders and initialize Vertex Buffer Object
    win.renderscene()  # Swap buffer and render scene

Shaders.py

vertex_code = """
    attribute vec2 position;
    void main()
    {
        gl_Position = vec4(position, 0.0, 1.0);
    }   
    """

fragment_code = """
    void main() 
    { 
        gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); 
    }
    """

Math_3d.py

import numpy as np


class Vector2f:
    def __init__(self, x, y):
        self.data = np.array([x, y], dtype=np.float32)


if __name__ == '__main__':
    vec2 = Vector2f(0.0, 0.0)
    print(vec2.data)
    print(type(vec2.data.strides[0]))
    print(vec2.data.strides[0])

错误原因分析

  1. 缺失VBO数据填充:代码中注释掉了glBufferData调用,导致绑定的GL_ARRAY_BUFFER为空,glVertexAttribPointer无法找到有效数据存储位置。
  2. 核心模式未使用VAO:OpenGL 3.3核心配置文件要求必须绑定顶点数组对象(VAO),否则顶点属性配置无法被正确保存,会触发glVertexAttribPointer调用错误。
  3. glBufferData参数错误:即使取消注释,原代码中glBufferData的第二个和第三个参数传入的是v2f_1(Vector2f对象),而非实际的numpy数组v2f_1.data,会导致数据传递失败。

修复方案

1. 添加VAO创建与绑定

在createshaders方法中,VBO创建前添加VAO的初始化:

# 核心模式必须绑定VAO
vao = glGenVertexArrays(1)
glBindVertexArray(vao)

2. 修复glBufferData调用

取消注释并修正参数:

# 向VBO填充数据
glBufferData(GL_ARRAY_BUFFER, v2f_1.data.nbytes, v2f_1.data, GL_DYNAMIC_DRAW)

3. 优化strides参数

由于数据是紧密排列的,可直接传入0(OpenGL会自动计算步长),或保留原strides值(需确保正确):

# 步长设为0,或使用v2f_1.data.strides[0]
glVertexAttribPointer(loc, 2, GL_FLOAT, False, 0, None)

修改后的createshaders方法关键片段

# Make default program to run
glUseProgram(program)

# 核心模式必须绑定VAO
vao = glGenVertexArrays(1)
glBindVertexArray(vao)

# Vertex Buffer Object
# Create point vertex data
v2f_1 = Vector2f(0.0, 0.0)
# Request a buffer slot from GPU
buffer = glGenBuffers(1)
# Make this buffer the default one
glBindBuffer(GL_ARRAY_BUFFER, buffer)
# 向VBO填充数据
glBufferData(GL_ARRAY_BUFFER, v2f_1.data.nbytes, v2f_1.data, GL_DYNAMIC_DRAW)

loc = glGetAttribLocation(program, 'position')
glEnableVertexAttribArray(loc)
# 使用0作为步长(紧密排列数据)
glVertexAttribPointer(loc, 2, GL_FLOAT, False, 0, None)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 17:25:26