编写DX12时使用的辅助类

news/2025/10/13 23:52:00/文章来源:https://www.cnblogs.com/wsdanshenmiao/p/19139717

编写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.mzph.cn/news/936529.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HLSL语法

语义 语义的概念语义xxxx:+ 大写单词,是用来限定输入值的来源、输出值的去向,其中那些大写单词都是系统提供的,我们需要用他们去填充我们的参数,然后传到顶点着色器和片元着色器中,进行进一步的计算,最后再通过…

DirectX12初始化

DirectX12初始化 这几天跟着龙书把dx12的初始化过了一遍,写点东西记一下,免得之后又忘了。 创建d3d设备 d3d设备相当于对显示适配器的抽象,显示适配器一般为显卡,也可由软件来模拟。可通过下列接口来创建一个d3d设…

用Vmware ESXI6.7离线包封装网卡驱动

用Vmware ESXI6.7离线包封装网卡驱动本来想装最新版的Vmware ESXI9.0的,但安装时提示找不到网卡无法安装,于是在网上搜索一番,发现可以用离线升级包封装网卡驱动的办法进行安装,但由于我的网卡是Realtek瑞昱RTL811…

CF2159B

Sol 假设 \(n<m\)。 考虑枚举列,然后对于每个位置分别做。 但是这非常难做,然后我们考虑包含 \([l,r]\) 这几行的最小矩形,然后发现这个东西可以在枚举列的时候同时计算,然后就做完了。 Code Link。

登录校验---Filter过滤器

过滤器(Filter)概念: Filter 过滤器,是 JavaWeb 三大组件(Servlet、Filter、Listener)之一。 过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。 过滤器一般完成一些通用的操作,比如: 登录校验、统一编码…

环境变量 Path 配置实战指南:从“能用”到“专业”--两种配置环境变量的方法

本指南将通过一个完整的实例,手把手教你如何配置 `Path` 环境变量。我们将超越“如何做”,深入探讨“为什么这么做”,让你彻底理解直接路径与引用路径的本质区别。我们将以配置 Java 开发环境为例,让你清晰地看到每…

10月13日

上午建模语言和数据结构课程 下午听讲Java知识点和练习数据库

Ubuntu22.04安装CH340/CH341驱动

转载自: 陈拓 2024/12/20-2024/12/20 https://zhuanlan.zhihu.com/p/137683332711. 我的系统硬件系统架构arch操作系统版本lsb_release -a2. CH340G,USB-串口转换器3. Ubuntu22.04安装CH340驱动 3.1 用lsusb查看USB插…

玄机蓝队靶场_应急响应_198:实战Live勒索病毒溯源排查

前言: 版权作者:思而听(山东)网络科技有限公司、solar应急响应团队、州弟学安全 特别注意:环境中的勒索家族全版本加密器已被 solar应急响应团队 破解 系统:Windows server 2016 账号密码:administrator/Sierting…

JetBrains Mono字体好看、及其它

请注意箭头。还有输入的是grep != 另外,进到那个深深的目录里后,可以: ln -s `readlink -f .` somewhere 目录不能有hard link,原因可问AI.

STM32——UART

UART通信协议(串口通信) 1、两根通信线(发送和接收),TX与RX要交叉连接。只需进行单向通讯时可只连接一根通信线。 2、仅支持点对点的通信,不像I2C、SPI支持一对多通信。 3、进行通信的两设备电平标准必须一致,当…

WebApi 交叉观察者- IntersectionObserver复盘

交叉观察者- IntersectionObserver复盘 一、 Intersection Observer是什么? Intersection Observer API 提供了一种异步观察目标元素与祖先元素或视口交叉状态的方法。通俗地说,就是可以高效地监测一个元素是否进入或…

[KaibaMath]1009 关于||a|-|b||≤|a+b|的证明

[KaibaMath]1009 关于||a|-|b||≤|a+b|的证明绝对值的三角形不等式为||a|-|b||≤|ab|≤|a|+|b|. 本文给出前半段的证明,即证明||a|-|b||≤|ab|.

css: Bootstrap5 Accordions

<!doctype html> <html> <head> <meta charset="utf-8"> <title>Bootstrap5 Accordions</title><link rel="stylesheet" href="https://cdn.jsdeliv…

AMPopTip - 优雅的iOS动画提示框库

AMPopTip是一个功能丰富的iOS动画提示框库,支持多种弹出方向和箭头样式,可高度自定义颜色、边框和字体,适用于用户引导和界面提示等场景,让应用交互更加生动有趣。AMPopTip AMPopTip 是一个优雅的动画弹出提示框,…

2026年深度对比值得推荐的10个在线客服系统

1. 唯一客服—— 可独立部署的高性能客服系统源码唯一客服系统主要功能是,为网站或APP等提供在线即时聊天功能,可以方便客户与我们的客服人员进行实时沟通的。主要用户群体是中小互联网科技公司,有自己的开发产品,…

文件名中有空格比较烦人

我们已经造好了两个文件:" t.sh"和"t m p" $ " t.sh" "t m p" OK $ " t.sh t m p" # 首先找不到t.sh,其次就算找到,接收到的也是3个参数t, m, p不是一个"t…

十月总结

10.11 广二 T1:计数、容斥原理 有一个计数的做法,大致做法是在最后面的开头统计,然后要求后面不能出现,这样贡献就是唯一的,需要fail树上跑下来dfn这样 容斥原理就比较直接,加上序列中有一个开头的,减去有两个开…

20251013 之所思 - 人生如梦

20251013 之所思1. 前天老板约了一个会议,讨论log的录制,防止问题发生时无法录到现场的数据而反复要求实车同事去复现问题采集数据。当我发言时被另一个同事打断并说表达的不正确,当时很气愤,一是自己刚刚开始发言…