From 60afc595823391f32c251a394e7483eacb5410f2 Mon Sep 17 00:00:00 2001 From: Xiang Silian Date: Mon, 22 Sep 2025 18:10:34 +0800 Subject: [PATCH] =?UTF-8?q?=E8=99=9A=E7=BA=BF=E7=9A=84=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/texture_loading/texture_loading.cpp | 135 +++++++++++------- samples/api/texture_loading/texture_loading.h | 23 +++ 2 files changed, 108 insertions(+), 50 deletions(-) diff --git a/samples/api/texture_loading/texture_loading.cpp b/samples/api/texture_loading/texture_loading.cpp index fab1ee0..72a9aae 100644 --- a/samples/api/texture_loading/texture_loading.cpp +++ b/samples/api/texture_loading/texture_loading.cpp @@ -51,6 +51,7 @@ TextureLoading::~TextureLoading() index_buffer.reset(); uniform_buffer_vs.reset(); uniform_buffer_vs_point.reset(); + uniform_buffer_DashParameters.reset(); vertex_buffer_point.reset(); // BufferC 会自动清理 @@ -870,11 +871,18 @@ void TextureLoading::setup_descriptor_set_layout_point_line() VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, 0), - // Binding 1 : Fragment shader image sampler - vkb::initializers::descriptor_set_layout_binding( - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - VK_SHADER_STAGE_FRAGMENT_BIT, - 1) + + // Binding 0 : Vertex shader uniform buffer + vkb::initializers::descriptor_set_layout_binding( + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + VK_SHADER_STAGE_FRAGMENT_BIT, + 1), + + // Binding 1 : Fragment shader image sampler + vkb::initializers::descriptor_set_layout_binding( + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + VK_SHADER_STAGE_FRAGMENT_BIT, + 2) }; VkDescriptorSetLayoutCreateInfo descriptor_layout = @@ -904,6 +912,7 @@ void TextureLoading::setup_descriptor_set_point_line() VK_CHECK(vkAllocateDescriptorSets(get_device().get_handle(), &alloc_info, &descriptor_set_point_line)); VkDescriptorBufferInfo buffer_descriptor = create_descriptor(*uniform_buffer_vs_point); + VkDescriptorBufferInfo buffer_descriptorDashParameters = create_descriptor(*uniform_buffer_DashParameters); VkDescriptorImageInfo image_descriptor; @@ -919,13 +928,20 @@ void TextureLoading::setup_descriptor_set_point_line() VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &buffer_descriptor), - // Binding 1 : Fragment shader texture sampler - // Fragment shader: layout (binding = 1) uniform sampler2D samplerColor; - vkb::initializers::write_descriptor_set( - descriptor_set_point_line, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, // The descriptor set will use a combined image sampler (sampler and image could be split) - 1, // Shader binding point 1 - &image_descriptor) // Pointer to the descriptor image for our texture + + // Binding 1 : Vertex shader uniform buffer + vkb::initializers::write_descriptor_set( + descriptor_set_point_line, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + 1, + &buffer_descriptorDashParameters), + // Binding 2 : Fragment shader texture sampler + // Fragment shader: layout (binding = 1) uniform sampler2D samplerColor; + vkb::initializers::write_descriptor_set( + descriptor_set_point_line, + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, // The descriptor set will use a combined image sampler (sampler and image could be split) + 2, // Shader binding point 1 + &image_descriptor) // Pointer to the descriptor image for our texture }; vkUpdateDescriptorSets(get_device().get_handle(), static_cast(write_descriptor_sets.size()), write_descriptor_sets.data(), 0, NULL); @@ -968,13 +984,32 @@ void TextureLoading::prepare_uniform_buffers_point() VMA_MEMORY_USAGE_CPU_TO_GPU); } +void TextureLoading::prepare_uniform_buffers_DashParameters() +{ + uniform_buffer_DashParameters = std::make_unique(get_device(), + sizeof(_DashParameters), + VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, + VMA_MEMORY_USAGE_CPU_TO_GPU); +} -void global_update_mvp(float fov, float x, float y, float z, float sx, float sy, float sz, float rotx, float roty, float rotz, float camx, float camy, float camz) +void TextureLoading::update_uniform_buffers_DashParameters(float dashSize, float gapSize, float dashOffset, float uAASize, int useWorldSpace) +{ + _DashParameters.dashSize = dashSize; + _DashParameters.gapSize = gapSize; + _DashParameters.dashOffset = dashOffset; + _DashParameters.uAASize = uAASize; + _DashParameters.useWorldSpace = useWorldSpace; + uniform_buffer_DashParameters->convert_and_update(_DashParameters); +} + + +void global_update_mvp(float fov, float x, float y, float z, float sx, float sy, float sz, float rotx, float roty, float rotz, float camx, float camy, float camz, float dashSize, float gapSize, float dashOffset, float uAASize) { TextureLoading* self = TextureLoading::Get(); if (self != nullptr) { self->update_uniform_buffers_point(fov, x, y, z, sx, sy, sz, rotx, roty, rotz, camx, camy, camz); + self->update_uniform_buffers_DashParameters(dashSize, gapSize, dashOffset, uAASize, 0); } } @@ -1281,10 +1316,17 @@ void TextureLoading::prepare_pipeline_point_line() vertex_input_binding_description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; // 顶点输入属性描述 (告诉 Vulkan 每个属性在顶点结构中的位置) - std::array vertex_input_attributes = { - VkVertexInputAttributeDescription{0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(PointVertex, x)}, // 位置 - VkVertexInputAttributeDescription{1, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(PointVertex, r)} // 颜色 - }; + //std::array vertex_input_attributes = { + // VkVertexInputAttributeDescription{0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(PointVertex, x)}, // 位置 + // VkVertexInputAttributeDescription{1, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(PointVertex, r)} // 颜色 + //}; + + std::array vertex_input_attributes{}; + + vertex_input_attributes[0] = { 0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(LineVertex, position) }; + vertex_input_attributes[1] = { 1, 1, VK_FORMAT_R32G32B32_SFLOAT, offsetof(LineVertex, color) }; + vertex_input_attributes[2] = { 2, 2, VK_FORMAT_R32G32B32_SFLOAT, offsetof(LineVertex, lineStart) }; + vertex_input_attributes[3] = { 3, 3, VK_FORMAT_R32G32B32_SFLOAT, offsetof(LineVertex, lineEnd) }; VkPipelineVertexInputStateCreateInfo vertex_input_state{ VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO }; vertex_input_state.vertexBindingDescriptionCount = 1; @@ -1294,7 +1336,7 @@ void TextureLoading::prepare_pipeline_point_line() // 输入装配 (绘制点列表) VkPipelineInputAssemblyStateCreateInfo input_assembly_state{ VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO }; - input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP; + input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST; input_assembly_state.primitiveRestartEnable = VK_FALSE; // 光栅化 @@ -1403,6 +1445,7 @@ bool TextureLoading::prepare(const vkb::ApplicationOptions& options) prepare_uniform_buffers(); prepare_uniform_buffers_point(); + prepare_uniform_buffers_DashParameters(); setup_descriptor_pool(); @@ -2016,44 +2059,36 @@ void TextureLoading::update_point_vertex_buffer_line(float* pos, int count, floa point_count_line = count; + glm::vec3 color = { r,g,b }; + // 1. 准备顶点数据 - std::vector vertices(point_count_line); - // 假设 pos 数组是 [x0,y0,z0,x1,y1,z1,...] - // 为了可视化,这里简单地将坐标映射为颜色 (0-1范围) - //float min_x = std::numeric_limits::max(), max_x = std::numeric_limits::lowest(); - //float min_y = std::numeric_limits::max(), max_y = std::numeric_limits::lowest(); - //float min_z = std::numeric_limits::max(), max_z = std::numeric_limits::lowest(); + std::vector vertices(point_count_line); - //for (int i = 0; i < point_count_line; ++i) { - // float x = pos[i * 3 + 0]; - // float y = pos[i * 3 + 1]; - // float z = pos[i * 3 + 2]; - // min_x = std::min(min_x, x); max_x = std::max(max_x, x); - // min_y = std::min(min_y, y); max_y = std::max(max_y, y); - // min_z = std::min(min_z, z); max_z = std::max(max_z, z); - //} - //float range_x = max_x - min_x; - //float range_y = max_y - min_y; - //float range_z = max_z - min_z; - //if (range_x == 0) range_x = 1.0f; // 防止除零 - //if (range_y == 0) range_y = 1.0f; - //if (range_z == 0) range_z = 1.0f; + for (int i = 0; i < point_count_line - 1; ++i) + { - for (int i = 0; i < point_count_line; ++i) { - vertices[i].x = pos[i * 3 + 0]; - vertices[i].y = pos[i * 3 + 1]; - vertices[i].z = pos[i * 3 + 2]; - // 简单颜色映射 - /*vertices[i].r = (vertices[i].x - min_x) / range_x; - vertices[i].g = (vertices[i].y - min_y) / range_y; - vertices[i].b = (vertices[i].z - min_z) / range_z;*/ - vertices[i].r = r; - vertices[i].g = g; - vertices[i].b = b; + const glm::vec3& start = {pos[i*3], pos[i * 3+1], pos[i * 3+2] }; + const glm::vec3& end = { pos[(i+1) * 3], pos[(i + 1) * 3 + 1], pos[(i + 1) * 3 + 2] }; + + // 线段起点顶点 + vertices.push_back({ + start, // position + color, // color + start, // lineStart + end, // lineEnd + }); + + // 线段终点顶点 + vertices.push_back({ + end, // position + color, // color + start, // lineStart (相同) + end, // lineEnd (相同) + }); } // 2. 更新或创建顶点缓冲区 - VkDeviceSize buffer_size = sizeof(PointVertex) * point_count_line; + VkDeviceSize buffer_size = sizeof(LineVertex) * point_count_line; if (!vertex_buffer_point_line || vertex_buffer_point_line->get_size() < buffer_size) { // 如果缓冲区不存在或太小,则重新创建 diff --git a/samples/api/texture_loading/texture_loading.h b/samples/api/texture_loading/texture_loading.h index 31db1c6..bf930b7 100644 --- a/samples/api/texture_loading/texture_loading.h +++ b/samples/api/texture_loading/texture_loading.h @@ -40,6 +40,13 @@ struct PointVertex { float r, g, b; // 颜色 (可以根据需要修改) }; +struct LineVertex { + glm::vec3 position; // 顶点自身位置 + glm::vec3 color; + glm::vec3 lineStart; // 该顶点所属线段的起点 + glm::vec3 lineEnd; // 该顶点所属线段的终点 +}; + class TextureLoading : public ApiVulkanSample { public: @@ -84,8 +91,22 @@ public: glm::mat4 view; } ubo_vs_point; + // 确保内存布局与GLSL中的std140一致 + struct DashParameters { + alignas(4) float dashSize = 5.0f; // 实线长度(像素) + alignas(4) float gapSize = 3.0f; // 间隙长度(像素) + alignas(4) float dashOffset = 0.0f; // 虚线偏移 + alignas(4) float uAASize = 1.5f; // 抗锯齿过渡区大小 + alignas(4) int useWorldSpace = 0; // 0:屏幕空间,1:世界空间 + // 添加padding以确保大小为16字节的倍数(std140要求) + alignas(8) glm::vec2 padding; // 可选,确保16字节对齐 + }_DashParameters; + + static_assert(sizeof(DashParameters) == 32, "DashParameters size must match GLSL layout"); + std::unique_ptr uniform_buffer_vs; std::unique_ptr uniform_buffer_vs_point; + std::unique_ptr uniform_buffer_DashParameters; //glm::vec3 camear_pos_point = {0, 0, -2.f}; @@ -153,6 +174,8 @@ public: void prepare_uniform_buffers_point(); void update_uniform_buffers_point(float fov, float x, float y, float z, float sx, float sy, float sz, float rotx, float roty, float rotz, float camx, float camy, float camz); + void prepare_uniform_buffers_DashParameters(); + void update_uniform_buffers_DashParameters(float dashSize, float gapSize, float dashOffset, float uAASize, int useWorldSpace); void prepare_pipelines(); void prepare_pipeline_bg();