【问题标题】:glDrawArrays returning invalid operation 1282 - pyOpenGLglDrawArrays 返回无效操作 1282 - pyOpenGL
【发布时间】:2018-08-24 12:46:33
【问题描述】:

我这辈子都想不通。我需要第二双眼睛……或者更好的大脑。我试图让这个“Hello Triangle”python 示例正常工作。我一直在从 c 教程翻译它。但是,无论我做什么,我都会不断收到此错误。

Traceback (most recent call last):
File ".../demo/tester.py", line 107, in <module>
  if __name__ == '__main__': main()
File ".../demo/tester.py", line 87, in main
  glDrawArrays(GL_TRIANGLES, 0, 3)
File ".../venv/lib/python3.6/site packages/OpenGL/platform/baseplatform.py", line 402, in __call__
  return self( *args, **named )
File ".../venv/lib/python3.6/site-packages/OpenGL/error.py", line 232, in glCheckError
  baseOperation = baseOperation,
OpenGL.error.GLError: GLError(
  err = 1282,
  description = b'invalid operation',
  baseOperation = glDrawArrays,
  cArguments = (GL_TRIANGLES, 0, 3)

我的代码如下。我在 Mac 上运行,因此您会注意到其中的一些东西可能不需要 PC。在 glDrawArrays 之前一切正常。我知道 openGL for C 和 python 使用 pyOpenGL 之间的一些函数有点不同。我一直在交叉引用文档,以确保我不会像 Python 中的 C 程序员那样尝试编写。

try:
    from AppKit import NSApp, NSApplication
except:
    pass

import sys
import cyglfw3 as glfw
import numpy as np
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.arrays import vbo as glvbo



def main():
    glfw.Init()
    glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, 3)
    glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, 3)
    glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
    glfw.WindowHint(glfw.OPENGL_FORWARD_COMPAT, GL_TRUE)

    window = glfw.CreateWindow(800, 600, 'LearnOpenGL', None)
    if window is None:
        glfw.Terminate()
        exit()

    glfw.MakeContextCurrent(window)
    glfw.SetFramebufferSizeCallback(window, framebuffer_size_callback())

    # Setting up a vertex buffer
    verts = glvbo.VBO(
    np.array([[0.0, 0.5, 0.0], [0.5, -0.5, 0.0], [-0.5, -0.5, 0.0]], 'f')
)

    vbo = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, vbo)
    glBufferData(GL_ARRAY_BUFFER, verts.size, verts, GL_STATIC_DRAW)

    vao = glGenVertexArrays(1)
    glBindVertexArray(vao)
    glEnableVertexAttribArray(vao)
    glBindBuffer(GL_ARRAY_BUFFER, vbo)
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None)

    vertex_shader = """
        #version 330 core
        in vec3 vp;
        void main() {
            gl_Position = vec4(vp, 1.0);
        }"""

    fragment_shader = """
        #version 330 core
        out vec4 frag_color;
        void main() {
            frag_color = vec4(0.5, 0.0, 0.5, 1.0);
        }"""

    vs = glCreateShader(GL_VERTEX_SHADER)
    glShaderSource(vs, vertex_shader)
    glCompileShader(vs)

    if glGetShaderiv(vs, GL_COMPILE_STATUS) != GL_TRUE:
        raise Exception("vertex shader did not compile")

    fs = glCreateShader(GL_FRAGMENT_SHADER)
    glShaderSource(fs, fragment_shader)
    glCompileShader(fs)

    if glGetShaderiv(fs, GL_COMPILE_STATUS) != GL_TRUE:
        raise Exception("fragment shader did not compile")

    sp = glCreateProgram()
    glAttachShader(sp, fs)
    glAttachShader(sp, vs)
    glLinkProgram(sp)

    if glGetProgramiv(sp, GL_LINK_STATUS) != GL_TRUE:
        raise Exception("program did not link")

    while not glfw.WindowShouldClose(window):

        processInput(window)

        glClearColor(0.0, 0.0, 0.0, 1.0)
        glClear(GL_COLOR_BUFFER_BIT)

        glUseProgram(sp)
        glBindVertexArray(vao)
        glDrawArrays(GL_TRIANGLES, 0, 3)    # This is where things happen

        glfw.PollEvents()
        glfw.SwapBuffers(window)

    glfw.Terminate()
    exit()

def framebuffer_size_callback():
    glViewport(0, 0, 800, 600)

def processInput(window):
    if glfw.GetKey(window, glfw.KEY_ESCAPE) == glfw.PRESS:
        glfw.SetWindowShouldClose(window, True)

if __name__ == '__main__': main()

最后我想做的就是画一个三角形:(

【问题讨论】:

  • glEnableVertexAttribArray(vao) 看起来不对。您必须启用 vp 的属性位置,而不是 vao。但这可能不会导致无效的操作错误。
  • 您应该检查您的着色器是否编译和链接正常 (glGetShaderiv/glGetProgramvi)。
  • vp的位置是什么意思?我添加了异常并且没有遇到着色器和程序的问题。
  • @BDL - 我注意到它需要一个索引。我为索引传递了一个 0。它现在运行没有问题,但没有显示我的三角形:)

标签: python opengl pyopengl


【解决方案1】:

我确定有 2 个问题。

  1. 正如 BDL 所述,glEnableVertexAttribArray 设置不正确。它需要一个索引而不是顶点数组对象。
  2. glBufferData 大小不正确,因为需要以字节为单位提供大小。在线快速搜索发现 (numpy.size * numpy.itemsize) 返回数组的大小。

完成这两件事后...我有一个三角形。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-02
    • 2014-12-25
    • 2019-09-08
    相关资源
    最近更新 更多