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;
} else if (!strcasecmp(api, "qt_opengles")) {
return 2;
} else if (!strcasecmp(api, "qt_opengl3")) {
return 3;
}
return 0;
@@ -97,6 +99,9 @@ char* plat_vidapi_name(int api) {
case 2:
name = "qt_opengles";
break;
case 3:
name = "qt_opengl3";
break;
default:
fatal("Unknown renderer: %i\n", api);
break;

View File

@@ -27,16 +27,36 @@ void HardwareRenderer::initializeGL()
m_blt->create();
QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this);
const char *vsrc =
"attribute highp vec4 vertex;\n"
"attribute mediump vec4 texCoord;\n"
"attribute highp vec4 VertexCoord;\n"
"attribute mediump vec4 TexCoord;\n"
"varying mediump vec4 texc;\n"
"uniform mediump mat4 matrix;\n"
"uniform mediump mat4 MVPMatrix;\n"
"void main(void)\n"
"{\n"
" gl_Position = matrix * vertex;\n"
" texc = texCoord;\n"
" gl_Position = MVPMatrix * VertexCoord;\n"
" texc = TexCoord;\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);
const char *fsrc =
@@ -46,18 +66,47 @@ void HardwareRenderer::initializeGL()
"{\n"
" gl_FragColor = texture2D(texture, texc.st).bgra;\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->addShader(vshader);
m_prog->addShader(fshader);
m_prog->bindAttributeLocation("vertex", PROGRAM_VERTEX_ATTRIBUTE);
m_prog->bindAttributeLocation("texCoord", PROGRAM_TEXCOORD_ATTRIBUTE);
m_prog->bindAttributeLocation("VertexCoord", PROGRAM_VERTEX_ATTRIBUTE);
m_prog->bindAttributeLocation("TexCoord", PROGRAM_TEXCOORD_ATTRIBUTE);
m_prog->link();
m_prog->bind();
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 renderer: %s\n", glGetString(GL_RENDERER));
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() + 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));
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_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->setMinMagFilters(video_filter_method ? QOpenGLTexture::Linear : QOpenGLTexture::Nearest, video_filter_method ? QOpenGLTexture::Linear : QOpenGLTexture::Nearest);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
@@ -92,6 +144,9 @@ void HardwareRenderer::paintGL() {
void HardwareRenderer::setRenderType(RenderType type) {
QSurfaceFormat format;
switch (type) {
case RenderType::OpenGL3:
format.setVersion(3, 0);
format.setProfile(QSurfaceFormat::CoreProfile);
case RenderType::OpenGL:
format.setRenderableType(QSurfaceFormat::OpenGL);
break;
@@ -107,6 +162,12 @@ void HardwareRenderer::onBlit(const std::unique_ptr<uint8_t>* img, int x, int y,
auto tval = this;
void* nuldata = 0;
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_texture->setData(QOpenGLTexture::PixelFormat::RGBA, QOpenGLTexture::PixelType::UInt8, (const void*)img->get());
in_use->clear();

View File

@@ -1,8 +1,10 @@
#pragma once
#include <QOpenGLFunctions>
#include <QOpenGLBuffer>
#include <QOpenGLWidget>
#include <QOpenGLWindow>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLTexture>
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>
@@ -29,13 +31,16 @@ private:
bool wayland = false;
QWidget* parentWidget{nullptr};
QOpenGLContext* m_context;
QOpenGLTexture* m_texture;
QOpenGLShaderProgram* m_prog;
QOpenGLTextureBlitter* m_blt;
QOpenGLTexture* m_texture{nullptr};
QOpenGLShaderProgram* m_prog{nullptr};
QOpenGLTextureBlitter* m_blt{nullptr};
QOpenGLBuffer m_vbo[2];
QOpenGLVertexArrayObject m_vao;
public:
enum class RenderType {
OpenGL,
OpenGLES,
OpenGL3,
};
void resizeGL(int w, int h) override;
void initializeGL() override;
@@ -56,6 +61,11 @@ public:
{
m_context->makeCurrent(this);
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_soundgain.hpp"
#include "qt_rendererstack.hpp"
#include "qt_renderercomon.hpp"
extern "C" {
#include <86box/86box.h>
#include <86box/config.h>
@@ -36,6 +39,9 @@ extern "C" {
#include "qt_mediamenu.hpp"
#ifdef __unix__
#ifdef WAYLAND
#include "wl_mouse.hpp"
#endif
#include <X11/Xlib.h>
#include <X11/keysym.h>
#undef KeyPress
@@ -163,11 +169,16 @@ MainWindow::MainWindow(QWidget *parent) :
ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGLES);
ui->actionHardware_Renderer_OpenGL_ES->setChecked(true);
break;
case 3:
ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGL3);
ui->actionOpenGL_3_0_Core->setChecked(true);
break;
}
actGroup = new QActionGroup(this);
actGroup->addAction(ui->actionSoftware_Renderer);
actGroup->addAction(ui->actionHardware_Renderer_OpenGL);
actGroup->addAction(ui->actionHardware_Renderer_OpenGL_ES);
actGroup->addAction(ui->actionOpenGL_3_0_Core);
switch (scale) {
case 0:
ui->action0_5x->setChecked(true);
@@ -1028,6 +1039,7 @@ void MainWindow::on_actionSoftware_Renderer_triggered() {
ui->stackedWidget->switchRenderer(RendererStack::Renderer::Software);
ui->actionHardware_Renderer_OpenGL->setChecked(false);
ui->actionHardware_Renderer_OpenGL_ES->setChecked(false);
ui->actionOpenGL_3_0_Core->setChecked(false);
vid_api = 0;
}
@@ -1035,6 +1047,7 @@ void MainWindow::on_actionHardware_Renderer_OpenGL_triggered() {
ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGL);
ui->actionSoftware_Renderer->setChecked(false);
ui->actionHardware_Renderer_OpenGL_ES->setChecked(false);
ui->actionOpenGL_3_0_Core->setChecked(false);
vid_api = 1;
}
@@ -1042,6 +1055,7 @@ void MainWindow::on_actionHardware_Renderer_OpenGL_ES_triggered() {
ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGLES);
ui->actionSoftware_Renderer->setChecked(false);
ui->actionHardware_Renderer_OpenGL->setChecked(false);
ui->actionOpenGL_3_0_Core->setChecked(false);
vid_api = 2;
}
@@ -1343,3 +1357,13 @@ void MainWindow::setSendKeyboardInput(bool 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_actionOpenGL_3_0_Core_triggered();
protected:
void keyPressEvent(QKeyEvent* event) override;
void keyReleaseEvent(QKeyEvent* event) override;

View File

@@ -37,7 +37,7 @@
<number>0</number>
</property>
<item>
<widget class="RendererStack" name="stackedWidget" />
<widget class="RendererStack" name="stackedWidget"/>
</item>
</layout>
</widget>
@@ -47,7 +47,7 @@
<x>0</x>
<y>0</y>
<width>724</width>
<height>19</height>
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="menuAction">
@@ -87,6 +87,7 @@
<addaction name="actionSoftware_Renderer"/>
<addaction name="actionHardware_Renderer_OpenGL"/>
<addaction name="actionHardware_Renderer_OpenGL_ES"/>
<addaction name="actionOpenGL_3_0_Core"/>
</widget>
<widget class="QMenu" name="menuWindow_scale_factor">
<property name="title">
@@ -511,19 +512,16 @@
<string>Sound gain...</string>
</property>
</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>
<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>
<class>RendererStack</class>
<extends>QStackedWidget</extends>

View File

@@ -196,6 +196,14 @@ void RendererStack::switchRenderer(Renderer renderer) {
current.reset(this->createWindowContainer(hw, this));
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->setFocusProxy(this);

View File

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