Qt: Shader loading and unloading

This commit is contained in:
Jeffrey Pfau 2015-11-22 13:46:46 -08:00
parent 88e56b5c40
commit a9ae152dd4
9 changed files with 122 additions and 12 deletions

View File

@ -53,6 +53,7 @@ public slots:
virtual void filter(bool filter);
virtual void framePosted(const uint32_t*) = 0;
virtual void setShaders(struct VDir*) = 0;
virtual void clearShaders() = 0;
void showMessage(const QString& message);
@ -62,7 +63,6 @@ protected:
MessagePainter* messagePainter() { return &m_messagePainter; }
private:
static Driver s_driver;
static const int MOUSE_DISAPPEAR_TIMER = 1000;

View File

@ -148,7 +148,15 @@ void DisplayGL::framePosted(const uint32_t* buffer) {
}
void DisplayGL::setShaders(struct VDir* shaders) {
QMetaObject::invokeMethod(m_painter, "setShaders", Q_ARG(struct VDir*, shaders));
if (m_drawThread) {
QMetaObject::invokeMethod(m_painter, "setShaders", Qt::BlockingQueuedConnection, Q_ARG(struct VDir*, shaders));
} else {
m_painter->setShaders(shaders);
}
}
void DisplayGL::clearShaders() {
QMetaObject::invokeMethod(m_painter, "clearShaders");
}
void DisplayGL::resizeEvent(QResizeEvent* event) {
@ -390,6 +398,23 @@ void PainterGL::setShaders(struct VDir* dir) {
#endif
}
void PainterGL::clearShaders() {
if (!supportsShaders()) {
return;
}
#if !defined(_WIN32) || defined(USE_EPOXY)
m_gl->makeCurrent();
#if defined(_WIN32) && defined(USE_EPOXY)
epoxy_handle_external_wglMakeCurrent();
#endif
if (m_shader.passes) {
GBAGLES2ShaderDetach(reinterpret_cast<GBAGLES2Context*>(m_backend));
GBAGLES2ShaderFree(&m_shader);
}
m_gl->doneCurrent();
#endif
}
VideoShader* PainterGL::shaders() {
return &m_shader;
}

View File

@ -59,6 +59,7 @@ public slots:
void filter(bool filter) override;
void framePosted(const uint32_t*) override;
void setShaders(struct VDir*) override;
void clearShaders() override;
protected:
virtual void paintEvent(QPaintEvent*) override {}
@ -99,6 +100,7 @@ public slots:
void filter(bool filter);
void setShaders(struct VDir*);
void clearShaders();
VideoShader* shaders();
private:

View File

@ -35,6 +35,7 @@ public slots:
void filter(bool filter) override;
void framePosted(const uint32_t*) override;
void setShaders(struct VDir*) override {}
void clearShaders() override {}
protected:
virtual void paintEvent(QPaintEvent*) override;

View File

@ -6,6 +6,8 @@
#include "ShaderSelector.h"
#include "Display.h"
#include "GBAApp.h"
#include "VFileDevice.h"
#include <QCheckBox>
#include <QDoubleSpinBox>
@ -30,6 +32,9 @@ ShaderSelector::ShaderSelector(Display* display, QWidget* parent)
m_ui.setupUi(this);
refreshShaders();
connect(m_ui.load, SIGNAL(clicked()), this, SLOT(selectShader()));
connect(m_ui.unload, SIGNAL(clicked()), this, SLOT(clearShader()));
}
ShaderSelector::~ShaderSelector() {
@ -47,15 +52,58 @@ void ShaderSelector::clear() {
}
}
void ShaderSelector::selectShader() {
QFileDialog *dialog = GBAApp::app()->getOpenFileDialog(nullptr, tr("Load shader"), tr("%1 Shader (%.shader)").arg(projectName));
dialog->setFileMode(QFileDialog::Directory);
dialog->exec();
QStringList names = dialog->selectedFiles();
if (names.count() == 1) {
loadShader(names[0]);
}
delete dialog;
refreshShaders();
}
void ShaderSelector::loadShader(const QString& path) {
VDir* shader = VFileDevice::openDir(path);
if (!shader) {
shader = VFileDevice::openArchive(path);
}
if (!shader) {
return;
}
m_display->setShaders(shader);
shader->close(shader);
// TODO: Config
}
void ShaderSelector::clearShader() {
m_display->clearShaders();
refreshShaders();
// TODO: Config
}
void ShaderSelector::refreshShaders() {
clear();
m_shaders = m_display->shaders();
if (!m_shaders) {
return;
}
m_ui.shaderName->setText(m_shaders->name);
m_ui.description->setText(m_shaders->description);
m_ui.author->setText(tr("by %1").arg(m_shaders->author));
if (m_shaders->name) {
m_ui.shaderName->setText(m_shaders->name);
} else {
m_ui.shaderName->setText(tr("No shader loaded"));
}
if (m_shaders->description) {
m_ui.description->setText(m_shaders->description);
} else {
m_ui.description->clear();
}
if (m_shaders->author) {
m_ui.author->setText(tr("by %1").arg(m_shaders->author));
} else {
m_ui.author->clear();
}
#if !defined(_WIN32) || defined(USE_EPOXY)
GBAGLES2Shader* shaders = static_cast<GBAGLES2Shader*>(m_shaders->passes);
@ -124,6 +172,7 @@ void ShaderSelector::addUniform(QGridLayout* settings, float* value, float min,
settings->addWidget(f, y, x);
connect(f, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), [value](double v) {
*value = v;
// TODO: Config
});
}
@ -139,5 +188,6 @@ void ShaderSelector::addUniform(QGridLayout* settings, int* value, int min, int
settings->addWidget(i, y, x);
connect(i, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [value](int v) {
*value = v;
// TODO: Config
});
}

View File

@ -28,6 +28,11 @@ public slots:
void refreshShaders();
void clear();
private slots:
void selectShader();
void loadShader(const QString& path);
void clearShader();
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);

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
<width>378</width>
<height>350</height>
</rect>
</property>
<property name="windowTitle">
@ -32,7 +32,7 @@
<item>
<widget class="QLabel" name="shaderName">
<property name="text">
<string>TextLabel</string>
<string>Name</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
@ -42,7 +42,7 @@
<item>
<widget class="QLabel" name="author">
<property name="text">
<string>TextLabel</string>
<string>Author</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -59,7 +59,7 @@
</font>
</property>
<property name="text">
<string>TextLabel</string>
<string>Description</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@ -80,6 +80,24 @@
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="unload">
<property name="text">
<string>Unload Shader</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="load">
<property name="text">
<string>Load New Shader</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">

View File

@ -26,6 +26,13 @@ qint64 VFileDevice::size() const {
return m_vf->size(m_vf);
}
VFile* VFileDevice::open(QString path, int mode) {
VFile* VFileDevice::open(const QString& path, int mode) {
return VFileOpen(path.toUtf8().constData(), mode);
}
VDir* VFileDevice::openDir(const QString& path) {
return VDirOpen(path.toUtf8().constData());
}
VDir* VFileDevice::openArchive(const QString& path) {
return VDirOpenArchive(path.toUtf8().constData());
}

View File

@ -20,7 +20,9 @@ Q_OBJECT
public:
VFileDevice(VFile* vf, QObject* parent = nullptr);
static VFile* open(QString path, int mode);
static VFile* open(const QString& path, int mode);
static VDir* openDir(const QString& path);
static VDir* openArchive(const QString& path);
protected:
virtual qint64 readData(char* data, qint64 maxSize) override;