mirror of
https://github.com/Linloir/SceneEditor.git
synced 2025-12-16 23:18:12 +08:00
Merge branch 'master' into terrain_merge
This commit is contained in:
commit
e88edfcb02
1
.gitignore
vendored
1
.gitignore
vendored
@ -364,4 +364,5 @@ FodyWeavers.xsd
|
|||||||
/FinalProject/temp/shaders
|
/FinalProject/temp/shaders
|
||||||
/Models
|
/Models
|
||||||
/Terrains
|
/Terrains
|
||||||
|
|
||||||
/terrain
|
/terrain
|
||||||
|
|||||||
@ -125,6 +125,12 @@
|
|||||||
<ClCompile Include="roundedcornerwidget.cpp" />
|
<ClCompile Include="roundedcornerwidget.cpp" />
|
||||||
<ClCompile Include="sceneviewer.cpp" />
|
<ClCompile Include="sceneviewer.cpp" />
|
||||||
<ClCompile Include="scrolllistwidget.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="shader.cpp" />
|
||||||
<ClCompile Include="sidebar.cpp" />
|
<ClCompile Include="sidebar.cpp" />
|
||||||
<ClCompile Include="skybox.cpp" />
|
<ClCompile Include="skybox.cpp" />
|
||||||
@ -162,6 +168,7 @@
|
|||||||
<QtMoc Include="modelthumbnailwidget.h" />
|
<QtMoc Include="modelthumbnailwidget.h" />
|
||||||
<QtMoc Include="modelattrslide.h" />
|
<QtMoc Include="modelattrslide.h" />
|
||||||
<ClInclude Include="ray.h" />
|
<ClInclude Include="ray.h" />
|
||||||
|
<QtMoc Include="settingpage.h" />
|
||||||
<ClInclude Include="skybox.h" />
|
<ClInclude Include="skybox.h" />
|
||||||
<QtMoc Include="slider.h" />
|
<QtMoc Include="slider.h" />
|
||||||
<ClInclude Include="terrain.h" />
|
<ClInclude Include="terrain.h" />
|
||||||
|
|||||||
@ -77,6 +77,12 @@
|
|||||||
<Filter Include="Header Files\Qt Widgets\Pages\Scene Editor\Object Setter">
|
<Filter Include="Header Files\Qt Widgets\Pages\Scene Editor\Object Setter">
|
||||||
<UniqueIdentifier>{6c5ac0df-26ad-40ad-860c-3d0372b81094}</UniqueIdentifier>
|
<UniqueIdentifier>{6c5ac0df-26ad-40ad-860c-3d0372b81094}</UniqueIdentifier>
|
||||||
</Filter>
|
</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>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<QtRcc Include="mainwindow.qrc">
|
<QtRcc Include="mainwindow.qrc">
|
||||||
@ -180,8 +186,8 @@
|
|||||||
<ClCompile Include="modelattrslide.cpp">
|
<ClCompile Include="modelattrslide.cpp">
|
||||||
<Filter>Source Files\Qt Widgets\Pages\Scene Editor\Object Setter</Filter>
|
<Filter>Source Files\Qt Widgets\Pages\Scene Editor\Object Setter</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="terrain.cpp">
|
<ClCompile Include="settingpage.cpp">
|
||||||
<Filter>Source Files\OpenGL Abstractions</Filter>
|
<Filter>Source Files\Qt Widgets\Pages\Setting Page</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -292,6 +298,9 @@
|
|||||||
<QtMoc Include="modelattrslide.h">
|
<QtMoc Include="modelattrslide.h">
|
||||||
<Filter>Header Files\Qt Widgets\Pages\Scene Editor\Object Setter</Filter>
|
<Filter>Header Files\Qt Widgets\Pages\Scene Editor\Object Setter</Filter>
|
||||||
</QtMoc>
|
</QtMoc>
|
||||||
|
<QtMoc Include="settingpage.h">
|
||||||
|
<Filter>Header Files\Qt Widgets\Pages\Setting Page</Filter>
|
||||||
|
</QtMoc>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="fragmentshader.glsl">
|
<None Include="fragmentshader.glsl">
|
||||||
|
|||||||
@ -26,7 +26,7 @@ AboutPage::AboutPage(QWidget* parent) :
|
|||||||
_mainWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
_mainWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||||
_mainWidget->setStyleSheet("QWidget#mainWidget { background-color: #efefef; border-radius: 8px; }");
|
_mainWidget->setStyleSheet("QWidget#mainWidget { background-color: #efefef; border-radius: 8px; }");
|
||||||
_mainLayout = new QVBoxLayout(_mainWidget);
|
_mainLayout = new QVBoxLayout(_mainWidget);
|
||||||
_mainLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
_mainLayout->setAlignment(Qt::AlignTop);
|
||||||
_mainLayout->setContentsMargins(0, 8, 0, 8);
|
_mainLayout->setContentsMargins(0, 8, 0, 8);
|
||||||
_mainLayout->setSpacing(8);
|
_mainLayout->setSpacing(8);
|
||||||
_mainWidget->setLayout(_mainLayout);
|
_mainWidget->setLayout(_mainLayout);
|
||||||
|
|||||||
@ -78,6 +78,12 @@ EditorPage::EditorPage(QWidget* parent) :
|
|||||||
|
|
||||||
EditorPage::~EditorPage() {}
|
EditorPage::~EditorPage() {}
|
||||||
|
|
||||||
|
void EditorPage::updateSetting(QPair<QString, QString> setting) {
|
||||||
|
if (_sceneViewer != nullptr) {
|
||||||
|
_sceneViewer->updateSetting(setting);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PushButton* EditorPage::getPageIconButton(QWidget* context) {
|
PushButton* EditorPage::getPageIconButton(QWidget* context) {
|
||||||
// Check for existed button
|
// Check for existed button
|
||||||
if (_iconButton != nullptr) {
|
if (_iconButton != nullptr) {
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
#include <qwidget.h>
|
#include <qwidget.h>
|
||||||
#include <qboxlayout.h>
|
#include <qboxlayout.h>
|
||||||
#include <qlabel.h>
|
#include <qlabel.h>
|
||||||
|
#include <qpair.h>
|
||||||
|
|
||||||
#include "pagewidget.h"
|
#include "pagewidget.h"
|
||||||
#include "sceneviewer.h"
|
#include "sceneviewer.h"
|
||||||
@ -44,6 +45,9 @@ private:
|
|||||||
|
|
||||||
ModelSetter* _modelSetter = nullptr;
|
ModelSetter* _modelSetter = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void updateSetting(QPair<QString, QString> setting);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual PushButton* getPageIconButton(QWidget* context) override;
|
virtual PushButton* getPageIconButton(QWidget* context) override;
|
||||||
virtual PushButton* getPageTextButton(QWidget* context) override;
|
virtual PushButton* getPageTextButton(QWidget* context) override;
|
||||||
|
|||||||
@ -30,19 +30,21 @@ public:
|
|||||||
class DirLight : public Illuminer{
|
class DirLight : public Illuminer{
|
||||||
protected:
|
protected:
|
||||||
glm::vec3 _direction; // The outgoing direction of the light source
|
glm::vec3 _direction; // The outgoing direction of the light source
|
||||||
|
float _intensity = 50;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DirLight(glm::vec3 direction = glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3 color = glm::vec3(1.0f));
|
DirLight(glm::vec3 direction = glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3 color = glm::vec3(1.0f));
|
||||||
~DirLight();
|
~DirLight();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual glm::vec3 ambientLightColor() const override { return glm::vec3(0.2f) * _lightColor; }
|
virtual glm::vec3 ambientLightColor() const override { return glm::vec3(_intensity / 200.0f) * _lightColor; }
|
||||||
virtual glm::vec3 diffuseLightColor() const override { return glm::vec3(0.6f) * _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; }
|
virtual glm::vec3 specularLightColor() const override { return glm::vec3(1.0f) * _lightColor; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
glm::vec3 lightDirection() const { return _direction; } // The same direction as the outgoing direction
|
glm::vec3 lightDirection() const { return _direction; } // The same direction as the outgoing direction
|
||||||
void setLightDirection(glm::vec3 direction) { _direction = direction; }
|
void setLightDirection(glm::vec3 direction) { _direction = direction; }
|
||||||
|
void setIntensity(float intensity) { _intensity = intensity; }
|
||||||
|
|
||||||
// Render util function
|
// Render util function
|
||||||
virtual void updateShader(ShaderProgram shader, int index) const override;
|
virtual void updateShader(ShaderProgram shader, int index) const override;
|
||||||
|
|||||||
@ -45,10 +45,17 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
_editorPage->setMouseTracking(true);
|
_editorPage->setMouseTracking(true);
|
||||||
_sideBar->addPage(_editorPage);
|
_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
|
// Create about page and connect to side bar
|
||||||
_aboutPage = new AboutPage(_placeHolderWidget);
|
_aboutPage = new AboutPage(_placeHolderWidget);
|
||||||
_aboutPage->setMouseTracking(true);
|
_aboutPage->setMouseTracking(true);
|
||||||
_sideBar->addPage(_aboutPage);
|
_sideBar->addPage(_aboutPage);
|
||||||
|
|
||||||
|
connect(_settingPage, &SettingPage::onSettingsChanged, _editorPage, &EditorPage::updateSetting);
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow() {
|
MainWindow::~MainWindow() {
|
||||||
@ -65,6 +72,7 @@ void MainWindow::resizePages(QResizeEvent* event) {
|
|||||||
|
|
||||||
// Resize the editor page
|
// Resize the editor page
|
||||||
_editorPage->resize(size);
|
_editorPage->resize(size);
|
||||||
|
_settingPage->resize(size);
|
||||||
_aboutPage->resize(size);
|
_aboutPage->resize(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,6 +82,7 @@ void MainWindow::showEvent(QShowEvent* event) {
|
|||||||
|
|
||||||
// Resize all the pages based on the placeholder widget
|
// Resize all the pages based on the placeholder widget
|
||||||
_editorPage->resize(_placeHolderWidget->size());
|
_editorPage->resize(_placeHolderWidget->size());
|
||||||
|
_settingPage->resize(_placeHolderWidget->size());
|
||||||
_aboutPage->resize(_placeHolderWidget->size());
|
_aboutPage->resize(_placeHolderWidget->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
#include "sidebar.h"
|
#include "sidebar.h"
|
||||||
#include "editorpage.h"
|
#include "editorpage.h"
|
||||||
#include "aboutpage.h"
|
#include "aboutpage.h"
|
||||||
|
#include "settingpage.h"
|
||||||
|
|
||||||
class MainWindow : public FramelessWindow
|
class MainWindow : public FramelessWindow
|
||||||
{
|
{
|
||||||
@ -23,6 +24,7 @@ private:
|
|||||||
SideBar* _sideBar = nullptr;
|
SideBar* _sideBar = nullptr;
|
||||||
EditorPage* _editorPage = nullptr;
|
EditorPage* _editorPage = nullptr;
|
||||||
AboutPage* _aboutPage = nullptr;
|
AboutPage* _aboutPage = nullptr;
|
||||||
|
SettingPage* _settingPage = nullptr;
|
||||||
|
|
||||||
// Place holder widget for resizing pages
|
// Place holder widget for resizing pages
|
||||||
QWidget* _placeHolderWidget = nullptr;
|
QWidget* _placeHolderWidget = nullptr;
|
||||||
|
|||||||
@ -146,7 +146,7 @@ void SceneViewer::initializeGL() {
|
|||||||
_skyShader.attachShader(skyFragmentShader);
|
_skyShader.attachShader(skyFragmentShader);
|
||||||
skyVertexShader.dispose();
|
skyVertexShader.dispose();
|
||||||
skyFragmentShader.dispose();
|
skyFragmentShader.dispose();
|
||||||
|
|
||||||
_terrainShader.ensureInitialized();
|
_terrainShader.ensureInitialized();
|
||||||
Logger::info("Terrain Shader initialized");
|
Logger::info("Terrain Shader initialized");
|
||||||
|
|
||||||
@ -156,24 +156,8 @@ void SceneViewer::initializeGL() {
|
|||||||
_terrainShader.attachShader(terrainFragmentShader);
|
_terrainShader.attachShader(terrainFragmentShader);
|
||||||
terrainVertexShader.dispose();
|
terrainVertexShader.dispose();
|
||||||
terrainFragmentShader.dispose();
|
terrainFragmentShader.dispose();
|
||||||
|
|
||||||
// Test Code Start
|
|
||||||
_sky = new SkyBox("D:\\ProgrammingFile\\SceneEditor\\SkyBoxes");
|
|
||||||
_terrain = new Terrain("D:\\ProgrammingFile\\SceneEditor\\Terrains");
|
|
||||||
|
|
||||||
_dirLight = new DirLight();
|
_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));
|
_camera.setPosition(glm::vec3(0.0f, 0.0f, 10.0f));
|
||||||
}
|
}
|
||||||
@ -239,7 +223,7 @@ void SceneViewer::paintGL() {
|
|||||||
_shaderProgram.setUniform("pointlightnr", pointLights);
|
_shaderProgram.setUniform("pointlightnr", pointLights);
|
||||||
_shaderProgram.setUniform("spotlightnr", spotLights);
|
_shaderProgram.setUniform("spotlightnr", spotLights);
|
||||||
|
|
||||||
if (_dirLight != nullptr) {
|
if (_dirLight != nullptr && _dirLightOn) {
|
||||||
_dirLight->updateShader(_shaderProgram, 0);
|
_dirLight->updateShader(_shaderProgram, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -569,3 +553,62 @@ void SceneViewer::deleteObject() {
|
|||||||
emit onSelect(nullptr);
|
emit onSelect(nullptr);
|
||||||
parentWidget()->update();
|
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();
|
||||||
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
#include <qwidget.h>
|
#include <qwidget.h>
|
||||||
#include <qevent.h>
|
#include <qevent.h>
|
||||||
#include <qopenglfunctions.h>
|
#include <qopenglfunctions.h>
|
||||||
|
#include <qpair.h>
|
||||||
#include <QtOpenGLWidgets/qopenglwidget.h>
|
#include <QtOpenGLWidgets/qopenglwidget.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -24,10 +25,11 @@ private:
|
|||||||
// OpenGL section-------------------------------------
|
// OpenGL section-------------------------------------
|
||||||
// List of objects currently in the scene
|
// List of objects currently in the scene
|
||||||
std::vector<Renderable*> _objects;
|
std::vector<Renderable*> _objects;
|
||||||
|
// Sky Box
|
||||||
|
SkyBox* _sky = nullptr;
|
||||||
// Dir light
|
// Dir light
|
||||||
|
bool _dirLightOn = false;
|
||||||
DirLight* _dirLight = nullptr;
|
DirLight* _dirLight = nullptr;
|
||||||
// Sky Box
|
|
||||||
SkyBox* _sky;
|
|
||||||
// Terrain
|
// Terrain
|
||||||
Terrain* _terrain;
|
Terrain* _terrain;
|
||||||
// Shader program for objects
|
// Shader program for objects
|
||||||
@ -103,6 +105,7 @@ public:
|
|||||||
parentWidget()->update();
|
parentWidget()->update();
|
||||||
}
|
}
|
||||||
void deleteObject();
|
void deleteObject();
|
||||||
|
void updateSetting(QPair<QString, QString> setting);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void onHover(Renderable* object);
|
void onHover(Renderable* object);
|
||||||
|
|||||||
313
FinalProject/settingpage.cpp
Normal file
313
FinalProject/settingpage.cpp
Normal 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));
|
||||||
|
}
|
||||||
72
FinalProject/settingpage.h
Normal file
72
FinalProject/settingpage.h
Normal 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);
|
||||||
|
};
|
||||||
Loading…
x
Reference in New Issue
Block a user