我使用OpenTK warpper for C#,着色器没有正确运行(我想使用纹理生成顶点置换着色器),所以我假装使用gpu调试器来查看发生了什么。
应用程序非常简单。它只是创建一个游戏窗口,加载着色器,纹理和渲染纹理立方体(所以它工作正常,我发现尝试使用顶点位移的问题)。
我使用gDebugger和AMD CodeXL得到了相同的结果。调试器检测着色器,vbos等,但从未看到分配的纹理。这是没有意义的,因为当我正在运行应用程序时,我看到一个带纹理的立方体在屏幕上旋转,调试器在后面/前面缓冲区上渲染对象。
作为参考,这是纹理加载函数:
int loadImage(Bitmap image,int tex)
{
int texID = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, texID);
System.Drawing.Imaging.BitmapData data = image.LockBits(new System.Drawing.Rectangle(0, 0, image.Width, image.Height),
System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0,
OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
image.UnlockBits(data);
return texID;
}
我正在搜索更多信息,但我无法找到有关此错误的任何内容,我不确定问题是否在包装中,在函数中还是我必须考虑其他内容
修改
似乎问题出现在包装器中,OpenTK.BindTexture与原生glBindTexture不同,因此探查器无法捕获调用,这就是纹理未显示的原因。所以下一步是寻找使用OpenTK进行原生gl调用的方法。
建议的解决方案:
正如我所说,OpenTK包装器的一些功能与原生glCalls不同,当你使用GL.BindTexture,GL.GenTexture等功能时(我想还有更多功能,但我还不知道),OpenTK使用与原始调用不匹配的重载调用,分析器无法捕获它。
它很容易检查,只需使用OpenTK.GenTextures或GL.BindTextures将断点添加到具有这些功能的探查器中,它们永远不会破坏。
现在,解决方案,我正在考虑它,并且结论是使用GetProcAddress函数用本机gl.dll调用替换一些OpenTK调用。
使用分析器中包含的opengl32.dll,我使用与上一个链接相同的结构
static class NativeMethods
{
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
[DllImport("kernel32.dll")]
public static extern bool FreeLibrary(IntPtr hModule);
}
这是在GameWindow类中添加的:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void BindTexture(OpenTK.Graphics.OpenGL.TextureTarget target, int texID);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void GenTexture(int n, int[] arr_text);
这里是新的bindTexture函数:
IntPtr pDll = NativeMethods.LoadLibrary(@"....\opengl32.dll");
IntPtr pAddressOfFunctionToCall = NativeMethods.GetProcAddress(pDll, "glBindTexture");
BindTexture bindTexture = (BindTexture)Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall, typeof(BindTexture));
bindTexture(OpenTK.Graphics.OpenGL.TextureTarget.Texture2D, arr_texture[0]);
现在,如果你在探查器中再次尝试使用断点,它将会破坏glGenTextures和glBindTextures,识别分配的纹理。
我希望它有所帮助。