diff --git a/.gitmodules b/.gitmodules index 47e3454..ce6ebab 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,3 +19,6 @@ [submodule "external/stb"] path = external/stb url = https://github.com/nothings/stb.git +[submodule "external/SPIRV-Cross"] + path = external/SPIRV-Cross + url = https://github.com/KhronosGroup/SPIRV-Cross.git diff --git a/cmake/FindSPIRV.cmake b/cmake/FindSPIRV.cmake new file mode 100644 index 0000000..0756e42 --- /dev/null +++ b/cmake/FindSPIRV.cmake @@ -0,0 +1,50 @@ +# +# Find SPIR-V Cross +# +# Try to find SPIR-V Cross library. +# This module defines the following variables: +# - SPIRV_INCLUDE_DIRS +# - SPIRV_LIBRARIES +# - SPIRV_FOUND +# +# The following variables can be set as arguments for the module. +# - SPIRV_ROOT : Root library directory of SPIR-V Cross +# +# References: +# - https://github.com/progschj/OpenGL-Examples/blob/master/cmake_modules/FindGLFW.cmake +# - https://bitbucket.org/Ident8/cegui-mk2-opengl3-renderer/src/befd47200265/cmake/FindGLFW.cmake +# + +# Additional modules +include(FindPackageHandleStandardArgs) +find_path(SPIRV_INCLUDE_DIR + NAMES spirv.h + PATHS + ${SPIRV_ROOT}) + +find_library(SPIRV_CORE_LIBRARY +NAMES spirv-cross-core${CMAKE_DEBUG_POSTFIX} +PATHS + ${Seele_BINARY_DIR}/external/SPIRV-Cross) + + +find_library(SPIRV_GLSL_LIBRARY +NAMES spirv-cross-glsl${CMAKE_DEBUG_POSTFIX} +PATHS + ${Seele_BINARY_DIR}/external/SPIRV-Cross) + +find_library(SPIRV_REFLECT_LIBRARY + NAMES spirv-cross-reflect${CMAKE_DEBUG_POSTFIX} + PATHS + ${Seele_BINARY_DIR}/external/SPIRV-Cross) + + +find_package_handle_standard_args(SPIRV DEFAULT_MSG SPIRV_CORE_LIBRARY SPIRV_GLSL_LIBRARY SPIRV_REFLECT_LIBRARY SPIRV_INCLUDE_DIR) + +if(SPIRV_FOUND) + set(SPIRV_LIBRARIES ${SPIRV_CORE_LIBRARY} ${SPIRV_GLSL_LIBRARY} ${SPIRV_REFLECT_LIBRARY}) + set(SPIRV_INCLUDE_DIRS ${SPIRV_INCLUDE_DIR}) +endif() + +mark_as_advanced(SPIRV_INCLUDE_DIR SPIRV_LIBRARY) + diff --git a/external/SPIRV-Cross b/external/SPIRV-Cross new file mode 160000 index 0000000..ea3cd74 --- /dev/null +++ b/external/SPIRV-Cross @@ -0,0 +1 @@ +Subproject commit ea3cd744266a28c1fa3b977b9b22df679c97b344 diff --git a/src/Engine/Material/ShaderExpression.cpp b/src/Engine/Material/ShaderExpression.cpp new file mode 100644 index 0000000..56d4db5 --- /dev/null +++ b/src/Engine/Material/ShaderExpression.cpp @@ -0,0 +1,73 @@ +#include "ShaderExpression.h" +#include "Graphics/GraphicsResources.h" +#include "Asset/TextureAsset.h" + +using namespace Seele; + +ShaderParameter::ShaderParameter(std::string name, uint32 byteOffset, uint32 binding) + : name(name) + , byteOffset(byteOffset) + , binding(binding) +{ +} + +ShaderParameter::~ShaderParameter() +{ +} + +FloatParameter::FloatParameter(std::string name, uint32 byteOffset, uint32 binding) + : ShaderParameter(name, byteOffset, binding) +{ +} + +FloatParameter::~FloatParameter() +{ +} + +void FloatParameter::updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) +{ + std::memcpy(dst + byteOffset, &data, sizeof(float)); +} + +VectorParameter::VectorParameter(std::string name, uint32 byteOffset, uint32 binding) + : ShaderParameter(name, byteOffset, binding) +{ +} + +VectorParameter::~VectorParameter() +{ +} + +void VectorParameter::updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) +{ + std::memcpy(dst + byteOffset, &data, sizeof(Vector)); +} + +TextureParameter::TextureParameter(std::string name, uint32 byteOffset, uint32 binding) + : ShaderParameter(name, byteOffset, binding) +{ +} + +TextureParameter::~TextureParameter() +{ +} + +void TextureParameter::updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) +{ + descriptorSet->updateTexture(binding, data->getTexture()); +} + +SamplerParameter::SamplerParameter(std::string name, uint32 byteOffset, uint32 binding) + : ShaderParameter(name, byteOffset, binding) +{ +} + +SamplerParameter::~SamplerParameter() +{ + +} + +void SamplerParameter::updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) +{ + descriptorSet->updateSampler(binding, data); +} \ No newline at end of file diff --git a/src/Engine/Scene/Actor/Actor.h b/src/Engine/Scene/Actor/Actor.h index 0ec1de9..5ae57f7 100644 --- a/src/Engine/Scene/Actor/Actor.h +++ b/src/Engine/Scene/Actor/Actor.h @@ -35,7 +35,7 @@ public: PComponent getRootComponent(); void setRootComponent(PComponent newRoot); -private: +protected: void setParent(PActor parent); PScene owningScene; PActor parent; diff --git a/src/Engine/Scene/Actor/CMakeLists.txt b/src/Engine/Scene/Actor/CMakeLists.txt index 3aa282d..85f3357 100644 --- a/src/Engine/Scene/Actor/CMakeLists.txt +++ b/src/Engine/Scene/Actor/CMakeLists.txt @@ -1,4 +1,6 @@ target_sources(SeeleEngine PRIVATE Actor.cpp - Actor.h) \ No newline at end of file + Actor.h + CameraActor.cpp + CameraActor.h) \ No newline at end of file diff --git a/src/Engine/Scene/Actor/CameraActor.cpp b/src/Engine/Scene/Actor/CameraActor.cpp new file mode 100644 index 0000000..d374a2e --- /dev/null +++ b/src/Engine/Scene/Actor/CameraActor.cpp @@ -0,0 +1,21 @@ +#include "CameraActor.h" +#include "Scene/Components/Component.h" +#include "Scene/Components/CameraComponent.h" + +using namespace Seele; + +CameraActor::CameraActor() +{ + sceneComponent = new Component(); + setRootComponent(sceneComponent); + + cameraComponent = new CameraComponent(); + cameraComponent->fieldOfView = 70.0f; + cameraComponent->aspectRatio = 1.777778f; + cameraComponent->setParent(sceneComponent); + cameraComponent->setOwner(this); +} + +CameraActor::~CameraActor() +{ +} \ No newline at end of file diff --git a/src/Engine/Scene/Actor/CameraActor.h b/src/Engine/Scene/Actor/CameraActor.h new file mode 100644 index 0000000..133d0ab --- /dev/null +++ b/src/Engine/Scene/Actor/CameraActor.h @@ -0,0 +1,21 @@ +#pragma once +#include "Actor.h" + +namespace Seele +{ +DECLARE_REF(CameraComponent) +class CameraActor : public Actor +{ +public: + CameraActor(); + virtual ~CameraActor(); + PCameraComponent getCameraComponent() const + { + return cameraComponent; + } +private: + PCameraComponent cameraComponent; + PComponent sceneComponent; // This will be the root, camera will be the child +}; +DEFINE_REF(CameraActor); +} // namespace Seele diff --git a/src/Engine/Scene/Components/CMakeLists.txt b/src/Engine/Scene/Components/CMakeLists.txt index 3871b11..fb05eb3 100644 --- a/src/Engine/Scene/Components/CMakeLists.txt +++ b/src/Engine/Scene/Components/CMakeLists.txt @@ -1,5 +1,7 @@ target_sources(SeeleEngine PRIVATE + CameraComponent.h + CameraComponent.cpp Component.h Component.cpp PrimitiveComponent.cpp diff --git a/src/Engine/Scene/Components/CameraComponent.cpp b/src/Engine/Scene/Components/CameraComponent.cpp new file mode 100644 index 0000000..48a84bd --- /dev/null +++ b/src/Engine/Scene/Components/CameraComponent.cpp @@ -0,0 +1,69 @@ +#include "CameraComponent.h" +#include + +using namespace Seele; + +CameraComponent::CameraComponent() + : bNeedsProjectionBuild(true) + , bNeedsViewBuild(true) + , originPoint(0, 0, 0) + , cameraPosition(0, 0, 0) +{ + distance = 50; + rotationX = 0; + rotationY = -0.5f; +} + +CameraComponent::~CameraComponent() +{ +} + +void CameraComponent::mouseMove(float deltaX, float deltaY) +{ + //0.01 mouse sensitivity + rotationX += deltaX/100.f; + rotationY += deltaY/100.f; + rotationY = std::clamp(rotationY, -1.5f, 1.5f); + bNeedsViewBuild = true; +} + +void CameraComponent::mouseScroll(double x) +{ + distance += static_cast(x); + distance = std::max(distance, 1.f); + bNeedsViewBuild = true; +} + +void CameraComponent::moveOrigin(float up) +{ + originPoint.y += up; + bNeedsViewBuild = true; +} + +void CameraComponent::buildViewMatrix() +{ + Matrix4 rotation = glm::rotate(Matrix4(), rotationX, Vector(0, 1, 0)); + rotation = glm::rotate(rotation, rotationY, Vector(1, 0, 0)); + Vector4 translation(0, 0, distance, 1); + translation = rotation * translation; + + cameraPosition = originPoint + Vector(translation); + viewMatrix = glm::lookAt(cameraPosition, originPoint, Vector(0, 1, 0)); + + bNeedsViewBuild = false; +} + +void CameraComponent::buildProjectionMatrix() +{ + projectionMatrix = glm::perspective(fieldOfView, aspectRatio, 1.0f, 1000.f); + static Matrix4 correctionMatrix = + Matrix4( + Vector4(1, 0, 0, 0), + Vector4(0, 1, 0, 0), + Vector4(0, 0, 0.5f, 0), + Vector4(0, 0, 0.5f, 1)); + projectionMatrix = correctionMatrix * projectionMatrix; + bNeedsProjectionBuild = false; +} + + diff --git a/src/Engine/Scene/Components/CameraComponent.h b/src/Engine/Scene/Components/CameraComponent.h new file mode 100644 index 0000000..5cbd4eb --- /dev/null +++ b/src/Engine/Scene/Components/CameraComponent.h @@ -0,0 +1,52 @@ +#pragma once +#include "Component.h" +#include "Math/Matrix.h" + +namespace Seele +{ +class CameraComponent : public Component +{ +public: + CameraComponent(); + virtual ~CameraComponent(); + + Matrix4 getViewMatrix() + { + if (bNeedsViewBuild) + { + buildViewMatrix(); + } + return viewMatrix; + } + Matrix4 getProjectionMatrix() + { + if (bNeedsProjectionBuild) + { + buildProjectionMatrix(); + } + return projectionMatrix; + } + void mouseMove(float deltaX, float deltaY); + void mouseScroll(double x); + void moveOrigin(float up); + float aspectRatio; + float fieldOfView; +private: + bool bNeedsViewBuild; + bool bNeedsProjectionBuild; + void buildViewMatrix(); + void buildProjectionMatrix(); + + float rotationX; + float rotationY; + float distance; + + Vector eye; + Vector originPoint; + Vector cameraPosition; + //Transforms relative to actor + Matrix4 viewMatrix; + Matrix4 projectionMatrix; +}; +DEFINE_REF(CameraComponent); +} // namespace Seele diff --git a/src/Engine/Scene/Components/Component.cpp b/src/Engine/Scene/Components/Component.cpp index ddda15f..df38619 100644 --- a/src/Engine/Scene/Components/Component.cpp +++ b/src/Engine/Scene/Components/Component.cpp @@ -124,6 +124,11 @@ void Component::setParent(PComponent newParent) parent = newParent; } +void Component::setOwner(PActor newOwner) +{ + owner = newOwner; +} + void Component::internalSetTransform(Vector newLocation, Quaternion newRotation) { if (parent != nullptr) diff --git a/src/Engine/Scene/Components/Component.h b/src/Engine/Scene/Components/Component.h index 213582d..f4b41db 100644 --- a/src/Engine/Scene/Components/Component.h +++ b/src/Engine/Scene/Components/Component.h @@ -15,6 +15,8 @@ public: void tick(float deltaTime); PComponent getParent(); PActor getOwner(); + void setParent(PComponent parent); + void setOwner(PActor owner); virtual void notifySceneAttach(PScene scene); void setWorldLocation(Vector location); @@ -34,7 +36,6 @@ public: Transform getTransform() const; private: - void setParent(PComponent parent); void internalSetTransform(Vector newLocation, Quaternion newRotation); void propagateTransformUpdate(); void updateComponentTransform(Quaternion relativeRotationQuat); diff --git a/src/Engine/Scene/Components/PrimitiveComponent.cpp b/src/Engine/Scene/Components/PrimitiveComponent.cpp index 7382e5d..99cf0d1 100644 --- a/src/Engine/Scene/Components/PrimitiveComponent.cpp +++ b/src/Engine/Scene/Components/PrimitiveComponent.cpp @@ -17,7 +17,7 @@ PrimitiveComponent::PrimitiveComponent(PMeshAsset asset) for (uint32 i = 0; i < assetMeshes.size(); i++) { auto& batch = staticMeshes[i]; - batch.material = assetMeshes[i]->referencedMaterial->getRenderMaterial(); + batch.material = assetMeshes[i]->referencedMaterial; batch.isBackfaceCullingDisabled = false; batch.isCastingShadow = true; batch.primitiveComponent = this; diff --git a/src/Engine/Scene/Scene.h b/src/Engine/Scene/Scene.h index 13ae5cc..ac6eedc 100644 --- a/src/Engine/Scene/Scene.h +++ b/src/Engine/Scene/Scene.h @@ -10,6 +10,30 @@ namespace Seele { DECLARE_REF(Material); +struct DirectionalLight +{ + Vector4 color; + Vector4 direction; + Vector4 intensity; +}; + +struct PointLight +{ + Vector4 positionWS; + Vector4 positionVS; + Vector4 colorRange; +}; + +#define MAX_DIRECTIONAL_LIGHTS 4 +#define MAX_POINT_LIGHTS 256 +struct LightEnv +{ + DirectionalLight directionalLights[MAX_DIRECTIONAL_LIGHTS]; + PointLight pointLights[MAX_POINT_LIGHTS]; + uint32 numDirectionalLgiths; + uint32 numPointLights; +}; + class Scene { public: @@ -21,10 +45,12 @@ public: const Array& getPrimitives() const { return primitives; } const Array& getStaticMeshes() const { return staticMeshes; } + const LightEnv& getLightEnvironment() const { return lightEnv; } private: Array staticMeshes; Array rootActors; Array primitives; + LightEnv lightEnv; Gfx::PGraphics graphics; }; } // namespace Seele \ No newline at end of file