diff options
Diffstat (limited to 'src/blu_cat/int')
-rw-r--r-- | src/blu_cat/int/core.cpp | 761 | ||||
-rw-r--r-- | src/blu_cat/int/core.hpp | 141 |
2 files changed, 902 insertions, 0 deletions
diff --git a/src/blu_cat/int/core.cpp b/src/blu_cat/int/core.cpp new file mode 100644 index 0000000..7e78b89 --- /dev/null +++ b/src/blu_cat/int/core.cpp @@ -0,0 +1,761 @@ +/* + * 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 "core.hpp" + +namespace +{ + +#ifdef DEBUG +VKAPI_ATTR VkBool32 VKAPI_CALL +vk_debug_callback( + VkDebugUtilsMessageSeverityFlagBitsEXT message_severity, + VkDebugUtilsMessageTypeFlagsEXT message_type, + const VkDebugUtilsMessengerCallbackDataEXT* callback_data, + void* _obj) +{ + // Set level. + Log::Level log_level; + switch(message_severity) + { + case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT: + log_level = Log::Level::Trace; + break; + case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT: + log_level = Log::Level::Information; + break; + case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT: + log_level = Log::Level::Warning; + break; + case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT: + default: + log_level = Log::Level::Error; + break; + } + + // Log message. + BluCat::INT::core.log.message(log_level, callback_data->pMessage); + + return VK_FALSE; +} +#endif + +void +load_sdl(void *obj) +{ + if(SDL_Init(SDL_INIT_EVERYTHING) < 0) + { + std::string error{"SDL could not initialize! SDL Error → "}; + error += SDL_GetError(); + throw error; + } + + if(SDL_Vulkan_LoadLibrary(nullptr) != 0) + { + SDL_Quit(); + std::string error{"SDL could not initialize Vulkan! SDL_Error → "}; + error += SDL_GetError(); + throw CommandError{error}; + } +} + +void +unload_sdl(void *obj) +{ + SDL_Vulkan_UnloadLibrary(); + SDL_Quit(); +} + +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) + { + std::string error{"Window could not be created! SDL_Error → "}; + error += SDL_GetError(); + throw CommandError{error}; + } +} + +void +unload_window(void *obj) +{ + SDL_DestroyWindow(BluCat::INT::core.window); +} + +void +load_vk_instance(void *obj) +{ + std::vector<const char*> vk_extensions; + std::vector<const char*> vk_required_layers_names; + + // Get extensions. + { + uint32_t vk_extensions_count; + std::vector<const char*> vk_required_extensions; + + // Load debuging layers. +#ifdef DEBUG + vk_required_extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); + vk_required_layers_names.push_back("VK_LAYER_KHRONOS_validation"); +#endif + + // Get extensions for SDL. + { + 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)) + { + std::string error{ + "Vulkan extensions could not be loaded by SDL! SDL_Error: "}; + error += SDL_GetError(); + 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()); + + // Combine all extensions. + vk_extensions_count = vk_sdl_extension_count + + vk_required_extensions.size(); + vk_extensions.resize(vk_extensions_count); + for(auto i{0}; i < vk_sdl_extension_count; i++) + vk_extensions[i] = vk_sdl_extensions[i]; + for(auto i{0}; i < vk_required_extensions.size(); i++) + vk_extensions[i + vk_sdl_extension_count] = vk_required_extensions[i]; + } + +#ifdef DEBUG + BluCat::INT::core.log.message(Log::Level::Trace, "Enabled VK extensions."); + for(auto vk_extension: vk_extensions) + { + std::string message{"Extension name: "}; + message += vk_extension; + BluCat::INT::core.log.message(Log::Level::Trace, message); + } +#endif + } + + // Get available instance layers. + { + uint32_t vk_available_layers_count; + std::vector<VkLayerProperties> vk_available_layers; + std::vector<const char*> vk_available_layers_names; + + vkEnumerateInstanceLayerProperties(&vk_available_layers_count, nullptr); + vk_available_layers.resize(vk_available_layers_count); + vkEnumerateInstanceLayerProperties(&vk_available_layers_count, + vk_available_layers.data()); + vk_available_layers_names.resize(vk_available_layers_count); +#ifdef DEBUG + BluCat::INT::core.log.message( + Log::Level::Trace, "Available VK instance layers."); +#endif + for(uint32_t i = 0; i < vk_available_layers_count; i++) + { +#ifdef DEBUG + std::stringstream message{}; + message << "\nname: " << vk_available_layers[i].layerName << std::endl; + message << "Description: " << vk_available_layers[i].description << + std::endl; + message << "Spec version: " << vk_available_layers[i].specVersion << + std::endl; + message << "Implementation version: " << + vk_available_layers[i].implementationVersion << std::endl; + BluCat::INT::core.log.message(Log::Level::Trace, message.str()); +#endif + + vk_available_layers_names[i] = vk_available_layers[i].layerName; + } + + // If required layers are not all available. + if(!std::includes( + vk_available_layers_names.begin(), vk_available_layers_names.end(), + vk_required_layers_names.begin(), vk_required_layers_names.begin())) + throw CommandError{"Some required Vulkan layers are not available."}; + } + + { + VkApplicationInfo app_info; + app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + app_info.pNext = nullptr; + app_info.pApplicationName = BluCat::INT::core.game_name.c_str(); + app_info.applicationVersion = VK_MAKE_VERSION( + BluCat::INT::core.game_version_major, + BluCat::INT::core.game_version_minor, + BluCat::INT::core.game_version_patch); + app_info.pEngineName = "BluCat::GRA"; + app_info.engineVersion = VK_MAKE_VERSION( + BLU_CAT_VERSION_MAJOR, + BLU_CAT_VERSION_MINOR, + BLU_CAT_VERSION_PATCH); + app_info.apiVersion = VK_API_VERSION_1_0; + + VkInstanceCreateInfo create_info; + create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + create_info.pNext = nullptr; + create_info.flags = 0; + create_info.pApplicationInfo = &app_info; + create_info.enabledExtensionCount = vk_extensions.size(); + create_info.ppEnabledExtensionNames = vk_extensions.data(); + create_info.enabledLayerCount = vk_required_layers_names.size(); + create_info.ppEnabledLayerNames = vk_required_layers_names.data(); + + VkResult result = + vkCreateInstance(&create_info, nullptr, &BluCat::INT::core.vk_instance); + if(result != VK_SUCCESS) + { + std::string error{""}; + switch(result) + { + case VK_ERROR_LAYER_NOT_PRESENT: + error = " Layer not present."; + break; + case VK_ERROR_EXTENSION_NOT_PRESENT: + error = " Extension not present."; + } + error = "Failed to create Vulkan instance." + error; + throw CommandError{error}; + } + } +} + +void +unload_vk_instance(void *obj) +{ + vkDestroyInstance(BluCat::INT::core.vk_instance, nullptr); +} + +void +load_window_surface(void *obj) +{ + if(!SDL_Vulkan_CreateSurface( + BluCat::INT::core.window, BluCat::INT::core.vk_instance, + &BluCat::INT::core.window_surface)) + { + std::string error{"Failed to create a window surface → "}; + error += SDL_GetError(); + throw CommandError{error}; + } +} + +void +unload_window_surface(void *obj) +{ + vkDestroySurfaceKHR( + BluCat::INT::core.vk_instance, BluCat::INT::core.window_surface, nullptr); +} + +void +load_threads(void *obj) +{ + auto num_threads{std::thread::hardware_concurrency() - 1}; + for(auto i{0}; i < num_threads; i++) + BluCat::INT::core.threads.emplace_back( + BluCat::INT::core.workers.emplace_back(&BluCat::INT::core.job_queue)); +} + +void +unload_threads(void *obj) +{ + BluCat::INT::core.job_queue.stop(); + for(auto &t: BluCat::INT::core.threads) t.join(); +} + +void +load_fps(void *obj) +{ + using namespace std::chrono; + + BluCat::INT::core.max_frame_duration = + duration<long long, std::milli>(1000 / BluCat::INT::core.fps); + // FIXME: actually calculates the real delta time. + BluCat::INT::core.delta_time = 1.0f / BluCat::INT::core.fps; +} + +void +load_font_library(void *obj) +{ + FT_Error error{FT_Init_FreeType(&BluCat::INT::core.font_library)}; + if(error) throw CommandError{"Failed to open the FreeType library."}; +} + +void +unload_font_library(void *obj) +{ + FT_Done_FreeType(BluCat::INT::core.font_library); +} + +#ifdef DEBUG +void +load_vk_debug_callback(void *obj) +{ + PFN_vkCreateDebugUtilsMessengerEXT debug_messenger; + + // A Vulkan instance extension named VK_EXT_debug_utils and a Vulkan instance + // layer named VK_LAYER_LUNARG_standard_validation are required to enable + // this callback. These instance extension and instance layer are loaded at + // Instance::load_blucat_instance. + VkDebugUtilsMessengerCreateInfoEXT create_info; + create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; + create_info.pNext = nullptr; + create_info.messageSeverity = + VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; + create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; + create_info.pfnUserCallback = vk_debug_callback; + create_info.pUserData = nullptr; + create_info.flags = 0; + + debug_messenger = (PFN_vkCreateDebugUtilsMessengerEXT) + vkGetInstanceProcAddr(BluCat::INT::core.vk_instance, + "vkCreateDebugUtilsMessengerEXT"); + + if(debug_messenger(BluCat::INT::core.vk_instance, &create_info, nullptr, + &BluCat::INT::core.vk_callback) != VK_SUCCESS) + CommandError{"Failed to setup debug callback for Vulkan."}; +} + +void +unload_vk_debug_callback(void *obj) +{ + PFN_vkDestroyDebugUtilsMessengerEXT debug_messenger; + + debug_messenger = (PFN_vkDestroyDebugUtilsMessengerEXT) + vkGetInstanceProcAddr(BluCat::INT::core.vk_instance, + "vkDestroyDebugUtilsMessengerEXT"); + + debug_messenger(BluCat::INT::core.vk_instance, BluCat::INT::core.vk_callback, nullptr); +} +#endif + +void +load_devices(void *obj) +{ + uint32_t devices_count; + std::vector<VkPhysicalDevice> vk_physical_devices; + + // Enumerate physical devices + { + vkEnumeratePhysicalDevices( + BluCat::INT::core.vk_instance, &devices_count, nullptr); + if(devices_count < 1) + CommandError{"Failed to find GPUs with Vulkan support."}; + vk_physical_devices.resize(devices_count); + vkEnumeratePhysicalDevices( + BluCat::INT::core.vk_instance, &devices_count, vk_physical_devices.data()); + } + +#ifdef DEBUG + BluCat::INT::core.log.message(Log::Level::Trace, "Physical devices properties"); +#endif + + BluCat::INT::core.vk_devices.reserve(devices_count); + for(auto i = 0; i < devices_count; i++) + { + // Use swapchain on first device. + if(i == 0) + { + BluCat::INT::core.vk_devices.emplace_back(vk_physical_devices[i], true); + BluCat::INT::core.vk_device_with_swapchain = &BluCat::INT::core.vk_devices[i]; + } + else + BluCat::INT::core.vk_devices.emplace_back(vk_physical_devices[i], false); + } +} + +void +unload_devices(void *obj) +{ + BluCat::INT::core.vk_devices.clear(); +} + +static void +load_swapchain(void *obj) +{ + try { BluCat::INT::core.vk_swapchain = new BluCat::GRA::Swapchain(); } + catch(const CommandError &error) + { + std::string error_message{"Failed to create swapchain → "}; + error_message += error.what(); + throw CommandError{error_message}; + } +} + +void +unload_swapchain(void *obj) +{ + delete BluCat::INT::core.vk_swapchain; +} + +void +load_framebuffer(void *obj) +{ + try + { + BluCat::INT::core.vk_framebuffer = new BluCat::GRA::Framebuffer(); + } + catch(const CommandError &e) + { + throw CommandError{"Failed to create framebuffer."}; + } +} + +void +unload_framebuffer(void *obj) +{ + delete BluCat::INT::core.vk_framebuffer; +} + +void +load_render_pass(void *obj) +{ + try + { + BluCat::INT::core.vk_render_pass = new BluCat::GRA::RenderPass(); + } + catch(const CommandError &e) + { + throw CommandError{"Failed to create render pass."}; + } +} + +void +unload_render_pass(void *obj) +{ + delete BluCat::INT::core.vk_render_pass; +} + +void +load_descriptor_set_layout(void *obj) +{ + try + { + BluCat::INT::core.vk_descriptor_set_layout = new BluCat::GRA::DescriptorSetLayout(); + } + catch(const CommandError &e) + { + throw CommandError{"Failed to create descriptor set layouts."}; + } +} + +void +unload_descriptor_set_layout(void *obj) +{ + delete BluCat::INT::core.vk_descriptor_set_layout; +} + +void +load_graphics_pipeline_3d_layout(void *obj) +{ + try + { + BluCat::INT::core.vk_graphics_pipeline_3d_layout = + new BluCat::GRA::GraphicsPipeline3DLayout(); + } + catch(const CommandError &e) + { + throw CommandError{"Failed to create 3d graphics pipeline."}; + } +} + +void +unload_graphics_pipeline_3d_layout(void *obj) +{ + delete BluCat::INT::core.vk_graphics_pipeline_3d_layout; +} + +void +load_graphics_pipeline_2d_solid_layout(void *obj) +{ + try + { + BluCat::INT::core.vk_graphics_pipeline_2d_solid_layout = + new BluCat::GRA::GraphicsPipeline2DSolidLayout(); + } + catch(const CommandError &e) + { + throw CommandError{"Failed to create 2d graphics pipeline."}; + } +} + +void +unload_graphics_pipeline_2d_solid_layout(void *obj) +{ + delete BluCat::INT::core.vk_graphics_pipeline_2d_solid_layout; +} + +void +load_graphics_pipeline_2d_wired_layout(void *obj) +{ + try + { + BluCat::INT::core.vk_graphics_pipeline_2d_wired_layout = + new BluCat::GRA::GraphicsPipeline2DWiredLayout(); + } + catch(const CommandError &e) + { + throw CommandError{"Failed to create 2d graphics pipeline."}; + } +} + +void +unload_graphics_pipeline_2d_wired_layout(void *obj) +{ + delete BluCat::INT::core.vk_graphics_pipeline_2d_wired_layout; +} + +void +load_light(void *obj) +{ + try + { + BluCat::INT::core.vk_light = new BluCat::GRA::Light(); + } + catch(const CommandError &e) + { + throw CommandError{"Failed to descriptor sets for light."}; + } +} + +void +unload_light(void *obj) +{ + delete BluCat::INT::core.vk_light; +} + +void +load_graphics_pipeline_3d(void *obj) +{ + try + { + BluCat::INT::core.vk_graphics_pipeline_3d = + std::make_unique<BluCat::GRA::GraphicsPipeline3D>(); + } + catch(const CommandError &e) + { + throw CommandError{"Failed to create 3d graphics pipeline."}; + } +} + +void +unload_graphics_pipeline_3d(void *obj) +{ + BluCat::INT::core.vk_graphics_pipeline_3d = nullptr; +} + +void +load_graphics_pipeline_3d_skeletal(void *obj) +{ + try + { + BluCat::INT::core.vk_graphics_pipeline_3d_skeletal = + std::make_unique<BluCat::GRA::GraphicsPipeline3DSkeletal>(); + } + catch(const CommandError &e) + { + throw CommandError{"Failed to create 3d skeletal graphics pipeline."}; + } +} + +void +unload_graphics_pipeline_3d_skeletal(void *obj) +{ + BluCat::INT::core.vk_graphics_pipeline_3d_skeletal = nullptr; +} + +void +load_graphics_pipeline_sprite_3d(void *obj) +{ + try + { + BluCat::INT::core.vk_graphics_pipeline_sprite_3d = + std::make_unique<BluCat::GRA::GraphicsPipelineSprite3D>(); + } + catch(const CommandError &e) + { + throw CommandError{"Failed to create sprite 3d graphics pipeline."}; + } +} + +void +unload_graphics_pipeline_sprite_3d(void *obj) +{ + BluCat::INT::core.vk_graphics_pipeline_sprite_3d = nullptr; +} + +void +load_graphics_pipeline_2d_solid(void *obj) +{ + try + { + BluCat::INT::core.vk_graphics_pipeline_2d_solid = + std::make_unique<BluCat::GRA::GraphicsPipeline2DSolid>(); + } + catch(const CommandError &e) + { + throw CommandError{"Failed to create 2d graphics pipeline."}; + } +} + +void +unload_graphics_pipeline_2d_solid(void *obj) +{ + BluCat::INT::core.vk_graphics_pipeline_2d_solid = nullptr; +} + +void +load_graphics_pipeline_2d_wired(void *obj) +{ + try + { + BluCat::INT::core.vk_graphics_pipeline_2d_wired = + std::make_unique<BluCat::GRA::GraphicsPipeline2DWired>(); + } + catch(const CommandError &e) + { + throw CommandError{"Failed to create 2d graphics pipeline."}; + } +} + +void +unload_graphics_pipeline_2d_wired(void *obj) +{ + BluCat::INT::core.vk_graphics_pipeline_2d_wired = nullptr; +} + +void +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, width, height); + BluCat::INT::core.vk_renderer = new BluCat::GRA::Renderer( + {std::make_shared<BluCat::GRA::View>(region, region.z, region.w)}, + width, height); + } + catch(const CommandError &e) + { + throw CommandError{"Failed to create renderer."}; + } +} + +void +unload_renderer(void *obj) +{ + delete BluCat::INT::core.vk_renderer; +} + +} + +namespace BluCat::INT +{ + +std::random_device random_seed; +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}, + {&load_threads, &unload_threads}, + {&load_fps, nullptr}, + {&load_font_library, &unload_font_library}, +#ifdef DEBUG + {&load_vk_debug_callback, &unload_vk_debug_callback}, +#endif + {&load_devices, &unload_devices}, + {&load_swapchain, &unload_swapchain}, + + {&load_render_pass, &unload_render_pass}, + {&load_framebuffer, &unload_framebuffer}, + {&load_descriptor_set_layout, &unload_descriptor_set_layout}, + {&load_graphics_pipeline_3d_layout, + &unload_graphics_pipeline_3d_layout}, + {&load_graphics_pipeline_2d_solid_layout, + &unload_graphics_pipeline_2d_solid_layout}, + {&load_graphics_pipeline_2d_wired_layout, + &unload_graphics_pipeline_2d_wired_layout}, + {&load_light, &unload_light}, + {&load_graphics_pipeline_3d_skeletal, + &unload_graphics_pipeline_3d_skeletal}, + {&load_graphics_pipeline_3d, &unload_graphics_pipeline_3d}, + {&load_graphics_pipeline_sprite_3d, + &unload_graphics_pipeline_sprite_3d}, + {&load_graphics_pipeline_2d_solid, &unload_graphics_pipeline_2d_solid}, + {&load_graphics_pipeline_2d_wired, &unload_graphics_pipeline_2d_wired}, + {&load_renderer, &unload_renderer}, +}; + +Core core; + +} diff --git a/src/blu_cat/int/core.hpp b/src/blu_cat/int/core.hpp new file mode 100644 index 0000000..a334dfa --- /dev/null +++ b/src/blu_cat/int/core.hpp @@ -0,0 +1,141 @@ +/* + * 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_CORE_H +#define BLU_CAT_INT_CORE_H 1 + +#define BLU_CAT_VERSION_MAJOR 0 +#define BLU_CAT_VERSION_MINOR 1 +#define BLU_CAT_VERSION_PATCH 0 + +#include <chrono> +#include <cstdint> +#include <memory> +#include <random> + +#define SDL_MAIN_HANDLED + +#ifdef _WIN64 +#include <Windows.h> +#endif + +#include <SDL2/SDL.h> +#include <SDL2/SDL_vulkan.h> +#include <SDL2/SDL_mixer.h> + +#include <ft2build.h> +#include FT_FREETYPE_H + +#include "../com/command.hpp" +#include "../com/job_queue.hpp" +#include "../com/worker.hpp" +#include "../gra/device.hpp" +#include "../gra/descriptor_set_layout.hpp" +#include "../gra/framebuffer.hpp" +#include "../gra/graphics_pipeline_2d_solid_layout.hpp" +#include "../gra/graphics_pipeline_2d_wired_layout.hpp" +#include "../gra/graphics_pipeline_2d_solid.hpp" +#include "../gra/graphics_pipeline_2d_wired.hpp" +#include "../gra/graphics_pipeline_3d_layout.hpp" +#include "../gra/graphics_pipeline_3d.hpp" +#include "../gra/graphics_pipeline_3d_skeletal.hpp" +#include "../gra/graphics_pipeline_sprite_3d.hpp" +#include "../gra/light.hpp" +#include "../gra/log.hpp" +#include "../gra/render_pass.hpp" +#include "../gra/renderer.hpp" +#include "../gra/swapchain.hpp" +#include "../gra/vulkan.hpp" + +namespace BluCat::INT +{ + +extern std::random_device random_seed; +extern std::mt19937 random_number_generator; + +struct Core +{ + static const CommandChain loader; + + Log::Logger log; + + COM::JobQueue job_queue; + std::vector<COM::Worker> workers; + std::vector<std::thread> threads; + + /// Text displayed in the game window. + std::string game_name{"BluCat Game"}; + + /** + * @{ + * This is the ammount of pixel that the games uses when rendering to the + * screen. + */ + uint32_t display_width{800}; + uint32_t display_height{600}; + /// @} + + int game_version_major{0}; + int game_version_minor{1}; + int game_version_patch{0}; + + uint32_t fps{30}; + std::chrono::duration<long long, std::milli> max_frame_duration; + float delta_time; + + SDL_Window *window; + + FT_Library font_library; + + VkSurfaceKHR window_surface; + VkInstance vk_instance; + +#ifdef DEBUG + VkDebugUtilsMessengerEXT vk_callback; +#endif + + // Vulkan devices. + std::vector<BluCat::GRA::Device> vk_devices; + BluCat::GRA::Device *vk_device_with_swapchain; + BluCat::GRA::Swapchain *vk_swapchain; + + BluCat::GRA::Framebuffer *vk_framebuffer; + BluCat::GRA::RenderPass *vk_render_pass; + BluCat::GRA::DescriptorSetLayout *vk_descriptor_set_layout; + BluCat::GRA::GraphicsPipeline3DLayout *vk_graphics_pipeline_3d_layout; + BluCat::GRA::GraphicsPipeline2DSolidLayout + *vk_graphics_pipeline_2d_solid_layout; + BluCat::GRA::GraphicsPipeline2DWiredLayout + *vk_graphics_pipeline_2d_wired_layout; + BluCat::GRA::Light *vk_light; + std::unique_ptr<BluCat::GRA::GraphicsPipeline3D> vk_graphics_pipeline_3d; + std::unique_ptr<BluCat::GRA::GraphicsPipeline3DSkeletal> + vk_graphics_pipeline_3d_skeletal; + std::unique_ptr<BluCat::GRA::GraphicsPipelineSprite3D> + vk_graphics_pipeline_sprite_3d; + std::unique_ptr<BluCat::GRA::GraphicsPipeline2DSolid> + vk_graphics_pipeline_2d_solid; + std::unique_ptr<BluCat::GRA::GraphicsPipeline2DWired> + vk_graphics_pipeline_2d_wired; + + BluCat::GRA::Renderer *vk_renderer; +}; + +extern Core core; + +} + +#endif /* BLU_CAT_INT_CORE_H */ |