Reputation: 59
Using OpenTK with VB.Net.
My render method:
' clear the screen
GL.ClearColor(Color4.Purple)
GL.Clear(ClearBufferMask.ColorBufferBit Or ClearBufferMask.DepthBufferBit)
' activate shader program and set uniforms
shaderProgram.Use()
projectionMatrix.Set(shaderProgram)
' bind vertex buffer and array objects
vertexBuffer.Bind()
vertexArray.Bind()
' upload vertices to GPU and draw them
vertexBuffer.BufferData()
vertexArray.enableAll()
vertexBuffer.Draw()
' reset state for potential further draw calls (optional, but good practice)
vertexArray.DisableAll()
GL.BindVertexArray(0)
GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0)
GL.BindBuffer(BufferTarget.ArrayBuffer, 0)
GL.UseProgram(0)
' swap backbuffer
SwapBuffers()
All these functions are abstracted and have the original gl{whatever} commands in them.(Yes, I shamelessly copied the code from here.)
My vertexbuffer's draw code:
Public Sub Bind()
' make this the active array buffer
GL.BindBuffer(BufferTarget.ArrayBuffer, Me.handle)
End Sub
Public Sub BufferData()
' copy contained vertices to GPU memory
GL.BufferData(BufferTarget.ArrayBuffer, New IntPtr(Me.vertexSize * Me.count), Me.vertices, BufferUsageHint.StreamDraw)
End Sub
Public Sub Draw()
' draw buffered vertices as triangles
'GL.DrawArrays(PrimitiveType.Triangles, 0, Me.count) <--commented
GL.DrawElements(PrimitiveType.Triangles, 6, DrawElementsType.UnsignedInt, 0) '<--line 44
End Sub
This gives me the error:
Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. at OpenTK.Graphics.OpenGL.GL.DrawElements(PrimitiveType mode, Int32 count, DrawElementsType type, Int32 indices) at VertexBuffer`1.Draw() in C:\Users\Tushar\Desktop\genericgamedev-opentk-intro-master\vb\src\Ver texBuffer.vb:line 44
I read somewhere that you need to disable vertexarrays after each draw so I did that too but no avail. I saw this question but it didn't help me either(newbie).
Instead, using glDrawArrays in the draw method of vertex buffer renders perfectly.But I do not want to use glDrawArrays.
Public Sub Draw()
' draw buffered vertices as triangles
GL.DrawArrays(PrimitiveType.Triangles, 0, count)
' commented line --> GL.DrawElements(PrimitiveType.Triangles, 5, DrawElementsType.UnsignedInt, 0)
End Sub
Upvotes: 2
Views: 1237
Reputation: 59
Got it!
Thanks to this gentleman:DeathByAlgorithm
glDrawElements requires you specify an index buffer, which my code was lacking. So I created a simple ibo wrapper:
Class IndexBuffer
Private handle%
Private data As UInteger()
Sub New(ParamArray Indices As UInteger())
handle = GL.GenBuffer()
data = Indices
End Sub
Public Sub Bind()
GL.BindBuffer(BufferTarget.ElementArrayBuffer, handle)
End Sub
Public Sub BufferData()
GL.BufferData(Of UInteger)(BufferTarget.ElementArrayBuffer, CType(Marshal.SizeOf(New UInteger) * data.Length, System.IntPtr), data, BufferUsageHint.StaticDraw)
End Sub
End Class
,made a field "indexbuffer" in the gamewindow class, and inititalised it:
indexbuffer = New IndexBuffer({0, 1, 2, 3, 4, 5})
then binded and buffered the data in the indexbuffer. My final render code:
' clear the screen
GL.ClearColor(Color4.Purple)
GL.Clear(ClearBufferMask.ColorBufferBit Or ClearBufferMask.DepthBufferBit)
' activate shader program and set uniforms
shaderProgram.Use()
projectionMatrix.Set(shaderProgram)
' bind vertex buffer and array objects
vbo.Bind()
vertexArray.Bind()
indexbuffer.Bind()
' upload vertices to GPU and draw them
vbo.BufferData()
indexbuffer.BufferData()
GL.EnableClientState(ArrayCap.VertexArray) 'works without this line
vbo.Draw()
' reset state for potential further draw calls (optional, but good practice)
GL.BindVertexArray(0)
GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0)
GL.BindBuffer(BufferTarget.ArrayBuffer, 0)
GL.DisableClientState(ArrayCap.VertexArray) 'works without this line
GL.UseProgram(0)
' swap backbuffer
SwapBuffers()
Everything works now!
Upvotes: 2