我有一个可以在我的所有计算机上运行的OpenGL程序。它是一台配备Vista 64和Radeon HD4850的台式机。问题似乎在于我对SwapBuffers(hdc)的调用。
编译好,然后给我一个例外:
Program.exe中0x00000000处的未处理异常:0xC0000005:Acces违规。
在调用SwapBuffers之前使用VC ++中断显示hdc的值为:
0xfe011734 {unused = ???} CXX0030:错误:无法评估表达式
任何人都知道可能会发生什么?有没有关于SwapBuffers的东西会从一台PC转移到另一台PC?我已经将它用于XP32,XP64和(不同的)Vista64。
while (!quit)
{
if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
{
if (msg.message == WM_QUIT)
quit = true;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
renderFrame(); //draws the scene
SwapBuffers(hdc);
if (GetAsyncKeyState(VK_ESCAPE))
shutdown();
think(); //calculates object positions, etc.
}
问题系统(HD4850)上的驱动程序是最新的。我在另一个带有Radeon HD4870的Vista64系统上运行并编写了该程序,该程序还带有最新的驱动程序。据我所知,这两款显卡的驱动程序几乎相同,因为它们都属于HD48xx系列。出于这个原因,GPU导致问题似乎很奇怪。
无论如何,我错了还是这是一个记忆问题? (访问违规)
另外,如果我删除了对SwapBuffers(hdc)的调用,程序运行似乎很好,虽然没有绘制,当然,因为帧缓冲区从不交换。但它至少是稳定的。
调用堆栈( - >是堆栈ptr):
ATKOGL32.dll!6aef27bc()
opengl32.dll!665edb2d()
opengl32.dll!665f80d1()
gdi32.dll!75e14104()
-> MyProg.exe!WinMain(HINSTANCE__ * hinstance=0x009a0000, HINSTANCE__ * hprevinstance=0x00000000, char * lpcmdline=0x003b4a51, int nshowcmd=1) Line 259 + 0xe bytes
MyProg.exe!__tmainCRTStartup() Line 578 + 0x35 bytes
MyProg.exe!WinMainCRTStartup() Line 400
kernel32.dll!7641e3f3()
ntdll.dll!777dcfed()
ntdll.dll!777dd1ff()
继承集合( - >是下一条要执行的指令):
SwapBuffers(hdc);
009B1B5C mov esi,esp
009B1B5E mov eax,dword ptr [hdc (9BF874h)]
009B1B63 push eax
009B1B64 call dword ptr [__imp__SwapBuffers@4 (0E1040Ch)]
-> 009B1B6A cmp esi,esp
009B1B6C call @ILT+780(__RTC_CheckEsp) (9B1311h)
答案 0 :(得分:1)
看起来你可能在窗口被破坏后访问HDC,如果你在获得WM_QUIT后立即突破循环,问题是否会消失?
答案 1 :(得分:0)
无论hdc设置为什么,它看起来都不合适。在此通话之前是否创建了窗口?这个应用程序是否涉及可能损害hdc的多线程?
尝试在hdc本身的地址上创建一个监视,并查看该值何时更改为无效位置,这可能会提示您更改的位置。
答案 2 :(得分:0)
这几乎肯定是驱动程序中的一个错误。您无法看到hdc值的原因是因为崩溃的顶层堆栈实际上在ATKOGL32.dll中,但由于没有符号,调试器会显示您的代码。据我所知,ATKOGL32.dll实际上是ATI驱动程序的ASUS包装器,而这正是发生崩溃的地方。您可能希望从amd.com安装库存ATI驱动程序,并查看崩溃是否仍然存在。
虽然无论你做什么系列的OpenGL调用,驱动程序都不会崩溃,但根据我的经验,崩溃通常是程序产生的某种无效调用的结果。从技术上讲,这应该被忽略并设置错误状态,但这并不总是会发生什么。您可以使用gDebugger等程序轻松检查任何无效的OpenGL调用。