添加多模型渲染,添加贴图渲染,添加平行光, 暂时不上传assets
This commit is contained in:
@@ -13,6 +13,7 @@ namespace Engine {
|
||||
|
||||
#define ENGINE_TRACE(...) ::spdlog::trace(__VA_ARGS__)
|
||||
#define ENGINE_INFO(...) ::spdlog::info(__VA_ARGS__)
|
||||
#define ENGINE_DEBUG(...) ::spdlog::debug(__VA_ARGS__)
|
||||
#define ENGINE_WARN(...) ::spdlog::warn(__VA_ARGS__)
|
||||
#define ENGINE_ERROR(...) ::spdlog::error(__VA_ARGS__)
|
||||
#define ENGINE_FATAL(...) ::spdlog::critical(__VA_ARGS__)
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
//
|
||||
// Created by atdunbg on 2026/9/21.
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_STATS_H
|
||||
#define HELLOVULKAN_STATS_H
|
||||
|
||||
|
||||
#include <Engine/Core/Types.h>
|
||||
#include <mutex>
|
||||
|
||||
namespace Engine
|
||||
{
|
||||
class Stats
|
||||
{
|
||||
public:
|
||||
static Stats& Get();
|
||||
|
||||
// ---- Engine 自己管理的 GPU 内存 ----
|
||||
void AddTexture(u64 bytes);
|
||||
void RemoveTexture(u64 bytes);
|
||||
|
||||
void AddMesh(u64 vertexBytes, u64 indexBytes);
|
||||
void RemoveMesh(u64 vertexBytes, u64 indexBytes);
|
||||
|
||||
void AddBuffer(u64 bytes);
|
||||
void RemoveBuffer(u64 bytes);
|
||||
|
||||
void AddMemoryBlock(u64 bytes);
|
||||
void RemoveMemoryBlock(u64 bytes);
|
||||
void AddMemoryUsed(u64 bytes);
|
||||
void RemoveMemoryUsed(u64 bytes);
|
||||
|
||||
// ---- 每帧统计 ----
|
||||
void BeginFrame();
|
||||
void EndFrame();
|
||||
void AddAllocation(u64 bytes);
|
||||
void AddDeallocation(u64 bytes);
|
||||
|
||||
// ---- 采样进程真实内存 ----
|
||||
void SampleProcessMemory();
|
||||
|
||||
// ---- 打印 ----
|
||||
void Print() const;
|
||||
void PrintDetailed() const;
|
||||
void PrintComparison() const;
|
||||
|
||||
private:
|
||||
Stats() = default;
|
||||
|
||||
struct ProcessMemory
|
||||
{
|
||||
u64 VmSize = 0; // /proc/self/status VmSize
|
||||
u64 Rss = 0; // /proc/self/status VmRSS
|
||||
u64 Pss = 0; // smaps_rollup
|
||||
u64 SharedClean = 0;
|
||||
u64 PrivateDirty = 0;
|
||||
u64 PrivateClean = 0;
|
||||
};
|
||||
|
||||
ProcessMemory ReadProcessMemory() const;
|
||||
|
||||
mutable std::mutex m_Mutex;
|
||||
|
||||
// 资源计数
|
||||
u64 m_TextureCount = 0;
|
||||
u64 m_TextureBytes = 0;
|
||||
|
||||
u64 m_MeshCount = 0;
|
||||
u64 m_MeshBytes = 0;
|
||||
|
||||
u64 m_BufferCount = 0;
|
||||
u64 m_BufferBytes = 0;
|
||||
|
||||
// MemoryAllocator
|
||||
u64 m_MemoryBlockBytes = 0;
|
||||
u64 m_MemoryUsedBytes = 0;
|
||||
|
||||
// 每帧
|
||||
u64 m_FrameAllocation = 0;
|
||||
u64 m_FrameDeallocation = 0;
|
||||
u64 m_TotalAllocation = 0;
|
||||
u64 m_TotalDeallocation = 0;
|
||||
|
||||
// 进程快照
|
||||
ProcessMemory m_ProcessMem{};
|
||||
};
|
||||
|
||||
#define STATS Engine::Stats::Get()
|
||||
} // namespace Engine
|
||||
|
||||
#endif //HELLOVULKAN_STATS_H
|
||||
@@ -38,11 +38,26 @@ namespace Engine {
|
||||
// 需要的 Vulkan 扩展(GLFW 提供)
|
||||
static std::vector<const char*> GetRequiredExtensions();
|
||||
|
||||
// 窗口事件
|
||||
void GetFramebufferSize(int& width, int& height) const;
|
||||
bool WasResized() const { return m_FramebufferResized; }
|
||||
void ResetResizedFlag() { m_FramebufferResized = false; }
|
||||
|
||||
// 输入事件系统
|
||||
|
||||
bool IsKeyPressed(int key) const;
|
||||
void GetMouseDelta(float& dx, float& dy);
|
||||
|
||||
|
||||
|
||||
private:
|
||||
GLFWwindow* m_Window = nullptr;
|
||||
u32 m_Width;
|
||||
u32 m_Height;
|
||||
std::string m_Title;
|
||||
|
||||
bool m_FramebufferResized = false;
|
||||
static void FramebufferResizeCallback(GLFWwindow* window, int width, int height);
|
||||
};
|
||||
|
||||
} // namespace Engine
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// Created by atdunbg on 2026/9/21.
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_MATERIAL_H
|
||||
#define HELLOVULKAN_MATERIAL_H
|
||||
|
||||
#include <Engine/Core/Types.h>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace Engine
|
||||
{
|
||||
class Device;
|
||||
class DescriptorManager;
|
||||
class Texture;
|
||||
|
||||
class Material
|
||||
{
|
||||
public:
|
||||
Material(Device& device,
|
||||
DescriptorManager& descriptorManager,
|
||||
vk::DescriptorSetLayout layout,
|
||||
Texture* texture);
|
||||
~Material();
|
||||
|
||||
Material(const Material&) = delete;
|
||||
Material& operator=(const Material&) = delete;
|
||||
|
||||
vk::DescriptorSet GetDescriptorSet() const { return m_DescriptorSet; }
|
||||
Texture* GetTexture() const { return m_Texture; }
|
||||
|
||||
private:
|
||||
Texture* m_Texture = nullptr;
|
||||
vk::DescriptorSet m_DescriptorSet;
|
||||
};
|
||||
} // namespace Engine
|
||||
|
||||
#endif //HELLOVULKAN_MATERIAL_H
|
||||
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// Created by atdunbg on 2026/9/21.
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_MESH_H
|
||||
#define HELLOVULKAN_MESH_H
|
||||
|
||||
|
||||
#include <Engine/Core/Types.h>
|
||||
#include <Engine/Renderer/Vertex.h>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace Engine
|
||||
{
|
||||
class Device;
|
||||
class MemoryAllocator;
|
||||
class Buffer;
|
||||
class Material;
|
||||
|
||||
class Mesh
|
||||
{
|
||||
public:
|
||||
Mesh(Device& device, MemoryAllocator& allocator,
|
||||
const std::vector<Vertex>& vertices,
|
||||
const std::vector<u32>& indices,
|
||||
Scope<Material> material);
|
||||
~Mesh();
|
||||
|
||||
Mesh(const Mesh&) = delete;
|
||||
Mesh& operator=(const Mesh&) = delete;
|
||||
|
||||
void Draw(vk::CommandBuffer cmd) const;
|
||||
|
||||
Material* GetMaterial() const { return m_Material.get(); }
|
||||
u32 GetIndexCount() const { return m_IndexCount; }
|
||||
|
||||
private:
|
||||
Scope<Buffer> m_VertexBuffer;
|
||||
Scope<Buffer> m_IndexBuffer;
|
||||
Scope<Material> m_Material;
|
||||
u32 m_IndexCount = 0;
|
||||
|
||||
u64 m_VertexBytes = 0;
|
||||
u64 m_IndexBytes = 0;
|
||||
};
|
||||
} // namespace Engine
|
||||
|
||||
#endif //HELLOVULKAN_MESH_H
|
||||
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// Created by atdunbg on 2026/9/21.
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_MODEL_H
|
||||
#define HELLOVULKAN_MODEL_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Engine/Core/Types.h>
|
||||
#include <Engine/Renderer/Mesh.h>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
struct aiNode;
|
||||
struct aiMesh;
|
||||
struct aiScene;
|
||||
|
||||
namespace Engine
|
||||
{
|
||||
class Device;
|
||||
class MemoryAllocator;
|
||||
class DescriptorManager;
|
||||
class Texture;
|
||||
|
||||
class Model
|
||||
{
|
||||
public:
|
||||
Model(Device& device, MemoryAllocator& allocator,
|
||||
DescriptorManager& descriptorManager,
|
||||
vk::DescriptorSetLayout textureLayout,
|
||||
const std::string& path);
|
||||
~Model();
|
||||
|
||||
Model(const Model&) = delete;
|
||||
Model& operator=(const Model&) = delete;
|
||||
|
||||
const std::vector<Scope<Mesh>>& GetMeshes() const { return m_Meshes; }
|
||||
|
||||
private:
|
||||
void LoadModel(const std::string& path);
|
||||
void ProcessNode(aiNode* node, const aiScene* scene);
|
||||
Scope<Mesh> ProcessMesh(aiMesh* mesh, const aiScene* scene);
|
||||
|
||||
Texture* GetOrLoadTexture(const std::string& path);
|
||||
|
||||
Device& m_Device;
|
||||
MemoryAllocator& m_Allocator;
|
||||
DescriptorManager& m_DescriptorManager;
|
||||
vk::DescriptorSetLayout m_TextureLayout;
|
||||
|
||||
std::vector<Scope<Mesh>> m_Meshes;
|
||||
std::string m_ModelPath;
|
||||
|
||||
// 纹理缓存:同一路径只加载一次
|
||||
std::unordered_map<std::string, Scope<Texture>> m_TextureCache;
|
||||
Scope<Texture> m_DefaultTexture;
|
||||
};
|
||||
} // namespace Engine
|
||||
|
||||
|
||||
#endif //HELLOVULKAN_MODEL_H
|
||||
@@ -11,6 +11,11 @@
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <chrono>
|
||||
|
||||
#include "Engine/Vulkan/Texture.h"
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "Model.h"
|
||||
|
||||
namespace Engine {
|
||||
|
||||
class Window;
|
||||
@@ -24,6 +29,11 @@ namespace Engine {
|
||||
class Buffer;
|
||||
class UniformBuffer;
|
||||
|
||||
struct Object {
|
||||
glm::mat4 transform = glm::mat4(1.0f);
|
||||
Model* model = nullptr;
|
||||
};
|
||||
|
||||
class Renderer {
|
||||
public:
|
||||
Renderer(Window& window);
|
||||
@@ -49,13 +59,16 @@ namespace Engine {
|
||||
Scope<SyncManager> m_SyncManager;
|
||||
Scope<CommandManager> m_CommandManager;
|
||||
|
||||
Scope<Buffer> m_VertexBuffer;
|
||||
Scope<Buffer> m_IndexBuffer;
|
||||
Scope<Model> m_Model;
|
||||
std::vector<Object> m_Objects;
|
||||
Scope<UniformBuffer> m_UniformBuffer;
|
||||
|
||||
vk::DescriptorSetLayout m_DescriptorSetLayout;
|
||||
vk::PipelineLayout m_PipelineLayout;
|
||||
vk::DescriptorSet m_DescriptorSet;
|
||||
|
||||
vk::DescriptorSetLayout m_UBOSetLayout;
|
||||
vk::DescriptorSet m_UBODescriptorSet;
|
||||
vk::DescriptorSetLayout m_TextureSetLayout;
|
||||
|
||||
|
||||
vk::ShaderEXT m_VertShader;
|
||||
vk::ShaderEXT m_FragShader;
|
||||
@@ -66,6 +79,16 @@ namespace Engine {
|
||||
static constexpr u32 kMaxFramesInFlight = 2;
|
||||
u32 m_CurrentFrame = 0;
|
||||
|
||||
|
||||
// 相机
|
||||
glm::vec3 m_CameraPos = glm::vec3(0.0f, 0.0f, 7.0f);
|
||||
f32 m_CameraYaw = -90.0f; // 朝向 -Z
|
||||
f32 m_CameraPitch = 0.0f;
|
||||
f32 m_CameraSpeed = 2.5f;
|
||||
f32 m_MouseSensitivity = 0.1f;
|
||||
f32 m_DeltaTime = 0.016f;
|
||||
f32 m_LastFrameTime = 0.0f;
|
||||
|
||||
std::chrono::steady_clock::time_point m_StartTime;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// Created by atdunbg on 2026/9/21.
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_VERTEX_H
|
||||
#define HELLOVULKAN_VERTEX_H
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
namespace Engine {
|
||||
|
||||
struct Vertex {
|
||||
glm::vec3 position;
|
||||
glm::vec3 normal;
|
||||
glm::vec2 uv;
|
||||
|
||||
static vk::VertexInputBindingDescription2EXT GetBindingDescription() {
|
||||
vk::VertexInputBindingDescription2EXT binding;
|
||||
binding.setBinding(0)
|
||||
.setStride(sizeof(Vertex))
|
||||
.setInputRate(vk::VertexInputRate::eVertex)
|
||||
.setDivisor(1);
|
||||
return binding;
|
||||
}
|
||||
|
||||
static std::array<vk::VertexInputAttributeDescription2EXT, 3> GetAttributeDescriptions() {
|
||||
std::array<vk::VertexInputAttributeDescription2EXT, 3> attrs;
|
||||
|
||||
attrs[0].setLocation(0)
|
||||
.setBinding(0)
|
||||
.setFormat(vk::Format::eR32G32B32Sfloat)
|
||||
.setOffset(offsetof(Vertex, position));
|
||||
|
||||
attrs[1].setLocation(1)
|
||||
.setBinding(0)
|
||||
.setFormat(vk::Format::eR32G32B32Sfloat)
|
||||
.setOffset(offsetof(Vertex, normal));
|
||||
|
||||
attrs[2].setLocation(2)
|
||||
.setBinding(0)
|
||||
.setFormat(vk::Format::eR32G32Sfloat)
|
||||
.setOffset(offsetof(Vertex, uv));
|
||||
|
||||
return attrs;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Engine
|
||||
|
||||
#endif //HELLOVULKAN_VERTEX_H
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
#include "MemoryAllocator.h"
|
||||
|
||||
namespace Engine {
|
||||
|
||||
class Device;
|
||||
@@ -39,6 +41,9 @@ namespace Engine {
|
||||
|
||||
vk::DeviceSize m_BlockSize; // 所属内存块的总大小
|
||||
|
||||
MemoryAllocator::Allocation m_Allocation;
|
||||
MemoryAllocator& m_Allocator;
|
||||
|
||||
void* m_MappedPtr = nullptr;
|
||||
};
|
||||
|
||||
|
||||
@@ -8,11 +8,18 @@
|
||||
|
||||
#include <Engine/Core/Types.h>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace Engine {
|
||||
|
||||
class Device;
|
||||
|
||||
struct DescriptorBinding {
|
||||
u32 Binding;
|
||||
vk::DescriptorType Type;
|
||||
vk::ShaderStageFlags Stages;
|
||||
};
|
||||
|
||||
class DescriptorManager {
|
||||
public:
|
||||
DescriptorManager(Device& device);
|
||||
@@ -21,18 +28,24 @@ namespace Engine {
|
||||
DescriptorManager(const DescriptorManager&) = delete;
|
||||
DescriptorManager& operator=(const DescriptorManager&) = delete;
|
||||
|
||||
// 创建一个描述符布局:一个 binding,类型是 Uniform Buffer
|
||||
vk::DescriptorSetLayout CreateUniformBufferLayout(u32 binding);
|
||||
vk::DescriptorSetLayout CreateLayout(const std::vector<DescriptorBinding>& bindings);
|
||||
|
||||
vk::PipelineLayout CreatePipelineLayout(vk::DescriptorSetLayout layout);
|
||||
|
||||
// 根据布局分配一个描述符集
|
||||
vk::DescriptorSet AllocateDescriptorSet(vk::DescriptorSetLayout layout);
|
||||
|
||||
// 把 Buffer 绑到描述符集的某个 binding
|
||||
void UpdateUniformBuffer(vk::DescriptorSet set, u32 binding,
|
||||
vk::Buffer buffer, u64 size);
|
||||
|
||||
void UpdateTexture(vk::DescriptorSet set, u32 binding,
|
||||
vk::Sampler sampler, vk::ImageView view);
|
||||
|
||||
// 单个 set layout 的旧接口(保留)
|
||||
vk::PipelineLayout CreatePipelineLayout(vk::DescriptorSetLayout layout,
|
||||
u32 pushConstantSize);
|
||||
|
||||
// 多 set layout 的新接口
|
||||
vk::PipelineLayout CreatePipelineLayout(
|
||||
const std::vector<vk::DescriptorSetLayout>& layouts,
|
||||
u32 pushConstantSize);
|
||||
|
||||
private:
|
||||
Device& m_Device;
|
||||
@@ -43,4 +56,5 @@ namespace Engine {
|
||||
|
||||
} // namespace Engine
|
||||
|
||||
|
||||
#endif //HELLOVULKAN_DESCRIPTORMANAGER_H
|
||||
|
||||
@@ -6,10 +6,14 @@
|
||||
#define HELLOVULKAN_MEMORYALLOCATOR_H
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
#include "Engine/Core/Types.h"
|
||||
|
||||
namespace Engine {
|
||||
|
||||
class Device;
|
||||
@@ -26,23 +30,39 @@ namespace Engine {
|
||||
vk::DeviceMemory Memory;
|
||||
vk::DeviceSize Offset;
|
||||
vk::DeviceSize Size;
|
||||
void* MappedPtr; // HOST_VISIBLE 时才有
|
||||
void* MappedPtr = nullptr;
|
||||
|
||||
// 内部用于 Free
|
||||
u32 BlockIndex = 0;
|
||||
u32 TypeIndex = 0;
|
||||
bool Valid = false;
|
||||
};
|
||||
|
||||
Allocation Allocate(vk::MemoryRequirements reqs, vk::MemoryPropertyFlags props);
|
||||
void Free(const Allocation& alloc);
|
||||
|
||||
void PrintStats() const;
|
||||
|
||||
private:
|
||||
struct FreeRange {
|
||||
vk::DeviceSize Offset;
|
||||
vk::DeviceSize Size;
|
||||
};
|
||||
|
||||
struct Block {
|
||||
vk::DeviceMemory Memory;
|
||||
vk::DeviceSize Size;
|
||||
vk::DeviceSize Used;
|
||||
vk::DeviceSize Used = 0; // bump 分配用
|
||||
void* MappedPtr = nullptr;
|
||||
bool IsMapped = false;
|
||||
std::vector<FreeRange> FreeList; // 已释放的区域
|
||||
};
|
||||
|
||||
Device& m_Device;
|
||||
std::array<std::vector<Block>, VK_MAX_MEMORY_TYPES> m_Blocks;
|
||||
vk::DeviceSize m_DefaultBlockSize = 256ull * 1024 * 1024; // 256 MB
|
||||
std::array<vk::DeviceSize, VK_MAX_MEMORY_TYPES> m_TotalAllocated{};
|
||||
|
||||
vk::DeviceSize GetBlockSize(vk::MemoryPropertyFlags props) const;
|
||||
};
|
||||
|
||||
} // namespace Engine
|
||||
|
||||
@@ -30,14 +30,16 @@ namespace Engine {
|
||||
ShaderManager(const ShaderManager&) = delete;
|
||||
ShaderManager& operator=(const ShaderManager&) = delete;
|
||||
|
||||
// layout 可选:为 nullptr 时不使用描述符
|
||||
// 改成接受 vector
|
||||
ShaderObject CreateFromFile(const std::string& spvPath,
|
||||
vk::ShaderStageFlagBits stage,
|
||||
vk::DescriptorSetLayout layout = nullptr);
|
||||
const std::vector<vk::DescriptorSetLayout>& layouts = {},
|
||||
u32 pushConstantSize = 0);
|
||||
|
||||
ShaderObject CreateFromSPIRV(const std::vector<u32>& spirv,
|
||||
vk::ShaderStageFlagBits stage,
|
||||
vk::DescriptorSetLayout layout = nullptr);
|
||||
const std::vector<vk::DescriptorSetLayout>& layouts = {},
|
||||
u32 pushConstantSize = 0);
|
||||
|
||||
void Destroy(const ShaderObject& shader);
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
//
|
||||
// Created by atdunbg on 2026/9/20.
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_TEXTURE_H
|
||||
#define HELLOVULKAN_TEXTURE_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Engine/Core/Types.h>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <string>
|
||||
|
||||
#include "MemoryAllocator.h"
|
||||
|
||||
namespace Engine {
|
||||
|
||||
class Device;
|
||||
class MemoryAllocator;
|
||||
|
||||
class Texture {
|
||||
public:
|
||||
Texture(Device& device, MemoryAllocator& allocator, const std::string& path);
|
||||
~Texture();
|
||||
|
||||
Texture(const Texture&) = delete;
|
||||
Texture& operator=(const Texture&) = delete;
|
||||
|
||||
vk::Image Get() const { return m_Image; }
|
||||
vk::ImageView GetView() const { return m_View; }
|
||||
u32 GetWidth() const { return m_Width; }
|
||||
u32 GetHeight() const { return m_Height; }
|
||||
|
||||
vk::Sampler GetSampler() const { return m_Sampler; }
|
||||
|
||||
private:
|
||||
Device& m_Device;
|
||||
vk::Image m_Image;
|
||||
vk::ImageView m_View;
|
||||
vk::DeviceMemory m_Memory;
|
||||
|
||||
vk::Sampler m_Sampler;
|
||||
|
||||
|
||||
u32 m_Width = 0;
|
||||
u32 m_Height = 0;
|
||||
|
||||
u64 m_TextureBytes = 0;
|
||||
|
||||
MemoryAllocator::Allocation m_ImageAllocation;
|
||||
MemoryAllocator& m_Allocator;
|
||||
};
|
||||
|
||||
} // namespace Engine
|
||||
|
||||
#endif //HELLOVULKAN_TEXTURE_H
|
||||
Reference in New Issue
Block a user