Я наконец пытаюсь обернуть голову вокруг шейдеров, используя учебник , который я нашел. Я решил начать с Qt5 (Windows), так как я знаком с ним и могу начать с изучения самого GLSL. Единственная разница между тем, что я делаю, и учебным пособием заключается в том, что я работаю с QOpenGLWidget
, а не с QOpenGLWindow
(у меня просто есть форма с одним виджетом, ничего особенного).
Чтобы начать работу с фрагментным шейдером, в Qt я добавил новый настольный (не ES) фрагментный шейдер в свой проект, и Qt генерирует следующий шейдер:
uniform sampler2D qt_Texture0;
varying vec4 qt_TexCoord0;
void main(void)
{
gl_FragColor = texture2D(qt_Texture0, qt_TexCoord0.st);
}
Однако при компиляции этого шейдера выдается эта ошибка:
QOpenGLShader::compile(Fragment): ERROR: 0:2: '' : No precision specified for (float)
Я немного поискал и нашел этот ответ , в котором говорится:
Нет точности по умолчанию для типов fp в фрагментных шейдерах в OpenGL ES 2.0.
Исходя из этого, я пришел к выводу, что мое приложение использует OpenGL ES, а не Desktop (иначе оно не будет ожидать определения точности).
Строка версии GL, которую я вижу: OpenGL ES 2.0 (ANGLE 2.1.0.8613f4946861) . Кстати, в Qt4 на этой же машине строка версии - 3.0.0 - сборка 9.17.10.4229 .
Если мой вывод верен, мой вопрос: как я могу настроить приложение на использование обычного OpenGL вместо OpenGL ES?
Предложение в комментариях установить тип визуализируемого формата поверхности на OpenGL
показалось многообещающим, но оно не работает. Например, если я изменю его в конструкторе виджета:
View::View (QWidget *parent) :
QOpenGLWidget(parent),
...
{
QSurfaceFormat f = format();
qDebug() << "type was" << f.renderableType();
f.setRenderableType(QSurfaceFormat::OpenGL);
qDebug() << "type set to" << f.renderableType();
setFormat(f);
qDebug() << "type is now" << format().renderableType();
}
void View::initializeGL () {
qDebug() << __FUNCTION__ << "type is now" << this->format().renderableType();
...
}
Проблема сохраняется, и вывод будет (0 = по умолчанию, 1 = OpenGL
, 2 = OpenGLES
):
type was 0
type set to 1
type is now 1
initializeGL type is now 2
Похоже, что он вынужден вернуться к OpenGLES
в некоторый момент между конструктором и initializeGL
.
Я наблюдал похожее поведение при настройке формата поверхности по умолчанию перед созданием любых объектов графического интерфейса пользователя (и перед созданием QApplication
).