From b34c9a1bbea924233cf2e4ef23471017f31dbcc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20Petter=20Sk=C3=A5lerud?= <np_skalerud@hotmail.com> Date: Fri, 22 Mar 2019 13:52:21 +0100 Subject: [PATCH] Worked on lighting Updated shaders to use UBO for cameradata. Update submodule DMath to latest master version (22.03.2019) Added CircleCollider component. Still WIP. Modified MeshRenderer component to use reduced matrices. Added PointLight component. Still WIP. Renamed ScriptBase::Start to ScriptBase::SceneStart. Added simple error report system in OpenGL backend. Modified Renderer::CameraInfo::GetModel to use new DMath perspective function. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nils Petter Skålerud <np_skalerud@hotmail.com> --- Data/Shaders/Mesh/Mesh.frag | 2 +- Data/Shaders/Mesh/Mesh.vert | 10 ++-- external/DMath | 2 +- src/Engine/Components/CircleCollider.cpp | 23 ++++++++ src/Engine/Components/CircleCollider.hpp | 26 +++++++++ src/Engine/Components/MeshRenderer.cpp | 17 +++--- src/Engine/Components/MeshRenderer.hpp | 3 +- src/Engine/Components/PointLight.cpp | 33 ++++++++++++ src/Engine/Components/PointLight.hpp | 28 ++++++++++ src/Engine/Components/ScriptBase.cpp | 2 +- src/Engine/Components/ScriptBase.hpp | 2 +- src/Engine/Engine.cpp | 43 ++++----------- src/Engine/Renderer/OpenGL.cpp | 67 ++++++++++++++++-------- src/Engine/Renderer/Renderer.cpp | 4 +- src/Engine/Scene.cpp | 5 +- src/Engine/Scene.hpp | 2 +- 16 files changed, 196 insertions(+), 73 deletions(-) create mode 100644 src/Engine/Components/CircleCollider.cpp create mode 100644 src/Engine/Components/CircleCollider.hpp create mode 100644 src/Engine/Components/PointLight.cpp create mode 100644 src/Engine/Components/PointLight.hpp diff --git a/Data/Shaders/Mesh/Mesh.frag b/Data/Shaders/Mesh/Mesh.frag index 5d327cb..183e675 100644 --- a/Data/Shaders/Mesh/Mesh.frag +++ b/Data/Shaders/Mesh/Mesh.frag @@ -1,4 +1,4 @@ -#version 330 core +#version 420 core in FragData { diff --git a/Data/Shaders/Mesh/Mesh.vert b/Data/Shaders/Mesh/Mesh.vert index 64d8749..aaee841 100644 --- a/Data/Shaders/Mesh/Mesh.vert +++ b/Data/Shaders/Mesh/Mesh.vert @@ -1,11 +1,15 @@ -#version 330 core +#version 420 core layout(location = 0) in vec3 position; layout(location = 1) in vec2 texCoord; layout(location = 2) in vec3 normal; +layout(std140, binding = 0) uniform CameraData +{ + mat4 viewProjection; +} cameraData; + uniform mat4 model; -uniform mat4 viewProjection; out FragData { @@ -16,7 +20,7 @@ out FragData void main() { - gl_Position = viewProjection * model * vec4(position, 1.0); + gl_Position = cameraData.viewProjection * model * vec4(position, 1.0); fragData.wsPosition = vec4(model * vec4(position, 1.0)).xyz; fragData.wsNormal = vec4(model * vec4(normal, 0.0)).xyz; diff --git a/external/DMath b/external/DMath index d93a427..b44a8d7 160000 --- a/external/DMath +++ b/external/DMath @@ -1 +1 @@ -Subproject commit d93a427928ba7957e5e162dd8567f22bc803ff57 +Subproject commit b44a8d7273fcc7e9775733a014c5d944fd48167c diff --git a/src/Engine/Components/CircleCollider.cpp b/src/Engine/Components/CircleCollider.cpp new file mode 100644 index 0000000..ec4a4e6 --- /dev/null +++ b/src/Engine/Components/CircleCollider.cpp @@ -0,0 +1,23 @@ +#include "CircleCollider.hpp" + +namespace Engine +{ + namespace Components + { + CircleCollider::CircleCollider(SceneObject& owningObject) : + ParentType(owningObject), + positionOffset(), + radius(1) + { + } + + CircleCollider::~CircleCollider() + { + + } + Math::Matrix<4, 3, float> CircleCollider::GetModel_Reduced(Space space) const + { + return Math::Matrix<4, 3, float>(); + } + } +} \ No newline at end of file diff --git a/src/Engine/Components/CircleCollider.hpp b/src/Engine/Components/CircleCollider.hpp new file mode 100644 index 0000000..d2aa45e --- /dev/null +++ b/src/Engine/Components/CircleCollider.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include "Components.hpp" +#include "../Enum.hpp" + +#include "DMath/Vector/Vector.hpp" + +namespace Engine +{ + namespace Components + { + class CircleCollider : ComponentBase + { + public: + using ParentType = ComponentBase; + + explicit CircleCollider(SceneObject& owningObject); + ~CircleCollider(); + + Math::Matrix<4, 3, float> GetModel_Reduced(Space space) const; + + Math::Vector<3, float> positionOffset; + float radius; + }; + } +} \ No newline at end of file diff --git a/src/Engine/Components/MeshRenderer.cpp b/src/Engine/Components/MeshRenderer.cpp index 7f3f3d5..f7ea7da 100644 --- a/src/Engine/Components/MeshRenderer.cpp +++ b/src/Engine/Components/MeshRenderer.cpp @@ -18,7 +18,7 @@ namespace Engine MeshRenderer::MeshRenderer(SceneObject& owningSceneObject) : ParentType(owningSceneObject), mesh(Asset::Mesh::None), - position{ 0, 0, 0 }, + positionOffset{ 0, 0, 0 }, scale{ 1, 1, 1 }, rotation() { @@ -42,16 +42,21 @@ namespace Engine mesh = newMesh; } - Math::Matrix4x4 MeshRenderer::GetModel(Space space) const + Math::Matrix<4, 3> MeshRenderer::GetModel_Reduced(Space space) const { using namespace Math::LinTran3D; - auto localModel = Multiply(Scale_Reduced(scale), Rotate_Reduced(rotation)); - AddTranslation(localModel, position); + Math::Matrix<4, 3> localModel = Multiply(Scale_Reduced(scale), Rotate_Reduced(rotation)); + AddTranslation(localModel, positionOffset); if (space == Space::Local) - return AsMat4(localModel); + return localModel; else - return AsMat4(Multiply(GetSceneObject().transform.GetModel_Reduced(Space::World), localModel)); + Multiply(GetSceneObject().transform.GetModel_Reduced(Space::World), localModel); + } + + Math::Matrix4x4 MeshRenderer::GetModel(Space space) const + { + return Math::LinTran3D::AsMat4(GetModel_Reduced(space)); } } } diff --git a/src/Engine/Components/MeshRenderer.hpp b/src/Engine/Components/MeshRenderer.hpp index 3842cb0..18841df 100644 --- a/src/Engine/Components/MeshRenderer.hpp +++ b/src/Engine/Components/MeshRenderer.hpp @@ -26,9 +26,10 @@ namespace Engine std::underlying_type_t<Asset::Mesh> GetMeshID() const; void SetMesh(Asset::Mesh newMesh); + [[nodiscard]] Math::Matrix<4, 3> GetModel_Reduced(Space space) const; Math::Matrix4x4 GetModel(Space space) const; - Math::Vector3D position; + Math::Vector3D positionOffset; Math::UnitQuaternion<> rotation; Math::Vector3D scale; diff --git a/src/Engine/Components/PointLight.cpp b/src/Engine/Components/PointLight.cpp new file mode 100644 index 0000000..6dc43ae --- /dev/null +++ b/src/Engine/Components/PointLight.cpp @@ -0,0 +1,33 @@ +#include "PointLight.hpp" + +#include "../SceneObject.hpp" + +#include "DMath/LinearTransform3D.hpp" + +namespace Engine +{ + namespace Components + { + PointLight::PointLight(SceneObject& owningObject) : + ParentType(owningObject), + positionOffset(), + intensity(1) + { + } + + PointLight::~PointLight() + { + } + + Math::Matrix<4, 3> PointLight::GetModel_Reduced(Space space) const + { + using namespace Math::LinTran3D; + auto localModel = Translate_Reduced(positionOffset); + + if (space == Space::Local) + return localModel; + else + Multiply(GetSceneObject().transform.GetModel_Reduced(Space::World), localModel); + } + } +} \ No newline at end of file diff --git a/src/Engine/Components/PointLight.hpp b/src/Engine/Components/PointLight.hpp new file mode 100644 index 0000000..9507c4e --- /dev/null +++ b/src/Engine/Components/PointLight.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include "Components.hpp" +#include "../Enum.hpp" + +#include "DMath/Vector/Vector.hpp" +#include "DMath/Matrix/Matrix.hpp" + + +namespace Engine +{ + namespace Components + { + class PointLight : public ComponentBase + { + public: + using ParentType = ComponentBase; + + explicit PointLight(SceneObject& owningObject); + ~PointLight(); + + float intensity; + Math::Vector3D positionOffset; + + [[nodiscard]] Math::Matrix<4, 3> GetModel_Reduced(Space space) const; + }; + } +} \ No newline at end of file diff --git a/src/Engine/Components/ScriptBase.cpp b/src/Engine/Components/ScriptBase.cpp index 48d0956..caefdc9 100644 --- a/src/Engine/Components/ScriptBase.cpp +++ b/src/Engine/Components/ScriptBase.cpp @@ -15,7 +15,7 @@ namespace Engine } - void ScriptBase::Start() {} + void ScriptBase::SceneStart() {} void ScriptBase::Tick() {} diff --git a/src/Engine/Components/ScriptBase.hpp b/src/Engine/Components/ScriptBase.hpp index 22ab303..a2adcd1 100644 --- a/src/Engine/Components/ScriptBase.hpp +++ b/src/Engine/Components/ScriptBase.hpp @@ -25,7 +25,7 @@ namespace Engine const SceneObject& GetSceneObject() const; protected: - virtual void Start() = 0; + virtual void SceneStart() = 0; virtual void Tick() = 0; diff --git a/src/Engine/Engine.cpp b/src/Engine/Engine.cpp index 59eafd0..aab234d 100644 --- a/src/Engine/Engine.cpp +++ b/src/Engine/Engine.cpp @@ -36,9 +36,9 @@ public: protected: - void Start() override + void SceneStart() override { - ParentType::Start(); + ParentType::SceneStart(); } void Tick() override @@ -48,32 +48,6 @@ protected: } }; -class ScriptTest2 : public Engine::Components::ScriptBase -{ - using ParentType = Engine::Components::ScriptBase; - -public: - explicit ScriptTest2(Engine::SceneObject& owningObject) : - ParentType(owningObject) - { - - } - -protected: - - - void Start() override - { - ParentType::Start(); - } - - void Tick() override - { - ParentType::Tick(); - std::cout << "We ticked222222!" << std::endl; - } -}; - std::vector<std::unique_ptr<Engine::Scene>> Engine::Core::scenes; void Engine::Core::Run() @@ -103,7 +77,7 @@ void Engine::Core::Run() auto& mesh2 = sceneObject1.AddComponent<Components::MeshRenderer>().first.get(); mesh2.SetMesh(Asset::Mesh::Cube); - mesh2.position.x = 2.5f; + mesh2.positionOffset.x = 2.5f; auto& objCamera = scene1.NewSceneObject(); auto& camera = objCamera.AddComponent<Components::Camera>().first.get(); @@ -111,18 +85,16 @@ void Engine::Core::Run() camera.position.z = 5.f; auto& obj3 = scene1.NewSceneObject(); - ScriptTest& scriptTest = obj3.AddComponent<ScriptTest>(); - ScriptTest2& scriptTest2 = obj3.AddComponent<ScriptTest2>(); + //ScriptTest& scriptTest = obj3.AddComponent<ScriptTest>(); Renderer::RenderGraph graph; Renderer::RenderGraphTransform graphTransform; - scene1.ScriptStart(); + scene1.Scripts_SceneStart(); while (Application::Core::UpdateEvents(), Application::IsRunning()) { - // Handles origin movement for camera const float speed = 2.5f; auto cross = Math::Vector3D::Cross(camera.forward, camera.up); @@ -140,6 +112,11 @@ void Engine::Core::Run() camera.position += Math::Vector3D::Down() * speed * scene1.GetTimeData().GetDeltaTime(); camera.LookAt({ 0, 0, 0 }); + if (Input::Raw::GetEventType(Input::Raw::Button::C) == Input::EventType::Pressed) + { + scene1.Clear(); + } + scene1.ScriptTick(); diff --git a/src/Engine/Renderer/OpenGL.cpp b/src/Engine/Renderer/OpenGL.cpp index 0c9f6aa..be81be0 100644 --- a/src/Engine/Renderer/OpenGL.cpp +++ b/src/Engine/Renderer/OpenGL.cpp @@ -19,6 +19,12 @@ namespace Engine { namespace OpenGL { +#ifdef NDEBUG + constexpr bool enableDebug = false; +#else + constexpr bool enableDebug = true; +#endif + struct VertexBufferObject; using VBO = VertexBufferObject; @@ -26,6 +32,7 @@ namespace Engine using IBO = ImageBufferObject; struct Data; + struct CameraDataUBO; void UpdateVBODatabase(Data& data, const std::vector<MeshID>& loadQueue); std::optional<VBO> VBOFromPath(const std::string& path); @@ -42,6 +49,11 @@ namespace Engine } } +struct Engine::Renderer::OpenGL::CameraDataUBO +{ + Math::Matrix<4, 4, float> viewProjection; +}; + struct Engine::Renderer::OpenGL::VertexBufferObject { enum class Attribute @@ -76,16 +88,17 @@ struct Engine::Renderer::OpenGL::Data std::unordered_map<SpriteID, IBO> iboDatabase; + GLuint cameraDataUBO; + GLuint samplerObject; + GLuint spriteProgram; GLint spriteModelUniform; - GLint spriteViewUniform; GLint spriteSamplerUniform; GLuint meshProgram; GLint meshModelUniform; - GLint meshViewUniform; - GLuint samplerObject; + }; Engine::Renderer::OpenGL::Data& Engine::Renderer::OpenGL::GetData() { return std::any_cast<Data&>(Core::GetAPIData()); } @@ -173,10 +186,6 @@ void Engine::Renderer::OpenGL::LoadSpriteShader(Data& data) for (unsigned int i = 0; i < 2; i++) glAttachShader(data.spriteProgram, shaders[i]); - glBindAttribLocation(data.spriteProgram, 0, "position"); - glBindAttribLocation(data.spriteProgram, 1, "texCoord"); - glBindAttribLocation(data.spriteProgram, 2, "normal"); - glLinkProgram(data.spriteProgram); CheckShaderError(data.spriteProgram, GL_LINK_STATUS, true, "Error linking shader program"); @@ -188,7 +197,6 @@ void Engine::Renderer::OpenGL::LoadSpriteShader(Data& data) // Grab uniforms data.spriteModelUniform = glGetUniformLocation(data.spriteProgram, "model"); - data.spriteViewUniform = glGetUniformLocation(data.spriteProgram, "viewProjection"); data.spriteSamplerUniform = glGetUniformLocation(data.spriteProgram, "sampler"); } @@ -205,10 +213,6 @@ void Engine::Renderer::OpenGL::LoadMeshShader(Engine::Renderer::OpenGL::Data &da for (unsigned int i = 0; i < 2; i++) glAttachShader(data.meshProgram, shader[i]); - glBindAttribLocation(data.meshProgram, 0, "position"); - glBindAttribLocation(data.meshProgram, 1, "texCoord"); - glBindAttribLocation(data.meshProgram, 2, "normal"); - glLinkProgram(data.meshProgram); CheckShaderError(data.meshProgram, GL_LINK_STATUS, true, "Error linking shader program"); @@ -220,7 +224,8 @@ void Engine::Renderer::OpenGL::LoadMeshShader(Engine::Renderer::OpenGL::Data &da // Grab uniforms data.meshModelUniform = glGetUniformLocation(data.meshProgram, "model"); - data.meshViewUniform = glGetUniformLocation(data.meshProgram, "viewProjection"); + + glUniformBlockBinding(data.meshProgram, 0, 0); } void Engine::Renderer::OpenGL::Initialize(std::any& apiData, CreateInfo&& createInfo) @@ -228,13 +233,16 @@ void Engine::Renderer::OpenGL::Initialize(std::any& apiData, CreateInfo&& create auto glInitResult = glewInit(); assert(glInitResult == 0); - apiData = std::make_any<Data>(); Data& data = std::any_cast<Data&>(apiData); data.glSwapBuffers = std::move(createInfo.glSwapBuffers); - + // Make camera ubo + glGenBuffers(1, &data.cameraDataUBO); + glBindBuffer(GL_UNIFORM_BUFFER, data.cameraDataUBO); + glBufferData(GL_UNIFORM_BUFFER, sizeof(CameraDataUBO), nullptr, GL_DYNAMIC_DRAW); + glBindBufferRange(GL_UNIFORM_BUFFER, 0, data.cameraDataUBO, 0, sizeof(CameraDataUBO)); // Gen sampler glGenSamplers(1, &data.samplerObject); @@ -250,6 +258,8 @@ void Engine::Renderer::OpenGL::Initialize(std::any& apiData, CreateInfo&& create else assert(false); + + glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); @@ -257,6 +267,13 @@ void Engine::Renderer::OpenGL::Initialize(std::any& apiData, CreateInfo&& create //LoadSpriteShader(data); LoadMeshShader(data); + + if constexpr (enableDebug) + { + auto errorEnum = glGetError(); + if (errorEnum != 0) + std::cout << glewGetErrorString(errorEnum) << std::endl; + } } void Engine::Renderer::OpenGL::Terminate(std::any& apiData) @@ -271,6 +288,7 @@ void Engine::Renderer::OpenGL::Terminate(std::any& apiData) iboItem.second.DeallocateDeviceBuffers(); glDeleteProgram(data.spriteProgram); + glDeleteProgram(data.meshProgram); //delete static_cast<Data*>(apiData); //apiData = nullptr; @@ -295,6 +313,12 @@ void Engine::Renderer::OpenGL::Draw() auto& viewport = Renderer::GetViewport(0); + + auto& cameraInfo = Renderer::Core::GetCameraInfo(); + auto viewMatrix = cameraInfo.GetModel(viewport.GetDimensions().GetAspectRatio()); + glNamedBufferSubData(data.cameraDataUBO, 0, sizeof(CameraDataUBO::viewProjection), viewMatrix.data.data()); + + const auto& renderGraph = Core::GetRenderGraph(); const auto& renderGraphTransform = Core::GetRenderGraphTransform(); @@ -302,6 +326,13 @@ void Engine::Renderer::OpenGL::Draw() Draw_SpritePass(data, renderGraph.sprites, renderGraphTransform.sprites); Draw_MeshPass(data, renderGraph.meshes, renderGraphTransform.meshes); + if constexpr (enableDebug) + { + auto errorEnum = glGetError(); + if (errorEnum != 0) + std::cout << glewGetErrorString(errorEnum) << std::endl; + } + data.glSwapBuffers(viewport.GetSurfaceHandle()); } @@ -316,9 +347,6 @@ void Engine::Renderer::OpenGL::Draw_SpritePass(const Data& data, { glUseProgram(data.spriteProgram); - auto viewMat = Core::GetCameraInfo().GetModel(viewport.GetDimensions().GetAspectRatio()); - glProgramUniformMatrix4fv(data.spriteProgram, data.spriteViewUniform, 1, GL_FALSE, viewMat.data.data()); - glProgramUniform1ui(data.spriteProgram, data.spriteSamplerUniform, 0); glBindSampler(0, data.samplerObject); @@ -348,9 +376,6 @@ void Engine::Renderer::OpenGL::Draw_MeshPass(const Engine::Renderer::OpenGL::Dat { glUseProgram(data.meshProgram); - auto viewMat = Core::GetCameraInfo().GetModel(viewport.GetDimensions().GetAspectRatio()); - glProgramUniformMatrix4fv(data.meshProgram, data.meshViewUniform, 1, GL_FALSE, viewMat.data.data()); - for (size_t i = 0; i < meshes.size(); i++) { glProgramUniformMatrix4fv(data.meshProgram, data.meshModelUniform, 1, GL_FALSE, transforms[i].data.data()); diff --git a/src/Engine/Renderer/Renderer.cpp b/src/Engine/Renderer/Renderer.cpp index 50fde57..9aaa7d4 100644 --- a/src/Engine/Renderer/Renderer.cpp +++ b/src/Engine/Renderer/Renderer.cpp @@ -245,9 +245,9 @@ Math::Matrix4x4 Engine::Renderer::CameraInfo::GetModel(float aspectRatio) const switch (GetActiveAPI()) { case API::OpenGL: - return Math::LinTran3D::PerspectiveRH_NO(fovY, aspectRatio, zNear, zFar) * transform; + return Math::LinTran3D::Perspective<float>(Math::API3D::OpenGL, fovY, aspectRatio, zNear, zFar) * transform; case API::Vulkan: - return Math::LinTran3D::PerspectiveRH_ZO(fovY, aspectRatio, zNear, zFar) * transform; + return Math::LinTran3D::Perspective<float>(Math::API3D::Vulkan, fovY, aspectRatio, zNear, zFar) * transform; default: assert(false); return {}; diff --git a/src/Engine/Scene.cpp b/src/Engine/Scene.cpp index dc8516f..3c783dd 100644 --- a/src/Engine/Scene.cpp +++ b/src/Engine/Scene.cpp @@ -42,15 +42,16 @@ namespace Engine void Scene::Clear() { + sceneObjects.clear(); components.clear(); } - void Scene::ScriptStart() + void Scene::Scripts_SceneStart() { for (auto& ptr : scriptComponents) { auto& ref = *ptr; - ref.Start(); + ref.SceneStart(); } } diff --git a/src/Engine/Scene.hpp b/src/Engine/Scene.hpp index db2520c..e534fcc 100644 --- a/src/Engine/Scene.hpp +++ b/src/Engine/Scene.hpp @@ -72,7 +72,7 @@ namespace Engine std::vector<Components::ScriptBase*> scriptComponents; - void ScriptStart(); + void Scripts_SceneStart(); void ScriptTick(); Time::SceneData &GetTimeData(); -- GitLab