打包通过

This commit is contained in:
xsl
2025-09-29 22:53:48 +08:00
parent 55b9c00292
commit 13d3372fc4
2 changed files with 109 additions and 332 deletions
+101 -331
View File
@@ -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<uint8_t> 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<VkBufferImageCopy> 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<uint32_t>(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<float>(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<float
}
}
file.close();
return true;
}
bool TextureLoading::LoadOBJ(const std::string& filename,
@@ -935,6 +612,32 @@ void TextureLoading::setup_descriptor_set()
vkUpdateDescriptorSets(get_device().get_handle(), static_cast<uint32_t>(write_descriptor_sets.size()), write_descriptor_sets.data(), 0, NULL);
}
void TextureLoading::update_texture(Texture& new_texture)
{
std::unique_lock<std::mutex> 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<VkDescriptorSetLayoutBinding> 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<float> 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<const vkb::TouchInputEvent&>(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<std::mutex> lock(mtx_point);
last_update_time = getCurrentTimeMillis();
extendPoint(pos, 68, 54);
@@ -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<vkb::core::BufferC> vertex_buffer;
std::unique_ptr<vkb::core::BufferC> 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;