Qt: Add preprocessor shader step customization

This commit is contained in:
Jeffrey Pfau 2015-11-22 13:56:53 -08:00
parent a9ae152dd4
commit f922f3c152
6 changed files with 97 additions and 51 deletions

View File

@ -5,6 +5,7 @@ Features:
- Booting of multiboot images
- Customization of GIF recording
- Libretro: Cheat code support
- Support for GLSL shaders
Bugfixes:
- Util: Fix PowerPC PNG read/write pixel order
- Qt: Use safer isLoaded check in GameController

View File

@ -84,18 +84,35 @@ static void GBAGLES2ContextInit(struct VideoBackend* v, WHandle handle) {
struct GBAGLES2Uniform* uniforms = malloc(sizeof(struct GBAGLES2Uniform) * 3);
uniforms[0].name = "gamma";
uniforms[0].readableName = "Gamma";
uniforms[0].type = GL_FLOAT;
uniforms[0].value.f = 1.0f;
uniforms[0].min.f = 0.1f;
uniforms[0].max.f = 3.0f;
uniforms[1].name = "scale";
uniforms[1].readableName = "Scale";
uniforms[1].type = GL_FLOAT_VEC3;
uniforms[1].value.fvec3[0] = 1.0f;
uniforms[1].value.fvec3[1] = 1.0f;
uniforms[1].value.fvec3[2] = 1.0f;
uniforms[1].min.fvec3[0] = -1.0f;
uniforms[1].min.fvec3[1] = -1.0f;
uniforms[1].min.fvec3[2] = -1.0f;
uniforms[1].max.fvec3[0] = 2.0f;
uniforms[1].max.fvec3[1] = 2.0f;
uniforms[1].max.fvec3[2] = 2.0f;
uniforms[2].name = "bias";
uniforms[2].readableName = "Bias";
uniforms[2].type = GL_FLOAT_VEC3;
uniforms[2].value.fvec3[0] = 0.0f;
uniforms[2].value.fvec3[1] = 0.0f;
uniforms[2].value.fvec3[2] = 0.0f;
uniforms[2].min.fvec3[0] = -1.0f;
uniforms[2].min.fvec3[1] = -1.0f;
uniforms[2].min.fvec3[2] = -1.0f;
uniforms[2].max.fvec3[0] = 1.0f;
uniforms[2].max.fvec3[1] = 1.0f;
uniforms[2].max.fvec3[2] = 1.0f;
GBAGLES2ShaderInit(&context->initialShader, _vertexShader, _fragmentShader, -1, -1, uniforms, 3);
GBAGLES2ShaderInit(&context->finalShader, 0, 0, 0, 0, 0, 0);
glDeleteFramebuffers(1, &context->finalShader.fbo);

View File

@ -208,6 +208,19 @@ PainterGL::PainterGL(QGLWidget* parent, QGLFormat::OpenGLVersionFlags glVersion)
PainterGL* painter = static_cast<PainterGL*>(v->user);
painter->m_gl->swapBuffers();
};
m_gl->makeCurrent();
#if defined(_WIN32) && defined(USE_EPOXY)
epoxy_handle_external_wglMakeCurrent();
#endif
m_backend->init(m_backend, reinterpret_cast<WHandle>(m_gl->winId()));
#if !defined(_WIN32) || defined(USE_EPOXY)
if (m_supportsShaders) {
m_shader.preprocessShader = static_cast<void*>(&reinterpret_cast<GBAGLES2Context*>(m_backend)->initialShader);
}
#endif
m_gl->doneCurrent();
m_backend->user = this;
m_backend->filter = false;
m_backend->lockAspectRatio = false;
@ -224,11 +237,14 @@ PainterGL::~PainterGL() {
for (auto item : m_free) {
delete[] item;
}
delete m_backend;
m_backend = nullptr;
#if !defined(_WIN32) || defined(USE_EPOXY)
if (m_shader.passes) {
GBAGLES2ShaderFree(&m_shader);
}
#endif
m_backend->deinit(m_backend);
delete m_backend;
m_backend = nullptr;
}
void PainterGL::setContext(GBAThread* context) {
@ -265,10 +281,9 @@ void PainterGL::start() {
#if defined(_WIN32) && defined(USE_EPOXY)
epoxy_handle_external_wglMakeCurrent();
#endif
m_backend->init(m_backend, reinterpret_cast<WHandle>(m_gl->winId()));
#if !defined(_WIN32) || defined(USE_EPOXY)
if (m_shader.passes) {
if (m_supportsShaders && m_shader.passes) {
GBAGLES2ShaderAttach(reinterpret_cast<GBAGLES2Context*>(m_backend), static_cast<GBAGLES2Shader*>(m_shader.passes), m_shader.nPasses);
}
#endif
@ -314,7 +329,6 @@ void PainterGL::stop() {
dequeueAll();
m_backend->clear(m_backend);
m_backend->swap(m_backend);
m_backend->deinit(m_backend);
m_gl->doneCurrent();
m_gl->context()->moveToThread(m_gl->thread());
moveToThread(m_gl->thread());

View File

@ -106,14 +106,60 @@ void ShaderSelector::refreshShaders() {
}
#if !defined(_WIN32) || defined(USE_EPOXY)
m_ui.passes->addTab(makePage(static_cast<GBAGLES2Shader*>(m_shaders->preprocessShader)), tr("Preprocessing"));
GBAGLES2Shader* shaders = static_cast<GBAGLES2Shader*>(m_shaders->passes);
for (size_t p = 0; p < m_shaders->nPasses; ++p) {
QWidget* page = makePage(&shaders[p]);
if (page) {
m_ui.passes->addTab(page, tr("Pass %1").arg(p + 1));
}
}
#endif
}
void ShaderSelector::addUniform(QGridLayout* settings, float* value, float min, float max, int y, int x) {
QDoubleSpinBox* f = new QDoubleSpinBox;
f->setDecimals(3);
if (min < max) {
f->setMinimum(min);
f->setMaximum(max);
}
f->setValue(*value);
f->setSingleStep(0.001);
f->setAccelerated(true);
settings->addWidget(f, y, x);
connect(f, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), [value](double v) {
*value = v;
// TODO: Config
});
}
void ShaderSelector::addUniform(QGridLayout* settings, int* value, int min, int max, int y, int x) {
QSpinBox* i = new QSpinBox;
if (min < max) {
i->setMinimum(min);
i->setMaximum(max);
}
i->setValue(*value);
i->setSingleStep(1);
i->setAccelerated(true);
settings->addWidget(i, y, x);
connect(i, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [value](int v) {
*value = v;
// TODO: Config
});
}
QWidget* ShaderSelector::makePage(GBAGLES2Shader* shader) {
if (!shader->nUniforms) {
return nullptr;
}
QWidget* page = new QWidget;
QFormLayout* layout = new QFormLayout;
page->setLayout(layout);
for (size_t u = 0 ; u < shaders[p].nUniforms; ++u) {
for (size_t u = 0 ; u < shader->nUniforms; ++u) {
QGridLayout* settings = new QGridLayout;
GBAGLES2Uniform* uniform = &shaders[p].uniforms[u];
GBAGLES2Uniform* uniform = &shader->uniforms[u];
switch (uniform->type) {
case GL_FLOAT:
addUniform(settings, &uniform->value.f, uniform->min.f, uniform->max.f, 0, 0);
@ -152,42 +198,7 @@ void ShaderSelector::refreshShaders() {
addUniform(settings, &uniform->value.ivec4[3], uniform->min.ivec4[3], uniform->max.ivec4[3], 0, 3);
break;
}
layout->addRow(shaders[p].uniforms[u].readableName, settings);
layout->addRow(shader->uniforms[u].readableName, settings);
}
m_ui.passes->addTab(page, tr("Pass %1").arg(p + 1));
}
#endif
}
void ShaderSelector::addUniform(QGridLayout* settings, float* value, float min, float max, int y, int x) {
QDoubleSpinBox* f = new QDoubleSpinBox;
f->setDecimals(3);
if (min < max) {
f->setMinimum(min);
f->setMaximum(max);
}
f->setValue(*value);
f->setSingleStep(0.001);
f->setAccelerated(true);
settings->addWidget(f, y, x);
connect(f, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), [value](double v) {
*value = v;
// TODO: Config
});
}
void ShaderSelector::addUniform(QGridLayout* settings, int* value, int min, int max, int y, int x) {
QSpinBox* i = new QSpinBox;
if (min < max) {
i->setMinimum(min);
i->setMaximum(max);
}
i->setValue(*value);
i->setSingleStep(1);
i->setAccelerated(true);
settings->addWidget(i, y, x);
connect(i, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [value](int v) {
*value = v;
// TODO: Config
});
return page;
}

View File

@ -10,6 +10,7 @@
#include "ui_ShaderSelector.h"
struct GBAGLES2Shader;
class QGridLayout;
struct VideoShader;
@ -36,6 +37,7 @@ private slots:
private:
void addUniform(QGridLayout*, float* value, float min, float max, int y, int x);
void addUniform(QGridLayout*, int* value, int min, int max, int y, int x);
QWidget* makePage(GBAGLES2Shader*);
Ui::ShaderSelector m_ui;
Display* m_display;

View File

@ -36,6 +36,7 @@ struct VideoShader {
const char* name;
const char* author;
const char* description;
void* preprocessShader;
void* passes;
size_t nPasses;
};