'System.AccessViolationException' 发生在 OpenTK.dll 加载纹理时

'System.AccessViolationException' occurred in OpenTK.dll when loading a texture

所以我目前正在使用 OpenTK 在 C# 中开发 3D OpenGL 游戏引擎,但是我 运行 在添加纹理加载时遇到了问题

我收到这个错误

An unhandled exception of type 'System.AccessViolationException' occurred in OpenTK.dll Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

我不是 100% 确定为什么我会收到 "memory corruption" 错误,我不应该,我以前使用过此代码,但我现在才收到此错误。

这是我的代码:

`

    public static int UploadTexture(string pathname)
    {
        // Create a new OpenGL texture object
        int id = GL.GenTexture(); //THIS IS THE LINE VISUAL STUDIO POINTS OUT WHEN I GET THE ERROR

        // Select the new texture
        GL.BindTexture(TextureTarget.Texture2D, id);

        // Load the image
        Bitmap bmp = new Bitmap(pathname);

        // Lock image data to allow direct access
        BitmapData bmp_data = bmp.LockBits(
                new Rectangle(0, 0, bmp.Width, bmp.Height),
                System.Drawing.Imaging.ImageLockMode.ReadOnly,
                System.Drawing.Imaging.PixelFormat.Format32bppArgb);

        // Import the image data into the OpenGL texture
        GL.TexImage2D(TextureTarget.Texture2D,
                      0,
                      PixelInternalFormat.Rgba,
                      bmp_data.Width,
                      bmp_data.Height,
                      0,
                      OpenTK.Graphics.OpenGL.PixelFormat.Bgra,
                      OpenTK.Graphics.OpenGL.PixelType.UnsignedByte,
                      bmp_data.Scan0);

        // Unlock the image data
        bmp.UnlockBits(bmp_data);

        // Configure minification and magnification filters
        GL.TexParameter(TextureTarget.Texture2D,
                TextureParameterName.TextureMinFilter,
                (int)TextureMinFilter.Linear);
        GL.TexParameter(TextureTarget.Texture2D,
                TextureParameterName.TextureMagFilter,
                (int)TextureMagFilter.Linear);

        // Return the OpenGL object ID for use
        return id;
    }

`

像您这样的问题通常与越界内存访问有关。虽然 C# 和 CLI 提供内存安全的执行环境,但 OpenGL 本身是不安全的 API,除非您使用包装器在调用 OpenGL 之前执行某些验证,否则这可能会发生。

那么最有可能导致您遇到麻烦的原因是什么?为什么 OpenGL 会越界访问内存?一个字:对齐!

默认情况下,OpenGL 假定图像行与 4 字节边界对齐。假设您的实际图像数据行对齐到 1 字节边界,您的图像宽度是 3 的倍数但既不是 2 也不是 4 那么 OpenGL 将读取图像高度乘以 3 字节超出图像实际占用的内存区域。

解决方案很简单:告诉 OpenGL 图像数据的对齐方式。对于 BMP 部分,它恰好是 1 字节对齐。在调用 glTexImage2D 之前添加:

GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);