乔格。 OpenGL。如何更新 VBO?
JOGL. OpenGL. How to update a VBO?
想法 - 通过代码画一些线:
gl.glBindBuffer(GL_ARRAY_BUFFER, line.getVertexOpenGLArray());
gl.glVertexAttribPointer(VERTEX_INDEX, 3, GL_FLOAT, false, 0, 0);
gl.glEnableVertexAttribArray(VERTEX_INDEX);
gl.glEnable(GL_DEPTH_TEST);
gl.glDepthFunc(GL_LEQUAL);
gl.glFrontFace(GL_CCW);
gl.glDrawArrays(GL_LINES, 0, line.getVertices().length);
当line.getVertexOpenGLArray()
returns VBO 对象索引生成时:
FloatBuffer vertBuf = Buffers.newDirectFloatBuffer(pvalues);
gl.glBufferData(GL_ARRAY_BUFFER, vertBuf.limit() * 4, vertBuf, GL_STATIC_DRAW);
pvalues 是 float[6] {x1,y1,z1,x2,y2,z2}
包含这条线的两个顶点的坐标。
然后我尝试通过以下方式更改 VBO 中的第二个顶点:
FloatBuffer line_buf = Buffers.newDirectFloatBuffer(new_vertexes);
gl.glBufferSubData(GL_ARRAY_BUFFER, 0, line_buf.limit() * 4, line_buf);
Buffer f = Buffers.newDirectFloatBuffer(line_vertexes);
gl.glGetBufferSubData(GL_ARRAY_BUFFER, 0, line_buf.limit() * 4, f);
System.out.println("Vertexes: " +
((FloatBuffer) f).get() + ", "+
((FloatBuffer) f).get() + ", "+
((FloatBuffer) f).get() + ", "+
((FloatBuffer) f).get() + ", "+
((FloatBuffer) f).get() + ", "+
((FloatBuffer) f).get());
并报告值已成功更改。但是当我渲染下一帧时,我看到那条线由旧的顶点坐标放置。
我尝试使用 gl.glInvalidateBufferData(vbo[VERTEX_INDEX]);但结果相同。
有缓存什么的吗?
When line.getVertexOpenGLArray()
returns the VBO object index that was generated by:
FloatBuffer vertBuf = Buffers.newDirectFloatBuffer(pvalues);
gl.glBufferData(GL_ARRAY_BUFFER, vertBuf.limit() * 4, vertBuf, GL_STATIC_DRAW);
此代码不会生成 “VBO 对象索引”。
glGenBuffers
保留名称以用作缓冲区对象。
glBufferData
创建并初始化缓冲区对象的数据存储。
因此,当调用 gl.glBufferData(...)
时,缓冲区数据将被销毁、重新创建和初始化。这会导致缓冲区数据的更改丢失。
这只需在缓冲区初始化时执行一次,而不是在每一帧中执行。
想法 - 通过代码画一些线:
gl.glBindBuffer(GL_ARRAY_BUFFER, line.getVertexOpenGLArray());
gl.glVertexAttribPointer(VERTEX_INDEX, 3, GL_FLOAT, false, 0, 0);
gl.glEnableVertexAttribArray(VERTEX_INDEX);
gl.glEnable(GL_DEPTH_TEST);
gl.glDepthFunc(GL_LEQUAL);
gl.glFrontFace(GL_CCW);
gl.glDrawArrays(GL_LINES, 0, line.getVertices().length);
当line.getVertexOpenGLArray()
returns VBO 对象索引生成时:
FloatBuffer vertBuf = Buffers.newDirectFloatBuffer(pvalues);
gl.glBufferData(GL_ARRAY_BUFFER, vertBuf.limit() * 4, vertBuf, GL_STATIC_DRAW);
pvalues 是 float[6] {x1,y1,z1,x2,y2,z2}
包含这条线的两个顶点的坐标。
然后我尝试通过以下方式更改 VBO 中的第二个顶点:
FloatBuffer line_buf = Buffers.newDirectFloatBuffer(new_vertexes);
gl.glBufferSubData(GL_ARRAY_BUFFER, 0, line_buf.limit() * 4, line_buf);
Buffer f = Buffers.newDirectFloatBuffer(line_vertexes);
gl.glGetBufferSubData(GL_ARRAY_BUFFER, 0, line_buf.limit() * 4, f);
System.out.println("Vertexes: " +
((FloatBuffer) f).get() + ", "+
((FloatBuffer) f).get() + ", "+
((FloatBuffer) f).get() + ", "+
((FloatBuffer) f).get() + ", "+
((FloatBuffer) f).get() + ", "+
((FloatBuffer) f).get());
并报告值已成功更改。但是当我渲染下一帧时,我看到那条线由旧的顶点坐标放置。
我尝试使用 gl.glInvalidateBufferData(vbo[VERTEX_INDEX]);但结果相同。
有缓存什么的吗?
When
line.getVertexOpenGLArray()
returns the VBO object index that was generated by:FloatBuffer vertBuf = Buffers.newDirectFloatBuffer(pvalues); gl.glBufferData(GL_ARRAY_BUFFER, vertBuf.limit() * 4, vertBuf, GL_STATIC_DRAW);
此代码不会生成 “VBO 对象索引”。
glGenBuffers
保留名称以用作缓冲区对象。
glBufferData
创建并初始化缓冲区对象的数据存储。
因此,当调用 gl.glBufferData(...)
时,缓冲区数据将被销毁、重新创建和初始化。这会导致缓冲区数据的更改丢失。
这只需在缓冲区初始化时执行一次,而不是在每一帧中执行。