summaryrefslogtreecommitdiff
path: root/src/blu_cat
diff options
context:
space:
mode:
Diffstat (limited to 'src/blu_cat')
-rw-r--r--src/blu_cat/com/binary_reader.cpp8
-rw-r--r--src/blu_cat/com/binary_reader.hpp3
-rw-r--r--src/blu_cat/com/binary_writer.cpp4
-rw-r--r--src/blu_cat/com/numbers.hpp1
-rw-r--r--src/blu_cat/gra/animation.cpp7
-rw-r--r--src/blu_cat/gra/animation.hpp7
-rw-r--r--src/blu_cat/gra/bitmap_character.cpp36
-rw-r--r--src/blu_cat/gra/bitmap_character.hpp40
-rw-r--r--src/blu_cat/gra/bitmap_font.cpp47
-rw-r--r--src/blu_cat/gra/bitmap_font.hpp52
-rw-r--r--src/blu_cat/gra/graphics_pipeline_2d_solid.cpp39
-rw-r--r--src/blu_cat/gra/graphics_pipeline_2d_solid.hpp8
-rw-r--r--src/blu_cat/gra/graphics_pipeline_2d_wired.cpp35
-rw-r--r--src/blu_cat/gra/graphics_pipeline_2d_wired.hpp10
-rw-r--r--src/blu_cat/gra/graphics_pipeline_3d.cpp6
-rw-r--r--src/blu_cat/gra/graphics_pipeline_3d.hpp6
-rw-r--r--src/blu_cat/gra/graphics_pipeline_3d_skeletal.cpp6
-rw-r--r--src/blu_cat/gra/graphics_pipeline_3d_skeletal.hpp6
-rw-r--r--src/blu_cat/gra/graphics_pipeline_sprite_3d.cpp6
-rw-r--r--src/blu_cat/gra/graphics_pipeline_sprite_3d.hpp6
-rw-r--r--src/blu_cat/gra/renderer.cpp196
-rw-r--r--src/blu_cat/gra/renderer.hpp28
-rw-r--r--src/blu_cat/gra/skeletal_mesh.cpp8
-rw-r--r--src/blu_cat/gra/skeletal_model.cpp40
-rw-r--r--src/blu_cat/gra/text.cpp90
-rw-r--r--src/blu_cat/gra/text.hpp47
-rw-r--r--src/blu_cat/gra/texture.cpp6
-rw-r--r--src/blu_cat/gra/view.cpp (renamed from src/blu_cat/gra/view_3d.cpp)65
-rw-r--r--src/blu_cat/gra/view.hpp (renamed from src/blu_cat/gra/view_3d.hpp)31
-rw-r--r--src/blu_cat/gra/view_2d.cpp160
-rw-r--r--src/blu_cat/gra/view_2d.hpp60
-rw-r--r--src/blu_cat/int/controller.hpp50
-rw-r--r--src/blu_cat/int/core.cpp150
-rw-r--r--src/blu_cat/int/core.hpp12
-rw-r--r--src/blu_cat/int/mode.hpp41
35 files changed, 824 insertions, 493 deletions
diff --git a/src/blu_cat/com/binary_reader.cpp b/src/blu_cat/com/binary_reader.cpp
index bb4d231..d572ec9 100644
--- a/src/blu_cat/com/binary_reader.cpp
+++ b/src/blu_cat/com/binary_reader.cpp
@@ -68,6 +68,14 @@ BinaryReader::read_ui8()
}
UI32
+BinaryReader::read_ui16()
+{
+ UI8 b1{this->data[_pointer++]}, b2{this->data[_pointer++]};
+
+ return b1 << 8 | b2;
+}
+
+UI32
BinaryReader::read_ui32()
{
UI8 b1{this->data[_pointer++]}, b2{this->data[_pointer++]},
diff --git a/src/blu_cat/com/binary_reader.hpp b/src/blu_cat/com/binary_reader.hpp
index fec88b6..7b7309c 100644
--- a/src/blu_cat/com/binary_reader.hpp
+++ b/src/blu_cat/com/binary_reader.hpp
@@ -43,6 +43,9 @@ public:
read_ui8();
UI32
+ read_ui16();
+
+ UI32
read_ui32();
UI64
diff --git a/src/blu_cat/com/binary_writer.cpp b/src/blu_cat/com/binary_writer.cpp
index 7af3b6d..fe06195 100644
--- a/src/blu_cat/com/binary_writer.cpp
+++ b/src/blu_cat/com/binary_writer.cpp
@@ -32,12 +32,12 @@ union IntAndFloat64bit{
}
BinaryWriter::BinaryWriter(const char *file_path):
- output{file_path, std::ios::binary}
+ output{file_path, std::ios::binary}
{
}
BinaryWriter::BinaryWriter(const std::string &file_path):
- BinaryWriter{file_path.c_str()}
+ BinaryWriter{file_path.c_str()}
{
}
diff --git a/src/blu_cat/com/numbers.hpp b/src/blu_cat/com/numbers.hpp
index 1fd3400..6f0ca47 100644
--- a/src/blu_cat/com/numbers.hpp
+++ b/src/blu_cat/com/numbers.hpp
@@ -60,6 +60,7 @@ typedef uint_fast64_t UI64F;
typedef std::float32_t F32;
typedef std::float64_t F64;
+constexpr UI32F SIZE_16_BIT{2};
constexpr UI32F SIZE_32_BIT{4};
constexpr UI32F SIZE_64_BIT{8};
diff --git a/src/blu_cat/gra/animation.cpp b/src/blu_cat/gra/animation.cpp
index dc2c281..062fb48 100644
--- a/src/blu_cat/gra/animation.cpp
+++ b/src/blu_cat/gra/animation.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 Frederico de Oliveira Linhares
+ * Copyright 2022-2025 Frederico de Oliveira Linhares
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,8 +19,9 @@
namespace BluCat::GRA
{
-Bone::Bone(glm::mat4 offset_matrix):
- offset_matrix{offset_matrix}
+Bone::Bone(glm::mat4 offset_matrix, UI16 parent):
+ offset_matrix{offset_matrix},
+ parent{parent}
{
}
diff --git a/src/blu_cat/gra/animation.hpp b/src/blu_cat/gra/animation.hpp
index 1275b48..11b1d0a 100644
--- a/src/blu_cat/gra/animation.hpp
+++ b/src/blu_cat/gra/animation.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 Frederico de Oliveira Linhares
+ * Copyright 2022-2025 Frederico de Oliveira Linhares
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,15 +28,16 @@ namespace BluCat::GRA
struct Bone
{
glm::mat4x4 offset_matrix;
+ UI16 parent;
- Bone(glm::mat4 offset_matrix);
+ Bone(glm::mat4 offset_matrix, UI16 parent);
};
struct BoneTransform
{
uint32_t bone_id;
- Channel<glm::vec3> positions;
Channel<glm::quat> rotations;
+ Channel<glm::vec3> positions;
Channel<glm::vec3> scales;
};
diff --git a/src/blu_cat/gra/bitmap_character.cpp b/src/blu_cat/gra/bitmap_character.cpp
new file mode 100644
index 0000000..d5352a0
--- /dev/null
+++ b/src/blu_cat/gra/bitmap_character.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2022-2025 Frederico de Oliveira Linhares
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bitmap_character.hpp"
+
+namespace BluCat::GRA
+{
+
+BitmapCharacter::BitmapCharacter(
+ F32 x, F32 y, F32 width, F32 height,
+ std::shared_ptr<BluCat::GRA::Texture> texture):
+ width{width},
+ height{height},
+ sprite{std::make_shared<Sprite>(
+ texture, glm::vec4(
+ x / texture->width,
+ y / texture->height,
+ (x + width) / texture->width,
+ (y + height) / texture->height))}
+{
+}
+
+}
diff --git a/src/blu_cat/gra/bitmap_character.hpp b/src/blu_cat/gra/bitmap_character.hpp
new file mode 100644
index 0000000..31f88ed
--- /dev/null
+++ b/src/blu_cat/gra/bitmap_character.hpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022-2025 Frederico de Oliveira Linhares
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BLU_CAT_GRA_BITMAP_CHARACTER_H
+#define BLU_CAT_GRA_BITMAP_CHARACTER_H 1
+
+#include <memory>
+#include <vector>
+
+#include "../com/numbers.hpp"
+#include "sprite.hpp"
+
+namespace BluCat::GRA
+{
+
+struct BitmapCharacter
+{
+ F32 width, height;
+ std::shared_ptr<BluCat::GRA::Sprite> sprite;
+
+ BitmapCharacter(F32 x, F32 y, F32 width, F32 height,
+ std::shared_ptr<BluCat::GRA::Texture> texture);
+};
+
+}
+
+#endif /* BLU_CAT_GRA_BITMAP_CHARACTER_H */
diff --git a/src/blu_cat/gra/bitmap_font.cpp b/src/blu_cat/gra/bitmap_font.cpp
new file mode 100644
index 0000000..0cafc2a
--- /dev/null
+++ b/src/blu_cat/gra/bitmap_font.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2022-2025 Frederico de Oliveira Linhares
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bitmap_font.hpp"
+
+#include <format>
+
+namespace BluCat::GRA
+{
+
+void
+BitmapFont::add_letters(
+ const char *texture_path, std::span<NewBitmapCharacter> characters)
+{
+ std::shared_ptr<BluCat::GRA::Texture> texture{
+ std::make_shared<BluCat::GRA::Texture>(texture_path)};
+ this->textures.push_back(texture);
+
+ for(NewBitmapCharacter &ch: characters)
+ this->characters.insert({
+ ch.code, BitmapCharacter(
+ ch.x, ch.y, ch.width, ch.height, texture)});
+}
+
+BitmapFont::BitmapFont(
+ I32F width, I32F height, I32F white_space_width, I32F letter_spacing):
+ width{width},
+ height{height},
+ white_space_width{white_space_width},
+ letter_spacing{letter_spacing}
+ {
+ }
+
+}
diff --git a/src/blu_cat/gra/bitmap_font.hpp b/src/blu_cat/gra/bitmap_font.hpp
new file mode 100644
index 0000000..7918354
--- /dev/null
+++ b/src/blu_cat/gra/bitmap_font.hpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2022-2025 Frederico de Oliveira Linhares
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BLU_CAT_GRA_BITMAP_FONT_H
+#define BLU_CAT_GRA_BITMAP_FONT_H 1
+
+#include <memory>
+#include <unordered_map>
+#include <vector>
+
+#include "bitmap_character.hpp"
+#include "texture.hpp"
+
+namespace BluCat::GRA
+{
+
+struct NewBitmapCharacter
+{
+ const UI32F code;
+ const F32 x, y, width, height;
+};
+
+struct BitmapFont
+{
+ const I32F width, height, white_space_width, letter_spacing;
+ std::vector<std::shared_ptr<BluCat::GRA::Texture>> textures;
+ std::unordered_map<UI32F, BitmapCharacter> characters;
+
+ void
+ add_letters(
+ const char *texture_path, std::span<NewBitmapCharacter> characters);
+
+ BitmapFont(
+ I32F width, I32F height, I32F white_space_width, I32F letter_spacing);
+};
+
+}
+
+#endif /* BLU_CAT_GRA_BITMAP_FONT_H */
diff --git a/src/blu_cat/gra/graphics_pipeline_2d_solid.cpp b/src/blu_cat/gra/graphics_pipeline_2d_solid.cpp
index 7acca09..0d72fc9 100644
--- a/src/blu_cat/gra/graphics_pipeline_2d_solid.cpp
+++ b/src/blu_cat/gra/graphics_pipeline_2d_solid.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 Frederico de Oliveira Linhares
+ * Copyright 2022-2025 Frederico de Oliveira Linhares
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -235,43 +235,26 @@ GraphicsPipeline2DSolid::~GraphicsPipeline2DSolid()
void
GraphicsPipeline2DSolid::draw(
- std::shared_ptr<View2D> view, const VkCommandBuffer draw_command_buffer,
- const size_t current_frame, const size_t next_frame,
- const uint32_t image_index)
+ const VkCommandBuffer draw_command_buffer, const size_t current_frame,
+ const size_t next_frame, const uint32_t image_index)
{
- // TODO set viewport just once per view, not once per pipeline.
- { // Set viewport
- VkViewport vk_viewport{};
- vk_viewport.x = view->region.x;
- vk_viewport.y = view->region.y;
- vk_viewport.width = view->region.z;
- vk_viewport.height = view->region.w;
- vk_viewport.minDepth = 0.0f;
- vk_viewport.maxDepth = 1.0f;
- vkCmdSetViewport(draw_command_buffer, 0, 1, &vk_viewport);
-
- VkRect2D vk_scissor{};
- vk_scissor.offset.x = static_cast<int32_t>(view->region.x);
- vk_scissor.offset.y = static_cast<int32_t>(view->region.y);
- vk_scissor.extent.width = static_cast<uint32_t>(view->region.z);
- vk_scissor.extent.height = static_cast<uint32_t>(view->region.w);
- vkCmdSetScissor(draw_command_buffer, 0, 1, &vk_scissor);
- }
-
vkCmdBindPipeline(
draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
this->graphic_pipeline);
// FIXME: I know sorting is expensive, but I need to figure out better what
// to do here.
- std::sort(view->sprites_to_draw[current_frame].begin(),
- view->sprites_to_draw[current_frame].end());
+ std::sort(BluCat::INT::core.vk_renderer->sprites_to_draw[
+ current_frame].begin(),
+ BluCat::INT::core.vk_renderer->sprites_to_draw[
+ current_frame].end());
// Draw sprites
- for(auto& sprite_to_draw: view->sprites_to_draw[current_frame])
+ for(auto& sprite_to_draw:
+ BluCat::INT::core.vk_renderer->sprites_to_draw[current_frame])
{
std::array<VkDescriptorSet, 2> vk_descriptor_sets{
- view->descriptor_sets_2d[image_index],
+ BluCat::INT::core.vk_renderer->descriptor_sets_2d[image_index],
sprite_to_draw.sprite->texture->descriptor_sets[image_index]};
VkDeviceSize offsets[]{0};
@@ -292,7 +275,7 @@ GraphicsPipeline2DSolid::draw(
}
// Prepare for the next frame.
- view->sprites_to_draw[next_frame].clear();
+ BluCat::INT::core.vk_renderer->sprites_to_draw[next_frame].clear();
}
}
diff --git a/src/blu_cat/gra/graphics_pipeline_2d_solid.hpp b/src/blu_cat/gra/graphics_pipeline_2d_solid.hpp
index c1520c2..c2d85d5 100644
--- a/src/blu_cat/gra/graphics_pipeline_2d_solid.hpp
+++ b/src/blu_cat/gra/graphics_pipeline_2d_solid.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 Frederico de Oliveira Linhares
+ * Copyright 2022-2025 Frederico de Oliveira Linhares
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@
#include "vulkan.hpp"
#include "command_pool.hpp"
-#include "view_2d.hpp"
namespace BluCat::GRA
{
@@ -34,9 +33,8 @@ struct GraphicsPipeline2DSolid
~GraphicsPipeline2DSolid();
void
- draw(std::shared_ptr<View2D> view, const VkCommandBuffer draw_command_buffer,
- const size_t current_frame, const size_t next_frame,
- const uint32_t image_index);
+ draw(const VkCommandBuffer draw_command_buffer, const size_t current_frame,
+ const size_t next_frame, const uint32_t image_index);
};
}
diff --git a/src/blu_cat/gra/graphics_pipeline_2d_wired.cpp b/src/blu_cat/gra/graphics_pipeline_2d_wired.cpp
index 20491ed..209dafd 100644
--- a/src/blu_cat/gra/graphics_pipeline_2d_wired.cpp
+++ b/src/blu_cat/gra/graphics_pipeline_2d_wired.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 Frederico de Oliveira Linhares
+ * Copyright 2022-2025 Frederico de Oliveira Linhares
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -247,33 +247,14 @@ GraphicsPipeline2DWired::~GraphicsPipeline2DWired()
void
GraphicsPipeline2DWired::draw(
- std::shared_ptr<View2D> view, const VkCommandBuffer draw_command_buffer,
- const size_t current_frame, const size_t next_frame,
- const uint32_t image_index)
+ const VkCommandBuffer draw_command_buffer, const size_t current_frame,
+ const size_t next_frame, const uint32_t image_index)
{
- // Set viewport
- {
- VkViewport vk_viewport{};
- vk_viewport.x = view->region.x;
- vk_viewport.y = view->region.y;
- vk_viewport.width = view->region.z;
- vk_viewport.height = view->region.w;
- vk_viewport.minDepth = 0.0f;
- vk_viewport.maxDepth = 1.0f;
- vkCmdSetViewport(draw_command_buffer, 0, 1, &vk_viewport);
-
- VkRect2D vk_scissor{};
- vk_scissor.offset.x = static_cast<int32_t>(view->region.x);
- vk_scissor.offset.y = static_cast<int32_t>(view->region.y);
- vk_scissor.extent.width = static_cast<uint32_t>(view->region.z);
- vk_scissor.extent.height = static_cast<uint32_t>(view->region.w);
- vkCmdSetScissor(draw_command_buffer, 0, 1, &vk_scissor);
- }
// Draw rectangles
{
std::array<VkDescriptorSet, 1> vk_descriptor_sets{
- view->descriptor_sets_2d[image_index]};
+ BluCat::INT::core.vk_renderer->descriptor_sets_2d[image_index]};
VkDeviceSize offsets[]{0};
vkCmdBindDescriptorSets(
@@ -287,9 +268,11 @@ GraphicsPipeline2DWired::draw(
draw_command_buffer, this->index_buffer->buffer, 0,
VK_INDEX_TYPE_UINT32);
- for(auto i{0}; i < view->rectangles_to_draw[current_frame].size(); i++)
+ for(auto i{0}; i < BluCat::INT::core.vk_renderer->rectangles_to_draw[
+ current_frame].size(); i++)
{
- auto &rect{view->rectangles_to_draw[current_frame][i]};
+ auto &rect{BluCat::INT::core.vk_renderer->rectangles_to_draw[
+ current_frame][i]};
UDOVector4D position{rect.position};
UDOVector3D color{rect.color};
@@ -308,7 +291,7 @@ GraphicsPipeline2DWired::draw(
}
// Prepare for the next frame.
- view->rectangles_to_draw[next_frame].clear();
+ BluCat::INT::core.vk_renderer->rectangles_to_draw[next_frame].clear();
}
}
diff --git a/src/blu_cat/gra/graphics_pipeline_2d_wired.hpp b/src/blu_cat/gra/graphics_pipeline_2d_wired.hpp
index 7d2752e..9fc46c4 100644
--- a/src/blu_cat/gra/graphics_pipeline_2d_wired.hpp
+++ b/src/blu_cat/gra/graphics_pipeline_2d_wired.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 Frederico de Oliveira Linhares
+ * Copyright 2022-2025 Frederico de Oliveira Linhares
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,8 @@
#include <memory>
#include "vulkan.hpp"
-#include "view_2d.hpp"
+#include "command_pool.hpp"
+#include "destination_buffer.hpp"
namespace BluCat::GRA
{
@@ -37,9 +38,8 @@ struct GraphicsPipeline2DWired
~GraphicsPipeline2DWired();
void
- draw(std::shared_ptr<View2D> view, const VkCommandBuffer draw_command_buffer,
- const size_t current_frame, const size_t next_frame,
- const uint32_t image_index);
+ draw(const VkCommandBuffer draw_command_buffer, const size_t current_frame,
+ const size_t next_frame, const uint32_t image_index);
};
}
diff --git a/src/blu_cat/gra/graphics_pipeline_3d.cpp b/src/blu_cat/gra/graphics_pipeline_3d.cpp
index 1f7324a..288e186 100644
--- a/src/blu_cat/gra/graphics_pipeline_3d.cpp
+++ b/src/blu_cat/gra/graphics_pipeline_3d.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 Frederico de Oliveira Linhares
+ * Copyright 2022-2025 Frederico de Oliveira Linhares
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -257,7 +257,7 @@ GraphicsPipeline3D::~GraphicsPipeline3D()
void
GraphicsPipeline3D::draw(
- std::shared_ptr<View3D> view, const VkCommandBuffer draw_command_buffer,
+ std::shared_ptr<View> view, const VkCommandBuffer draw_command_buffer,
const size_t current_frame, const uint32_t image_index)
{
vkCmdBindPipeline(
@@ -286,7 +286,7 @@ GraphicsPipeline3D::draw(
std::array<VkDescriptorSet, 4> vk_descriptor_sets{
INT::core.vk_light->descriptor_sets_world[image_index],
- view->descriptor_sets_3d[image_index],
+ view->descriptor_sets[image_index],
instance->descriptor_sets[image_index],
instance->texture->descriptor_sets[image_index]};
diff --git a/src/blu_cat/gra/graphics_pipeline_3d.hpp b/src/blu_cat/gra/graphics_pipeline_3d.hpp
index 0dc0b03..2e30e02 100644
--- a/src/blu_cat/gra/graphics_pipeline_3d.hpp
+++ b/src/blu_cat/gra/graphics_pipeline_3d.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 Frederico de Oliveira Linhares
+ * Copyright 2022-2025 Frederico de Oliveira Linhares
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@
#include "vulkan.hpp"
#include "command_pool.hpp"
-#include "view_3d.hpp"
+#include "view.hpp"
namespace BluCat::GRA
{
@@ -34,7 +34,7 @@ struct GraphicsPipeline3D
~GraphicsPipeline3D();
void
- draw(std::shared_ptr<View3D> view, const VkCommandBuffer draw_command_buffer,
+ draw(std::shared_ptr<View> view, const VkCommandBuffer draw_command_buffer,
const size_t current_frame, const uint32_t image_index);
};
diff --git a/src/blu_cat/gra/graphics_pipeline_3d_skeletal.cpp b/src/blu_cat/gra/graphics_pipeline_3d_skeletal.cpp
index e8eda6b..79a85f1 100644
--- a/src/blu_cat/gra/graphics_pipeline_3d_skeletal.cpp
+++ b/src/blu_cat/gra/graphics_pipeline_3d_skeletal.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 Frederico de Oliveira Linhares
+ * Copyright 2022-2025 Frederico de Oliveira Linhares
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -266,7 +266,7 @@ GraphicsPipeline3DSkeletal::~GraphicsPipeline3DSkeletal()
void
GraphicsPipeline3DSkeletal::draw(
- std::shared_ptr<View3D> view, const VkCommandBuffer draw_command_buffer,
+ std::shared_ptr<View> view, const VkCommandBuffer draw_command_buffer,
const size_t current_frame, const uint32_t image_index)
{
vkCmdBindPipeline(
@@ -295,7 +295,7 @@ GraphicsPipeline3DSkeletal::draw(
std::array<VkDescriptorSet, 4> vk_descriptor_sets{
INT::core.vk_light->descriptor_sets_world[image_index],
- view->descriptor_sets_3d[image_index],
+ view->descriptor_sets[image_index],
instance->descriptor_sets[image_index],
instance->texture->descriptor_sets[image_index]};
diff --git a/src/blu_cat/gra/graphics_pipeline_3d_skeletal.hpp b/src/blu_cat/gra/graphics_pipeline_3d_skeletal.hpp
index bad117d..16d65b0 100644
--- a/src/blu_cat/gra/graphics_pipeline_3d_skeletal.hpp
+++ b/src/blu_cat/gra/graphics_pipeline_3d_skeletal.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 Frederico de Oliveira Linhares
+ * Copyright 2022-2025 Frederico de Oliveira Linhares
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@
#include "vulkan.hpp"
#include "command_pool.hpp"
-#include "view_3d.hpp"
+#include "view.hpp"
namespace BluCat::GRA
{
@@ -34,7 +34,7 @@ struct GraphicsPipeline3DSkeletal
~GraphicsPipeline3DSkeletal();
void
- draw(std::shared_ptr<View3D> view, const VkCommandBuffer draw_command_buffer,
+ draw(std::shared_ptr<View> view, const VkCommandBuffer draw_command_buffer,
const size_t current_frame, const uint32_t image_index);
};
diff --git a/src/blu_cat/gra/graphics_pipeline_sprite_3d.cpp b/src/blu_cat/gra/graphics_pipeline_sprite_3d.cpp
index 14796d3..63e10b9 100644
--- a/src/blu_cat/gra/graphics_pipeline_sprite_3d.cpp
+++ b/src/blu_cat/gra/graphics_pipeline_sprite_3d.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 Frederico de Oliveira Linhares
+ * Copyright 2022-2025 Frederico de Oliveira Linhares
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -265,7 +265,7 @@ GraphicsPipelineSprite3D::~GraphicsPipelineSprite3D()
void
GraphicsPipelineSprite3D::draw(
- std::shared_ptr<View3D> view, const VkCommandBuffer draw_command_buffer,
+ std::shared_ptr<View> view, const VkCommandBuffer draw_command_buffer,
const size_t current_frame, const uint32_t image_index)
{
vkCmdBindPipeline(
@@ -290,7 +290,7 @@ GraphicsPipelineSprite3D::draw(
{
std::array<VkDescriptorSet, 4> vk_descriptor_sets{
INT::core.vk_light->descriptor_sets_world[image_index],
- view->descriptor_sets_3d[image_index],
+ view->descriptor_sets[image_index],
sprite.sprite_3d->descriptor_sets[image_index],
sprite.sprite_3d->sprite->texture->descriptor_sets[image_index]};
VkDeviceSize offsets[]{0};
diff --git a/src/blu_cat/gra/graphics_pipeline_sprite_3d.hpp b/src/blu_cat/gra/graphics_pipeline_sprite_3d.hpp
index 325d943..d03b8e8 100644
--- a/src/blu_cat/gra/graphics_pipeline_sprite_3d.hpp
+++ b/src/blu_cat/gra/graphics_pipeline_sprite_3d.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 Frederico de Oliveira Linhares
+ * Copyright 2022-2025 Frederico de Oliveira Linhares
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@
#include "vulkan.hpp"
#include "command_pool.hpp"
#include "sprite_3d.hpp"
-#include "view_3d.hpp"
+#include "view.hpp"
namespace BluCat::GRA
{
@@ -35,7 +35,7 @@ struct GraphicsPipelineSprite3D
~GraphicsPipelineSprite3D();
void
- draw(std::shared_ptr<View3D> view, const VkCommandBuffer draw_command_buffer,
+ draw(std::shared_ptr<View> view, const VkCommandBuffer draw_command_buffer,
const size_t current_frame, const uint32_t image_index);
};
diff --git a/src/blu_cat/gra/renderer.cpp b/src/blu_cat/gra/renderer.cpp
index d13f814..eb11899 100644
--- a/src/blu_cat/gra/renderer.cpp
+++ b/src/blu_cat/gra/renderer.cpp
@@ -25,15 +25,39 @@ namespace
{
void
+load_2d_uniform_buffer(void *obj)
+{
+ auto self = static_cast<BluCat::GRA::Renderer*>(obj);
+
+ try
+ {
+ self->ub_2d.reserve(BluCat::INT::core.vk_swapchain->images_count);
+ for(auto i{0}; i < BluCat::INT::core.vk_swapchain->images_count; i++)
+ self->ub_2d.emplace_back(
+ BluCat::INT::core.vk_device_with_swapchain,
+ sizeof(BluCat::GRA::UDOView2D));
+ }
+ catch(const std::exception& e)
+ {
+ throw CommandError{e.what()};
+ }
+}
+
+void
+unload_2d_uniform_buffer(void *obj)
+{
+ auto self = static_cast<BluCat::GRA::Renderer*>(obj);
+
+ self->ub_2d.clear();
+}
+
+void
load_descriptor_pool(void *obj)
{
auto self = static_cast<BluCat::GRA::Renderer*>(obj);
- uint32_t uniform_buffer_count = 0;
- for(auto &view : self->views_3d)
- uniform_buffer_count += (view->ub_3d.size() + view->ub_2d.size());
- for(auto &view : self->views_2d)
- uniform_buffer_count += (view->ub_2d.size());
+ uint32_t uniform_buffer_count = self->ub_2d.size();
+ for(auto &view : self->views) uniform_buffer_count += view->ub_3d.size();
VkDescriptorPoolSize descriptor_pool_size{};
descriptor_pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
@@ -52,9 +76,7 @@ load_descriptor_pool(void *obj)
&self->descriptor_pool) != VK_SUCCESS)
throw CommandError{"Failed to create a Vulkan descriptor pool."};
- for(auto &view : self->views_3d)
- view->load_descriptor_sets(self->descriptor_pool);
- for(auto &view : self->views_2d)
+ for(auto &view : self->views)
view->load_descriptor_sets(self->descriptor_pool);
}
@@ -63,8 +85,7 @@ unload_descriptor_pool(void *obj)
{
auto self = static_cast<BluCat::GRA::Renderer*>(obj);
- for(auto &view : self->views_3d) view->unload_descriptor_sets();
- for(auto &view : self->views_2d) view->unload_descriptor_sets();
+ for(auto &view : self->views) view->unload_descriptor_sets();
vkDestroyDescriptorPool(
BluCat::INT::core.vk_device_with_swapchain->device, self->descriptor_pool,
@@ -72,6 +93,64 @@ unload_descriptor_pool(void *obj)
}
void
+load_descriptor_sets_2d(void *obj)
+{
+ auto self = static_cast<BluCat::GRA::Renderer*>(obj);
+
+ std::vector<VkDescriptorSetLayout> layouts(
+ BluCat::INT::core.vk_swapchain->images_count,
+ BluCat::INT::core.vk_descriptor_set_layout->view);
+
+ VkDescriptorSetAllocateInfo alloc_info{};
+ alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+ alloc_info.descriptorPool = self->descriptor_pool;
+ alloc_info.descriptorSetCount = layouts.size();
+ alloc_info.pSetLayouts = layouts.data();
+
+ self->descriptor_sets_2d.resize(layouts.size());
+ if(vkAllocateDescriptorSets(
+ BluCat::INT::core.vk_device_with_swapchain->device, &alloc_info,
+ self->descriptor_sets_2d.data()) != VK_SUCCESS)
+ throw CommandError{"Failed to create Vulkan descriptor sets for view."};
+}
+
+void
+load_resources_to_descriptor_sets_2d(void *obj)
+{
+ auto self = static_cast<BluCat::GRA::Renderer*>(obj);
+
+ for(auto i{0}; i < self->ub_2d.size(); i++)
+ {
+ VkDescriptorBufferInfo view_2d_info{};
+ view_2d_info.buffer = self->ub_2d[i].buffer;
+ view_2d_info.offset = 0;
+ view_2d_info.range = sizeof(BluCat::GRA::UDOView2D);
+
+ std::array<VkWriteDescriptorSet, 1> write_descriptors{};
+ write_descriptors[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+ write_descriptors[0].dstSet = self->descriptor_sets_2d[i];
+ write_descriptors[0].dstBinding = 0;
+ write_descriptors[0].dstArrayElement = 0;
+ write_descriptors[0].descriptorCount = 1;
+ write_descriptors[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+ write_descriptors[0].pBufferInfo = &view_2d_info;
+ write_descriptors[0].pImageInfo = nullptr;
+ write_descriptors[0].pTexelBufferView = nullptr;
+
+ vkUpdateDescriptorSets(
+ BluCat::INT::core.vk_device_with_swapchain->device, write_descriptors.size(),
+ write_descriptors.data(), 0, nullptr);
+
+ BluCat::GRA::UDOView2D ubo_view_2d;
+ ubo_view_2d.proj = glm::ortho(
+ 0.0f, self->projection_width,
+ 0.0f, self->projection_height,
+ 0.0f, 100.0f);
+ self->ub_2d[i].copy_data(&ubo_view_2d);
+ }
+}
+
+void
load_queue_family(void *obj)
{
auto self = static_cast<BluCat::GRA::Renderer*>(obj);
@@ -128,7 +207,10 @@ load_draw_command_buffer(void *obj)
}
const CommandChain loader{
+ {&load_2d_uniform_buffer, &unload_2d_uniform_buffer},
{&load_descriptor_pool, &unload_descriptor_pool},
+ {&load_descriptor_sets_2d, nullptr},
+ {&load_resources_to_descriptor_sets_2d, nullptr},
{&load_queue_family, nullptr},
{&load_command_pool, &unload_command_pool},
{&load_draw_command_buffer, nullptr}
@@ -139,21 +221,25 @@ const CommandChain loader{
namespace BluCat::GRA
{
-Renderer::Renderer(std::vector<std::shared_ptr<View2D>> views_2d,
- std::vector<std::shared_ptr<View3D>> views_3d):
+Renderer::Renderer(
+ std::vector<std::shared_ptr<View>> views, F32 width, F32 height):
skeletal_models_to_draw{BluCat::INT::core.vk_swapchain->images_count},
static_models_to_draw{BluCat::INT::core.vk_swapchain->images_count},
sprites_3d_to_draw{BluCat::INT::core.vk_swapchain->images_count},
+ rectangles_to_draw{BluCat::INT::core.vk_swapchain->images_count},
+ sprites_to_draw{BluCat::INT::core.vk_swapchain->images_count},
+ projection_width{width},
+ projection_height{height},
clear_screen_color{0.0f, 0.0f, 0.0f, 1.0f},
- views_2d{views_2d},
- views_3d{views_3d}
+ views{views}
{
loader.execute(this);
}
-Renderer::Renderer(std::initializer_list<std::shared_ptr<View2D>> views_2d,
- std::initializer_list<std::shared_ptr<View3D>> views_3d):
- Renderer(std::vector(views_2d), std::vector(views_3d))
+Renderer::Renderer(
+ std::initializer_list<std::shared_ptr<View>> views,
+ F32 width, F32 height):
+ Renderer(std::vector(views), width, height)
{
}
@@ -251,7 +337,7 @@ Renderer::draw()
draw_command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE);
}
- for(auto &view: this->views_3d)
+ for(auto &view: this->views)
{
{ // Set viewport
VkViewport vk_viewport{};
@@ -272,16 +358,17 @@ Renderer::draw()
}
BluCat::INT::core.vk_graphics_pipeline_3d->draw(
- view, draw_command_buffer, BluCat::INT::core.vk_swapchain->current_frame,
+ view, draw_command_buffer,
+ BluCat::INT::core.vk_swapchain->current_frame,
image_index);
BluCat::INT::core.vk_graphics_pipeline_sprite_3d->draw(
- view, draw_command_buffer, BluCat::INT::core.vk_swapchain->current_frame,
- image_index);
+ view, draw_command_buffer,
+ BluCat::INT::core.vk_swapchain->current_frame, image_index);
BluCat::INT::core.vk_graphics_pipeline_3d_skeletal->draw(
- view, draw_command_buffer, BluCat::INT::core.vk_swapchain->current_frame,
- image_index);
+ view, draw_command_buffer,
+ BluCat::INT::core.vk_swapchain->current_frame, image_index);
{ // Update view uniform buffers
BluCat::GRA::UDOView3D ubo_view_3d{};
@@ -303,7 +390,7 @@ Renderer::draw()
}
}
- vkCmdEndRenderPass(draw_command_buffer);
+ vkCmdEndRenderPass(draw_command_buffer);
{ // 2D render pass
VkRenderPassBeginInfo render_pass_begin{};
@@ -319,33 +406,38 @@ Renderer::draw()
render_pass_begin.clearValueCount = 0;
render_pass_begin.pClearValues = nullptr;
- vkCmdBeginRenderPass(
- draw_command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE);
-
+ vkCmdBeginRenderPass(
+ draw_command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE);
}
- { // 2D solid drawing
- for(auto &view: this->views_2d)
- BluCat::INT::core.vk_graphics_pipeline_2d_solid->draw(
- view, draw_command_buffer, BluCat::INT::core.vk_swapchain->current_frame,
- next_frame, image_index);
+ { // Set viewport
+ VkViewport vk_viewport{};
+ vk_viewport.x = 0;
+ vk_viewport.y = 0;
+ vk_viewport.width = static_cast<float>(BluCat::INT::core.display_width);
+ vk_viewport.height = static_cast<float>(BluCat::INT::core.display_height);
+ vk_viewport.minDepth = 0.0f;
+ vk_viewport.maxDepth = 1.0f;
+ vkCmdSetViewport(draw_command_buffer, 0, 1, &vk_viewport);
+
+ VkRect2D vk_scissor{};
+ vk_scissor.offset.x = 0;
+ vk_scissor.offset.y = 0;
+ vk_scissor.extent.width = BluCat::INT::core.display_width;
+ vk_scissor.extent.height = BluCat::INT::core.display_height;
+ vkCmdSetScissor(draw_command_buffer, 0, 1, &vk_scissor);
+ }
- for(auto &view: this->views_3d)
- BluCat::INT::core.vk_graphics_pipeline_2d_solid->draw(
- view, draw_command_buffer, BluCat::INT::core.vk_swapchain->current_frame,
- next_frame, image_index);
+ { // 2D solid drawing
+ BluCat::INT::core.vk_graphics_pipeline_2d_solid->draw(
+ draw_command_buffer, BluCat::INT::core.vk_swapchain->current_frame,
+ next_frame, image_index);
}
{ // 2D wired drawing
- for(auto &view: this->views_2d)
- BluCat::INT::core.vk_graphics_pipeline_2d_wired->draw(
- view, draw_command_buffer, BluCat::INT::core.vk_swapchain->current_frame,
- next_frame, image_index);
-
- for(auto &view: this->views_3d)
- BluCat::INT::core.vk_graphics_pipeline_2d_wired->draw(
- view, draw_command_buffer, BluCat::INT::core.vk_swapchain->current_frame,
- next_frame, image_index);
+ BluCat::INT::core.vk_graphics_pipeline_2d_wired->draw(
+ draw_command_buffer, BluCat::INT::core.vk_swapchain->current_frame,
+ next_frame, image_index);
}
vkCmdEndRenderPass(draw_command_buffer);
@@ -403,7 +495,9 @@ Renderer::draw()
this->skeletal_models_to_draw[next_frame].clear();
this->static_models_to_draw[next_frame].clear();
this->sprites_3d_to_draw[next_frame].clear();
- BluCat::INT::core.vk_swapchain->current_frame = next_frame;
+ this->rectangles_to_draw[next_frame].clear();
+ this->sprites_to_draw[next_frame].clear();
+ BluCat::INT::core.vk_swapchain->current_frame = next_frame;
}
}
else
@@ -415,10 +509,12 @@ Renderer::draw()
BluCat::INT::core.vk_swapchain->current_frame].clear();
this->sprites_3d_to_draw[
BluCat::INT::core.vk_swapchain->current_frame].clear();
- for(auto &view: this->views_2d)
- view->sprites_to_draw[BluCat::INT::core.vk_swapchain->current_frame].clear();
- for(auto &view: this->views_3d)
- view->sprites_to_draw[BluCat::INT::core.vk_swapchain->current_frame].clear();
+ this->sprites_to_draw[
+ BluCat::INT::core.vk_swapchain->current_frame].clear();
+ this->rectangles_to_draw[
+ BluCat::INT::core.vk_swapchain->current_frame].clear();
+ this->sprites_to_draw[
+ BluCat::INT::core.vk_swapchain->current_frame].clear();
}
}
diff --git a/src/blu_cat/gra/renderer.hpp b/src/blu_cat/gra/renderer.hpp
index 82948cb..58b9972 100644
--- a/src/blu_cat/gra/renderer.hpp
+++ b/src/blu_cat/gra/renderer.hpp
@@ -22,14 +22,15 @@
#include <vector>
#include "vulkan.hpp"
+#include "queue_family.hpp"
+#include "rectangle.hpp"
#include "skeletal_mesh.hpp"
#include "skeletal_model.hpp"
#include "sprite_3d.hpp"
+#include "sprite_to_draw.hpp"
#include "static_mesh.hpp"
#include "static_model.hpp"
-#include "queue_family.hpp"
-#include "view_2d.hpp"
-#include "view_3d.hpp"
+#include "view.hpp"
namespace BluCat::GRA
{
@@ -52,16 +53,25 @@ struct Renderer
VkDescriptorPool descriptor_pool;
VkClearColorValue clear_screen_color;
- std::vector<std::shared_ptr<View2D>> views_2d;
- std::vector<std::shared_ptr<View3D>> views_3d;
+
+ float projection_width, projection_height;
+
+ // FIXME: if these vectors get resized, they can cause a segmentation fault!
+ std::vector<UniformBuffer> ub_2d;
+ std::vector<VkDescriptorSet> descriptor_sets_2d;
+
+ std::vector<std::vector<Rectangle>> rectangles_to_draw;
+ std::vector<std::vector<SpriteToDraw>> sprites_to_draw;
+
+ std::vector<std::shared_ptr<View>> views;
+
QueueFamily *queue_family;
VkCommandPool command_pool;
std::vector<VkCommandBuffer> draw_command_buffers;
- Renderer(std::vector<std::shared_ptr<View2D>> views_2d,
- std::vector<std::shared_ptr<View3D>> views_3d);
- Renderer(std::initializer_list<std::shared_ptr<View2D>> views_2d,
- std::initializer_list<std::shared_ptr<View3D>> views_3d);
+ Renderer(std::vector<std::shared_ptr<View>> views, F32 width, F32 height);
+ Renderer(std::initializer_list<std::shared_ptr<View>> views,
+ F32 width, F32 height);
~Renderer();
void
diff --git a/src/blu_cat/gra/skeletal_mesh.cpp b/src/blu_cat/gra/skeletal_mesh.cpp
index 1515dda..8e2e39f 100644
--- a/src/blu_cat/gra/skeletal_mesh.cpp
+++ b/src/blu_cat/gra/skeletal_mesh.cpp
@@ -86,7 +86,7 @@ load_mesh(void *obj)
SKELETAL_MESH_HEADER_SIZE +
header.num_vertexes * 16 * SIZE_32_BIT +
header.num_indexes * SIZE_32_BIT +
- header.num_bones * 16 * SIZE_32_BIT +
+ header.num_bones * (16 * SIZE_32_BIT + SIZE_16_BIT) +
header.num_animations * (2 * SIZE_64_BIT + SIZE_32_BIT) +
header.num_bone_transforms * 4 * SIZE_32_BIT +
header.num_bone_positions * (3 * SIZE_32_BIT + SIZE_64_BIT) +
@@ -153,7 +153,11 @@ load_mesh(void *obj)
{ // Load bones
self->mesh->bones.reserve(header.num_bones);
for(int i{0}; i < header.num_bones; i++)
- self->mesh->bones.emplace_back(input.read_mat4());
+ {
+ auto matrix{input.read_mat4()};
+ auto parent{input.read_ui16()};
+ self->mesh->bones.emplace_back(matrix, parent);
+ }
}
{ // Load animations
diff --git a/src/blu_cat/gra/skeletal_model.cpp b/src/blu_cat/gra/skeletal_model.cpp
index 4b44910..726b97e 100644
--- a/src/blu_cat/gra/skeletal_model.cpp
+++ b/src/blu_cat/gra/skeletal_model.cpp
@@ -172,30 +172,30 @@ SkeletalModel::~SkeletalModel()
void
SkeletalModel::tick(float delta)
{
- BluCat::GRA::Animation *current_animation =
- &this->skeletal_mesh->animations[this->animation_index];
+ BluCat::GRA::Animation &current_animation =
+ this->skeletal_mesh->animations[this->animation_index];
{ // update time
this->animation_time += delta;
- if(this->animation_time > current_animation->final_time)
+ if(this->animation_time > current_animation.final_time)
{
- this->animation_time -= current_animation->final_time;
+ this->animation_time -= current_animation.final_time;
for(BluCat::GRA::BoneTransform &bone_transform:
- current_animation->bone_transforms)
+ current_animation.bone_transforms)
{
- bone_transform.positions.current_index = 0;
- bone_transform.rotations.current_index = 0;
- bone_transform.scales.current_index = 0;
+ bone_transform.positions.current_index = 0;
+ bone_transform.rotations.current_index = 0;
+ bone_transform.scales.current_index = 0;
}
}
}
- for(int i{0}; i < current_animation->bone_transforms.size(); i++)
+ for(UI16 i{0}; i < current_animation.bone_transforms.size(); i++)
{
- BluCat::GRA::BoneTransform *bone_transform =
- &current_animation->bone_transforms[i];
+ BluCat::GRA::BoneTransform &bone_transform =
+ current_animation.bone_transforms[i];
- auto position{bone_transform->positions.interpolate(
+ auto position{bone_transform.positions.interpolate(
this->animation_time,
[](glm::vec3 frame)
{
@@ -208,7 +208,7 @@ SkeletalModel::tick(float delta)
return glm::translate(glm::mat4(1.0f), final_position);
})};
- auto rotation{bone_transform->rotations.interpolate(
+ auto rotation{bone_transform.rotations.interpolate(
this->animation_time,
[](glm::quat frame)
{
@@ -220,7 +220,7 @@ SkeletalModel::tick(float delta)
previous_frame, next_frame, scale_factor));
})};
- auto scale{bone_transform->scales.interpolate(
+ auto scale{bone_transform.scales.interpolate(
this->animation_time,
[](glm::vec3 frame)
{
@@ -233,9 +233,15 @@ SkeletalModel::tick(float delta)
return glm::scale(glm::mat4(1.0f), scale);
})};
- this->bone_transforms[i] =
- this->skeletal_mesh->bones[i].offset_matrix *
- (position * rotation * scale);
+ auto parent{this->skeletal_mesh->bones[i].parent};
+ auto node_transform{(this->skeletal_mesh->bones[i].offset_matrix *
+ (position * rotation * scale))};
+
+ if(parent == i)
+ this->bone_transforms[i] = node_transform;
+ else
+ this->bone_transforms[i] =
+ this->bone_transforms[parent] * node_transform;
}
}
diff --git a/src/blu_cat/gra/text.cpp b/src/blu_cat/gra/text.cpp
new file mode 100644
index 0000000..42341a3
--- /dev/null
+++ b/src/blu_cat/gra/text.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2022-2025 Frederico de Oliveira Linhares
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "text.hpp"
+
+#include "../int/core.hpp"
+
+namespace BluCat::GRA
+{
+
+Text::Text(
+ const BitmapFont &font, const char *str, const I32F x, const I32F y,
+ F32 z_index):
+ x{x},
+ y{y},
+ width{0},
+ height{0},
+ z_index{z_index}
+{
+ const std::vector<UI32> text{BluCat::GRA::Character::str_to_unicode(str)};
+ this->letters.reserve(text.size());
+
+ I32F current_column{0};
+ I32F current_line{0};
+
+ for(I32F index{0}; index < text.size(); index++)
+ {
+ switch(str[index])
+ {
+ case 10:
+ if((current_column + 1) * font.width > this->width)
+ this->width = (current_column + 1) * font.width;
+ current_column = 0;
+ current_line++;
+ continue;
+
+ case 32:
+ current_column++;
+ continue;
+ }
+
+ glm::vec4 rect{
+ x + current_column * font.width,
+ y + current_line * font.height,
+ x + (current_column + 1) * font.width,
+ y + (current_line + 1) * font.height};
+
+ this->letters.emplace_back(font.characters.at(text[index]).sprite, rect);
+ current_column++;
+ }
+
+ if((current_column + 1) * font.width > this->width)
+ this->width = (current_column + 1) * font.width;
+ this->height = font.height * (current_line + 1);
+}
+
+Text::Text():
+ letters(0),
+ x{0},
+ y{0},
+ width{0},
+ height{0},
+ z_index{4.5f}
+{
+}
+
+void
+Text::draw()
+{
+ auto &sprites_to_draw = BluCat::INT::core.vk_renderer->sprites_to_draw[
+ BluCat::INT::core.vk_swapchain->current_frame];
+
+ for(Letter &l: this->letters)
+ sprites_to_draw.emplace_back(l.sprite, l.position, this->z_index);
+}
+
+}
diff --git a/src/blu_cat/gra/text.hpp b/src/blu_cat/gra/text.hpp
new file mode 100644
index 0000000..5b7dcde
--- /dev/null
+++ b/src/blu_cat/gra/text.hpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2022-2025 Frederico de Oliveira Linhares
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BLU_CAT_GRA_TEXT_H
+#define BLU_CAT_GRA_TEXT_H 1
+
+#include "bitmap_font.hpp"
+
+namespace BluCat::GRA
+{
+
+struct Letter
+{
+ std::shared_ptr<Sprite> sprite;
+ glm::vec4 position;
+};
+
+struct Text
+{
+ std::vector<Letter> letters;
+ I32F x, y, width, height;
+ F32 z_index;
+
+ Text(const BitmapFont &font, const char *str, const I32F x, const I32F y,
+ F32 z_index);
+ Text();
+
+ void
+ draw();
+};
+
+}
+
+#endif /* BLU_CAT_GRA_TEXT_H */
diff --git a/src/blu_cat/gra/texture.cpp b/src/blu_cat/gra/texture.cpp
index 5abf751..7546d56 100644
--- a/src/blu_cat/gra/texture.cpp
+++ b/src/blu_cat/gra/texture.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 Frederico de Oliveira Linhares
+ * Copyright 2022-2025 Frederico de Oliveira Linhares
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -173,8 +173,8 @@ load_sampler(void *obj)
sampler_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
sampler_info.pNext = nullptr;
sampler_info.flags = 0;
- sampler_info.magFilter = VK_FILTER_LINEAR;
- sampler_info.minFilter = VK_FILTER_LINEAR;
+ sampler_info.magFilter = VK_FILTER_NEAREST;
+ sampler_info.minFilter = VK_FILTER_NEAREST;
sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
diff --git a/src/blu_cat/gra/view_3d.cpp b/src/blu_cat/gra/view.cpp
index dc310e3..26017ce 100644
--- a/src/blu_cat/gra/view_3d.cpp
+++ b/src/blu_cat/gra/view.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 Frederico de Oliveira Linhares
+ * Copyright 2022-2025 Frederico de Oliveira Linhares
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,27 +14,30 @@
* limitations under the License.
*/
-#include "view_3d.hpp"
+#include "view.hpp"
#include <array>
#include "../int/core.hpp"
#include "uniform_data_object.hpp"
+#include <iostream>
+
namespace
{
void
-load_3d_uniform_buffer(void *obj)
+load_uniform_buffer(void *obj)
{
- auto self = static_cast<BluCat::GRA::View3D*>(obj);
+ auto self = static_cast<BluCat::GRA::View*>(obj);
try
{
self->ub_3d.reserve(BluCat::INT::core.vk_swapchain->images_count);
for(auto i{0}; i < BluCat::INT::core.vk_swapchain->images_count; i++)
self->ub_3d.emplace_back(
- BluCat::INT::core.vk_device_with_swapchain, sizeof(BluCat::GRA::UDOView3D));
+ BluCat::INT::core.vk_device_with_swapchain,
+ sizeof(BluCat::GRA::UDOView3D));
}
catch(const std::exception& e)
{
@@ -43,17 +46,17 @@ load_3d_uniform_buffer(void *obj)
}
void
-unload_3d_uniform_buffer(void *obj)
+unload_uniform_buffer(void *obj)
{
- auto self = static_cast<BluCat::GRA::View3D*>(obj);
+ auto self = static_cast<BluCat::GRA::View*>(obj);
self->ub_3d.clear();
}
void
-load_descriptor_sets_3d(void *obj)
+load_descriptor_sets(void *obj)
{
- auto self = static_cast<BluCat::GRA::View3D*>(obj);
+ auto self = static_cast<BluCat::GRA::View*>(obj);
std::vector<VkDescriptorSetLayout> layouts(
BluCat::INT::core.vk_swapchain->images_count,
@@ -65,17 +68,17 @@ load_descriptor_sets_3d(void *obj)
alloc_info.descriptorSetCount = layouts.size();
alloc_info.pSetLayouts = layouts.data();
- self->descriptor_sets_3d.resize(layouts.size());
+ self->descriptor_sets.resize(layouts.size());
if(vkAllocateDescriptorSets(
BluCat::INT::core.vk_device_with_swapchain->device, &alloc_info,
- self->descriptor_sets_3d.data()) != VK_SUCCESS)
+ self->descriptor_sets.data()) != VK_SUCCESS)
throw CommandError{"Failed to create Vulkan descriptor sets for view."};
}
void
-load_resources_to_descriptor_sets_3d(void *obj)
+load_resources_to_descriptor_sets(void *obj)
{
- auto self = static_cast<BluCat::GRA::View3D*>(obj);
+ auto self = static_cast<BluCat::GRA::View*>(obj);
for(auto i{0}; i < self->ub_3d.size(); i++)
{
@@ -86,7 +89,7 @@ load_resources_to_descriptor_sets_3d(void *obj)
std::array<VkWriteDescriptorSet, 1> write_descriptors{};
write_descriptors[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
- write_descriptors[0].dstSet = self->descriptor_sets_3d[i];
+ write_descriptors[0].dstSet = self->descriptor_sets[i];
write_descriptors[0].dstBinding = 0;
write_descriptors[0].dstArrayElement = 0;
write_descriptors[0].descriptorCount = 1;
@@ -96,18 +99,18 @@ load_resources_to_descriptor_sets_3d(void *obj)
write_descriptors[0].pTexelBufferView = nullptr;
vkUpdateDescriptorSets(
- BluCat::INT::core.vk_device_with_swapchain->device, write_descriptors.size(),
- write_descriptors.data(), 0, nullptr);
+ BluCat::INT::core.vk_device_with_swapchain->device,
+ write_descriptors.size(), write_descriptors.data(), 0, nullptr);
}
}
const CommandChain loader{
- {&load_3d_uniform_buffer, &unload_3d_uniform_buffer}
+ {&load_uniform_buffer, &unload_uniform_buffer}
};
const CommandChain descriptor_sets_loader{
- {&load_descriptor_sets_3d, nullptr},
- {&load_resources_to_descriptor_sets_3d, nullptr}
+ {&load_descriptor_sets, nullptr},
+ {&load_resources_to_descriptor_sets, nullptr}
};
}
@@ -115,41 +118,41 @@ const CommandChain descriptor_sets_loader{
namespace BluCat::GRA
{
-View3D::View3D(
- glm::vec4 region, float projection_width, float projection_height):
- View2D{region, projection_width, projection_height},
+View::View(
+ glm::vec4 region, float projection_width,
+ float projection_height):
+ region{region},
+ projection_width{projection_width},
+ projection_height{projection_height},
field_of_view{45.0f},
+ descriptor_pool{VK_NULL_HANDLE},
camera_position{std::make_shared<glm::vec3>(0.0f, 0.0f, 0.0f)},
camera_orientation{std::make_shared<glm::quat>(0.0f, 0.0f, 0.0f, 0.0f)}
{
- ::loader.execute(this);
+ loader.execute(this);
}
-View3D::~View3D()
+View::~View()
{
- ::loader.revert(this);
+ loader.revert(this);
}
void
-View3D::load_descriptor_sets(VkDescriptorPool descriptor_pool)
+View::load_descriptor_sets(VkDescriptorPool descriptor_pool)
{
if(this->descriptor_pool != VK_NULL_HANDLE) return;
- auto parent = dynamic_cast<BluCat::GRA::View2D*>(this);
this->descriptor_pool = descriptor_pool;
- View2D::descriptor_sets_loader.execute(parent);
::descriptor_sets_loader.execute(this);
}
void
-View3D::unload_descriptor_sets()
+View::unload_descriptor_sets()
{
if(this->descriptor_pool == VK_NULL_HANDLE) return;
- auto parent = dynamic_cast<BluCat::GRA::View2D*>(this);
this->descriptor_pool = VK_NULL_HANDLE;
::descriptor_sets_loader.revert(this);
- View2D::descriptor_sets_loader.revert(parent);
}
}
diff --git a/src/blu_cat/gra/view_3d.hpp b/src/blu_cat/gra/view.hpp
index f09c70f..a61ac34 100644
--- a/src/blu_cat/gra/view_3d.hpp
+++ b/src/blu_cat/gra/view.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 Frederico de Oliveira Linhares
+ * Copyright 2022-2025 Frederico de Oliveira Linhares
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,35 +14,42 @@
* limitations under the License.
*/
-#ifndef BLU_CAT_GRA_VIEW_3D_H
-#define BLU_CAT_GRA_VIEW_3D_H 1
+#ifndef BLU_CAT_GRA_VIEW_H
+#define BLU_CAT_GRA_VIEW_H 1
-#include "view_2d.hpp"
+#include <memory>
+#include <unordered_map>
+#include <vector>
+
+#include "vulkan.hpp"
+#include "uniform_buffer.hpp"
namespace BluCat::GRA
{
-struct View3D: public View2D
+struct View
{
- float field_of_view;
+ glm::vec4 region;
+ float field_of_view, projection_width, projection_height;
+
// FIXME: if this vector get resized, it can cause a segmentation fault!
std::vector<UniformBuffer> ub_3d;
- std::vector<VkDescriptorSet> descriptor_sets_3d;
+ VkDescriptorPool descriptor_pool;
+ std::vector<VkDescriptorSet> descriptor_sets;
std::shared_ptr<glm::vec3> camera_position;
std::shared_ptr<glm::quat> camera_orientation;
- View3D(glm::vec4 region, float projection_width, float projection_height);
- ~View3D();
-
void
load_descriptor_sets(VkDescriptorPool descriptor_pool);
-
void
unload_descriptor_sets();
+
+ View(glm::vec4 region, float projection_width, float projection_height);
+ ~View();
};
}
-#endif /* BLU_CAT_GRA_VIEW_3D_H */
+#endif /* BLU_CAT_GRA_VIEW_H */
diff --git a/src/blu_cat/gra/view_2d.cpp b/src/blu_cat/gra/view_2d.cpp
deleted file mode 100644
index 948b145..0000000
--- a/src/blu_cat/gra/view_2d.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright 2022-2024 Frederico de Oliveira Linhares
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "view_2d.hpp"
-
-#include <array>
-
-#include "../int/core.hpp"
-#include "uniform_data_object.hpp"
-
-namespace
-{
-
-void
-load_2d_uniform_buffer(void *obj)
-{
- auto self = static_cast<BluCat::GRA::View2D*>(obj);
-
- try
- {
- self->ub_2d.reserve(BluCat::INT::core.vk_swapchain->images_count);
- for(auto i{0}; i < BluCat::INT::core.vk_swapchain->images_count; i++)
- self->ub_2d.emplace_back(
- BluCat::INT::core.vk_device_with_swapchain, sizeof(BluCat::GRA::UDOView2D));
- }
- catch(const std::exception& e)
- {
- throw CommandError{e.what()};
- }
-}
-
-void
-unload_2d_uniform_buffer(void *obj)
-{
- auto self = static_cast<BluCat::GRA::View2D*>(obj);
-
- self->ub_2d.clear();
-}
-
-void
-load_descriptor_sets_2d(void *obj)
-{
- auto self = static_cast<BluCat::GRA::View2D*>(obj);
-
- std::vector<VkDescriptorSetLayout> layouts(
- BluCat::INT::core.vk_swapchain->images_count,
- BluCat::INT::core.vk_descriptor_set_layout->view);
-
- VkDescriptorSetAllocateInfo alloc_info{};
- alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
- alloc_info.descriptorPool = self->descriptor_pool;
- alloc_info.descriptorSetCount = layouts.size();
- alloc_info.pSetLayouts = layouts.data();
-
- self->descriptor_sets_2d.resize(layouts.size());
- if(vkAllocateDescriptorSets(
- BluCat::INT::core.vk_device_with_swapchain->device, &alloc_info,
- self->descriptor_sets_2d.data()) != VK_SUCCESS)
- throw CommandError{"Failed to create Vulkan descriptor sets for view."};
-}
-
-void
-load_resources_to_descriptor_sets_2d(void *obj)
-{
- auto self = static_cast<BluCat::GRA::View2D*>(obj);
-
- for(auto i{0}; i < self->ub_2d.size(); i++)
- {
- VkDescriptorBufferInfo view_2d_info{};
- view_2d_info.buffer = self->ub_2d[i].buffer;
- view_2d_info.offset = 0;
- view_2d_info.range = sizeof(BluCat::GRA::UDOView2D);
-
- std::array<VkWriteDescriptorSet, 1> write_descriptors{};
- write_descriptors[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
- write_descriptors[0].dstSet = self->descriptor_sets_2d[i];
- write_descriptors[0].dstBinding = 0;
- write_descriptors[0].dstArrayElement = 0;
- write_descriptors[0].descriptorCount = 1;
- write_descriptors[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- write_descriptors[0].pBufferInfo = &view_2d_info;
- write_descriptors[0].pImageInfo = nullptr;
- write_descriptors[0].pTexelBufferView = nullptr;
-
- vkUpdateDescriptorSets(
- BluCat::INT::core.vk_device_with_swapchain->device, write_descriptors.size(),
- write_descriptors.data(), 0, nullptr);
-
- BluCat::GRA::UDOView2D ubo_view_2d;
- ubo_view_2d.proj = glm::ortho(
- 0.0f, self->projection_width,
- 0.0f, self->projection_height,
- 0.0f, 100.0f);
- self->ub_2d[i].copy_data(&ubo_view_2d);
- }
-}
-
-}
-
-namespace BluCat::GRA
-{
-
-const CommandChain View2D::loader{
- {&load_2d_uniform_buffer, &unload_2d_uniform_buffer}
-};
-
-const CommandChain View2D::descriptor_sets_loader{
- {&load_descriptor_sets_2d, nullptr},
- {&load_resources_to_descriptor_sets_2d, nullptr}
-};
-
-View2D::View2D(
- glm::vec4 region, float projection_width, float projection_height):
- projection_width{projection_width},
- projection_height{projection_height},
- region{region},
- descriptor_pool{VK_NULL_HANDLE},
- rectangles_to_draw{BluCat::INT::core.vk_swapchain->images_count},
- sprites_to_draw{BluCat::INT::core.vk_swapchain->images_count}
-{
- loader.execute(this);
-}
-
-View2D::~View2D()
-{
- loader.revert(this);
-}
-
-void
-View2D::load_descriptor_sets(VkDescriptorPool descriptor_pool)
-{
- if(this->descriptor_pool != VK_NULL_HANDLE) return;
-
- this->descriptor_pool = descriptor_pool;
- descriptor_sets_loader.execute(this);
-}
-
-void
-View2D::unload_descriptor_sets()
-{
- if(this->descriptor_pool == VK_NULL_HANDLE) return;
-
- this->descriptor_pool = VK_NULL_HANDLE;
- descriptor_sets_loader.revert(this);
-}
-
-}
diff --git a/src/blu_cat/gra/view_2d.hpp b/src/blu_cat/gra/view_2d.hpp
deleted file mode 100644
index 84b9f09..0000000
--- a/src/blu_cat/gra/view_2d.hpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2022-2024 Frederico de Oliveira Linhares
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef BLU_CAT_GRA_VIEW_2D_H
-#define BLU_CAT_GRA_VIEW_2D_H 1
-
-#include <memory>
-#include <unordered_map>
-#include <vector>
-
-#include "vulkan.hpp"
-#include "sprite_to_draw.hpp"
-#include "rectangle.hpp"
-
-namespace BluCat::GRA
-{
-
-struct View2D
-{
- glm::vec4 region;
- float projection_width, projection_height;
-
- // FIXME: if these vectors get resized, they can cause a segmentation fault!
- std::vector<UniformBuffer> ub_2d;
-
- VkDescriptorPool descriptor_pool;
- std::vector<VkDescriptorSet> descriptor_sets_2d;
-
- std::vector<std::vector<Rectangle>> rectangles_to_draw;
- std::vector<std::vector<SpriteToDraw>> sprites_to_draw;
-
- View2D(glm::vec4 region, float projection_width, float projection_height);
- virtual ~View2D();
-
- void
- virtual load_descriptor_sets(VkDescriptorPool descriptor_pool);
-
- void
- virtual unload_descriptor_sets();
-
-protected:
- static const CommandChain loader, descriptor_sets_loader;
-};
-
-}
-
-#endif /* BLU_CAT_GRA_VIEW_2D_H */
diff --git a/src/blu_cat/int/controller.hpp b/src/blu_cat/int/controller.hpp
new file mode 100644
index 0000000..deedde3
--- /dev/null
+++ b/src/blu_cat/int/controller.hpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2022-2025 Frederico de Oliveira Linhares
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BLU_CAT_INT_CONTROLLER_H
+#define BLU_CAT_INT_CONTROLLER_H 1
+
+#include <SDL3/SDL.h>
+
+namespace BluCat::INT
+{
+
+struct Controller
+{
+ virtual void
+ key_down(SDL_Keycode keycode){};
+ virtual void
+ key_up(SDL_Keycode keycode){};
+
+ virtual void
+ mouse_button_down(SDL_MouseButtonEvent& e){};
+ virtual void
+ mouse_button_up(SDL_MouseButtonEvent& e){};
+ virtual void
+ mouse_motion(int x, int y, int xrel, int yrel){};
+
+ virtual void
+ tick(){};
+ virtual void
+ render(){};
+
+ virtual
+ ~Controller(){};
+};
+
+}
+
+#endif /* BLU_CAT_INT_CONTROLLER_H */
diff --git a/src/blu_cat/int/core.cpp b/src/blu_cat/int/core.cpp
index d631d17..6f67b98 100644
--- a/src/blu_cat/int/core.cpp
+++ b/src/blu_cat/int/core.cpp
@@ -56,14 +56,14 @@ vk_debug_callback(
void
load_sdl(void *obj)
{
- if(SDL_Init(SDL_INIT_EVERYTHING) < 0)
+ if(!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS))
{
std::string error{"SDL could not initialize! SDL Error → "};
error += SDL_GetError();
- throw error;
+ throw CommandError{error};
}
- if(SDL_Vulkan_LoadLibrary(nullptr) != 0)
+ if(!SDL_Vulkan_LoadLibrary(nullptr))
{
SDL_Quit();
std::string error{"SDL could not initialize Vulkan! SDL_Error → "};
@@ -80,51 +80,13 @@ unload_sdl(void *obj)
}
void
-load_sdl_mixer(void *obj)
-{
- int flags = MIX_INIT_OGG|MIX_INIT_MOD;
- int initted = Mix_Init(flags);
- if(initted&flags != flags)
- {
- std::string error{"Could not initialize SDL mixer → "};
- error += Mix_GetError();
- throw CommandError{error};
- }
-}
-
-void
-unload_sdl_mixer(void *obj)
-{
- while(Mix_Init(0)) Mix_Quit();
-}
-
-void
-load_sdl_open_audio(void *obj)
-{
- if(Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, 2, 1024) == -1)
- {
- std::string error{"Could not open SDL mixer audio → "};
- error += Mix_GetError();
- throw CommandError{error};
- }
-}
-
-void
-unload_sdl_open_audio(void *obj)
-{
- Mix_CloseAudio();
-}
-
-void
load_window(void *obj)
{
- BluCat::INT::core.window = nullptr;
BluCat::INT::core.window = SDL_CreateWindow(
BluCat::INT::core.game_name.c_str(),
- SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
BluCat::INT::core.display_width, BluCat::INT::core.display_height,
SDL_WINDOW_VULKAN);
- if(BluCat::INT::core.window == nullptr)
+ if(BluCat::INT::core.window == NULL)
{
std::string error{"Window could not be created! SDL_Error → "};
error += SDL_GetError();
@@ -160,8 +122,10 @@ load_vk_instance(void *obj)
uint32_t vk_sdl_extension_count;
std::vector<const char*> vk_sdl_extensions;
- if(!SDL_Vulkan_GetInstanceExtensions(
- BluCat::INT::core.window, &vk_sdl_extension_count, nullptr))
+ const char * const *instance_extensions =
+ SDL_Vulkan_GetInstanceExtensions(&vk_sdl_extension_count);
+
+ if(instance_extensions == NULL)
{
std::string error{
"Vulkan extensions could not be loaded by SDL! SDL_Error: "};
@@ -169,10 +133,8 @@ load_vk_instance(void *obj)
throw CommandError{error};
}
- vk_sdl_extensions.resize(vk_sdl_extension_count);
- SDL_Vulkan_GetInstanceExtensions(
- BluCat::INT::core.window, &vk_sdl_extension_count,
- vk_sdl_extensions.data());
+ for(auto i{0}; i < vk_sdl_extension_count; i++)
+ vk_sdl_extensions.push_back(instance_extensions[i]);
// Combine all extensions.
vk_extensions_count = vk_sdl_extension_count +
@@ -290,7 +252,7 @@ load_window_surface(void *obj)
{
if(!SDL_Vulkan_CreateSurface(
BluCat::INT::core.window, BluCat::INT::core.vk_instance,
- &BluCat::INT::core.window_surface))
+ nullptr, &BluCat::INT::core.window_surface))
{
std::string error{"Failed to create a window surface → "};
error += SDL_GetError();
@@ -692,13 +654,13 @@ load_renderer(void *obj)
{
try
{
+ auto width{static_cast<float>(BluCat::INT::core.display_width)};
+ auto height{static_cast<float>(BluCat::INT::core.display_height)};
glm::vec4 region(
- 0.f, 0.f,
- static_cast<float>(BluCat::INT::core.display_width),
- static_cast<float>(BluCat::INT::core.display_height));
+ 0.f, 0.f, width, height);
BluCat::INT::core.vk_renderer = new BluCat::GRA::Renderer(
- {},
- {std::make_shared<BluCat::GRA::View3D>(region, region.z, region.w)});
+ {std::make_shared<BluCat::GRA::View>(region, region.z, region.w)},
+ width, height);
}
catch(const CommandError &e)
{
@@ -722,8 +684,6 @@ std::mt19937 random_number_generator;
const CommandChain Core::loader{
{&load_sdl, &unload_sdl},
- {&load_sdl_mixer, &unload_sdl_mixer},
- {&load_sdl_open_audio, &unload_sdl_open_audio},
{&load_window, &unload_window},
{&load_vk_instance, &unload_vk_instance},
{&load_window_surface, &unload_window_surface},
@@ -758,4 +718,82 @@ const CommandChain Core::loader{
Core core;
+void
+run_game(std::unique_ptr<BluCat::INT::Mode> _mode)
+{
+ using namespace std::chrono;
+ using namespace std::this_thread;
+
+ std::unique_ptr<BluCat::INT::Mode> mode{std::move(_mode)};
+ std::unique_ptr<BluCat::INT::Controller> controller{
+ mode->default_controller()};
+
+ bool quit{false};
+ int x, y, xrel, yrel;
+ SDL_Event event;
+ auto frame_start = steady_clock::now();
+
+ while(!quit)
+ {
+ if(core.next_game_mode)
+ {
+ mode = std::move(core.next_game_mode);
+ controller = mode->default_controller();
+ }
+ else if(core.next_game_controller)
+ controller = std::move(core.next_game_controller);
+
+ while(SDL_PollEvent(&event))
+ {
+ switch(event.type)
+ {
+ case SDL_EVENT_KEY_DOWN:
+ if(event.key.repeat != 0) continue;
+ controller->key_down(event.key.key);
+ break;
+ case SDL_EVENT_KEY_UP:
+ if(event.key.repeat != 0) continue;
+ controller->key_up(event.key.key);
+ break;
+ case SDL_EVENT_MOUSE_BUTTON_DOWN:
+ controller->mouse_button_down(event.button);
+ break;
+ case SDL_EVENT_MOUSE_BUTTON_UP:
+ controller->mouse_button_up(event.button);
+ break;
+ case SDL_EVENT_MOUSE_MOTION:
+ x = event.motion.x;
+ y = event.motion.y;
+
+ xrel = event.motion.xrel;
+ yrel = event.motion.yrel;
+
+ controller->mouse_motion(x, y, xrel, yrel);
+ break;
+ case SDL_EVENT_QUIT:
+ quit = true;
+ }
+ }
+
+ controller->tick();
+ mode->render();
+ controller->render();
+ BluCat::INT::core.vk_renderer->draw();
+
+ { // Timer
+ auto frame_stop = steady_clock::now();
+ auto frame_duration = frame_stop - frame_start;
+
+ // If frame take less time than maximum allowed.
+ if(core.max_frame_duration > frame_duration)
+ sleep_for(core.max_frame_duration - frame_duration);
+
+ frame_start = frame_stop;
+ }
+ }
+
+ controller = nullptr;
+ mode = nullptr;
+}
+
}
diff --git a/src/blu_cat/int/core.hpp b/src/blu_cat/int/core.hpp
index a334dfa..4737123 100644
--- a/src/blu_cat/int/core.hpp
+++ b/src/blu_cat/int/core.hpp
@@ -32,9 +32,8 @@
#include <Windows.h>
#endif
-#include <SDL2/SDL.h>
-#include <SDL2/SDL_vulkan.h>
-#include <SDL2/SDL_mixer.h>
+#include <SDL3/SDL.h>
+#include <SDL3/SDL_vulkan.h>
#include <ft2build.h>
#include FT_FREETYPE_H
@@ -59,6 +58,7 @@
#include "../gra/renderer.hpp"
#include "../gra/swapchain.hpp"
#include "../gra/vulkan.hpp"
+#include "mode.hpp"
namespace BluCat::INT
{
@@ -132,10 +132,16 @@ struct Core
vk_graphics_pipeline_2d_wired;
BluCat::GRA::Renderer *vk_renderer;
+
+ std::unique_ptr<BluCat::INT::Mode> next_game_mode{nullptr};
+ std::unique_ptr<BluCat::INT::Controller> next_game_controller{nullptr};
};
extern Core core;
+void
+run_game(std::unique_ptr<Mode> initial_mode);
+
}
#endif /* BLU_CAT_INT_CORE_H */
diff --git a/src/blu_cat/int/mode.hpp b/src/blu_cat/int/mode.hpp
new file mode 100644
index 0000000..8197f75
--- /dev/null
+++ b/src/blu_cat/int/mode.hpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2022-2025 Frederico de Oliveira Linhares
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BLU_CAT_INT_MODE_H
+#define BLU_CAT_INT_MODE_H 1
+
+#include <memory>
+
+#include "controller.hpp"
+
+namespace BluCat::INT
+{
+
+struct Mode
+{
+ virtual std::unique_ptr<Controller>
+ default_controller() = 0;
+
+ virtual void
+ render() = 0;
+
+ virtual
+ ~Mode(){};
+};
+
+}
+
+#endif /* BLU_CAT_INT_MODE_H */