diff --git a/CopiumEngine/CopiumEngine.vcxproj b/CopiumEngine/CopiumEngine.vcxproj index 8f37933..2ab5e7e 100644 --- a/CopiumEngine/CopiumEngine.vcxproj +++ b/CopiumEngine/CopiumEngine.vcxproj @@ -212,6 +212,7 @@ + @@ -256,6 +257,8 @@ + + @@ -290,6 +293,7 @@ + @@ -302,6 +306,7 @@ + diff --git a/CopiumEngine/CopiumEngine.vcxproj.filters b/CopiumEngine/CopiumEngine.vcxproj.filters index af482b7..1f35fa9 100644 --- a/CopiumEngine/CopiumEngine.vcxproj.filters +++ b/CopiumEngine/CopiumEngine.vcxproj.filters @@ -219,6 +219,9 @@ Source Files + + Source Files + @@ -506,5 +509,17 @@ Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files + \ No newline at end of file diff --git a/CopiumEngine/assets/fox2.meta b/CopiumEngine/assets/character.meta similarity index 82% rename from CopiumEngine/assets/fox2.meta rename to CopiumEngine/assets/character.meta index d0215b7..a3146a0 100644 --- a/CopiumEngine/assets/fox2.meta +++ b/CopiumEngine/assets/character.meta @@ -1,3 +1,4 @@ [Texture2D] filepath=res/textures/texture2.png +mag-filter=nearest uuid=0964e525-22c3-4d25-d5c6-a162965f6e8d diff --git a/CopiumEngine/assets/fox.meta b/CopiumEngine/assets/fox.meta index efe3944..3988fda 100644 --- a/CopiumEngine/assets/fox.meta +++ b/CopiumEngine/assets/fox.meta @@ -1,3 +1,4 @@ [Texture2D] filepath=res/textures/texture.png +mag-filter=nearest uuid=f49a5284-d666-0982-95ca-cf68cc3d4f45 diff --git a/CopiumEngine/assets/stone.meta b/CopiumEngine/assets/stone.meta new file mode 100644 index 0000000..14e2cfe --- /dev/null +++ b/CopiumEngine/assets/stone.meta @@ -0,0 +1,4 @@ +[Texture2D] +filepath=res/textures/stone.png +mag-filter=nearest +uuid=0c83bab1-9406-94fe-2068-6ea324dacb27 diff --git a/CopiumEngine/res/shaders/passthrough.frag b/CopiumEngine/res/shaders/passthrough.frag index f09ade6..48c1f4f 100644 --- a/CopiumEngine/res/shaders/passthrough.frag +++ b/CopiumEngine/res/shaders/passthrough.frag @@ -8,5 +8,5 @@ layout(location = 0) out vec4 outColor; void main() { - outColor = texture(texSampler, inTexCoord); + outColor = vec4(texture(texSampler, inTexCoord).rgb, 1.0); } \ No newline at end of file diff --git a/CopiumEngine/res/textures/stone.png b/CopiumEngine/res/textures/stone.png new file mode 100644 index 0000000..01634fe Binary files /dev/null and b/CopiumEngine/res/textures/stone.png differ diff --git a/CopiumEngine/res/textures/texture2.aseprite b/CopiumEngine/res/textures/texture2.aseprite new file mode 100644 index 0000000..28b457b Binary files /dev/null and b/CopiumEngine/res/textures/texture2.aseprite differ diff --git a/CopiumEngine/res/textures/texture2.png b/CopiumEngine/res/textures/texture2.png index c2f4aa3..7fd652a 100644 Binary files a/CopiumEngine/res/textures/texture2.png and b/CopiumEngine/res/textures/texture2.png differ diff --git a/CopiumEngine/src/copium/buffer/Framebuffer.cpp b/CopiumEngine/src/copium/buffer/Framebuffer.cpp index 5d90320..3de8ec6 100644 --- a/CopiumEngine/src/copium/buffer/Framebuffer.cpp +++ b/CopiumEngine/src/copium/buffer/Framebuffer.cpp @@ -111,18 +111,18 @@ namespace Copium void Framebuffer::InitializeImage() { - colorAttachment = AssetManager::RegisterRuntimeAsset("Framebuffer::ColorAttachment", std::make_unique(width, height)); + colorAttachment = AssetManager::RegisterRuntimeAsset("Framebuffer::ColorAttachment", std::make_unique(width, height, SamplerCreator{})); } void Framebuffer::InitializeDepthBuffer() { - depthAttachment = std::make_unique(width, height); + depthAttachment = std::make_unique(width, height, SamplerCreator{}); } void Framebuffer::InitializeRenderPass() { VkAttachmentDescription colorAttachment{}; - colorAttachment.format = VK_FORMAT_R8G8B8A8_SRGB; + colorAttachment.format = VK_FORMAT_R8G8B8A8_UNORM; colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT; colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; diff --git a/CopiumEngine/src/copium/core/Scene.cpp b/CopiumEngine/src/copium/core/Scene.cpp index 52a7378..832f693 100644 --- a/CopiumEngine/src/copium/core/Scene.cpp +++ b/CopiumEngine/src/copium/core/Scene.cpp @@ -9,17 +9,20 @@ #include "copium/event/MouseMoveEvent.h" #include "copium/example/CameraFollowPlayerSystem.h" #include "copium/example/CameraUpdateSystem.h" +#include "copium/example/ColliderSystem.h" #include "copium/example/Components.h" +#include "copium/example/DebugSystem.h" +#include "copium/example/AnimationSystem.h" #include "copium/example/FrameCountSystem.h" #include "copium/example/HealthChangeSystem.h" #include "copium/example/HealthComponentListener.h" #include "copium/example/HealthDisplaySystem.h" #include "copium/example/MouseFollowSystem.h" -#include "copium/example/ColliderSystem.h" #include "copium/example/PhysicsSystem.h" +#include "copium/example/PickupSystem.h" #include "copium/example/PlayerControllerSystem.h" #include "copium/example/RenderSystem.h" -#include "copium/example/PickupSystem.h" +#include "copium/example/UiRenderSystem.h" #include #include @@ -30,7 +33,9 @@ namespace Copium Scene::Scene(CommandBuffer& commandBuffer, DescriptorPool& descriptorPool) { renderer = std::make_unique(); + uiRenderer = std::make_unique(); descriptorSetRenderer = renderer->GetGraphicsPipeline().CreateDescriptorSet(descriptorPool, 1); + uiDescriptorSetRenderer = renderer->GetGraphicsPipeline().CreateDescriptorSet(descriptorPool, 1); ecs = std::make_unique(); ecs->AddSystem(); @@ -40,41 +45,54 @@ namespace Copium ecs->AddSystem(); ecs->AddSystem(); ecs->AddSystem(); - ecs->AddSystem(&viewMatrix, &projectionMatrix, &invPvMatrix); + ecs->AddSystem(&viewMatrix, &projectionMatrix, &invPvMatrix, &uiProjectionMatrix); ecs->AddSystem(&invPvMatrix); ecs->AddSystem(); + ecs->AddSystem(); + ecs->AddSystem(); ecs->AddSystem(renderer.get(), descriptorSetRenderer.get(), &commandBuffer, &viewMatrix, &projectionMatrix); // better way to store the RenderSystem data? + ecs->AddSystem(uiRenderer.get(), uiDescriptorSetRenderer.get(), &commandBuffer, &uiProjectionMatrix); ecs->SetComponentListener(); // TODO: Load from scene file - for (int y = 0; y < 10; y++) + for (int y = 0; y < 20; y++) { { Entity entity = Entity::Create(ecs.get()); - entity.AddComponent(glm::vec2{-10.0f + 0.4f, -11.0f + y * 1.6 + 0.4f}, glm::vec2{0.8f, 0.8f}); - entity.AddComponent(AssetRef{AssetManager::LoadAsset("fox.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f}); + entity.AddComponent(glm::vec2{-10.0f, -10.0f + y * 1.0}, glm::vec2{1.0f, 1.0f}); + if(y == 0 || y == 19) + entity.AddComponent(AssetRef{AssetManager::LoadAsset("stone.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{0.25f, 1.0f}); + else + entity.AddComponent(AssetRef{AssetManager::LoadAsset("stone.meta")}, glm::vec2{0.75f, 0.0f}, glm::vec2{1.0f, 1.0f}); entity.AddComponent(true); + entity.AddComponent(); } { Entity entity = Entity::Create(ecs.get()); - entity.AddComponent(glm::vec2{10.0f - 0.4f, -10.0f + y * 1.6 + 0.4f}, glm::vec2{0.8f, 0.8f}); - entity.AddComponent(AssetRef{AssetManager::LoadAsset("fox.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f}); + entity.AddComponent(glm::vec2{10.0f, -10.0f + y * 1.0}, glm::vec2{1.0f, 1.0f}); + if(y == 0 || y == 19) + entity.AddComponent(AssetRef{AssetManager::LoadAsset("stone.meta")}, glm::vec2{0.5f, 0.0f}, glm::vec2{0.75f, 1.0f}); + else + entity.AddComponent(AssetRef{AssetManager::LoadAsset("stone.meta")}, glm::vec2{0.75f, 0.0f}, glm::vec2{1.0f, 1.0f}); entity.AddComponent(true); + entity.AddComponent(); } } - for (int x = 0; x < 10; x++) + for (int x = 1; x < 20; x++) { { Entity entity = Entity::Create(ecs.get()); - entity.AddComponent(glm::vec2{-11.0f + x * 1.6 + 0.4f, -10.0f + 0.4f, }, glm::vec2{0.8f, 0.8f}); - entity.AddComponent(AssetRef{AssetManager::LoadAsset("fox.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f}); + entity.AddComponent(glm::vec2{-10.0f + x * 1.0, -10.0f}, glm::vec2{1.0f, 1.0f}); + entity.AddComponent(AssetRef{AssetManager::LoadAsset("stone.meta")}, glm::vec2{0.25f, 0.0f}, glm::vec2{0.5f, 1.0f}); entity.AddComponent(true); + entity.AddComponent(); } { Entity entity = Entity::Create(ecs.get()); - entity.AddComponent(glm::vec2{-11.0f + x * 1.6 + 0.4f, 10.0f - 0.4f, }, glm::vec2{0.8f, 0.8f}); - entity.AddComponent(AssetRef{AssetManager::LoadAsset("fox.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f}); + entity.AddComponent(glm::vec2{-10.0f + x * 1.0, 10.0f}, glm::vec2{1.0f, 1.0f}); + entity.AddComponent(AssetRef{AssetManager::LoadAsset("stone.meta")}, glm::vec2{0.25f, 0.0f}, glm::vec2{0.5f, 1.0f}); entity.AddComponent(true); + entity.AddComponent(); } } for (int y = 0; y < 10; y++) @@ -86,6 +104,7 @@ namespace Copium entity.AddComponent(glm::vec3{x * 0.1f, y * 0.1f, 1.0f}); entity.AddComponent(false); entity.AddComponent(); + entity.AddComponent(); } } @@ -94,34 +113,50 @@ namespace Copium entityFox.AddComponent(glm::vec2{-0.9f, -0.4f}, glm::vec2{0.8f, 0.8f}); entityFox.AddComponent(AssetRef{AssetManager::LoadAsset("fox.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f}); entityFox.AddComponent(true); + entityFox.AddComponent(); Entity entityFontAtlas = Entity::Create(ecs.get()); entityFontAtlas.AddComponent(glm::vec2{0.1f, -0.4f}, glm::vec2{0.8, 0.8}); entityFontAtlas.AddComponent(AssetRef{AssetManager::LoadAsset("font.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f}); entityFontAtlas.AddComponent(false); entityFontAtlas.AddComponent(); + entityFontAtlas.AddComponent(); Entity entityMouse = Entity::Create(ecs.get()); entityMouse.AddComponent(glm::vec2(0.1), glm::vec2{0.2}); - entityMouse.AddComponent(AssetRef{AssetManager::LoadAsset("fox2.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f}); + entityMouse.AddComponent(AssetRef{AssetManager::LoadAsset("fox.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f}); entityMouse.AddComponent(); + entityMouse.AddComponent(); Entity entityText = Entity::Create(ecs.get()); entityText.AddComponent(glm::vec2{-aspect * 10.0f + 0.1f, 9.4f}, glm::vec2{1.0}); entityText.AddComponent(AssetRef{AssetManager::LoadAsset("font.meta")}, std::to_string(0) + " fps", 0.6f); entityText.AddComponent(); + entityText.AddComponent(); Entity entityCamera = Entity::Create(ecs.get()); - entityCamera.AddComponent(BoundingBox(-aspect, -1.0f, aspect, 1.0f), false); - entityCamera.AddComponent(glm::vec2{0.0f}, glm::vec2{4.0f}); + entityCamera.AddComponent(BoundingBox(-aspect, -1.0f, aspect, 1.0f), false, false); + entityCamera.AddComponent(glm::vec2{0.0f}, glm::vec2{2.0f}); + + Entity entityUiCamera = Entity::Create(ecs.get()); + entityUiCamera.AddComponent(BoundingBox(0.0f, 0.0f, Vulkan::GetSwapChain().GetExtent().width, Vulkan::GetSwapChain().GetExtent().height), false, true); + entityUiCamera.AddComponent(glm::vec2{0.0f}, glm::vec2{1.0f}); Entity entityPlayer = Entity::Create(ecs.get()); - entityPlayer.AddComponent(entityCamera); + entityPlayer.AddComponent(entityCamera, false); entityPlayer.AddComponent(10, 10); entityPlayer.AddComponent(0.1f, glm::vec2{0.0f, 0.0f}, glm::vec2{0.0f, 0.0f}); entityPlayer.AddComponent(glm::vec2{0.0f, 2.0f}, glm::vec2{1.0f}); - entityPlayer.AddComponent(AssetRef{AssetManager::LoadAsset("fox2.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f}); - entityPlayer.AddComponent(false, glm::vec2{0.0f}); + entityPlayer.AddComponent(AssetRef{AssetManager::LoadAsset("character.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{0.25f, 1.0f}); + entityPlayer.AddComponent(4, 4, 0, 3, 4, true, 0.5f); + entityPlayer.AddComponent(false, glm::vec2{14.0f / 32.0f, 0.0f / 32.0f}, glm::vec2{4.0f / 32.0f, 21.0f / 32.0f}, glm::vec2{0.0f}); + entityPlayer.AddComponent(); + + Entity entityDebug = Entity::Create(ecs.get()); + entityDebug.AddComponent(entityPlayer); + entityDebug.AddComponent(AssetRef(AssetManager::LoadAsset("font.meta")), "", 20.0f); + entityDebug.AddComponent(glm::vec2{10.0f, Vulkan::GetSwapChain().GetExtent().height - 10.0f}, glm::vec2{1.0f}); + entityDebug.AddComponent(); } void Scene::Update() diff --git a/CopiumEngine/src/copium/core/Scene.h b/CopiumEngine/src/copium/core/Scene.h index fa31fe4..83c2642 100644 --- a/CopiumEngine/src/copium/core/Scene.h +++ b/CopiumEngine/src/copium/core/Scene.h @@ -13,11 +13,14 @@ namespace Copium { private: std::unique_ptr renderer; + std::unique_ptr uiRenderer; std::unique_ptr ecs; std::unique_ptr descriptorSetRenderer; + std::unique_ptr uiDescriptorSetRenderer; glm::mat4 projectionMatrix; glm::mat4 viewMatrix; glm::mat4 invPvMatrix; + glm::mat4 uiProjectionMatrix; public: Scene(CommandBuffer& commandBuffer, DescriptorPool& descriptorPool); void Update(); diff --git a/CopiumEngine/src/copium/core/SwapChain.cpp b/CopiumEngine/src/copium/core/SwapChain.cpp index b79191f..af4da68 100644 --- a/CopiumEngine/src/copium/core/SwapChain.cpp +++ b/CopiumEngine/src/copium/core/SwapChain.cpp @@ -256,7 +256,7 @@ namespace Copium void SwapChain::InitializeDepthAttachment() { - depthAttachment = std::make_unique(extent.width, extent.height); + depthAttachment = std::make_unique(extent.width, extent.height, SamplerCreator{}); } void SwapChain::InitializeRenderPass() @@ -374,7 +374,7 @@ namespace Copium { for (auto&& availableFormat : availableFormats) { - if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) + if (availableFormat.format == VK_FORMAT_R8G8B8A8_UNORM && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) { return availableFormat; } diff --git a/CopiumEngine/src/copium/core/Vulkan.cpp b/CopiumEngine/src/copium/core/Vulkan.cpp index bf08857..7e5407e 100644 --- a/CopiumEngine/src/copium/core/Vulkan.cpp +++ b/CopiumEngine/src/copium/core/Vulkan.cpp @@ -13,6 +13,7 @@ namespace Copium std::unique_ptr Vulkan::window; std::unique_ptr Vulkan::device; std::unique_ptr Vulkan::swapChain; + AssetHandle Vulkan::emptyTexture2D; void Vulkan::Initialize() { @@ -30,10 +31,12 @@ namespace Copium // TODO: Make the working directory always be relative to the assets folder // By looking at where the executable is, since that should always be in the bin folder (it currently isn't though) AssetManager::RegisterAssetDir("assets/"); + emptyTexture2D = AssetManager::RegisterRuntimeAsset("empty_texture2d", std::make_unique(std::vector{0, 0, 0, 255}, 1, 1, SamplerCreator{})); } void Vulkan::Destroy() { + AssetManager::UnloadAsset(emptyTexture2D); AssetManager::UnregisterAssetDir("assets/"); AssetManager::Cleanup(); swapChain.reset(); @@ -62,6 +65,11 @@ namespace Copium return *swapChain; } + AssetHandle Vulkan::GetEmptyTexture2D() + { + return emptyTexture2D; + } + bool Vulkan::Valid() { return instance && window && device && swapChain; diff --git a/CopiumEngine/src/copium/core/Vulkan.h b/CopiumEngine/src/copium/core/Vulkan.h index 85327f1..a0e5159 100644 --- a/CopiumEngine/src/copium/core/Vulkan.h +++ b/CopiumEngine/src/copium/core/Vulkan.h @@ -18,6 +18,8 @@ namespace Copium static std::unique_ptr window; static std::unique_ptr device; static std::unique_ptr swapChain; + + static AssetHandle emptyTexture2D; public: static void Initialize(); static void Destroy(); @@ -26,6 +28,6 @@ namespace Copium static Device& GetDevice(); static SwapChain& GetSwapChain(); static bool Valid(); - + static AssetHandle GetEmptyTexture2D(); }; } \ No newline at end of file diff --git a/CopiumEngine/src/copium/core/Window.cpp b/CopiumEngine/src/copium/core/Window.cpp index e0fcf10..a22d16e 100644 --- a/CopiumEngine/src/copium/core/Window.cpp +++ b/CopiumEngine/src/copium/core/Window.cpp @@ -118,6 +118,8 @@ namespace Copium void Window::KeyCallback(GLFWwindow* glfwWindow, int key, int scancode, int action, int mods) { + if (key == -1) // For some reason media keys count as keys with value -1 + return; try { if (action == GLFW_PRESS) diff --git a/CopiumEngine/src/copium/event/Input.cpp b/CopiumEngine/src/copium/event/Input.cpp index c0d64a1..488a601 100644 --- a/CopiumEngine/src/copium/event/Input.cpp +++ b/CopiumEngine/src/copium/event/Input.cpp @@ -15,49 +15,49 @@ namespace Copium bool Input::IsKeyPressed(int keyCode) { - CP_ASSERT(keyCode >= 0 && keyCode < MAX_NUM_KEYS, "KeyCode is out of range"); + CP_ASSERT(keyCode >= 0 && keyCode < MAX_NUM_KEYS, "KeyCode is out of range %d", keyCode); return keyEventList[keyCode] && keyDownList[keyCode]; } bool Input::IsKeyReleased(int keyCode) { - CP_ASSERT(keyCode >= 0 && keyCode < MAX_NUM_KEYS, "KeyCode is out of range"); + CP_ASSERT(keyCode >= 0 && keyCode < MAX_NUM_KEYS, "KeyCode is out of range %d", keyCode); return keyEventList[keyCode] && !keyDownList[keyCode]; } bool Input::IsKeyDown(int keyCode) { - CP_ASSERT(keyCode >= 0 && keyCode < MAX_NUM_KEYS, "KeyCode is out of range"); + CP_ASSERT(keyCode >= 0 && keyCode < MAX_NUM_KEYS, "KeyCode is out of range %d", keyCode); return keyDownList[keyCode]; } bool Input::IsKeyUp(int keyCode) { - CP_ASSERT(keyCode >= 0 && keyCode < MAX_NUM_KEYS, "KeyCode is out of range"); + CP_ASSERT(keyCode >= 0 && keyCode < MAX_NUM_KEYS, "KeyCode is out of range %d", keyCode); return !keyDownList[keyCode]; } bool Input::IsMousePressed(int button) { - CP_ASSERT(button >= 0 && button < MAX_NUM_MOUSE_BUTTONS, "button is out of range"); + CP_ASSERT(button >= 0 && button < MAX_NUM_MOUSE_BUTTONS, "button is out of range %d", button); return mouseEventList[button] && mouseDownList[button]; } bool Input::IsMouseReleased(int button) { - CP_ASSERT(button >= 0 && button < MAX_NUM_MOUSE_BUTTONS, "button is out of range"); + CP_ASSERT(button >= 0 && button < MAX_NUM_MOUSE_BUTTONS, "button is out of range %d", button); return mouseEventList[button] && !mouseDownList[button]; } bool Input::IsMouseDown(int button) { - CP_ASSERT(button >= 0 && button < MAX_NUM_MOUSE_BUTTONS, "button is out of range"); + CP_ASSERT(button >= 0 && button < MAX_NUM_MOUSE_BUTTONS, "button is out of range %d", button); return mouseDownList[button]; } bool Input::IsMouseUp(int button) { - CP_ASSERT(button >= 0 && button < MAX_NUM_MOUSE_BUTTONS, "button is out of range"); + CP_ASSERT(button >= 0 && button < MAX_NUM_MOUSE_BUTTONS, "button is out of range %d", button); return !mouseDownList[button]; } @@ -73,14 +73,14 @@ namespace Copium void Input::OnKey(int keyCode, bool pressed) { - CP_ASSERT(keyCode >= 0 && keyCode < MAX_NUM_KEYS, "KeyCode is out of range"); + CP_ASSERT(keyCode >= 0 && keyCode < MAX_NUM_KEYS, "KeyCode is out of range %d", keyCode); keyDownList[keyCode] = pressed; keyEventList[keyCode] = true; } void Input::OnMouse(int button, bool pressed) { - CP_ASSERT(button >= 0 && button < MAX_NUM_MOUSE_BUTTONS, "button is out of range"); + CP_ASSERT(button >= 0 && button < MAX_NUM_MOUSE_BUTTONS, "button is out of range %d", button); mouseDownList[button] = pressed; mouseEventList[button] = true; } diff --git a/CopiumEngine/src/copium/example/AnimationSystem.h b/CopiumEngine/src/copium/example/AnimationSystem.h new file mode 100644 index 0000000..4cb986f --- /dev/null +++ b/CopiumEngine/src/copium/example/AnimationSystem.h @@ -0,0 +1,32 @@ +#pragma once + +#include "copium/ecs/System.h" +#include "copium/example/Components.h" + +namespace Copium +{ + class AnimationSystem : public System + { + void RunEntity(Entity entity, AnimationC& animation, TextureC& texture) override + { + animation.timeElapsed += 1 / 165.0f; // TODO: Update to real Timestep + if (animation.timeElapsed >= animation.time) + { + animation.timeElapsed -= animation.time; + animation.frame = (animation.frame + 1) % animation.images; + } + if (animation.horizontal) { + texture.texCoord1.x = (animation.sheetStartCoordX + animation.frame) / (float)animation.sheetSizeX; + texture.texCoord2.x = (animation.sheetStartCoordX + animation.frame + 1) / (float)animation.sheetSizeX; + texture.texCoord1.y = (animation.sheetStartCoordY) / (float)animation.sheetSizeY; + texture.texCoord2.y = (animation.sheetStartCoordY + 1) / (float)animation.sheetSizeY; + } + else { + texture.texCoord1.x = (animation.sheetStartCoordX) / (float)animation.sheetSizeX; + texture.texCoord2.x = (animation.sheetStartCoordX + 1) / (float)animation.sheetSizeX; + texture.texCoord1.y = (animation.sheetStartCoordY + animation.frame) / (float)animation.sheetSizeY; + texture.texCoord2.y = (animation.sheetStartCoordY + animation.frame + 1) / (float)animation.sheetSizeY; + } + } + }; +} diff --git a/CopiumEngine/src/copium/example/CameraUpdateSystem.h b/CopiumEngine/src/copium/example/CameraUpdateSystem.h index c8f23e7..cdec66f 100644 --- a/CopiumEngine/src/copium/example/CameraUpdateSystem.h +++ b/CopiumEngine/src/copium/example/CameraUpdateSystem.h @@ -15,16 +15,24 @@ namespace Copium glm::mat4* viewMatrix; glm::mat4* projectionMatrix; glm::mat4* invPvMatrix; + glm::mat4* uiProjectionMatrix; public: - CameraUpdateSystem(glm::mat4* viewMatrix, glm::mat4* projectionMatrix, glm::mat4* invPvMatrix) - : viewMatrix{viewMatrix}, projectionMatrix{projectionMatrix}, invPvMatrix{invPvMatrix} + CameraUpdateSystem(glm::mat4* viewMatrix, glm::mat4* projectionMatrix, glm::mat4* invPvMatrix, glm::mat4* uiProjectionMatrix) + : viewMatrix{viewMatrix}, projectionMatrix{projectionMatrix}, invPvMatrix{invPvMatrix}, uiProjectionMatrix{uiProjectionMatrix} {} void RunEntity(Entity entity, CameraC& camera, TransformC& transform) { - *projectionMatrix = glm::ortho(camera.projection.l, camera.projection.r, camera.projection.b, camera.projection.t); - *viewMatrix = glm::translate(glm::scale(glm::mat4{1}, glm::vec3{1.0f / transform.size.x, 1.0f / transform.size.y, 1.0f}), glm::vec3{-transform.position.x, -transform.position.y, 0.0f}); - *invPvMatrix = glm::inverse((*projectionMatrix) * (*viewMatrix)); + if (camera.uiCamera) + { + *uiProjectionMatrix = glm::ortho(camera.projection.l, camera.projection.r, camera.projection.b, camera.projection.t); + } + else + { + *projectionMatrix = glm::ortho(camera.projection.l, camera.projection.r, camera.projection.b, camera.projection.t); + *viewMatrix = glm::translate(glm::scale(glm::mat4{1}, glm::vec3{1.0f / transform.size.x, 1.0f / transform.size.y, 1.0f}), glm::vec3{-transform.position.x, -transform.position.y, 0.0f}); + *invPvMatrix = glm::inverse((*projectionMatrix) * (*viewMatrix)); + } } void RunEntity(const Signal& signal, Entity entity, CameraC& camera, TransformC& transform) override @@ -41,9 +49,19 @@ namespace Copium case EventType::WindowResize: { const WindowResizeEvent& windowResizeEvent = static_cast(eventSignal.GetEvent()); - float aspect = windowResizeEvent.GetWidth() / (float)windowResizeEvent.GetHeight(); - camera.projection.r = aspect; - camera.projection.l = -aspect; + if (camera.uiCamera) + { + camera.projection.r = windowResizeEvent.GetWidth(); + camera.projection.t = windowResizeEvent.GetHeight(); + camera.projection.l = 0.0f; + camera.projection.b = 0.0f; + } + else + { + float aspect = windowResizeEvent.GetWidth() / (float)windowResizeEvent.GetHeight(); + camera.projection.r = aspect; + camera.projection.l = -aspect; + } break; } } diff --git a/CopiumEngine/src/copium/example/CollideSignal.h b/CopiumEngine/src/copium/example/CollideSignal.h index 262cf7e..37bd4c5 100644 --- a/CopiumEngine/src/copium/example/CollideSignal.h +++ b/CopiumEngine/src/copium/example/CollideSignal.h @@ -10,9 +10,12 @@ namespace Copium private: Entity first; Entity second; + bool resolved; + int xDir; + int yDir; public: - CollideSignal(Entity first, Entity second) - : first{first}, second{second} + CollideSignal(Entity first, Entity second, bool resolved, int xDir, int yDir) + : first{first}, second{second}, resolved{resolved}, xDir{xDir}, yDir{yDir} {} Entity GetFirst() const @@ -25,6 +28,21 @@ namespace Copium return second; } + bool WasResolved() const + { + return resolved; + } + + int GetXDir() const + { + return xDir; + } + + int GetYDir() const + { + return yDir; + } + CP_SIGNAL_DECLERATION_DEFINITION(); }; } diff --git a/CopiumEngine/src/copium/example/ColliderSystem.h b/CopiumEngine/src/copium/example/ColliderSystem.h index 008410c..331a217 100644 --- a/CopiumEngine/src/copium/example/ColliderSystem.h +++ b/CopiumEngine/src/copium/example/ColliderSystem.h @@ -12,69 +12,77 @@ namespace Copium { std::queue signals; - bool Overlap(TransformC& firstTransform, TransformC& secondTransform) + bool Overlap(TransformC& firstTransform, DynamicColliderC& dynamicCollider, TransformC& secondTransform) { - if (firstTransform.position.x >= secondTransform.position.x + secondTransform.size.x) + glm::vec2 firstPosition1 = firstTransform.position + dynamicCollider.colliderOffset * firstTransform.size; + glm::vec2 firstPosition2 = firstTransform.position + (dynamicCollider.colliderOffset + dynamicCollider.colliderSize) * firstTransform.size; + if (firstPosition1.x >= secondTransform.position.x + secondTransform.size.x) return false; - if (firstTransform.position.y >= secondTransform.position.y + secondTransform.size.y) + if (firstPosition1.y >= secondTransform.position.y + secondTransform.size.y) return false; - if (firstTransform.position.x + firstTransform.size.x <= secondTransform.position.x) + if (firstPosition2.x <= secondTransform.position.x) return false; - if (firstTransform.position.y + firstTransform.size.y <= secondTransform.position.y) + if (firstPosition2.y <= secondTransform.position.y) return false; return true; } - void CollideCheckDynamic(Entity firstEntity, TransformC& firstTransform, Entity secondEntity, TransformC& secondTransform) + void CollideCheckDynamic(Entity firstEntity, DynamicColliderC& dynamicCollider, TransformC& firstTransform, Entity secondEntity, TransformC& secondTransform) { if (firstEntity.GetId() >= secondEntity.GetId()) return; - if (!Overlap(firstTransform, secondTransform)) + if (!Overlap(firstTransform, dynamicCollider, secondTransform)) return; - signals.emplace(firstEntity, secondEntity); + signals.emplace(firstEntity, secondEntity, false, 0, 0); } void CollideCheckStatic(Entity firstEntity, DynamicColliderC& dynamicCollider, TransformC& firstTransform, Entity secondEntity, StaticColliderC& secondStaticCollider, TransformC& secondTransform) { - if (!Overlap(firstTransform, secondTransform)) + if (!Overlap(firstTransform, dynamicCollider, secondTransform)) return; - signals.emplace(firstEntity, secondEntity); - if (!secondStaticCollider.resolveCollision) - return; - - + int xDir = 0; if (firstTransform.position.x != dynamicCollider.oldPosition.x) { TransformC transform = firstTransform; transform.position.y = dynamicCollider.oldPosition.y; - if (Overlap(transform, secondTransform)) + if (Overlap(transform, dynamicCollider, secondTransform)) { - if (dynamicCollider.oldPosition.x < firstTransform.position.x) - firstTransform.position.x = secondTransform.position.x - firstTransform.size.x; - else - firstTransform.position.x = secondTransform.position.x + secondTransform.size.x; - if (firstEntity.HasComponent()) - firstEntity.GetComponent().velocity.x = 0; + xDir = dynamicCollider.oldPosition.x < firstTransform.position.x ? 1 : -1; + if (secondStaticCollider.resolveCollision) + { + if (dynamicCollider.oldPosition.x < firstTransform.position.x) + firstTransform.position.x = secondTransform.position.x - firstTransform.size.x * (dynamicCollider.colliderOffset.x + dynamicCollider.colliderSize.x); + else + firstTransform.position.x = secondTransform.position.x + secondTransform.size.x - firstTransform.size.x * dynamicCollider.colliderOffset.x; + if (firstEntity.HasComponent()) + firstEntity.GetComponent().velocity.x = 0; + } } } + int yDir = 0; if (firstTransform.position.y != dynamicCollider.oldPosition.y) { TransformC transform = firstTransform; transform.position.x = dynamicCollider.oldPosition.x; - if (Overlap(transform, secondTransform)) + if (Overlap(transform, dynamicCollider, secondTransform)) { - if (dynamicCollider.oldPosition.y < firstTransform.position.y) - firstTransform.position.y = secondTransform.position.y - firstTransform.size.y; - else - firstTransform.position.y = secondTransform.position.y + secondTransform.size.y; - if (firstEntity.HasComponent()) - firstEntity.GetComponent().velocity.y = 0; + yDir = dynamicCollider.oldPosition.y < firstTransform.position.y ? 1 : -1; + if (secondStaticCollider.resolveCollision) + { + if (dynamicCollider.oldPosition.y < firstTransform.position.y) + firstTransform.position.y = secondTransform.position.y - firstTransform.size.y * (dynamicCollider.colliderOffset.y + dynamicCollider.colliderSize.y); + else + firstTransform.position.y = secondTransform.position.y + secondTransform.size.y - firstTransform.size.y * dynamicCollider.colliderOffset.y; + if (firstEntity.HasComponent()) + firstEntity.GetComponent().velocity.y = 0; + } } } + signals.emplace(firstEntity, secondEntity, secondStaticCollider.resolveCollision, xDir, yDir); } void RunEntity(Entity entity, DynamicColliderC& dynamicCollider, TransformC& transform) override @@ -82,7 +90,7 @@ namespace Copium manager->Each( [&](EntityId otherEntity, DynamicColliderC& otherDynamicCollider, TransformC& otherTransform) { - CollideCheckDynamic(entity, transform, Entity{manager, otherEntity}, otherTransform); + CollideCheckDynamic(entity, dynamicCollider, transform, Entity{manager, otherEntity}, otherTransform); } ); manager->Each( diff --git a/CopiumEngine/src/copium/example/Components.h b/CopiumEngine/src/copium/example/Components.h index 339ae33..582abcc 100644 --- a/CopiumEngine/src/copium/example/Components.h +++ b/CopiumEngine/src/copium/example/Components.h @@ -15,6 +15,9 @@ namespace Copium glm::vec2 size; }; + struct Renderable {}; + struct UiRenderable {}; + struct ColorC { glm::vec3 color; @@ -44,6 +47,7 @@ namespace Copium { BoundingBox projection; bool staticBoundingBox; + bool uiCamera; }; struct PhysicsC @@ -56,7 +60,7 @@ namespace Copium struct PlayerC { Entity camera; - Timer jumpTimer; + bool grounded; }; struct HealthC @@ -76,6 +80,9 @@ namespace Copium struct DynamicColliderC { bool resolveCollision; + glm::vec2 colliderOffset; + glm::vec2 colliderSize; + glm::vec2 oldPosition; }; @@ -83,4 +90,23 @@ namespace Copium { }; + + struct DebugC + { + Entity playerEntity; + }; + + struct AnimationC + { + int sheetSizeX; + int sheetSizeY; + int sheetStartCoordX; + int sheetStartCoordY; + int images; + bool horizontal; + float time; + + float timeElapsed; + int frame; + }; } \ No newline at end of file diff --git a/CopiumEngine/src/copium/example/DebugSystem.h b/CopiumEngine/src/copium/example/DebugSystem.h new file mode 100644 index 0000000..fe9cbca --- /dev/null +++ b/CopiumEngine/src/copium/example/DebugSystem.h @@ -0,0 +1,29 @@ +#pragma once + +#include "copium/ecs/System.h" +#include "copium/example/Components.h" + +#include + +namespace Copium +{ + class DebugSystem : public System + { + public: + void RunEntity(Entity entity, DebugC& debug, TextC& text, TransformC& transform) override + { + const PlayerC& player = debug.playerEntity.GetComponent(); + const TransformC& playerTransform = debug.playerEntity.GetComponent(); + const PhysicsC& playerPhysics = debug.playerEntity.GetComponent(); + const glm::vec2& velocity = playerPhysics.velocity; + + text.text = ""; + text.text += String::Format("Position: (%.3f, %.3f)\n", playerTransform.position.x, playerTransform.position.y); + text.text += String::Format("Velocity: (%.3f, %.3f)\n", velocity.x, velocity.y) ; + text.text += String::Format("Grounded: %s", player.grounded ? "true" : "false"); + + const Font& font = AssetManager::GetAsset(text.font); + transform.position.y = Vulkan::GetSwapChain().GetExtent().height - 10.0f - font.GetBaseHeight() * text.fontSize; + } + }; +} \ No newline at end of file diff --git a/CopiumEngine/src/copium/example/HealthComponentListener.h b/CopiumEngine/src/copium/example/HealthComponentListener.h index 112718d..b5ca222 100644 --- a/CopiumEngine/src/copium/example/HealthComponentListener.h +++ b/CopiumEngine/src/copium/example/HealthComponentListener.h @@ -14,12 +14,14 @@ namespace Copium CP_ASSERT(!health.foreground, "Health already has foreground entity assigned"); health.background = Entity::Create(manager); - health.background.AddComponent(glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 0.2f}); - health.background.AddComponent(glm::vec3{0.9f, 0.2f, 0.2f}); + health.background.AddComponent(glm::vec2{0.0f, 0.0f}, glm::vec2{0.5f, 0.05f}); + health.background.AddComponent(glm::vec3{0.152f, 0.14f, 0.207f}); + health.background.AddComponent(); health.foreground = Entity::Create(manager); - health.foreground.AddComponent(glm::vec2{0.0f, 0.0f}, glm::vec2{std::clamp(health.current, 0, health.max) / (float)health.max, 0.2f}); - health.foreground.AddComponent(glm::vec3{0.2f, 0.9f, 0.2f}); + health.foreground.AddComponent(glm::vec2{0.0f, 0.0f}, glm::vec2{0.5f * std::clamp(health.current, 0, health.max) / (float)health.max, 0.05f}); + health.foreground.AddComponent(glm::vec3{0.581f, 0.393f, 0.462f}); + health.foreground.AddComponent(); } void Removed(EntityId entityId, HealthC& health) override diff --git a/CopiumEngine/src/copium/example/HealthDisplaySystem.h b/CopiumEngine/src/copium/example/HealthDisplaySystem.h index 5785b13..6e566d8 100644 --- a/CopiumEngine/src/copium/example/HealthDisplaySystem.h +++ b/CopiumEngine/src/copium/example/HealthDisplaySystem.h @@ -11,11 +11,11 @@ namespace Copium void RunEntity(Entity entity, HealthC& health, TransformC& transform) override { TransformC& foregroundTransform = health.foreground.GetComponent(); - foregroundTransform.position = transform.position + glm::vec2{0.0f, transform.size.y * 1.13}; - foregroundTransform.size = glm::vec2{std::clamp(health.current, 0, health.max) / (float)health.max, 0.2f}; + foregroundTransform.size = glm::vec2{0.5f * std::clamp(health.current, 0, health.max) / (float)health.max, 0.05f}; + foregroundTransform.position = transform.position + glm::vec2{0.0f, transform.size.y * 0.73} + glm::vec2{transform.size.x * 0.5f - 0.25f, 0.0f}; TransformC& backgroundTransform = health.background.GetComponent(); - backgroundTransform.position = transform.position + glm::vec2{0.0f, transform.size.y * 1.13}; + backgroundTransform.position = transform.position + glm::vec2{0.0f, transform.size.y * 0.73} + glm::vec2{transform.size.x * 0.5f - backgroundTransform.size.x * 0.5f, 0.0f}; } }; diff --git a/CopiumEngine/src/copium/example/PlayerControllerSystem.h b/CopiumEngine/src/copium/example/PlayerControllerSystem.h index 5268688..70b4a34 100644 --- a/CopiumEngine/src/copium/example/PlayerControllerSystem.h +++ b/CopiumEngine/src/copium/example/PlayerControllerSystem.h @@ -3,20 +3,22 @@ #include "copium/ecs/System.h" #include "copium/event/Input.h" #include "copium/example/Components.h" +#include "copium/example/CollideSignal.h" namespace Copium { - class PlayerControllerSystem : public System + class PlayerControllerSystem : public System { public: - void RunEntity(Entity entity, PlayerC& player, PhysicsC& physics) override + void RunEntity(Entity entity, PlayerC& player, PhysicsC& physics, AnimationC& animation) override { + if (physics.velocity.y != 0.0f) + player.grounded = false; const float MAX_JUMP_TIME = 0.2; float force = 0.0f; - if (Input::IsKeyPressed(CP_KEY_SPACE)) + if (Input::IsKeyPressed(CP_KEY_SPACE) && player.grounded) { - player.jumpTimer.Start(); - physics.velocity.y += 15; + physics.velocity.y = 15; } else if (!Input::IsKeyDown(CP_KEY_SPACE)) { @@ -25,8 +27,23 @@ namespace Copium physics.force.y -= 12; } } - if (Input::IsKeyDown(CP_KEY_A)) force -= 1.0f; - if (Input::IsKeyDown(CP_KEY_D)) force += 1.0f; + animation.time = 0.5; + if (Input::IsKeyDown(CP_KEY_A)) { + force -= 1.0f; + animation.sheetStartCoordY = 0; + animation.time = 0.2; + } + + if (Input::IsKeyDown(CP_KEY_D)) { + force += 1.0f; + animation.sheetStartCoordY = 1; + animation.time = 0.2; + } + + if (force == 0.0f && animation.sheetStartCoordY == 1) + animation.sheetStartCoordY = 3; + if (force == 0.0f && animation.sheetStartCoordY == 0) + animation.sheetStartCoordY = 2; float magnitude = 75.0f; physics.force.x += force * magnitude; @@ -39,5 +56,18 @@ namespace Copium entity.AddComponent(8, 10); } } + + void Run(const Signal& signal) override + { + if (signal.GetId() == CollideSignal::GetIdStatic()) + { + const CollideSignal& collideSignal = static_cast(signal); + if (collideSignal.GetFirst().HasComponent() && collideSignal.WasResolved()) + { + if (collideSignal.GetYDir() == -1) + collideSignal.GetFirst().GetComponent().grounded = true; + } + } + } }; } diff --git a/CopiumEngine/src/copium/example/RenderSystem.h b/CopiumEngine/src/copium/example/RenderSystem.h index 7b41452..e383207 100644 --- a/CopiumEngine/src/copium/example/RenderSystem.h +++ b/CopiumEngine/src/copium/example/RenderSystem.h @@ -10,7 +10,7 @@ namespace Copium { - class RenderSystem : public System + class RenderSystem : public System { private: // Find better way to store these? @@ -19,6 +19,8 @@ namespace Copium CommandBuffer* commandBuffer; glm::mat4* viewMatrix; glm::mat4* projectionMatrix; + + bool renderColliders = false; public: RenderSystem(Renderer* renderer, DescriptorSet* descriptorSet, CommandBuffer* commandBuffer, glm::mat4* viewMatrix, glm::mat4* projectionMatrix) : renderer{renderer}, @@ -28,7 +30,7 @@ namespace Copium projectionMatrix{projectionMatrix} {} - void RunEntity(Entity entity, TransformC& transform) + void RunEntity(Entity entity, Renderable& renderable, TransformC& transform) override { if (entity.HasComponent()) { @@ -47,9 +49,15 @@ namespace Copium } } + void RenderCollider(Entity entity, DynamicColliderC& dynamicCollider, TransformC& transform) + { + renderer->Quad(transform.position + transform.size * dynamicCollider.colliderOffset, transform.size * dynamicCollider.colliderSize, glm::vec3{0.8, 0.1, 0.1}); + } + void Run() override { - float aspect = Vulkan::GetSwapChain().GetExtent().width / (float)Vulkan::GetSwapChain().GetExtent().height; + if (Input::IsKeyPressed(CP_KEY_K)) + renderColliders = !renderColliders; UniformBuffer& uniformBuffer = descriptorSet->GetUniformBuffer("ubo"); uniformBuffer.Set("projection", *projectionMatrix); uniformBuffer.Set("view", *viewMatrix); @@ -58,6 +66,11 @@ namespace Copium renderer->SetDescriptorSet(*descriptorSet); renderer->Begin(*commandBuffer); System::Run(); + if (renderColliders) + { + manager->Each([&](EntityId entityId, DynamicColliderC& dynamicCollider, TransformC& transform) { RenderCollider(Entity{manager, entityId}, dynamicCollider, transform); }); + } + renderer->End(); } }; diff --git a/CopiumEngine/src/copium/example/UiRenderSystem.h b/CopiumEngine/src/copium/example/UiRenderSystem.h new file mode 100644 index 0000000..6199fef --- /dev/null +++ b/CopiumEngine/src/copium/example/UiRenderSystem.h @@ -0,0 +1,62 @@ +#pragma once + +#include "copium/ecs/System.h" +#include "copium/example/Components.h" +#include "copium/renderer/Renderer.h" +#include "copium/asset/AssetManager.h" +#include "copium/core/Vulkan.h" + +#include + +namespace Copium +{ + class UiRenderSystem : public System + { + private: + // Find better way to store these? + Renderer* renderer; + DescriptorSet* descriptorSet; + CommandBuffer* commandBuffer; + glm::mat4* projectionMatrix; + public: + UiRenderSystem(Renderer* renderer, DescriptorSet* descriptorSet, CommandBuffer* commandBuffer, glm::mat4* projectionMatrix) + : renderer{renderer}, + descriptorSet{descriptorSet}, + commandBuffer{commandBuffer}, + projectionMatrix{projectionMatrix} + {} + + void RunEntity(Entity entity, UiRenderable& uiRenderable, TransformC& transform) + { + if (entity.HasComponent()) + { + const TextC& text = entity.GetComponent(); + renderer->Text(text.text, transform.position, AssetManager::GetAsset(text.font), text.fontSize); + } + else if (entity.HasComponent()) + { + const ColorC& color = entity.GetComponent(); + renderer->Quad(transform.position, transform.size, color.color); + } + else if (entity.HasComponent()) + { + const TextureC& texture = entity.GetComponent(); + renderer->Quad(transform.position, transform.size, AssetManager::GetAsset(texture.asset), texture.texCoord1, texture.texCoord2); + } + } + + void Run() override + { + UniformBuffer& uniformBuffer = descriptorSet->GetUniformBuffer("ubo"); + uniformBuffer.Set("projection", *projectionMatrix); + uniformBuffer.Set("view", glm::mat4{1.0f}); + uniformBuffer.Update(); + + renderer->SetDescriptorSet(*descriptorSet); + renderer->Begin(*commandBuffer); + System::Run(); + renderer->End(); + } + }; + +} diff --git a/CopiumEngine/src/copium/renderer/Renderer.cpp b/CopiumEngine/src/copium/renderer/Renderer.cpp index b7d43c2..f84ecc0 100644 --- a/CopiumEngine/src/copium/renderer/Renderer.cpp +++ b/CopiumEngine/src/copium/renderer/Renderer.cpp @@ -15,8 +15,7 @@ namespace Copium Renderer::Renderer() : descriptorPool{}, ibo{MAX_NUM_INDICES}, - emptyTexture{AssetManager::RegisterRuntimeAsset("empty", std::make_unique(std::vector{0, 0, 0, 255}, 1, 1))}, - samplers{MAX_NUM_TEXTURES, &AssetManager::GetAsset(emptyTexture)} + samplers{MAX_NUM_TEXTURES, &AssetManager::GetAsset(Vulkan::GetEmptyTexture2D())} { InitializeIndexBuffer(); InitializeGraphicsPipeline(); @@ -24,7 +23,6 @@ namespace Copium Renderer::~Renderer() { - AssetManager::UnloadAsset(emptyTexture); AssetManager::UnloadAsset(pipeline); } @@ -184,7 +182,7 @@ namespace Copium void Renderer::NextBatch() { batchIndex++; - std::fill(samplers.begin(), samplers.end(), &AssetManager::GetAsset(emptyTexture)); + std::fill(samplers.begin(), samplers.end(), &AssetManager::GetAsset(Vulkan::GetEmptyTexture2D())); if (batchIndex >= batches.size()) { batches.emplace_back(std::make_unique(pipeline, descriptorPool, MAX_NUM_VERTICES, samplers)); diff --git a/CopiumEngine/src/copium/renderer/Renderer.h b/CopiumEngine/src/copium/renderer/Renderer.h index 95b5629..64cb3d9 100644 --- a/CopiumEngine/src/copium/renderer/Renderer.h +++ b/CopiumEngine/src/copium/renderer/Renderer.h @@ -21,7 +21,6 @@ namespace Copium private: DescriptorPool descriptorPool; IndexBuffer ibo; - AssetHandle emptyTexture; AssetHandle pipeline; std::vector> batches; diff --git a/CopiumEngine/src/copium/sampler/ColorAttachment.cpp b/CopiumEngine/src/copium/sampler/ColorAttachment.cpp index e5e6545..914b24f 100644 --- a/CopiumEngine/src/copium/sampler/ColorAttachment.cpp +++ b/CopiumEngine/src/copium/sampler/ColorAttachment.cpp @@ -7,6 +7,7 @@ namespace Copium { ColorAttachment::ColorAttachment(const MetaFile& metaFile) + : Sampler{SamplerCreator{metaFile.GetMetaClass("RenderTexture")}} { const MetaFileClass& metaClass = metaFile.GetMetaClass("RenderTexture"); if (metaClass.HasValue("width")) @@ -30,7 +31,8 @@ namespace Copium InitializeColorAttachment(width, height); } - ColorAttachment::ColorAttachment(int width, int height) + ColorAttachment::ColorAttachment(int width, int height, const SamplerCreator& samplerCreator) + : Sampler{samplerCreator} { InitializeColorAttachment(width, height); } @@ -92,8 +94,8 @@ namespace Copium imageMemories.resize(SwapChain::MAX_FRAMES_IN_FLIGHT); for (size_t i = 0; i < images.size(); i++) { - Image::InitializeImage(width, height, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &images[i], &imageMemories[i]); - imageViews[i] = Image::InitializeImageView(images[i], VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT); + Image::InitializeImage(width, height, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &images[i], &imageMemories[i]); + imageViews[i] = Image::InitializeImageView(images[i], VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT); } } } diff --git a/CopiumEngine/src/copium/sampler/ColorAttachment.h b/CopiumEngine/src/copium/sampler/ColorAttachment.h index abefd61..ebe6bdb 100644 --- a/CopiumEngine/src/copium/sampler/ColorAttachment.h +++ b/CopiumEngine/src/copium/sampler/ColorAttachment.h @@ -18,7 +18,7 @@ namespace Copium int height; public: ColorAttachment(const MetaFile& metaFile); - ColorAttachment(int width, int height); + ColorAttachment(int width, int height, const SamplerCreator& samplerCreator); ~ColorAttachment() override; void Resize(int width, int height); diff --git a/CopiumEngine/src/copium/sampler/DepthAttachment.cpp b/CopiumEngine/src/copium/sampler/DepthAttachment.cpp index b40a4a6..5e6d169 100644 --- a/CopiumEngine/src/copium/sampler/DepthAttachment.cpp +++ b/CopiumEngine/src/copium/sampler/DepthAttachment.cpp @@ -5,8 +5,8 @@ namespace Copium { - DepthAttachment::DepthAttachment(int width, int height) - : Sampler{} + DepthAttachment::DepthAttachment(int width, int height, const SamplerCreator& samplerCreator) + : Sampler{samplerCreator} { InitializeDepthAttachment(width, height); } diff --git a/CopiumEngine/src/copium/sampler/DepthAttachment.h b/CopiumEngine/src/copium/sampler/DepthAttachment.h index f69d766..7ddfb39 100644 --- a/CopiumEngine/src/copium/sampler/DepthAttachment.h +++ b/CopiumEngine/src/copium/sampler/DepthAttachment.h @@ -15,7 +15,7 @@ namespace Copium VkDeviceMemory imageMemory; VkImageView imageView; public: - DepthAttachment(int width, int height); + DepthAttachment(int width, int height, const SamplerCreator& samplerCreator); ~DepthAttachment() override; void Resize(int width, int height); diff --git a/CopiumEngine/src/copium/sampler/Font.cpp b/CopiumEngine/src/copium/sampler/Font.cpp index e8aff92..94e1834 100644 --- a/CopiumEngine/src/copium/sampler/Font.cpp +++ b/CopiumEngine/src/copium/sampler/Font.cpp @@ -9,6 +9,7 @@ namespace Copium { Font::Font(const MetaFile& metaFile) + : Sampler{SamplerCreator{metaFile.GetMetaClass("Font")}} { msdfgen::FreetypeHandle* ft = msdfgen::initializeFreetype(); CP_ASSERT(ft, "Failed to initialize FreeType"); // TODO: Move to Vulkan singleton class? @@ -66,6 +67,7 @@ namespace Copium this->glyphs.emplace((char)glyphGeom.getCodepoint(), glyph); } lineHeight = fontGeometry.getMetrics().lineHeight; + baseHeight = fontGeometry.getMetrics().ascenderY; msdfgen::destroyFont(font); msdfgen::deinitializeFreetype(ft); @@ -99,6 +101,11 @@ namespace Copium return lineHeight; } + float Font::GetBaseHeight() const + { + return baseHeight; + } + BoundingBox Font::GetTextBoundingBox(const std::string& str, float size) const { BoundingBox boundingBox{0.0f}; @@ -143,10 +150,10 @@ namespace Copium memcpy(data, rgbaData, bufferSize); stagingBuffer.Unmap(); - Image::InitializeImage(width, height, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &image, &imageMemory); - Image::TransitionImageLayout(image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + Image::InitializeImage(width, height, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &image, &imageMemory); + Image::TransitionImageLayout(image, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); Image::CopyBufferToImage(stagingBuffer, image, width, height); - Image::TransitionImageLayout(image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - imageView = Image::InitializeImageView(image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT); + Image::TransitionImageLayout(image, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + imageView = Image::InitializeImageView(image, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT); } } diff --git a/CopiumEngine/src/copium/sampler/Font.h b/CopiumEngine/src/copium/sampler/Font.h index 7242495..1360a6c 100644 --- a/CopiumEngine/src/copium/sampler/Font.h +++ b/CopiumEngine/src/copium/sampler/Font.h @@ -16,6 +16,7 @@ namespace Copium std::map glyphs; float lineHeight; + float baseHeight; public: Font(const MetaFile& metaFile); ~Font() override; @@ -24,10 +25,10 @@ namespace Copium const Glyph& GetGlyph(char c) const; float GetLineHeight() const; + float GetBaseHeight() const; BoundingBox GetTextBoundingBox(const std::string& str, float size) const; private: - void InitializeTextureImageFromFile(const std::string& filename); void InitializeTextureImageFromData(const uint8_t* rgbaData, int width, int height); }; } diff --git a/CopiumEngine/src/copium/sampler/Sampler.cpp b/CopiumEngine/src/copium/sampler/Sampler.cpp index 20bb3a4..920f379 100644 --- a/CopiumEngine/src/copium/sampler/Sampler.cpp +++ b/CopiumEngine/src/copium/sampler/Sampler.cpp @@ -4,9 +4,9 @@ namespace Copium { - Sampler::Sampler() + Sampler::Sampler(const SamplerCreator& samplerCreator) { - InitializeSampler(); + InitializeSampler(samplerCreator); } Sampler::~Sampler() @@ -14,15 +14,15 @@ namespace Copium vkDestroySampler(Vulkan::GetDevice(), sampler, nullptr); } - void Sampler::InitializeSampler() + void Sampler::InitializeSampler(const SamplerCreator& samplerCreator) { VkPhysicalDeviceProperties properties{}; vkGetPhysicalDeviceProperties(Vulkan::GetDevice().GetPhysicalDevice(), &properties); VkSamplerCreateInfo createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - createInfo.magFilter = VK_FILTER_LINEAR; // TODO: Some way to control this - createInfo.minFilter = VK_FILTER_LINEAR; // TODO: Some way to control this + createInfo.magFilter = samplerCreator.magFilter; + createInfo.minFilter = samplerCreator.minFilter; createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; diff --git a/CopiumEngine/src/copium/sampler/Sampler.h b/CopiumEngine/src/copium/sampler/Sampler.h index a6a1466..3dca60c 100644 --- a/CopiumEngine/src/copium/sampler/Sampler.h +++ b/CopiumEngine/src/copium/sampler/Sampler.h @@ -1,6 +1,7 @@ #pragma once #include "copium/asset/Asset.h" +#include "copium/sampler/SamplerCreator.h" #include "copium/util/Common.h" #include @@ -13,12 +14,13 @@ namespace Copium protected: VkSampler sampler; public: - Sampler(); + // Sampler(); + Sampler(const SamplerCreator& samplerCreator); virtual ~Sampler(); virtual VkDescriptorImageInfo GetDescriptorImageInfo(int index) const = 0; operator VkSampler() const; private: - void InitializeSampler(); + void InitializeSampler(const SamplerCreator& samplerCreator); }; } diff --git a/CopiumEngine/src/copium/sampler/SamplerCreator.cpp b/CopiumEngine/src/copium/sampler/SamplerCreator.cpp new file mode 100644 index 0000000..a9fb7e3 --- /dev/null +++ b/CopiumEngine/src/copium/sampler/SamplerCreator.cpp @@ -0,0 +1,37 @@ +#include "copium/sampler/SamplerCreator.h" + +#include "copium/util/Common.h" + +namespace Copium +{ + + SamplerCreator::SamplerCreator() = default; + + SamplerCreator::SamplerCreator(const MetaFileClass& metaClass) + { + if (metaClass.HasValue("min-filter")) + minFilter = GetFilterFromString(metaClass.GetValue("min-filter")); + if (metaClass.HasValue("mag-filter")) + magFilter = GetFilterFromString(metaClass.GetValue("mag-filter")); + } + + void SamplerCreator::SetMinFilter(VkFilter minFilter) + { + SamplerCreator::minFilter = minFilter; + } + + void SamplerCreator::SetMagFilter(VkFilter magFilter) + { + SamplerCreator::magFilter = magFilter; + } + + VkFilter SamplerCreator::GetFilterFromString(const std::string& str) const + { + if (str == "nearest") + return VK_FILTER_NEAREST; + else if (str == "linear") + return VK_FILTER_LINEAR; + else + CP_ABORT("Invalid texture filtering: %s", str.c_str()); + } +} diff --git a/CopiumEngine/src/copium/sampler/SamplerCreator.h b/CopiumEngine/src/copium/sampler/SamplerCreator.h new file mode 100644 index 0000000..f735232 --- /dev/null +++ b/CopiumEngine/src/copium/sampler/SamplerCreator.h @@ -0,0 +1,25 @@ +#pragma once + +#include "copium/util/MetaFile.h" +#include + +namespace Copium +{ + class SamplerCreator + { + friend class Sampler; + private: + VkFilter minFilter = VK_FILTER_LINEAR; + VkFilter magFilter = VK_FILTER_LINEAR; + + public: + SamplerCreator(); + SamplerCreator(const MetaFileClass& metaClass); + + void SetMinFilter(VkFilter minFilter); + void SetMagFilter(VkFilter magFilter); + + private: + VkFilter GetFilterFromString(const std::string& str) const; + }; +} diff --git a/CopiumEngine/src/copium/sampler/Texture2D.cpp b/CopiumEngine/src/copium/sampler/Texture2D.cpp index 95b06e6..57fb2b2 100644 --- a/CopiumEngine/src/copium/sampler/Texture2D.cpp +++ b/CopiumEngine/src/copium/sampler/Texture2D.cpp @@ -11,13 +11,15 @@ namespace Copium { Texture2D::Texture2D(const MetaFile& metaFile) + : Sampler{metaFile.GetMetaClass("Texture2D")} { const std::string& filepath = metaFile.GetMetaClass("Texture2D").GetValue("filepath"); CP_DEBUG("Loading texture file: %s", filepath.c_str()); InitializeTextureImageFromFile(filepath); } - Texture2D::Texture2D(const std::vector& rgbaData, int width, int height) + Texture2D::Texture2D(const std::vector& rgbaData, int width, int height, const SamplerCreator& samplerCreator) + : Sampler{samplerCreator} { CP_ASSERT(rgbaData.size() == width * height * 4, "rgbaData has invalid size, should be equal to width * height * 4 (%d) actually is %d", width * height * 4, rgbaData.size()); InitializeTextureImageFromData(rgbaData.data(), width, height); @@ -63,10 +65,10 @@ namespace Copium memcpy(data, rgbaData, bufferSize); stagingBuffer.Unmap(); - Image::InitializeImage(width, height, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &image, &imageMemory); - Image::TransitionImageLayout(image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + Image::InitializeImage(width, height, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &image, &imageMemory); + Image::TransitionImageLayout(image, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); Image::CopyBufferToImage(stagingBuffer, image, width, height); - Image::TransitionImageLayout(image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - imageView = Image::InitializeImageView(image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT); + Image::TransitionImageLayout(image, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + imageView = Image::InitializeImageView(image, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT); } } diff --git a/CopiumEngine/src/copium/sampler/Texture2D.h b/CopiumEngine/src/copium/sampler/Texture2D.h index 7b5f26a..29d2dbc 100644 --- a/CopiumEngine/src/copium/sampler/Texture2D.h +++ b/CopiumEngine/src/copium/sampler/Texture2D.h @@ -14,7 +14,7 @@ namespace Copium VkImageView imageView; public: Texture2D(const MetaFile& metaFile); - Texture2D(const std::vector& rgbaData, int width, int height); + Texture2D(const std::vector& rgbaData, int width, int height, const SamplerCreator& samplerCreator); ~Texture2D() override; VkDescriptorImageInfo GetDescriptorImageInfo(int index) const override;