SwapBuffers崩溃我的程序!

时间:2009-03-20 23:13:37

标签: c++ winapi opengl

我有一个可以在我的所有计算机上运行的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) 

3 个答案:

答案 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调用。