1326 lines
34 KiB
Markdown
1326 lines
34 KiB
Markdown
# Unity风格RHI架构设计方案
|
||
|
||
## 一、概述
|
||
|
||
### 1.1 设计目标
|
||
|
||
本设计方案参考Unity引擎的渲染架构,设计一套跨平台的渲染抽象层(Graphics API),使其能够同时支持DirectX 12、Vulkan、OpenGL等多种图形API。
|
||
|
||
Unity的核心设计理念:
|
||
- **分层架构**:上层应用与底层API完全解耦
|
||
- **CommandBuffer**:使用命令缓冲模式,延迟执行渲染命令
|
||
- **资源绑定抽象**:统一的资源绑定接口,隐藏不同API的差异
|
||
|
||
### 1.2 架构概览
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ 应用层 / 渲染管线 │
|
||
│ (RenderPass, DrawCall, Material) │
|
||
├─────────────────────────────────────────────────────────┤
|
||
│ CommandBuffer │
|
||
│ (统一的渲染命令缓冲,类似Unity) │
|
||
├─────────────────────────────────────────────────────────┤
|
||
│ Graphics API │
|
||
│ ┌────────────────┬────────────────┬────────────────┐ │
|
||
│ │ GraphicsAPI │ GraphicsAPI │ GraphicsAPI │ │
|
||
│ │ (D3D12) │ (Vulkan) │ (OpenGL) │ │
|
||
│ └────────────────┴────────────────┴────────────────┘ │
|
||
└─────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 二、核心接口设计
|
||
|
||
### 2.1 CommandBuffer(命令缓冲)
|
||
|
||
Unity的CommandBuffer是渲染命令的核心抽象,本设计采用相同概念。
|
||
|
||
```cpp
|
||
namespace XCEngine {
|
||
namespace Graphics {
|
||
|
||
// 前向声明
|
||
class ComputeBuffer;
|
||
class ComputeShader;
|
||
class Material;
|
||
class Mesh;
|
||
class ComputeProgram;
|
||
class RenderTexture;
|
||
class Texture;
|
||
class Shader;
|
||
|
||
// ==================== 基本类型定义 ====================
|
||
|
||
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) {}
|
||
};
|
||
|
||
using byte = uint8_t;
|
||
|
||
// 命令缓冲类
|
||
class CommandBuffer {
|
||
public:
|
||
CommandBuffer();
|
||
~CommandBuffer();
|
||
|
||
// ==================== 状态设置 ====================
|
||
|
||
// 设置渲染管线/程序
|
||
void SetRenderProgram(ComputeProgram* program);
|
||
void SetMaterial(Material* material);
|
||
|
||
// 设置纹理
|
||
void SetTexture(Shader* shader, const char* name, Texture* texture);
|
||
void SetTexture(Shader* shader, int texureID, Texture* texture);
|
||
void SetTextures(Shader* shader, const char* name, std::vector<Texture*>& textures);
|
||
|
||
// 设置矩阵/向量参数
|
||
void SetMatrix(Shader* shader, const char* name, const float4x4& matrix);
|
||
void SetMatrixArray(Shader* shader, const char* name, const float4x4* matrices, int count);
|
||
void SetVector(Shader* shader, const char* name, const float4& vector);
|
||
void SetFloat(Shader* shader, const char* name, float value);
|
||
void SetInt(Shader* shader, const char* name, int value);
|
||
|
||
// 全局参数(所有Shader可见)
|
||
void SetGlobalMatrix(const char* name, const float4x4& matrix);
|
||
void SetGlobalVector(const char* name, const float4& vector);
|
||
void SetGlobalFloat(const char* name, float value);
|
||
void SetGlobalTexture(const char* name, Texture* texture);
|
||
|
||
// ==================== 渲染目标 ====================
|
||
|
||
// 设置渲染目标
|
||
void SetRenderTarget(RenderTexture* color, RenderTexture* depth);
|
||
void SetRenderTarget(RenderTexture* color);
|
||
void SetRenderTarget(RenderTexture* color, int colorSlice, RenderTexture* depth, int depthSlice);
|
||
|
||
// 激活渲染纹理(用于后续绘制)
|
||
void ActivateRenderTarget(RenderTexture* color, RenderTexture* depth);
|
||
|
||
// ==================== 视口 ====================
|
||
|
||
void SetViewport(float x, float y, float width, float height);
|
||
void SetViewports(int count, Viewport* viewports);
|
||
void SetScissor(Rect rect);
|
||
void SetScissors(int count, Rect* rects);
|
||
|
||
// ==================== 绘制 ====================
|
||
|
||
// 绘制网格
|
||
void Draw(Mesh* mesh, int subMeshIndex = 0);
|
||
void DrawInstanced(Mesh* mesh, int subMeshIndex, int instanceCount);
|
||
void DrawMeshInstanced(Mesh* mesh, int subMeshIndex, int instanceCount, Material* material, int shaderPass = 0);
|
||
|
||
// 绘制程序(Compute Shader)
|
||
void DispatchCompute(ComputeShader* shader, int threadGroupsX, int threadGroupsY, int threadGroupsZ);
|
||
|
||
// 间接绘制
|
||
void DrawMeshInstancedIndirect(Mesh* mesh, ComputeBuffer* argsBuffer, int argsOffset = 0);
|
||
|
||
// ==================== 清除 ====================
|
||
|
||
void ClearRenderTarget(bool clearColor, bool clearDepth, bool clearStencil);
|
||
void ClearColor(const float4& color);
|
||
void ClearDepth(float depth);
|
||
void ClearStencil(int stencil);
|
||
|
||
// ==================== 纹理操作 ====================
|
||
|
||
// 复制纹理
|
||
void CopyTexture(Texture* src, Texture* dst);
|
||
void CopyTexture(Texture* src, int srcElement, int srcMip, int srcX, int srcY, int srcZ,
|
||
Texture* dst, int dstElement, int dstMip, int dstX, int dstY, int dstZ,
|
||
int width, int height, int depth);
|
||
|
||
// 异步读取纹理
|
||
void AsyncReadPixels(RenderTexture* source, Rect rect, TextureFormat format, bool activeCube);
|
||
|
||
// ==================== 计算着色器 ====================
|
||
|
||
void SetComputeBuffer(ComputeShader* shader, const char* name, ComputeBuffer* buffer);
|
||
|
||
// ==================== 同步 ====================
|
||
|
||
void IssuePluginEvent(int eventID);
|
||
void Flush();
|
||
|
||
// ==================== 渲染状态设置 ====================
|
||
|
||
// 设置模板引用值
|
||
void SetStencilRef(int ref);
|
||
|
||
// 启用/禁用裁剪
|
||
void EnableScissor();
|
||
void DisableScissor();
|
||
|
||
// 渲染目标(立即模式,不记录命令)
|
||
void SetRenderTargetImmediate(RenderTexture* color, RenderTexture* depth);
|
||
void SetRenderTargetImmediate(RenderTexture* color);
|
||
|
||
// 线条宽度
|
||
void SetLineWidth(float width);
|
||
|
||
// 视口变换矩阵
|
||
void SetViewTransform(const float4x4& view, const float4x4& projection);
|
||
void SetViewTransform(const float4x4& view, const float4x4& projection, const float4x4& brdf);
|
||
|
||
// ==================== Blit(后处理) ====================
|
||
|
||
void Blit(Material* material, RenderTexture* source, RenderTexture* dest);
|
||
void Blit(Material* material, RenderTexture* source, RenderTexture* dest, int pass);
|
||
void Blit(Material* material, RenderTexture* source, RenderTexture* dest, int pass, int lodLevel);
|
||
|
||
// ==================== 延迟执行 ====================
|
||
|
||
// 执行此CommandBuffer
|
||
void Execute();
|
||
void Execute(CommandBuffer* other);
|
||
|
||
// 立即执行(可选)
|
||
void ExecuteImmediate();
|
||
};
|
||
|
||
// 全局命令缓冲
|
||
CommandBuffer* GetMainCommandBuffer();
|
||
|
||
} // namespace Graphics
|
||
} // namespace XCEngine
|
||
```
|
||
|
||
### 2.2 GraphicsDevice(图形设备)
|
||
|
||
Unity使用GraphicsDevice代表底层图形设备,本设计采用相同概念。
|
||
|
||
```cpp
|
||
namespace XCEngine {
|
||
namespace Graphics {
|
||
|
||
// 图形API类型
|
||
enum class GraphicsAPI {
|
||
Direct3D12,
|
||
Vulkan,
|
||
OpenGL,
|
||
OpenGLES3,
|
||
Metal
|
||
};
|
||
|
||
// 设备能力
|
||
struct DeviceCapabilities {
|
||
bool supportsComputeShaders;
|
||
bool supportsGeometryShaders;
|
||
bool supportsTessellation;
|
||
bool supportsRaytracing;
|
||
bool supportsMeshShaders;
|
||
bool supportsNonPow2Textures;
|
||
bool supportsRenderTargetFloat;
|
||
bool supportsHDR;
|
||
int maxTextureSize;
|
||
int maxRenderTextureSize;
|
||
int maxCubemapSize;
|
||
int maxColorAttachments;
|
||
int maxComputeBuffers;
|
||
int maxComputeBufferSize;
|
||
int maxVertexAttributes;
|
||
};
|
||
|
||
// 纹理格式信息
|
||
struct TextureFormatInfo {
|
||
TextureFormat format;
|
||
bool isSupported;
|
||
int bitsPerPixel;
|
||
bool isColor;
|
||
bool isDepth;
|
||
bool isPacked;
|
||
bool isCompressed;
|
||
};
|
||
|
||
// 图形设备接口
|
||
class GraphicsDevice {
|
||
public:
|
||
virtual ~GraphicsDevice() = default;
|
||
|
||
// 设备信息
|
||
virtual GraphicsAPI GetAPI() const = 0;
|
||
virtual const char* GetDeviceName() const = 0;
|
||
virtual const DeviceCapabilities& GetCapabilities() const = 0;
|
||
|
||
// 创建资源
|
||
virtual Texture* CreateTexture(const TextureDescriptor& desc) = 0;
|
||
virtual RenderTexture* CreateRenderTexture(const RenderTextureDescriptor& desc) = 0;
|
||
virtual ComputeBuffer* CreateComputeBuffer(const ComputeBufferDescriptor& desc) = 0;
|
||
virtual Mesh* CreateMesh() = 0;
|
||
virtual ComputeShader* CreateComputeShader(const void* source, int sourceLength) = 0;
|
||
virtual ComputeProgram* CreateComputeProgram(ComputeShader* computeShader) = 0;
|
||
virtual Material* CreateMaterial(Shader* shader) = 0;
|
||
virtual Shader* CreateShader(const ShaderSource& source) = 0;
|
||
|
||
// 命令缓冲管理
|
||
virtual CommandBuffer* CreateCommandBuffer() = 0;
|
||
virtual CommandBuffer* GetTempCommandBuffer() = 0;
|
||
virtual void ReleaseTempCommandBuffer(CommandBuffer* cmd) = 0;
|
||
virtual void SubmitCommandBuffer(CommandBuffer* cmd) = 0;
|
||
|
||
// 同步
|
||
virtual void WaitForIdle() = 0;
|
||
|
||
// 特性检测
|
||
virtual bool SupportsTextureFormat(TextureFormat format) const = 0;
|
||
virtual bool SupportsVertexFormat(VertexAttribute format) const = 0;
|
||
|
||
// 纹理格式信息
|
||
virtual TextureFormatInfo GetTextureFormatInfo(TextureFormat format) const = 0;
|
||
|
||
// 性能统计
|
||
virtual void ResetStatistics() = 0;
|
||
virtual void GetStatistics() const = 0;
|
||
};
|
||
|
||
// 工厂函数
|
||
GraphicsDevice* CreateGraphicsDevice(GraphicsAPI api, void* windowHandle = nullptr);
|
||
void DestroyGraphicsDevice(GraphicsDevice* device);
|
||
GraphicsAPI GetDefaultGraphicsAPI();
|
||
std::vector<GraphicsAPI> GetAvailableGraphicsAPIs();
|
||
|
||
} // namespace Graphics
|
||
} // namespace XCEngine
|
||
```
|
||
|
||
### 2.3 Texture(纹理)
|
||
|
||
```cpp
|
||
namespace XCEngine {
|
||
namespace Graphics {
|
||
|
||
enum class TextureFormat {
|
||
// 颜色格式
|
||
Alpha8,
|
||
ARGB4444,
|
||
RGB24,
|
||
RGBA32,
|
||
ARGB32,
|
||
RGB565,
|
||
DXT1,
|
||
DXT5,
|
||
RGBA4444,
|
||
BGRA32,
|
||
FloatRGHalf,
|
||
FloatRGBAHalf,
|
||
FloatRGBA,
|
||
FloatR,
|
||
HalfR,
|
||
IntR,
|
||
IntRG,
|
||
IntRGB,
|
||
IntRGBA,
|
||
DXT1Crunched,
|
||
DXT5Crunched,
|
||
RGBCrunched,
|
||
RGBACrunched,
|
||
|
||
// 深度格式
|
||
Depth16,
|
||
Depth24,
|
||
Depth24Stencil8,
|
||
Depth32Float,
|
||
Depth32FloatStencil8,
|
||
|
||
// 阴影格式
|
||
Shadowmap16,
|
||
Shadowmap24,
|
||
|
||
// HDR
|
||
RGB9E5,
|
||
RG11B10Float,
|
||
RGB10A2,
|
||
|
||
// YUV
|
||
YUV422,
|
||
YUV420
|
||
};
|
||
|
||
enum class TextureDimension {
|
||
None,
|
||
Texture2D,
|
||
Texture3D,
|
||
Texture2DArray,
|
||
TextureCube,
|
||
TextureCubeArray
|
||
};
|
||
|
||
enum class TextureWrapMode {
|
||
Repeat,
|
||
Clamp,
|
||
Mirror,
|
||
Border
|
||
};
|
||
|
||
enum class TextureFilterMode {
|
||
Point,
|
||
Bilinear,
|
||
Trilinear,
|
||
Anisotropic
|
||
};
|
||
|
||
enum class TextureUsage {
|
||
Default = 0,
|
||
RenderTarget = 1,
|
||
DepthStencil = 2,
|
||
Memoryless = 3,
|
||
Staging = 4
|
||
};
|
||
|
||
struct TextureDescriptor {
|
||
int width;
|
||
int height;
|
||
int depth;
|
||
int mipmapLevels;
|
||
int anisoLevel;
|
||
TextureFilterMode filterMode;
|
||
TextureWrapMode wrapMode;
|
||
TextureFormat format;
|
||
TextureDimension dimension;
|
||
TextureUsage usage;
|
||
bool enableRandomWrite;
|
||
bool useMipMap;
|
||
bool autoGenerateMipMaps;
|
||
};
|
||
|
||
class Texture {
|
||
public:
|
||
virtual ~Texture() = default;
|
||
|
||
// 属性
|
||
virtual int GetWidth() const = 0;
|
||
virtual int GetHeight() const = 0;
|
||
virtual int GetDepth() const = 0;
|
||
virtual int GetMipmapLevels() const = 0;
|
||
virtual TextureFormat GetFormat() const = 0;
|
||
virtual TextureDimension GetDimension() const = 0;
|
||
|
||
// 过滤模式
|
||
virtual void SetFilterMode(TextureFilterMode mode) = 0;
|
||
virtual TextureFilterMode GetFilterMode() const = 0;
|
||
|
||
// 纹理坐标包装模式
|
||
virtual void SetWrapMode(TextureWrapMode mode) = 0;
|
||
virtual TextureWrapMode GetWrapMode() const = 0;
|
||
|
||
// 各向异性过滤
|
||
virtual void SetAnisoLevel(int level) = 0;
|
||
virtual int GetAnisoLevel() const = 0;
|
||
|
||
// MipMap
|
||
virtual void GenerateMipMaps() = 0;
|
||
virtual void SetAnisotropicFiltering(float min, float max) = 0;
|
||
|
||
// 像素数据
|
||
virtual void SetData(const void* data, int mipLevel = 0) = 0;
|
||
virtual void GetData(void* data, int mipLevel = 0) = 0;
|
||
|
||
// 底层句柄
|
||
virtual void* GetNativeTexturePtr() = 0;
|
||
virtual void* GetNativeTexturePtr(int target) = 0;
|
||
};
|
||
|
||
} // namespace Graphics
|
||
} // namespace XCEngine
|
||
```
|
||
|
||
### 2.4 RenderTexture(渲染纹理)
|
||
|
||
```cpp
|
||
namespace XCEngine {
|
||
namespace Graphics {
|
||
|
||
enum class RenderTextureFormat {
|
||
ARGB32,
|
||
ARGBHalf,
|
||
ARGBFloat,
|
||
RGHalf,
|
||
RGFloat,
|
||
RFloat,
|
||
Int,
|
||
Long,
|
||
Depth,
|
||
ARGBInt,
|
||
RGBAUShort,
|
||
RGBA16,
|
||
RGB10A2,
|
||
R8,
|
||
RG16,
|
||
R16,
|
||
RGHalf,
|
||
RG16,
|
||
R8Int,
|
||
RG8Int,
|
||
R16Int,
|
||
R32Int,
|
||
RGBA8,
|
||
RFloat,
|
||
RGHalf,
|
||
RHalf
|
||
};
|
||
|
||
enum class RenderTextureMemoryless {
|
||
None,
|
||
Depth,
|
||
Color
|
||
};
|
||
|
||
struct RenderTextureDescriptor {
|
||
int width;
|
||
int height;
|
||
int volumeDepth;
|
||
int mipCount;
|
||
int depthBufferBits;
|
||
RenderTextureFormat colorFormat;
|
||
RenderTextureFormat depthFormat;
|
||
int stencilFormat;
|
||
int antiAliasing;
|
||
bool enableRandomWrite;
|
||
bool useMipMap;
|
||
bool sRGB;
|
||
TextureDimension dimension;
|
||
RenderTextureMemoryless memoryless;
|
||
bool bindMSRenderTarget;
|
||
bool bindMSDepthSurface;
|
||
bool useDynamicscale;
|
||
bool forceIntoRT;
|
||
};
|
||
|
||
class RenderTexture : public Texture {
|
||
public:
|
||
virtual ~RenderTexture() = default;
|
||
|
||
// 创建/释放
|
||
virtual bool Create() = 0;
|
||
virtual void Release() = 0;
|
||
|
||
// 是否有效
|
||
virtual bool IsCreated() const = 0;
|
||
virtual bool IsDestroyed() const = 0;
|
||
|
||
// 颜色缓冲
|
||
virtual Texture* GetColorBuffer() = 0;
|
||
virtual void SetColorBuffer(Texture* color) = 0;
|
||
|
||
// 深度缓冲
|
||
virtual Texture* GetDepthBuffer() = 0;
|
||
virtual void SetDepthBuffer(Texture* depth) = 0;
|
||
|
||
// 深度模板
|
||
virtual int GetDepthBufferBits() const = 0;
|
||
|
||
// MSAA
|
||
virtual int GetAntiAliasing() const = 0;
|
||
virtual void SetAntiAliasing(int aa) = 0;
|
||
|
||
// 纹理数量
|
||
virtual int GetVolumeDepth() const = 0;
|
||
virtual int GetMipMapLevelCount() const = 0;
|
||
|
||
// 维度
|
||
virtual TextureDimension GetDimension() const = 0;
|
||
|
||
// 是否使用MipMap
|
||
virtual bool GetMipMap() const = 0;
|
||
virtual void SetMipMap(bool value) = 0;
|
||
|
||
// sRGB读写
|
||
virtual bool GetSRGBRead() const = 0;
|
||
virtual void SetSRGBRead(bool value) = 0;
|
||
virtual bool GetSRGBWrite() const = 0;
|
||
virtual void SetSRGBWrite(bool value) = 0;
|
||
|
||
// 临时渲染纹理
|
||
static RenderTexture* GetTemporary(const RenderTextureDescriptor& desc);
|
||
static void ReleaseTemporary(RenderTexture* rt);
|
||
|
||
// ==================== 生命周期 ====================
|
||
|
||
// 初始化/反初始化
|
||
virtual void Initialize() = 0;
|
||
virtual void Deinitialize() = 0;
|
||
virtual bool IsInitialized() const = 0;
|
||
|
||
// 创建/销毁(替代构造函数)
|
||
virtual bool Create() = 0;
|
||
virtual void Destroy() = 0;
|
||
|
||
// 是否有效
|
||
virtual bool IsCreated() const = 0;
|
||
virtual bool IsDestroyed() const = 0;
|
||
|
||
// 描述符
|
||
virtual void* GetDescriptor() = 0;
|
||
|
||
// 目标纹理
|
||
virtual void SetTargetTexture(Texture* tex) = 0;
|
||
virtual Texture* GetTargetTexture() = 0;
|
||
|
||
// ==================== 激活/解析 ====================
|
||
|
||
// 激活/停用
|
||
virtual void Activate() = 0;
|
||
virtual void Resolve() = 0;
|
||
virtual void Resolve(Texture* target, int mipLevel = 0) = 0;
|
||
};
|
||
|
||
} // namespace Graphics
|
||
} // namespace XCEngine
|
||
```
|
||
|
||
### 2.5 ComputeBuffer(计算缓冲)
|
||
|
||
```cpp
|
||
namespace XCEngine {
|
||
namespace Graphics {
|
||
|
||
enum class ComputeBufferType {
|
||
Default,
|
||
Raw,
|
||
Append,
|
||
Counter,
|
||
DrawIndirect,
|
||
Structured,
|
||
ByteAddress
|
||
};
|
||
|
||
enum class ComputeBufferUsage {
|
||
Default = 0,
|
||
Dynamic = 1,
|
||
Immutable = 2,
|
||
Staging = 3
|
||
};
|
||
|
||
struct ComputeBufferDescriptor {
|
||
int count;
|
||
int stride;
|
||
ComputeBufferType type;
|
||
ComputeBufferUsage usage;
|
||
};
|
||
|
||
class ComputeBuffer {
|
||
public:
|
||
virtual ~ComputeBuffer() = default;
|
||
|
||
// 属性
|
||
virtual int GetCount() const = 0;
|
||
virtual int GetStride() const = 0;
|
||
virtual ComputeBufferType GetBufferType() const = 0;
|
||
|
||
// 数据操作
|
||
virtual void SetData(const void* data) = 0;
|
||
virtual void GetData(void* data) = 0;
|
||
virtual void SetCounterValue(int counterValue) = 0;
|
||
|
||
// 原子操作(用于Append/Counter类型)
|
||
virtual void Begin() = 0; // 开始计数
|
||
virtual void End() = 0; // 结束计数
|
||
virtual int GetCounterValue() = 0;
|
||
|
||
// 有效性检查
|
||
virtual bool IsValid() const = 0;
|
||
|
||
// 底层句柄
|
||
virtual void* GetNativeBufferPtr() = 0;
|
||
};
|
||
|
||
} // namespace Graphics
|
||
} // namespace XCEngine
|
||
```
|
||
|
||
### 2.6 Shader与ComputeShader
|
||
|
||
```cpp
|
||
namespace XCEngine {
|
||
namespace Graphics {
|
||
|
||
// Shader属性类型
|
||
enum class ShaderPropertyType {
|
||
Color,
|
||
Vector,
|
||
Float,
|
||
Range,
|
||
Texture
|
||
};
|
||
|
||
struct ShaderProperty {
|
||
std::string name;
|
||
ShaderPropertyType type;
|
||
int nameID;
|
||
float defaultValue;
|
||
float defaultMin;
|
||
float defaultMax;
|
||
};
|
||
|
||
// Shader编译结果
|
||
struct ShaderCompilationResult {
|
||
bool success;
|
||
std::string errorMessage;
|
||
int line;
|
||
std::vector<std::string> errors;
|
||
std::vector<std::string> warnings;
|
||
};
|
||
|
||
// Shader源
|
||
struct ShaderSource {
|
||
const char* code;
|
||
const char* filename;
|
||
const char* entryPoint;
|
||
ShaderLanguage language;
|
||
};
|
||
|
||
// Shader语言
|
||
enum class ShaderLanguage {
|
||
HLSL,
|
||
GLSL,
|
||
SPIRV,
|
||
DXIL
|
||
};
|
||
|
||
// Shader类型
|
||
enum class ShaderType {
|
||
Vertex,
|
||
Fragment,
|
||
Geometry,
|
||
Compute,
|
||
Hull,
|
||
Domain,
|
||
RayGeneration,
|
||
RayIntersection,
|
||
RayMiss,
|
||
RayClosestHit
|
||
};
|
||
|
||
class Shader {
|
||
public:
|
||
virtual ~Shader() = default;
|
||
|
||
// 属性
|
||
virtual const char* GetName() const = 0;
|
||
virtual int GetPropertyCount() const = 0;
|
||
virtual ShaderProperty GetProperty(int index) const = 0;
|
||
virtual int FindPropertyIndex(const char* name) const = 0;
|
||
virtual ShaderPropertyType GetPropertyType(int nameID) const = 0;
|
||
|
||
// 编译
|
||
virtual bool IsSupported() const = 0;
|
||
virtual bool IsValid() const = 0;
|
||
virtual bool Compile(const char* entryPoint, ShaderType type) = 0;
|
||
|
||
// Pass数量
|
||
virtual int GetPassCount() const = 0;
|
||
|
||
// 查找属性
|
||
virtual int FindPropertyIndexByName(const char* name) const = 0;
|
||
|
||
// 关键字
|
||
virtual void DisableKeyword(const char* keyword) = 0;
|
||
virtual void EnableKeyword(const char* keyword) = 0;
|
||
virtual bool IsKeywordEnabled(const char* keyword) const = 0;
|
||
|
||
// 获取Shader变体数量
|
||
virtual int GetVariantCount() const = 0;
|
||
virtual int GetVariantCount(int pass) const = 0;
|
||
|
||
// 设置全局关键词
|
||
static void EnableKeywordGlobal(const char* keyword);
|
||
static void DisableKeywordGlobal(const char* keyword);
|
||
|
||
// 预编译
|
||
virtual void Precompile() = 0;
|
||
};
|
||
|
||
// Compute Shader
|
||
class ComputeShader : public Shader {
|
||
public:
|
||
virtual ~ComputeShader() = 0;
|
||
|
||
// 内核
|
||
virtual const char* GetKernelName() const = 0;
|
||
virtual void SetKernelArg(const char* argName, const void* data, int dataSize) = 0;
|
||
virtual void SetTexture(const char* argName, Texture* texture) = 0;
|
||
virtual void SetBuffer(const char* argName, ComputeBuffer* buffer) = 0;
|
||
|
||
// 线程组大小
|
||
virtual int GetKernelThreadGroupSizeX() const = 0;
|
||
virtual int GetKernelThreadGroupSizeY() const = 0;
|
||
virtual int GetKernelThreadGroupSizeZ() const = 0;
|
||
};
|
||
|
||
// Compute Program
|
||
class ComputeProgram {
|
||
public:
|
||
virtual ~ComputeProgram() = 0;
|
||
|
||
virtual ComputeShader* GetKernel() const = 0;
|
||
virtual bool IsValid() const = 0;
|
||
virtual void GetKernelThreadGroupSizes(size_t& x, size_t& y, size_t& z) const = 0;
|
||
};
|
||
|
||
} // namespace Graphics
|
||
} // namespace XCEngine
|
||
```
|
||
|
||
### 2.7 Material与RenderState
|
||
|
||
```cpp
|
||
namespace XCEngine {
|
||
namespace Graphics {
|
||
|
||
// 混合模式
|
||
enum class BlendMode {
|
||
Alpha,
|
||
AlphaPremultiply,
|
||
Additive,
|
||
Multiply,
|
||
Overlay,
|
||
Opaque,
|
||
Transparent,
|
||
Custom
|
||
};
|
||
|
||
// 混合因子
|
||
enum class BlendFactor {
|
||
Zero,
|
||
One,
|
||
SrcColor,
|
||
InvSrcColor,
|
||
SrcAlpha,
|
||
InvSrcAlpha,
|
||
DstAlpha,
|
||
InvDstAlpha,
|
||
DstColor,
|
||
InvDstColor,
|
||
SrcAlphaSat,
|
||
BlendFactor,
|
||
InvBlendFactor,
|
||
Src1Color,
|
||
InvSrc1Color,
|
||
Src1Alpha,
|
||
InvSrc1Alpha
|
||
};
|
||
|
||
// 混合操作
|
||
enum class BlendOp {
|
||
Add,
|
||
Subtract,
|
||
ReverseSubtract,
|
||
Min,
|
||
Max
|
||
};
|
||
|
||
// 比较函数
|
||
enum class CompareFunction {
|
||
Disabled,
|
||
Never,
|
||
Less,
|
||
Equal,
|
||
LessEqual,
|
||
Greater,
|
||
NotEqual,
|
||
GreaterEqual,
|
||
Always
|
||
};
|
||
|
||
// 模板操作
|
||
enum class StencilOp {
|
||
Keep,
|
||
Zero,
|
||
Replace,
|
||
IncrSat,
|
||
DecrSat,
|
||
Invert,
|
||
IncrWrap,
|
||
DecrWrap
|
||
};
|
||
|
||
// 背面剔除
|
||
enum class CullMode {
|
||
Off,
|
||
Front,
|
||
Back
|
||
};
|
||
|
||
// 深度写入
|
||
enum class DepthWrite {
|
||
Less,
|
||
LessEqual,
|
||
Equal,
|
||
GreaterEqual,
|
||
Greater,
|
||
Always
|
||
};
|
||
|
||
// 颜色写入
|
||
enum class ColorWriteMask {
|
||
Alpha = 1,
|
||
Blue = 2,
|
||
Green = 4,
|
||
Red = 8,
|
||
All = 15
|
||
};
|
||
|
||
struct RenderState {
|
||
// 混合
|
||
BlendMode blend;
|
||
BlendFactor srcBlend;
|
||
BlendFactor dstBlend;
|
||
BlendOp blendOp;
|
||
BlendFactor srcBlendAlpha;
|
||
BlendFactor dstBlendAlpha;
|
||
BlendOp blendOpAlpha;
|
||
ColorWriteMask colorWriteMask;
|
||
|
||
// 深度
|
||
bool depthWrite;
|
||
bool depthTest;
|
||
CompareFunction depthFunc;
|
||
|
||
// 模板
|
||
bool stencil;
|
||
CompareFunction stencilCompare;
|
||
StencilOp stencilPass;
|
||
StencilOp stencilFail;
|
||
StencilOp stencilZFail;
|
||
byte stencilReadMask;
|
||
byte stencilWriteMask;
|
||
byte stencilRef;
|
||
|
||
// 背面剔除
|
||
CullMode cullMode;
|
||
bool frontFaceCCW;
|
||
|
||
// 深度偏移
|
||
bool depthBias;
|
||
float slopeScaledDepthBias;
|
||
float depthBiasClamp;
|
||
float depthBiasConstantFactor;
|
||
|
||
// 渲染队列
|
||
int renderQueue;
|
||
};
|
||
|
||
// ==================== Pass(渲染通道) ====================
|
||
// Unity中每个Material有多个Pass,每个Pass独立渲染
|
||
class Pass {
|
||
public:
|
||
virtual ~Pass() = default;
|
||
|
||
// 渲染状态
|
||
virtual const RenderState& GetRenderState() const = 0;
|
||
virtual void SetRenderState(const RenderState& state) = 0;
|
||
|
||
// Shader
|
||
virtual Shader* GetShader() const = 0;
|
||
virtual void SetShader(Shader* shader) = 0;
|
||
|
||
// 混合
|
||
virtual void SetBlendMode(BlendMode mode) = 0;
|
||
|
||
// 模板
|
||
virtual void SetStencil(const RenderState& state) = 0;
|
||
|
||
// 渲染队列覆盖
|
||
virtual void SetRenderQueue(int queue) = 0;
|
||
virtual int GetRenderQueue() const = 0;
|
||
};
|
||
|
||
// ==================== Material(材质) ====================
|
||
|
||
class Material {
|
||
public:
|
||
virtual ~Material() = default;
|
||
|
||
// Shader
|
||
virtual Shader* GetShader() const = 0;
|
||
virtual void SetShader(Shader* shader) = 0;
|
||
|
||
// Pass管理
|
||
virtual int GetPassCount() const = 0;
|
||
virtual Pass* GetPass(int index) = 0;
|
||
virtual Pass* CreatePass(const char* name = nullptr) = 0;
|
||
virtual void ReleasePass(Pass* pass) = 0;
|
||
virtual const char* GetPassName(int index) const = 0;
|
||
virtual int FindPass(const char* name) const = 0;
|
||
virtual void SetPass(int pass) = 0;
|
||
|
||
// 快捷方法(作用于当前Pass)
|
||
virtual void SetInt(const char* name, int value) = 0;
|
||
virtual void SetFloat(const char* name, float value) = 0;
|
||
virtual void SetFloatArray(const char* name, const float* values, int count) = 0;
|
||
virtual void SetVector(const char* name, const float4& value) = 0;
|
||
virtual void SetVectorArray(const char* name, const float4* values, int count) = 0;
|
||
virtual void SetMatrix(const char* name, const float4x4& value) = 0;
|
||
virtual void SetMatrixArray(const char* name, const float4x4* values, int count) = 0;
|
||
virtual void SetTexture(const char* name, Texture* value) = 0;
|
||
|
||
// 渲染状态(快捷方法,作用于当前Pass)
|
||
virtual RenderState GetRenderState() const = 0;
|
||
virtual void SetRenderState(const RenderState& state) = 0;
|
||
virtual void SetOverrideTag(const char* tag) = 0;
|
||
|
||
// 渲染队列
|
||
virtual int GetRenderQueue() const = 0;
|
||
virtual void SetRenderQueue(int queue) = 0;
|
||
virtual void SetRenderQueue(int queue, int subqueueShift) = 0;
|
||
|
||
// 关键字
|
||
virtual void EnableKeyword(const char* keyword) = 0;
|
||
virtual void DisableKeyword(const char* keyword) = 0;
|
||
virtual bool IsKeywordEnabled(const char* keyword) const = 0;
|
||
virtual void ShaderKeywordsFromGlobal() = 0;
|
||
|
||
// Pass启用
|
||
virtual void SetPassEnabled(const char* passName, bool enabled) = 0;
|
||
virtual bool IsPassEnabled(const char* passName) const = 0;
|
||
|
||
// 复制
|
||
virtual Material* Clone() = 0;
|
||
};
|
||
|
||
} // namespace Graphics
|
||
} // namespace XCEngine
|
||
```
|
||
|
||
### 2.8 Mesh(网格)
|
||
|
||
```cpp
|
||
namespace XCEngine {
|
||
namespace Graphics {
|
||
|
||
enum class MeshTopology {
|
||
Points,
|
||
Lines,
|
||
LineStrip,
|
||
Triangles,
|
||
TriangleStrip,
|
||
Quads
|
||
};
|
||
|
||
enum class MeshIndexFormat {
|
||
Index16,
|
||
Index32
|
||
};
|
||
|
||
class Mesh {
|
||
public:
|
||
virtual ~Mesh() = 0;
|
||
|
||
// 顶点数据
|
||
virtual void SetVertices(const float3* vertices, int count) = 0;
|
||
virtual void SetVertices(const void* vertices, int count, const VertexAttribute* attributes, int attributeCount) = 0;
|
||
virtual void GetVertices(float3* vertices) = 0;
|
||
virtual int GetVertexCount() const = 0;
|
||
|
||
// 索引数据
|
||
virtual void SetIndices(const uint16_t* indices, int count) = 0;
|
||
virtual void SetIndices(const uint32_t* indices, int count) = 0;
|
||
virtual void GetIndices(uint16_t* indices) = 0;
|
||
virtual void GetIndices(uint32_t* indices) = 0;
|
||
virtual int GetIndexCount() const = 0;
|
||
virtual MeshIndexFormat GetIndexFormat() const = 0;
|
||
|
||
// 顶点属性
|
||
virtual void SetTangents(const float4* tangents) = 0;
|
||
virtual void SetNormals(const float3* normals) = 0;
|
||
virtual void SetColors(const Color* colors) = 0;
|
||
virtual void SetColors(const float4* colors) = 0;
|
||
virtual void SetUVs(int channel, const float2* uvs) = 0;
|
||
virtual void SetUVs(int channel, const float3* uvs) = 0;
|
||
virtual void SetBoneWeights(const float4* weights, const uint8_t* indices) = 0;
|
||
|
||
// 子网格
|
||
virtual void SetSubmeshCount(int count) = 0;
|
||
virtual void SetSubmesh(int index, int startIndex, int indexCount, int baseVertex) = 0;
|
||
|
||
// 边界
|
||
virtual void RecalculateBounds() = 0;
|
||
virtual AABB GetBounds() const = 0;
|
||
|
||
// 顶点缓冲区
|
||
virtual int GetVertexBufferCount() const = 0;
|
||
virtual VertexBuffer* GetVertexBuffer(int index) const = 0;
|
||
|
||
// 索引缓冲区
|
||
virtual VertexBuffer* GetIndexBuffer() const = 0;
|
||
|
||
// 拓扑
|
||
virtual void SetTopology(MeshTopology topology) = 0;
|
||
virtual MeshTopology GetTopology() const = 0;
|
||
|
||
// 动态标记(频繁更新)
|
||
virtual void MarkDynamic() = 0;
|
||
virtual bool IsDynamic() const = 0;
|
||
|
||
// 上传
|
||
virtual void UploadMeshData(bool markNoLongerReadable = false) = 0;
|
||
virtual void Clear() = 0;
|
||
|
||
// 获取子网格信息
|
||
virtual int GetSubmeshCount() const = 0;
|
||
virtual void GetSubmesh(int index, int& startIndex, int& indexCount, int& baseVertex) const = 0;
|
||
};
|
||
|
||
} // namespace Graphics
|
||
} // namespace XCEngine
|
||
```
|
||
|
||
### 2.9 辅助类型
|
||
|
||
```cpp
|
||
namespace XCEngine {
|
||
namespace Graphics {
|
||
|
||
// 顶点属性格式
|
||
enum class VertexAttributeFormat {
|
||
Float,
|
||
Float2,
|
||
Float3,
|
||
Float4,
|
||
Half,
|
||
Half2,
|
||
Half4,
|
||
Int,
|
||
Int2,
|
||
Int3,
|
||
Int4,
|
||
UInt,
|
||
UInt2,
|
||
UInt3,
|
||
UInt4,
|
||
Color,
|
||
Color32,
|
||
Short,
|
||
Short2,
|
||
Short4,
|
||
UShort,
|
||
UShort2,
|
||
UShort4
|
||
};
|
||
|
||
// 顶点输入描述
|
||
struct VertexAttribute {
|
||
std::string semantic;
|
||
int semanticIndex;
|
||
VertexAttributeFormat format;
|
||
int stream;
|
||
int offset;
|
||
};
|
||
|
||
// 顶点布局
|
||
class VertexLayout {
|
||
public:
|
||
void AddAttribute(const char* semantic, int semanticIndex, VertexAttributeFormat format);
|
||
void AddAttribute(const char* semantic, VertexAttributeFormat format);
|
||
const std::vector<VertexAttribute>& GetAttributes() const;
|
||
int GetStride() const;
|
||
};
|
||
|
||
// 视口
|
||
struct Viewport {
|
||
float x, y;
|
||
float width, height;
|
||
float minDepth, maxDepth;
|
||
|
||
Viewport() : x(0), y(0), width(0), height(0), minDepth(0), maxDepth(1) {}
|
||
Viewport(float x, float y, float w, float h) : x(x), y(y), width(w), height(h), minDepth(0), maxDepth(1) {}
|
||
};
|
||
|
||
// 矩阵和向量(使用现有Math库)
|
||
using float4x4 = XCEngine::Math::Matrix4;
|
||
using float4 = XCEngine::Math::Vector4;
|
||
using float3 = XCEngine::Math::Vector3;
|
||
using float2 = XCEngine::Math::Vector2;
|
||
using Color = XCEngine::Math::Color;
|
||
using AABB = XCEngine::Math::AABB;
|
||
|
||
} // namespace Graphics
|
||
} // namespace XCEngine
|
||
```
|
||
|
||
---
|
||
|
||
## 三、后端实现
|
||
|
||
### 3.1 D3D12后端
|
||
|
||
```cpp
|
||
namespace XCEngine {
|
||
namespace Graphics {
|
||
namespace D3D12 {
|
||
|
||
class D3D12GraphicsDevice : public GraphicsDevice {
|
||
public:
|
||
D3D12GraphicsDevice(ID3D12Device* device, IDXGIFactory4* factory);
|
||
~D3D12GraphicsDevice() override;
|
||
|
||
GraphicsAPI GetAPI() const override { return GraphicsAPI::Direct3D12; }
|
||
const char* GetDeviceName() const override;
|
||
const DeviceCapabilities& GetCapabilities() const override;
|
||
|
||
Texture* CreateTexture(const TextureDescriptor& desc) override;
|
||
RenderTexture* CreateRenderTexture(const RenderTextureDescriptor& desc) override;
|
||
ComputeBuffer* CreateComputeBuffer(const ComputeBufferDescriptor& desc) override;
|
||
Mesh* CreateMesh() override;
|
||
ComputeShader* CreateComputeShader(const void* source, int sourceLength) override;
|
||
ComputeProgram* CreateComputeProgram(ComputeShader* computeShader) override;
|
||
Material* CreateMaterial(Shader* shader) override;
|
||
Shader* CreateShader(const ShaderSource& source) override;
|
||
|
||
CommandBuffer* CreateCommandBuffer() override;
|
||
void SubmitCommandBuffer(CommandBuffer* cmd) override;
|
||
|
||
void WaitForIdle() override;
|
||
bool SupportsTextureFormat(TextureFormat format) const override;
|
||
bool SupportsVertexFormat(VertexAttribute format) const override;
|
||
|
||
private:
|
||
ComPtr<ID3D12Device> m_device;
|
||
ComPtr<IDXGIFactory4> m_factory;
|
||
ComPtr<ID3D12CommandQueue> m_commandQueue;
|
||
DeviceCapabilities m_capabilities;
|
||
};
|
||
|
||
class D3D12CommandBuffer : public CommandBuffer {
|
||
public:
|
||
D3D12CommandBuffer(ID3D12Device* device);
|
||
~D3D12CommandBuffer() override;
|
||
|
||
// 实现CommandBuffer接口...
|
||
// 使用D3D12的ID3D12GraphicsCommandList
|
||
|
||
private:
|
||
ComPtr<ID3D12GraphicsCommandList> m_commandList;
|
||
std::vector<ComPtr<ID3D12Resource>> m_resources;
|
||
};
|
||
|
||
} // namespace D3D12
|
||
} // namespace Graphics
|
||
} // namespace XCEngine
|
||
```
|
||
|
||
### 3.2 OpenGL后端
|
||
|
||
```cpp
|
||
namespace XCEngine {
|
||
namespace Graphics {
|
||
namespace OpenGL {
|
||
|
||
class OpenGLGraphicsDevice : public GraphicsDevice {
|
||
public:
|
||
OpenGLGraphicsDevice(void* windowHandle);
|
||
~OpenGLGraphicsDevice() override;
|
||
|
||
GraphicsAPI GetAPI() const override { return GraphicsAPI::OpenGL; }
|
||
const char* GetDeviceName() const override;
|
||
const DeviceCapabilities& GetCapabilities() const override;
|
||
|
||
// 实现工厂方法...
|
||
|
||
private:
|
||
void* m_windowHandle;
|
||
DeviceCapabilities m_capabilities;
|
||
};
|
||
|
||
class OpenGLCommandBuffer : public CommandBuffer {
|
||
public:
|
||
OpenGLCommandBuffer();
|
||
~OpenGLCommandBuffer() override;
|
||
|
||
// 实现CommandBuffer接口
|
||
// OpenGL直接执行,无需命令列表
|
||
// 可以使用Display List或记录命令
|
||
|
||
private:
|
||
GLuint m_vao;
|
||
std::unordered_map<std::string, GLuint> m_boundTextures;
|
||
};
|
||
|
||
} // namespace OpenGL
|
||
} // namespace Graphics
|
||
} // namespace XCEngine
|
||
```
|
||
|
||
---
|
||
|
||
## 四、目录结构
|
||
|
||
```
|
||
engine/
|
||
├── include/XCEngine/
|
||
│ └── Graphics/
|
||
│ ├── CommandBuffer.h # 命令缓冲
|
||
│ ├── GraphicsDevice.h # 图形设备
|
||
│ ├── Texture.h # 纹理
|
||
│ ├── RenderTexture.h # 渲染纹理
|
||
│ ├── ComputeBuffer.h # 计算缓冲
|
||
│ ├── Shader.h # Shader
|
||
│ ├── ComputeShader.h # Compute Shader
|
||
│ ├── Material.h # 材质
|
||
│ ├── Mesh.h # 网格
|
||
│ ├── VertexLayout.h # 顶点布局
|
||
│ ├── Types.h # 类型定义
|
||
│ └── Enums.h # 枚举定义
|
||
│
|
||
└── src/
|
||
└── Graphics/
|
||
├── D3D12/
|
||
│ ├── D3D12Device.cpp
|
||
│ ├── D3D12CommandBuffer.cpp
|
||
│ ├── D3D12Texture.cpp
|
||
│ └── ...
|
||
│
|
||
├── OpenGL/
|
||
│ ├── OpenGLDevice.cpp
|
||
│ ├── OpenGLCommandBuffer.cpp
|
||
│ ├── OpenGLTexture.cpp
|
||
│ └── ...
|
||
│
|
||
└── Common/
|
||
└── ...
|
||
```
|
||
|
||
---
|
||
|
||
## 五、使用示例
|
||
|
||
```cpp
|
||
// 创建图形设备
|
||
GraphicsDevice* device = CreateGraphicsDevice(GraphicsAPI::D3D12, hwnd);
|
||
|
||
// 创建纹理
|
||
TextureDescriptor texDesc;
|
||
texDesc.width = 1024;
|
||
texDesc.height = 1024;
|
||
texDesc.format = TextureFormat::RGBA32;
|
||
texDesc.dimension = TextureDimension::Texture2D;
|
||
Texture* texture = device->CreateTexture(texDesc);
|
||
|
||
// 创建Compute Shader
|
||
ComputeShader* computeShader = device->CreateComputeShader(csSource, csSourceLen);
|
||
|
||
// 创建Compute Program
|
||
ComputeProgram* computeProgram = device->CreateComputeProgram(computeShader);
|
||
|
||
// 创建CommandBuffer
|
||
CommandBuffer* cmd = device->CreateCommandBuffer();
|
||
|
||
// 渲染命令
|
||
cmd->SetComputeTexture(computeShader, "MainTex", texture);
|
||
cmd->DispatchCompute(computeShader, 32, 32, 1);
|
||
|
||
// 执行
|
||
device->SubmitCommandBuffer(cmd);
|
||
```
|
||
|
||
---
|
||
|
||
*文档版本:2.0*
|
||
*更新日期:2026-03-16*
|