3

几天前,由于某些硬件更改,我设置了计算机并安装了 Windows 8 的新副本。其中,我将显卡从 Radeon HD 7870 更改为 Nvidia GTX 660。

再次设置 Visual Studio 11 后,我从 Github 下载了我的最后一个 OpenGL 项目并重建了整个项目。我从 Visual Studio 中运行了应用程序,但由于nvoglv32.dll.

Application.exe 中 0x5D9F74E3 (nvoglv32.dll) 处的未处理异常:0xC0000005:访问冲突读取位置 0x00000000。

在旧环境中,应用程序按预期工作。我没有更改项目或源代码的任何内容。唯一的区别是 Visual Studio 安装的语言,现在是英语,以前是德语。因此我创建了一个新项目并采用了所有设置,但错误仍然存​​在。

为了定位崩溃,我注意到所有初始化(窗口,着色器,...)都成功了,错误出现在绘制调用glDrawElements()上,它引用了我的延迟渲染器的几何传递。

经过一番研究,我发现它nvoglv32.dll来自 Nvidia,是关于一个名为Compatible OpenGL ICD. 这是否意味着我的应用程序以兼容模式运行?这听起来像是一种支持旧应用程序的模式,我希望我的应用程序以常规模式运行!顺便说一句,我为我的显卡安装了最新的稳定驱动程序。

老实说,我不知道如何解决这个崩溃问题。什么可能导致它以及如何解决它?

更新:我在 Geforce 论坛上找到了一篇关于我的问题的帖子。虽然没有回复,但作者可以通过更改两个 OpenGL 调用的顺序来解决问题。

大家好,

在浏览了我的应用程序源代码几个小时后,我发现调用这些函数......

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, #)
glBindVertexArray(#)

...按此顺序会导致 nvoglv64.dll 崩溃。将这些调用的顺序颠倒到...

glBindVertexArray(#)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, #)

...防止崩溃并且表现良好。

干杯,罗伯特格拉夫

由于我不使用顶点数组,因此无法简单地进行此修复,但可能存在类似问题。我会报告我的进展。

更新:我完全不知道如何解决我的问题。我尝试了不同的视频驱动程序版本,但没有区别。我使用最少的着色器和简单的前向渲染完全重写了渲染器。但是崩溃发生在第一次绘制调用时。

4

2 回答 2

4

为了定位崩溃,我注意到所有初始化(窗口、着色器……)都成功了,错误出现在绘制调用 glDrawElements() 处。

很可能您的代码一直存在越界访问,但 AMD Radeon Catalyst 驱动程序确实保留了更多地址空间,或者提前捕获了它们。现在您的 NVidia GeForce 驱动程序没有。

您传递的 glDrawElements 数量太大而count无法绘制元素,或者您的索引缓冲区包含索引超出顶点数组范围的值。如果是后者,那么您可能正在使用客户端顶点数组,因为 VBO 通常会捕获越界访问;那些也不会使您的客户端程序崩溃,而只会渲染垃圾。

于 2013-02-23T14:00:52.210 回答
1

最后我想出了一个解决方案来修复崩溃。

我用来创建窗口等的 SFML 框架提供了一个函数来重置上下文的 OpenGL 状态。我在创建窗口后立即调用它。

即使我无法解释原因,删除该函数调用也解决了崩溃问题。也许是因为 GLEW 或其他东西在那一刻还没有初始化。

sf::RenderWindow window;
window.create(VideoMode(1024, 768), "Window Title");
window.resetGLStates(); // removing this line fixed the crash
window.setVerticalSyncEnabled(true);
于 2013-02-25T14:21:49.053 回答