Python OpenGL VAO - 如何为顶点和颜色数据使用单独的数组

Python OpenGL VAO - How to use separate arrays for vertex and color data

我很难找到有关如何正确绑定和取消绑定顶点缓冲区对象和颜色缓冲区对象的信息/解释,以及当顶点和颜色数据存储在中时对绘制调用所做的更改单独的数组。

我的工作代码正确地(我希望)创建 VBO,将其绑定到 VAO,并传递顶点数据以使其显示:

from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
import pygame
import numpy as np
import time

vertex_Data = [
    -1.0, -1.0, -1.0,
    -1.0, -1.0, 1.0,
    -1.0, 1.0, 1.0,
    1.0, 1.0, -1.0,
    -1.0,-1.0, -1.0,
    -1.0, 1.0, -1.0,
    1.0, -1.0, 1.0,
    -1.0, -1.0, -1.0,
    1.0, -1.0, -1.0,
    1.0, 1.0, -1.0,
    1.0, -1.0, -1.0,
    -1.0,- 1.0, -1.0,
    -1.0, -1.0, -1.0,
    -1.0, 1.0, 1.0,
    -1.0, 1.0, -1.0,
    1.0, -1.0, 1.0,
    -1.0, -1.0, 1.0,
    -1.0, -1.0, -1.0,
    -1.0, 1.0, 1.0,
    -1.0, -1.0, 1.0,
    1.0, -1.0, 1.0,
    1.0, 1.0, 1.0,
    1.0, -1.0, -1.0,
    1.0, 1.0, -1.0,
    1.0, -1.0, -1.0,
    1.0, 1.0, 1.0,
    1.0,-1.0, 1.0,
    1.0, 1.0, 1.0,
    1.0, 1.0, -1.0,
    -1.0, 1.0, -1.0,
    1.0, 1.0, 1.0,
    -1.0, 1.0, -1.0,
    -1.0, 1.0, 1.0,
    1.0, 1.0, 1.0,
    -1.0, 1.0, 1.0,
    1.0, -1.0, 1.0
]

color_Data = [
    0.583,  0.771,  0.014,
    0.609,  0.115,  0.436,
    0.327,  0.483,  0.844,
    0.822,  0.569,  0.201,
    0.435,  0.602,  0.223,
    0.310,  0.747,  0.185,
    0.597,  0.770,  0.761,
    0.559,  0.436,  0.730,
    0.359,  0.583,  0.152,
    0.483,  0.596,  0.789,
    0.559,  0.861,  0.639,
    0.195,  0.548,  0.859,
    0.014,  0.184,  0.576,
    0.771,  0.328,  0.970,
    0.406,  0.615,  0.116,
    0.676,  0.977,  0.133,
    0.971,  0.572,  0.833,
    0.140,  0.616,  0.489,
    0.997,  0.513,  0.064,
    0.945,  0.719,  0.592,
    0.543,  0.021,  0.978,
    0.279,  0.317,  0.505,
    0.167,  0.620,  0.077,
    0.347,  0.857,  0.137,
    0.055,  0.953,  0.042,
    0.714,  0.505,  0.345,
    0.783,  0.290,  0.734,
    0.722,  0.645,  0.174,
    0.302,  0.455,  0.848,
    0.225,  0.587,  0.040,
    0.517,  0.713,  0.338,
    0.053,  0.959,  0.120,
    0.393,  0.621,  0.362,
    0.673,  0.211,  0.457,
    0.820,  0.883,  0.371,
    0.982,  0.099,  0.879
]



if __name__ == '__main__':

    # create and initialize window
    pygame.init()
    display = (1920, 1080)
    pygame.display.set_mode(display, DOUBLEBUF | OPENGL)

    # set perspective and near and far view limits
    gluPerspective(10, (display[0] / display[1]), 0.1, 500.0)

    # move and rotate world space
    glTranslatef(0, 0, -80)
    glRotatef(-10, 1, 0, 0)

    # Enables Z depth testing
    glEnable(GL_DEPTH_TEST)

    # ____Vertex____

    # Enables capability
    # (capability to enable)
    glEnableClientState(GL_VERTEX_ARRAY)

    # Generates n buffer objects
    # (number of names to generate)
    vertex_buffer_object = glGenBuffers(1)

    # Binds the buffer to a target
    # (target = Vertex Array Object, name of buffer object)
    # GL_ARRAY_BUFFER = vertex attributes
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_object)


    # Copies data into target (currently bound buffer)
    # (Target, size in bites, data, usage)
    glBufferData(GL_ARRAY_BUFFER, len(vertex_Data) * 4, np.array(vertex_Data, dtype="float32"), GL_DYNAMIC_DRAW)

    # defines the array of vertex data
    # (number of coordinates per vertex, data type, stride = offset between end of vertex and start of next, pointer to first coordinate = must be None for python?)
    glVertexPointer(3, GL_FLOAT, 0, None)

    # ____Color____
    # glEnableClientState(GL_COLOR_ARRAY)
    # color_buffer_object = glGenBuffers(1)
    # glBindBuffer(GL_ARRAY_BUFFER, color_buffer_object)
    # glBufferData(GL_ARRAY_BUFFER, len(color_Data) * 4, np.array(color_Data, dtype="float32"), GL_DYNAMIC_DRAW)
    # glBindBuffer(GL_ARRAY_BUFFER, color_buffer_object)
    # glColorPointer(3, GL_FLOAT, 0, None)

    while True:
        # enable event detection for closing the window
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

        # rotate the world space
        glRotatef(-10, 0, 1, 0)

        # clears target buffers
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        # render primitives
        # (type of primitives to be rendered, starting index, number of indices to be rendered)
        glDrawArrays(GL_TRIANGLES, 0, int(len(vertex_Data) / 3))

        # update window and sleep
        pygame.display.flip()
        time.sleep(.1)

我的代码生成了一个旋转的白色立方体,但我没有完全理解 gl 调用是如何相互连接的,因此我不知道如何将第二个缓冲区对象集成到 VAO 或如果这就是我应该打算做的。

根据 gl 文档,我认为我需要启用 GL_COLOR_ARRAY,创建另一个缓冲区对象(它仍会称为 VBO 吗?),将该对象绑定到 VAO,传递颜色数据,并使用 glColorPointer 定义颜色数据数组。但至于那些与现有代码相关的顺序 vertex_Data 以及 when/if 我正在解除约束,我很茫然。

任何帮助或见解将不胜感激。

像为顶点一样创建一个数组缓冲区:

color_buffer_object = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, color_buffer_object)
glBufferData(GL_ARRAY_BUFFER, len(color_Data) * 4, np.array(color_Data, dtype="float32"), GL_DYNAMIC_DRAW)

glColorPointer定义颜色属性数组并启用客户端状态:

glBindBuffer(GL_ARRAY_BUFFER, color_buffer_object)
glColorPointer(3, GL_FLOAT, 0, None)
glEnableClientState(GL_COLOR_ARRAY)

OpenGL 是一个状态引擎。状态保持不变,直到它再次改变。当前数组缓冲区绑定是一个全局状态(用 glBindBuffer(GL_ARRAY_BUFFER, object) 设置)。如果用glVertexPointerglColorPointer指定数组,则必须绑定相应的缓冲区对象。调用此指令时,当前绑定到 GL_ARRAY_BUFFER 目标的缓冲区将关联到固定函数属性(顶点和颜色)。