ситуация
Я разрабатываю 32-битное приложение, использующее Qt 4, и работаю над 64-битной Windows 7.
В моей программе есть основной виджет, отличный от OpenGL, и QGLWidget, который может быть открыт пользователем.
проблема:
Когда я создаю этот QGLWidget
, glGetVersion
сообщает «1.1.0» (моё оборудование поддерживает OpenGL 4.3.0). В результате многие нужные мне функции вообще не работают (очевидно, потому что их нет в OpenGL 1). Эта проблема возникает «иногда».
дополнительная информация
ЕСЛИ я запускаю программу с помощью gDebugger, все работает нормально, а glGetVersion возвращает «4.3.0», как и ожидалось. Добавление этой строки:
QGLFormat::OpenGLVersionFlags flags = QGLFormat::openGLVersionFlags();
в начале функции main() также устраняет проблему.
Приложение отлично работает на WinXP 32bit.
Я написал подсистему OpenGL для этого приложения 2..3 года назад, и ребята, которые ее использовали, сказали, что у них была похожая проблема на виртуальных машинах (гостевая Win7 или Vista), но я не помню, как я справлялся с этой проблемой в то время.
Инициализация OpenGL
Инициализация OpenGL выполняется Qt 4 без glew или дополнительных библиотек с использованием QGLWidget.
В программе есть только один QGLWidget. Если быть точным, есть класс, производный от QGLWidget, его инициализация выглядит так:
DisplayWidget::DisplayWidget(QWidget* parent)
: QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer), parent)
Конфигурация системы:
ОС: Windows 7 64-разрядная.
Компилятор: MSVC2008 Express SP1.
Qt: Qt 4.8.1 (скомпилировано из исходного кода с поддержкой OpenSSL с использованием MSVC2008). Windows SDK: Windows Server 2008 и .NET 3.5. Графический процессор: GeForce 460 GTX
вопрос:
Что может быть причиной этой проблемы?
--Обновить--
«волшебное исправление» (OpenGLVersionFlags) перестало работать после полной пересборки, и теперь приложение постоянно инициализирует программный рендерер, даже при запуске с помощью gDebugger.
Все остальные приложения OpenGL на моей машине работают нормально и могут использовать шейдеры.
Я использую последние версии драйверов.
Любые идеи?
--Обновить--
После некоторого тестирования я обнаружил, что каким-то образом клиент Google Chrome и Steam влияет на все приложения Qt, использующие OpenGL.
Если у меня открыты Google Chrome и Steam, со временем все программы перестанут работать должным образом и больше не смогут получать аппаратное ускорение OpenGL.
Если я закрою Google Chrome и оставлю Steam открытым, каждая вторая попытка запуска программы с аппаратным ускорением будет неудачной.
Если я закрою и стим и хром, то каждый запуск программы будет успешным.
Почему это могло происходить?
--Обновить--
Я прочитал вывод отладчика и нашел очень интересную вещь:
'vdclient.exe': Loaded 'C:\Windows\SysWOW64\nvoglv32.dll'
First-chance exception at 0x777f47a5 (ntdll.dll) in vdclient.exe: 0xC0000005: Access violation reading location 0x05aa9000.
'vdclient.exe': Unloaded 'C:\Windows\SysWOW64\nvoglv32.dll'
По сути, при загрузке nvoglv32.dll "что-то" где-то падает (отладчик на это событие, кстати, никак не реагирует), и система решает выгрузить nvoglv32.dll. Судя по названию, это системный/драйверный компонент nvidia, без которого аппаратное ускорение быть не может.
Когда opengl работает правильно, эта часть лога выглядит так:
'vdclient.exe': Loaded 'C:\Windows\SysWOW64\nvoglv32.dll'
'vdclient.exe': Loaded 'C:\Windows\SysWOW64\ntmarta.dll', Symbols loaded (source information stripped).
'vdclient.exe': Loaded 'C:\Windows\SysWOW64\Wldap32.dll', Symbols loaded (source information stripped).
'vdclient.exe': Loaded 'C:\Windows\SysWOW64\powrprof.dll', Symbols loaded (source information stripped).
The thread 'Win32 Thread' (0x1744) has exited with code 0 (0x0).
The thread 'Win32 Thread' (0x1740) has exited with code 0 (0x0).
'vdclient.exe': Unloaded 'C:\Windows\SysWOW64\powrprof.dll'
The thread 'Win32 Thread' (0x1748) has exited with code 0 (0x0).
The thread 'Win32 Thread' (0x174c) has exited with code 0 (0x0).
'vdclient.exe': Loaded 'C:\Windows\SysWOW64\uxtheme.dll', Symbols loaded (source information stripped).
Идеи?
QGLFormat::OpenGLVersionFlags flags = QGLFormat::openGLVersionFlags();
послеmainWindow.show();
, чтобы контекст OpenGL инициализировался до запроса флагов версии? - person user2448027   schedule 16.06.2013