Make material editor functional
This commit is contained in:
parent
4a01dab006
commit
09b6d59cf9
5 changed files with 146 additions and 12 deletions
4
data/test2.material
Normal file
4
data/test2.material
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"albedoTexture": "",
|
||||
"color": "1,0,0.0156863"
|
||||
}
|
|
@ -11,10 +11,10 @@ public:
|
|||
void setRenderer(Renderer* r) {
|
||||
renderer = r;
|
||||
}
|
||||
|
||||
|
||||
MeshAsset* loadMesh(const std::string& path);
|
||||
MaterialAsset* loadMaterial(const std::string& path);
|
||||
|
||||
|
||||
private:
|
||||
Renderer* renderer = nullptr;
|
||||
};
|
||||
|
|
|
@ -50,7 +50,13 @@ MeshAsset* AssetManager::loadMesh(const std::string& path) {
|
|||
}
|
||||
|
||||
MaterialAsset* AssetManager::loadMaterial(const std::string& path) {
|
||||
std::ifstream file("data/" + path);
|
||||
std::string fixedPath;
|
||||
if(path[0] != '/') // then this is an absolute path, and we absolutely do not want to mess with that
|
||||
fixedPath = "data/" + path;
|
||||
else
|
||||
fixedPath = path;
|
||||
|
||||
std::ifstream file(fixedPath);
|
||||
if(!file)
|
||||
return nullptr;
|
||||
|
||||
|
|
|
@ -2,14 +2,32 @@
|
|||
|
||||
#include <QMainWindow>
|
||||
#include <QVulkanInstance>
|
||||
#include <QGridLayout>
|
||||
#include <QStringList>
|
||||
|
||||
struct Context;
|
||||
struct MeshComponent;
|
||||
|
||||
class MainWindow : public QMainWindow {
|
||||
public:
|
||||
MainWindow(Context& context);
|
||||
~MainWindow();
|
||||
|
||||
private:
|
||||
void openMaterial(QString path);
|
||||
void saveMaterial(QString path);
|
||||
|
||||
void updateControls();
|
||||
|
||||
QStringList openedFiles;
|
||||
|
||||
QAction* saveAction, *saveAsAction, *openRecentAction;
|
||||
|
||||
QString currentlyOpenMaterial;
|
||||
MeshComponent* meshComponent;
|
||||
|
||||
QGridLayout* attributesLayout;
|
||||
|
||||
Context& context;
|
||||
QVulkanInstance* instance = nullptr;
|
||||
};
|
||||
|
|
|
@ -6,8 +6,11 @@
|
|||
#include <QAction>
|
||||
#include <QVulkanWindow>
|
||||
#include <QHBoxLayout>
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QFileDialog>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QSettings>
|
||||
|
||||
#include "renderwindow.h"
|
||||
#include "renderer.h"
|
||||
|
@ -15,11 +18,15 @@
|
|||
#include "ecs.h"
|
||||
#include "worldmanager.h"
|
||||
#include "material.h"
|
||||
#include "assetmanager.h"
|
||||
|
||||
MainWindow::MainWindow(Context& context) : context(context) {
|
||||
setWindowTitle("Material Editor");
|
||||
resize(1280, 720);
|
||||
|
||||
QSettings settings;
|
||||
if(!settings.value("recentlyOpened").isNull())
|
||||
openedFiles = settings.value("recentlyOpened").toStringList();
|
||||
|
||||
QMenuBar* mainMenuBar = new QMenuBar();
|
||||
setMenuBar(mainMenuBar);
|
||||
|
||||
|
@ -30,26 +37,47 @@ MainWindow::MainWindow(Context& context) : context(context) {
|
|||
{
|
||||
QAction* newAction = new QAction("New");
|
||||
newAction->setIcon(QIcon::fromTheme("document-new"));
|
||||
connect(newAction, &QAction::triggered, [this] {
|
||||
openMaterial("basic.material");
|
||||
currentlyOpenMaterial = "new material";
|
||||
});
|
||||
newAction->setShortcut(QKeySequence("CTRL+N"));
|
||||
fileMenu->addAction(newAction);
|
||||
|
||||
QAction* openAction = new QAction("Open");
|
||||
connect(openAction, &QAction::triggered, [this] {
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
|
||||
"../data/",
|
||||
tr("Material Files (*.material)"));
|
||||
if(!fileName.isEmpty())
|
||||
openMaterial(fileName);
|
||||
});
|
||||
openAction->setIcon(QIcon::fromTheme("document-open"));
|
||||
openAction->setShortcut(QKeySequence("CTRL+O"));
|
||||
fileMenu->addAction(openAction);
|
||||
|
||||
QAction* openRecentAction = new QAction("Open Recent...");
|
||||
openRecentAction = new QAction("Open Recent...");
|
||||
openRecentAction->setIcon(QIcon::fromTheme("document-open-recent"));
|
||||
fileMenu->addAction(openRecentAction);
|
||||
|
||||
fileMenu->addSeparator();
|
||||
|
||||
QAction* saveAction = new QAction("Save");
|
||||
saveAction = new QAction("Save");
|
||||
connect(saveAction, &QAction::triggered, [this] {
|
||||
saveMaterial(currentlyOpenMaterial);
|
||||
});
|
||||
saveAction->setIcon(QIcon::fromTheme("document-save"));
|
||||
saveAction->setShortcut(QKeySequence("CTRL+S"));
|
||||
fileMenu->addAction(saveAction);
|
||||
|
||||
QAction* saveAsAction = new QAction("Save As...");
|
||||
saveAsAction = new QAction("Save As...");
|
||||
connect(saveAsAction, &QAction::triggered, [this] {
|
||||
QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),
|
||||
"../data/",
|
||||
tr("Material Files (*.material)"));
|
||||
if(!fileName.isEmpty())
|
||||
saveMaterial(fileName);
|
||||
});
|
||||
saveAsAction->setIcon(QIcon::fromTheme("document-save-as"));
|
||||
saveAsAction->setShortcut(QKeySequence("CTRL+SHIFT+S"));
|
||||
fileMenu->addAction(saveAsAction);
|
||||
|
@ -69,7 +97,7 @@ MainWindow::MainWindow(Context& context) : context(context) {
|
|||
QHBoxLayout* layout = new QHBoxLayout();
|
||||
centralWidget->setLayout(layout);
|
||||
|
||||
QGridLayout* attributesLayout = new QGridLayout();
|
||||
attributesLayout = new QGridLayout();
|
||||
attributesLayout->setAlignment(Qt::AlignTop);
|
||||
attributesLayout->setSpacing(0);
|
||||
layout->addLayout(attributesLayout);
|
||||
|
@ -80,9 +108,7 @@ MainWindow::MainWindow(Context& context) : context(context) {
|
|||
auto meshComponents = ECS::getWorldComponents<MeshComponent>(worldManager.getCurrentWorld());
|
||||
|
||||
auto& [id, mesh] = meshComponents[0];
|
||||
|
||||
ColorEdit* colorEdit = new ColorEdit(mesh->material->color);
|
||||
attributesLayout->addWidget(colorEdit, 0, 1);
|
||||
meshComponent = mesh;
|
||||
|
||||
instance = new QVulkanInstance();
|
||||
instance->setVkInstance(context.renderer->getInstance());
|
||||
|
@ -93,5 +119,85 @@ MainWindow::MainWindow(Context& context) : context(context) {
|
|||
|
||||
QWidget* wrapper = QWidget::createWindowContainer(window);
|
||||
layout->addWidget(wrapper);
|
||||
|
||||
updateControls();
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow() {
|
||||
QSettings settings;
|
||||
settings.setValue("recentlyOpened", openedFiles);
|
||||
}
|
||||
|
||||
void MainWindow::openMaterial(QString path) {
|
||||
currentlyOpenMaterial = path;
|
||||
|
||||
meshComponent->material = assetManager.loadMaterial(path.toStdString());
|
||||
|
||||
ColorEdit* colorEdit = new ColorEdit(meshComponent->material->color);
|
||||
attributesLayout->addWidget(colorEdit, 0, 1);
|
||||
|
||||
if(openedFiles.contains(path))
|
||||
openedFiles.removeOne(path);
|
||||
|
||||
openedFiles.push_back(path);
|
||||
|
||||
updateControls();
|
||||
}
|
||||
|
||||
void MainWindow::saveMaterial(QString path) {
|
||||
MaterialAsset* material = meshComponent->material;
|
||||
|
||||
QString color;
|
||||
color = QString::number(material->color.x) + "," + QString::number(material->color.y) + "," + QString::number(material->color.z);
|
||||
|
||||
QJsonObject object {
|
||||
{"albedoTexture", material->albedoTexturePath.c_str()},
|
||||
{"color", color}
|
||||
};
|
||||
|
||||
QJsonDocument document(object);
|
||||
|
||||
QFile jsonFile(path);
|
||||
jsonFile.open(QFile::WriteOnly);
|
||||
jsonFile.write(document.toJson());
|
||||
|
||||
currentlyOpenMaterial = path;
|
||||
}
|
||||
|
||||
void MainWindow::updateControls() {
|
||||
if(!currentlyOpenMaterial.isEmpty())
|
||||
setWindowTitle("Material Editor - " + currentlyOpenMaterial);
|
||||
else
|
||||
setWindowTitle("Material Editor");
|
||||
|
||||
saveAction->setEnabled(!currentlyOpenMaterial.isEmpty());
|
||||
saveAsAction->setEnabled(!currentlyOpenMaterial.isEmpty());
|
||||
|
||||
if(!openedFiles.empty()) {
|
||||
QMenu* recentlyOpenedMenu = new QMenu();
|
||||
for(auto file : openedFiles) {
|
||||
QAction* fileAction = new QAction(file);
|
||||
connect(fileAction, &QAction::triggered, [this, file] {
|
||||
openMaterial(file);
|
||||
});
|
||||
fileAction->setIcon(QIcon("data/maticon.png"));
|
||||
recentlyOpenedMenu->addAction(fileAction);
|
||||
}
|
||||
|
||||
recentlyOpenedMenu->addSeparator();
|
||||
|
||||
QAction* clearRecentAction = new QAction("Clear");
|
||||
connect(clearRecentAction, &QAction::triggered, [this] {
|
||||
openedFiles.clear();
|
||||
updateControls();
|
||||
});
|
||||
clearRecentAction->setIcon(QIcon::fromTheme("edit-clear"));
|
||||
recentlyOpenedMenu->addAction(clearRecentAction);
|
||||
|
||||
openRecentAction->setEnabled(true);
|
||||
openRecentAction->setMenu(recentlyOpenedMenu);
|
||||
} else {
|
||||
openRecentAction->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Reference in a new issue