I am a new openGL programmer and I have gotten pretty far so far. I program in C# so there are not a lot of examples out there and my final task to update a VBO with new data each frame. I cannot find any examples. I'm also new to Vectors as well. So here is the basic code and what I have tried. I am using opengl4csharp and freeglut libraries. I initially set up a simple pyramid outside of the render callback as follows:
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);
I then execute the following in OnRender callback:
// 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);
This works great I then have a nice pyramid display. Now in the real application it will have a lot more than the single pyramid and this will be updated in real time. This is where I have my issue. I do not understand how to update the VBO properly. This is what I have tried in the OnRender callback. This is just an example with the very first vertex changed
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);
This also works however I when I exit the program I get a System Access Violation Exception. This is the same error one gets if they do not dispose of one of the vertex objects. However in this case I do call dispose. Does this mean I need to call dispose each time I use this? I aslo heard something about glMapBuffers but can find no examples. Thanks for any help.
You created new VBO objects, instead of updating the existing one. So the VBOs are piling up on the video card.
When the documentation of a library is bad, then it's a good idea to look into its source code. That library consists mainly of 3 parts:
Low level OpenGL bindings: https://github.com/giawa/opengl4csharp/blob/master/OpenGL/Core/GlCore.cs
The code there just call functions from an OpenGL dll.
Higher level functions. For example you mentioned in a comment, that you upload the buffers to the GPU using the BindBufferToShaderAttribute function: https://github.com/giawa/opengl4csharp/blob/master/OpenGL/Core/GlMethods.cs#L600
As you see that function just calls some lower level OpenGL functions. Also notice that it doesn't upload the buffers to the GPU, so that happens somewhere else. (It just marks entries in the buffer for passing them as attributes to the shaders.)
High level classes. For example the VBO class you used in your example: https://github.com/giawa/opengl4csharp/blob/master/OpenGL/Constructs/VBO.cs
Notice that its constructor calls CreateVBO: https://github.com/giawa/opengl4csharp/blob/master/OpenGL/Constructs/VBO.cs#L54
And that CreateVBO method has a call to glBufferData, which I mentioned in my comment: https://github.com/giawa/opengl4csharp/blob/master/OpenGL/Core/GlMethods.cs#L342
So it is the VBO class, which uploads the buffer to the GPU. We can expect that you can modify the buffers with the same class. And there it is: https://github.com/giawa/opengl4csharp/blob/master/OpenGL/Constructs/VBO.cs#L129
The BufferSubData method of the VBO object can be used for modifying the buffers. Example: