
VBO + drawArray -> AccessViolation Exception
Posted Thursday, 22 July, 2010 - 15:41 by sjoerd222 inHi
I'm trying to use VBOs and get an AccesVioaltion Exception. Not immediately but after spinning my 3D object around long enough. For me it's not so clear what happens here.
I think the problem lies in the buffer creation or in the rendering function:
public void CreateBuffer(ref float[] vertices_LAB, int vertices_LAB_count) { // Format of array : x,y,z v_LAB = vertices_LAB; v_LAB_count = vertices_LAB_count; GL.GenBuffers(1, out vbo); GL.BindBuffer(BufferTarget.ArrayBuffer, vbo); GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(sizeof(float)*v_LAB.Length),v_LAB ,BufferUsageHint.DynamicDraw); GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(v_LAB_count * 3 * sizeof(float)), v_LAB, BufferUsageHint.DynamicDraw); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); }
public void Render(ref Matrix4 mvpMatrix) { GL.Enable(EnableCap.AlphaTest); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.One); GL.UseProgram(shaderProg.GetId()); GL.EnableClientState(ArrayCap.VertexArray); GL.BindBuffer(BufferTarget.ArrayBuffer, vbo); foreach (int id in dict_attrib.Values) { GL.EnableVertexAttribArray(id); } GL.UniformMatrix4(dict_uniform["u_mvpMatrix"], false, ref mvpMatrix); GL.Uniform1(dict_uniform["u_useTrueColor"], useTrueColor); GL.Uniform1(dict_uniform["u_useTransparence"], useTransparence); GL.Uniform4(dict_uniform["u_color"], pointColor); GL.VertexAttribPointer(dict_attrib["a_position"], 3, VertexAttribPointerType.Float, false, sizeof(float)*3, sizeof(float)*0); GL.VertexPointer(3, VertexPointerType.Float, 3 * sizeof(float), new IntPtr(0)); GL.DrawArrays(BeginMode.Lines, 0, 12); //<--- Hardcoded for testing there are 36 elements in the array, 3d, meaning 12 'items' GL.DisableClientState(ArrayCap.VertexArray); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.Disable(EnableCap.AlphaTest); GL.Disable(EnableCap.Blend); }
I'm also not sure if I need this calls at all:
GL.VertexPointer(3, VertexPointerType.Float, 3 * sizeof(float), new IntPtr(0)); GL.EnableClientState(ArrayCap.VertexArray);
Cause they don't change anything. What I tried is to play around with GL.DrawArrays(BeginMode.Lines, 0, n); and change n to lower numbers like 6, but even then crashes seem to occur. I also investigated the content of the vertices_LAB array in the CreateBuffer function while debugging. He contains 36 values. vertices_LAB_count is 12.
Thank you very much for reading!


Comments
Re: VBO + drawArray -> AccessViolation Exception
Are you sure that v_LAB.Length equals v_LAB_count? If not, that could be causing some problems. I would rely exclusively on v_LAB.Length unless you only wanted to use a subset (in which case you might consider using a start and length). Also, from my understanding, you're immediately overwriting the content that you wrote to your vbo buffer.
EDIT: Missed the last part of your post there, sorry.
If vertices_LAB.Length is 36 and vertices_LAB_count is 12 and you try to draw 12 lines (which require 24 vertices), then you'd likely have an issue (though I'm not sure how it would manifest itself).
Also, these calls are crucially important.
Re: VBO + drawArray -> AccessViolation Exception
Thx for your respond!
GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(sizeof(float)*v_LAB.Length),v_LAB ,BufferUsageHint.DynamicDraw);is the call I use. The other should have been commented out.If vertices_LAB.Length is 36 and vertices_LAB_count is 12 and you try to draw 12 lines (which require 24 vertices), then you'd likely have an issue (though I'm not sure how it would manifest itself).
When I draw 12 lines and each point takes x,y,z (3) then I then whole array of vertices's should have I count of 36 and not 24.
Also, these calls are crucially important.
GL.VertexPointer(3, VertexPointerType.Float, 3 * sizeof(float), new IntPtr(0));
GL.EnableClientState(ArrayCap.VertexArray);
Why are this calls crucial? The crash seems not related to this calls.
I found this example:
But so, what's the big difference to my code except that they use an indices and thus glDrawElements instead of glDrawArray. (Btw. I tried it with glDrawElements with a stupied indices array of 0,1,2,...,11 and the same behavior, crash after spinning around the 3D object long enough.
Re: VBO + drawArray -> AccessViolation Exception
Problem resolved:
various missing GL.DisableVertexAttribArray(id) caused the exception.
are NOT crucial to my understanding. I think that the call is even wrong here as I use vertexAttribPointer INSTEAD.
Important is to call GL.DisableVertexAttribArray(id) after GL.EnableVertexAttribArray(id). Maybe the crashed occurred, cause I mixed VBO with non VBO rendering.
Re: VBO + drawArray -> AccessViolation Exception
You are right, this code is not needed when using generic vertex attributes (VertexAttribPointer). You need to call DisableVertexAttribArray to disable any ids you are not using, otherwise OpenGL will try to read from those (and crash, if the bound VBO has a different layout from what it expected).
Starting with OpenGL 3.x, you can VAOs (Vertex Array Objects) to encapsulate this information and avoid calling Disable/EnableVertexAttribArray for each and every VBO.