# XCVolumeRenderer - 渲染引擎架构设计文档 > **基于 XCGameEngine 架构提取的渲染引擎子集** > 版本: 1.0 > 日期: 2026-03-13 > 目标: 构建专业级实时体积渲染引擎 --- ## 第一章 核心基础层 ### 1.1 数学库 (Math Library) ```cpp namespace XCEngine { namespace Math { struct Vector2 { float x, y; static Vector2 Zero() { return Vector2{0, 0}; } static Vector2 One() { return Vector2{1, 1}; } static Vector2 Up() { return Vector2{0, 1}; } static Vector2 Down() { return Vector2{0, -1}; } static Vector2 Right() { return Vector2{1, 0}; } static Vector2 Left() { return Vector2{-1, 0}; } static float Dot(const Vector2& a, const Vector2& b); static float Cross(const Vector2& a, const Vector2& b); static Vector2 Normalize(const Vector2& v); static float Magnitude(const Vector2& v); static Vector2 Lerp(const Vector2& a, const Vector2& b, float t); }; struct Vector3 { float x, y, z; static Vector3 Zero() { return Vector3{0, 0, 0}; } static Vector3 One() { return Vector3{1, 1, 1}; } static Vector3 Forward() { return Vector3{0, 0, 1}; } static Vector3 Back() { return Vector3{0, 0, -1}; } static Vector3 Up() { return Vector3{0, 1, 0}; } static Vector3 Down() { return Vector3{0, -1, 0}; } static Vector3 Right() { return Vector3{1, 0, 0}; } static Vector3 Left() { return Vector3{-1, 0, 0}; } static Vector3 Cross(const Vector3& a, const Vector3& b); static float Dot(const Vector3& a, const Vector3& b); static Vector3 Normalize(const Vector3& v); static float Magnitude(const Vector3& v); static float SqrMagnitude(const Vector3& v); static Vector3 Lerp(const Vector3& a, const Vector3& b, float t); static Vector3 MoveTowards(const Vector3& current, const Vector3& target, float maxDistance); }; struct Vector4 { float x, y, z, w; }; struct Matrix3x3; struct Matrix4x4; struct Quaternion { float x, y, z, w; static Quaternion Identity() { return Quaternion{0, 0, 0, 1}; } static Quaternion FromAxisAngle(const Vector3& axis, float radians); static Quaternion FromEulerAngles(float pitch, float yaw, float roll); static Quaternion FromRotationMatrix(const Matrix4x4& matrix); static Quaternion Slerp(const Quaternion& a, const Quaternion& b, float t); static Quaternion LookRotation(const Vector3& forward, const Vector3& up = Vector3::Up()); Vector3 ToEulerAngles() const; Matrix4x4 ToMatrix4x4() const; Vector3 operator*(const Vector3& v) const; Quaternion operator*(const Quaternion& other) const; Quaternion Inverse() const; float Dot(const Quaternion& other) const; }; struct Transform { Vector3 position = Vector3::Zero(); Quaternion rotation = Quaternion::Identity(); Vector3 scale = Vector3::One(); Matrix4x4 ToMatrix() const; Transform Inverse() const; Transform operator*(const Transform& other) const; Vector3 TransformPoint(const Vector3& point) const; Vector3 TransformDirection(const Vector3& direction) const; }; enum class Space { Self, World }; struct Color { float r, g, b, a; static Color White() { return Color{1, 1, 1, 1}; } static Color Black() { return Color{0, 0, 0, 1}; } static Color Red() { return Color{1, 0, 0, 1}; } static Color Green() { return Color{0, 1, 0, 1}; } static Color Blue() { return Color{0, 0, 1, 1}; } static Color Yellow() { return Color{1, 1, 0, 1}; } static Color Cyan() { return Color{0, 1, 1, 1}; } static Color Magenta() { return Color{1, 0, 1, 1}; } static Color Clear() { return Color{0, 0, 0, 0}; } static Color Lerp(const Color& a, const Color& b, float t); }; struct Rect { float x, y, width, height; Rect() : x(0), y(0), width(0), height(0) {} Rect(float x, float y, float w, float h) : x(x), y(y), width(w), height(h) {} float GetLeft() const { return x; } float GetRight() const { return x + width; } float GetTop() const { return y; } float GetBottom() const { return y + height; } Vector2 GetPosition() const { return Vector2{x, y}; } Vector2 GetSize() const { return Vector2{width, height}; } bool Contains(float px, float py) const { return px >= x && px < x + width && py >= y && py < y + height; } }; struct RectInt { int32_t x, y, width, height; RectInt() : x(0), y(0), width(0), height(0) {} RectInt(int32_t x, int32_t y, int32_t w, int32_t h) : x(x), y(y), width(w), height(h) {} }; struct Viewport { float x, y, width, height; float minDepth = 0.0f; float maxDepth = 1.0f; Viewport() : x(0), y(0), width(0), height(0) {} Viewport(float x, float y, float w, float h) : x(x), y(y), width(w), height(h) {} }; struct Ray { Vector3 origin; Vector3 direction; Vector3 GetPoint(float t) const; bool Intersects(const Sphere& sphere, float& t) const; bool Intersects(const Box& box, float& t) const; bool Intersects(const Plane& plane, float& t) const; }; struct Sphere { Vector3 center; float radius; }; struct Box { Vector3 center; Vector3 extents; Matrix4x4 transform; }; struct Plane { Vector3 normal; float distance; }; struct Frustum; struct OBB; struct AABB; } // namespace Math } // namespace XCEngine ``` ### 1.2 内存管理 (Memory Management) ```cpp namespace XCEngine { namespace Memory { class IAllocator { public: virtual ~IAllocator() = default; virtual void* Allocate(size_t size, size_t alignment = 0) = 0; virtual void Free(void* ptr) = 0; virtual void* Reallocate(void* ptr, size_t newSize) = 0; virtual size_t GetTotalAllocated() const = 0; virtual size_t GetTotalFreed() const = 0; virtual size_t GetPeakAllocated() const = 0; virtual size_t GetAllocationCount() const = 0; virtual const char* GetName() const = 0; }; class LinearAllocator : public IAllocator { public: explicit LinearAllocator(size_t size, IAllocator* parent = nullptr); ~LinearAllocator(); void* Allocate(size_t size, size_t alignment = 8) override; void Free(void* ptr) override; void Clear(); void* GetMarker() const; void SetMarker(void* marker); private: byte* m_buffer = nullptr; size_t m_capacity = 0; size_t m_offset = 0; IAllocator* m_parent = nullptr; }; class PoolAllocator : public IAllocator { public: PoolAllocator(size_t blockSize, size_t poolSize, size_t alignment = 8); ~PoolAllocator(); void* Allocate(size_t size, size_t alignment = 0) override; void Free(void* ptr) override; bool Contains(void* ptr) const; size_t GetBlockSize() const { return m_blockSize; } size_t GetFreeBlockCount() const; private: struct FreeNode { FreeNode* next; }; size_t m_blockSize = 0; size_t m_alignment = 0; void* m_memory = nullptr; FreeNode* m_freeList = nullptr; size_t m_totalBlocks = 0; size_t m_freeBlocks = 0; }; class ProxyAllocator : public IAllocator { public: ProxyAllocator(IAllocator* underlying, const char* name); void* Allocate(size_t size, size_t alignment = 0) override; void Free(void* ptr) override; void* Reallocate(void* ptr, size_t newSize) override; struct Stats { size_t totalAllocated; size_t totalFreed; size_t peakAllocated; size_t allocationCount; size_t memoryOverhead; }; const Stats& GetStats() const; private: IAllocator* m_underlying; const char* m_name; Stats m_stats; Mutex m_mutex; }; class MemoryManager { public: static MemoryManager& Get(); void Initialize(); void Shutdown(); IAllocator* GetSystemAllocator(); std::unique_ptr CreateLinearAllocator(size_t size); std::unique_ptr CreatePoolAllocator(size_t blockSize, size_t count); std::unique_ptr CreateProxyAllocator(const char* name); void SetTrackAllocations(bool track); void DumpMemoryLeaks(); void GenerateMemoryReport(); }; #define XE_ALLOC(allocator, size, ...) allocator->Allocate(size, ##__VA_ARGS__) #define XE_FREE(allocator, ptr) allocator->Free(ptr) } // namespace Memory } // namespace XCEngine ``` ### 1.3 容器库 (Containers) ```cpp namespace XCEngine { namespace Containers { template class Array { public: using Iterator = T*; using ConstIterator = const T*; Array() = default; explicit Array(size_t capacity); Array(size_t count, const T& value); Array(std::initializer_list init); ~Array(); Array(const Array& other); Array(Array&& other) noexcept; Array& operator=(const Array& other); Array& operator=(Array&& other) noexcept; T& operator[](size_t index); const T& operator[](size_t index) const; T* Data() { return m_data; } const T* Data() const { return m_data; } size_t Size() const { return m_size; } size_t Capacity() const { return m_capacity; } void Clear(); void PushBack(const T& value); void PushBack(T&& value); template T& EmplaceBack(Args&&... args); void PopBack(); private: T* m_data = nullptr; size_t m_size = 0; size_t m_capacity = 0; IAllocator* m_allocator = nullptr; }; class String { public: String(); String(const char* str); String(const char* str, size_t len); ~String(); String& operator+=(const String& other); String& operator+=(const char* str); String Substring(size_t pos, size_t len = npos) const; String Trim() const; String ToLower() const; String ToUpper() const; size_t Find(const char* str, size_t pos = 0) const; bool StartsWith(const String& prefix) const; bool EndsWith(const String& suffix) const; const char* CStr() const { return m_data; } size_t Length() const { return m_length; } private: char* m_data = nullptr; size_t m_length = 0; size_t m_capacity = 0; }; template class HashMap { public: struct Pair { Key first; Value second; }; HashMap() = default; explicit HashMap(size_t bucketCount, IAllocator* allocator = nullptr); Value& operator[](const Key& key); Value* Find(const Key& key); const Value* Find(const Key& key) const; bool Contains(const Key& key) const; bool Insert(const Key& key, const Value& value); bool Erase(const Key& key); void Clear(); size_t Size() const { return m_size; } private: size_t GetBucketIndex(const Key& key) const; void Resize(); struct Bucket { Array pairs; }; Array m_buckets; size_t m_bucketCount = 0; size_t m_size = 0; float m_loadFactor = 0.75f; IAllocator* m_allocator = nullptr; }; } // namespace Containers } // namespace XCEngine ``` ### 1.4 线程系统 (Threading) ```cpp namespace XCEngine { namespace Threading { enum class TaskPriority : uint8_t { Critical = 0, High = 1, Normal = 2, Low = 3, Idle = 4 }; enum class TaskStatus : uint8_t { Pending, Scheduled, Running, Completed, Failed, Canceled }; template using Func = std::function; class ITask { public: virtual ~ITask() = default; virtual void Execute() = 0; virtual void OnComplete() {} virtual void OnCancel() {} TaskPriority GetPriority() const { return m_priority; } TaskStatus GetStatus() const { return m_status; } uint64 GetId() const { return m_id; } protected: TaskPriority m_priority = TaskPriority::Normal; TaskStatus m_status = TaskStatus::Pending; uint64 m_id = 0; std::atomic m_refCount{1}; }; template class LambdaTask : public ITask { public: explicit LambdaTask(Func&& func, TaskPriority priority = TaskPriority::Normal) : m_func(std::move(func)), m_priority(priority) {} void Execute() override { m_func(); } private: Func m_func; }; class TaskGroup { public: using Callback = std::function; TaskGroup(); ~TaskGroup(); uint64 AddTask(std::unique_ptr task); uint64 AddTask(Func&& func, TaskPriority priority = TaskPriority::Normal); void AddDependency(uint64 taskId, uint64 dependsOn); void Wait(); bool WaitFor(std::chrono::milliseconds timeout); void SetCompleteCallback(Callback&& callback); bool IsComplete() const; float GetProgress() const; }; class TaskSystem { public: static TaskSystem& Get(); void Initialize(const TaskSystemConfig& config); void Shutdown(); uint64 Submit(std::unique_ptr task); uint64 Submit(Func&& func, TaskPriority priority = TaskPriority::Normal); TaskGroup* CreateTaskGroup(); void DestroyTaskGroup(TaskGroup* group); void Wait(uint64 taskId); uint32 GetWorkerThreadCount() const; void Update(); template void ParallelFor(int32 start, int32 end, Func&& func); void RunOnMainThread(Func&& func); }; } // namespace Threading } // namespace XCEngine ``` ### 1.5 日志与调试系统 ```cpp namespace XCEngine { namespace Core { template class Event { public: using Callback = std::function; using Listener = std::pair; using Iterator = typename std::vector::iterator; uint64_t Subscribe(Callback callback) { std::lock_guard lock(m_mutex); uint64_t id = ++m_nextId; m_listeners.emplace_back(id, std::move(callback)); return id; } void Unsubscribe(uint64_t id) { std::lock_guard lock(m_mutex); m_pendingUnsubscribes.push_back(id); } void ProcessUnsubscribes() { std::lock_guard lock(m_mutex); for (uint64_t id : m_pendingUnsubscribes) { m_listeners.erase( std::remove_if(m_listeners.begin(), m_listeners.end(), [id](const auto& pair) { return pair.first == id; }), m_listeners.end() ); } m_pendingUnsubscribes.clear(); } void Invoke(Args... args) const { if (!m_pendingUnsubscribes.empty()) { std::vector listenersCopy; { std::lock_guard lock(m_mutex); listenersCopy = m_listeners; m_pendingUnsubscribes.clear(); } for (const auto& [id, callback] : listenersCopy) { callback(args...); } } else { for (const auto& [id, callback] : m_listeners) { callback(args...); } } } void Clear() { std::lock_guard lock(m_mutex); m_listeners.clear(); } Iterator begin() { return m_listeners.begin(); } Iterator end() { return m_listeners.end(); } private: mutable std::mutex m_mutex; std::vector m_listeners; std::vector m_pendingUnsubscribes; uint64_t m_nextId = 0; }; using int8 = int8_t; using int16 = int16_t; using int32 = int32_t; using int64 = int64_t; using uint8 = uint8_t; using uint16 = uint16_t; using uint32 = uint32_t; using uint64 = uint64_t; using byte = uint8_t; class RefCounted { public: RefCounted() : m_refCount(1) {} virtual ~RefCounted() = default; void AddRef() { ++m_refCount; } void Release() { if (--m_refCount == 0) { delete this; } } uint32_t GetRefCount() const { return m_refCount.load(); } protected: std::atomic m_refCount; }; template using Ref = std::shared_ptr; template using UniqueRef = std::unique_ptr; } // namespace Core } // namespace XCEngine namespace XCEngine { namespace Debug { enum class LogLevel : uint8_t { Verbose = 0, Debug = 1, Info = 2, Warning = 3, Error = 4, Fatal = 5 }; enum class LogCategory { General, Rendering, Physics, Audio, Scripting, Network, Memory, Threading, FileSystem, Custom }; struct LogEntry { LogLevel level; LogCategory category; String message; String file; int32 line; String function; uint64 timestamp; uint32 threadId; }; class ILogSink { public: virtual ~ILogSink() = default; virtual void Log(const LogEntry& entry) = 0; virtual void Flush() = 0; }; class ConsoleLogSink : public ILogSink { public: void Log(const LogEntry& entry) override; void Flush() override; void SetColorOutput(bool enable); void SetMinimumLevel(LogLevel level); }; class FileLogSink : public ILogSink { public: explicit FileLogSink(const String& filePath); ~FileLogSink(); void Log(const LogEntry& entry) override; void Flush() override; private: String m_filePath; FileWriter m_writer; }; class Logger { public: static Logger& Get(); void Initialize(); void Shutdown(); void AddSink(std::unique_ptr sink); void RemoveSink(ILogSink* sink); void Log(LogLevel level, LogCategory category, const String& message, const char* file = nullptr, int32 line = 0, const char* function = nullptr); void Verbose(LogCategory category, const String& message); void Debug(LogCategory category, const String& message); void Info(LogCategory category, const String& message); void Warning(LogCategory category, const String& message); void Error(LogCategory category, const String& message); void Fatal(LogCategory category, const String& message); void SetMinimumLevel(LogLevel level); void SetCategoryEnabled(LogCategory category, bool enabled); }; #define XE_LOG(category, level, message) \ XCEngine::Debug::Logger::Get().Log(level, category, message, __FILE__, __LINE__, __FUNCTION__) #define XE_ASSERT(condition, message) \ if (!(condition)) { \ XCEngine::Debug::Logger::Get().Fatal(XCEngine::Debug::LogCategory::General, message); \ __debugbreak(); \ } class Profiler { public: static Profiler& Get(); void Initialize(); void Shutdown(); void BeginProfile(const char* name); void EndProfile(); void BeginFrame(); void EndFrame(); void MarkEvent(const char* name, uint64_t timestamp, uint32_t threadId); void SetMarker(const char* name, uint32_t color); void ExportChromeTracing(const String& filePath); }; #define XE_PROFILE_BEGIN(name) XCEngine::Debug::Profiler::Get().BeginProfile(name) #define XE_PROFILE_END() XCEngine::Debug::Profiler::Get().EndProfile() #define XE_PROFILE_FUNCTION() XE_PROFILE_BEGIN(__FUNCTION__) } // namespace Debug } // namespace XCEngine ``` --- ## 第二章 组件系统 ### 2.1 组件基类 ```cpp namespace XCEngine { class Scene; class GameObject; class TransformComponent; // 组件类型注册(用于运行时类型识别) class ComponentTypeRegistry { public: static ComponentTypeRegistry& Get(); template static uint32_t GetTypeId() { static uint32_t id = Get().Register(typeid(T).name(), static_cast(-1)); return id; } template static uint32_t GetTypeId(const char* typeName) { static uint32_t id = Get().Register(typeName, static_cast(-1)); return id; } static uint32_t GetTypeIdFromName(const char* typeName) { return Get().GetIdByName(typeName); } static const char* GetTypeName(uint32_t typeId) { return Get().GetNameById(typeId); } private: uint32_t Register(const char* typeName, uint32_t suggestedId); uint32_t GetIdByName(const char* typeName) const; const char* GetNameById(uint32_t typeId) const; std::atomic m_nextTypeId{0}; std::unordered_map m_idToName; std::unordered_map m_nameToId; Mutex m_mutex; }; // 组件基类(类Unity MonoBehaviour) class Component { public: Component(); virtual ~Component(); GameObject* gameObject() const { return m_gameObject; } TransformComponent& transform() const { return m_gameObject->GetTransform(); } bool IsEnabled() const { return m_enabled; } void SetEnabled(bool enabled) { m_enabled = enabled; } Scene* GetScene() const; template T* GetComponent() const { return m_gameObject->GetComponent(); } template std::vector GetComponents() const { return m_gameObject->GetComponents(); } virtual void Awake() {} virtual void Start() {} virtual void Update(float deltaTime) {} virtual void FixedUpdate() {} virtual void LateUpdate(float deltaTime) {} virtual void OnDestroy() {} virtual void OnEnable() {} virtual void OnDisable() {} protected: GameObject* m_gameObject = nullptr; bool m_enabled = true; friend class GameObject; }; } // namespace XCEngine ``` ### 2.2 Transform组件 ```cpp namespace XCEngine { class TransformComponent : public Component { public: Vector3 GetLocalPosition() const { return m_localPosition; } void SetLocalPosition(const Vector3& position) { m_localPosition = position; SetDirty(); } Quaternion GetLocalRotation() const { return m_localRotation; } void SetLocalRotation(const Quaternion& rotation) { m_localRotation = rotation; SetDirty(); } Vector3 GetLocalScale() const { return m_localScale; } void SetLocalScale(const Vector3& scale) { m_localScale = scale; SetDirty(); } Vector3 GetPosition() const; void SetPosition(const Vector3& position); Quaternion GetRotation() const; void SetRotation(const Quaternion& rotation); Vector3 GetScale() const; void SetScale(const Vector3& scale); Vector3 GetForward() const { return GetRotation() * Vector3::Forward(); } Vector3 GetRight() const { return GetRotation() * Vector3::Right(); } Vector3 GetUp() const { return GetRotation() * Vector3::Up(); } const Matrix4x4& GetLocalToWorldMatrix() const; Matrix4x4 GetWorldToLocalMatrix() const; TransformComponent* GetParent() const { return m_parent; } void SetParent(TransformComponent* parent, bool worldPositionStays = true); int GetChildCount() const { return static_cast(m_children.size()); } TransformComponent* GetChild(int index) const; TransformComponent* Find(const String& name) const; void DetachChildren(); void SetAsFirstSibling(); void SetAsLastSibling(); void SetSiblingIndex(int index); int GetSiblingIndex() const; void LookAt(const Vector3& target); void LookAt(const Vector3& target, const Vector3& up); void Rotate(const Vector3& eulers); void Rotate(const Vector3& axis, float angle); void Translate(const Vector3& translation); void Translate(const Vector3& translation, Math::Space relativeTo); Vector3 TransformPoint(const Vector3& point) const; Vector3 InverseTransformPoint(const Vector3& point) const; Vector3 TransformDirection(const Vector3& direction) const; Vector3 InverseTransformDirection(const Vector3& direction) const; void SetDirty() { m_dirty = true; } private: Vector3 m_localPosition = Vector3::Zero(); Quaternion m_localRotation = Quaternion::Identity(); Vector3 m_localScale = Vector3::One(); TransformComponent* m_parent = nullptr; std::vector m_children; mutable Matrix4x4 m_localToWorldMatrix; mutable Matrix4x4 m_worldToLocalMatrix; mutable Vector3 m_worldPosition; mutable Quaternion m_worldRotation; mutable Vector3 m_worldScale; mutable bool m_dirty = true; void UpdateWorldTransform() const; friend class GameObject; }; } // namespace XCEngine ``` ### 2.3 GameObject ```cpp namespace XCEngine { class Scene; class GameObject { public: GameObject(); ~GameObject(); struct ConstructParams { String name = "GameObject"; GameObject* parent = nullptr; bool active = true; }; static GameObject* Create(const ConstructParams& params = {}); static void Destroy(GameObject* obj); String name; bool active = true; TransformComponent& GetTransform() { return m_transform; } const TransformComponent& GetTransform() const { return m_transform; } Scene* GetScene() const { return m_scene; } template T* AddComponent(); template void RemoveComponent(); template T* GetComponent() const; template std::vector GetComponents() const; template T* GetComponentInChildren() const; template std::vector GetComponentsInChildren() const; template T* GetComponentInParent() const; GameObject* GetParent() const; void SetParent(GameObject* parent); void SetParent(GameObject* parent, bool worldPositionStays); const std::vector& GetChildren() const; GameObject* GetChild(int index) const; int GetChildCount() const; int GetSiblingIndex() const; void SetSiblingIndex(int index); void SetActive(bool active); bool IsActive() const; bool IsActiveInHierarchy() const; static GameObject* Find(const String& name); static std::vector FindObjectsOfType(); static std::vector FindGameObjectsWithTag(const String& tag); void Destroy(); private: void AddComponentInternal(Component* component); void RemoveComponentInternal(Component* component); std::vector> m_components; std::unordered_map m_componentTypeIndex; std::vector m_children; GameObject* m_parent = nullptr; Scene* m_scene = nullptr; TransformComponent m_transform; void Initialize(const ConstructParams& params); friend class Scene; friend class TransformComponent; }; inline GameObject::GameObject() { } inline GameObject::~GameObject() { for (auto* child : m_children) { delete child; } } inline GameObject* GameObject::Create(const ConstructParams& params) { GameObject* obj = new GameObject(); obj->Initialize(params); return obj; } inline void GameObject::Destroy(GameObject* obj) { delete obj; } inline void GameObject::Initialize(const ConstructParams& params) { name = params.name; active = params.active; m_transform.m_gameObject = this; if (params.parent) { params.parent->m_children.push_back(this); m_parent = params.parent; } } inline void GameObject::Destroy() { if (m_scene) { m_scene->DestroyGameObject(this); } else { delete this; } } inline GameObject* GameObject::Find(const String& name) { return SceneManager::Get().GetActiveScene()->Find(name); } inline std::vector GameObject::FindObjectsOfType() { return SceneManager::Get().GetActiveScene()->FindObjectsOfType(); } inline std::vector GameObject::FindGameObjectsWithTag(const String& tag) { return SceneManager::Get().GetActiveScene()->FindGameObjectsWithTag(tag); } } // namespace XCEngine ``` --- ## 第三章 场景系统 ### 3.1 Scene ```cpp namespace XCEngine { class Scene { public: Scene(); ~Scene(); const String& GetName() const { return m_name; } void SetName(const String& name) { m_name = name; } GameObject* CreateGameObject(const String& name = "GameObject") { GameObject::ConstructParams params; params.name = name; params.parent = nullptr; params.active = true; GameObject* obj = GameObject::Create(params); obj->m_scene = this; AddGameObject(obj); return obj; } GameObject* CreateGameObject(const String& name, GameObject* parent) { GameObject::ConstructParams params; params.name = name; params.parent = parent; params.active = true; GameObject* obj = GameObject::Create(params); obj->m_scene = this; AddGameObject(obj); return obj; } void DestroyGameObject(GameObject* obj); std::vector GetRootGameObjects() const { std::vector roots; roots.reserve(m_gameObjects.size() / 2); for (auto& obj : m_gameObjects) { if (obj->GetParent() == nullptr) { roots.push_back(obj.get()); } } return roots; } GameObject* Find(const String& name) const; GameObject* FindGameObjectWithTag(const String& tag) const; std::vector FindGameObjectsWithTag(const String& tag) const; template std::vector FindObjectsOfType() const; T* FindObjectOfType() const; bool IsActive() const { return m_isActive; } void SetActive(bool active); void Load(const String& filePath); void LoadAsync(const String& filePath, std::function callback); void Save(const String& filePath); void Update(float deltaTime); void FixedUpdate(float fixedDeltaTime); void LateUpdate(float deltaTime); void DebugDraw(); int GetObjectCount() const { return m_gameObjects.size(); } private: void AddGameObject(GameObject* obj); void RemoveGameObject(GameObject* obj); String m_name; std::vector> m_gameObjects; bool m_isActive = true; friend class GameObject; friend class SceneManager; }; class SceneManager { public: static SceneManager& Get(); void Initialize(); void Shutdown(); Scene* CreateScene(const String& name); void LoadScene(const String& filePath); void LoadSceneAsync(const String& filePath, std::function callback); void UnloadScene(Scene* scene); void UnloadScene(const String& sceneName); void SetActiveScene(Scene* scene); void SetActiveScene(const String& sceneName); Scene* GetActiveScene() const; Scene* GetScene(const String& name) const; std::vector GetAllScenes() const; void Update(float deltaTime); void FixedUpdate(float fixedDeltaTime); void LateUpdate(float deltaTime); Event OnSceneLoaded; Event OnSceneUnloaded; Event OnActiveSceneChanged; private: SceneManager() = default; std::vector> m_scenes; Scene* m_activeScene = nullptr; Scene* m_loadingScene = nullptr; std::unordered_map m_sceneNameMap; std::function m_loadCallback; bool m_loading = false; }; // GameObject创建辅助类 class GameObjectBuilder { public: explicit GameObjectBuilder(const String& name = "GameObject"); ~GameObjectBuilder() = default; template GameObjectBuilder& AddComponent(Args&&... args); GameObject* Build(); private: String m_name; std::vector> m_components; }; } // namespace XCEngine ``` --- ## 第四章 渲染系统 ### 4.1 渲染抽象层 ```cpp namespace XCEngine { namespace Rendering { enum class ResourceState { Undefined, RenderTarget, DepthStencil, ShaderResource, UnorderedAccess, CopySrc, CopyDst, Present }; struct ResourceDesc { ResourceType type; uint32_t width = 1; uint32_t height = 1; uint32_t depth = 1; uint32_t mipLevels = 1; uint32_t arraySize = 1; Format format = Format::Unknown; SampleCount sampleCount = SampleCount::Count1; ResourceState initialState = ResourceState::Undefined; bool cpuAccessible = false; bool randomAccess = false; MemoryUsage memoryUsage = MemoryUsage::Default; String name; }; class IRenderDevice { public: virtual ~IRenderDevice() = default; virtual const char* GetApiName() const = 0; virtual const char* GetDriverVersion() const = 0; virtual uint64_t GetDeviceId() const = 0; virtual uint64_t GetVendorId() const = 0; virtual bool SupportsRaytracing() const = 0; virtual bool SupportsMeshShaders() const = 0; virtual bool SupportsVariableRateShading() const = 0; virtual bool SupportsSamplerFeedback() const = 0; virtual uint32_t GetMaxTextureSize() const = 0; virtual uint32_t GetMaxUBOSize() const = 0; virtual uint32_t GetMaxMSAA() const = 0; virtual std::unique_ptr CreateTexture(const ResourceDesc& desc) = 0; virtual std::unique_ptr CreateBuffer(const ResourceDesc& desc, const void* initialData = nullptr) = 0; virtual std::unique_ptr CreateShader(const ShaderDesc& desc) = 0; virtual std::unique_ptr CreatePipeline(const PipelineDesc& desc) = 0; virtual std::unique_ptr CreateRenderPass(const RenderPassDesc& desc) = 0; virtual ICommandQueue* GetGraphicsQueue() = 0; virtual ICommandQueue* GetComputeQueue() = 0; virtual ICommandQueue* GetCopyQueue() = 0; virtual std::unique_ptr CreateFence() = 0; virtual IDescriptorHeap* CreateDescriptorHeap(const DescriptorHeapDesc& desc) = 0; virtual std::unique_ptr CreateQueryHeap(const QueryHeapDesc& desc) = 0; }; class ICommandList { public: virtual ~ICommandList() = default; virtual void TransitionBarrier(const IResource* resource, ResourceState newState) = 0; virtual void UAVBarrier(const IResource* resource) = 0; virtual void FlushBarriers() = 0; virtual void SetPipeline(const IPipeline* pipeline) = 0; virtual void SetVertexBuffer(uint32_t slot, const IBuffer* buffer, uint64_t offset = 0) = 0; virtual void SetIndexBuffer(const IBuffer* buffer, IndexType indexType, uint64_t offset = 0) = 0; virtual void SetConstantBuffer(uint32_t slot, const IBuffer* buffer, uint64_t offset = 0) = 0; virtual void SetShaderResource(uint32_t slot, const IResource* resource) = 0; virtual void SetSampler(uint32_t slot, const ISampler* sampler) = 0; virtual void Draw(uint32_t vertexCount, uint32_t firstVertex = 0) = 0; virtual void DrawIndexed(uint32_t indexCount, uint32_t firstIndex = 0, int32_t baseVertex = 0) = 0; virtual void DrawInstanced(uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t firstVertex = 0, uint32_t firstInstance = 0) = 0; virtual void DrawIndexedInstanced(uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t firstIndex = 0, int32_t baseVertex = 0, uint32_t firstInstance = 0) = 0; virtual void Dispatch(uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ) = 0; virtual void BuildAccelerationStructure(const RaytracingBuildDesc& desc) = 0; virtual void SetRaytracingPipeline(const IPipeline* pipeline) = 0; virtual void DispatchRays(const DispatchRaysDesc& desc) = 0; virtual void BeginRenderPass(const RenderPassBeginDesc& desc) = 0; virtual void EndRenderPass() = 0; virtual void CopyResource(IResource* dst, const IResource* src) = 0; virtual void CopyBuffer(IBuffer* dst, uint64_t dstOffset, const IBuffer* src, uint64_t srcOffset, uint64_t size) = 0; virtual void BeginQuery(IQueryHeap* heap, uint32_t index) = 0; virtual void EndQuery(IQueryHeap* heap, uint32_t index) = 0; virtual void SetMarker(const char* name, uint32_t color) = 0; virtual void BeginEvent(const char* name, uint32_t color) = 0; virtual void EndEvent() = 0; }; class RenderContext { public: class GBufferPass; class LightingPass; class ShadowPass; class PostProcessPass; static RenderContext* Create(const RenderContextDesc& desc); static void Destroy(RenderContext* context); static RenderContext* GetMain(); void Initialize(const RenderContextDesc& desc); void Shutdown(); IRenderDevice* GetDevice() { return m_device.get(); } void BeginFrame(); void EndFrame(); ICommandList* GetMainCommandList() { return m_mainCommandList.get(); } void SetRenderTarget(const RenderTarget& target); void SetViewport(const Viewport& viewport); void SetScissorRect(const Rect& rect); void RenderScene(const SceneRenderDesc& desc); void ApplyPostProcessing(const PostProcessDesc& desc); void CaptureFrame(const String& filePath); void ToggleDebugView(); private: std::unique_ptr m_device; std::unique_ptr m_mainCommandList; std::unique_ptr m_swapChain; std::unique_ptr m_gBufferPass; std::unique_ptr m_lightingPass; std::unique_ptr m_shadowPass; std::unique_ptr m_postProcessPass; uint32_t m_frameIndex = 0; uint64_t m_frameCount = 0; static RenderContext* s_mainContext; }; // 资源类型 enum class ResourceType { Unknown, Mesh, Texture, Material, Shader, Audio, Animation, Skeleton, Font, Prefab, Scene, Script, PhysicsMaterial, NavMesh, Video, Custom }; // 资源GUID struct ResourceGUID { static constexpr uint64_t INVALID = 0; uint64_t value = INVALID; bool IsValid() const { return value != INVALID; } bool operator==(const ResourceGUID& other) const { return value == other.value; } bool operator!=(const ResourceGUID& other) const { return value != other.value; } String ToString() const; static ResourceGUID FromString(const String& str); struct Hash { size_t operator()(const ResourceGUID& guid) const { return std::hash{}(guid.value); } }; }; // 资源基类 class IResource { public: virtual ~IResource() = default; virtual ResourceType GetType() const = 0; virtual const String& GetName() const = 0; virtual ResourceGUID GetGUID() const = 0; virtual bool IsLoaded() const = 0; virtual bool IsLoading() const = 0; virtual float GetLoadingProgress() const = 0; virtual void AddRef() = 0; virtual void Release() = 0; virtual uint32_t GetRefCount() const = 0; virtual void Unload() = 0; }; class RenderTexture : public IResource { public: uint32_t GetWidth() const { return m_width; } uint32_t GetHeight() const { return m_height; } uint32_t GetMipLevels() const { return m_mipLevels; } Format GetFormat() const { return m_format; } void* GetNativeHandle() const { return m_nativeHandle; } IShaderResourceView* GetSRV() { return m_srv.get(); } IRenderTargetView* GetRTV() { return m_rtv.get(); } IDepthStencilView* GetDSV() { return m_dsv.get(); } void* Map(); void Unmap(); private: uint32_t m_width, m_height; uint32_t m_mipLevels; Format m_format; void* m_nativeHandle = nullptr; std::unique_ptr m_srv; std::unique_ptr m_rtv; std::unique_ptr m_dsv; }; class RenderBuffer : public IResource { public: uint64_t GetSize() const { return m_size; } BufferUsage GetUsage() const { return m_usage; } void* GetNativeHandle() const { return m_nativeHandle; } void SetData(const void* data, uint64_t size, uint64_t offset = 0); void* Map(); void Unmap(); private: uint64_t m_size; BufferUsage m_usage; void* m_nativeHandle = nullptr; }; } // namespace Rendering } // namespace XCEngine ``` ### 4.2 渲染图 (Render Graph) ```cpp namespace XCEngine { namespace Rendering { class RenderGraphResource { public: RenderGraphResource() = default; RenderGraphResource(const String& name); const String& GetName() const { return m_name; } uint32_t GetIndex() const { return m_index; } bool IsValid() const { return m_index != UINT32_MAX; } operator bool() const { return IsValid(); } private: String m_name; uint32_t m_index = UINT32_MAX; friend class RenderGraph; }; class RenderGraphPass { public: using ExecuteFn = std::function; RenderGraphPass(const String& name, PassType type); RenderGraphResource Read(const String& resourceName); RenderGraphResource Write(const String& resourceName); RenderGraphResource ReadWrite(const String& resourceName, ResourceState initialState, ResourceState finalState); void Execute(ExecuteFn&& fn); void Execute() const; void SetDebugColor(const Color& color); const String& GetName() const { return m_name; } PassType GetType() const { return m_type; } const std::vector& GetReads() const { return m_reads; } const std::vector& GetWrites() const { return m_writes; } private: String m_name; PassType m_type; std::vector m_reads; std::vector m_writes; ExecuteFn m_executeFn; Color m_debugColor; friend class RenderGraph; }; class RenderGraph { public: RenderGraph(); ~RenderGraph(); RenderGraphResource CreateTexture(const String& name, const TextureDesc& desc); RenderGraphResource CreateBuffer(const String& name, const BufferDesc& desc); RenderGraphPass& AddPass(const String& name, PassType type); void Build(); void Execute(ICommandList* commandList); void SetName(const String& name); void Print() const; void ExportToDot(const String& filePath) const; void Clear(); private: void Compile(); void Validate(); void SortPasses(); void AllocateResources(); struct ResourceInfo { String name; ResourceDesc desc; ResourceState currentState; uint32_t firstPassWrite = UINT32_MAX; uint32_t lastPassRead = UINT32_MAX; bool imported = false; }; struct PassInfo { String name; PassType type; std::vector reads; std::vector writes; std::function executeFn; }; std::vector m_resources; std::vector m_passes; std::unordered_map m_resourceIndex; bool m_built = false; }; } // namespace Rendering } // namespace XCEngine ``` ### 4.3 相机组件 ```cpp namespace XCEngine { class CameraComponent : public Component { public: void Awake() override; void Start() override; void Update(float deltaTime) override; enum class ProjectionType : uint8_t { Perspective, Orthographic }; void SetProjectionType(ProjectionType type) { m_projectionType = type; } ProjectionType GetProjectionType() const { return m_projectionType; } void SetFieldOfView(float fov) { m_fieldOfView = fov; } float GetFieldOfView() const { return m_fieldOfView; } void SetOrthographicSize(float size) { m_orthographicSize = size; } float GetOrthographicSize() const { return m_orthographicSize; } void SetNearClipPlane(float near) { m_nearPlane = near; } float GetNearClipPlane() const { return m_nearPlane; } void SetFarClipPlane(float far) { m_farPlane = far; } float GetFarClipPlane() const { return m_farPlane; } void SetViewport(const Rect& rect) { m_viewportRect = rect; } const Rect& GetViewport() const { return m_viewportRect; } void SetCullingMask(int32_t mask) { m_cullingMask = mask; } int32_t GetCullingMask() const { return m_cullingMask; } void SetDepth(float depth) { m_depth = depth; } float GetDepth() const { return m_depth; } Matrix4x4 GetViewMatrix() const; Matrix4x4 GetProjectionMatrix() const; Matrix4x4 GetViewProjectionMatrix() const; Vector3 ScreenToWorldPoint(const Vector3& screenPoint) const; Vector3 WorldToScreenPoint(const Vector3& worldPoint) const; Ray ScreenPointToRay(const Vector2& screenPoint) const; Frustum& GetFrustum() { return m_frustum; } private: ProjectionType m_projectionType = ProjectionType::Perspective; float m_fieldOfView = 60.0f; float m_orthographicSize = 5.0f; float m_nearPlane = 0.1f; float m_farPlane = 1000.0f; float m_aspectRatio = 16.0f / 9.0f; Rect m_viewportRect = Rect(0, 0, 1, 1); float m_depth = 0.0f; int32_t m_cullingMask = -1; Frustum m_frustum; }; } // namespace XCEngine ``` ### 4.4 光照组件 ```cpp namespace XCEngine { class RenderLightComponent : public Component { public: void Awake() override; void Update(float deltaTime) override; enum class LightType : uint8_t { Directional, Point, Spot, Area }; void SetLightType(LightType type) { m_type = type; } LightType GetLightType() const { return m_type; } void SetColor(const Vector3& color) { m_color = color; } Vector3 GetColor() const { return m_color; } void SetIntensity(float intensity) { m_intensity = intensity; } float GetIntensity() const { return m_intensity; } void SetRange(float range) { m_range = range; } float GetRange() const { return m_range; } void SetSpotAngle(float angle) { m_spotAngle = angle; } float GetSpotAngle() const { return m_spotAngle; } void SetCastShadows(bool cast) { m_castShadows = cast; } bool GetCastShadows() const { return m_castShadows; } void SetShadowResolution(uint32_t resolution) { m_shadowResolution = resolution; } uint32_t GetShadowResolution() const { return m_shadowResolution; } void SetCullingMask(int32_t mask) { m_cullingMask = mask; } int32_t GetCullingMask() const { return m_cullingMask; } private: LightType m_type = LightType::Point; Vector3 m_color = Vector3::One(); float m_intensity = 1.0f; float m_range = 10.0f; float m_spotAngle = 30.0f; float m_penumbraAngle = 5.0f; bool m_castShadows = true; uint32_t m_shadowResolution = 1024; float m_shadowBias = 0.005f; float m_normalOffsetBias = 0.001f; float m_nearPlane = 0.1f; int32_t m_cullingMask = -1; float m_intensityVariation = 0.0f; ResourceGUID m_cookieTextureGuid = ResourceGUID::Invalid; float m_cookieSize = 5.0f; }; } // namespace XCEngine ``` ### 4.5 渲染网格组件 ```cpp namespace XCEngine { class RenderMeshComponent : public Component { public: void Awake() override; void Start() override; void Update(float deltaTime) override; ResourceGUID GetMesh() const { return m_meshGuid; } void SetMesh(const ResourceGUID& guid); ResourceGUID GetMaterial() const { return m_materialGuid; } void SetMaterial(const ResourceGUID& guid); bool GetCastShadows() const { return m_castShadows; } void SetCastShadows(bool cast) { m_castShadows = cast; } bool GetReceiveShadows() const { return m_receiveShadows; } void SetReceiveShadows(bool receive) { m_receiveShadows = receive; } private: ResourceGUID m_meshGuid; ResourceGUID m_materialGuid; bool m_castShadows = true; bool m_receiveShadows = true; }; } // namespace XCEngine ``` --- ## 第五章 目录结构 ``` XCVolumeRenderer/ ├── engine/ # 引擎核心库(静态库) │ ├── CMakeLists.txt │ ├── include/ │ │ └── XCGameEngine/ │ │ ├── Core/ # 核心基础 │ │ │ ├── Assert.h │ │ │ ├── Event.h │ │ │ ├── TypeTraits.h │ │ │ └── UniquePtr.h │ │ ├── Math/ # 数学库 │ │ │ ├── Vector2.h │ │ │ ├── Vector3.h │ │ │ ├── Vector4.h │ │ │ ├── Matrix3.h │ │ │ ├── Matrix4.h │ │ │ ├── Quaternion.h │ │ │ ├── Transform.h │ │ │ ├── Color.h │ │ │ ├── Ray.h │ │ │ ├── Plane.h │ │ │ ├── Sphere.h │ │ │ ├── Box.h │ │ │ └── Frustum.h │ │ ├── Containers/ # 容器 │ │ │ ├── Array.h │ │ │ ├── String.h │ │ │ └── HashMap.h │ │ ├── Memory/ # 内存管理 │ │ │ ├── Allocator.h │ │ │ ├── LinearAllocator.h │ │ │ ├── PoolAllocator.h │ │ │ └── ProxyAllocator.h │ │ ├── Threading/ # 线程 │ │ │ ├── Thread.h │ │ │ ├── Mutex.h │ │ │ ├── TaskSystem.h │ │ │ └── Atomic.h │ │ ├── Debug/ # 调试 │ │ │ ├── Logger.h │ │ │ └── Profiler.h │ │ ├── Components/ # 组件系统 │ │ │ ├── GameObject.h │ │ │ ├── Component.h │ │ │ ├── TransformComponent.h │ │ │ ├── RenderMeshComponent.h │ │ │ ├── RenderLightComponent.h │ │ │ └── CameraComponent.h │ │ ├── Scene/ # 场景系统 │ │ │ ├── Scene.h │ │ │ └── SceneManager.h │ │ ├── Renderer/ # 渲染系统 │ │ │ ├── Device.h │ │ │ ├── Context.h │ │ │ ├── SwapChain.h │ │ │ ├── Buffer.h │ │ │ ├── Texture.h │ │ │ ├── Shader.h │ │ │ ├── Pipeline.h │ │ │ ├── RenderPass.h │ │ │ ├── CommandList.h │ │ │ ├── RenderGraph.h │ │ │ └── RenderModule.h │ │ └── XCGameEngine.h # 主头文件 │ ├── src/ │ │ ├── Core/ │ │ ├── Math/ │ │ ├── Components/ │ │ ├── Scene/ │ │ ├── Renderer/ │ │ └── ... │ └── third_party/ │ ├── stb/ │ └── json/ │ ├── runtime/ # 游戏运行时(独立可执行文件) │ ├── CMakeLists.txt │ ├── src/ │ │ ├── GameMain.cpp │ │ └── EntryPoint.cpp │ └── resources/ │ ├── tools/ # 工具链 │ ├── ShaderCompiler/ # 着色器编译器 │ └── BuildTool/ # 构建打包工具 │ ├── content/ # 资源内容 │ ├── Assets/ │ │ ├── Scenes/ │ │ ├── Materials/ │ │ ├── Meshes/ │ │ ├── Textures/ │ │ └── Shaders/ │ └── Library/ │ └── docs/ # 文档 ``` --- ## 附录:待扩展功能 以下功能将在后续迭代中添加: 1. **物理系统** - RigidBodyComponent, ColliderComponent, PhysicsWorld 2. **音频系统** - AudioSourceComponent, AudioListenerComponent, AudioEngine 3. **动画系统** - AnimatorComponent, AnimationClip, Skeleton 4. **粒子系统** - ParticleSystemComponent, GPUParticles 5. **UI系统** - CanvasComponent, ImageComponent, TextComponent, ButtonComponent 6. **网络系统** - NetworkIdentityComponent, NetworkTransformComponent 7. **完整编辑器** - HierarchyPanel, InspectorPanel, SceneViewPanel