Merge pull request #2199 from ts-korhonen/qt-opengl
Fix OpenGL Core renderer on macOS
This commit is contained in:
@@ -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());
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
@@ -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()
|
||||||
|
@@ -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();
|
||||||
};
|
};
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user