Fix gamma rendering issues

- Remove gamma correction from the Vulkan renderer
- Add SamplerCreator, used to specify Min/Mag filter
- Add character texture to example project
- Add AnimationSystem, DebugSystem and UiRenderSystem to example project
This commit is contained in:
Thraix
2023-06-19 12:37:11 +02:00
parent 76bda0ace4
commit 042d1b6c70
42 changed files with 510 additions and 123 deletions
+5
View File
@@ -212,6 +212,7 @@
<ClCompile Include="src\copium\pipeline\DescriptorPool.cpp" />
<ClCompile Include="src\copium\pipeline\DescriptorSet.cpp" />
<ClCompile Include="src\copium\sampler\Font.cpp" />
<ClCompile Include="src\copium\sampler\SamplerCreator.cpp" />
<ClCompile Include="src\copium\util\BoundingBox.cpp" />
<ClCompile Include="src\copium\util\RuntimeException.cpp" />
<ClCompile Include="src\copium\util\FileSystem.cpp" />
@@ -256,6 +257,8 @@
<ClInclude Include="src\copium\ecs\ECSManager.h" />
<ClInclude Include="src\copium\ecs\Entity.h" />
<ClInclude Include="src\copium\ecs\EntitySet.h" />
<ClInclude Include="src\copium\example\AnimationSystem.h" />
<ClInclude Include="src\copium\example\DebugSystem.h" />
<ClInclude Include="src\copium\example\PickupSystem.h" />
<ClInclude Include="src\copium\ecs\Signal.h" />
<ClInclude Include="src\copium\ecs\System.h" />
@@ -290,6 +293,7 @@
<ClInclude Include="src\copium\example\RenderSystem.h" />
<ClInclude Include="src\copium\example\MouseFollowSystem.h" />
<ClInclude Include="src\copium\example\ColliderSystem.h" />
<ClInclude Include="src\copium\example\UiRenderSystem.h" />
<ClInclude Include="src\copium\mesh\Mesh.h" />
<ClInclude Include="src\copium\pipeline\ShaderBinding.h" />
<ClInclude Include="src\copium\renderer\Batch.h" />
@@ -302,6 +306,7 @@
<ClInclude Include="src\copium\buffer\CommandBuffer.h" />
<ClInclude Include="src\copium\sampler\Font.h" />
<ClInclude Include="src\copium\sampler\Glyph.h" />
<ClInclude Include="src\copium\sampler\SamplerCreator.h" />
<ClInclude Include="src\copium\util\BoundingBox.h" />
<ClInclude Include="src\copium\example\CollideSignal.h" />
<ClInclude Include="src\copium\util\Common.h" />
+15
View File
@@ -219,6 +219,9 @@
<ClCompile Include="src\copium\event\Input.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\copium\sampler\SamplerCreator.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\copium\sampler\DepthAttachment.h">
@@ -506,5 +509,17 @@
<ClInclude Include="src\copium\example\PickupSystem.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\copium\example\DebugSystem.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\copium\example\UiRenderSystem.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\copium\sampler\SamplerCreator.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\copium\example\AnimationSystem.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
@@ -1,3 +1,4 @@
[Texture2D]
filepath=res/textures/texture2.png
mag-filter=nearest
uuid=0964e525-22c3-4d25-d5c6-a162965f6e8d
+1
View File
@@ -1,3 +1,4 @@
[Texture2D]
filepath=res/textures/texture.png
mag-filter=nearest
uuid=f49a5284-d666-0982-95ca-cf68cc3d4f45
+4
View File
@@ -0,0 +1,4 @@
[Texture2D]
filepath=res/textures/stone.png
mag-filter=nearest
uuid=0c83bab1-9406-94fe-2068-6ea324dacb27
+1 -1
View File
@@ -8,5 +8,5 @@ layout(location = 0) out vec4 outColor;
void main()
{
outColor = texture(texSampler, inTexCoord);
outColor = vec4(texture(texSampler, inTexCoord).rgb, 1.0);
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 501 B

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 441 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

@@ -111,18 +111,18 @@ namespace Copium
void Framebuffer::InitializeImage()
{
colorAttachment = AssetManager::RegisterRuntimeAsset("Framebuffer::ColorAttachment", std::make_unique<ColorAttachment>(width, height));
colorAttachment = AssetManager::RegisterRuntimeAsset("Framebuffer::ColorAttachment", std::make_unique<ColorAttachment>(width, height, SamplerCreator{}));
}
void Framebuffer::InitializeDepthBuffer()
{
depthAttachment = std::make_unique<DepthAttachment>(width, height);
depthAttachment = std::make_unique<DepthAttachment>(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;
+54 -19
View File
@@ -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 <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
@@ -30,7 +33,9 @@ namespace Copium
Scene::Scene(CommandBuffer& commandBuffer, DescriptorPool& descriptorPool)
{
renderer = std::make_unique<Renderer>();
uiRenderer = std::make_unique<Renderer>();
descriptorSetRenderer = renderer->GetGraphicsPipeline().CreateDescriptorSet(descriptorPool, 1);
uiDescriptorSetRenderer = renderer->GetGraphicsPipeline().CreateDescriptorSet(descriptorPool, 1);
ecs = std::make_unique<ECSManager>();
ecs->AddSystem<PlayerControllerSystem>();
@@ -40,41 +45,54 @@ namespace Copium
ecs->AddSystem<HealthChangeSystem>();
ecs->AddSystem<HealthDisplaySystem>();
ecs->AddSystem<CameraFollowPlayerSystem>();
ecs->AddSystem<CameraUpdateSystem>(&viewMatrix, &projectionMatrix, &invPvMatrix);
ecs->AddSystem<CameraUpdateSystem>(&viewMatrix, &projectionMatrix, &invPvMatrix, &uiProjectionMatrix);
ecs->AddSystem<MouseFollowSystem>(&invPvMatrix);
ecs->AddSystem<FrameCountSystem>();
ecs->AddSystem<DebugSystem>();
ecs->AddSystem<AnimationSystem>();
ecs->AddSystem<RenderSystem>(renderer.get(), descriptorSetRenderer.get(), &commandBuffer, &viewMatrix, &projectionMatrix); // better way to store the RenderSystem data?
ecs->AddSystem<UiRenderSystem>(uiRenderer.get(), uiDescriptorSetRenderer.get(), &commandBuffer, &uiProjectionMatrix);
ecs->SetComponentListener<HealthComponentListener>();
// 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<TransformC>(glm::vec2{-10.0f + 0.4f, -11.0f + y * 1.6 + 0.4f}, glm::vec2{0.8f, 0.8f});
entity.AddComponent<TextureC>(AssetRef{AssetManager::LoadAsset("fox.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f});
entity.AddComponent<TransformC>(glm::vec2{-10.0f, -10.0f + y * 1.0}, glm::vec2{1.0f, 1.0f});
if(y == 0 || y == 19)
entity.AddComponent<TextureC>(AssetRef{AssetManager::LoadAsset("stone.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{0.25f, 1.0f});
else
entity.AddComponent<TextureC>(AssetRef{AssetManager::LoadAsset("stone.meta")}, glm::vec2{0.75f, 0.0f}, glm::vec2{1.0f, 1.0f});
entity.AddComponent<StaticColliderC>(true);
entity.AddComponent<Renderable>();
}
{
Entity entity = Entity::Create(ecs.get());
entity.AddComponent<TransformC>(glm::vec2{10.0f - 0.4f, -10.0f + y * 1.6 + 0.4f}, glm::vec2{0.8f, 0.8f});
entity.AddComponent<TextureC>(AssetRef{AssetManager::LoadAsset("fox.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f});
entity.AddComponent<TransformC>(glm::vec2{10.0f, -10.0f + y * 1.0}, glm::vec2{1.0f, 1.0f});
if(y == 0 || y == 19)
entity.AddComponent<TextureC>(AssetRef{AssetManager::LoadAsset("stone.meta")}, glm::vec2{0.5f, 0.0f}, glm::vec2{0.75f, 1.0f});
else
entity.AddComponent<TextureC>(AssetRef{AssetManager::LoadAsset("stone.meta")}, glm::vec2{0.75f, 0.0f}, glm::vec2{1.0f, 1.0f});
entity.AddComponent<StaticColliderC>(true);
entity.AddComponent<Renderable>();
}
}
for (int x = 0; x < 10; x++)
for (int x = 1; x < 20; x++)
{
{
Entity entity = Entity::Create(ecs.get());
entity.AddComponent<TransformC>(glm::vec2{-11.0f + x * 1.6 + 0.4f, -10.0f + 0.4f, }, glm::vec2{0.8f, 0.8f});
entity.AddComponent<TextureC>(AssetRef{AssetManager::LoadAsset("fox.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f});
entity.AddComponent<TransformC>(glm::vec2{-10.0f + x * 1.0, -10.0f}, glm::vec2{1.0f, 1.0f});
entity.AddComponent<TextureC>(AssetRef{AssetManager::LoadAsset("stone.meta")}, glm::vec2{0.25f, 0.0f}, glm::vec2{0.5f, 1.0f});
entity.AddComponent<StaticColliderC>(true);
entity.AddComponent<Renderable>();
}
{
Entity entity = Entity::Create(ecs.get());
entity.AddComponent<TransformC>(glm::vec2{-11.0f + x * 1.6 + 0.4f, 10.0f - 0.4f, }, glm::vec2{0.8f, 0.8f});
entity.AddComponent<TextureC>(AssetRef{AssetManager::LoadAsset("fox.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f});
entity.AddComponent<TransformC>(glm::vec2{-10.0f + x * 1.0, 10.0f}, glm::vec2{1.0f, 1.0f});
entity.AddComponent<TextureC>(AssetRef{AssetManager::LoadAsset("stone.meta")}, glm::vec2{0.25f, 0.0f}, glm::vec2{0.5f, 1.0f});
entity.AddComponent<StaticColliderC>(true);
entity.AddComponent<Renderable>();
}
}
for (int y = 0; y < 10; y++)
@@ -86,6 +104,7 @@ namespace Copium
entity.AddComponent<ColorC>(glm::vec3{x * 0.1f, y * 0.1f, 1.0f});
entity.AddComponent<StaticColliderC>(false);
entity.AddComponent<PickupC>();
entity.AddComponent<Renderable>();
}
}
@@ -94,34 +113,50 @@ namespace Copium
entityFox.AddComponent<TransformC>(glm::vec2{-0.9f, -0.4f}, glm::vec2{0.8f, 0.8f});
entityFox.AddComponent<TextureC>(AssetRef{AssetManager::LoadAsset("fox.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f});
entityFox.AddComponent<StaticColliderC>(true);
entityFox.AddComponent<Renderable>();
Entity entityFontAtlas = Entity::Create(ecs.get());
entityFontAtlas.AddComponent<TransformC>(glm::vec2{0.1f, -0.4f}, glm::vec2{0.8, 0.8});
entityFontAtlas.AddComponent<TextureC>(AssetRef{AssetManager::LoadAsset("font.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f});
entityFontAtlas.AddComponent<StaticColliderC>(false);
entityFontAtlas.AddComponent<PickupC>();
entityFontAtlas.AddComponent<Renderable>();
Entity entityMouse = Entity::Create(ecs.get());
entityMouse.AddComponent<TransformC>(glm::vec2(0.1), glm::vec2{0.2});
entityMouse.AddComponent<TextureC>(AssetRef{AssetManager::LoadAsset("fox2.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f});
entityMouse.AddComponent<TextureC>(AssetRef{AssetManager::LoadAsset("fox.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f});
entityMouse.AddComponent<MouseFollowC>();
entityMouse.AddComponent<Renderable>();
Entity entityText = Entity::Create(ecs.get());
entityText.AddComponent<TransformC>(glm::vec2{-aspect * 10.0f + 0.1f, 9.4f}, glm::vec2{1.0});
entityText.AddComponent<TextC>(AssetRef{AssetManager::LoadAsset("font.meta")}, std::to_string(0) + " fps", 0.6f);
entityText.AddComponent<FrameCountC>();
entityText.AddComponent<Renderable>();
Entity entityCamera = Entity::Create(ecs.get());
entityCamera.AddComponent<CameraC>(BoundingBox(-aspect, -1.0f, aspect, 1.0f), false);
entityCamera.AddComponent<TransformC>(glm::vec2{0.0f}, glm::vec2{4.0f});
entityCamera.AddComponent<CameraC>(BoundingBox(-aspect, -1.0f, aspect, 1.0f), false, false);
entityCamera.AddComponent<TransformC>(glm::vec2{0.0f}, glm::vec2{2.0f});
Entity entityUiCamera = Entity::Create(ecs.get());
entityUiCamera.AddComponent<CameraC>(BoundingBox(0.0f, 0.0f, Vulkan::GetSwapChain().GetExtent().width, Vulkan::GetSwapChain().GetExtent().height), false, true);
entityUiCamera.AddComponent<TransformC>(glm::vec2{0.0f}, glm::vec2{1.0f});
Entity entityPlayer = Entity::Create(ecs.get());
entityPlayer.AddComponent<PlayerC>(entityCamera);
entityPlayer.AddComponent<PlayerC>(entityCamera, false);
entityPlayer.AddComponent<HealthC>(10, 10);
entityPlayer.AddComponent<PhysicsC>(0.1f, glm::vec2{0.0f, 0.0f}, glm::vec2{0.0f, 0.0f});
entityPlayer.AddComponent<TransformC>(glm::vec2{0.0f, 2.0f}, glm::vec2{1.0f});
entityPlayer.AddComponent<TextureC>(AssetRef{AssetManager::LoadAsset("fox2.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f});
entityPlayer.AddComponent<DynamicColliderC>(false, glm::vec2{0.0f});
entityPlayer.AddComponent<TextureC>(AssetRef{AssetManager::LoadAsset("character.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{0.25f, 1.0f});
entityPlayer.AddComponent<AnimationC>(4, 4, 0, 3, 4, true, 0.5f);
entityPlayer.AddComponent<DynamicColliderC>(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<Renderable>();
Entity entityDebug = Entity::Create(ecs.get());
entityDebug.AddComponent<DebugC>(entityPlayer);
entityDebug.AddComponent<TextC>(AssetRef(AssetManager::LoadAsset("font.meta")), "", 20.0f);
entityDebug.AddComponent<TransformC>(glm::vec2{10.0f, Vulkan::GetSwapChain().GetExtent().height - 10.0f}, glm::vec2{1.0f});
entityDebug.AddComponent<UiRenderable>();
}
void Scene::Update()
+3
View File
@@ -13,11 +13,14 @@ namespace Copium
{
private:
std::unique_ptr<Renderer> renderer;
std::unique_ptr<Renderer> uiRenderer;
std::unique_ptr<ECSManager> ecs;
std::unique_ptr<DescriptorSet> descriptorSetRenderer;
std::unique_ptr<DescriptorSet> uiDescriptorSetRenderer;
glm::mat4 projectionMatrix;
glm::mat4 viewMatrix;
glm::mat4 invPvMatrix;
glm::mat4 uiProjectionMatrix;
public:
Scene(CommandBuffer& commandBuffer, DescriptorPool& descriptorPool);
void Update();
+2 -2
View File
@@ -256,7 +256,7 @@ namespace Copium
void SwapChain::InitializeDepthAttachment()
{
depthAttachment = std::make_unique<DepthAttachment>(extent.width, extent.height);
depthAttachment = std::make_unique<DepthAttachment>(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;
}
+8
View File
@@ -13,6 +13,7 @@ namespace Copium
std::unique_ptr<Window> Vulkan::window;
std::unique_ptr<Device> Vulkan::device;
std::unique_ptr<SwapChain> 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<Texture2D>(std::vector<uint8_t>{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;
+3 -1
View File
@@ -18,6 +18,8 @@ namespace Copium
static std::unique_ptr<Window> window;
static std::unique_ptr<Device> device;
static std::unique_ptr<SwapChain> 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();
};
}
+2
View File
@@ -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)
+10 -10
View File
@@ -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;
}
@@ -0,0 +1,32 @@
#pragma once
#include "copium/ecs/System.h"
#include "copium/example/Components.h"
namespace Copium
{
class AnimationSystem : public System<AnimationC, TextureC>
{
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;
}
}
};
}
@@ -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<const WindowResizeEvent&>(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;
}
}
@@ -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();
};
}
@@ -12,69 +12,77 @@ namespace Copium
{
std::queue<CollideSignal> 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<PhysicsC>())
firstEntity.GetComponent<PhysicsC>().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<PhysicsC>())
firstEntity.GetComponent<PhysicsC>().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<PhysicsC>())
firstEntity.GetComponent<PhysicsC>().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<PhysicsC>())
firstEntity.GetComponent<PhysicsC>().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<DynamicColliderC, TransformC>(
[&](EntityId otherEntity, DynamicColliderC& otherDynamicCollider, TransformC& otherTransform)
{
CollideCheckDynamic(entity, transform, Entity{manager, otherEntity}, otherTransform);
CollideCheckDynamic(entity, dynamicCollider, transform, Entity{manager, otherEntity}, otherTransform);
}
);
manager->Each<StaticColliderC, TransformC>(
+27 -1
View File
@@ -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;
};
}
@@ -0,0 +1,29 @@
#pragma once
#include "copium/ecs/System.h"
#include "copium/example/Components.h"
#include <string>
namespace Copium
{
class DebugSystem : public System<DebugC, TextC, TransformC>
{
public:
void RunEntity(Entity entity, DebugC& debug, TextC& text, TransformC& transform) override
{
const PlayerC& player = debug.playerEntity.GetComponent<PlayerC>();
const TransformC& playerTransform = debug.playerEntity.GetComponent<TransformC>();
const PhysicsC& playerPhysics = debug.playerEntity.GetComponent<PhysicsC>();
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<Font>(text.font);
transform.position.y = Vulkan::GetSwapChain().GetExtent().height - 10.0f - font.GetBaseHeight() * text.fontSize;
}
};
}
@@ -14,12 +14,14 @@ namespace Copium
CP_ASSERT(!health.foreground, "Health already has foreground entity assigned");
health.background = Entity::Create(manager);
health.background.AddComponent<TransformC>(glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 0.2f});
health.background.AddComponent<ColorC>(glm::vec3{0.9f, 0.2f, 0.2f});
health.background.AddComponent<TransformC>(glm::vec2{0.0f, 0.0f}, glm::vec2{0.5f, 0.05f});
health.background.AddComponent<ColorC>(glm::vec3{0.152f, 0.14f, 0.207f});
health.background.AddComponent<Renderable>();
health.foreground = Entity::Create(manager);
health.foreground.AddComponent<TransformC>(glm::vec2{0.0f, 0.0f}, glm::vec2{std::clamp(health.current, 0, health.max) / (float)health.max, 0.2f});
health.foreground.AddComponent<ColorC>(glm::vec3{0.2f, 0.9f, 0.2f});
health.foreground.AddComponent<TransformC>(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<ColorC>(glm::vec3{0.581f, 0.393f, 0.462f});
health.foreground.AddComponent<Renderable>();
}
void Removed(EntityId entityId, HealthC& health) override
@@ -11,11 +11,11 @@ namespace Copium
void RunEntity(Entity entity, HealthC& health, TransformC& transform) override
{
TransformC& foregroundTransform = health.foreground.GetComponent<TransformC>();
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<TransformC>();
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};
}
};
@@ -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<PlayerC, PhysicsC>
class PlayerControllerSystem : public System<PlayerC, PhysicsC, AnimationC>
{
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<HealthC>(8, 10);
}
}
void Run(const Signal& signal) override
{
if (signal.GetId() == CollideSignal::GetIdStatic())
{
const CollideSignal& collideSignal = static_cast<const CollideSignal&>(signal);
if (collideSignal.GetFirst().HasComponent<PlayerC>() && collideSignal.WasResolved())
{
if (collideSignal.GetYDir() == -1)
collideSignal.GetFirst().GetComponent<PlayerC>().grounded = true;
}
}
}
};
}
+16 -3
View File
@@ -10,7 +10,7 @@
namespace Copium
{
class RenderSystem : public System<TransformC>
class RenderSystem : public System<Renderable, TransformC>
{
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<TextC>())
{
@@ -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<DynamicColliderC, TransformC>([&](EntityId entityId, DynamicColliderC& dynamicCollider, TransformC& transform) { RenderCollider(Entity{manager, entityId}, dynamicCollider, transform); });
}
renderer->End();
}
};
@@ -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 <glm/gtc/matrix_transform.hpp>
namespace Copium
{
class UiRenderSystem : public System<UiRenderable, TransformC>
{
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<TextC>())
{
const TextC& text = entity.GetComponent<TextC>();
renderer->Text(text.text, transform.position, AssetManager::GetAsset<Font>(text.font), text.fontSize);
}
else if (entity.HasComponent<ColorC>())
{
const ColorC& color = entity.GetComponent<ColorC>();
renderer->Quad(transform.position, transform.size, color.color);
}
else if (entity.HasComponent<TextureC>())
{
const TextureC& texture = entity.GetComponent<TextureC>();
renderer->Quad(transform.position, transform.size, AssetManager::GetAsset<Sampler>(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();
}
};
}
@@ -15,8 +15,7 @@ namespace Copium
Renderer::Renderer()
: descriptorPool{},
ibo{MAX_NUM_INDICES},
emptyTexture{AssetManager::RegisterRuntimeAsset("empty", std::make_unique<Texture2D>(std::vector<uint8_t>{0, 0, 0, 255}, 1, 1))},
samplers{MAX_NUM_TEXTURES, &AssetManager::GetAsset<Texture2D>(emptyTexture)}
samplers{MAX_NUM_TEXTURES, &AssetManager::GetAsset<Texture2D>(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<Texture2D>(emptyTexture));
std::fill(samplers.begin(), samplers.end(), &AssetManager::GetAsset<Texture2D>(Vulkan::GetEmptyTexture2D()));
if (batchIndex >= batches.size())
{
batches.emplace_back(std::make_unique<Batch>(pipeline, descriptorPool, MAX_NUM_VERTICES, samplers));
@@ -21,7 +21,6 @@ namespace Copium
private:
DescriptorPool descriptorPool;
IndexBuffer ibo;
AssetHandle emptyTexture;
AssetHandle pipeline;
std::vector<std::unique_ptr<Batch>> batches;
@@ -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);
}
}
}
@@ -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);
@@ -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);
}
@@ -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);
+11 -4
View File
@@ -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);
}
}
+2 -1
View File
@@ -16,6 +16,7 @@ namespace Copium
std::map<char, Glyph> 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);
};
}
+5 -5
View File
@@ -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;
+4 -2
View File
@@ -1,6 +1,7 @@
#pragma once
#include "copium/asset/Asset.h"
#include "copium/sampler/SamplerCreator.h"
#include "copium/util/Common.h"
#include <vulkan/vulkan.hpp>
@@ -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);
};
}
@@ -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());
}
}
@@ -0,0 +1,25 @@
#pragma once
#include "copium/util/MetaFile.h"
#include <vulkan/vulkan.hpp>
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;
};
}
@@ -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<uint8_t>& rgbaData, int width, int height)
Texture2D::Texture2D(const std::vector<uint8_t>& 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);
}
}
+1 -1
View File
@@ -14,7 +14,7 @@ namespace Copium
VkImageView imageView;
public:
Texture2D(const MetaFile& metaFile);
Texture2D(const std::vector<uint8_t>& rgbaData, int width, int height);
Texture2D(const std::vector<uint8_t>& rgbaData, int width, int height, const SamplerCreator& samplerCreator);
~Texture2D() override;
VkDescriptorImageInfo GetDescriptorImageInfo(int index) const override;