diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index cd3d381..8b8ad22 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -11,6 +11,20 @@ "cppStandard": "gnu++17", "intelliSenseMode": "linux-gcc-x64", "configurationProvider": "ms-vscode.makefile-tools" + }, + { + "name": "Mac", + "includePath": [ + "${workspaceFolder}/**", + "/Users/wanghao/VulkanSDK/1.4.328.1/macOS/include", + "/opt/local/include", + "/usr/local/include" + ], + "defines": [], + "compilerPath": "/usr/bin/clang++", + "cStandard": "c17", + "cppStandard": "c++17", + "intelliSenseMode": "macos-clang-arm64" } ], "version": 4 diff --git a/Makefile b/Makefile index 5d1825f..259c901 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ VULKAN_SDK_PATH = /Users/wanghao/VulkanSDK/1.4.328.1/macOS +GLSLC = $(VULKAN_SDK_PATH)/bin/glslc CFLAGS = -std=c++17 -o2 -I. -I$(VULKAN_SDK_PATH)/include -I/opt/local/include LDFLAGS = -L$(VULKAN_SDK_PATH)/lib -L/opt/local/lib `pkg-config --static --libs glfw3` -lvulkan -ldl -lpthread -lX11 diff --git a/VulkanTest b/VulkanTest index e8c3f5a..5fc6210 100755 Binary files a/VulkanTest and b/VulkanTest differ diff --git a/first_app.cpp b/first_app.cpp index 6519e32..b9e4b06 100644 --- a/first_app.cpp +++ b/first_app.cpp @@ -1,7 +1,6 @@ #include "first_app.hpp" #include "simple_render_system.hpp" #include "rainbow_system.hpp" -#include "gravity_physics_system.hpp" // libs #define GLM_FORCE_RADIANS @@ -25,72 +24,6 @@ namespace hk { } - void FirstApp::runGravitySystem() - { - // Gravity Physics System - // Create some Models - std::shared_ptr squareModel = createSquareModel(m_device, {.5f, .0f}); - std::shared_ptr circleModel = createCircleModel(m_device, 64); - // Create Physics Objects - std::vector physicsObjects{}; - auto red = GameObject::createGameObject(); - red.m_transform2d.scale = glm::vec2{.05f}; - red.m_transform2d.translation = {.5f, .5f}; - red.m_color = {1.f, 0.f, 0.f}; - red.m_rigidBody2d.velocity = {-.5f, .0f}; - red.m_model = circleModel; - physicsObjects.push_back(std::move(red)); - auto blue = GameObject::createGameObject(); - blue.m_transform2d.scale = glm::vec2{.05f}; - blue.m_transform2d.translation = {-.45f, -.25f}; - blue.m_color = {0.f, 0.f, 1.f}; - blue.m_rigidBody2d.velocity = {.5f, .0f}; - blue.m_model = circleModel; - physicsObjects.push_back(std::move(blue)); - - // Create Vector Field - std::vector vectorField{}; - int gridCount = 40; - for (int i = 0; i < gridCount; i++) - { - for(int j = 0; j < gridCount; j ++) - { - auto vf = GameObject::createGameObject(); - vf.m_transform2d.scale = glm::vec2{0.005f}; - vf.m_transform2d.translation = {-1.0f + (i + 0.5f) * 2.0f / gridCount, -1.0f + (j + 0.5f) * 2.0f / gridCount}; - vf.m_color = glm::vec3{1.0f}; - vf.m_model = squareModel; - vectorField.push_back(std::move(vf)); - } - } - - GravityPhysicsSystem gravitySystem(0.81f); - Vec2FieldSystem vecFieldSystem{}; - - SimpleRenderSystem simpleRenderSystem{m_device, m_renderer.getSwapChainRenderPass()}; - - while(!m_window.shouldClose()) - { - glfwPollEvents(); - - if (auto commandBuffer = m_renderer.beginFrame()) - { - // update system - gravitySystem.update(physicsObjects, 1.f / 60, 5); - vecFieldSystem.update(gravitySystem, physicsObjects, vectorField); - - // render system - m_renderer.beginSwapChainRenderPass(commandBuffer); - simpleRenderSystem.renderGameObjects(commandBuffer, physicsObjects); - simpleRenderSystem.renderGameObjects(commandBuffer, vectorField); - m_renderer.endSwapChainRenderPass(commandBuffer); - m_renderer.endFrame(); - } - - vkDeviceWaitIdle(m_device.device()); - } - } - void FirstApp::run() { SimpleRenderSystem simpleRenderSystem{m_device, m_renderer.getSwapChainRenderPass()}; @@ -115,22 +48,74 @@ namespace hk vkDeviceWaitIdle(m_device.device()); } - void FirstApp::loadGameObjects() + // temporary helper function, creates a 1x1x1 cube centered at offset + std::unique_ptr createCubeModel(hk::Device &device, glm::vec3 offset) { std::vector vertices{ - {{0.0f, -0.5f}, {1.0f, 0.0f, 0.0f}}, - {{0.5f, 0.5f}, {0.0f, 1.0f, 0.0f}}, - {{-0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}} - }; - auto model = std::make_shared(m_device, vertices); - auto triangle = GameObject::createGameObject(); - triangle.m_model = model; - triangle.m_color = {.1f, .8f, .1f}; - triangle.m_transform2d.translation.x = .2f; - triangle.m_transform2d.scale = {2.0f, .5f}; - triangle.m_transform2d.rotation = .25f * glm::two_pi(); - - m_gameObjects.push_back(std::move(triangle)); + // left face (white) + {{-.5f, -.5f, -.5f}, {.9f, .9f, .9f}}, + {{-.5f, .5f, .5f}, {.9f, .9f, .9f}}, + {{-.5f, -.5f, .5f}, {.9f, .9f, .9f}}, + {{-.5f, -.5f, -.5f}, {.9f, .9f, .9f}}, + {{-.5f, .5f, -.5f}, {.9f, .9f, .9f}}, + {{-.5f, .5f, .5f}, {.9f, .9f, .9f}}, + + // right face (yellow) + {{.5f, -.5f, -.5f}, {.8f, .8f, .1f}}, + {{.5f, .5f, .5f}, {.8f, .8f, .1f}}, + {{.5f, -.5f, .5f}, {.8f, .8f, .1f}}, + {{.5f, -.5f, -.5f}, {.8f, .8f, .1f}}, + {{.5f, .5f, -.5f}, {.8f, .8f, .1f}}, + {{.5f, .5f, .5f}, {.8f, .8f, .1f}}, + + // top face (orange, remember y axis points down) + {{-.5f, -.5f, -.5f}, {.9f, .6f, .1f}}, + {{.5f, -.5f, .5f}, {.9f, .6f, .1f}}, + {{-.5f, -.5f, .5f}, {.9f, .6f, .1f}}, + {{-.5f, -.5f, -.5f}, {.9f, .6f, .1f}}, + {{.5f, -.5f, -.5f}, {.9f, .6f, .1f}}, + {{.5f, -.5f, .5f}, {.9f, .6f, .1f}}, + + // bottom face (red) + {{-.5f, .5f, -.5f}, {.8f, .1f, .1f}}, + {{.5f, .5f, .5f}, {.8f, .1f, .1f}}, + {{-.5f, .5f, .5f}, {.8f, .1f, .1f}}, + {{-.5f, .5f, -.5f}, {.8f, .1f, .1f}}, + {{.5f, .5f, -.5f}, {.8f, .1f, .1f}}, + {{.5f, .5f, .5f}, {.8f, .1f, .1f}}, + + // nose face (blue) + {{-.5f, -.5f, 0.5f}, {.1f, .1f, .8f}}, + {{.5f, .5f, 0.5f}, {.1f, .1f, .8f}}, + {{-.5f, .5f, 0.5f}, {.1f, .1f, .8f}}, + {{-.5f, -.5f, 0.5f}, {.1f, .1f, .8f}}, + {{.5f, -.5f, 0.5f}, {.1f, .1f, .8f}}, + {{.5f, .5f, 0.5f}, {.1f, .1f, .8f}}, + + // tail face (green) + {{-.5f, -.5f, -0.5f}, {.1f, .8f, .1f}}, + {{.5f, .5f, -0.5f}, {.1f, .8f, .1f}}, + {{-.5f, .5f, -0.5f}, {.1f, .8f, .1f}}, + {{-.5f, -.5f, -0.5f}, {.1f, .8f, .1f}}, + {{.5f, -.5f, -0.5f}, {.1f, .8f, .1f}}, + {{.5f, .5f, -0.5f}, {.1f, .8f, .1f}}, + + }; + for (auto &v : vertices) + { + v.position += offset; + } + return std::make_unique(device, vertices); + } + + void FirstApp::loadGameObjects() + { + std::shared_ptr cubeModel = createCubeModel(m_device, {0.f, 0.f, 0.f}); + auto cube = GameObject::createGameObject(); + cube.m_model = cubeModel; + cube.m_transform.translation = {0.f, 0.f, .5f}; + cube.m_transform.scale = {.5f, .5f, .5f}; + m_gameObjects.push_back(std::move(cube)); } } // namespace hk \ No newline at end of file diff --git a/gravity_physics_system.hpp b/gravity_physics_system.hpp deleted file mode 100644 index b53f3f1..0000000 --- a/gravity_physics_system.hpp +++ /dev/null @@ -1,129 +0,0 @@ -#pragma once - -#include - -#define GLM_FORCE_RADIANS -#define GLM_FORCE_DEPTH_ZERO_TO_ONE -#include -#include - -// std -#include -#include -#include - -namespace hk -{ - class GravityPhysicsSystem - { - public: - GravityPhysicsSystem(float strength) :m_strengthGravity(strength) {} - - void update(std::vector &objs, float dt, unsigned int substeps = 1) - { - const float stepDelta = dt / substeps; - - for (int i = 0; i < substeps; i++) - { - stepSimulation(objs, stepDelta); - } - } - - glm::vec2 computeForce(GameObject &fromObj, GameObject &toObj) const - { - auto offset = fromObj.m_transform2d.translation - toObj.m_transform2d.translation; - float distanceSquared = glm::dot(offset, offset); - - if (glm::abs(distanceSquared < 1e-10f)) - { - return {.0f, .0f}; - } - float force = m_strengthGravity * toObj.m_rigidBody2d.mass * fromObj.m_rigidBody2d.mass / distanceSquared; - - return force * offset / glm::sqrt(distanceSquared); - } - - const float m_strengthGravity; - private: - void stepSimulation(std::vector &physicsObjs, float dt) - { - // Loops throught all pairs of objects and applies attractive force between them - for (auto iterA = physicsObjs.begin(); iterA != physicsObjs.end(); ++iterA) - { - auto &objA = *iterA; - for (auto iterB = iterA; iterB != physicsObjs.end(); ++iterB) - { - if (iterA == iterB) continue; - - auto &objB = *iterB; - auto force = computeForce(objA, objB); - objA.m_rigidBody2d.velocity += dt * -force / objA.m_rigidBody2d.mass; - objB.m_rigidBody2d.velocity += dt * force / objB.m_rigidBody2d.mass; - } - } - - // update each objects position based on its final velocity - for (auto &obj : physicsObjs) - { - obj.m_transform2d.translation += dt * obj.m_rigidBody2d.velocity; - } - } - }; - - class Vec2FieldSystem - { - public: - void update(const GravityPhysicsSystem &physicsSystem, std::vector &physicsObjs, std::vector &vectorField) - { - for (auto &vf : vectorField) - { - glm::vec2 direction{}; - for (auto &obj : physicsObjs) - { - direction += physicsSystem.computeForce(obj, vf); - } - - vf.m_transform2d.scale.x = 0.005f + 0.045f * glm::clamp(glm::log(glm::length(direction) + 1) / 3.f, 0.f, 1.f); - vf.m_transform2d.rotation = atan2(direction.y, direction.x); - } - } - }; - - std::unique_ptr createSquareModel(Device &device, glm::vec2 offset) - { - std::vector vertices = { - {{-0.5f, -0.5f}}, {{0.5f, 0.5f}}, - {{-0.5f, 0.5f}}, {{-0.5f, -0.5f}}, - {{0.5f, -0.5f}}, {{0.5f, 0.5f}}, - }; - - for (auto &v : vertices) - { - v.posision += offset; - } - - return std::make_unique(device, vertices); - } - - std::unique_ptr createCircleModel(Device &device, unsigned int numSides) - { - std::vector uniqueVertices{}; - for(int i = 0; i < numSides; i++) - { - float angle = i * glm::two_pi() / numSides; - uniqueVertices.push_back({{glm::cos(angle), glm::sin(angle)}}); - } - - uniqueVertices.push_back({}); - - std::vector vertices{}; - for(int i = 0; i < numSides; i++) - { - vertices.push_back(uniqueVertices[i]); - vertices.push_back(uniqueVertices[(i+1) % numSides]); - vertices.push_back(uniqueVertices[numSides]); - } - return std::make_unique(device, vertices); - } - -} \ No newline at end of file diff --git a/hk_game_object.hpp b/hk_game_object.hpp index 6a2521b..736385b 100644 --- a/hk_game_object.hpp +++ b/hk_game_object.hpp @@ -2,29 +2,51 @@ #include "hk_model.hpp" +// libs +#include + // std #include namespace hk { - struct Transform2dComponent + struct TransformComponent { - glm::vec2 translation{}; - glm::vec2 scale{1.0f, 1.0f}; - float rotation; - glm::mat2 mat2() + glm::vec3 translation{}; + glm::vec3 scale{1.0f, 1.0f, 1.0f}; + glm::vec3 rotation{}; + + // Matrix corrsponds to Translate * Ry * Rx * Rz * Scale + // Rotations correspond to Tait-bryan angles of Y(1), X(2), Z(3) + // https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix + glm::mat4 mat4() { - const float cos = glm::cos(rotation); - const float sin = glm::sin(rotation); - glm::mat2 rotationMat{ - {cos, sin}, - {-sin, cos}}; - - glm::mat2 scaleMat{ - {scale.x, .0f}, - {.0f, scale.y}}; - - return rotationMat * scaleMat; + const float c3 = glm::cos(rotation.z); + const float s3 = glm::sin(rotation.z); + const float c2 = glm::cos(rotation.x); + const float s2 = glm::sin(rotation.x); + const float c1 = glm::cos(rotation.y); + const float s1 = glm::sin(rotation.y); + return glm::mat4{ + { + scale.x * (c1 * c3 + s1 * s2 * s3), + scale.x * (c2 * s3), + scale.x * (c1 * s2 * s3 - c3 * s1), + 0.0f, + }, + { + scale.y * (c3 * s1 * s2 - c1 * s3), + scale.y * (c2 * c3), + scale.y * (c1 * c3 * s2 + s1 * s3), + 0.0f, + }, + { + scale.z * (c2 * s1), + scale.z * (-s2), + scale.z * (c1 * c2), + 0.0f, + }, + {translation.x, translation.y, translation.z, 1.0f}}; } }; @@ -55,7 +77,7 @@ namespace hk std::shared_ptr m_model{}; glm::vec3 m_color{}; - Transform2dComponent m_transform2d{}; + TransformComponent m_transform{}; RigidBody2dComponent m_rigidBody2d{}; diff --git a/hk_model.cpp b/hk_model.cpp index 9ec33fd..fb549ee 100644 --- a/hk_model.cpp +++ b/hk_model.cpp @@ -58,8 +58,8 @@ namespace hk{ std::vector attributeDescriptions(2); attributeDescriptions[0].binding = 0; attributeDescriptions[0].location = 0; - attributeDescriptions[0].format = VK_FORMAT_R32G32_SFLOAT; - attributeDescriptions[0].offset = offsetof(Vertex, posision); + attributeDescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT; + attributeDescriptions[0].offset = offsetof(Vertex, position); attributeDescriptions[1].binding = 0; attributeDescriptions[1].location = 1; diff --git a/hk_model.hpp b/hk_model.hpp index 6514f86..22d6550 100644 --- a/hk_model.hpp +++ b/hk_model.hpp @@ -13,7 +13,7 @@ namespace hk{ { public: struct Vertex { - glm::vec2 posision; + glm::vec3 position; glm::vec3 color; static std::vector getBindingDescriptions(); diff --git a/main.cpp b/main.cpp index ee252b8..e7e76be 100644 --- a/main.cpp +++ b/main.cpp @@ -5,19 +5,13 @@ #include #include -#define GRAVITY_SYSTEM 0 - int main() { hk::FirstApp app{}; try { -#if GRAVITY_SYSTEM == 1 - app.runGravitySystem(); -#else app.run(); -#endif } catch(const std::exception& e) { diff --git a/shaders/simple_shader.frag b/shaders/simple_shader.frag index 1ac75db..f794937 100644 --- a/shaders/simple_shader.frag +++ b/shaders/simple_shader.frag @@ -1,13 +1,13 @@ #version 450 +layout (location = 0) in vec3 fragColor; layout (location = 0) out vec4 outColor; layout(push_constant) uniform Push{ - mat2 transform; - vec2 offset; + mat4 transform; vec3 color; } push; void main(){ - outColor = vec4(push.color, 1.0); + outColor = vec4(fragColor, 1.0); } \ No newline at end of file diff --git a/shaders/simple_shader.frag.spv b/shaders/simple_shader.frag.spv index 96bd40b..2539eb5 100644 Binary files a/shaders/simple_shader.frag.spv and b/shaders/simple_shader.frag.spv differ diff --git a/shaders/simple_shader.vert b/shaders/simple_shader.vert index 575caf9..6ba50dd 100644 --- a/shaders/simple_shader.vert +++ b/shaders/simple_shader.vert @@ -1,14 +1,16 @@ #version 450 -layout(location = 0) in vec2 position; +layout(location = 0) in vec3 position; layout(location = 1) in vec3 color; +layout(location = 0) out vec3 fragColor; + layout(push_constant) uniform Push{ - mat2 transform; - vec2 offset; + mat4 transform; vec3 color; } push; void main(){ - gl_Position = vec4(push.transform * position + push.offset, 0.0, 1.0); + gl_Position = push.transform * vec4(position, 1.0); + fragColor = color; } diff --git a/shaders/simple_shader.vert.spv b/shaders/simple_shader.vert.spv index 807bfb5..b343590 100644 Binary files a/shaders/simple_shader.vert.spv and b/shaders/simple_shader.vert.spv differ diff --git a/simple_render_system.cpp b/simple_render_system.cpp index 2105d4d..1e127b9 100644 --- a/simple_render_system.cpp +++ b/simple_render_system.cpp @@ -14,8 +14,7 @@ namespace hk { struct SimplePushConstantData { - glm::mat2 transform{1.0f}; - glm::vec2 offset; + glm::mat4 transform{1.0f}; alignas(16) glm::vec3 color; }; @@ -72,12 +71,12 @@ namespace hk m_pipeline->bind(commandBuffer); for (auto &obj : gameObjects) { - obj.m_transform2d.rotation = glm::mod(obj.m_transform2d.rotation + 0.01f, glm::two_pi()); + obj.m_transform.rotation.y = glm::mod(obj.m_transform.rotation.y + 0.01f, glm::two_pi()); + obj.m_transform.rotation.x = glm::mod(obj.m_transform.rotation.x + 0.005f, glm::two_pi()); SimplePushConstantData push{}; - push.offset = obj.m_transform2d.translation; push.color = obj.m_color; - push.transform = obj.m_transform2d.mat2(); + push.transform = obj.m_transform.mat4(); vkCmdPushConstants( commandBuffer,