Merge branch 'master' into terrain_merge

This commit is contained in:
Linloir 2022-12-19 21:36:09 +08:00 committed by GitHub
commit e88edfcb02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 496 additions and 25 deletions

1
.gitignore vendored
View File

@ -364,4 +364,5 @@ FodyWeavers.xsd
/FinalProject/temp/shaders
/Models
/Terrains
/terrain

View File

@ -125,6 +125,12 @@
<ClCompile Include="roundedcornerwidget.cpp" />
<ClCompile Include="sceneviewer.cpp" />
<ClCompile Include="scrolllistwidget.cpp" />
<ClCompile Include="settingpage.cpp">
<DynamicSource Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">input</DynamicSource>
<QtMocFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(Filename).moc</QtMocFileName>
<DynamicSource Condition="'$(Configuration)|$(Platform)'=='Release|x64'">input</DynamicSource>
<QtMocFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(Filename).moc</QtMocFileName>
</ClCompile>
<ClCompile Include="shader.cpp" />
<ClCompile Include="sidebar.cpp" />
<ClCompile Include="skybox.cpp" />
@ -162,6 +168,7 @@
<QtMoc Include="modelthumbnailwidget.h" />
<QtMoc Include="modelattrslide.h" />
<ClInclude Include="ray.h" />
<QtMoc Include="settingpage.h" />
<ClInclude Include="skybox.h" />
<QtMoc Include="slider.h" />
<ClInclude Include="terrain.h" />

View File

@ -77,6 +77,12 @@
<Filter Include="Header Files\Qt Widgets\Pages\Scene Editor\Object Setter">
<UniqueIdentifier>{6c5ac0df-26ad-40ad-860c-3d0372b81094}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Qt Widgets\Pages\Setting Page">
<UniqueIdentifier>{cb50686f-5bfb-4087-a103-04188e392f6d}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Qt Widgets\Pages\Setting Page">
<UniqueIdentifier>{9bdb6f33-7b69-4419-878a-e4891d73f84f}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<QtRcc Include="mainwindow.qrc">
@ -180,8 +186,8 @@
<ClCompile Include="modelattrslide.cpp">
<Filter>Source Files\Qt Widgets\Pages\Scene Editor\Object Setter</Filter>
</ClCompile>
<ClCompile Include="terrain.cpp">
<Filter>Source Files\OpenGL Abstractions</Filter>
<ClCompile Include="settingpage.cpp">
<Filter>Source Files\Qt Widgets\Pages\Setting Page</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
@ -292,6 +298,9 @@
<QtMoc Include="modelattrslide.h">
<Filter>Header Files\Qt Widgets\Pages\Scene Editor\Object Setter</Filter>
</QtMoc>
<QtMoc Include="settingpage.h">
<Filter>Header Files\Qt Widgets\Pages\Setting Page</Filter>
</QtMoc>
</ItemGroup>
<ItemGroup>
<None Include="fragmentshader.glsl">

View File

@ -26,7 +26,7 @@ AboutPage::AboutPage(QWidget* parent) :
_mainWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
_mainWidget->setStyleSheet("QWidget#mainWidget { background-color: #efefef; border-radius: 8px; }");
_mainLayout = new QVBoxLayout(_mainWidget);
_mainLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
_mainLayout->setAlignment(Qt::AlignTop);
_mainLayout->setContentsMargins(0, 8, 0, 8);
_mainLayout->setSpacing(8);
_mainWidget->setLayout(_mainLayout);

View File

@ -78,6 +78,12 @@ EditorPage::EditorPage(QWidget* parent) :
EditorPage::~EditorPage() {}
void EditorPage::updateSetting(QPair<QString, QString> setting) {
if (_sceneViewer != nullptr) {
_sceneViewer->updateSetting(setting);
}
}
PushButton* EditorPage::getPageIconButton(QWidget* context) {
// Check for existed button
if (_iconButton != nullptr) {

View File

@ -3,6 +3,7 @@
#include <qwidget.h>
#include <qboxlayout.h>
#include <qlabel.h>
#include <qpair.h>
#include "pagewidget.h"
#include "sceneviewer.h"
@ -44,6 +45,9 @@ private:
ModelSetter* _modelSetter = nullptr;
public:
void updateSetting(QPair<QString, QString> setting);
public:
virtual PushButton* getPageIconButton(QWidget* context) override;
virtual PushButton* getPageTextButton(QWidget* context) override;

View File

@ -30,19 +30,21 @@ public:
class DirLight : public Illuminer{
protected:
glm::vec3 _direction; // The outgoing direction of the light source
float _intensity = 50;
public:
DirLight(glm::vec3 direction = glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3 color = glm::vec3(1.0f));
~DirLight();
protected:
virtual glm::vec3 ambientLightColor() const override { return glm::vec3(0.2f) * _lightColor; }
virtual glm::vec3 diffuseLightColor() const override { return glm::vec3(0.6f) * _lightColor; }
virtual glm::vec3 ambientLightColor() const override { return glm::vec3(_intensity / 200.0f) * _lightColor; }
virtual glm::vec3 diffuseLightColor() const override { return glm::vec3(_intensity / 100.0f) * _lightColor; }
virtual glm::vec3 specularLightColor() const override { return glm::vec3(1.0f) * _lightColor; }
public:
glm::vec3 lightDirection() const { return _direction; } // The same direction as the outgoing direction
void setLightDirection(glm::vec3 direction) { _direction = direction; }
void setIntensity(float intensity) { _intensity = intensity; }
// Render util function
virtual void updateShader(ShaderProgram shader, int index) const override;

View File

@ -45,10 +45,17 @@ MainWindow::MainWindow(QWidget *parent)
_editorPage->setMouseTracking(true);
_sideBar->addPage(_editorPage);
// Create setting page and connect to side bar
_settingPage = new SettingPage(_placeHolderWidget);
_settingPage->setMouseTracking(true);
_sideBar->addPage(_settingPage);
// Create about page and connect to side bar
_aboutPage = new AboutPage(_placeHolderWidget);
_aboutPage->setMouseTracking(true);
_sideBar->addPage(_aboutPage);
connect(_settingPage, &SettingPage::onSettingsChanged, _editorPage, &EditorPage::updateSetting);
}
MainWindow::~MainWindow() {
@ -65,6 +72,7 @@ void MainWindow::resizePages(QResizeEvent* event) {
// Resize the editor page
_editorPage->resize(size);
_settingPage->resize(size);
_aboutPage->resize(size);
}
@ -74,6 +82,7 @@ void MainWindow::showEvent(QShowEvent* event) {
// Resize all the pages based on the placeholder widget
_editorPage->resize(_placeHolderWidget->size());
_settingPage->resize(_placeHolderWidget->size());
_aboutPage->resize(_placeHolderWidget->size());
}

View File

@ -6,6 +6,7 @@
#include "sidebar.h"
#include "editorpage.h"
#include "aboutpage.h"
#include "settingpage.h"
class MainWindow : public FramelessWindow
{
@ -23,6 +24,7 @@ private:
SideBar* _sideBar = nullptr;
EditorPage* _editorPage = nullptr;
AboutPage* _aboutPage = nullptr;
SettingPage* _settingPage = nullptr;
// Place holder widget for resizing pages
QWidget* _placeHolderWidget = nullptr;

View File

@ -157,24 +157,8 @@ void SceneViewer::initializeGL() {
terrainVertexShader.dispose();
terrainFragmentShader.dispose();
// Test Code Start
_sky = new SkyBox("D:\\ProgrammingFile\\SceneEditor\\SkyBoxes");
_terrain = new Terrain("D:\\ProgrammingFile\\SceneEditor\\Terrains");
_dirLight = new DirLight();
//Model* model = new Model("E:\\Repositories\\CollegeProjects\\CGAssignments\\FinalProject\\Models\\backpack\\backpack.obj");
//Renderable* backpack = new Renderable(model);
//backpack->move(glm::vec3(-5.0f, -2.0f, -2.0f));
//backpack->updateBoundary();
//_objects.push_back(backpack);
//
//Renderable* backpack2 = new Renderable(model);
//backpack2->makeLight();
//backpack2->originalLight()->setIdealDistance(500);
//_objects.push_back(backpack2);
// Test Code End
_camera.setPosition(glm::vec3(0.0f, 0.0f, 10.0f));
}
@ -239,7 +223,7 @@ void SceneViewer::paintGL() {
_shaderProgram.setUniform("pointlightnr", pointLights);
_shaderProgram.setUniform("spotlightnr", spotLights);
if (_dirLight != nullptr) {
if (_dirLight != nullptr && _dirLightOn) {
_dirLight->updateShader(_shaderProgram, 0);
}
@ -569,3 +553,62 @@ void SceneViewer::deleteObject() {
emit onSelect(nullptr);
parentWidget()->update();
}
void SceneViewer::updateSetting(QPair<QString, QString> setting) {
makeCurrent();
if (setting.first == "stickSurface") {
_stickToSurface = true;
}
else if (setting.first == "skybox") {
if (_sky != nullptr) {
delete _sky;
_sky = nullptr;
}
if (!setting.second.isEmpty()) {
_sky = new SkyBox(setting.second.toStdString());
}
}
else if (setting.first == "terrain") {
if (_terrain != nullptr) {
delete _terrain;
_terrain = nullptr;
}
if (!setting.second.isEmpty()) {
_terrain = new Terrain(setting.second.toStdString());
}
}
else if (setting.first == "dirLight") {
if (setting.second == "true") {
_dirLightOn = true;
}
else {
_dirLightOn = false;
}
}
else if (setting.first == "dirLightColorR") {
_dirLight->setLightColor(glm::vec3(setting.second.toFloat(), _dirLight->lightColor().y, _dirLight->lightColor().z));
}
else if (setting.first == "dirLightColorG") {
_dirLight->setLightColor(glm::vec3(_dirLight->lightColor().x, setting.second.toFloat(), _dirLight->lightColor().z));
}
else if (setting.first == "dirLightColorB") {
_dirLight->setLightColor(glm::vec3(_dirLight->lightColor().x, _dirLight->lightColor().y, setting.second.toFloat()));
}
else if (setting.first == "dirLightIntensity") {
_dirLight->setIntensity(setting.second.toFloat());
}
else if (setting.first == "dirLightDir") {
// parse "x,y,z"
QStringList list = setting.second.split(",");
if (list.size() == 3) {
_dirLight->setLightDirection(glm::vec3(list[0].toFloat(), list[1].toFloat(), list[2].toFloat()));
}
else {
Logger::error("Invalid direction light direction setting");
}
}
else {
Logger::warning("Unknown setting input");
}
doneCurrent();
}

View File

@ -3,6 +3,7 @@
#include <qwidget.h>
#include <qevent.h>
#include <qopenglfunctions.h>
#include <qpair.h>
#include <QtOpenGLWidgets/qopenglwidget.h>
#include <vector>
@ -24,10 +25,11 @@ private:
// OpenGL section-------------------------------------
// List of objects currently in the scene
std::vector<Renderable*> _objects;
// Sky Box
SkyBox* _sky = nullptr;
// Dir light
bool _dirLightOn = false;
DirLight* _dirLight = nullptr;
// Sky Box
SkyBox* _sky;
// Terrain
Terrain* _terrain;
// Shader program for objects
@ -103,6 +105,7 @@ public:
parentWidget()->update();
}
void deleteObject();
void updateSetting(QPair<QString, QString> setting);
signals:
void onHover(Renderable* object);

View File

@ -0,0 +1,313 @@
#include <qfiledialog.h>
#include <qmessagebox.h>
#include <GLM/glm.hpp>
#include "settingpage.h"
#include "logger.h"
SettingPage::SettingPage(QWidget* parent) :
PageWidget(parent)
{
_contentWidget->setMouseTracking(true);
// Construct title layout
_titleLayout = new QVBoxLayout(_contentWidget);
_titleLayout->setContentsMargins(28, 46, 28, 28);
_titleLayout->setSpacing(18);
_titleLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
_contentWidget->setLayout(_titleLayout);
// Construct title
_titleLabel = new QLabel("SETTINGS", _contentWidget);
_titleLabel->setFont(_titleFont);
_titleLayout->addWidget(_titleLabel);
_titleLabel->show();
// Construct main layout
_mainWidget = new QWidget(_contentWidget);
_mainWidget->setObjectName("mainWidget");
_mainWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
_mainWidget->setStyleSheet("QWidget#mainWidget { background-color: #f5f5f5; border-radius: 8px; }");
_mainLayout = new QVBoxLayout(_mainWidget);
_mainLayout->setAlignment(Qt::AlignTop);
_mainLayout->setContentsMargins(12, 12, 12, 12);
_mainLayout->setSpacing(8);
_mainWidget->setLayout(_mainLayout);
_titleLayout->addWidget(_mainWidget);
_mainWidget->show();
// Create stick surface button
_stickSurfaceBtn = new PushButton(nullptr, _mainWidget);
_stickSurfaceBtn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
_stickSurfaceBtn->setMaximumHeight(48);
_stickSurfaceBtn->setBackgroundColor(QColor(220, 220, 220));
_stickSurfaceBtnLabel = new QLabel("Stick to Surface", _stickSurfaceBtn);
_stickSurfaceBtnLabel->setAlignment(Qt::AlignCenter);
_stickSurfaceBtnLabel->show();
_stickSurfaceBtn->setChildWidget(_stickSurfaceBtnLabel);
_mainLayout->addWidget(_stickSurfaceBtn);
_stickSurfaceBtn->show();
connect(_stickSurfaceBtn, &PushButton::onClick, this, [=]() {
if (_stickSurfaceBtn->isSelected()) {
_stickSurfaceBtn->deselect();
emit onSettingsChanged(QPair<QString, QString>("stickSurface", "false"));
}
else {
_stickSurfaceBtn->select();
emit onSettingsChanged(QPair<QString, QString>("stickSurface", "true"));
}
});
// Create skybox selector
_skyTerSelContainer = new QWidget(_mainWidget);
_skyTerSelContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
_skyTerSelContainer->setMaximumHeight(48);
_skyTerSelLayout = new QHBoxLayout(_skyTerSelContainer);
_skyTerSelLayout->setContentsMargins(0, 0, 0, 0);
_skyTerSelLayout->setSpacing(6);
_skyTerSelContainer->setLayout(_skyTerSelLayout);
_mainLayout->addWidget(_skyTerSelContainer);
_skyTerSelContainer->show();
_skySelector = new PushButton(nullptr, _skyTerSelContainer);
_skySelector->setBackgroundColor(QColor(220, 220, 220));
_skySelector->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
_skySelectorLabel = new QLabel("Import Skybox", _skySelector);
_skySelectorLabel->setAlignment(Qt::AlignCenter);
_skySelectorLabel->show();
_skySelector->setChildWidget(_skySelectorLabel);
_skyTerSelLayout->addWidget(_skySelector);
_skySelector->show();
connect(_skySelector, &PushButton::onClick, this, &SettingPage::selectSkyBox);
_terrainSelector = new PushButton(nullptr, _skyTerSelContainer);
_terrainSelector->setBackgroundColor(QColor(220, 220, 220));
_terrainSelector->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
_terrainSelectorLabel = new QLabel("Import Terrain", _terrainSelector);
_terrainSelectorLabel->setAlignment(Qt::AlignCenter);
_terrainSelectorLabel->show();
_terrainSelector->setChildWidget(_terrainSelectorLabel);
_skyTerSelLayout->addWidget(_terrainSelector);
_terrainSelector->show();
connect(_terrainSelector, &PushButton::onClick, this, &SettingPage::selectTerrain);
// Create direction light setter
_dirLightSwitch = new PushButton(nullptr, _mainWidget);
_dirLightSwitch->setBackgroundColor(QColor(220, 220, 220));
_dirLightSwitch->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
_dirLightSwitch->setMaximumHeight(48);
_dirLightSwitchLabel = new QLabel("Directional Light", _dirLightSwitch);
_dirLightSwitchLabel->setAlignment(Qt::AlignCenter);
_dirLightSwitchLabel->show();
_dirLightSwitch->setChildWidget(_dirLightSwitchLabel);
_mainLayout->addWidget(_dirLightSwitch);
_dirLightSwitch->show();
connect(_dirLightSwitch, &PushButton::onClick, this, [=]() {
if (_dirLightSwitch->isSelected()) {
_dirLightSwitch->deselect();
_dirLightColorR->setEnabled(false);
_dirLightColorG->setEnabled(false);
_dirLightColorB->setEnabled(false);
_dirLightIntensity->setEnabled(false);
_dirLightTheta->setEnabled(false);
_dirLightPhi->setEnabled(false);
emit onSettingsChanged(QPair<QString, QString>("dirLight", "false"));
}
else {
_dirLightSwitch->select();
_dirLightColorR->setEnabled(true);
_dirLightColorG->setEnabled(true);
_dirLightColorB->setEnabled(true);
_dirLightIntensity->setEnabled(true);
_dirLightTheta->setEnabled(true);
_dirLightPhi->setEnabled(true);
emit onSettingsChanged(QPair<QString, QString>("dirLight", "true"));
}
});
_dirLightColorR = new ModelAttributeSlide("Red", 0, 255, 255, _mainWidget);
_dirLightColorR->setValue(255);
_dirLightColorR->setEnabled(false);
_mainLayout->addWidget(_dirLightColorR);
_dirLightColorR->show();
connect(_dirLightColorR, &ModelAttributeSlide::onChanged, this, [=](int value) {
emit onSettingsChanged(QPair<QString, QString>("dirLightColorR", QString::number(value / 255.0f)));
});
_dirLightColorG = new ModelAttributeSlide("Green", 0, 255, 255, _mainWidget);
_dirLightColorG->setValue(255);
_dirLightColorG->setEnabled(false);
_mainLayout->addWidget(_dirLightColorG);
_dirLightColorG->show();
connect(_dirLightColorG, &ModelAttributeSlide::onChanged, this, [=](int value) {
emit onSettingsChanged(QPair<QString, QString>("dirLightColorG", QString::number(value / 255.0f)));
});
_dirLightColorB = new ModelAttributeSlide("Blue", 0, 255, 255, _mainWidget);
_dirLightColorB->setValue(255);
_dirLightColorB->setEnabled(false);
_mainLayout->addWidget(_dirLightColorB);
_dirLightColorB->show();
connect(_dirLightColorB, &ModelAttributeSlide::onChanged, this, [=](int value) {
emit onSettingsChanged(QPair<QString, QString>("dirLightColorB", QString::number(value / 255.0f)));
});
_dirLightIntensity = new ModelAttributeSlide("Intensity", 0, 100, 100, _mainWidget);
_dirLightIntensity->setValue(50);
_dirLightIntensity->setEnabled(false);
_mainLayout->addWidget(_dirLightIntensity);
_dirLightIntensity->show();
connect(_dirLightIntensity, &ModelAttributeSlide::onChanged, this, [=](int value) {
emit onSettingsChanged(QPair<QString, QString>("dirLightIntensity", QString::number(value)));
});
_dirLightTheta = new ModelAttributeSlide("Rotate\u03B8", 0, 360, 3600, _mainWidget);
_dirLightTheta->setValue(0);
_dirLightTheta->setEnabled(false);
_mainLayout->addWidget(_dirLightTheta);
_dirLightTheta->show();
connect(_dirLightTheta, &ModelAttributeSlide::onChanged, this, [=]() {
// Calculate direction vector by theta and phi
float theta = _dirLightTheta->val(); // theta angle
float phi = _dirLightPhi->val(); // phi angle
float x = sin(theta) * cos(phi);
float y = sin(theta) * sin(phi);
float z = cos(theta);
glm::vec3 dir = glm::vec3(x, y, z);
emit onSettingsChanged(QPair<QString, QString>("dirLightDir", QString::number(dir.x) + "," + QString::number(dir.y) + "," + QString::number(dir.z)));
});
_dirLightPhi = new ModelAttributeSlide("Rotate\u03C6", 0, 360, 3600, _mainWidget);
_dirLightPhi->setValue(0);
_dirLightPhi->setEnabled(false);
_mainLayout->addWidget(_dirLightPhi);
_dirLightPhi->show();
connect(_dirLightPhi, &ModelAttributeSlide::onChanged, this, [=]() {
// Calculate direction vector by theta and phi
float theta = _dirLightTheta->val(); // theta angle
float phi = _dirLightPhi->val(); // phi angle
float x = sin(theta) * cos(phi);
float y = sin(theta) * sin(phi);
float z = cos(theta);
glm::vec3 dir = glm::vec3(x, y, z);
emit onSettingsChanged(QPair<QString, QString>("dirLightDir", QString::number(dir.x) + "," + QString::number(dir.y) + "," + QString::number(dir.z)));
});
}
SettingPage::~SettingPage() {}
PushButton* SettingPage::getPageIconButton(QWidget* context) {
// Check for existed button
if (_iconButton != nullptr) {
return _iconButton;
}
// Generate new icon button
_iconButton = new PushButton(nullptr, context);
_iconButton->setMargin(20, 18, 16, 18);
_iconButtonLabel = new QLabel(_iconButton);
_iconButtonLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
QFont iconButtonFont("Font Awesome 6 Free Solid", 12);
iconButtonFont.setStyleStrategy(QFont::PreferAntialias);
_iconButtonLabel->setFont(iconButtonFont);
_iconButtonLabel->setText("\uf013");
_iconButtonLabel->setAlignment(Qt::AlignLeft);
_iconButton->setChildWidget(_iconButtonLabel);
// Return newly generated icon
return _iconButton;
}
PushButton* SettingPage::getPageTextButton(QWidget* context) {
// Check for existed button
if (_textButton != nullptr) {
return _textButton;
}
// Generate new text button
_textButton = new PushButton(nullptr, context);
_textButton->setMargin(20, 18, 16, 18);
_textButtonWidget = new QWidget(_textButton);
_textButtonLayout = new QHBoxLayout(_textButtonWidget);
_textButtonLayout->setContentsMargins(0, 0, 0, 0);
_textButtonLayout->setSpacing(12);
_textButtonWidget->setLayout(_textButtonLayout);
// Generate text button contents
_textButtonIcon = new QLabel(_textButtonWidget);
QFont textButtonFont("Font Awesome 6 Free Solid", 12);
textButtonFont.setStyleStrategy(QFont::PreferQuality);
_textButtonIcon->setFont(textButtonFont);
_textButtonIcon->setText("\uf013");
_textButtonIcon->setAlignment(Qt::AlignLeft);
_textButtonLabel = new QLabel(_textButtonWidget);
_textButtonLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
_textButtonLabel->setText("Settings");
_textButtonLabel->setAlignment(Qt::AlignLeft);
// Add text button contents to layout
_textButtonLayout->addWidget(_textButtonIcon);
_textButtonLayout->addWidget(_textButtonLabel);
_textButtonIcon->show();
_textButtonLabel->show();
// Set text button child widget
_textButton->setChildWidget(_textButtonWidget);
_textButtonWidget->show();
// Return newly generated text button
return _textButton;
}
void SettingPage::selectSkyBox() {
// Select a directory that contains back.jpg, bottom.jpg, front.jpg, left.jpg, right.jpg, top.jpg
QString dir = QFileDialog::getExistingDirectory(this, tr("Select Skybox Directory"), QDir::currentPath(), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if (dir.isEmpty()) {
Logger::warning("Tempt to open invalid skybox folder");
emit onSettingsChanged(QPair<QString, QString>("skybox", ""));
return;
}
// Check if the directory contains all the required files
QDir skyboxDir(dir);
QStringList skyboxFiles = skyboxDir.entryList(QStringList() << "*.jpg", QDir::Files);
if (
skyboxFiles.indexOf("back.jpg") == -1 ||
skyboxFiles.indexOf("bottom.jpg") == -1 ||
skyboxFiles.indexOf("front.jpg") == -1 ||
skyboxFiles.indexOf("left.jpg") == -1 ||
skyboxFiles.indexOf("right.jpg") == -1 ||
skyboxFiles.indexOf("top.jpg") == -1
) {
QMessageBox::warning(this, "Error", "The selected directory does not contain all the required files.");
Logger::warning("Tempt to open invalid skybox folder");
emit onSettingsChanged(QPair<QString, QString>("skybox", ""));
return;
}
emit onSettingsChanged(QPair<QString, QString>("skybox", dir));
}
void SettingPage::selectTerrain() {
QString dir = QFileDialog::getExistingDirectory(this, tr("Select Terrain Directory"), QDir::currentPath(), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if (dir.isEmpty()) {
Logger::warning("Tempt to open invalid terrain folder");
emit onSettingsChanged(QPair<QString, QString>("terrain", ""));
return;
}
QDir terrainDir(dir);
QStringList terrainFiles = terrainDir.entryList(QStringList() << "*.jpg", QDir::Files);
if (
terrainFiles.indexOf("heightmap.png") == -1 ||
terrainFiles.indexOf("texture.jpg") == -1
) {
QMessageBox::warning(this, "Error", "The selected directory does not contain all the required files.");
Logger::warning("Tempt to open invalid terrain folder");
emit onSettingsChanged(QPair<QString, QString>("terrain", ""));
return;
}
emit onSettingsChanged(QPair<QString, QString>("terrain", dir));
}

View File

@ -0,0 +1,72 @@
#pragma once
#include <qwidget.h>
#include <qlabel.h>
#include <qboxlayout.h>
#include <qpair.h>
#include "pagewidget.h"
#include "lineeditwidget.h"
#include "modelattrslide.h"
class SettingPage : public PageWidget
{
Q_OBJECT
public:
SettingPage(QWidget* parent = 0);
~SettingPage();
private:
// Push button icons
QLabel* _iconButtonLabel = nullptr;
QWidget* _textButtonWidget = nullptr;
QHBoxLayout* _textButtonLayout = nullptr;
QLabel* _textButtonIcon = nullptr;
QLabel* _textButtonLabel = nullptr;
// UI elements
QVBoxLayout* _titleLayout = nullptr;
const QFont _titleFont = QFont("DengXian", 26, QFont::ExtraLight);
QLabel* _titleLabel = nullptr;
QWidget* _mainWidget = nullptr;
QVBoxLayout* _mainLayout = nullptr;
// Stick to surface checkbox
PushButton* _stickSurfaceBtn = nullptr;
QLabel* _stickSurfaceBtnLabel = nullptr;
// Terrain & Skybox selector
QWidget* _skyTerSelContainer = nullptr;
QHBoxLayout* _skyTerSelLayout = nullptr;
PushButton* _skySelector = nullptr;
QLabel* _skySelectorLabel = nullptr;
PushButton* _terrainSelector = nullptr;
QLabel* _terrainSelectorLabel = nullptr;
// Dir light setter
//QWidget* _dirLightSetter = nullptr;
//QHBoxLayout* _dirLightSetterLayout = nullptr;
PushButton* _dirLightSwitch = nullptr;
QLabel* _dirLightSwitchLabel = nullptr;
//QVBoxLayout* _dirLightColorLayout = nullptr;
ModelAttributeSlide* _dirLightColorR = nullptr;
ModelAttributeSlide* _dirLightColorG = nullptr;
ModelAttributeSlide* _dirLightColorB = nullptr;
//QVBoxLayout* _dirLightAttrLayout;
ModelAttributeSlide* _dirLightIntensity = nullptr;
ModelAttributeSlide* _dirLightTheta = nullptr;
ModelAttributeSlide* _dirLightPhi = nullptr;
private:
void selectSkyBox();
void selectTerrain();
public:
virtual PushButton* getPageIconButton(QWidget* context) override;
virtual PushButton* getPageTextButton(QWidget* context) override;
signals:
void onSettingsChanged(QPair<QString, QString> settings);
};