From 13d3372fc4dc8d1343ebdadda90effb3639b2c83 Mon Sep 17 00:00:00 2001 From: xiangsilian Date: Mon, 29 Sep 2025 22:53:48 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=93=E5=8C=85=E9=80=9A=E8=BF=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/texture_loading/texture_loading.cpp | 432 ++++-------------- samples/api/texture_loading/texture_loading.h | 9 +- 2 files changed, 109 insertions(+), 332 deletions(-) diff --git a/samples/api/texture_loading/texture_loading.cpp b/samples/api/texture_loading/texture_loading.cpp index d2dcac1..99abf41 100644 --- a/samples/api/texture_loading/texture_loading.cpp +++ b/samples/api/texture_loading/texture_loading.cpp @@ -45,6 +45,10 @@ TextureLoading::~TextureLoading() } destroy_texture(texture); + destroy_texture(tex_demo1); + destroy_texture(tex_demo2); + destroy_texture(tex_demo3); + destroy_texture(tex_demo4); destroy_texture(texture_point); destroy_texture(texture_point_line); destroy_texture(cam_text); @@ -189,335 +193,7 @@ std::vector generateSimpleTestImage(int width, int height, int cell_wid return imageData; } -void TextureLoading::load_texture() -{ - // We use the Khronos texture format (https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/) - std::string filename = vkb::fs::path::get(vkb::fs::path::Assets, "textures/metalplate01_rgba.ktx"); - // ktx1 doesn't know whether the content is sRGB or linear, but most tools save in sRGB, so assume that. - VkFormat format = VK_FORMAT_R8G8B8A8_SRGB; - ktxTexture* ktx_texture; - KTX_error_code result; - - result = ktxTexture_CreateFromNamedFile(filename.c_str(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, &ktx_texture); - - if (ktx_texture == nullptr) - { - throw std::runtime_error("Couldn't load texture"); - } - - // assert(!tex2D.empty()); - - texture.width = ktx_texture->baseWidth; - texture.height = ktx_texture->baseHeight; - texture.mip_levels = ktx_texture->numLevels; - - // We prefer using staging to copy the texture data to a device local optimal image - VkBool32 use_staging = true; - - // Only use linear tiling if forced - bool force_linear_tiling = false; - if (force_linear_tiling) - { - // Don't use linear if format is not supported for (linear) shader sampling - // Get device properties for the requested texture format - VkFormatProperties format_properties; - vkGetPhysicalDeviceFormatProperties(get_device().get_gpu().get_handle(), format, &format_properties); - use_staging = !(format_properties.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT); - } - - VkMemoryAllocateInfo memory_allocate_info = vkb::initializers::memory_allocate_info(); - VkMemoryRequirements memory_requirements = {}; - - ktx_uint8_t* ktx_image_data = ktx_texture->pData; - ktx_size_t ktx_texture_size = ktx_texture->dataSize; - - if (use_staging) - { - // Copy data to an optimal tiled image - // This loads the texture data into a host local buffer that is copied to the optimal tiled image on the device - - // Create a host-visible staging buffer that contains the raw image data - // This buffer will be the data source for copying texture data to the optimal tiled image on the device - VkBuffer staging_buffer; - VkDeviceMemory staging_memory; - - VkBufferCreateInfo buffer_create_info = vkb::initializers::buffer_create_info(); - buffer_create_info.size = ktx_texture_size; - // This buffer is used as a transfer source for the buffer copy - buffer_create_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - VK_CHECK(vkCreateBuffer(get_device().get_handle(), &buffer_create_info, nullptr, &staging_buffer)); - - // Get memory requirements for the staging buffer (alignment, memory type bits) - vkGetBufferMemoryRequirements(get_device().get_handle(), staging_buffer, &memory_requirements); - memory_allocate_info.allocationSize = memory_requirements.size; - // Get memory type index for a host visible buffer - memory_allocate_info.memoryTypeIndex = - get_device().get_gpu().get_memory_type(memory_requirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - VK_CHECK(vkAllocateMemory(get_device().get_handle(), &memory_allocate_info, nullptr, &staging_memory)); - VK_CHECK(vkBindBufferMemory(get_device().get_handle(), staging_buffer, staging_memory, 0)); - - // Copy texture data into host local staging buffer - - uint8_t* data; - VK_CHECK(vkMapMemory(get_device().get_handle(), staging_memory, 0, memory_requirements.size, 0, (void**)&data)); - memcpy(data, ktx_image_data, ktx_texture_size); - vkUnmapMemory(get_device().get_handle(), staging_memory); - - // Setup buffer copy regions for each mip level - std::vector buffer_copy_regions; - for (uint32_t i = 0; i < texture.mip_levels; i++) - { - ktx_size_t offset; - KTX_error_code result = ktxTexture_GetImageOffset(ktx_texture, i, 0, 0, &offset); - VkBufferImageCopy buffer_copy_region = {}; - buffer_copy_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - buffer_copy_region.imageSubresource.mipLevel = i; - buffer_copy_region.imageSubresource.baseArrayLayer = 0; - buffer_copy_region.imageSubresource.layerCount = 1; - buffer_copy_region.imageExtent.width = ktx_texture->baseWidth >> i; - buffer_copy_region.imageExtent.height = ktx_texture->baseHeight >> i; - buffer_copy_region.imageExtent.depth = 1; - buffer_copy_region.bufferOffset = offset; - buffer_copy_regions.push_back(buffer_copy_region); - } - - // Create optimal tiled target image on the device - VkImageCreateInfo image_create_info = vkb::initializers::image_create_info(); - image_create_info.imageType = VK_IMAGE_TYPE_2D; - image_create_info.format = format; - image_create_info.mipLevels = texture.mip_levels; - image_create_info.arrayLayers = 1; - image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; - image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; - image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - // Set initial layout of the image to undefined - image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - image_create_info.extent = { texture.width, texture.height, 1 }; - image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; - VK_CHECK(vkCreateImage(get_device().get_handle(), &image_create_info, nullptr, &texture.image)); - - vkGetImageMemoryRequirements(get_device().get_handle(), texture.image, &memory_requirements); - memory_allocate_info.allocationSize = memory_requirements.size; - memory_allocate_info.memoryTypeIndex = get_device().get_gpu().get_memory_type(memory_requirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - VK_CHECK(vkAllocateMemory(get_device().get_handle(), &memory_allocate_info, nullptr, &texture.device_memory)); - VK_CHECK(vkBindImageMemory(get_device().get_handle(), texture.image, texture.device_memory, 0)); - - VkCommandBuffer copy_command = get_device().create_command_buffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); - - // Image memory barriers for the texture image - - // The sub resource range describes the regions of the image that will be transitioned using the memory barriers below - VkImageSubresourceRange subresource_range = {}; - // Image only contains color data - subresource_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - // Start at first mip level - subresource_range.baseMipLevel = 0; - // We will transition on all mip levels - subresource_range.levelCount = texture.mip_levels; - // The 2D texture only has one layer - subresource_range.layerCount = 1; - - // Transition the texture image layout to transfer target, so we can safely copy our buffer data to it. - VkImageMemoryBarrier image_memory_barrier = vkb::initializers::image_memory_barrier(); - - image_memory_barrier.image = texture.image; - image_memory_barrier.subresourceRange = subresource_range; - image_memory_barrier.srcAccessMask = 0; - image_memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; - image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - - // Insert a memory dependency at the proper pipeline stages that will execute the image layout transition - // Source pipeline stage is host write/read execution (VK_PIPELINE_STAGE_HOST_BIT) - // Destination pipeline stage is copy command execution (VK_PIPELINE_STAGE_TRANSFER_BIT) - vkCmdPipelineBarrier( - copy_command, - VK_PIPELINE_STAGE_HOST_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, - 0, nullptr, - 0, nullptr, - 1, &image_memory_barrier); - - // Copy mip levels from staging buffer - vkCmdCopyBufferToImage( - copy_command, - staging_buffer, - texture.image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - static_cast(buffer_copy_regions.size()), - buffer_copy_regions.data()); - - // Once the data has been uploaded we transfer to the texture image to the shader read layout, so it can be sampled from - image_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - // Insert a memory dependency at the proper pipeline stages that will execute the image layout transition - // Source pipeline stage stage is copy command execution (VK_PIPELINE_STAGE_TRANSFER_BIT) - // Destination pipeline stage fragment shader access (VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT) - vkCmdPipelineBarrier( - copy_command, - VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - 0, - 0, nullptr, - 0, nullptr, - 1, &image_memory_barrier); - - // Store current layout for later reuse - texture.image_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - get_device().flush_command_buffer(copy_command, queue, true); - - // Clean up staging resources - vkDestroyBuffer(get_device().get_handle(), staging_buffer, nullptr); - vkFreeMemory(get_device().get_handle(), staging_memory, nullptr); - } - else - { - // Copy data to a linear tiled image - - VkImage mappable_image; - VkDeviceMemory mappable_memory; - - // Load mip map level 0 to linear tiling image - VkImageCreateInfo image_create_info = vkb::initializers::image_create_info(); - image_create_info.imageType = VK_IMAGE_TYPE_2D; - image_create_info.format = format; - image_create_info.mipLevels = 1; - image_create_info.arrayLayers = 1; - image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; - image_create_info.tiling = VK_IMAGE_TILING_LINEAR; - image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; - image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; - image_create_info.extent = { texture.width, texture.height, 1 }; - VK_CHECK(vkCreateImage(get_device().get_handle(), &image_create_info, nullptr, &mappable_image)); - - // Get memory requirements for this image like size and alignment - vkGetImageMemoryRequirements(get_device().get_handle(), mappable_image, &memory_requirements); - // Set memory allocation size to required memory size - memory_allocate_info.allocationSize = memory_requirements.size; - // Get memory type that can be mapped to host memory - memory_allocate_info.memoryTypeIndex = - get_device().get_gpu().get_memory_type(memory_requirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - VK_CHECK(vkAllocateMemory(get_device().get_handle(), &memory_allocate_info, nullptr, &mappable_memory)); - VK_CHECK(vkBindImageMemory(get_device().get_handle(), mappable_image, mappable_memory, 0)); - - // Map image memory - void* data; - ktx_size_t ktx_image_size = ktxTexture_GetImageSize(ktx_texture, 0); - VK_CHECK(vkMapMemory(get_device().get_handle(), mappable_memory, 0, memory_requirements.size, 0, &data)); - // Copy image data of the first mip level into memory - memcpy(data, ktx_image_data, ktx_image_size); - vkUnmapMemory(get_device().get_handle(), mappable_memory); - - // Linear tiled images don't need to be staged and can be directly used as textures - texture.image = mappable_image; - texture.device_memory = mappable_memory; - texture.image_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - // Setup image memory barrier transfer image to shader read layout - VkCommandBuffer copy_command = get_device().create_command_buffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); - - // The sub resource range describes the regions of the image we will be transition - VkImageSubresourceRange subresource_range = {}; - subresource_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - subresource_range.baseMipLevel = 0; - subresource_range.levelCount = 1; - subresource_range.layerCount = 1; - - // Transition the texture image layout to shader read, so it can be sampled from - VkImageMemoryBarrier image_memory_barrier = vkb::initializers::image_memory_barrier(); - ; - image_memory_barrier.image = texture.image; - image_memory_barrier.subresourceRange = subresource_range; - image_memory_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; - image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; - image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - // Insert a memory dependency at the proper pipeline stages that will execute the image layout transition - // Source pipeline stage is host write/read execution (VK_PIPELINE_STAGE_HOST_BIT) - // Destination pipeline stage fragment shader access (VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT) - vkCmdPipelineBarrier( - copy_command, - VK_PIPELINE_STAGE_HOST_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - 0, - 0, nullptr, - 0, nullptr, - 1, &image_memory_barrier); - - get_device().flush_command_buffer(copy_command, queue, true); - } - - // now, the ktx_texture can be destroyed - ktxTexture_Destroy(ktx_texture); - - // Calculate valid filter and mipmap modes - VkFilter filter = VK_FILTER_LINEAR; - VkSamplerMipmapMode mipmap_mode = VK_SAMPLER_MIPMAP_MODE_LINEAR; - vkb::make_filters_valid(get_device().get_gpu().get_handle(), format, &filter, &mipmap_mode); - - // Create a texture sampler - // In Vulkan textures are accessed by samplers - // This separates all the sampling information from the texture data. This means you could have multiple sampler objects for the same texture with different settings - // Note: Similar to the samplers available with OpenGL 3.3 - VkSamplerCreateInfo sampler = vkb::initializers::sampler_create_info(); - sampler.magFilter = filter; - sampler.minFilter = filter; - sampler.mipmapMode = mipmap_mode; - sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; - sampler.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; - sampler.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; - sampler.mipLodBias = 0.0f; - sampler.compareOp = VK_COMPARE_OP_NEVER; - sampler.minLod = 0.0f; - // Set max level-of-detail to mip level count of the texture - sampler.maxLod = (use_staging) ? static_cast(texture.mip_levels) : 0.0f; - // Enable anisotropic filtering - // This feature is optional, so we must check if it's supported on the device - if (get_device().get_gpu().get_features().samplerAnisotropy) - { - // Use max. level of anisotropy for this example - sampler.maxAnisotropy = get_device().get_gpu().get_properties().limits.maxSamplerAnisotropy; - sampler.anisotropyEnable = VK_TRUE; - } - else - { - // The device does not support anisotropic filtering - sampler.maxAnisotropy = 1.0; - sampler.anisotropyEnable = VK_FALSE; - } - sampler.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; - VK_CHECK(vkCreateSampler(get_device().get_handle(), &sampler, nullptr, &texture.sampler)); - - // Create image view - // Textures are not directly accessed by the shaders and - // are abstracted by image views containing additional - // information and sub resource ranges - VkImageViewCreateInfo view = vkb::initializers::image_view_create_info(); - view.viewType = VK_IMAGE_VIEW_TYPE_2D; - view.format = format; - view.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - // The subresource range describes the set of mip levels (and array layers) that can be accessed through this image view - // It's possible to create multiple image views for a single image referring to different (and/or overlapping) ranges of the image - view.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - view.subresourceRange.baseMipLevel = 0; - view.subresourceRange.baseArrayLayer = 0; - view.subresourceRange.layerCount = 1; - // Linear tiling usually won't support mip maps - // Only set mip map count if optimal tiling is used - view.subresourceRange.levelCount = (use_staging) ? texture.mip_levels : 1; - // The view will be based on the texture's image - view.image = texture.image; - VK_CHECK(vkCreateImageView(get_device().get_handle(), &view, nullptr, &texture.view)); -} // Free all Vulkan resources used by a texture object void TextureLoading::destroy_texture(Texture texture) @@ -655,6 +331,7 @@ bool TextureLoading::LoadOBJ_test(const std::string& filename, std::vector(write_descriptor_sets.size()), write_descriptor_sets.data(), 0, NULL); } +void TextureLoading::update_texture(Texture& new_texture) +{ + std::unique_lock lock(mtx); + auto current_texture = &new_texture; + + // 更新descriptor set + VkDescriptorImageInfo image_descriptor{}; + image_descriptor.imageView = current_texture->view; + image_descriptor.sampler = current_texture->sampler; + image_descriptor.imageLayout = current_texture->image_layout; + + VkWriteDescriptorSet write_descriptor_set = + vkb::initializers::write_descriptor_set( + descriptor_set, + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + 1, // 纹理绑定点 + &image_descriptor); + + vkUpdateDescriptorSets( + get_device().get_handle(), + 1, + &write_descriptor_set, + 0, + nullptr); +} + void TextureLoading::setup_descriptor_set_layout_bg() { std::vector set_layout_bindings = @@ -1665,7 +1368,7 @@ bool TextureLoading::prepare(const vkb::ApplicationOptions& options) last_update_time = getCurrentTimeMillis(); - myFloatValue = 1.5f; + myFloatValue = 1.3f; // --- 加载前景纹理 (示例) --- int width = 640; @@ -1699,8 +1402,16 @@ bool TextureLoading::prepare(const vkb::ApplicationOptions& options) processWithVulkan(lineImage.data(), width, height, rowStride, dataSize, texture_point_line); #ifdef _WIN32 const char* filename_test = "assets/DemoHeadBaseColor.png"; + const char* filename_demo1 = "assets/demo1.png"; + const char* filename_demo2 = "assets/demo2.png"; + const char* filename_demo3 = "assets/demo3.png"; + const char* filename_demo4 = "assets/demo4.png"; #else const char* filename_test = "/sdcard/Android/data/com.khronos.vulkan_samples/files/assets/DemoHeadBaseColor.png"; + const char* filename_demo1 = "/sdcard/Android/data/com.khronos.vulkan_samples/files/assets/assets/demo1.png"; + const char* filename_demo2 = "/sdcard/Android/data/com.khronos.vulkan_samples/files/assets/assets/demo2.png"; + const char* filename_demo3 = "/sdcard/Android/data/com.khronos.vulkan_samples/files/assets/assets/demo3.png"; + const char* filename_demo4 = "/sdcard/Android/data/com.khronos.vulkan_samples/files/assets/assets/demo4.png"; #endif // _WIN32 @@ -1708,6 +1419,27 @@ bool TextureLoading::prepare(const vkb::ApplicationOptions& options) unsigned w_t, h_t; unsigned error_t = lodepng::decode(image_test, w_t, h_t, filename_test, LCT_RGBA, 8); processWithVulkan(image_test.data(), w_t, h_t, w_t * 4, image_test.size(), texture); + + image_test.clear(); + w_t, h_t; + error_t = lodepng::decode(image_test, w_t, h_t, filename_demo1, LCT_RGBA, 8); + processWithVulkan(image_test.data(), w_t, h_t, w_t * 4, image_test.size(), tex_demo1); + + image_test.clear(); + w_t, h_t; + error_t = lodepng::decode(image_test, w_t, h_t, filename_demo2, LCT_RGBA, 8); + processWithVulkan(image_test.data(), w_t, h_t, w_t * 4, image_test.size(), tex_demo2); + + image_test.clear(); + w_t, h_t; + error_t = lodepng::decode(image_test, w_t, h_t, filename_demo3, LCT_RGBA, 8); + processWithVulkan(image_test.data(), w_t, h_t, w_t * 4, image_test.size(), tex_demo3); + + image_test.clear(); + w_t, h_t; + error_t = lodepng::decode(image_test, w_t, h_t, filename_demo4, LCT_RGBA, 8); + processWithVulkan(image_test.data(), w_t, h_t, w_t * 4, image_test.size(), tex_demo4); + //load_texture(); prepare_uniform_buffers(); @@ -1758,11 +1490,11 @@ bool TextureLoading::prepare(const vkb::ApplicationOptions& options) #ifdef _WIN32 - LoadOBJ("assets/DemoHead.obj", obj_vertices, obj_indices); + LoadOBJ("assets/face_929.obj", obj_vertices, obj_indices); //std::vector positions_test; //LoadOBJ_test("assets/face.obj", positions_test); #else - LoadOBJ("/sdcard/Android/data/com.khronos.vulkan_samples/files/assets/DemoHead.obj", obj_vertices, obj_indices); + LoadOBJ("/sdcard/Android/data/com.khronos.vulkan_samples/files/assets/face_929.obj", obj_vertices, obj_indices); #endif // _WIN32 @@ -1892,7 +1624,44 @@ void TextureLoading::view_changed() void TextureLoading::input_event(const vkb::InputEvent& input_event) { + ApiVulkanSample::input_event(input_event); + if (input_event.get_source() == vkb::EventSource::Touchscreen || input_event.get_source() == vkb::EventSource::Mouse) + { + const auto& touch_event = static_cast(input_event); + if (touch_event.get_action() == vkb::TouchAction::Down) + { + + } + else if (touch_event.get_action() == vkb::TouchAction::Up) + { + if (cur_texture == "texture") + { + update_texture(tex_demo1); + cur_texture = "tex_demo1"; + } + else if (cur_texture == "tex_demo1") + { + update_texture(tex_demo2); + cur_texture = "tex_demo2"; + } + else if (cur_texture == "tex_demo2") + { + update_texture(tex_demo3); + cur_texture = "tex_demo3"; + } + else if (cur_texture == "tex_demo3") + { + update_texture(tex_demo4); + cur_texture = "tex_demo4"; + } + else if (cur_texture == "tex_demo4") + { + update_texture(texture); + cur_texture = "texture"; + } + } + } } void TextureLoading::on_update_ui_overlay(vkb::Drawer& drawer) @@ -1934,6 +1703,7 @@ void TextureLoading::extendPoint(float* pos, int start_id, int end_id, float rat void TextureLoading::update_face_vertex_buffer(float* pos, int pointCount) { + std::lock_guard lock(mtx_point); last_update_time = getCurrentTimeMillis(); extendPoint(pos, 68, 54); diff --git a/samples/api/texture_loading/texture_loading.h b/samples/api/texture_loading/texture_loading.h index ba94a95..a1d0221 100644 --- a/samples/api/texture_loading/texture_loading.h +++ b/samples/api/texture_loading/texture_loading.h @@ -50,10 +50,18 @@ public: }; Texture texture = { 0 }; + Texture tex_demo1 = { 0 }; + Texture tex_demo2 = { 0 }; + Texture tex_demo3 = { 0 }; + Texture tex_demo4 = { 0 }; Texture texture_point = { 0 }; Texture texture_point_line = { 0 }; Texture cam_text = { 0 }; + std::string cur_texture = "texture"; + // 更新纹理的方法 + void update_texture(Texture& new_texture); + std::unique_ptr vertex_buffer; std::unique_ptr index_buffer; uint32_t index_count; @@ -133,7 +141,6 @@ public: TextureLoading(); ~TextureLoading(); virtual void request_gpu_features(vkb::PhysicalDevice& gpu) override; - void load_texture(); void destroy_texture(Texture texture); void build_command_buffers() override;