c#opentk AccessViolationException

c#opentk AccessViolationException,c#,opengl,textures,access-violation,opentk,C#,Opengl,Textures,Access Violation,Opentk,我目前是一名学生,正在编写一个游戏。为此,我在开始时将纹理加载到程序中,并在需要时进行渲染。 到目前为止它确实有效,但有时我会遇到AccessViolationException。我已经尝试了很多我在互联网上找到的东西,但是没有任何效果。这个错误确实令人沮丧,因为它发生得不规则。有时在20秒后崩溃,有时持续8分钟。 将每秒帧数限制为20有帮助,我注意到它会崩溃,当有很多对象要渲染时,所以它不会经常崩溃,但它仍然会崩溃 以下是我在开始时加载纹理的代码: Dictionary<

我目前是一名学生,正在编写一个游戏。为此,我在开始时将纹理加载到程序中,并在需要时进行渲染。
到目前为止它确实有效,但有时我会遇到
AccessViolationException
。我已经尝试了很多我在互联网上找到的东西,但是没有任何效果。这个错误确实令人沮丧,因为它发生得不规则。有时在20秒后崩溃,有时持续8分钟。
将每秒帧数限制为20有帮助,我注意到它会崩溃,当有很多对象要渲染时,所以它不会经常崩溃,但它仍然会崩溃

以下是我在开始时加载纹理的代码:

        Dictionary<string, Texture> ddc = new Dictionary<string, Texture>();
        DirectoryInfo img_dir = new DirectoryInfo("./Resources/drawable/");
        foreach(FileInfo file in img_dir.GetFiles())
        {
            string name = file.Name.Substring(0, file.Name.Length - 4);
            if (name.StartsWith("spr_"))
            {
                Bitmap bmp = new Bitmap(file.FullName);
                int texture = GL.GenTexture();

                BitmapData bmp_data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                GL.BindTexture(TextureTarget.Texture2D, texture);

                        GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmp.Width, bmp.Height, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bmp_data.Scan0);
                bmp.UnlockBits(bmp_data);

                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Clamp);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Clamp);


                ddc.Add(name.Substring(4), new Texture()
                {
                    TextureID = texture,
                    Rows = (bmp.Height/64),
                    Columns = (bmp.Width/64)
                });
            }
        }
        return ddc;

我希望有人能帮助我

我对C#及其作用域规则不太熟悉,但我的第一个预感是,在调用
DrawArrays
之前,您为
VertexInter
TexCoordPointer
new float[]{…}
)创建的原位数组将被释放。
…指针
函数不会创建传递给它们的数据的内部副本;它们存储指向您传递给它们的某个内存区域的指针,该指针将仅在
Draw…
调用时解除引用

如果是这种情况,则必须在绘图之前将阵列保持在范围内:

public void batchDraw(int x, int y, int w, int h, float tx, float ty, float tw, float th)
{
    float[] vpos = new float[] { x, y, x + w, y, x, y + h, x + w, y + h };
    float[] vtxc = new float[] { tx, ty + th, tx + tw, ty + th, tx , ty, tx + tw, ty };
    GL.VertexPointer(2, VertexPointerType.Float, 0, vpos);
    GL.EnableClientState(ArrayCap.VertexArray);
    GL.TexCoordPointer(2, TexCoordPointerType.Float, 0, vtxc);
    GL.EnableClientState(ArrayCap.TextureCoordArray);

    //Sometimes Error at DrawArrays: AccessViolationException
    GL.DrawArrays(PrimitiveType.TriangleStrip, 0, 4);

    GL.DisableClientState(ArrayCap.VertexArray);
    GL.DisableClientState(ArrayCap.TextureCoordArray);
}
请注意,您在那里所做的全部工作都使用了旧的固定函数管道,并且分配需要小数组。这是直接通过即时模式调用(glTexCoord、glVertex)可能执行得更好的情况之一


当然,您首先不应该使用老式的OpenGL。

几乎正确。这会增加工作执行的可能性,但并不健壮:垃圾收集器可以自由移动托管内存,从而在绘图时导致无效指针。解决方案是固定受管阵列@安迪
public void batchDraw(int x, int y, int w, int h, float tx, float ty, float tw, float th)
{
    float[] vpos = new float[] { x, y, x + w, y, x, y + h, x + w, y + h };
    float[] vtxc = new float[] { tx, ty + th, tx + tw, ty + th, tx , ty, tx + tw, ty };
    GL.VertexPointer(2, VertexPointerType.Float, 0, vpos);
    GL.EnableClientState(ArrayCap.VertexArray);
    GL.TexCoordPointer(2, TexCoordPointerType.Float, 0, vtxc);
    GL.EnableClientState(ArrayCap.TextureCoordArray);

    //Sometimes Error at DrawArrays: AccessViolationException
    GL.DrawArrays(PrimitiveType.TriangleStrip, 0, 4);

    GL.DisableClientState(ArrayCap.VertexArray);
    GL.DisableClientState(ArrayCap.TextureCoordArray);
}