QOpenGLWidget暗恋显示

QOpenGLWidget crushes on shown

本文关键字:显示 暗恋 QOpenGLWidget      更新时间:2023-10-16

我在QMainWindow实例中嵌入了一个QOpenGLWidgetw。编译是可以的。但是在调试时,程序在w.show()时崩溃。

错误对话框显示:

在 (d3d11sdklayers.dll) 中引发的0x000007FEE5AF4469异常 TestQtOpenGL.exe:0xC0000005:访问违规读取位置 0x00000806E5B03A98。

调用堆栈为:

d3d11sdklayers.dll!000007fee5af4469()   Unknown
d3d11sdklayers.dll!000007fee5ad2971()   Unknown
libGLESv2d.dll!000007fed7d58a8d()   Unknown
libGLESv2d.dll!000007fed7d56313()   Unknown
libGLESv2d.dll!000007fed7d55521()   Unknown
libGLESv2d.dll!000007fed7b2308a()   Unknown
libGLESv2d.dll!000007fed7b24f1b()   Unknown
libGLESv2d.dll!000007fed79dbba8()   Unknown
libGLESv2d.dll!000007fed7bf2678()   Unknown
libEGLd.dll!000007feecd1209d()  Unknown
qwindowsd.dll!000007fed86752ac()    Unknown
qwindowsd.dll!000007fed8674906()    Unknown
qwindowsd.dll!000007fed8602d55()    Unknown
qwindowsd.dll!000007fed8602999()    Unknown
qwindowsd.dll!000007fed860223b()    Unknown
qwindowsd.dll!000007fed86020fe()    Unknown
Qt5Guid.dll!000007fed93a18a0()  Unknown
Qt5Widgetsd.dll!0000000057d55dc2()  Unknown
Qt5Widgetsd.dll!0000000057d97037()  Unknown
Qt5Widgetsd.dll!0000000057d95d45()  Unknown
Qt5Widgetsd.dll!0000000057d439f6()  Unknown
Qt5Widgetsd.dll!0000000057d95fa9()  Unknown
Qt5Widgetsd.dll!0000000057ce700e()  Unknown
Qt5Widgetsd.dll!0000000057ce46c6()  Unknown
Qt5Cored.dll!0000000058c15af6() Unknown
Qt5Cored.dll!0000000058c20c32() Unknown
Qt5Widgetsd.dll!0000000057d520b0()  Unknown
Qt5Widgetsd.dll!0000000057d523f0()  Unknown
Qt5Widgetsd.dll!0000000057d3dd71()  Unknown
Qt5Widgetsd.dll!0000000057d3e0c9()  Unknown
Qt5Widgetsd.dll!0000000057d50b12()  Unknown
Qt5Widgetsd.dll!0000000057d52411()  Unknown
Qt5Widgetsd.dll!0000000057d3dd71()  Unknown
Qt5Widgetsd.dll!0000000057d3e0c9()  Unknown
> TestQtOpenGL.exe!main(int argc, char * * argv) Line 9 C++ TestQtOpenGL.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 104    C++
[External Code]

演示:

// main.cpp
#include "TestQtOpenGL.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
/*
* According to some solutions, I have tried the following
* codes, but no use.
*/
// QSurfaceFormat format; format.setDepthBufferSize(24);
// format.setStencilBufferSize(8);
// format.setVersion(4, 3);
// format.setProfile(QSurfaceFormat::CoreProfile);
// QSurfaceFormat::setDefaultFormat(format);
QApplication a(argc, argv);
TestQtOpenGL w;
w.show();
return a.exec();
}
// TestQtOpenGL.h
#pragma once
#include <QtWidgets/QMainWindow>
#include <qopenglwidget.h>
class TestQtOpenGL : public QMainWindow
{
Q_OBJECT
public:
TestQtOpenGL(QWidget *parent = Q_NULLPTR);
private:
QOpenGLWidget *glwidget;
};
// TestQtOpenGL.cpp
#include "TestQtOpenGL.h"
TestQtOpenGL::TestQtOpenGL(QWidget *parent)
: QMainWindow(parent)
{
setFixedSize(800, 600);
glwidget = new QOpenGLWidget(this);
setCentralWidget(glwidget);
}

环境:

  • Qt 5.9.4 msvc2015 64位
  • Visual Studio 2015
  • 视窗 7

根据@Aleph0的建议,我已经通过使用[Visual Studio]->[Debug]->[Windows]->[Modules]来调查加载的模块。但是我没有发现任何可疑的DLL。模块列表在此处上传。

受到@RoQuOTriX的启发,我以一种非常简单的方式解决了这个问题:

更新 Windows 设备管理器中的图形驱动程序。然后重新启动。重新编译,问题就消失了。

请注意,我的显卡是英特尔核芯显卡。如果使用独立显卡,则可能需要从设备提供商处获取图形驱动程序更新。

在阅读了 QOpenGLWidget 的文档后,我发现了以下段落,可能对您很重要:

注意:在构造之前调用 QSurfaceFormat::setDefaultFormat() QApplication 实例在某些平台上是必需的(例如, macOS),当请求 OpenGL 核心配置文件上下文时。这是为了 确保上下文之间的资源共享保持正常运行 内部上下文是使用正确的版本和配置文件创建的。

也许你应该重写你的main.cpp,并在创建QApplication对象之前放setDefaultFormat

#include "TestQtOpenGL.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
// This should be come first on some platforms
QSurfaceFormat format; format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
format.setVersion(4, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
QSurfaceFormat::setDefaultFormat(format);
QApplication a(argc, argv);
TestQtOpenGL w;
w.show();
return a.exec();
}

在考虑了您的调用堆栈后,我发现有一个libGLESv2d.dll,它没有列在我的加载模块中。我尝试通过设置切换到OpenGL ES

#include "TestQtOpenGL.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QSurfaceFormat format; format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
format.setVersion(4, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
format.setRenderableType(QSurfaceFormat::RenderableType::OpenGLES);
QSurfaceFormat::setDefaultFormat(format);
// Setting surface format before creation of QApplication
QApplication a(argc, argv);  
TestQtOpenGL w;
w.show();
return a.exec();
}

这导致了错误消息:

QOpenGLWidget: Failed to create context
QOpenGLWidget: Failed to create context
qt.qpa.backingstore: composeAndFlush: QOpenGLContext creation failed
qt.qpa.backingstore: composeAndFlush: makeCurrent() failed
qt.qpa.backingstore: composeAndFlush: makeCurrent() failed

我建议,你改变你的渲染类型来绘制OpenGL,看看会发生什么。