Add OpenGL 3.0 Core renderer
This commit is contained in:
@@ -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;
|
||||
|
@@ -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();
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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>
|
||||
|
@@ -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);
|
||||
|
@@ -39,6 +39,7 @@ public:
|
||||
Software,
|
||||
OpenGL,
|
||||
OpenGLES,
|
||||
OpenGL3
|
||||
};
|
||||
void switchRenderer(Renderer renderer);
|
||||
|
||||
|
Reference in New Issue
Block a user