diff --git a/include/MainWindow.h b/include/MainWindow.h index 45842cf..927e4a6 100644 --- a/include/MainWindow.h +++ b/include/MainWindow.h @@ -8,20 +8,55 @@ class MainWindow : public QMainWindow { Q_OBJECT - public: - explicit MainWindow(QWidget * parent = nullptr); + //----------------------------------------------------------------------------------------------------- + /// @brief Explcit constructor for the main window. It is explicit so QWidgets can't be implicitly cast + /// to MainWindows. + /// @param [io] io_parent the parent widget of this window. + //----------------------------------------------------------------------------------------------------- + explicit MainWindow(QWidget *io_parent = nullptr) : + QMainWindow(io_parent) + {} + //----------------------------------------------------------------------------------------------------- + /// @brief Default destructor + //----------------------------------------------------------------------------------------------------- ~MainWindow() = default; - + //----------------------------------------------------------------------------------------------------- + /// @brief Used to initialise the Window with a Scene, placing it in the central widget. + /// @param [io] io_scene is the scene to be placed in the central widget. + //----------------------------------------------------------------------------------------------------- void init(const std::shared_ptr &io_scene); -private: - Ui::MainWindow m_ui; - std::shared_ptr m_gl = nullptr; +private: + //----------------------------------------------------------------------------------------------------- + /// @brief Used to handle a key press, will get delegated to the scene. + /// @param [io] io_event the key that was pressed. + //----------------------------------------------------------------------------------------------------- void keyPressEvent(QKeyEvent * io_event); + //----------------------------------------------------------------------------------------------------- + /// @brief Used to handle a mouse move, will get delegated to the scene. + /// @param [io] io_event contains the mouse position. + //----------------------------------------------------------------------------------------------------- void mouseMoveEvent(QMouseEvent * io_event); + //----------------------------------------------------------------------------------------------------- + /// @brief Used to handle a mouse button press, will get delegated to the scene. + /// @param [io] io_event contains the mouse button that was pressed. + //----------------------------------------------------------------------------------------------------- void mousePressEvent(QMouseEvent *io_event); + //----------------------------------------------------------------------------------------------------- + /// @brief Used to handle a mouse button release, will get delegated to the scene. + /// @param [io] io_event contains the mouse button that was released. + //----------------------------------------------------------------------------------------------------- void mouseReleaseEvent(QMouseEvent *io_event); + //----------------------------------------------------------------------------------------------------- + /// @brief The Qt UI form. + //----------------------------------------------------------------------------------------------------- + Ui::MainWindow m_ui; + //----------------------------------------------------------------------------------------------------- + /// @brief A pointer to the scene that should be placed in the central widget. + //----------------------------------------------------------------------------------------------------- + std::shared_ptr m_scene = nullptr; + }; #endif // MAINWINDOW_H diff --git a/include/MaterialPBR.h b/include/MaterialPBR.h index 00b75cf..75ea092 100644 --- a/include/MaterialPBR.h +++ b/include/MaterialPBR.h @@ -7,9 +7,22 @@ class MaterialPBR : public Material { public: - MaterialPBR(const std::shared_ptr &io_camera, const std::shared_ptr &io_shaderLib, std::array* io_matrices, const glm::vec3 &_albedo) : + MaterialPBR( + const std::shared_ptr &io_camera, + const std::shared_ptr &io_shaderLib, + std::array* io_matrices, + const glm::vec3 &_albedo, + const float _ao, + const float _exposure, + const float _roughness, + const float _metallic + ) : Material(io_camera, io_shaderLib, io_matrices), - m_albedo(_albedo) + m_albedo(_albedo), + m_ao(_ao), + m_exposure(_exposure), + m_roughness(_roughness), + m_metallic(_metallic) {} MaterialPBR(const MaterialPBR&) = default; MaterialPBR& operator=(const MaterialPBR&) = default; @@ -26,6 +39,10 @@ class MaterialPBR : public Material private: glm::vec3 m_albedo; + float m_ao; + float m_exposure; + float m_roughness; + float m_metallic; }; diff --git a/include/Mesh.h b/include/Mesh.h index 15033e6..8e46f5d 100644 --- a/include/Mesh.h +++ b/include/Mesh.h @@ -4,6 +4,7 @@ #include #include #include +#include "MeshVBO.h" class Mesh { @@ -34,6 +35,12 @@ class Mesh //----------------------------------------------------------------------------------------------------- const GLfloat* getUVsData() const noexcept; //----------------------------------------------------------------------------------------------------- + /// @brief Gets a pointer to the first data element in the specified attribute array for use with + /// openGL buffers. + /// @return A pointer to the first element in an attribute array. + //----------------------------------------------------------------------------------------------------- + const GLfloat* getAttribData(const MeshAttributes::Attribute _attrib) const noexcept; + //----------------------------------------------------------------------------------------------------- /// @brief Used to the the amount of vertex data elements. /// @return The size of our vertex array. //----------------------------------------------------------------------------------------------------- diff --git a/include/MeshVBO.h b/include/MeshVBO.h index d40c92b..167c46e 100644 --- a/include/MeshVBO.h +++ b/include/MeshVBO.h @@ -7,13 +7,17 @@ #include #include +//----------------------------------------------------------------------------------------------------- +/// @brief used to refer to a section of buffer data +//----------------------------------------------------------------------------------------------------- +namespace MeshAttributes +{ + enum Attribute { VERTEX, NORMAL, UV }; +} + class MeshVBO { public: - //----------------------------------------------------------------------------------------------------- - /// @brief used to refer to a section of buffer data - //----------------------------------------------------------------------------------------------------- - enum BufferSection { VERTEX, NORMAL, UV }; //----------------------------------------------------------------------------------------------------- /// @brief called after construction, used to generate and bind our VBO to store mesh data. //----------------------------------------------------------------------------------------------------- @@ -34,7 +38,7 @@ class MeshVBO /// @param [in] _address is a pointer to the data we want to store. /// @param [in] _section is the section of the buffer we should write our data to. //----------------------------------------------------------------------------------------------------- - void append(const void * _address, const BufferSection _section); + void append(const void * _address, const MeshAttributes::Attribute _section); //----------------------------------------------------------------------------------------------------- /// @brief called to get the size of each data element we are storing. /// @return the size of the data elements in our buffer @@ -49,12 +53,12 @@ class MeshVBO /// @brief called to get the amount of data elements we are storing for a specific section. /// @return the number of data elements in the _section of the buffer //----------------------------------------------------------------------------------------------------- - int dataAmount(const BufferSection _section) const noexcept; + int dataAmount(const MeshAttributes::Attribute _section) const noexcept; //----------------------------------------------------------------------------------------------------- /// @brief called to get the offset in bytes of the specified section of data in our buffer. /// @return the offset in bytes of _section. //----------------------------------------------------------------------------------------------------- - int offset(const BufferSection _section) const noexcept; + int offset(const MeshAttributes::Attribute _section) const noexcept; private: //----------------------------------------------------------------------------------------------------- diff --git a/shaders/PBRFragment.glsl b/shaders/PBRFragment.glsl index 22e651d..f798c5f 100644 --- a/shaders/PBRFragment.glsl +++ b/shaders/PBRFragment.glsl @@ -1,16 +1,20 @@ -#version 330 core +#version 420 // Keeping you on the bleeding edge! +#extension GL_EXT_gpu_shader4 : enable // This code is based on code from here https://learnopengl.com/#!PBR/Lighting -layout (location =0) out vec4 fragColour; +layout (location = 0) out vec4 fragColour; in vec2 TexCoords; in vec3 WorldPos; in vec3 Normal; // material parameters -uniform vec3 albedo; +uniform vec3 albedo; uniform float metallic; uniform float roughness; uniform float ao; +// camera parameters +uniform vec3 camPos; +uniform float exposure; // lights const float scale = 10.0f; @@ -30,9 +34,7 @@ const vec3 lightColors[4] = vec3[4]( vec3(intensity, intensity, intensity) ); -uniform vec3 camPos; -uniform float exposure; - +// Define pi const float PI = 3.14159265359; // ---------------------------------------------------------------------------- float DistributionGGX(vec3 N, vec3 H, float roughness) diff --git a/shaders/PBRVertex.glsl b/shaders/PBRVertex.glsl index 673a1b7..56d84d8 100644 --- a/shaders/PBRVertex.glsl +++ b/shaders/PBRVertex.glsl @@ -1,4 +1,5 @@ -#version 410 core +#version 420 // Keeping you on the bleeding edge! +#extension GL_EXT_gpu_shader4 : enable // this demo is based on code from here https://learnopengl.com/#!PBR/Lighting /// @brief the vertex passed in layout (location = 0) in vec3 inVert; diff --git a/shaders/phong_frag.glsl b/shaders/phong_frag.glsl index 8ef18d0..621f48b 100644 --- a/shaders/phong_frag.glsl +++ b/shaders/phong_frag.glsl @@ -33,7 +33,7 @@ struct MaterialInfo { // The object has a material uniform MaterialInfo Material = MaterialInfo( vec3(0.1, 0.1, 0.1), // Ka - vec3(1.0, 1.0, 1.0), // Kd + vec3(0.1, 0.75, 0.1), // Kd vec3(1.0, 1.0, 1.0), // Ks 10.0 // Shininess ); diff --git a/src/DemoScene.cpp b/src/DemoScene.cpp index 541cdb7..de2e754 100644 --- a/src/DemoScene.cpp +++ b/src/DemoScene.cpp @@ -6,15 +6,12 @@ void DemoScene::loadMesh() { static constexpr std::array shaderAttribs = {{"inVert", "inNormal", "inUV"}}; const auto& mesh = m_meshes[m_meshIndex]; - const std::vector meshData { - mesh.getVertexData(), mesh.getNormalsData(), mesh.getUVsData() - }; + auto prog = m_shaderLib->getCurrentShader(); - using b = MeshVBO::BufferSection; - for (const auto buff : {b::VERTEX, b::NORMAL, b::UV}) + using namespace MeshAttributes; + for (const auto buff : {VERTEX, NORMAL, UV}) { - m_meshVBO.append(meshData[buff], buff); - auto prog = m_shaderLib->getCurrentShader(); + m_meshVBO.append(mesh.getAttribData(buff), buff); prog->enableAttributeArray(shaderAttribs[buff]); prog->setAttributeBuffer(shaderAttribs[buff], GL_FLOAT, m_meshVBO.offset(buff), 3); } @@ -53,8 +50,8 @@ void DemoScene::initMaterials() { m_materials.reserve(3); m_materials.emplace_back(new MaterialPhong(m_camera, m_shaderLib, &m_matrices)); - m_materials.emplace_back(new MaterialPBR(m_camera, m_shaderLib, &m_matrices, {0.5f, 0.0f, 0.0f})); - m_materials.emplace_back(new MaterialPBR(m_camera, m_shaderLib, &m_matrices, {0.0f, 0.5f, 0.5f})); + m_materials.emplace_back(new MaterialPBR(m_camera, m_shaderLib, &m_matrices, {0.5f, 0.0f, 0.0f}, 1.0f, 1.0f, 0.5f, 1.0f)); + m_materials.emplace_back(new MaterialPBR(m_camera, m_shaderLib, &m_matrices, {0.1f, 0.2f, 0.5f}, 0.5f, 1.0f, 0.4f, 0.2f)); for (size_t i = 0; i < m_materials.size(); ++i) { auto& mat = m_materials[i]; diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 9c7e891..81dd721 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -1,19 +1,14 @@ #include "MainWindow.h" -MainWindow::MainWindow(QWidget *parent) : - QMainWindow(parent) -{ - m_ui.setupUi(this); -} - void MainWindow::init(const std::shared_ptr &io_scene) { - m_gl = io_scene; - m_ui.s_mainWindowGridLayout->addWidget(m_gl.get(),0,0,3,5); - connect(m_ui.m_rotating, SIGNAL(clicked(bool)),m_gl.get(), SLOT(rotating(bool))); - connect(m_ui.generate, SIGNAL( clicked(bool)), m_gl.get(), SLOT(generateNewGeometry())); - connect(m_ui.material, SIGNAL( clicked(bool)), m_gl.get(), SLOT(nextMaterial())); + m_scene = io_scene; + m_ui.setupUi(this); + m_ui.s_mainWindowGridLayout->addWidget(m_scene.get(),0,0,3,5); + connect(m_ui.m_rotating, SIGNAL(clicked(bool)),m_scene.get(), SLOT(rotating(bool))); + connect(m_ui.generate, SIGNAL( clicked(bool)), m_scene.get(), SLOT(generateNewGeometry())); + connect(m_ui.material, SIGNAL( clicked(bool)), m_scene.get(), SLOT(nextMaterial())); } //---------------------------------------------------------------------------------------------------------------------- @@ -27,28 +22,28 @@ void MainWindow::keyPressEvent(QKeyEvent *io_event) case Qt::Key_Escape : QApplication::exit(EXIT_SUCCESS); break; default : break; } - m_gl->keyPress(io_event); + m_scene->keyPress(io_event); } //---------------------------------------------------------------------------------------------------------------------- void MainWindow::mouseMoveEvent(QMouseEvent * io_event) { - m_gl->mouseMove(io_event); + m_scene->mouseMove(io_event); } //---------------------------------------------------------------------------------------------------------------------- void MainWindow::mousePressEvent(QMouseEvent * io_event) { - m_gl->mouseClick(io_event); + m_scene->mouseClick(io_event); } //---------------------------------------------------------------------------------------------------------------------- void MainWindow::mouseReleaseEvent(QMouseEvent * io_event) { - m_gl->mouseClick(io_event); + m_scene->mouseClick(io_event); } //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/MaterialPBR.cpp b/src/MaterialPBR.cpp index 00d4b2a..4e2e063 100644 --- a/src/MaterialPBR.cpp +++ b/src/MaterialPBR.cpp @@ -7,10 +7,10 @@ void MaterialPBR::init() auto shaderPtr = m_shaderLib->getCurrentShader(); shaderPtr->setUniformValue("albedo", QVector3D{m_albedo.x, m_albedo.y, m_albedo.z}); - shaderPtr->setUniformValue("ao", 1.0f); - shaderPtr->setUniformValue("exposure", 1.0f); - shaderPtr->setUniformValue("roughness", 0.5f); - shaderPtr->setUniformValue("metallic", 1.0f); + shaderPtr->setUniformValue("ao", m_ao); + shaderPtr->setUniformValue("exposure", m_exposure); + shaderPtr->setUniformValue("roughness", m_roughness); + shaderPtr->setUniformValue("metallic", m_metallic); // Update our matrices update(); diff --git a/src/Mesh.cpp b/src/Mesh.cpp index 42ef9ac..72b9c16 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -87,6 +87,20 @@ const GLfloat *Mesh::getUVsData() const noexcept return &m_uvs[0]; } +const GLfloat *Mesh::getAttribData(const MeshAttributes::Attribute _attrib) const noexcept +{ + using namespace MeshAttributes; + const GLfloat * data = nullptr; + switch (_attrib) + { + case VERTEX: data = getVertexData(); break; + case NORMAL: data = getNormalsData(); break; + case UV: data = getUVsData(); break; + default: break; + } + return data; +} + int Mesh::getNVertData() const noexcept { return static_cast(m_vertices.size()); diff --git a/src/MeshVBO.cpp b/src/MeshVBO.cpp index 33b386a..fc0b9c2 100644 --- a/src/MeshVBO.cpp +++ b/src/MeshVBO.cpp @@ -11,10 +11,13 @@ void MeshVBO::init() //----------------------------------------------------------------------------------------------------- void MeshVBO::reset(const int _size, const int _nVert, const int _nNorm, const int _nUV) { - // Track the amount of data being stored - m_amountOfData[VERTEX] = _nVert; - m_amountOfData[NORMAL] = _nNorm; - m_amountOfData[UV] = _nUV; + { + using namespace MeshAttributes; + // Track the amount of data being stored + m_amountOfData[VERTEX] = _nVert; + m_amountOfData[NORMAL] = _nNorm; + m_amountOfData[UV] = _nUV; + } m_totalAmountOfData = _nVert + _nNorm + _nUV; // Track the size of our stored data m_size = _size; @@ -24,7 +27,7 @@ void MeshVBO::reset(const int _size, const int _nVert, const int _nNorm, const i m_vbo.allocate(m_size * m_totalAmountOfData); } //----------------------------------------------------------------------------------------------------- -void MeshVBO::append(const void *_address, const BufferSection _section) +void MeshVBO::append(const void *_address, const MeshAttributes::Attribute _section) { // Bind the requested buffer, then set it's data pointer m_vbo.bind(); @@ -43,13 +46,13 @@ int MeshVBO::dataAmount() const noexcept return m_totalAmountOfData; } //----------------------------------------------------------------------------------------------------- -int MeshVBO::dataAmount(const BufferSection _section) const noexcept +int MeshVBO::dataAmount(const MeshAttributes::Attribute _section) const noexcept { // Returns the amount of data elements return m_amountOfData[_section]; } //----------------------------------------------------------------------------------------------------- -int MeshVBO::offset(const BufferSection _section) const noexcept +int MeshVBO::offset(const MeshAttributes::Attribute _section) const noexcept { int offset = 0; for (size_t i = 0; i < _section; ++i)