mirror of https://github.com/mgba-emu/mgba.git
Qt: Shader loading and unloading
This commit is contained in:
parent
88e56b5c40
commit
a9ae152dd4
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue