get the whole OpenGL shit going

This commit is contained in:
Arisotura
2020-05-25 14:59:26 +02:00
parent 4e34359a80
commit 10f9eda58a
3 changed files with 145 additions and 27 deletions

View File

@ -54,6 +54,8 @@
#include "Savestate.h" #include "Savestate.h"
#include "main_shaders.h"
// TODO: uniform variable spelling // TODO: uniform variable spelling
@ -247,7 +249,8 @@ EmuThread::EmuThread(QObject* parent) : QThread(parent)
EmuRunning = 2; EmuRunning = 2;
RunningSomething = false; 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(windowUpdate()), mainWindow, SLOT(repaint()));
connect(this, SIGNAL(windowTitleChange(QString)), mainWindow, SLOT(onTitleUpdate(QString))); connect(this, SIGNAL(windowTitleChange(QString)), mainWindow, SLOT(onTitleUpdate(QString)));
connect(this, SIGNAL(windowEmuStart()), mainWindow, SLOT(onEmuStart())); connect(this, SIGNAL(windowEmuStart()), mainWindow, SLOT(onEmuStart()));
@ -726,11 +729,18 @@ void ScreenPanelNative::onScreenLayoutChanged()
ScreenPanelGL::ScreenPanelGL(QWidget* parent) : QOpenGLWidget(parent) 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() ScreenPanelGL::~ScreenPanelGL()
{ {
// CHECKME!!!!
delete screenShader;
} }
void ScreenPanelGL::setupScreenLayout() void ScreenPanelGL::setupScreenLayout()
@ -741,14 +751,120 @@ void ScreenPanelGL::setupScreenLayout()
screenSetupLayout(w, h); 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) void ScreenPanelGL::resizeEvent(QResizeEvent* event)
{ {
setupScreenLayout(); setupScreenLayout();
QOpenGLWidget::resizeEvent(event);
}
void ScreenPanelGL::resizeGL(int w, int h)
{
} }
void ScreenPanelGL::mousePressEvent(QMouseEvent* event) void ScreenPanelGL::mousePressEvent(QMouseEvent* event)
@ -977,7 +1093,8 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
} }
setMenuBar(menubar); setMenuBar(menubar);
panel = new ScreenPanelNative(this); //panel = new ScreenPanelNative(this);
panel = new ScreenPanelGL(this);
setCentralWidget(panel); setCentralWidget(panel);
connect(this, SIGNAL(screenLayoutChange()), panel, SLOT(onScreenLayoutChanged())); connect(this, SIGNAL(screenLayoutChange()), panel, SLOT(onScreenLayoutChanged()));
emit screenLayoutChange(); emit screenLayoutChange();

View File

@ -24,7 +24,12 @@
#include <QMainWindow> #include <QMainWindow>
#include <QImage> #include <QImage>
#include <QActionGroup> #include <QActionGroup>
#include <QOpenGLWidget> #include <QOpenGLWidget>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QOpenGLFunctions_3_2_Core>
#include <QOpenGLShaderProgram>
class EmuThread : public QThread 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 Q_OBJECT
@ -124,9 +129,12 @@ public:
~ScreenPanelGL(); ~ScreenPanelGL();
protected: protected:
void paintEvent(QPaintEvent* event) override; void initializeGL() override;
void paintGL() override;
void resizeEvent(QResizeEvent* event) override; void resizeEvent(QResizeEvent* event) override;
void resizeGL(int w, int h) override;
void mousePressEvent(QMouseEvent* event) override; void mousePressEvent(QMouseEvent* event) override;
void mouseReleaseEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override;
@ -138,7 +146,10 @@ private slots:
private: private:
void setupScreenLayout(); void setupScreenLayout();
// QOpenGLShaderProgram* screenShader;
GLuint screenVertexBuffer;
GLuint screenVertexArray;
GLuint screenTexture;
}; };

View File

@ -21,12 +21,8 @@
const char* kScreenVS = R"(#version 140 const char* kScreenVS = R"(#version 140
layout(std140) uniform uConfig uniform vec2 uScreenSize;
{ uniform mat2x3 uTransform;
vec2 uScreenSize;
uint u3DScale;
uint uFilterMode;
};
in vec2 vPosition; in vec2 vPosition;
in vec2 vTexcoord; in vec2 vTexcoord;
@ -36,7 +32,10 @@ smooth out vec2 fTexcoord;
void main() void main()
{ {
vec4 fpos; 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.y *= -1;
fpos.z = 0.0; fpos.z = 0.0;
fpos.w = 1.0; fpos.w = 1.0;
@ -48,14 +47,7 @@ void main()
const char* kScreenFS = R"(#version 140 const char* kScreenFS = R"(#version 140
layout(std140) uniform uConfig uniform sampler2D ScreenTex;
{
vec2 uScreenSize;
uint u3DScale;
uint uFilterMode;
};
uniform usampler2D ScreenTex;
smooth in vec2 fTexcoord; smooth in vec2 fTexcoord;
@ -63,11 +55,9 @@ out vec4 oColor;
void main() void main()
{ {
ivec4 pixel = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord), 0)); vec4 pixel = texture2D(ScreenTex, fTexcoord);
// TODO: filters oColor = vec4(pixel.bgr, 1.0);
oColor = vec4(vec3(pixel.bgr) / 255.0, 1.0);
} }
)"; )";