OpenGL - 告诉顶点着色器 VBO 已经改变
Posted
技术标签:
【中文标题】OpenGL - 告诉顶点着色器 VBO 已经改变【英文标题】:OpenGL - tell vertex shader that VBO has changed 【发布时间】: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 上传的任何内容
【参考方案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()
吗?
由于目前屏幕上只有一个点绘制以上是关于OpenGL - 告诉顶点着色器 VBO 已经改变的主要内容,如果未能解决你的问题,请参考以下文章
是否可以在顶点着色器内持续更改 iPhone OpenGL ES 2.0 上的 VBO 值?