简体   繁体   中英

Indexed drawing in PyOpenGL using glDrawElements doesn't draw anything

I'm fairly new to OpenGL and I tried recreating the tutorial from https://learnopengl.com/Getting-started/Hello-Triangle to draw a rectangle in PyOpenGL.

(Original source code: https://learnopengl.com/code_viewer_gh.php?code=src/1.getting_started/2.2.hello_triangle_indexed/hello_triangle_indexed.cpp )

The first part of the tutorial that only draws a triangle using glDrawArrays works perfectly but when I try to use glDrawElements nothing is drawn. It doesn't even raise an error, it just shows me a black screen. I'm pretty sure I copied the instructions from the tutorial one by one and since there is no error message, I have no idea what I did wrong.

I would appreciate any sort of help.

My code:

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


class Shaders:
    def vertex(self):
        v = """
        #version 330 core
        layout (location = 0) in vec3 aPos;

        void main()
        {
            gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
        }
        """
        return OpenGL.GL.shaders.compileShader(v, GL_VERTEX_SHADER)

    def fragment(self):
        f = """
        #version 330 core
        out vec4 FragColor;

        void main()
        {
            FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
        } 
        """
        return OpenGL.GL.shaders.compileShader(f, GL_FRAGMENT_SHADER)


def main():
    # glfw: initialize and configure
    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)
    window = glfw.create_window(1920, 1080, "Hello World", None, None)
    if not window:
        glfw.terminate()
        return
    glfw.make_context_current(window)

    # build and compile shaders
    s = Shaders()
    shader = OpenGL.GL.shaders.compileProgram(s.vertex(), s.fragment())

    # set up vertex data and buffers and configure vertex attributes
    vertices = 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,
        1, 2, 3
    ])

    VAO = glGenVertexArrays(1)
    VBO = glGenBuffers(1)
    EBO = glGenBuffers(1)

    glBindVertexArray(VAO)

    glBindBuffer(GL_ARRAY_BUFFER, VBO)
    glBufferData(GL_ARRAY_BUFFER, 48, vertices, GL_STATIC_DRAW)

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 12, indices, GL_STATIC_DRAW)

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0)
    glEnableVertexAttribArray(0)

    glBindBuffer(GL_ARRAY_BUFFER, 0)
    glBindVertexArray(0)

    # render loop
    while not glfw.window_should_close(window):
        glClearColor(0, 0, 0, 1.0)
        glClear(GL_COLOR_BUFFER_BIT)

        glUseProgram(shader)
        glBindVertexArray(VAO)
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None)

        glfw.swap_buffers(window)
        glfw.poll_events()

    glfw.terminate()


if __name__ == "__main__":
    main()

If a named buffer object is bound, then the 6th parameter of glVertexAttribPointer is treated as a byte offset into the buffer object's data store. But the type of the parameter is a pointer anyway ( c_void_p ).

So if the offset is 0, then the 6th parameter can either be None or c_void_p(0) :

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0)

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None)

The index buffer consist of 6 indices of the type uint32 . Hence the size of the index buffer is 24 instead of 12:

glBufferData(GL_ELEMENT_ARRAY_BUFFER, 12, indices, GL_STATIC_DRAW)

glBufferData(GL_ELEMENT_ARRAY_BUFFER, 24, indices, GL_STATIC_DRAW)

When using PyOpenGL the size parameter can be ommited (see glBufferData ). In this case the size off the array is used:

glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices, GL_STATIC_DRAW)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM