【问题标题】:why opengl show nothing with glfw and glbuffersubdata为什么opengl没有显示glfw和glbuffersubdata
【发布时间】:2021-10-04 21:28:28
【问题描述】:

我是 OpenGL 新手。 我想使用glbuffersubdata,因为我有很多片段数据。如果我不使用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()

【问题讨论】:

    标签: python opengl pyopengl


    【解决方案1】:

    索引缓冲区中的数据需要是整数并且对应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) 添加到子索引数组的索引中:

    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))
    

    【讨论】:

    • 感谢您的回复。有用。但是窗口中只有一个多边形,应该是三个,而且形状很奇怪
    • @wtyork 检查您的索引数组并确保顶点排列正确; openGL 以逆时针顺序(顶点)绘制形状的三角形。
    • @wtyork 第二个四边形的索引需要从 4 到 7,第三个四边形的索引需要从 8 到 11。
    • @Rabbid76 有效,感谢您的回复!
    猜你喜欢
    • 2016-03-30
    • 2019-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-30
    • 2020-06-13
    • 1970-01-01
    相关资源
    最近更新 更多