Windows 7 64bit, Qt 4: glGetVersion возвращает 1.1.0, nvogl32v.dll выгружается

ситуация

Я разрабатываю 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).

Идеи?


person SigTerm    schedule 11.06.2013    source источник
comment
Эта проблема иногда возникает. Что означает это? Можете ли вы определить что-то конкретное, что вызывает это? Какие у вас параметры формата пикселей?   -  person Nicol Bolas    schedule 11.06.2013
comment
@NicolBolas: Иногда, когда я запускаю приложение, оно сообщает gl версии 4.3.0. Однако в большинстве случаев, когда я запускаю его нормально (и без упомянутого магического исправления QGLFormat), версия gl сообщает 1.1.0.   -  person SigTerm    schedule 11.06.2013
comment
Версия драйвера графического процессора? Пробовали переустанавливать драйвера? Я предлагаю вам получить последнюю версию от NVidia и установить ее, чтобы исключить любые ошибки драйвера.   -  person datenwolf    schedule 11.06.2013
comment
@datenwolf: последние версии драйверов — 320.18. Не пробовал переустанавливать, потому что ОС была установлена ​​с нуля недавно (менее двух недель назад). Я почему-то подозреваю, что это ошибка Qt 4, а не ошибка драйвера, но у меня нет доказательств. Можно ли случайно создать контекст только для OpenGL 1.1.0 на платформе Windows? Я думаю, что Windows по умолчанию предоставляет какую-то эмуляцию OpenGL, которая довольно ограничена и только OpenGL 1.1.0. Однако я понятия не имею, что вам нужно сделать, чтобы получить его вместо OpenGL с аппаратным ускорением.   -  person SigTerm    schedule 11.06.2013
comment
@SigTerm: запрос пиксельного формата PFD_DRAW_TO_BITMAP надежно переведет вас в режим OpenGL-1.1. Некоторые другие конфигурации PFD также подвержены выпадающему списку версий OpenGL. Но я сомневаюсь, что это ваша проблема прямо сейчас.   -  person datenwolf    schedule 11.06.2013
comment
@datenwolf: висячий указатель или неинициализированная переменная теоретически могут изменить PIXELFORMATDESCRIPTOR таким образом, чтобы вызвать раскрывающийся список версий. Я больше нигде не вижу графических проблем, поэтому я не думаю, что это проблема драйвера. Поскольку приложение ведет себя по-другому в gDebugger, это может быть что-то вроде этого....   -  person SigTerm    schedule 11.06.2013
comment
Попробуйте использовать build:release, чтобы увидеть, что вы получите.   -  person adderly    schedule 16.06.2013
comment
Вы пытались поместить эту строку QGLFormat::OpenGLVersionFlags flags = QGLFormat::openGLVersionFlags(); после mainWindow.show();, чтобы контекст OpenGL инициализировался до запроса флагов версии?   -  person user2448027    schedule 16.06.2013
comment
@ user2448027: Он скажет, что я использую OpenGL 1.0. В основном, по неизвестной причине программа возвращается к программному рендерингу. Только ЭТА программа. Когда это происходит, я получаю определенные графические артефакты, поэтому их сложно не заметить.   -  person SigTerm    schedule 16.06.2013
comment
@SigTerm Происходит ли то же самое, если вы запускаете другую программу, использующую Qt и OpenGL (если вы, например, создаете небольшую тестовую программу и запускаете ее)?   -  person user2448027    schedule 16.06.2013
comment
@ user2448027: Похоже, что открытие Google Chrome каким-то образом влияет на программы Qt + OpenGL. Если у меня открыты программы OpenGL+Qt в Chrome/Steam, в конечном итоге перестанут работать, и каждая попытка получить OpenGL с аппаратным ускорением будет неудачной. Если я закрою его, в конце концов они начнут работать правильно. :-\   -  person SigTerm    schedule 17.06.2013
comment
Две мысли: 1) Поэкспериментируйте с другим браузером или другими приложениями, которые могут иметь проблемы с контекстами OpenGL. 2) Измените тег, чтобы включить google-chrome и/или steam.   -  person Samuel Harmer    schedule 20.06.2013
comment
@ Styne666: ограничение на 5 тегов.   -  person SigTerm    schedule 20.06.2013


Ответы (3)


Вы указываете версию OpenGL, используя QGLFormat.setVersion + QGLFormat.setProfile?

QGLFormat glFormat;
glFormat.setVersion( 3, 2 );
glFormat.setProfile( QGLFormat::CoreProfile );
glFormat.setSampleBuffers( true );

QGLWidget w( glFormat );

Еще одна потенциальная проблема. Ваш glGetVersion должен вызываться после инициализации контекста OpenGL в методе QGLWidget.initializeGL().

person Mortennobel    schedule 19.06.2013
comment
Явный запрос версии 1.5 (это все, что мне нужно) не решает проблему. - person SigTerm; 20.06.2013

Ладно, я сдаюсь.

Я отмечу это как ошибку драйвера или несовместимость с Google Chrome.

Я добавлю эту причуду|проблему в файл readme проекта и удостоверюсь, что приложение работает нормально (т. е. не отображает артефакты), даже если эмулируется OpenGL.

person SigTerm    schedule 22.06.2013

В OpenGL 3.0 и более поздних версиях действует модель прекращения поддержки устаревших функций. В старых версиях OpenGL новая версия была надстройкой старой версии. т.е. если вы хотели контекст OpenGL 1.5 и получили контекст OpenGL 2.0, это было нормально. Как только появилась возможность удаления старой функциональности, она больше не жизнеспособна. Было сделано расширение WGL_ARB_create_context: оно предоставляет новую функцию для замены wglCreateContext. Подобно wglChoosePixelFormatARB, он добавляет в систему механизм расширения, позволяющий расширять возможности создания контекста. Невозможно создать контекст основного профиля OpenGL 3.2+ без использования этой функции.

Вот официальная актуальная документация о том, как создать контекст OpenGL: http://www.opengl.org/wiki/Creating_an_OpenGL_Context_(WGL)

person Sergey K.    schedule 17.06.2013
comment
Без обид, но это не имеет отношения к проблеме. Потому что та же программа без каких-либо изменений либо успешно инициализируется и получает контекст с аппаратным ускорением OPenGL 4+, либо не может правильно инициализироваться и получает контекст OpenGL 1.0, который эмулируется программным обеспечением. - person SigTerm; 17.06.2013
comment
Это может быть поведение конкретного приложения/драйвера. - person Sergey K.; 18.06.2013
comment
Такое поведение нигде не задокументировано. Так что это ошибка, которая происходит где-то. Я хотел бы знать, что вызывает это и как надежно обойти/избежать его. Вот и все. - person SigTerm; 19.06.2013