为什么 opengl 不显示 glfw 和 glbuffersubdata

why opengl show nothing with glfw and glbuffersubdata

我是 OpenGL 新手。 我想使用 glbuffersubdata 因为我有很多片段 data.If 我不使用 glbuffersubdata,会有很多 vbo。 但是当我使用 glbuffersubdata 时,我不知道为什么什么都没有。 你在我的代码中看到任何问题吗?有没有更好的方法来显示片段数据?

下面是我的代码。

class Param(object):
    vertex_src = """
    # version 330
    layout(location = 0) in vec3 a_position;
    layout(location = 1) in vec3 a_color;
    uniform mat4 model;
    uniform mat4 projection;
    uniform mat4 view;
    out vec3 v_color;
    void main()
    {
        gl_Position = projection * view * model * vec4(a_position, 1.0);
        v_color = a_color;
    }
    """  # vec4(a_position, 1); 

    fragment_src = """
    # version 330
    in vec3 v_color;
    out vec4 out_color;
    void main()
    {
        out_color = vec4(v_color, 1.0);   
    }
    """
    width = 1280
    height = 720
    eye = glm.vec3(0, 0, 3) 
    target = glm.vec3(0, 0, 0)  
    up = glm.vec3(0, 1, 0)  
    near = 0.1
    far = 100
    radians = glm.radians(45)
    projection = glm.perspective(radians, width / height, near, far)
    view = glm.lookAt(eye, target, up)
    pan_start = None
    orbit_start = None
    pivot_world = None
    add = True


if not glfw.init():
    print("Cannot initialize GLFW")
    exit()
window = glfw.create_window(Param.width, Param.height, "Hello Triangle", None, None)
if not window:
    glfw.terminate()
glfw.window_hint(glfw.DOUBLEBUFFER, GL_TRUE)

glfw.make_context_current(window)

vao = glGenVertexArrays(1)
vbo = glGenBuffers(1)
ebo = glGenBuffers(1)

result = [
    np.array([0.220, 0.32, 0.32, 1.0, 0.0, 0.0, 0.32, 0.22, 0.32, 1.0, 0.0, 0.0,
              0.320, 0.22, 0.22, 1.0, 0.0, 0.0, 0.22, 0.32, 0.22, 1.0, 0.0, 0.0], dtype=np.float32),
    np.array([-0.955, -0.8557, -0.85554, 0.0, 1.0, 0.0, -0.8555, -0.955, -0.855, 0.0, 1.0, 0.0,
              -0.8557, -0.9573, -0.95553, 0.0, 1.0, 0.0, -0.955, -0.855, -0.955, 0.0, 1.0, 0.0], dtype=np.float32),
    np.array([-0.063320, 0.039, 0.036, 0.0, 0.0, 1.0, 0.036, -0.0630, 0.03679, 0.0, 0.0, 1.0,
              0.036679, -0.063, -0.0630, 0.0, 0.0, 1.0, -0.060, 0.03679, -0.063, 0.0, 0.0, 1.0], dtype=np.float32)
]
ins = [np.array([2, 3, 1, 3, 0, 1], dtype=np.uint32), np.array([2, 3, 1, 3, 0, 1], dtype=np.uint32),
       np.array([2, 3, 1, 3, 0, 1], dtype=np.uint32)]

glBindVertexArray(vao)
glBindBuffer(GL_ARRAY_BUFFER, vbo)
result_ = sum(len(i) for i in result) * 4
glBufferData(GL_ARRAY_BUFFER, result_, None, GL_STATIC_DRAW)
offset = 0
for i in result:
    arr = (ctypes.c_float * i.nbytes)(*i)
    glBufferSubData(GL_ARRAY_BUFFER, offset, i.nbytes, arr)
    offset += i.nbytes

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo)
ins_ = sum(len(i) for i in ins) * 4
glBufferData(GL_ELEMENT_ARRAY_BUFFER, ins_, None, GL_STATIC_DRAW)
offset = 0
for i in ins:
    arr = (ctypes.c_float * i.nbytes)(*i)
    glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, i.nbytes, arr)
    offset += i.nbytes

glEnableVertexAttribArray(0)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0))
glEnableVertexAttribArray(1)
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0))

program = compileProgram(compileShader(Param.vertex_src, GL_VERTEX_SHADER),
                         compileShader(Param.fragment_src, GL_FRAGMENT_SHADER))
glUseProgram(program)
glEnable(GL_DEPTH_TEST)

glUniformMatrix4fv(glGetUniformLocation(program, 'projection'), 1, GL_FALSE, glm.value_ptr(Param.projection))
glUniformMatrix4fv(glGetUniformLocation(program, 'view'), 1, GL_FALSE, glm.value_ptr(Param.view))
mat = glm.mat4()
glUniformMatrix4fv(glGetUniformLocation(program, 'model'), 1, GL_FALSE, glm.value_ptr(mat))

while not glfw.window_should_close(window):
    glUniformMatrix4fv(glGetUniformLocation(program, 'projection'), 1, GL_FALSE,
                       glm.value_ptr(Param.projection))
    glUniformMatrix4fv(glGetUniformLocation(program, 'view'), 1, GL_FALSE, glm.value_ptr(Param.view))
    glClearColor(0.2, 0.3, 0.3, 1.0)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    glBindVertexArray(vao)
    glDrawElements(GL_TRIANGLE_STRIP, sum([len(i) for i in ins]), GL_UNSIGNED_INT, None)

    glfw.poll_events()
    glfw.swap_buffers(window)
glfw.terminate()

index buffer中的数据需要是完整的并且对应draw call中指定的类型(GL_UNSIGNED_INT):

arr = (ctypes.c_float * i.nbytes)(*i)

arr = (ctypes.c_uint32 * i.nbytes)(*i)
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, i.nbytes, arr)

第二个四边形的索引必须从 4 到 7,第三个四边形的索引必须从 8 到 11。将起始索引 (4*i) 添加到 sub 数组的索引中-索引:

offset = 0
for i, sub_arr in enumerate(ins):
    arr = (ctypes.c_uint32 * sub_arr.nbytes)(*(sub_arr + 4*i))
    glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, sub_arr.nbytes, arr)
    offset += sub_arr.nbytes

glVertexAttribPointerstride 参数指定连续通用顶点属性之间的字节偏移量。 顶点缓冲区由具有 6 个分量(x、y、z、r、g、b)的元组组成。 因此 strids 参数必须是 6*4 并且颜色属性的 offset3*4:

glEnableVertexAttribArray(0)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6*4, ctypes.c_void_p(0))
glEnableVertexAttribArray(1)
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*4, ctypes.c_void_p(3*4))