【问题标题】:OpengL Where is my square?OpengL 我的广场在哪里?
【发布时间】:2018-04-01 13:12:53
【问题描述】:

我无法弄清楚为什么 glDrawElements 不起作用。我已经成功使用了 glDrawArrays。但是当我尝试使用 glDrawElements 绘图时,它不起作用。

我正在关注 learnopengl.com 网站的 python 教程,所以它有点让人头疼。知道为什么这不起作用吗?我已经看了将近一天了,我的方式看不到错误。

import glfw
import numpy as np
import OpenGL

from OpenGL.GL import *
from OpenGL.GL import shaders, ArrayDatatype
from ctypes import sizeof, c_float, c_void_p

def main():
    width = 800
    height = 600
    title = 'Hello Triangle'

    vertex = """#version 410 core
        in vec3 aPos;
        void main() {
            gl_Position = vec4(aPos, 1.0);
        }"""
    fragment = """#version 410 core
        out vec4 FragColor;
        void main() {
            FragColor = vec4(1.0, 0.5, 0.2, 1.0);
        }"""

    if not glfw.init():
        raise TypeError('Unable to initalize glfw')

    glfw.window_hint(glfw.SAMPLES, 4)
    glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
    glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 1)
    glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
    glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, True)
    glfw.window_hint(glfw.OPENGL_DEBUG_CONTEXT, True)

    window = glfw.create_window(width, height, title, None, None)
    if not window:
        raise TypeError('Unable to create the window')
    glfw.make_context_current(window)
    glfw.set_framebuffer_size_callback(window, framebuffer_size)

    verts = np.array([[-0.5, 0.5, 0.0], [-0.5, -0.5, 0.0], [0.5, -0.5, 0.0], [0.5, 0.5, 0.0]], dtype=np.float)
    indices = np.array([[0, 1, 3], [3, 1, 2]], dtype=np.uint)

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

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

    shader_program = glCreateProgram()
    glAttachShader(shader_program, vertex_shader)
    glAttachShader(shader_program, fragment_shader)
    glLinkProgram(shader_program)

    glDeleteShader(vertex_shader)
    glDeleteShader(fragment_shader)

    vao_id = glGenVertexArrays(1)
    vbo_id = glGenBuffers(1)
    ebo_id = glGenBuffers(1)

    glBindVertexArray(vao_id)

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo_id)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices, GL_STATIC_DRAW)
    #glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)

    glBindBuffer(GL_ARRAY_BUFFER, vbo_id)
    glBufferData(GL_ARRAY_BUFFER, verts, GL_STATIC_DRAW)
    glVertexAttribPointer(0, 3, GL_FLOAT, False, 0, None)
    glEnableVertexAttribArray(0)

    #glBindBuffer(GL_ARRAY_BUFFER, 0)

    #glBindVertexArray(0)

    while not glfw.window_should_close(window):
        glClearColor(0.2, 0.3, 0.3, 1.0)
        glClear(GL_COLOR_BUFFER_BIT)

        glUseProgram(shader_program)
        glBindVertexArray(vao_id)
        glEnableVertexAttribArray(0)
        #glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0)
        glBindVertexArray(0)

        glfw.swap_interval(1)
        glfw.swap_buffers(window)
        glfw.poll_events()

    glfw.destroy_window(window)
    glfw.terminate()

def framebuffer_size(window, width, height):
    glViewport(0, 0, width, height)


if __name__ == '__main__':
    main()

【问题讨论】:

    标签: python opengl pyopengl


    【解决方案1】:

    这段代码中有两个棘手的问题需要解决,它们都是微妙的并且是特定于 python 的。

    首先,您应该将glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0) 中的0 替换为None。我怀疑这是因为 PyOpenGL 使用 ctypes 来包装 OpenGL 并且建议 None 根据 ctypes documentation 来表示 NULL 指针。如果您以后需要为缓冲区使用偏移量,您应该查看this answer

    其次,如果您只执行第 1 步并运行代码,您可能会发现输出不是您所期望的:

    我们的橙色矩形发生了什么?好吧,这里的问题在于我们传递给缓冲区对象的数据。如果您在 64 位设备上,如果未完全指定,numpy 数据类型 (dtype) 也将是 64 位。 OpenGL 需要 32 位浮点数和整数而不是双精度数,因此我们需要使用 np.float32 代替。为了一致性起见,我还将使用np.uint32 作为索引缓冲区,但这并不是绝对必要的。如果我们将您的 vertsindices 初始化语句修复为:

    verts = np.array([[-0.5, 0.5, 0.0], [-0.5, -0.5, 0.0], [0.5, -0.5, 0.0], [0.5, 0.5, 0.0]], dtype=np.float32)
    indices = np.array([[0, 1, 3], [3, 1, 2]], dtype=np.uint32)
    

    结果应该更符合你的预期:

    希望这会有所帮助!

    【讨论】:

    • @AdamAdamAdam 很高兴它有帮助。如果您浏览了所有这些 learnopengl 教程,如果有机会,也许您可​​以将每个教程的所有最终代码放在 github 上?我怀疑它对于可能遇到类似问题的其他人会很有用(我知道我肯定是第一次这样做)。
    • 这是我的意图。浏览所有困难的部分并将代码发布到 github 上。
    猜你喜欢
    • 1970-01-01
    • 2010-10-30
    • 2011-02-04
    • 2020-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多