opengl SwapBuffers使我的程序崩溃!

stszievb  于 2022-11-04  发布在  其他
关注(0)|答案(4)|浏览(251)

我有一个OpenGL程序,除了一台电脑之外,它可以在我所有的电脑上运行。这是一台Vista 64和Radeon HD 4850的台式机。问题似乎出在我对SwapBuffers(hdc)的调用上。
它编译得很好,然后给我一个异常:
Program.exe中0x 00000000处出现未处理的异常:数据类型:访问违规。
使用VC++在调用SwapBuffers之前中断,显示hdc的值为:
0xfe 011734 {未使用=???} CXX 0030:错误:无法计算表达式
有人知道会发生什么吗?有没有什么关于交换缓冲区,将改变从一个PC到下一个?我已经得到了它的工作在XP 32,XP 64和(不同的)Vista 64。

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.
    }

有问题的系统(HD 4850)上的驱动程序是最新的。我在另一个装有Radeon HD 4870的Vista 64系统上运行并编写了该程序,也使用了最新的驱动程序。据我所知,这两个卡的驱动程序几乎完全相同,因为它们都在HD 48 xx系列中。出于这个原因,GPU导致问题似乎很奇怪。
无论如何,我错了还是这是一个内存问题?(访问冲突)
此外,如果我删除对SwapBuffers(hdc)的调用,程序看起来运行得很好,尽管没有绘制任何内容,当然,因为帧缓冲区从来没有交换过。
调用堆栈(-〉是堆栈指针):

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)
cygmwpex

cygmwpex1#

看起来你可能在窗口被破坏后访问HDC,如果你一得到WM_QUIT就跳出循环,问题会消失吗?

9udxz4iz

9udxz4iz2#

这几乎可以肯定是驱动程序中的一个bug。你看不到hdc值的原因是因为崩溃的顶层堆栈帧实际上在ATKOGL32.dll中,但由于没有相应的符号,调试器会向你显示代码。据我所知,ATKOGL32.dll实际上是ATI驱动程序的华硕 Package 程序,这就是崩溃发生的地方。您可能需要从www.example.com安装常用的ATI驱动程序amd.com,并查看崩溃是否仍然存在。
虽然驱动程序应该永远不会崩溃,无论你做了什么系列的OpenGL调用,在我的经验,通常崩溃的结果是某种类型的无效调用,你的程序。从技术上讲,这应该只是忽略和错误状态设置,但这并不总是发生。你可以检查任何无效的OpenGL调用很容易通过使用程序,如gDebugger。

k4aesqcs

k4aesqcs3#

无论hdc被设置为什么,它看起来都不是一个正确的值。窗口是在调用之前创建的吗?这个应用程序是否涉及到任何可能会损害hdc的多线程?
尝试在hdc本身的地址上创建一个监视器,并查看该值何时更改为无效位置,这可能给予您它在何处更改。

ru9i0ody

ru9i0ody4#

我们遇到了同样的(或者至少是非常相似的)问题。原来戴尔Nahimic服务和华硕Sonic套件使用了一些奇怪的注入代码。对我们来说,禁用这些服务后问题自行解决了。
来源:https://github.com/glfw/glfw/issues/1682

相关问题