首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >更新openGL VBO

更新openGL VBO
EN

Stack Overflow用户
提问于 2017-01-07 20:07:57
回答 1查看 1K关注 0票数 0

我是一个新的openGL程序员,到目前为止我已经取得了相当大的进步。我用C#编程,所以没有太多的例子,我的最后一项任务就是用每一帧的新数据更新一个VBO。我找不到任何例子。我也是新来的矢量。这是基本代码和我尝试过的。我正在使用opengl4csharp和freeglut库。我最初在呈现回调之外设置了一个简单的金字塔,如下所示:

代码语言:javascript
复制
        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回调中执行以下操作:

代码语言:javascript
复制
        // 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回调中尝试过的。这只是一个改变了第一个顶点的例子

代码语言:javascript
复制
        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的事情,但是找不到任何例子。谢谢你的帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-08 10:18:39

您创建了新的VBO对象,而不是更新现有的对象。所以VBO们在视频卡上堆积如山。

如果库的文档不好,那么查看它的源代码是个好主意。该图书馆主要由三部分组成:

  1. 低级别OpenGL绑定:https://github.com/giawa/opengl4csharp/blob/master/OpenGL/Core/GlCore.cs 那里的代码只是从一个OpenGL dll调用函数。
  2. 更高级别的功能。例如,您在注释中提到,您使用BindBufferToShaderAttribute函数:https://github.com/giawa/opengl4csharp/blob/master/OpenGL/Core/GlMethods.cs#L600将缓冲区上传到GPU。 如您所见,该函数只调用一些较低级别的OpenGL函数。还请注意,它没有将缓冲区上传到GPU,所以这发生在其他地方。(它只是标记缓冲区中的条目,以便将它们作为属性传递给着色器。)
  3. 高级课程。例如,您在示例中使用的VBO类:https://github.com/giawa/opengl4csharp/blob/master/OpenGL/Constructs/VBO.cs 注意,它的构造函数调用CreateVBO:https://github.com/giawa/opengl4csharp/blob/master/OpenGL/Constructs/VBO.cs#L54 这个CreateVBO方法调用了glBufferData,我在注释中提到了这个调用:https://github.com/giawa/opengl4csharp/blob/master/OpenGL/Core/GlMethods.cs#L342

所以它是VBO类,它将缓冲区上传到GPU。我们可以期望您可以使用相同的类修改缓冲区。这就是:https://github.com/giawa/opengl4csharp/blob/master/OpenGL/Constructs/VBO.cs#L129

VBO对象的BufferSubData方法可用于修改缓冲区。示例:

代码语言:javascript
复制
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);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41525954

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档