PyOpenGl 验证失败

PyOpenGl Validation failure

我正在尝试使用 pyopengl 创建一个简单的场景,但我一直收到运行时错误。我正在使用 glfw 来显示 opengl 场景。

我正在使用 python 因为我想在其他一些 python 项目中包含 opengl。

我使用的是 macOS Mojave (10.14),Python 3.7

错误:

Traceback (most recent call last):
File "main.py", line 109, in <module>
main()
File "main.py", line 64, in main
shader = OpenGL.GL.shaders.compileProgram(s.vertex(), s.fragment())
File "slib/python3.7/site-packages/OpenGL/GL/shaders.py", line 196, in         
compileProgram
program.check_validate()
File "lib/python3.7/site-packages/OpenGL/GL/shaders.py", line 108, in 
check_validate
glGetProgramInfoLog( self ),
RuntimeError: Validation failure (0): b'Validation Failed: No vertex 
array object bound.\n'

代码:

import glfw
from OpenGL.GL import *
import OpenGL.GL.shaders
import numpy as np


def trikotnik():
    trikotnik = np.array([
        -0.5, -0.5, 0.0,
        0.5, -0.5, 0.0,
        0.0, 0.5, 0.0
    ], dtype=np.float32)
    return trikotnik


class Shaders:
    def __init__(self):
        pass

    def vertex(self):
        v = """
        #version 330
        in vec4 position; 
        void main() { 
            gl_Position = position; 
        } 
        """
        return OpenGL.GL.shaders.compileShader(v, GL_VERTEX_SHADER)

    def fragment(self):
        f = """
        #version 330
        out vec4 fragColor;
        void main() { 
            fragColor = vec4( 0, 1, 0, 1 );
        } 
        """
        return OpenGL.GL.shaders.compileShader(f, GL_FRAGMENT_SHADER)


def main():
    # Initialize the library
    if not glfw.init():
        return
    glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
    glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 2)
    glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
    glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, GL_TRUE)

    # Create a windowed mode window and its OpenGL context
    window = glfw.create_window(640, 480, "Hello World", None, None)
    if not window:
        glfw.terminate()
        return

    # Make the window's context current
    glfw.make_context_current(window)

    # Creating shaders
    s = Shaders()
    shader = OpenGL.GL.shaders.compileProgram(s.vertex(), s.fragment())

    # Creating vertex buffer object on gpu
    VBO = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, VBO)
    # Load data on array buffer...32 = size in bytes 9x4
    # GL_STATIC_DRAW: The vertex data will be uploaded once and drawn many times.
    glBufferData(GL_ARRAY_BUFFER, 32, trikotnik(), GL_STATIC_DRAW)
    glBindBuffer(GL_ARRAY_BUFFER, VBO)

    position = glGetAttribLocation(shader, "position")
    glVertexAttribPointer(
        position,  # attribute 0. No particular reason for 0, but must match the layout in the shader.
        3,  # size
        GL_FLOAT,  # type
        GL_FALSE,  # normalized
        0,  # stride
        None  # array buffer offset
    )
    glEnableVertexAttribArray(position)

    glUseProgram(shader)

    glClearColor(0, 107, 179, 1.0)

    # Loop until the user closes the window
    while not glfw.window_should_close(window):
        # Render here, e.g. using pyOpenGL

        # Clear color buffer
        glClear(GL_COLOR_BUFFER_BIT)

        # Draw
        glDrawArrays(GL_TRIANGLES, 0, 3)

        # Swap front and back buffers
        glfw.swap_buffers(window)
        # Poll for and process events
        glfw.poll_events()

    glfw.terminate()


if __name__ == "__main__":
    main()

我在源代码中找到了这个:

validate (keyword only) -- if False, suppress automatic validation against current GL state. In advanced usage the validation can produce spurious errors. Note: this function is not really intended for advanced usage, if you're finding yourself specifying this flag you likely should be using your own shader management code.

我尝试将其设置为 False,但仍然出现错误。

要么使用 Vertex Array Object,要么切换到兼容性配置文件上下文 glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_COMPAT_PROFILE)。在核心配置文件中你必须有一个命名的 VAO,它不是可选的。

在指定顶点数组数据的数组之前创建并绑定一个VAO:

VAO = glGenVertexArrays(1)
glBindVertexArray(VAO)

glVertexAttribPointer(
    position,  # attribute 0. No particular reason for 0, but must match the layout in the shader.
    3,  # size
    GL_FLOAT,  # type
    GL_FALSE,  # normalized
    0,  # stride
    None  # array buffer offset
)
glEnableVertexAttribArray(position)