diff --git a/include/minecraft/data.inc b/include/minecraft/data.inc new file mode 100644 index 0000000..77e9177 --- /dev/null +++ b/include/minecraft/data.inc @@ -0,0 +1,23 @@ +static const short index_buffer_configuration_offsets[] = { + 0, 0, 6, 12, 24, 30, 42, 54, + 72, 78, 90, 102, 120, 132, 150, 168, + 192, 198, 210, 222, 240, 252, 270, 288, + 312, 324, 342, 360, 384, 402, 426, 450, + 480, 486, 498, 510, 528, 540, 558, 576, + 600, 612, 630, 648, 672, 690, 714, 738, + 768, 780, 798, 816, 840, 858, 882, 906, + 936, 954, 978, 1002, 1032, 1056, 1086, 1116, +}; +// generated from +static const struct { + short offset; + short count; +} index_buffer_custom_offsets[] = { + {1152, 3180}, // candle.obj + {4332, 1584}, // custom_mushroom.obj + {5916, 36}, // fence.obj + {5952, 24}, // slab.obj + {5976, 24}, // stair.obj + {6000, 12}, // tall_grass.obj + {6012, 2082}, // wall_torch.obj +}; diff --git a/include/minecraft/vulkan.h b/include/minecraft/vulkan.h index eb73f66..a17e1d3 100644 --- a/include/minecraft/vulkan.h +++ b/include/minecraft/vulkan.h @@ -2,7 +2,9 @@ #include "volk/volk.h" -namespace minecraft { +#include "minecraft/vulkan/per_world.h" + +namespace minecraft::vulkan { struct vulkan { struct { @@ -31,11 +33,14 @@ namespace minecraft { VkShaderModule shaderModule; VkPipeline pipeline; + per_world * worlds; + void init(); void load_vertex_index_buffer(char const * vertex_filename, char const * index_filename); void load_shader(); void create_pipeline(); - void draw(); + void load_worlds(); + void draw(VkCommandBuffer commandBuffer); }; } diff --git a/include/minecraft/vulkan/per_world.h b/include/minecraft/vulkan/per_world.h new file mode 100644 index 0000000..6abe2e2 --- /dev/null +++ b/include/minecraft/vulkan/per_world.h @@ -0,0 +1,27 @@ +#pragma once + +#include "minecraft/world.h" + +namespace minecraft::vulkan { + struct region { + VkBuffer vertexBuffer; + world::instance_cfg_entry * instanceCFG; + }; + + struct per_world { + world::descriptor const * descriptor; + region * regions; // malloc region_count + VkDeviceMemory regionVertexMemory; + entry_table::global_entry_t * entry_table; + int entry_table_length; + + void load_regions(VkDevice device, + VkPhysicalDeviceProperties const & physicalDeviceProperties, + VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties, + world::descriptor const * const descriptor); + void load(VkDevice device, + VkPhysicalDeviceProperties const & physicalDeviceProperties, + VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties, + world::descriptor const * const descriptor); + }; +} diff --git a/include/minecraft/world.h b/include/minecraft/world.h index 3a708ed..6e021a5 100644 --- a/include/minecraft/world.h +++ b/include/minecraft/world.h @@ -26,28 +26,14 @@ namespace minecraft::world { }; // also update index_buffer_custom_offsets in include/minecraft_data.inc - const int custom_block_types = 7; - const int instance_cfg_length = 64 + custom_block_types; + constexpr int custom_block_types = 7; + constexpr int instance_cfg_length = 64 + custom_block_types; struct instance_cfg_entry { int count; int offset; }; - struct region { - unsigned int per_instance_vertex_buffer; - instance_cfg_entry instance_cfg[instance_cfg_length]; - }; - - struct state { - world::descriptor const * descriptor; - world::region * region; // malloc region_count - entry_table::global_entry_t * entry_table; - unsigned int light_uniform_buffer; - int light_count; - int entry_table_length; - }; - extern descriptor const descriptors[]; extern int const descriptors_length; } diff --git a/include/popcount.h b/include/popcount.h new file mode 100644 index 0000000..580e172 --- /dev/null +++ b/include/popcount.h @@ -0,0 +1,6 @@ +#pragma once + +#ifdef _MSC_VER +#include +#define __builtin_popcount __popcnt +#endif diff --git a/src/minecraft/vulkan.cpp b/src/minecraft/vulkan.cpp index dc73d8a..ff24d75 100644 --- a/src/minecraft/vulkan.cpp +++ b/src/minecraft/vulkan.cpp @@ -7,10 +7,18 @@ #include "file.h" #include "check.h" #include "vulkan_helper.h" +#include "new.h" +#include "popcount.h" #include "minecraft/vulkan.h" +#include "minecraft/data.inc" -namespace minecraft { +namespace minecraft::vulkan { + + static inline int popcount(int x) + { + return __builtin_popcount(x); + } void vulkan::init() { @@ -253,19 +261,19 @@ namespace minecraft { .format = VK_FORMAT_R16_SINT, .offset = 8, }, - { // block id + { // data .location = 5, .binding = 1, .format = VK_FORMAT_R16_SINT, .offset = 10, }, - { // block id + { // texture id .location = 6, .binding = 1, .format = VK_FORMAT_R16_SINT, .offset = 12, }, - { // block id + { // special .location = 7, .binding = 1, .format = VK_FORMAT_R16_SINT, @@ -302,12 +310,31 @@ namespace minecraft { VK_CHECK(vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, pipelineCreateInfos, nullptr, &pipeline)); } + ////////////////////////////////////////////////////////////////////// + // load worlds + ////////////////////////////////////////////////////////////////////// + + void vulkan::load_worlds() + { + worlds = NewM(minecraft::world::descriptors_length); + + for (int i = 0; i < minecraft::world::descriptors_length; i++) { + worlds[i].load(device, physicalDeviceProperties, physicalDeviceMemoryProperties, &minecraft::world::descriptors[i]); + } + } + ////////////////////////////////////////////////////////////////////// // draw ////////////////////////////////////////////////////////////////////// - void vulkan::draw() + void vulkan::draw(VkCommandBuffer commandBuffer) { + vkCmdBindIndexBuffer(commandBuffer, vertexIndex.buffer, vertexIndex.indexOffset, VK_INDEX_TYPE_UINT16); + for (int configuration = 1; configuration < 64; configuration++) { + int element_count = 6 * popcount(configuration); + int index_offset = 2 * index_buffer_configuration_offsets[configuration]; + int instance_count = worlds[; + }; } }