Files
Vulkan-Samples/samples/api/hpp_terrain_tessellation/hpp_terrain_tessellation.h
T
2025-09-04 10:54:47 +08:00

183 lines
5.1 KiB
C++

/* Copyright (c) 2022-2024, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 the "License";
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Dynamic terrain tessellation, using vulkan.hpp
*/
#pragma once
#include <hpp_api_vulkan_sample.h>
#include <geometry/frustum.h>
class HPPTerrainTessellation : public HPPApiVulkanSample
{
public:
HPPTerrainTessellation();
~HPPTerrainTessellation();
private:
struct SkySphere
{
vk::DescriptorSet descriptor_set;
vk::DescriptorSetLayout descriptor_set_layout;
vk::PipelineLayout pipeline_layout;
vk::Pipeline pipeline;
std::unique_ptr<vkb::scene_graph::components::HPPSubMesh> geometry;
HPPTexture texture;
glm::mat4 transform;
std::unique_ptr<vkb::core::BufferCpp> transform_buffer;
void destroy(vk::Device device)
{
device.destroyPipeline(pipeline);
device.destroyPipelineLayout(pipeline_layout);
device.destroyDescriptorSetLayout(descriptor_set_layout);
// the descriptor_set is implicitly freed by destroying its DescriptorPool
device.destroySampler(texture.sampler);
}
};
struct Statistics
{
bool query_supported = false;
vk::QueryPool query_pool;
std::array<uint64_t, 2> results = {{0}};
void destroy(vk::Device device)
{
if (query_supported)
{
device.destroyQueryPool(query_pool);
}
}
};
// Shared values for tessellation control and evaluation stages
struct Tessellation
{
glm::mat4 projection;
glm::mat4 modelview;
glm::vec4 light_pos = glm::vec4(-48.0f, -40.0f, 46.0f, 0.0f);
glm::vec4 frustum_planes[6];
float displacement_factor = 32.0f;
float tessellation_factor = 0.75f;
glm::vec2 viewport_dim;
// Desired size of tessellated quad patch edge
float tessellated_edge_size = 20.0f;
};
struct Terrain
{
vk::DescriptorSet descriptor_set;
vk::DescriptorSetLayout descriptor_set_layout;
vk::PipelineLayout pipeline_layout;
vk::Pipeline pipeline;
std::unique_ptr<vkb::core::BufferCpp> vertices;
std::unique_ptr<vkb::core::BufferCpp> indices;
uint32_t index_count;
HPPTexture height_map;
HPPTexture terrain_array;
bool sampler_anisotropy_supported = false;
std::vector<vk::PipelineShaderStageCreateInfo> shader_stages;
Tessellation tessellation;
std::unique_ptr<vkb::core::BufferCpp> tessellation_buffer;
bool tessellation_enabled = true;
void destroy(vk::Device device)
{
device.destroyPipeline(pipeline);
device.destroyPipelineLayout(pipeline_layout);
device.destroyDescriptorSetLayout(descriptor_set_layout);
// the descriptor_set is implicitly freed by destroying its DescriptorPool
device.destroySampler(height_map.sampler);
device.destroySampler(terrain_array.sampler);
}
};
struct Vertex
{
glm::vec3 pos;
glm::vec3 normal;
glm::vec2 uv;
};
struct Wireframe
{
bool supported = false;
bool enabled = false;
vk::Pipeline pipeline;
void destroy(vk::Device device)
{
device.destroyPipeline(pipeline);
}
};
private:
// from vkb::Application
bool prepare(const vkb::ApplicationOptions &options) override;
// from vkb::VulkanSample
void request_gpu_features(vkb::core::HPPPhysicalDevice &gpu) override;
// from HPPApiVulkanSample
void build_command_buffers() override;
void on_update_ui_overlay(vkb::Drawer &drawer) override;
void render(float delta_time) override;
void view_changed() override;
vk::DescriptorPool create_descriptor_pool();
vk::DescriptorSetLayout create_sky_sphere_descriptor_set_layout();
vk::Pipeline create_sky_sphere_pipeline();
vk::DescriptorSetLayout create_terrain_descriptor_set_layout();
vk::Pipeline create_terrain_pipeline(vk::PolygonMode polygon_mode);
void draw();
void generate_terrain();
void load_assets();
void prepare_camera();
void prepare_sky_sphere();
void prepare_statistics();
void prepare_terrain();
void prepare_uniform_buffers();
void prepare_wireframe();
void update_uniform_buffers();
void update_sky_sphere_descriptor_set();
void update_terrain_descriptor_set();
private:
vkb::Frustum frustum; // View frustum passed to tessellation control shader for culling
SkySphere sky_sphere;
Statistics statistics;
Terrain terrain;
Wireframe wireframe;
};
std::unique_ptr<vkb::Application> create_hpp_terrain_tessellation();