'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);
所以我目前正在使用 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);