Merge pull request #2199 from ts-korhonen/qt-opengl

Fix OpenGL Core renderer on macOS
This commit is contained in:
Miran Grča
2022-03-06 17:47:53 +01:00
committed by GitHub
6 changed files with 44 additions and 23 deletions

View File

@@ -45,8 +45,9 @@ void main() {\n\
color = texture(texsampler, tex);\n\ color = texture(texsampler, tex);\n\
}\n"; }\n";
OpenGLOptions::OpenGLOptions(QObject *parent, bool loadConfig) OpenGLOptions::OpenGLOptions(QObject *parent, bool loadConfig, const QString &glslVersion)
: QObject(parent) : QObject(parent)
, m_glslVersion(glslVersion)
{ {
if (!loadConfig) if (!loadConfig)
return; return;
@@ -147,7 +148,7 @@ OpenGLOptions::addShader(const QString &path)
auto match = version.match(shader_text); auto match = version.match(shader_text);
QString version_line("#version 130"); QString version_line(m_glslVersion);
if (match.hasMatch()) { if (match.hasMatch()) {
/* Extract existing version and remove it. */ /* Extract existing version and remove it. */
@@ -155,10 +156,6 @@ OpenGLOptions::addShader(const QString &path)
shader_text.remove(version); shader_text.remove(version);
} }
if (QOpenGLContext::currentContext() && QOpenGLContext::currentContext()->isOpenGLES()) {
/* Force #version 300 es (the default of #version 100 es is too old and too limited) */
version_line = "#version 300 es";
}
auto shader = new QOpenGLShaderProgram(this); auto shader = new QOpenGLShaderProgram(this);
auto throw_shader_error = [path, shader](const QString &what) { auto throw_shader_error = [path, shader](const QString &what) {
@@ -169,10 +166,12 @@ OpenGLOptions::addShader(const QString &path)
.toStdString()); .toStdString());
}; };
if (!shader->addShaderFromSourceCode(QOpenGLShader::Vertex, version_line % "\n#extension GL_ARB_shading_language_420pack : enable\n" % "\n#define VERTEX\n" % shader_text)) static const char *extension = "\n#extension GL_ARB_shading_language_420pack : enable\n";
if (!shader->addShaderFromSourceCode(QOpenGLShader::Vertex, version_line % extension % "\n#define VERTEX\n#line 1\n" % shader_text))
throw_shader_error(tr("Error compiling vertex shader in file \"%1\"")); throw_shader_error(tr("Error compiling vertex shader in file \"%1\""));
if (!shader->addShaderFromSourceCode(QOpenGLShader::Fragment, version_line % "\n#extension GL_ARB_shading_language_420pack : enable\n" % "\n#define FRAGMENT\n" % shader_text)) if (!shader->addShaderFromSourceCode(QOpenGLShader::Fragment, version_line % extension % "\n#define FRAGMENT\n#line 1\n" % shader_text))
throw_shader_error(tr("Error compiling fragment shader in file \"%1\"")); throw_shader_error(tr("Error compiling fragment shader in file \"%1\""));
if (!shader->link()) if (!shader->link())
@@ -184,13 +183,9 @@ OpenGLOptions::addShader(const QString &path)
void void
OpenGLOptions::addDefaultShader() OpenGLOptions::addDefaultShader()
{ {
QString version = QOpenGLContext::currentContext() && QOpenGLContext::currentContext()->isOpenGLES()
? "#version 300 es\n"
: "#version 130\n";
auto shader = new QOpenGLShaderProgram(this); auto shader = new QOpenGLShaderProgram(this);
shader->addShaderFromSourceCode(QOpenGLShader::Vertex, version % vertex_shader); shader->addShaderFromSourceCode(QOpenGLShader::Vertex, m_glslVersion % "\n" % vertex_shader);
shader->addShaderFromSourceCode(QOpenGLShader::Fragment, version % fragment_shader); shader->addShaderFromSourceCode(QOpenGLShader::Fragment, m_glslVersion % "\n" % fragment_shader);
shader->link(); shader->link();
m_shaders << OpenGLShaderPass(shader, QString()); m_shaders << OpenGLShaderPass(shader, QString());
} }

View File

@@ -72,14 +72,14 @@ public:
enum FilterType { Nearest, enum FilterType { Nearest,
Linear }; Linear };
OpenGLOptions(QObject *parent = nullptr, bool loadConfig = false); OpenGLOptions(QObject *parent, bool loadConfig, const QString &glslVersion);
RenderBehaviorType renderBehavior() const { return m_renderBehavior; } RenderBehaviorType renderBehavior() const { return m_renderBehavior; }
int framerate() const { return m_framerate; } int framerate() const { return m_framerate; }
bool vSync() const { return m_vsync; } bool vSync() const { return m_vsync; }
FilterType filter() const; FilterType filter() const;
const QList<OpenGLShaderPass> &shaders() const { return m_shaders; }; const QList<OpenGLShaderPass> &shaders() const { return m_shaders; }
void setRenderBehavior(RenderBehaviorType value); void setRenderBehavior(RenderBehaviorType value);
void setFrameRate(int value); void setFrameRate(int value);
@@ -95,6 +95,7 @@ private:
bool m_vsync = false; bool m_vsync = false;
FilterType m_filter = Nearest; FilterType m_filter = Nearest;
QList<OpenGLShaderPass> m_shaders; QList<OpenGLShaderPass> m_shaders;
QString m_glslVersion;
}; };
#endif #endif

View File

@@ -24,9 +24,10 @@
#include "qt_util.hpp" #include "qt_util.hpp"
#include "ui_qt_opengloptionsdialog.h" #include "ui_qt_opengloptionsdialog.h"
OpenGLOptionsDialog::OpenGLOptionsDialog(QWidget *parent, const OpenGLOptions &options) OpenGLOptionsDialog::OpenGLOptionsDialog(QWidget *parent, const OpenGLOptions &options, std::function<OpenGLOptions *()> optionsFactory)
: QDialog(parent) : QDialog(parent)
, ui(new Ui::OpenGLOptionsDialog) , ui(new Ui::OpenGLOptionsDialog)
, createOptions(optionsFactory)
{ {
ui->setupUi(this); ui->setupUi(this);
@@ -54,7 +55,7 @@ OpenGLOptionsDialog::~OpenGLOptionsDialog()
void void
OpenGLOptionsDialog::accept() OpenGLOptionsDialog::accept()
{ {
auto options = new OpenGLOptions(); auto options = createOptions();
options->setRenderBehavior( options->setRenderBehavior(
ui->syncWithVideo->isChecked() ui->syncWithVideo->isChecked()

View File

@@ -19,6 +19,8 @@
#include <QDialog> #include <QDialog>
#include <functional>
#include "qt_opengloptions.hpp" #include "qt_opengloptions.hpp"
namespace Ui { namespace Ui {
@@ -29,7 +31,7 @@ class OpenGLOptionsDialog : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
explicit OpenGLOptionsDialog(QWidget *parent, const OpenGLOptions &options); explicit OpenGLOptionsDialog(QWidget *parent, const OpenGLOptions &options, std::function<OpenGLOptions *()> optionsFactory);
~OpenGLOptionsDialog(); ~OpenGLOptionsDialog();
signals: signals:
@@ -41,6 +43,8 @@ public slots:
private: private:
Ui::OpenGLOptionsDialog *ui; Ui::OpenGLOptionsDialog *ui;
std::function<OpenGLOptions *()> createOptions;
private slots: private slots:
void on_addShader_clicked(); void on_addShader_clicked();
}; };

View File

@@ -42,9 +42,12 @@ OpenGLRenderer::OpenGLRenderer(QWidget *parent)
QSurfaceFormat format; QSurfaceFormat format;
#ifdef Q_OS_MACOS
format.setVersion(4, 1);
#else
format.setVersion(3, 2);
#endif
format.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile); format.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile);
format.setMajorVersion(3);
format.setMinorVersion(2);
if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES)
format.setRenderableType(QSurfaceFormat::OpenGLES); format.setRenderableType(QSurfaceFormat::OpenGLES);
@@ -114,8 +117,23 @@ OpenGLRenderer::initialize()
if (!context->makeCurrent(this)) if (!context->makeCurrent(this))
throw opengl_init_error(tr("Couldn't switch to OpenGL context.")); throw opengl_init_error(tr("Couldn't switch to OpenGL context."));
auto version = context->format().version();
if (version.first < 3)
throw opengl_init_error(tr("OpenGL version 3.0 or greater is required. Current version is %1.%2").arg(version.first).arg(version.second));
initializeOpenGLFunctions(); initializeOpenGLFunctions();
/* Prepare the shader version string */
glslVersion = reinterpret_cast<const char *>(glGetString(GL_SHADING_LANGUAGE_VERSION));
glslVersion.truncate(4);
glslVersion.remove('.');
glslVersion.prepend("#version ");
if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES)
glslVersion.append(" es");
else if (context->format().profile() == QSurfaceFormat::CoreProfile)
glslVersion.append(" core");
initializeExtensions(); initializeExtensions();
initializeBuffers(); initializeBuffers();
@@ -147,7 +165,7 @@ OpenGLRenderer::initialize()
glTexImage2D(GL_TEXTURE_2D, 0, QOpenGLTexture::RGBA8_UNorm, INIT_WIDTH, INIT_HEIGHT, 0, QOpenGLTexture::BGRA, QOpenGLTexture::UInt32_RGBA8_Rev, NULL); glTexImage2D(GL_TEXTURE_2D, 0, QOpenGLTexture::RGBA8_UNorm, INIT_WIDTH, INIT_HEIGHT, 0, QOpenGLTexture::BGRA, QOpenGLTexture::UInt32_RGBA8_Rev, NULL);
options = new OpenGLOptions(this, true); options = new OpenGLOptions(this, true, glslVersion);
applyOptions(); applyOptions();
@@ -211,7 +229,7 @@ OpenGLRenderer::finalize()
QDialog * QDialog *
OpenGLRenderer::getOptions(QWidget *parent) OpenGLRenderer::getOptions(QWidget *parent)
{ {
auto dialog = new OpenGLOptionsDialog(parent, *options); auto dialog = new OpenGLOptionsDialog(parent, *options, [this]() { return new OpenGLOptions(this, false, glslVersion); });
connect(dialog, &OpenGLOptionsDialog::optionsChanged, this, &OpenGLRenderer::updateOptions); connect(dialog, &OpenGLOptionsDialog::optionsChanged, this, &OpenGLRenderer::updateOptions);

View File

@@ -77,6 +77,8 @@ private:
OpenGLOptions *options; OpenGLOptions *options;
QTimer *renderTimer; QTimer *renderTimer;
QString glslVersion;
bool isInitialized = false; bool isInitialized = false;
bool isFinalized = false; bool isFinalized = false;