当前位置: 首页 > news >正文

编写DX12时使用的辅助类

编写DX12时使用的辅助类

有一段时间没有学DX12,导致很多东西都忘了,跟着教程里写的东西还好,略看一遍教程就想起来的,但是自己封装的很多类就算写了注释过了一段时间也基本忘光,而且翻来翻去的也不方便,为了快速记起来写一下实现思路。

Singleton

简介

需要进行显式初始化,并且可控制生命周期的模板单例类。

主要接口

Create

template<typename... Args>
static void Create(Args... args);

显式初始化函数,可通过参数包创建一个全局实例。

ShutDown

static void ShutDown() noexcept;

销毁当前的实例对象,若是后续需要继续使用,需要调用Create重新显式初始化。

主要变量

m_Instance

inline static  T* m_Instance = nullptr;

当前的实例。

注意事项

使用前需要进行显式构造。同时由于父类无法访问子类的protected构造函数,所以若子类不是抽象类,则需要将Singleton设置为友元,例如:

class LightManager : public Singleton<LightManager>
{
protected:friend Singleton<LightManager>;
}

BaseImGuiManager

简介

Imgui管理抽象基类,继承自Singleton为单例类,为了让单例获取到的实例能够使用子类自定义的成员函数或变量,使用了奇异递归模板模式实现。

主要接口

InitImGui

virtual bool InitImGui(ID3D12Device* device, HWND hMainWnd, int bufferCount, DXGI_FORMAT bufferFormat);

使用默认模式初始化Imgui,子类可重写后自定义Imgui模式。

UpdateImGui

virtual void UpdateImGui(const CpuTimer& timer) = 0;

纯虚函数,子类通过该函数自定义GUI,会在公有成员函数Update中调用,每帧更新。

RenderImGui

virtual void RenderImGui(ID3D12GraphicsCommandList* cmdList);

使用命令列表设置描述符堆之后绘制Imgui。

LightManager

用于管理光源的单例类。

主要接口

LightManager

LightManager(ID3D12Device* device,UINT frameCount,int maxDirLight = 5,int maxPointLight = 5,int maxSpotLight = 5);

构造函数,需要传入D3D设备和帧资源的个数,同时还限定了光源的最大个数。

CreateLightBuffer

void CreateLightBuffer(ID3D12Device* device);

在构造函数中调用,在默认堆中根据帧资源的个数创建光源的常量缓冲区资源,后续若是实现堆管理则改为分配在自行管理的堆中。

Set-xxx-Light

void Set-xxx-Light(std::size_t index, const DirectionalLight& light);

三个设置不同光源的函数,xxx表示了方向光、点光、聚光灯三种灯光的一种,会检测当前的光源数量是否饱和,因此无需注意设置的光源是否达到上限。

GetGPUVirtualAddress

D3D12_GPU_VIRTUAL_ADDRESS GetGPUVirtualAddress() const;

获取当前帧对应的光源资源的GPU虚拟地址。

GetLightsShaderMacros

std::array<D3D_SHADER_MACRO, 4> GetLightsShaderMacros(const char* dirName,const char* pointName,const char* spotName) const;

获取三种光源数量的宏,需要输入在Shader中三个宏的名字。

UpdateLight

void UpdateLight();

更新官员,若是光源没有变化则只会更新光源资源的索引,不会发生拷贝。

主要变量

m_LightsUploaders

ComPtr<ID3D12Resource> m_LightsUploaders;

所有帧资源的光源的数据。

m_FrameCount

const UINT m_FrameCount;

帧资源个数。

m_NumFrameDirty

UINT m_NumFrameDirty;

用于判断当前数据是否变更,避免不必要的拷贝,当SetLight后,该数字变为帧资源个数。

GeometryMesh

简介

包含顶点及索引的几何网格数据。

主要接口

GetIndices16

std::vector<std::uint16_t>& GetIndices16() noexcept

获取每个索引为两字节的索引数据。

主要变量

m_Vertices

网格的所有顶点数据,其中顶点数据如下:

struct Vertex
{DirectX::XMFLOAT3 m_Position;DirectX::XMFLOAT3 m_Normal;DirectX::XMFLOAT4 m_Tangent;DirectX::XMFLOAT3 m_BiTangent;DirectX::XMFLOAT2 m_TexCoord;
};

m_Indices32

网格的所有索引,每个索引四个字节。

ModelMesh

简介

导入模型时使用的数据。

主要变量

struct ModelMesh
{std::string m_Name;Geometry::GeometryMesh m_MeshData;DirectX::BoundingBox m_BoundingBox;UINT m_MaterialIndex;
};

包含网格名字、网格的顶点及索引、包围盒、当前网格所使用的材质的索引。

Model

简介

模型类,包含模型名字、模型网格和材质。

主要接口

LoadModelFromFile

bool LoadModelFromFile(const std::string& filename);

从文件中加载模型,调用Assimp库获取模型数据,后将模型数据处理成自定义的模型网格和材质。

ProcessNode

void ProcessNode(aiNode* node, const aiScene* scene);

使用递归的方式处理模型数据中的所有节点,获取网格和材质。

ProcessMesh

ModelMesh ProcessMesh(aiMesh* mesh, const aiScene* scene);

提取Assimp中的网格及材质数据。

主要变量

m_Meshs

std::map<std::string, ModelMesh> m_Meshs;

所有的模型网格数据。

m_Materials

std::vector<Material> m_Materials;

所有的材质数据。

MeshData

简介

处理成ID3D12Resource后的网格数据,同时包含了顶点缓冲区和索引缓冲区所需要的数据,储存了子网格的绘制索引。

主要方法

GetVertexBufferView

D3D12_VERTEX_BUFFER_VIEW GetVertexBufferView() const;

获取顶点缓冲区的资源视图。

GetIndexBufferView

D3D12_INDEX_BUFFER_VIEW GetIndexBufferView() const;

获取索引缓冲区的资源视图。

DisposeUploaders

void DisposeUploaders();

释放上传缓冲区的内存。

主要成员

struct MeshData
{// 几何体集合的名字,便于索引std::string m_Name;// 系统内存中的副本,顶点和索引可为范式类型,用Blob表示,可在特定的时候转换ComPtr<ID3DBlob> m_VertexBufferCPU = nullptr;ComPtr<ID3DBlob> m_IndexBufferCPU = nullptr;// GPU资源ComPtr<ID3D12Resource> m_VertexBufferGPU = nullptr;ComPtr<ID3D12Resource> m_IndexBufferGPU = nullptr;ComPtr<ID3D12Resource> m_VertexBufferUploader = nullptr;ComPtr<ID3D12Resource> m_IndexBufferUploader = nullptr;// 缓冲区相关数据UINT m_VertexByteStride = 0;UINT m_VertexBufferByteSize = 0;DXGI_FORMAT m_IndexFormat = DXGI_FORMAT_R16_UINT;UINT m_IndexSize = 0;UINT m_IndexBufferByteSize = 0;// 一个MeshData可以统一储存多个几何体,使用下列容器可单独绘制每个几何体std::map<std::string, SubmeshData> m_DrawArgs;
};
http://www.hskmm.com/?act=detail&tid=30436

相关文章:

  • HLSL语法
  • DirectX12初始化
  • 实验2
  • CF2159B
  • 登录校验---Filter过滤器
  • 日志|Ajax
  • 环境变量 Path 配置实战指南:从“能用”到“专业”--两种配置环境变量的方法
  • 10月13日
  • Ubuntu22.04安装CH340/CH341驱动
  • 玄机蓝队靶场_应急响应_198:实战Live勒索病毒溯源排查
  • JetBrains Mono字体好看、及其它
  • STM32——UART
  • WebApi 交叉观察者- IntersectionObserver复盘
  • [KaibaMath]1009 关于||a|-|b||≤|a+b|的证明
  • AMPopTip - 优雅的iOS动画提示框库
  • 2026年深度对比值得推荐的10个在线客服系统
  • 文件名中有空格比较烦人
  • 20232421 2024-2025-1 《网络与系统攻防技术》实验一实验报告
  • 十月总结
  • 20251013 之所思 - 人生如梦
  • Markdown 基本语法
  • 简单工单系统的实现-客服系统中增加创建工单功能
  • 日总结 10
  • # 20232421 2024-2025-1 《网络与系统攻防技术》实验一实验报告
  • 20232317 2025-2026-1《网络与系统攻防技术》实验一实验报告
  • 给一个字符串数组,输出不同的部分
  • 连接 USB 设备
  • SpringBoot-day1(快速上手SpringBoot,SpringBoot简介,SpringBoot基础配置,属性配置,yaml文件) - a
  • Chroma私有化:本地部署完整方案
  • 嵌入式-C++面经2