diff --git a/shaders/simple_shader.frag b/shaders/simple_shader.frag index 1786c23b..f7cfa452 100644 --- a/shaders/simple_shader.frag +++ b/shaders/simple_shader.frag @@ -2,14 +2,18 @@ layout(set=1, binding = 0) uniform sampler2D texSampler; -layout(location = 0) in vec3 fragColor; +layout(location = 0) in vec3 fragNormal; layout(location = 1) in vec2 fragTexCoord; layout(location = 0) out vec4 outColor; -layout(location = 1) out vec2 outNormal; +layout(location = 1) out vec3 outNormal; void main() { - // outColor = vec4(fragColor, 1.0); outColor = texture(texSampler, fragTexCoord); - outNormal = fragTexCoord; + + vec3 abs_normal = abs(fragNormal); + + float grey_shade = abs_normal.x * 0.299 + abs_normal.y * 0.587 + abs_normal.z * 0.114; + + outNormal = vec3(grey_shade, grey_shade, grey_shade); } diff --git a/shaders/simple_shader.vert b/shaders/simple_shader.vert index 1c5e9e05..79d1acd1 100644 --- a/shaders/simple_shader.vert +++ b/shaders/simple_shader.vert @@ -10,14 +10,17 @@ layout(push_constant) uniform PushConstantObject { } pc; layout(location = 0) in vec3 inPosition; -layout(location = 1) in vec3 inColor; +layout(location = 1) in vec3 inNormal; layout(location = 2) in vec2 inTexCoord; -layout(location = 0) out vec3 fragColor; +layout(location = 0) out vec3 fragNormal; layout(location = 1) out vec2 fragTexCoord; void main() { gl_Position = ubo.proj * ubo.view * pc.model * vec4(inPosition, 1.0); - fragColor = inColor; + + // convert normal to world space + fragNormal = normalize((pc.model * vec4(inNormal, 0.0)).xyz); + fragTexCoord = inTexCoord; } diff --git a/src/app/application.cpp b/src/app/application.cpp index aa89c55f..4324029e 100644 --- a/src/app/application.cpp +++ b/src/app/application.cpp @@ -11,10 +11,19 @@ Application::Application(): { LOG_INFO("Application::Application()"); - m_world_scene.camera().setPosition(glm::vec3(-2.0f, 2.0f, 2.0f)); - m_world_scene.camera().moveDirection(-150.0f, 150.0f); + m_world_scene.camera().setPosition(glm::vec3(20.0f, 20.0f, 20.0f)); + m_world_scene.camera().lookAt(glm::vec3(0.0f, 0.0f, 0.0f)); - m_world_scene.addMeshData(1, glm::mat4(1.0f)); + int size = 10; + for (int x = -size; x < size; x++) + { + for (int z = -size; z < size; z++) + { + // 2d circular sine wave + int y = 3 * sin(0.4 * sqrt(x * x + z * z)); + m_world_scene.addMeshData(1, WorldScene::Transform(glm::vec3(x, y, z))); + } + } } Application::~Application() diff --git a/src/app/scenes/WorldScene.cpp b/src/app/scenes/WorldScene.cpp index bac68ded..09a6723a 100644 --- a/src/app/scenes/WorldScene.cpp +++ b/src/app/scenes/WorldScene.cpp @@ -9,16 +9,16 @@ WorldScene::~WorldScene() { } -void WorldScene::addMeshData(uint32_t meshID, glm::mat4 model) +void WorldScene::addMeshData(uint64_t meshID, const Transform & transform) { std::unique_lock lock(m_mesh_render_data_mutex); m_mesh_render_data.push_back({ .id = meshID, - .model = model + .transform = transform }); } -void WorldScene::removeMesh(uint32_t meshID) +void WorldScene::removeMesh(uint64_t meshID) { std::unique_lock lock(m_mesh_render_data_mutex); std::remove_if(m_mesh_render_data.begin(), m_mesh_render_data.end(), [meshID](MeshRenderData& mesh_render_data) { @@ -43,7 +43,7 @@ glm::mat4 WorldScene::Camera::getViewMatrix() const glm::mat4 WorldScene::Camera::getProjectionMatrix(float aspect_ratio) const { std::lock_guard lock(m_mutex); - return glm::perspective(glm::radians(fov), aspect_ratio, 0.1f, 100.0f); + return glm::perspective(glm::radians(fov), aspect_ratio, 0.1f, far_plane); } void WorldScene::Camera::moveForward(float distance) @@ -81,6 +81,14 @@ void WorldScene::Camera::setPosition(const glm::vec3& position) this->position = position; } +void WorldScene::Camera::lookAt(const glm::vec3& target) +{ + std::lock_guard lock(m_mutex); + glm::vec3 direction = glm::normalize(target - position); + pitch = glm::degrees(asin(direction.y)); + yaw = glm::degrees(atan2(direction.z, direction.x)); +} + glm::vec3 WorldScene::Camera::direction() const { return glm::vec3( diff --git a/src/app/scenes/WorldScene.hpp b/src/app/scenes/WorldScene.hpp index 798cc3cf..3521d534 100644 --- a/src/app/scenes/WorldScene.hpp +++ b/src/app/scenes/WorldScene.hpp @@ -19,10 +19,50 @@ class WorldScene public: + class Transform + { + public: + Transform( + const glm::vec3 & position = glm::vec3(0.0f, 0.0f, 0.0f), + const glm::vec3 & rotation = glm::vec3(0.0f, 0.0f, 0.0f), + const glm::vec3 & scale = glm::vec3(1.0f, 1.0f, 1.0f) + ): + m_position(position), m_rotation(rotation), m_scale(scale) + { + } + + glm::vec3 & position() { return m_position; } + const glm::vec3 & position() const { return m_position; } + + glm::vec3 & rotation() { return m_rotation; } + const glm::vec3 & rotation() const { return m_rotation; } + + glm::vec3 & scale() { return m_scale; } + const glm::vec3 & scale() const { return m_scale; } + + glm::mat4 model() const + { + glm::mat4 model = glm::mat4(1.0f); + model = glm::translate(model, m_position); + model = glm::rotate(model, m_rotation.x, glm::vec3(1.0f, 0.0f, 0.0f)); + model = glm::rotate(model, m_rotation.y, glm::vec3(0.0f, 1.0f, 0.0f)); + model = glm::rotate(model, m_rotation.z, glm::vec3(0.0f, 0.0f, 1.0f)); + model = glm::scale(model, m_scale); + return model; + } + + private: + + glm::vec3 m_position; + glm::vec3 m_rotation; + glm::vec3 m_scale; + + }; + struct MeshRenderData { uint64_t id; - glm::mat4 model; + Transform transform; }; class Camera @@ -87,7 +127,14 @@ class WorldScene * * @param position */ - void setPosition(const glm::vec3& position); + void setPosition(const glm::vec3 & position); + + /** + * @brief Set the pitch and yaw of the camera to look at a target. + * + * @param target + */ + void lookAt(const glm::vec3 & target); private: @@ -96,6 +143,7 @@ class WorldScene float yaw{ 0.0f }; glm::vec3 up{ 0.0f, 1.0f, 0.0f }; float fov{ 45.0f }; + float far_plane{ 300.0f }; mutable std::mutex m_mutex; @@ -115,6 +163,7 @@ class WorldScene WorldScene(WorldScene& scene) = delete; WorldScene(WorldScene&& scene) = delete; WorldScene& operator=(WorldScene& scene) = delete; + WorldScene& operator=(WorldScene&& scene) = delete; /** * @brief Function to add a mesh to the scene. @@ -122,14 +171,14 @@ class WorldScene * @param meshID The mesh ID. * @param model The model matrix of the mesh. */ - void addMeshData(uint32_t meshID, glm::mat4 model); + void addMeshData(uint64_t meshID, const Transform & transform); /** * @brief Function to remove a mesh from the scene. * * @param meshID The mesh ID to remove. */ - void removeMesh(uint32_t meshID); + void removeMesh(uint64_t meshID); /** * @brief Function to get the mesh data. diff --git a/src/app/threads/render/RenderThread.cpp b/src/app/threads/render/RenderThread.cpp index 7b36c1e9..3af40d26 100644 --- a/src/app/threads/render/RenderThread.cpp +++ b/src/app/threads/render/RenderThread.cpp @@ -52,7 +52,10 @@ void RenderThread::init() pipeline_create_info.push_constant_ranges = { {VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(ModelMatrix_push_constant)} }; - pipeline_create_info.color_target_ids = {m_texture_color_target_id, m_normal_color_target_id}; + pipeline_create_info.color_target_ids = { + m_texture_color_target_id, + m_normal_color_target_id + }; pipeline_create_info.depth_target_id = m_depth_target_id; m_simple_shader_pipeline_id = m_renderAPI.newPipeline(pipeline_create_info); @@ -64,6 +67,7 @@ void RenderThread::loop() auto currentTime = std::chrono::high_resolution_clock::now(); auto time = std::chrono::duration(currentTime - startTime).count(); + (void)time; std::vector mesh_render_data = m_world_scene.getMeshRenderData(); @@ -114,10 +118,12 @@ void RenderThread::loop() scissor.extent = { static_cast(width), static_cast(height) }; m_renderAPI.setScissor(scissor); - for (auto& data : mesh_render_data) + for (auto& mesh_data : mesh_render_data) { ModelMatrix_push_constant pushConstant{}; - pushConstant.model = data.model * glm::rotate(glm::mat4(1.0f), time * glm::radians(90.0f), glm::vec3(0.0f, 1.0f, 0.0f)); + pushConstant.model = mesh_data.transform.model() + * glm::rotate(glm::mat4(1.0f), time * glm::radians(45.0f), glm::vec3(0.0f, 1.0f, 0.0f)) + * glm::rotate(glm::mat4(1.0f), time * glm::radians(45.0f), glm::vec3(1.0f, 0.0f, 0.0f)); m_renderAPI.pushConstant( m_simple_shader_pipeline_id, VK_SHADER_STAGE_VERTEX_BIT, @@ -125,7 +131,7 @@ void RenderThread::loop() &pushConstant ); - m_renderAPI.drawMesh(data.id); + m_renderAPI.drawMesh(mesh_data.id); } //############################################################################