OpenGL:glDrawElements提供未处理的异常:System.AccessViolationException

时间:2017-03-14 04:35:31

标签: vb.net opengl graphics opentk vertex-buffer

将OpenTK与VB.Net一起使用。

我的渲染方法:

 ' 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()

所有这些函数都是抽象的,并且在其中有原始的gl {whatever}命令。(是的,我无耻地从here复制了代码。)

我的vertexbuffer的绘图代码:

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

这给了我错误:

  

未处理的异常:System.AccessViolationException:尝试读取或写入受保护的内存。这通常表明其他内存已损坏。      在OpenTK.Graphics.OpenGL.GL.DrawElements(PrimitiveType模式,Int32计数,DrawElementsType类型,    Int32指数)      在C:\ Users \ Tushar \ Desktop \ genericgamedev-opentk-intro-master \ vb \ src \ Ver中的VertexBuffer`1.Draw()   texBuffer.vb:第44行

我读到某个地方你需要在每次抽奖后禁用顶点阵列,所以我也这样做但没有用。 我看到了this question,但它也没有帮助我(新手)。

相反,在顶点缓冲区的draw方法中使用glDrawArrays可以完美呈现。但我不想使用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

1 个答案:

答案 0 :(得分:0)

知道了!

感谢这位先生:https://wiki.apache.org/solr/SimpleFacetParameters#Tagging_and_excluding_Filters

glDrawElements要求您指定我的代码缺少的索引缓冲区。所以我创建了一个简单的ibo包装器:

<template>
    <div class="list-group">
        <notifications-item
            v-for="(notification, index) in notifications"
            :notification="notification"
            DeathByAlgorithm="remove"
            :index="index">
            {{ notification.data['text'] }}
        </notifications-item>
    </div>
</template>

<script> export default { data() { return { notifications: notifications.data, } }, methods: { remove(index) { console.log(index); this.notifications.splice(index, 1); } }, mounted() { console.log('Notifications List mounted.') } } </script>

,做了一个字段&#34; indexbuffer&#34;在游戏窗口课上,并启动它:

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

然后绑定并缓冲indexbuffer中的数据。我的最终渲染代码:

indexbuffer = New IndexBuffer({0, 1, 2, 3, 4, 5})

现在一切正常!