我是一个新的openGL程序员,到目前为止我已经取得了相当大的进步。我用C#编程,所以没有太多的例子,我的最后一项任务就是用每一帧的新数据更新一个VBO。我找不到任何例子。我也是新来的矢量。这是基本代码和我尝试过的。我正在使用opengl4csharp和freeglut库。我最初在呈现回调之外设置了一个简单的金字塔,如下所示:
program = new ShaderProgram(VertexShader, FragmentShader)
// set the view and projection matrix for pyramid
program.Use();
program["projection_matrix"].SetValue(Matrix4.CreatePerspectiveFieldOfView(0.45f, (float)width / height, 0.1f, 1000f));
program["view_matrix"].SetValue(Matrix4.LookAt(new Vector3(0, 0, 10), Vector3.Zero, new Vector3(0, 1, 0)));
// create a pyramid with vertices and colors
pyramid = new VBO<Vector3>(new Vector3[] {
new Vector3(0, 0.5f, 0), new Vector3(-0.5f, -0.5f, 0.5f), new Vector3(0.5f, -0.5f, 0.5f), // front face
new Vector3(0, 0.5f, 0), new Vector3(0.5f, -0.5f, 0.5f), new Vector3(0.5f, -0.5f, -0.5f), // right face
new Vector3(0, 0.5f, 0), new Vector3(0.5f, -0.5f, -0.5f), new Vector3(-0.5f, -0.5f, -0.5f), // back face
new Vector3(0, 0.5f, 0), new Vector3(-0.5f, -0.5f, -0.5f), new Vector3(-0.5f, -0.5f, 0.5f) }); // left face
pyramidColor = new VBO<Vector3>(new Vector3[] {
new Vector3(0.5f, 0, 0), new Vector3(0, 0.5f, 0), new Vector3(0, 0, 0.5f),
new Vector3(0.5f, 0, 0), new Vector3(0, 0, 0.5f), new Vector3(0, 0.5f, 0),
new Vector3(0.5f, 0, 0), new Vector3(0, 0.5f, 0), new Vector3(0, 0, 0.5f),
new Vector3(0.5f, 0, 0), new Vector3(0, 0, 0.5f), new Vector3(0, 0.5f, 0) });
pyramidTriangles = new VBO<int>(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }, BufferTarget.ElementArrayBuffer);然后在OnRender回调中执行以下操作:
// use our vertex shader program
Gl.UseProgram(program);
// bind the vertex positions, colors and elements of the pyramid
program["model_matrix"].SetValue(Matrix4.CreateRotationY(yangle) * Matrix4.CreateRotationX(xangle));
Gl.BindBufferToShaderAttribute(pyramid, program, "vertexPosition");
Gl.BindBufferToShaderAttribute(pyramidColor, program, "vertexColor");
Gl.BindBuffer(pyramidTriangles);
Gl.DrawElements(BeginMode.Triangles, pyramidTriangles.Count, DrawElementsType.UnsignedInt, IntPtr.Zero);这工作很好,然后我有一个漂亮的金字塔显示器。现在,在实际的应用中,它将有更多的单一金字塔,这将是实时更新。这就是我的问题所在。我不明白如何正确地更新VBO。这就是我在OnRender回调中尝试过的。这只是一个改变了第一个顶点的例子
Gl.UseProgram(program);
pyramid = new VBO<Vector3>(new Vector3[] {
new Vector3(0, 0.5f, 0), new Vector3(-0.5f, -0.5f, 0.5f), new Vector3(0.5f, -0.5f, 0.5f), // front face
new Vector3(0, 0.5f, 0), new Vector3(0.5f, -0.5f, 0.5f), new Vector3(0.5f, -0.5f, -0.5f), // right face
new Vector3(0, 0.5f, 0), new Vector3(0.5f, -0.5f, -0.5f), new Vector3(-0.5f, -0.5f, -0.5f), // back face
new Vector3(0, 0.5f, 0), new Vector3(-0.5f, -0.5f, -0.5f), new Vector3(-0.5f, -0.5f, 0.5f) }); // left face
// bind the vertex positions, colors and elements of the pyramid
program["model_matrix"].SetValue(Matrix4.CreateRotationY(yangle) * Matrix4.CreateRotationX(xangle));
Gl.BindBufferToShaderAttribute(pyramid, program, "vertexPosition");
Gl.BindBufferToShaderAttribute(pyramidColor, program, "vertexColor");
Gl.BindBuffer(pyramidTriangles);
Gl.DrawElements(BeginMode.Triangles, pyramidTriangles.Count, DrawElementsType.UnsignedInt, IntPtr.Zero);但是,当我退出程序时,我得到了一个系统访问冲突异常。如果不释放其中一个顶点对象,则会出现相同的错误。然而,在这种情况下,我确实调用dispose。这是否意味着每次我使用这个的时候我都需要呼叫dispose?我听说过一些关于glMapBuffers的事情,但是找不到任何例子。谢谢你的帮助。
发布于 2017-01-08 10:18:39
您创建了新的VBO对象,而不是更新现有的对象。所以VBO们在视频卡上堆积如山。
如果库的文档不好,那么查看它的源代码是个好主意。该图书馆主要由三部分组成:
所以它是VBO类,它将缓冲区上传到GPU。我们可以期望您可以使用相同的类修改缓冲区。这就是:https://github.com/giawa/opengl4csharp/blob/master/OpenGL/Constructs/VBO.cs#L129
VBO对象的BufferSubData方法可用于修改缓冲区。示例:
Vector3[] vertexBuffer = new Vector3[] {
new Vector3(0, 0.5f, 0), new Vector3(-0.5f, -0.5f, 0.5f), new Vector3(0.5f, -0.5f, 0.5f), // front face
new Vector3(0, 0.5f, 0), new Vector3(0.5f, -0.5f, 0.5f), new Vector3(0.5f, -0.5f, -0.5f), // right face
new Vector3(0, 0.5f, 0), new Vector3(0.5f, -0.5f, -0.5f), new Vector3(-0.5f, -0.5f, -0.5f), // back face
new Vector3(0, 0.5f, 0), new Vector3(-0.5f, -0.5f, -0.5f), new Vector3(-0.5f, -0.5f, 0.5f) }; // left face
pyramid.BufferSubData(vertexBuffer);https://stackoverflow.com/questions/41525954
复制相似问题