虚线的代码完成。

This commit is contained in:
xsl
2025-09-22 18:10:34 +08:00
parent 12b26a0555
commit 60afc59582
2 changed files with 108 additions and 50 deletions
+76 -41
View File
@@ -51,6 +51,7 @@ TextureLoading::~TextureLoading()
index_buffer.reset(); index_buffer.reset();
uniform_buffer_vs.reset(); uniform_buffer_vs.reset();
uniform_buffer_vs_point.reset(); uniform_buffer_vs_point.reset();
uniform_buffer_DashParameters.reset();
vertex_buffer_point.reset(); // BufferC 会自动清理 vertex_buffer_point.reset(); // BufferC 会自动清理
@@ -870,11 +871,18 @@ void TextureLoading::setup_descriptor_set_layout_point_line()
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_VERTEX_BIT,
0), 0),
// 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 // Binding 1 : Fragment shader image sampler
vkb::initializers::descriptor_set_layout_binding( vkb::initializers::descriptor_set_layout_binding(
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
VK_SHADER_STAGE_FRAGMENT_BIT, VK_SHADER_STAGE_FRAGMENT_BIT,
1) 2)
}; };
VkDescriptorSetLayoutCreateInfo descriptor_layout = 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)); VK_CHECK(vkAllocateDescriptorSets(get_device().get_handle(), &alloc_info, &descriptor_set_point_line));
VkDescriptorBufferInfo buffer_descriptor = create_descriptor(*uniform_buffer_vs_point); VkDescriptorBufferInfo buffer_descriptor = create_descriptor(*uniform_buffer_vs_point);
VkDescriptorBufferInfo buffer_descriptorDashParameters = create_descriptor(*uniform_buffer_DashParameters);
VkDescriptorImageInfo image_descriptor; VkDescriptorImageInfo image_descriptor;
@@ -919,12 +928,19 @@ void TextureLoading::setup_descriptor_set_point_line()
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
0, 0,
&buffer_descriptor), &buffer_descriptor),
// Binding 1 : Fragment shader texture sampler
// 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; // Fragment shader: layout (binding = 1) uniform sampler2D samplerColor;
vkb::initializers::write_descriptor_set( vkb::initializers::write_descriptor_set(
descriptor_set_point_line, 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) 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 2, // Shader binding point 1
&image_descriptor) // Pointer to the descriptor image for our texture &image_descriptor) // Pointer to the descriptor image for our texture
}; };
@@ -968,13 +984,32 @@ void TextureLoading::prepare_uniform_buffers_point()
VMA_MEMORY_USAGE_CPU_TO_GPU); VMA_MEMORY_USAGE_CPU_TO_GPU);
} }
void TextureLoading::prepare_uniform_buffers_DashParameters()
{
uniform_buffer_DashParameters = std::make_unique<vkb::core::BufferC>(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(); TextureLoading* self = TextureLoading::Get();
if (self != nullptr) 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_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; vertex_input_binding_description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
// 顶点输入属性描述 (告诉 Vulkan 每个属性在顶点结构中的位置) // 顶点输入属性描述 (告诉 Vulkan 每个属性在顶点结构中的位置)
std::array<VkVertexInputAttributeDescription, 2> vertex_input_attributes = { //std::array<VkVertexInputAttributeDescription, 2> vertex_input_attributes = {
VkVertexInputAttributeDescription{0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(PointVertex, x)}, // 位置 // VkVertexInputAttributeDescription{0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(PointVertex, x)}, // 位置
VkVertexInputAttributeDescription{1, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(PointVertex, r)} // 颜色 // VkVertexInputAttributeDescription{1, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(PointVertex, r)} // 颜色
}; //};
std::array<VkVertexInputAttributeDescription, 5> 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 }; VkPipelineVertexInputStateCreateInfo vertex_input_state{ VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO };
vertex_input_state.vertexBindingDescriptionCount = 1; 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 }; 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; input_assembly_state.primitiveRestartEnable = VK_FALSE;
// 光栅化 // 光栅化
@@ -1403,6 +1445,7 @@ bool TextureLoading::prepare(const vkb::ApplicationOptions& options)
prepare_uniform_buffers(); prepare_uniform_buffers();
prepare_uniform_buffers_point(); prepare_uniform_buffers_point();
prepare_uniform_buffers_DashParameters();
setup_descriptor_pool(); setup_descriptor_pool();
@@ -2016,44 +2059,36 @@ void TextureLoading::update_point_vertex_buffer_line(float* pos, int count, floa
point_count_line = count; point_count_line = count;
glm::vec3 color = { r,g,b };
// 1. 准备顶点数据 // 1. 准备顶点数据
std::vector<PointVertex> vertices(point_count_line); std::vector<LineVertex> vertices(point_count_line);
// 假设 pos 数组是 [x0,y0,z0,x1,y1,z1,...]
// 为了可视化,这里简单地将坐标映射为颜色 (0-1范围)
//float min_x = std::numeric_limits<float>::max(), max_x = std::numeric_limits<float>::lowest();
//float min_y = std::numeric_limits<float>::max(), max_y = std::numeric_limits<float>::lowest();
//float min_z = std::numeric_limits<float>::max(), max_z = std::numeric_limits<float>::lowest();
//for (int i = 0; i < point_count_line; ++i) { for (int i = 0; i < point_count_line - 1; ++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; ++i) { const glm::vec3& start = {pos[i*3], pos[i * 3+1], pos[i * 3+2] };
vertices[i].x = pos[i * 3 + 0]; const glm::vec3& end = { pos[(i+1) * 3], pos[(i + 1) * 3 + 1], pos[(i + 1) * 3 + 2] };
vertices[i].y = pos[i * 3 + 1];
vertices[i].z = pos[i * 3 + 2]; // 线段起点顶点
// 简单颜色映射 vertices.push_back({
/*vertices[i].r = (vertices[i].x - min_x) / range_x; start, // position
vertices[i].g = (vertices[i].y - min_y) / range_y; color, // color
vertices[i].b = (vertices[i].z - min_z) / range_z;*/ start, // lineStart
vertices[i].r = r; end, // lineEnd
vertices[i].g = g; });
vertices[i].b = b;
// 线段终点顶点
vertices.push_back({
end, // position
color, // color
start, // lineStart (相同)
end, // lineEnd (相同)
});
} }
// 2. 更新或创建顶点缓冲区 // 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) { if (!vertex_buffer_point_line || vertex_buffer_point_line->get_size() < buffer_size) {
// 如果缓冲区不存在或太小,则重新创建 // 如果缓冲区不存在或太小,则重新创建
@@ -40,6 +40,13 @@ struct PointVertex {
float r, g, b; // 颜色 (可以根据需要修改) float r, g, b; // 颜色 (可以根据需要修改)
}; };
struct LineVertex {
glm::vec3 position; // 顶点自身位置
glm::vec3 color;
glm::vec3 lineStart; // 该顶点所属线段的起点
glm::vec3 lineEnd; // 该顶点所属线段的终点
};
class TextureLoading : public ApiVulkanSample class TextureLoading : public ApiVulkanSample
{ {
public: public:
@@ -84,8 +91,22 @@ public:
glm::mat4 view; glm::mat4 view;
} ubo_vs_point; } 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<vkb::core::BufferC> uniform_buffer_vs; std::unique_ptr<vkb::core::BufferC> uniform_buffer_vs;
std::unique_ptr<vkb::core::BufferC> uniform_buffer_vs_point; std::unique_ptr<vkb::core::BufferC> uniform_buffer_vs_point;
std::unique_ptr<vkb::core::BufferC> uniform_buffer_DashParameters;
//glm::vec3 camear_pos_point = {0, 0, -2.f}; //glm::vec3 camear_pos_point = {0, 0, -2.f};
@@ -153,6 +174,8 @@ public:
void prepare_uniform_buffers_point(); 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 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_pipelines();
void prepare_pipeline_bg(); void prepare_pipeline_bg();