From 3f7faff423cc8440189f0b90382fef06b408a2e8 Mon Sep 17 00:00:00 2001 From: xiangsilian Date: Sat, 27 Sep 2025 22:17:10 +0800 Subject: [PATCH] asdf --- .../api/texture_loading/texture_loading.cpp | 220 ++++++++++++++++-- samples/api/texture_loading/texture_loading.h | 5 + 2 files changed, 208 insertions(+), 17 deletions(-) diff --git a/samples/api/texture_loading/texture_loading.cpp b/samples/api/texture_loading/texture_loading.cpp index e7e7c6e..a04e60b 100644 --- a/samples/api/texture_loading/texture_loading.cpp +++ b/samples/api/texture_loading/texture_loading.cpp @@ -615,24 +615,171 @@ void TextureLoading::draw() ApiVulkanSample::submit_frame(); } +#include +#include +#include +#include +#include + + +bool TextureLoading::LoadOBJ(const std::string& filename, + std::vector& vertices, + std::vector& indices) { + + // 临时存储从OBJ文件读取的原始数据 + std::vector temp_positions; + std::vector temp_texcoords; + std::vector temp_normals; + + // 用于处理顶点索引 + std::vector vertexIndices, uvIndices, normalIndices; + + std::ifstream file(filename); + if (!file.is_open()) { + return false; + } + + std::string line; + while (std::getline(file, line)) { + // 跳过空行和注释行 + if (line.empty() || line[0] == '#') { + continue; + } + + std::istringstream iss(line); + std::string type; + iss >> type; + + if (type == "v") { // 顶点位置 + float x, y, z; + iss >> x >> y >> z; + temp_positions.push_back(x); + temp_positions.push_back(y); + temp_positions.push_back(z); + } + else if (type == "vt") { // 纹理坐标 + float u, v; + iss >> u >> v; + temp_texcoords.push_back(u); + temp_texcoords.push_back(v); + } + else if (type == "vn") { // 法线 + float nx, ny, nz; + iss >> nx >> ny >> nz; + temp_normals.push_back(nx); + temp_normals.push_back(ny); + temp_normals.push_back(nz); + } + else if (type == "f") { // 面(三角形) + std::string vertex1, vertex2, vertex3; + iss >> vertex1 >> vertex2 >> vertex3; + + // 处理每个顶点的索引 + for (const std::string& vertex : { vertex1, vertex2, vertex3 }) { + std::istringstream viss(vertex); + std::string v, vt, vn; + + // 解析顶点索引格式:v/vt/vn 或 v//vn 或 v + std::getline(viss, v, '/'); + std::getline(viss, vt, '/'); + std::getline(viss, vn, '/'); + + int posIndex = std::stoi(v) - 1; // OBJ索引从1开始 + int texIndex = -1, normIndex = -1; + + if (!vt.empty()) texIndex = std::stoi(vt) - 1; + if (!vn.empty()) normIndex = std::stoi(vn) - 1; + + vertexIndices.push_back(posIndex); + uvIndices.push_back(texIndex); + normalIndices.push_back(normIndex); + } + } + } + file.close(); + + // 创建顶点数据 + vertices.clear(); + indices.clear(); + + // 用于去重的哈希映射 + std::unordered_map vertexMap; + + for (size_t i = 0; i < vertexIndices.size(); i++) { + int posIndex = vertexIndices[i]; + int texIndex = uvIndices[i]; + int normIndex = normalIndices[i]; + + // 创建唯一标识符 + std::string vertexKey = std::to_string(posIndex) + "/" + + std::to_string(texIndex) + "/" + + std::to_string(normIndex); + + // 检查是否已经存在相同的顶点 + if (vertexMap.find(vertexKey) != vertexMap.end()) { + // 使用现有顶点的索引 + indices.push_back(vertexMap[vertexKey]); + } + else { + // 创建新顶点 + TextureLoadingVertexStructure vertex; + + // 设置位置 + if (posIndex >= 0 && posIndex * 3 + 2 < temp_positions.size()) { + vertex.pos[0] = temp_positions[posIndex * 3]; + vertex.pos[1] = temp_positions[posIndex * 3 + 1]; + vertex.pos[2] = temp_positions[posIndex * 3 + 2]; + } + else { + vertex.pos[0] = vertex.pos[1] = vertex.pos[2] = 0.0f; + } + + // 设置纹理坐标 + if (texIndex >= 0 && texIndex * 2 + 1 < temp_texcoords.size()) { + vertex.uv[0] = temp_texcoords[texIndex * 2]; + vertex.uv[1] = temp_texcoords[texIndex * 2 + 1]; + } + else { + vertex.uv[0] = vertex.uv[1] = 0.0f; + } + + // 设置法线 + if (normIndex >= 0 && normIndex * 3 + 2 < temp_normals.size()) { + vertex.normal[0] = temp_normals[normIndex * 3]; + vertex.normal[1] = temp_normals[normIndex * 3 + 1]; + vertex.normal[2] = temp_normals[normIndex * 3 + 2]; + } + else { + vertex.normal[0] = vertex.normal[1] = 0.0f; + vertex.normal[2] = 1.0f; // 默认法线 + } + + // 添加新顶点并记录索引 + uint32_t newIndex = static_cast(vertices.size()); + vertices.push_back(vertex); + indices.push_back(newIndex); + vertexMap[vertexKey] = newIndex; + } + } + + return true; +} + void TextureLoading::generate_quad() { - // Setup vertices for a single uv-mapped quad made from two triangles + //std::vector vertices = //{ - // {{1.0f, 1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f, 1.0f}}, - // {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f, 1.0f}}, - // {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f, 1.0f}}, - // {{1.0f, -1.0f, 0.0f}, {1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}} }; - std::vector vertices = - { - {{0.3f, 0.3f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f, 1.0f}}, - {{-0.3f, 0.3f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f, 1.0f}}, - {{-0.3f, -0.3f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f, 1.0f}}, - {{0.3f, -0.3f, 0.0f}, {1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}} }; + // {{0.3f, 0.3f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f, 1.0f}}, + // {{-0.3f, 0.3f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f, 1.0f}}, + // {{-0.3f, -0.3f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f, 1.0f}}, + // {{0.3f, -0.3f, 0.0f}, {1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}} }; + + //std::vector indices = { 0, 1, 2, 2, 3, 0 }; + + std::vector& vertices = obj_vertices; + std::vector indices = obj_indices; - // Setup indices - std::vector indices = { 0, 1, 2, 2, 3, 0 }; index_count = static_cast(indices.size()); auto vertex_buffer_size = vkb::to_u32(vertices.size() * sizeof(TextureLoadingVertexStructure)); @@ -697,11 +844,20 @@ void TextureLoading::setup_descriptor_set_layout() VK_CHECK(vkCreateDescriptorSetLayout(get_device().get_handle(), &descriptor_layout, nullptr, &descriptor_set_layout)); + VkPipelineLayoutCreateInfo pipeline_layout_create_info = vkb::initializers::pipeline_layout_create_info( &descriptor_set_layout, 1); + VkPushConstantRange pushConstantRange{}; + pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; // 只在片段着色器中使用 + pushConstantRange.offset = 0; + pushConstantRange.size = sizeof(float); // 或者 sizeof(PushConstants) + + pipeline_layout_create_info.pushConstantRangeCount = 1; + pipeline_layout_create_info.pPushConstantRanges = &pushConstantRange; + VK_CHECK(vkCreatePipelineLayout(get_device().get_handle(), &pipeline_layout_create_info, nullptr, &pipeline_layout)); } @@ -1516,8 +1672,6 @@ bool TextureLoading::prepare(const vkb::ApplicationOptions& options) processWithVulkan(image_test.data(), w_t, h_t, w_t * 4, image_test.size(), texture); //load_texture(); - generate_quad(); - prepare_uniform_buffers(); prepare_uniform_buffers_point(); prepare_uniform_buffers_DashParameters(); @@ -1561,9 +1715,27 @@ bool TextureLoading::prepare(const vkb::ApplicationOptions& options) pos[pos_id++] = p["z"]; } update_point_vertex_buffer(pos, rawPoint.size()); - demo1(pos); + update_face_vertex_buffer(pos, rawPoint.size()); + //demo1(pos); #endif + + +#ifdef _WIN32 + if (LoadOBJ("assets/face_with_uv.obj", obj_vertices, obj_indices)) +#else + if (LoadOBJ("/sdcard/Android/data/com.khronos.vulkan_samples/files/assets/face_with_uv.obj", obj_vertices, obj_indices)) +#endif // _WIN32 + { + std::cout << "成功加载OBJ文件" << std::endl; + std::cout << "顶点数量: " << obj_vertices.size() << std::endl; + std::cout << "索引数量: " << obj_indices.size() << std::endl; + } + else { + std::cout << "加载OBJ文件失败" << std::endl; + } + + generate_quad(); prepared = true; update_uniform_buffers_point(47, -0.5, -0.51, 0, 1, 1, 1, 0, 0, 0, 0, 0, -1); @@ -1656,11 +1828,25 @@ void ReceiveFacePoint(float* pos, int pointCount, int width, int height) if(self != nullptr) { TextureLoading::Get()->update_point_vertex_buffer(pos, pointCount); - self->demo1(pos); + TextureLoading::Get()->update_face_vertex_buffer(pos, pointCount); + //self->demo1(pos); } } +void TextureLoading::update_face_vertex_buffer(float* pos, int pointCount) +{ + for (int i = 0; i < pointCount; ++i) + { + obj_vertices[i].pos[0] = pos[i * 3 + 0]; + obj_vertices[i].pos[1] = pos[i * 3 + 1]; + obj_vertices[i].pos[2] = pos[i * 3 + 2]; + } + + auto vertex_buffer_size = vkb::to_u32(obj_vertices.size() * sizeof(TextureLoadingVertexStructure)); + vertex_buffer->update(obj_vertices.data(), vertex_buffer_size); +} + void TextureLoading::processWithVulkan(uint8_t* data, int width, int height, int rowStride, size_t dataSize, Texture& out_texture) { std::unique_lock lock(mtx); diff --git a/samples/api/texture_loading/texture_loading.h b/samples/api/texture_loading/texture_loading.h index 6c936cc..e2e5cb7 100644 --- a/samples/api/texture_loading/texture_loading.h +++ b/samples/api/texture_loading/texture_loading.h @@ -205,9 +205,14 @@ public: public: void update_point_vertex_buffer(float* pos, int pointCount); + void update_face_vertex_buffer(float* pos, int pointCount); void update_point_vertex_buffer_line(float* pos, int pointCount_line, float r, float g, float b, std::vector& vertices); void update_point_vertex_buffer_line_save(std::vector& vertices); + + bool LoadOBJ(const std::string& filename,std::vector& vertices,std::vector& indices); private: + std::vector obj_vertices; + std::vector obj_indices; std::thread workerThread; bool running = false;