Add OpenGL 3.0 Core renderer

This commit is contained in:
Cacodemon345
2021-12-27 16:32:03 +06:00
parent b40b3a56ae
commit 814aaf08a7
8 changed files with 137 additions and 28 deletions

View File

@@ -79,6 +79,8 @@ plat_vidapi(char* api) {
return 1; return 1;
} else if (!strcasecmp(api, "qt_opengles")) { } else if (!strcasecmp(api, "qt_opengles")) {
return 2; return 2;
} else if (!strcasecmp(api, "qt_opengl3")) {
return 3;
} }
return 0; return 0;
@@ -97,6 +99,9 @@ char* plat_vidapi_name(int api) {
case 2: case 2:
name = "qt_opengles"; name = "qt_opengles";
break; break;
case 3:
name = "qt_opengl3";
break;
default: default:
fatal("Unknown renderer: %i\n", api); fatal("Unknown renderer: %i\n", api);
break; break;

View File

@@ -27,16 +27,36 @@ void HardwareRenderer::initializeGL()
m_blt->create(); m_blt->create();
QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this); QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this);
const char *vsrc = const char *vsrc =
"attribute highp vec4 vertex;\n" "attribute highp vec4 VertexCoord;\n"
"attribute mediump vec4 texCoord;\n" "attribute mediump vec4 TexCoord;\n"
"varying mediump vec4 texc;\n" "varying mediump vec4 texc;\n"
"uniform mediump mat4 matrix;\n" "uniform mediump mat4 MVPMatrix;\n"
"void main(void)\n" "void main(void)\n"
"{\n" "{\n"
" gl_Position = matrix * vertex;\n" " gl_Position = MVPMatrix * VertexCoord;\n"
" texc = texCoord;\n" " texc = TexCoord;\n"
"}\n"; "}\n";
vshader->compileSourceCode(vsrc); QString vsrccore =
"in highp vec4 VertexCoord;\n"
"in mediump vec4 TexCoord;\n"
"out mediump vec4 texc;\n"
"uniform mediump mat4 MVPMatrix;\n"
"void main(void)\n"
"{\n"
" gl_Position = MVPMatrix * VertexCoord;\n"
" texc = TexCoord;\n"
"}\n";
if (m_context->isOpenGLES() && m_context->format().version() >= qMakePair(3, 0))
{
vsrccore.prepend("#version 300 es\n");
vshader->compileSourceCode(vsrccore);
}
else if (m_context->format().version() >= qMakePair(3, 0) && m_context->format().profile() == QSurfaceFormat::CoreProfile)
{
vsrccore.prepend("#version 130\n");
vshader->compileSourceCode(vsrccore);
}
else vshader->compileSourceCode(vsrc);
QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this); QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this);
const char *fsrc = const char *fsrc =
@@ -46,18 +66,47 @@ void HardwareRenderer::initializeGL()
"{\n" "{\n"
" gl_FragColor = texture2D(texture, texc.st).bgra;\n" " gl_FragColor = texture2D(texture, texc.st).bgra;\n"
"}\n"; "}\n";
fshader->compileSourceCode(fsrc); QString fsrccore =
"uniform sampler2D texture;\n"
"in mediump vec4 texc;\n"
"out highp vec4 FragColor;\n"
"void main(void)\n"
"{\n"
" FragColor = texture2D(texture, texc.st).bgra;\n"
"}\n";
if (m_context->isOpenGLES() && m_context->format().version() >= qMakePair(3, 0))
{
fsrccore.prepend("#version 300 es\n");
fshader->compileSourceCode(fsrccore);
}
else if (m_context->format().version() >= qMakePair(3, 0) && m_context->format().profile() == QSurfaceFormat::CoreProfile)
{
fsrccore.prepend("#version 130\n");
fshader->compileSourceCode(fsrccore);
}
else fshader->compileSourceCode(fsrc);
m_prog = new QOpenGLShaderProgram; m_prog = new QOpenGLShaderProgram;
m_prog->addShader(vshader); m_prog->addShader(vshader);
m_prog->addShader(fshader); m_prog->addShader(fshader);
m_prog->bindAttributeLocation("vertex", PROGRAM_VERTEX_ATTRIBUTE); m_prog->bindAttributeLocation("VertexCoord", PROGRAM_VERTEX_ATTRIBUTE);
m_prog->bindAttributeLocation("texCoord", PROGRAM_TEXCOORD_ATTRIBUTE); m_prog->bindAttributeLocation("TexCoord", PROGRAM_TEXCOORD_ATTRIBUTE);
m_prog->link(); m_prog->link();
m_prog->bind(); m_prog->bind();
m_prog->setUniformValue("texture", 0); m_prog->setUniformValue("texture", 0);
if (m_context->format().version() >= qMakePair(3, 0) && m_vao.create()) {
m_vao.bind();
}
m_vbo[PROGRAM_VERTEX_ATTRIBUTE].create();
m_vbo[PROGRAM_VERTEX_ATTRIBUTE].bind();
m_vbo[PROGRAM_VERTEX_ATTRIBUTE].allocate(sizeof(QVector2D) * 4);
m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].create();
m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].bind();
m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].allocate(sizeof(QVector2D) * 4);
pclog("OpenGL vendor: %s\n", glGetString(GL_VENDOR)); pclog("OpenGL vendor: %s\n", glGetString(GL_VENDOR));
pclog("OpenGL renderer: %s\n", glGetString(GL_RENDERER)); pclog("OpenGL renderer: %s\n", glGetString(GL_RENDERER));
pclog("OpenGL version: %s\n", glGetString(GL_VERSION)); pclog("OpenGL version: %s\n", glGetString(GL_VERSION));
@@ -78,12 +127,15 @@ void HardwareRenderer::paintGL() {
texcoords.push_back(QVector2D((float)source.x() / 2048.f, (float)(source.y() + source.height()) / 2048.f)); texcoords.push_back(QVector2D((float)source.x() / 2048.f, (float)(source.y() + source.height()) / 2048.f));
texcoords.push_back(QVector2D((float)(source.x() + source.width()) / 2048.f, (float)(source.y() + source.height()) / 2048.f)); texcoords.push_back(QVector2D((float)(source.x() + source.width()) / 2048.f, (float)(source.y() + source.height()) / 2048.f));
texcoords.push_back(QVector2D((float)(source.x() + source.width()) / 2048.f, (float)(source.y()) / 2048.f)); texcoords.push_back(QVector2D((float)(source.x() + source.width()) / 2048.f, (float)(source.y()) / 2048.f));
m_vbo[PROGRAM_VERTEX_ATTRIBUTE].bind(); m_vbo[PROGRAM_VERTEX_ATTRIBUTE].write(0, verts.data(), sizeof(QVector2D) * 4); m_vbo[PROGRAM_VERTEX_ATTRIBUTE].release();
m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].bind(); m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].write(0, texcoords.data(), sizeof(QVector2D) * 4); m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].release();
m_prog->setUniformValue("matrix", mat); m_prog->setUniformValue("MVPMatrix", mat);
m_prog->enableAttributeArray(PROGRAM_VERTEX_ATTRIBUTE); m_prog->enableAttributeArray(PROGRAM_VERTEX_ATTRIBUTE);
m_prog->enableAttributeArray(PROGRAM_TEXCOORD_ATTRIBUTE); m_prog->enableAttributeArray(PROGRAM_TEXCOORD_ATTRIBUTE);
m_prog->setAttributeArray(PROGRAM_VERTEX_ATTRIBUTE, verts.data());
m_prog->setAttributeArray(PROGRAM_TEXCOORD_ATTRIBUTE, texcoords.data()); m_vbo[PROGRAM_VERTEX_ATTRIBUTE].bind(); m_prog->setAttributeBuffer(PROGRAM_VERTEX_ATTRIBUTE, GL_FLOAT, 0, 2, 0); m_vbo[PROGRAM_VERTEX_ATTRIBUTE].release();
m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].bind(); m_prog->setAttributeBuffer(PROGRAM_TEXCOORD_ATTRIBUTE, GL_FLOAT, 0, 2, 0); m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].release();
m_texture->bind(); m_texture->bind();
m_texture->setMinMagFilters(video_filter_method ? QOpenGLTexture::Linear : QOpenGLTexture::Nearest, video_filter_method ? QOpenGLTexture::Linear : QOpenGLTexture::Nearest); m_texture->setMinMagFilters(video_filter_method ? QOpenGLTexture::Linear : QOpenGLTexture::Nearest, video_filter_method ? QOpenGLTexture::Linear : QOpenGLTexture::Nearest);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
@@ -92,6 +144,9 @@ void HardwareRenderer::paintGL() {
void HardwareRenderer::setRenderType(RenderType type) { void HardwareRenderer::setRenderType(RenderType type) {
QSurfaceFormat format; QSurfaceFormat format;
switch (type) { switch (type) {
case RenderType::OpenGL3:
format.setVersion(3, 0);
format.setProfile(QSurfaceFormat::CoreProfile);
case RenderType::OpenGL: case RenderType::OpenGL:
format.setRenderableType(QSurfaceFormat::OpenGL); format.setRenderableType(QSurfaceFormat::OpenGL);
break; break;
@@ -107,6 +162,12 @@ void HardwareRenderer::onBlit(const std::unique_ptr<uint8_t>* img, int x, int y,
auto tval = this; auto tval = this;
void* nuldata = 0; void* nuldata = 0;
if (memcmp(&tval, &nuldata, sizeof(void*)) == 0) return; if (memcmp(&tval, &nuldata, sizeof(void*)) == 0) return;
if (!m_texture || !img || !img->get() || (m_texture && !m_texture->isCreated()))
{
in_use->clear();
source.setRect(x, y, w, h);
return;
}
m_context->makeCurrent(this); m_context->makeCurrent(this);
m_texture->setData(QOpenGLTexture::PixelFormat::RGBA, QOpenGLTexture::PixelType::UInt8, (const void*)img->get()); m_texture->setData(QOpenGLTexture::PixelFormat::RGBA, QOpenGLTexture::PixelType::UInt8, (const void*)img->get());
in_use->clear(); in_use->clear();

View File

@@ -1,8 +1,10 @@
#pragma once #pragma once
#include <QOpenGLFunctions> #include <QOpenGLFunctions>
#include <QOpenGLBuffer>
#include <QOpenGLWidget> #include <QOpenGLWidget>
#include <QOpenGLWindow> #include <QOpenGLWindow>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLTexture> #include <QOpenGLTexture>
#include <QOpenGLShader> #include <QOpenGLShader>
#include <QOpenGLShaderProgram> #include <QOpenGLShaderProgram>
@@ -29,13 +31,16 @@ private:
bool wayland = false; bool wayland = false;
QWidget* parentWidget{nullptr}; QWidget* parentWidget{nullptr};
QOpenGLContext* m_context; QOpenGLContext* m_context;
QOpenGLTexture* m_texture; QOpenGLTexture* m_texture{nullptr};
QOpenGLShaderProgram* m_prog; QOpenGLShaderProgram* m_prog{nullptr};
QOpenGLTextureBlitter* m_blt; QOpenGLTextureBlitter* m_blt{nullptr};
QOpenGLBuffer m_vbo[2];
QOpenGLVertexArrayObject m_vao;
public: public:
enum class RenderType { enum class RenderType {
OpenGL, OpenGL,
OpenGLES, OpenGLES,
OpenGL3,
}; };
void resizeGL(int w, int h) override; void resizeGL(int w, int h) override;
void initializeGL() override; void initializeGL() override;
@@ -56,6 +61,11 @@ public:
{ {
m_context->makeCurrent(this); m_context->makeCurrent(this);
if (m_blt) m_blt->destroy(); if (m_blt) m_blt->destroy();
m_prog->release();
delete m_prog;
m_prog = nullptr;
m_context->doneCurrent();
delete m_context;
} }

View File

@@ -4,6 +4,9 @@
#include "qt_specifydimensions.h" #include "qt_specifydimensions.h"
#include "qt_soundgain.hpp" #include "qt_soundgain.hpp"
#include "qt_rendererstack.hpp"
#include "qt_renderercomon.hpp"
extern "C" { extern "C" {
#include <86box/86box.h> #include <86box/86box.h>
#include <86box/config.h> #include <86box/config.h>
@@ -36,6 +39,9 @@ extern "C" {
#include "qt_mediamenu.hpp" #include "qt_mediamenu.hpp"
#ifdef __unix__ #ifdef __unix__
#ifdef WAYLAND
#include "wl_mouse.hpp"
#endif
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/keysym.h> #include <X11/keysym.h>
#undef KeyPress #undef KeyPress
@@ -163,11 +169,16 @@ MainWindow::MainWindow(QWidget *parent) :
ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGLES); ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGLES);
ui->actionHardware_Renderer_OpenGL_ES->setChecked(true); ui->actionHardware_Renderer_OpenGL_ES->setChecked(true);
break; break;
case 3:
ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGL3);
ui->actionOpenGL_3_0_Core->setChecked(true);
break;
} }
actGroup = new QActionGroup(this); actGroup = new QActionGroup(this);
actGroup->addAction(ui->actionSoftware_Renderer); actGroup->addAction(ui->actionSoftware_Renderer);
actGroup->addAction(ui->actionHardware_Renderer_OpenGL); actGroup->addAction(ui->actionHardware_Renderer_OpenGL);
actGroup->addAction(ui->actionHardware_Renderer_OpenGL_ES); actGroup->addAction(ui->actionHardware_Renderer_OpenGL_ES);
actGroup->addAction(ui->actionOpenGL_3_0_Core);
switch (scale) { switch (scale) {
case 0: case 0:
ui->action0_5x->setChecked(true); ui->action0_5x->setChecked(true);
@@ -1028,6 +1039,7 @@ void MainWindow::on_actionSoftware_Renderer_triggered() {
ui->stackedWidget->switchRenderer(RendererStack::Renderer::Software); ui->stackedWidget->switchRenderer(RendererStack::Renderer::Software);
ui->actionHardware_Renderer_OpenGL->setChecked(false); ui->actionHardware_Renderer_OpenGL->setChecked(false);
ui->actionHardware_Renderer_OpenGL_ES->setChecked(false); ui->actionHardware_Renderer_OpenGL_ES->setChecked(false);
ui->actionOpenGL_3_0_Core->setChecked(false);
vid_api = 0; vid_api = 0;
} }
@@ -1035,6 +1047,7 @@ void MainWindow::on_actionHardware_Renderer_OpenGL_triggered() {
ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGL); ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGL);
ui->actionSoftware_Renderer->setChecked(false); ui->actionSoftware_Renderer->setChecked(false);
ui->actionHardware_Renderer_OpenGL_ES->setChecked(false); ui->actionHardware_Renderer_OpenGL_ES->setChecked(false);
ui->actionOpenGL_3_0_Core->setChecked(false);
vid_api = 1; vid_api = 1;
} }
@@ -1042,6 +1055,7 @@ void MainWindow::on_actionHardware_Renderer_OpenGL_ES_triggered() {
ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGLES); ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGLES);
ui->actionSoftware_Renderer->setChecked(false); ui->actionSoftware_Renderer->setChecked(false);
ui->actionHardware_Renderer_OpenGL->setChecked(false); ui->actionHardware_Renderer_OpenGL->setChecked(false);
ui->actionOpenGL_3_0_Core->setChecked(false);
vid_api = 2; vid_api = 2;
} }
@@ -1343,3 +1357,13 @@ void MainWindow::setSendKeyboardInput(bool enabled)
{ {
send_keyboard_input = enabled; send_keyboard_input = enabled;
} }
void MainWindow::on_actionOpenGL_3_0_Core_triggered()
{
ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGL3);
ui->actionSoftware_Renderer->setChecked(false);
ui->actionHardware_Renderer_OpenGL->setChecked(false);
ui->actionHardware_Renderer_OpenGL_ES->setChecked(false);
ui->actionOpenGL_3_0_Core->setChecked(true);
vid_api = 3;
}

View File

@@ -99,6 +99,8 @@ private slots:
void on_actionSound_gain_triggered(); void on_actionSound_gain_triggered();
void on_actionOpenGL_3_0_Core_triggered();
protected: protected:
void keyPressEvent(QKeyEvent* event) override; void keyPressEvent(QKeyEvent* event) override;
void keyReleaseEvent(QKeyEvent* event) override; void keyReleaseEvent(QKeyEvent* event) override;

View File

@@ -37,7 +37,7 @@
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
<widget class="RendererStack" name="stackedWidget" /> <widget class="RendererStack" name="stackedWidget"/>
</item> </item>
</layout> </layout>
</widget> </widget>
@@ -47,7 +47,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>724</width> <width>724</width>
<height>19</height> <height>22</height>
</rect> </rect>
</property> </property>
<widget class="QMenu" name="menuAction"> <widget class="QMenu" name="menuAction">
@@ -87,6 +87,7 @@
<addaction name="actionSoftware_Renderer"/> <addaction name="actionSoftware_Renderer"/>
<addaction name="actionHardware_Renderer_OpenGL"/> <addaction name="actionHardware_Renderer_OpenGL"/>
<addaction name="actionHardware_Renderer_OpenGL_ES"/> <addaction name="actionHardware_Renderer_OpenGL_ES"/>
<addaction name="actionOpenGL_3_0_Core"/>
</widget> </widget>
<widget class="QMenu" name="menuWindow_scale_factor"> <widget class="QMenu" name="menuWindow_scale_factor">
<property name="title"> <property name="title">
@@ -511,19 +512,16 @@
<string>Sound gain...</string> <string>Sound gain...</string>
</property> </property>
</action> </action>
<action name="actionOpenGL_3_0_Core">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>OpenGL 3.0 Core</string>
</property>
</action>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget>
<class>HardwareRenderer</class>
<extends>QOpenGLWidget</extends>
<header>qt_hardwarerenderer.hpp</header>
</customwidget>
<customwidget>
<class>SoftwareRenderer</class>
<extends>QWidget</extends>
<header>qt_softwarerenderer.hpp</header>
<container>1</container>
</customwidget>
<customwidget> <customwidget>
<class>RendererStack</class> <class>RendererStack</class>
<extends>QStackedWidget</extends> <extends>QStackedWidget</extends>

View File

@@ -196,6 +196,14 @@ void RendererStack::switchRenderer(Renderer renderer) {
current.reset(this->createWindowContainer(hw, this)); current.reset(this->createWindowContainer(hw, this));
break; break;
} }
case Renderer::OpenGL3:
{
this->createWinId();
auto hw = new HardwareRenderer(this, HardwareRenderer::RenderType::OpenGL3);
connect(this, &RendererStack::blitToRenderer, hw, &HardwareRenderer::onBlit, Qt::QueuedConnection);
current.reset(this->createWindowContainer(hw, this));
break;
}
} }
current->setFocusPolicy(Qt::NoFocus); current->setFocusPolicy(Qt::NoFocus);
current->setFocusProxy(this); current->setFocusProxy(this);

View File

@@ -39,6 +39,7 @@ public:
Software, Software,
OpenGL, OpenGL,
OpenGLES, OpenGLES,
OpenGL3
}; };
void switchRenderer(Renderer renderer); void switchRenderer(Renderer renderer);