Mazjuro's picture

AccessViolationException with BufferSubData

I am getting an AccessViolationException when I make a call to BufferSubData, but only sometimes. The code I'm working on is from a tutorial for drawing a triangle and moving it in a circle. I calculate the new position in OnRenderFrame then pass the data to RebindVertexData before my draw code. The triangle will go around a few times, though sometimes not even a full circle, then I get the exception. I have verified that the arrays (_vertexBufferData and newData) are the same size (12) and the values seem reasonable (all between 0 and 1).

 
void BindVertexData()
        {
            GL.GenBuffers(1, out _vertexBufferID);
            GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBufferID);
            GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(_vertexBufferData.Length * Vector4.SizeInBytes), _vertexBufferData, BufferUsageHint.StreamDraw);
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
        }
 
        void RebindVertexData(float[] newData)
        {
            GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBufferID);
            GL.BufferSubData(BufferTarget.ArrayBuffer, new IntPtr(0), new IntPtr(_vertexBufferData.Length * Vector4.SizeInBytes), newData);
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
        }

Any ideas on how to fix this?

Thanks.


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Mazjuro's picture

I continued on with the tutorial and it explains a new way of doing the same thing, which is offsetting the position within the vertex shader instead of updating the buffer. This works perfectly. However, if anyone has any thought on what I was doing wrong before, please let me know.

flopoloco's picture
Quote:

I calculate the new position in OnRenderFrame then pass the data to RebindVertexData

In this case _vertexBufferData.Length must the same or less, otherwise if you exceed the capacity of the buffer your application might likely to crash.

For example if you have only three vertices for a triangle your buffer capacity will be 36 bytes (12 * 3).
But now you will only have 3 vertices available as shape components, however a circle needs much more than 3 vertices.

One solution is to setup your buffer size to hold 100 vertices, this will help you render a circle up to 100 vertices.
Notice that I pass IntPtr.Zero instead of actual data, since any data will be set later on I guess there is no point to set them now.
GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(100 * Vector3.SizeInBytes), IntPtr.Zero, BufferUsageHint.StreamDraw);

Later when you want to draw your shape you would do:

For a triangle
GL.DrawArrays(PrimitiveType.Lines, 0, 3);

For a circle with 50 vertices
GL.DrawArrays(PrimitiveType.Lines, 0, 50);

I hope this helps, if there are any other questions you can tell.