glDrawArrays возвращает недопустимую операцию 1282 - pyOpenGL

Я не могу понять этого хоть убей. Мне нужна вторая пара глаз ... или лучший мозг. Я пытаюсь заставить работать этот пример Python "Hello Triangle". Я переводил это из учебника 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, поэтому вы заметите некоторые вещи, которые могут не понадобиться для ПК. Все работает нормально вплоть до glDrawArrays. Я знаю, что некоторые функции между openGL для C и python с использованием pyOpenGL немного отличаются. Я делал перекрестные ссылки на документацию, чтобы убедиться, что я не пытаюсь писать как программист на C на Python.

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()

Все, что я хочу сделать в конце дня, это нарисовать треугольник :(


person Adam Adam Adam    schedule 15.03.2018    source источник
comment
glEnableVertexAttribArray(vao) выглядит не так. Вместо vao необходимо включить расположение атрибута vp. Но это, вероятно, не приведет к ошибке недопустимой операции.   -  person BDL    schedule 15.03.2018
comment
Вы должны проверить, правильно ли скомпилирован и связан ваш шейдер (glGetShaderiv/glGetProgramvi).   -  person BDL    schedule 15.03.2018
comment
Что значит расположение вп? Я добавил исключения и проблем с шейдерами и программой не возникало.   -  person Adam Adam Adam    schedule 15.03.2018
comment
@BDL - Я заметил, что для этого требуется index. Я поставил индекс 0. Теперь он работает без проблем, но не показывает мой треугольник :)   -  person Adam Adam Adam    schedule 15.03.2018


Ответы (1)


Я определил, что было 2 проблемы.

  1. Как упоминалось в BDL, glEnableVertexAttribArray не был настроен должным образом. Ему нужен индекс, а не объект массива вершин.
  2. Размер glBufferData был неправильным, так как размер должен был быть указан в байтах. Быстрый поиск в Интернете показал, что (numpy.size * numpy.itemsize) возвращает размер массива.

С этими двумя делами ... у меня есть треугольник.

person Adam Adam Adam    schedule 15.03.2018