【问题标题】:OpenGL - tell vertex shader that VBO has changedOpenGL - 告诉顶点着色器 VBO 已经改变
【发布时间】:2016-07-07 21:06:05
【问题描述】:

我目前正在编写一个需要不断更新我的 VBO 数据的程序。 但是,我发现如果在初始化缓冲区后调用glBindBuffer(GL_ARRAY_BUFFER, 0),窗口会以某种方式自行关闭。 下面是我的代码 sn-p:

 glGenBuffers(1, &vertex_buffer);
 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
 glBufferData(GL_ARRAY_BUFFER, sizeof(pts[0]) * pts.size(), NULL, GL_DYNAMIC_DRAW);
 glBindBuffer(GL_ARRAY_BUFFER, 0); 

 vertex_shader = glCreateShader(GL_VERTEX_SHADER);
 glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL);
 glCompileShader(vertex_shader);

 fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
 glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL);
 glCompileShader(fragment_shader);

 program = glCreateProgram();
 glAttachShader(program, vertex_shader);
 glAttachShader(program, fragment_shader);
 glLinkProgram(program);

 mvp_location = glGetUniformLocation(program, "MVP");
 vpos_location = glGetAttribLocation(program, "vPos");

 glEnableVertexAttribArray(vpos_location);
 glVertexAttribPointer(vpos_location, 3, GL_FLOAT, GL_FALSE,
      sizeof(float) * 3, (void*) 0);

 while(!glfwWindowShouldClose(window)) {
    glUseProgram(program);

    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(pts[0]) * pts.size(), &pts);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    mat4x4_mul(mvp, m, p);

    glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) mvp);

    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
    glDrawArrays(GL_POINTS, 0, pts.size());
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glfwSwapBuffers(window);
    glfwPollEvents();
}

仅供参考:pts 会不断更新。

有没有办法告诉顶点着色器 VBO 数据已更新?

编辑:更新了代码 sn-p

编辑:我应该每次绘制pts.size()个顶点,但屏幕上只出现一个点

【问题讨论】:

  • 为什么在画之前要调用glBindBuffer
  • 我只是按照一些教程说glBindBuffer 会刷新缓冲区中的数据
  • 提供本教程的链接;我怀疑要么您误解了它所说的内容,要么该教程很愚蠢。无论哪种方式,您仍然需要提供minimal reproducible example,而上面的 sn-p 缺少太多东西,无法知道发生了什么。
  • 你不需要告诉顶点着色器。顶点着色器在绘制时使用 VBO 中的任何内容。这是使用 glBufferSubData 上传的任何内容

标签: c++ opengl


【解决方案1】:

就在你的绘图调用之前,你有 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);您需要实际设置属性指针(glVertexAttribPointer())。次要注意是 GlVertexAttribPointer() 将 GL_ARRAY_BUFFER 绑定到指定的属性指针。目前你调用它的地方没有绑定到 GL_ARRAY_BUFFER。

供参考 GLEnum error = glGetError() 将返回openGL的错误状态,是一个强大的调试工具。如果您使用 glew,glewGetErrorString() 将获取任何非零错误代码的字符串,该字符串会更详细地解释错误。

附言对不起,我的写作能力很差。

【讨论】:

  • 大部分都是错误的。顶点属性状态完全独立于活动程序,因此在哪里调用glUseProgram()与它无关。此外,步幅值 12 看起来是正确的,因为如果它由 3 个浮点值组成,那么它就是顶点的字节大小。步幅是一个顶点的 start 和下一个顶点的开始之间的字节数。这个答案中唯一正确的部分是 GL_ARRAY_BUFFER 绑定需要在调用 glVertexAttribPointer() 时有效。
  • 那这就是我要离开的部分
  • 啊我的困惑是你设置步幅为零然后假设顶点是紧密排列的,但零只是表示假设
  • 拨打glBufferSubData()后需要再拨打glVertexAttibPointer()吗?
  • 由于目前屏幕上只有一个点绘制
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-19
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多