From 8acb4a0aad7f4d1b2438010d487489a9641e30cb Mon Sep 17 00:00:00 2001 From: Frederico Linhares Date: Sat, 23 Mar 2024 19:05:26 -0300 Subject: fixt Make skeletal mesh work properly --- glsl/shader_3d_skeletal.vert.glsl | 26 ++++++--- src/core.cpp | 4 +- src/vk/device.cpp | 13 +++++ src/vk/device.hpp | 1 + src/vk/graphics_pipeline_3d_skeletal.cpp | 91 ++++++++++++++++--------------- src/vk/renderer.cpp | 5 ++ test/meshes/cuboid.cgmesh | Bin 0 -> 2772 bytes test/src/mode/demo.rb | 12 +++- 8 files changed, 94 insertions(+), 58 deletions(-) create mode 100644 test/meshes/cuboid.cgmesh diff --git a/glsl/shader_3d_skeletal.vert.glsl b/glsl/shader_3d_skeletal.vert.glsl index 169e1af..c078db9 100644 --- a/glsl/shader_3d_skeletal.vert.glsl +++ b/glsl/shader_3d_skeletal.vert.glsl @@ -55,16 +55,24 @@ main() { vec4 position = vec4(0.0f); vec3 normal = in_normal; - for(int i = 0; i < MAX_NUM_OF_INFLUENCING_BONES; i++) - { - if(in_bone_weights[i] == 0.0) - break; + if(in_bone_weights[0] == 0.0) + { + position = vec4(in_position, 1.0); + normal = mat3(ubo_skeletal_model.base_matrix) * in_normal; + } + else + { + for(int i = 0; i < MAX_NUM_OF_INFLUENCING_BONES; i++) + { + if(in_bone_weights[i] == 0.0) break; - vec4 local_position = ubo_skeletal_model.bone_matrices[in_bone_ids[i]] * - vec4(in_position, 1.0f); - position += local_position * in_bone_weights[i]; - normal = mat3(ubo_skeletal_model.bone_matrices[in_bone_ids[i]]) * normal; - } + vec4 local_position = + ubo_skeletal_model.bone_matrices[in_bone_ids[i]] * + vec4(in_position, 1.0f); + position += local_position * in_bone_weights[i]; + normal = mat3(ubo_skeletal_model.bone_matrices[in_bone_ids[i]]) * normal; + } + } mat4 view_model = ubo_view.view * ubo_skeletal_model.base_matrix; gl_Position = ubo_view.proj * view_model * position; diff --git a/src/core.cpp b/src/core.cpp index 3de9da5..1aeb111 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -837,8 +837,8 @@ const CommandChain cg_sCore::loader{ &unload_vk_graphics_pipeline_2d_wired_layout}, {&load_vk_light, &unload_vk_light}, // TODO: finish skeletal mesh animation - // {&load_vk_graphics_pipeline_3d_skeletal, - // &unload_vk_graphics_pipeline_3d_skeletal}, + {&load_vk_graphics_pipeline_3d_skeletal, + &unload_vk_graphics_pipeline_3d_skeletal}, {&load_vk_graphics_pipeline_3d, &unload_vk_graphics_pipeline_3d}, {&load_vk_graphics_pipeline_sprite_3d, &unload_vk_graphics_pipeline_sprite_3d}, diff --git a/src/vk/device.cpp b/src/vk/device.cpp index d0690d7..78baa53 100644 --- a/src/vk/device.cpp +++ b/src/vk/device.cpp @@ -203,6 +203,12 @@ Device::Device(VkPhysicalDevice vk_physical_device, bool with_swapchain) this->vert3d_shader_module = create_shader_module( this->device, vert3d_shader_module.c_str()); + std::string vert3d_skeletal_shader_module{data_dir}; + vert3d_skeletal_shader_module.append( + "\\glsl\\shader_3d_skeletal.vert.spv"); + this->vert3d_skeletal_shader_module = create_shader_module( + this->device, vert3d_skeletal_shader_module.c_str()); + std::string frag3d_shader_module{data_dir}; frag3d_shader_module.append("\\glsl\\shader_3d.frag.spv"); this->frag3d_shader_module = create_shader_module( @@ -245,6 +251,11 @@ Device::Device(VkPhysicalDevice vk_physical_device, bool with_swapchain) this->vert3d_shader_module = create_shader_module( this->device, vert3d_shader_module.c_str()); + std::string vert3d_skeletal_shader_module{data_dir}; + vert3d_skeletal_shader_module.append("/glsl/shader_3d_skeletal.vert.spv"); + this->vert3d_skeletal_shader_module = create_shader_module( + this->device, vert3d_skeletal_shader_module.c_str()); + std::string frag3d_shader_module{data_dir}; frag3d_shader_module.append("/glsl/shader_3d.frag.spv"); this->frag3d_shader_module = create_shader_module( @@ -308,6 +319,8 @@ Device::~Device() vkDestroyShaderModule( this->device, this->frag_sprite_3d_shader_module, nullptr); vkDestroyShaderModule(this->device, this->vert3d_shader_module, nullptr); + vkDestroyShaderModule( + this->device, this->vert3d_skeletal_shader_module, nullptr); vkDestroyShaderModule(this->device, this->frag3d_shader_module, nullptr); vkDestroyShaderModule( this->device, this->vert2d_solid_shader_module, nullptr); diff --git a/src/vk/device.hpp b/src/vk/device.hpp index 36fc08d..e52a143 100644 --- a/src/vk/device.hpp +++ b/src/vk/device.hpp @@ -40,6 +40,7 @@ public: VkShaderModule vert_sprite_3d_shader_module; VkShaderModule frag_sprite_3d_shader_module; VkShaderModule vert3d_shader_module; + VkShaderModule vert3d_skeletal_shader_module; VkShaderModule frag3d_shader_module; VkShaderModule vert2d_solid_shader_module; VkShaderModule frag2d_solid_shader_module; diff --git a/src/vk/graphics_pipeline_3d_skeletal.cpp b/src/vk/graphics_pipeline_3d_skeletal.cpp index 364b502..b000d89 100644 --- a/src/vk/graphics_pipeline_3d_skeletal.cpp +++ b/src/vk/graphics_pipeline_3d_skeletal.cpp @@ -39,7 +39,7 @@ load_pipeline(void *obj) vert_shader_stage_info.flags = 0; vert_shader_stage_info.stage = VK_SHADER_STAGE_VERTEX_BIT; vert_shader_stage_info.module = - cg_core.vk_device_with_swapchain->vert3d_shader_module; + cg_core.vk_device_with_swapchain->vert3d_skeletal_shader_module; vert_shader_stage_info.pName = "main"; vert_shader_stage_info.pSpecializationInfo = nullptr; @@ -287,51 +287,52 @@ GraphicsPipeline3DSkeletal::draw( vkCmdSetScissor(draw_command_buffer, 0, 1, &vk_scissor); } - // Draw models - for(auto& [skeletal_mesh, instances]: + vkCmdBindPipeline( + draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + this->graphic_pipeline); + + // Draw models + for(auto& [skeletal_mesh, instances]: cg_core.vk_renderer->skeletal_models_to_draw[current_frame]) - { - VkBuffer vertex_buffers[]{skeletal_mesh->vertex_buffer->buffer}; - VkDeviceSize offsets[]{0}; - - vkCmdBindPipeline( - draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - this->graphic_pipeline); - vkCmdBindVertexBuffers( - draw_command_buffer, 0, 1, vertex_buffers, offsets); - vkCmdBindIndexBuffer( - draw_command_buffer, skeletal_mesh->index_buffer->buffer, 0, - VK_INDEX_TYPE_UINT32); - - for(auto &instance: instances) - { // Object matrix. - glm::mat4 translation_matrix{1.0f}; - translation_matrix = glm::translate( - translation_matrix, *instance->position); - glm::mat4 rotation_matrix{glm::toMat4(*instance->orientation)}; - - std::array vk_descriptor_sets{ - cg_core.vk_light->descriptor_sets_world[image_index], - view->descriptor_sets_3d[image_index], - instance->texture->descriptor_sets[image_index], - instance->descriptor_sets[image_index]}; - - vkCmdBindDescriptorSets( - draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - cg_core.vk_graphics_pipeline_3d_layout->pipeline, 0, - vk_descriptor_sets.size(), vk_descriptor_sets.data(), 0, nullptr); - - vkCmdDrawIndexed( - draw_command_buffer, skeletal_mesh->index_count, 1, 0, 0, 0); - - VK::UDOSkeletalModel udo_skeletal_model{}; - instance->tick(cg_core.delta_time); - udo_skeletal_model.base_matrix = translation_matrix * rotation_matrix; - std::copy(instance->bone_transforms.begin(), - instance->bone_transforms.end(), - udo_skeletal_model.bone_matrices); - instance->uniform_buffers[image_index].copy_data(&udo_skeletal_model); - } + { + VkBuffer vertex_buffers[]{skeletal_mesh->vertex_buffer->buffer}; + VkDeviceSize offsets[]{0}; + + vkCmdBindVertexBuffers( + draw_command_buffer, 0, 1, vertex_buffers, offsets); + vkCmdBindIndexBuffer( + draw_command_buffer, skeletal_mesh->index_buffer->buffer, 0, + VK_INDEX_TYPE_UINT32); + + for(auto &instance: instances) + { // Object matrix. + glm::mat4 translation_matrix{1.0f}; + translation_matrix = glm::translate( + translation_matrix, *instance->position); + glm::mat4 rotation_matrix{glm::toMat4(*instance->orientation)}; + + std::array vk_descriptor_sets{ + cg_core.vk_light->descriptor_sets_world[image_index], + view->descriptor_sets_3d[image_index], + instance->descriptor_sets[image_index], + instance->texture->descriptor_sets[image_index]}; + + vkCmdBindDescriptorSets( + draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + cg_core.vk_graphics_pipeline_3d_layout->pipeline, 0, + vk_descriptor_sets.size(), vk_descriptor_sets.data(), 0, nullptr); + + vkCmdDrawIndexed( + draw_command_buffer, skeletal_mesh->index_count, 1, 0, 0, 0); + + VK::UDOSkeletalModel udo_skeletal_model{}; + instance->tick(cg_core.delta_time); + udo_skeletal_model.base_matrix = translation_matrix * rotation_matrix; + std::copy(instance->bone_transforms.begin(), + instance->bone_transforms.end(), + udo_skeletal_model.bone_matrices); + instance->uniform_buffers[image_index].copy_data(&udo_skeletal_model); + } } { // Update view uniform buffers diff --git a/src/vk/renderer.cpp b/src/vk/renderer.cpp index d4e25ba..21e0421 100644 --- a/src/vk/renderer.cpp +++ b/src/vk/renderer.cpp @@ -252,6 +252,11 @@ Renderer::draw() view, draw_command_buffer, cg_core.vk_swapchain->current_frame, image_index); + for(auto &view: this->views_3d) + cg_core.vk_graphics_pipeline_3d_skeletal->draw( + view, draw_command_buffer, cg_core.vk_swapchain->current_frame, + image_index); + vkCmdEndRenderPass(draw_command_buffer); { // 2D render pass diff --git a/test/meshes/cuboid.cgmesh b/test/meshes/cuboid.cgmesh new file mode 100644 index 0000000..ac280ae Binary files /dev/null and b/test/meshes/cuboid.cgmesh differ diff --git a/test/src/mode/demo.rb b/test/src/mode/demo.rb index a821d65..65ea52a 100644 --- a/test/src/mode/demo.rb +++ b/test/src/mode/demo.rb @@ -21,6 +21,7 @@ module Mode def initialize() texture = CandyGear::Texture.from_image("textures/color_texture.qoi"); mesh = CandyGear::StaticMesh.new("meshes/cube.cgmesh"); + skeletal_mesh = CandyGear::SkeletalMesh.new("meshes/cuboid.cgmesh"); font = CandyGear::Font.new("/usr/share/fonts/TTF/HanaMinA.ttf", 30); japanese_text = CandyGear::Texture.from_text( font, "こんにちは世界!"); @@ -66,11 +67,17 @@ module Mode mesh, texture, instance_positions[5], @instances_orientation) ] + skeletal_mesh_position = CandyGear::Vector3D.new(0.0, 0.0, 0.0); + skeletal_mesh_orientation = CandyGear::Orientation3D.new(0.0, 0.0, 0.0); + @skeletal_model = CandyGear::SkeletalModel.new( + skeletal_mesh, texture, skeletal_mesh_position, + skeletal_mesh_orientation); + sprite_3d_position = CandyGear::Vector3D.new(0.0, 0.0, 0.0); @sprite_3d = CandyGear::Sprite3D.new( @sprite, sprite_3d_position, 1.0, 1.0); - @camera_position = CandyGear::Vector3D.new(0.0, 0.0, 0.0); + @camera_position = CandyGear::Vector3D.new(0.0, 0.0, 20.0); @camera_orientation = CandyGear::Orientation3D.new(0.0, 0.0, 0.0); color = CandyGear::Vector3D.new(0.12, 0.12, 0.18); @@ -129,7 +136,8 @@ module Mode @instances_orientation.rotate(0.0, BOX_ROTATION_SPEED, 0.0); @rectangle.draw_rectangle(@view1, @color); @instances.each {_1.draw()}; - @sprite_3d.draw(); + @skeletal_model.draw(); + # @sprite_3d.draw(); end end end -- cgit v1.2.3