Files
XCEngine/docs/XCVolumeRenderer渲染引擎架构设计.md

1846 lines
52 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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<LinearAllocator> CreateLinearAllocator(size_t size);
std::unique_ptr<PoolAllocator> CreatePoolAllocator(size_t blockSize, size_t count);
std::unique_ptr<ProxyAllocator> 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<typename T>
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<T> 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<typename... Args>
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<typename Key, typename Value>
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<Pair> pairs;
};
Array<Bucket> 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<typename T = void()>
using Func = std::function<T>;
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<uint32> m_refCount{1};
};
template<typename Func>
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<void()>;
TaskGroup();
~TaskGroup();
uint64 AddTask(std::unique_ptr<ITask> 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<ITask> 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<typename Func>
void ParallelFor(int32 start, int32 end, Func&& func);
void RunOnMainThread(Func&& func);
};
} // namespace Threading
} // namespace XCEngine
```
### 1.5 日志与调试系统
```cpp
namespace XCEngine {
namespace Core {
template<typename... Args>
class Event {
public:
using Callback = std::function<void(Args...)>;
using Listener = std::pair<uint64_t, Callback>;
using Iterator = typename std::vector<Listener>::iterator;
uint64_t Subscribe(Callback callback) {
std::lock_guard<std::mutex> 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<std::mutex> lock(m_mutex);
m_pendingUnsubscribes.push_back(id);
}
void ProcessUnsubscribes() {
std::lock_guard<std::mutex> 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<Listener> listenersCopy;
{
std::lock_guard<std::mutex> 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<std::mutex> 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<Listener> m_listeners;
std::vector<uint64_t> 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<uint32_t> m_refCount;
};
template<typename T>
using Ref = std::shared_ptr<T>;
template<typename T>
using UniqueRef = std::unique_ptr<T>;
} // 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<ILogSink> 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<typename T>
static uint32_t GetTypeId() {
static uint32_t id = Get().Register(typeid(T).name(), static_cast<uint32_t>(-1));
return id;
}
template<typename T>
static uint32_t GetTypeId(const char* typeName) {
static uint32_t id = Get().Register(typeName, static_cast<uint32_t>(-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<uint32_t> m_nextTypeId{0};
std::unordered_map<uint32_t, String> m_idToName;
std::unordered_map<String, uint32_t> 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<typename T>
T* GetComponent() const { return m_gameObject->GetComponent<T>(); }
template<typename T>
std::vector<T*> GetComponents() const { return m_gameObject->GetComponents<T>(); }
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<int>(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<TransformComponent*> 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<typename T>
T* AddComponent();
template<typename T>
void RemoveComponent();
template<typename T>
T* GetComponent() const;
template<typename T>
std::vector<T*> GetComponents() const;
template<typename T>
T* GetComponentInChildren() const;
template<typename T>
std::vector<T*> GetComponentsInChildren() const;
template<typename T>
T* GetComponentInParent() const;
GameObject* GetParent() const;
void SetParent(GameObject* parent);
void SetParent(GameObject* parent, bool worldPositionStays);
const std::vector<GameObject*>& 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<GameObject*> FindObjectsOfType();
static std::vector<GameObject*> FindGameObjectsWithTag(const String& tag);
void Destroy();
private:
void AddComponentInternal(Component* component);
void RemoveComponentInternal(Component* component);
std::vector<std::unique_ptr<Component>> m_components;
std::unordered_map<uint32_t, size_t> m_componentTypeIndex;
std::vector<GameObject*> 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*> GameObject::FindObjectsOfType() {
return SceneManager::Get().GetActiveScene()->FindObjectsOfType<GameObject>();
}
inline std::vector<GameObject*> 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<GameObject*> GetRootGameObjects() const {
std::vector<GameObject*> 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<GameObject*> FindGameObjectsWithTag(const String& tag) const;
template<typename T>
std::vector<T*> 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<void()> 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<std::unique_ptr<GameObject>> 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<void(Scene*)> 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<Scene*> GetAllScenes() const;
void Update(float deltaTime);
void FixedUpdate(float fixedDeltaTime);
void LateUpdate(float deltaTime);
Event<Scene*> OnSceneLoaded;
Event<Scene*> OnSceneUnloaded;
Event<Scene*> OnActiveSceneChanged;
private:
SceneManager() = default;
std::vector<std::unique_ptr<Scene>> m_scenes;
Scene* m_activeScene = nullptr;
Scene* m_loadingScene = nullptr;
std::unordered_map<String, Scene*> m_sceneNameMap;
std::function<void(Scene*)> m_loadCallback;
bool m_loading = false;
};
// GameObject创建辅助类
class GameObjectBuilder {
public:
explicit GameObjectBuilder(const String& name = "GameObject");
~GameObjectBuilder() = default;
template<typename T, typename... Args>
GameObjectBuilder& AddComponent(Args&&... args);
GameObject* Build();
private:
String m_name;
std::vector<std::function<void(GameObject*)>> 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<RenderTexture> CreateTexture(const ResourceDesc& desc) = 0;
virtual std::unique_ptr<RenderBuffer> CreateBuffer(const ResourceDesc& desc, const void* initialData = nullptr) = 0;
virtual std::unique_ptr<Shader> CreateShader(const ShaderDesc& desc) = 0;
virtual std::unique_ptr<Pipeline> CreatePipeline(const PipelineDesc& desc) = 0;
virtual std::unique_ptr<RenderPass> CreateRenderPass(const RenderPassDesc& desc) = 0;
virtual ICommandQueue* GetGraphicsQueue() = 0;
virtual ICommandQueue* GetComputeQueue() = 0;
virtual ICommandQueue* GetCopyQueue() = 0;
virtual std::unique_ptr<IFence> CreateFence() = 0;
virtual IDescriptorHeap* CreateDescriptorHeap(const DescriptorHeapDesc& desc) = 0;
virtual std::unique_ptr<IQueryHeap> 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<IRenderDevice> m_device;
std::unique_ptr<ICommandList> m_mainCommandList;
std::unique_ptr<ISwapChain> m_swapChain;
std::unique_ptr<GBufferPass> m_gBufferPass;
std::unique_ptr<LightingPass> m_lightingPass;
std::unique_ptr<ShadowPass> m_shadowPass;
std::unique_ptr<PostProcessPass> 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<uint64_t>{}(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<IShaderResourceView> m_srv;
std::unique_ptr<IRenderTargetView> m_rtv;
std::unique_ptr<IDepthStencilView> 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<void(RenderGraphPass&, ICommandList&)>;
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<RenderGraphResource>& GetReads() const { return m_reads; }
const std::vector<RenderGraphResource>& GetWrites() const { return m_writes; }
private:
String m_name;
PassType m_type;
std::vector<RenderGraphResource> m_reads;
std::vector<RenderGraphResource> 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<uint32_t> reads;
std::vector<uint32_t> writes;
std::function<void(RenderGraphPass&, ICommandList&)> executeFn;
};
std::vector<ResourceInfo> m_resources;
std::vector<PassInfo> m_passes;
std::unordered_map<String, uint32_t> 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