aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/frontend/qt_sdl/main.cpp127
-rw-r--r--src/frontend/qt_sdl/main.h17
-rw-r--r--src/frontend/qt_sdl/main_shaders.h28
3 files changed, 145 insertions, 27 deletions
diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp
index b11dd10..bb08a87 100644
--- a/src/frontend/qt_sdl/main.cpp
+++ b/src/frontend/qt_sdl/main.cpp
@@ -54,6 +54,8 @@
#include "Savestate.h"
+#include "main_shaders.h"
+
// TODO: uniform variable spelling
@@ -247,7 +249,8 @@ EmuThread::EmuThread(QObject* parent) : QThread(parent)
EmuRunning = 2;
RunningSomething = false;
- connect(this, SIGNAL(windowUpdate()), mainWindow, SLOT(update()));
+ //connect(this, SIGNAL(windowUpdate()), mainWindow, SLOT(update()));
+ connect(this, SIGNAL(windowUpdate()), mainWindow->panel, SLOT(update()));
//connect(this, SIGNAL(windowUpdate()), mainWindow, SLOT(repaint()));
connect(this, SIGNAL(windowTitleChange(QString)), mainWindow, SLOT(onTitleUpdate(QString)));
connect(this, SIGNAL(windowEmuStart()), mainWindow, SLOT(onEmuStart()));
@@ -726,11 +729,18 @@ void ScreenPanelNative::onScreenLayoutChanged()
ScreenPanelGL::ScreenPanelGL(QWidget* parent) : QOpenGLWidget(parent)
{
- //
+ QSurfaceFormat format;
+ format.setDepthBufferSize(24);
+ format.setStencilBufferSize(8);
+ format.setVersion(3, 2);
+ format.setProfile(QSurfaceFormat::CoreProfile);
+ setFormat(format);
}
ScreenPanelGL::~ScreenPanelGL()
{
+ // CHECKME!!!!
+ delete screenShader;
}
void ScreenPanelGL::setupScreenLayout()
@@ -741,14 +751,120 @@ void ScreenPanelGL::setupScreenLayout()
screenSetupLayout(w, h);
}
-void ScreenPanelGL::paintEvent(QPaintEvent* event)
+void ScreenPanelGL::initializeGL()
{
- // TODO?
+ initializeOpenGLFunctions();
+
+ glClearColor(0, 0, 0, 1);
+
+ screenShader = new QOpenGLShaderProgram(this);
+ screenShader->addShaderFromSourceCode(QOpenGLShader::Vertex, kScreenVS);
+ screenShader->addShaderFromSourceCode(QOpenGLShader::Fragment, kScreenFS);
+
+ GLuint pid = screenShader->programId();
+ printf("program: %d\n", pid);
+ glBindAttribLocation(pid, 0, "vPosition");
+ glBindAttribLocation(pid, 1, "vTexcoord");
+ glBindFragDataLocation(pid, 0, "oColor");
+
+ screenShader->link();
+
+ screenShader->bind();
+ screenShader->setUniformValue("ScreenTex", (GLint)0);
+ screenShader->release();
+
+
+ float vertices[] =
+ {
+ 0, 0, 0, 0,
+ 0, 192, 0, 0.5,
+ 256, 192, 1, 0.5,
+ 0, 0, 0, 0,
+ 256, 192, 1, 0.5,
+ 256, 0, 1, 0,
+
+ 0, 0, 0, 0.5,
+ 0, 192, 0, 1,
+ 256, 192, 1, 1,
+ 0, 0, 0, 0.5,
+ 256, 192, 1, 1,
+ 256, 0, 1, 0.5
+ };
+
+ glGenBuffers(1, &screenVertexBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, screenVertexBuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
+
+ glGenVertexArrays(1, &screenVertexArray);
+ glBindVertexArray(screenVertexArray);
+ glEnableVertexAttribArray(0); // position
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4*4, (void*)(0));
+ glEnableVertexAttribArray(1); // texcoord
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4*4, (void*)(2*4));
+
+ glGenTextures(1, &screenTexture);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, screenTexture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 192*2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+}
+
+void ScreenPanelGL::paintGL()
+{
+ int w = width();
+ int h = height();
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ // TODO: check hiDPI compliance of this
+ glViewport(0, 0, w, h);
+
+ screenShader->bind();
+
+ screenShader->setUniformValue("uScreenSize", (float)w, (float)h);
+
+ int frontbuf = GPU::FrontBuffer;
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, screenTexture);
+
+ if (GPU::Framebuffer[frontbuf][0] && GPU::Framebuffer[frontbuf][1])
+ {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192, GL_RGBA,
+ GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192, 256, 192, GL_RGBA,
+ GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]);
+ }
+
+ GLint filter = Config::ScreenFilter ? GL_LINEAR : GL_NEAREST;
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
+
+ glBindBuffer(GL_ARRAY_BUFFER, screenVertexBuffer);
+ glBindVertexArray(screenVertexArray);
+
+ GLint transloc = screenShader->uniformLocation("uTransform");
+
+ glUniformMatrix2x3fv(transloc, 1, GL_TRUE, screenMatrix[0]);
+ glDrawArrays(GL_TRIANGLES, 0, 2*3);
+
+ glUniformMatrix2x3fv(transloc, 1, GL_TRUE, screenMatrix[1]);
+ glDrawArrays(GL_TRIANGLES, 2*3, 2*3);
+
+ screenShader->release();
}
void ScreenPanelGL::resizeEvent(QResizeEvent* event)
{
setupScreenLayout();
+
+ QOpenGLWidget::resizeEvent(event);
+}
+
+void ScreenPanelGL::resizeGL(int w, int h)
+{
}
void ScreenPanelGL::mousePressEvent(QMouseEvent* event)
@@ -977,7 +1093,8 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
}
setMenuBar(menubar);
- panel = new ScreenPanelNative(this);
+ //panel = new ScreenPanelNative(this);
+ panel = new ScreenPanelGL(this);
setCentralWidget(panel);
connect(this, SIGNAL(screenLayoutChange()), panel, SLOT(onScreenLayoutChanged()));
emit screenLayoutChange();
diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h
index a244907..8a8c041 100644
--- a/src/frontend/qt_sdl/main.h
+++ b/src/frontend/qt_sdl/main.h
@@ -24,7 +24,12 @@
#include <QMainWindow>
#include <QImage>
#include <QActionGroup>
+
#include <QOpenGLWidget>
+#include <QOpenGLContext>
+#include <QOpenGLFunctions>
+#include <QOpenGLFunctions_3_2_Core>
+#include <QOpenGLShaderProgram>
class EmuThread : public QThread
@@ -115,7 +120,7 @@ private:
};
-class ScreenPanelGL : public QOpenGLWidget, public ScreenHandler
+class ScreenPanelGL : public QOpenGLWidget, public ScreenHandler, protected QOpenGLFunctions_3_2_Core
{
Q_OBJECT
@@ -124,9 +129,12 @@ public:
~ScreenPanelGL();
protected:
- void paintEvent(QPaintEvent* event) override;
+ void initializeGL() override;
+
+ void paintGL() override;
void resizeEvent(QResizeEvent* event) override;
+ void resizeGL(int w, int h) override;
void mousePressEvent(QMouseEvent* event) override;
void mouseReleaseEvent(QMouseEvent* event) override;
@@ -138,7 +146,10 @@ private slots:
private:
void setupScreenLayout();
- //
+ QOpenGLShaderProgram* screenShader;
+ GLuint screenVertexBuffer;
+ GLuint screenVertexArray;
+ GLuint screenTexture;
};
diff --git a/src/frontend/qt_sdl/main_shaders.h b/src/frontend/qt_sdl/main_shaders.h
index 7c4feec..2e57e59 100644
--- a/src/frontend/qt_sdl/main_shaders.h
+++ b/src/frontend/qt_sdl/main_shaders.h
@@ -21,12 +21,8 @@
const char* kScreenVS = R"(#version 140
-layout(std140) uniform uConfig
-{
- vec2 uScreenSize;
- uint u3DScale;
- uint uFilterMode;
-};
+uniform vec2 uScreenSize;
+uniform mat2x3 uTransform;
in vec2 vPosition;
in vec2 vTexcoord;
@@ -36,7 +32,10 @@ smooth out vec2 fTexcoord;
void main()
{
vec4 fpos;
- fpos.xy = ((vPosition * 2.0) / uScreenSize) - 1.0;
+
+ fpos.xy = vec3(vPosition, 1.0) * uTransform;
+
+ fpos.xy = ((fpos.xy * 2.0) / uScreenSize) - 1.0;
fpos.y *= -1;
fpos.z = 0.0;
fpos.w = 1.0;
@@ -48,14 +47,7 @@ void main()
const char* kScreenFS = R"(#version 140
-layout(std140) uniform uConfig
-{
- vec2 uScreenSize;
- uint u3DScale;
- uint uFilterMode;
-};
-
-uniform usampler2D ScreenTex;
+uniform sampler2D ScreenTex;
smooth in vec2 fTexcoord;
@@ -63,11 +55,9 @@ out vec4 oColor;
void main()
{
- ivec4 pixel = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord), 0));
-
- // TODO: filters
+ vec4 pixel = texture2D(ScreenTex, fTexcoord);
- oColor = vec4(vec3(pixel.bgr) / 255.0, 1.0);
+ oColor = vec4(pixel.bgr, 1.0);
}
)";