将 C++ OpenGL 移植到 PyOpenGL 无法正确呈现

Porting C++ OpenGL to PyOpenGL not rendering properly

过去几天我一直面临一个问题,但我仍然无法弄清楚。我正在尝试将以前的 C++ Opengl 项目移植到 PyOpengl,但是我'我无法使对象按应有的方式呈现。我只是想渲染一个 3D 网格模型,它在原始 C++ 代码中有效,但在 Python PyOpenGL 中无效。

What it should look like:(C++ OpenGL)
What it looks like (Python PyOpenGL)

这是我在 PyOpenGL 中得到的代码:

import glfw
import glm
import numpy as np
from OpenGL.GL import *
import Shader

# Settings
SCR_WIDTH = 800
SCR_HEIGHT = 600


def framebuffer_size_callback(window, width, height):
    if width != 0 and height != 0:
        width = width
        height = height
        glViewport(0, 0, width, height)


def create_v_array():
    vertexArray = []
    indexArray = []

    for x in range(-100, 102, 2):
        # To draw lines across x axis from z = -1 to z = 1
        vertexArray.append(glm.vec3(x / 100.0, 0.0, -1.0))  # Vertex position 1
        vertexArray.append(glm.vec3(1.0, 1.0, 1.0))  # color for v1
        vertexArray.append(glm.vec3(x / 100.0, 0.0, 1.0))  # Vertex position 2
        vertexArray.append(glm.vec3(1.0, 1.0, 1.0))  # color for v2

    for z in range(-100, 102, 2):
        # To draw lines across z axis from x = -1 to x = 1
        vertexArray.append(glm.vec3(-1.0, 0.0, z / 100.0))  # Vertex position 1
        vertexArray.append(glm.vec3(1.0, 1.0, 1.0))  # color for v1
        vertexArray.append(glm.vec3(1.0, 0.0, z / 100.0))  # Vertex position 2
        vertexArray.append(glm.vec3(1.0, 1.0, 1.0))  # color for v2

    for i in range(10000):
        indexArray.append(i)

    vao = GLuint()
    vbo = GLuint()
    ebo = GLuint()

    vertexArray = np.array(vertexArray, dtype=np.float32)
    indexArray = np.array(indexArray, dtype=np.float32)

    # Bind vao
    glGenVertexArrays(1, vao)
    glBindVertexArray(vao)

    # Upload Vertex Buffer (VBO) to the GPU, keep a reference to it (vertexBufferObject)
    glGenBuffers(1, vbo)
    glBindBuffer(GL_ARRAY_BUFFER, vbo)
    glBufferData(GL_ARRAY_BUFFER, vertexArray.nbytes, vertexArray, GL_STATIC_DRAW)

    # Upload Index Buffer (EBO) to the GPU, keep a reference to it (elementBufferObject)
    glGenBuffers(1, ebo)
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexArray.nbytes, indexArray, GL_STATIC_DRAW)

    # Position
    glVertexAttribPointer(0,
                          3,
                          GL_FLOAT,
                          GL_FALSE,
                          24,
                          None
                          )
    glEnableVertexAttribArray(0)

    # Color
    glVertexAttribPointer(1,
                          3,
                          GL_FLOAT,
                          GL_FALSE,
                          24,
                          ctypes.c_void_p(12)
                          )
    glEnableVertexAttribArray(1)

    glBindBuffer(GL_ARRAY_BUFFER, 0)
    glBindVertexArray(0)

    return vao


def main():
    # Initialize the library
    #glfw.glewExperimental = GL_TRUE

    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(SCR_WIDTH, SCR_HEIGHT, "OpenGL", None, None)
    if not window:
        glfw.terminate()
        return

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

    #glEnable(GL_DEPTH_TEST)
    #glDepthFunc(GL_LESS)

    shader = Shader.Shader("VertexShader.vsh", "FragmentShader.fsh")
    vao = create_v_array()
    glUseProgram(shader.ID)

    # Loop until the user closes the window
    while not glfw.window_should_close(window):
        glClearColor(0.2, 0.3, 0.3, 1.0)
        glClear(GL_COLOR_BUFFER_BIT)

        glUseProgram(shader.ID)
        glBindVertexArray(vao)

        model = glm.mat4(1)
        view = glm.mat4(1)

        model = glm.rotate(model, glm.radians(15.0), glm.vec3(1.0, 0.0, 0.0))
        view = glm.translate(view, glm.vec3(0.0, 0.0, -1.0))
        projection = glm.perspective(glm.radians(45.0), (SCR_WIDTH/SCR_HEIGHT), 0.1, 100.0)

        shader.set_mat4("model", model)
        shader.set_mat4("view", view)
        shader.set_mat4("projection", projection)

        glBindVertexArray(vao)
        glDrawElements(GL_LINES, 20000, GL_UNSIGNED_INT, None)

        glfw.swap_buffers(window)
        glfw.poll_events()

    glfw.terminate()


if __name__ == "__main__":
    main()

自定义着色器class:

class Shader:

    def __init__(self, vertex_path, fragment_path):
        vertex_code = get_file_content(vertex_path)
        fragment_code = get_file_content(fragment_path)

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

        result = glGetShaderiv(vertex, GL_COMPILE_STATUS)
        if not (result):
            print("Vertex shader ERROR!")
            raise RuntimeError(glGetShaderInfoLog(vertex))

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

        result2 = glGetShaderiv(fragment, GL_COMPILE_STATUS)
        if not (result2):
            print("Fragment shader ERROR!")
            raise RuntimeError(glGetShaderInfoLog(vertex))

        self.ID = glCreateProgram()
        glAttachShader(self.ID, vertex)
        glAttachShader(self.ID, fragment)

        glLinkProgram(self.ID)

        success = glGetProgramiv(self.ID, GL_LINK_STATUS)
        if not success:
            print("gad darn")
            infolog = glGetProgramInfoLog(self.ID)
            print("ERROR::SHADER::PROGRAM::LINKING_FAILED\n", infolog)

        glDeleteShader(vertex)
        glDeleteShader(fragment)

    def set_mat4(self, name, matrix):
        glUniformMatrix4fv(glGetUniformLocation(self.ID, name), 1, GL_FALSE, glm.value_ptr(matrix))

    def use(self):
        glUseProgram(self.ID)

# Helper Function
def get_file_content(file):
    with open(file) as f:
        content = f.read()
    return content

glsl 文件:

顶点着色器:

#version 330 core

layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;

out vec3 vertexColor;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0);
    vertexColor = aColor;
}

片段着色器:

#version 330 core

in vec3 vertexColor;
out vec4 FragColor;

void main()
{
    FragColor = vec4(vertexColor.r, vertexColor.g, vertexColor.b, 1.0f);
}

索引的类型必须是整数,不能是浮点数:

indexArray = np.array(indexArray, dtype=np.float32)

indexArray = np.array(indexArray, dtype=np.uint32)