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
|
||||
/Models
|
||||
/Terrains
|
||||
|
||||
/terrain
|
||||
|
||||
@ -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" />
|
||||
|
||||
@ -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">
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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());
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -146,7 +146,7 @@ void SceneViewer::initializeGL() {
|
||||
_skyShader.attachShader(skyFragmentShader);
|
||||
skyVertexShader.dispose();
|
||||
skyFragmentShader.dispose();
|
||||
|
||||
|
||||
_terrainShader.ensureInitialized();
|
||||
Logger::info("Terrain Shader initialized");
|
||||
|
||||
@ -156,24 +156,8 @@ void SceneViewer::initializeGL() {
|
||||
_terrainShader.attachShader(terrainFragmentShader);
|
||||
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();
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
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