Dx11--用dx11绘制棱台,并用键盘和鼠标进行旋转缩放操作

本文详细讲解了如何在DirectX11中使用索引缓冲减少顶点冗余,以及常量缓冲优化性能,通过键盘鼠标控制棱台旋转和缩放。涉及索引缓冲创建、常量缓冲初始化和实际应用示例。

目录

一、索引缓冲区:

前言:

创建缓冲区:

缓冲区的描述:

二、常量缓冲区:

前言:

准备工作:

正式初始化:

 画面更新及其效果:

画面更新:

效果:

三、键盘和鼠标的创建:

1.鼠标的创建:

2.键盘的创建:

 3.更新画面:

4.消息回调函数(处理键盘鼠标信息):

效果:


一、索引缓冲区:

前言:

当我们要绘制如下图所示的立体图形棱台时,如果我们用顶点缓冲区来绘制的话,那我们需要绘制36个顶点。其中,我们知道棱台也就拥有8个顶点,这也说明了其余的28个顶点是重复的顶点

能不能减少顶点的创建获得内存与性能的提升呢?那么,索引缓冲区的作用就来了!

1.下图是棱台的八个顶点

 2.然后我们再把顶点数据放到索引数组里,我们就可以重复地利用顶点数据了,如下图所示

 解释:如0,1,2就是利用第0个顶点,第1个顶点和第2个顶点绘制了一个三角形,所以这里,我们就利用了012,230六个顶点即两个三角形来绘制正面(四边形)

 似乎特别容易理解,但是我们还没有创建索引缓冲区呢!我们需要索引缓冲区来和设备上下文打交道。

创建缓冲区:

//=======================================索引缓存的设置==============================================

	// --------索引数组
	DWORD indices[] =
	{
		// 正面
		0, 1, 2,
		2, 3, 0,
		// 左面
		4, 5, 1,
		1, 0, 4,
		// 顶面
		1, 5, 6,
		6, 2, 1,
		// 背面
		7, 6, 5,
		5, 4, 7,
		// 右面
		3, 2, 6,
		6, 7, 3,
		// 底面
		4, 0, 3,
		3, 7, 4
	};

	// -------描述索引缓冲区
	D3D11_BUFFER_DESC ibd;
	ZeroMemory(&ibd, sizeof(ibd));
	ibd.Usage = D3D11_USAGE_IMMUTABLE;
	ibd.ByteWidth = sizeof indices;
	ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
	ibd.CPUAccessFlags = 0;


	// -------创建索引缓冲区
	InitData.pSysMem = indices;
	HR(m_pDevice->CreateBuffer(&ibd, &InitData, m_pIndexBuffer.GetAddressOf()));
	//=======================================索引缓存的设置==============================================

 设备创建缓冲区函数(和顶点缓冲区,常量缓冲区的创建是一样):CreateBuffer

参数1:缓冲区的描述

参数2:数据的来源/资源

参数3:取得缓冲区的指针

参数2中的资源,我们在前面已经分析过了,也就是把索引数组指针赋给InitData.pSysMem,再传给参数2。然后参数3用我们的成员变量m_pIndexBuffer来取得就好。这些都比较容易理解。参数1是获取缓冲区描述的指针,也就是说,我们需要对缓冲区进行描述。

缓冲区的描述:

        结构原型:

typedef struct D3D11_BUFFER_DESC 
{ 
UINT ByteWidth; 
D3D11_USAGE Usage; 
UINT BindFlags; 
UINT CPUAccessFlags; 
UINT MiscFlags; 
UINT StructureByteStride;
 }
 D3D11_BUFFER_DESC;

1.ByteWidth:缓冲区大小

2.Usage:缓冲区的读取和写入方式,一般为D3D11_USIC_DEFAULT,这里使用D3D11_USAGE_IMMUTABLE

3.BindFlags:标识缓冲区将如何绑定到管道。

4.CPUAccessFlags:CPU访问标志,不访问CPU时,值为0

5.MiscFlags:杂项标识,未使用,则为0

6.StructureByteStride:每个元素的大小

到了这里,我们的索引缓冲区就创建成功了!

二、常量缓冲区:

前言:

一个常量缓冲区被用来向一个正在管线中执行的可编程着色器 应用程序提供常量信息。我们所说的常量,一般就是不会发生实质变化的量,那么我们就可以利用常量缓冲区进行世界矩阵,投影矩阵等变换。

//======================================常量缓冲区的设置=====================================================

	// --------描述常量缓冲区
	D3D11_BUFFER_DESC cbd;
	ZeroMemory(&cbd, sizeof(cbd));
	cbd.Usage = D3D11_USAGE_DYNAMIC;
	cbd.ByteWidth = sizeof(ConstantBuffer);
	cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	cbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;

	// --------新建常量缓冲区
	HR(m_pDevice->CreateBuffer(&cbd, nullptr, m_pConstantBuffer.GetAddressOf()));


	//--------- 初始化常量缓冲区
	// 
	//返回单位矩阵
	m_CBuffer.world = XMMatrixIdentity();

	//因为HLSL中的矩阵按列主序,又由于world为单位阵,所以我们把view和proj进行转置
	//矩阵转置
	m_CBuffer.view = XMMatrixTranspose

	//XMMatrixLookAtLH函数,基于左手坐标系,返回将点从世界空间转换为视图空间的视图矩阵,参1:摄像机的位置
							//	参2:协调中心的位置
							//参数3:相机向上的向量,表示3D坐标系中向上的坐标向量,这里表示屏幕由底向上递增的向上,这是一个规范化的坐标系
	(XMMatrixLookAtLH
	(
		XMVectorSet(0.0f, 0.0f, -5.0f, 0.0f),
		XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f),
		XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f)//以世界空间的y轴作为摄像机“向上”的方向。因此(0, 1, 0)是平行于世界空间中y轴的一个单位向量
	));

	m_CBuffer.proj = XMMatrixTranspose(XMMatrixPerspectiveFovLH(XM_PIDIV2, AspectRatio(), 1.0f, 1000.0f));
	//XMMatrixPerspectiveFovLH函数,返回透视投影矩阵,参数1:以弧度为单位的自顶向下视场角度,参数2:视宽比,参数3:距离近切飞机的距离,大于零。参数4:距离遥远的剪裁飞机,大于零
	


	//======================================常量缓冲区的设置=====================================================

 创建常量缓冲区的操作与创建索引缓冲区的操作类似,因此就不再展开。

我们来看下缓冲区的初始化。

准备工作:

1.这时候,我们就需要在HLSL头文件新增部分代码:

cbuffer :用于声明一个常量缓冲区

matrix :等价于 float4x4的矩阵

register(b0): 常量缓冲区位于寄存器索引为0的缓冲区

2.并改动HLSL头文件部分代码:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值