DirectX11学习笔记二 渲染一个立方体

本文是DirectX11学习笔记的第二部分,讲解了如何渲染一个立方体,包括顶点缓冲区、索引缓冲区的概念。作者介绍了MVP变换的重要性,探讨了矩阵乘法的左乘和右乘,以及空间类型的转换。同时,文章涵盖了数学基础,如向量、矩阵、平移、旋转和缩放。最后,讨论了DirectX11与OpenGL在数学上的差异,并提出思考,如如何在立方体旁创建四棱锥。
摘要由CSDN通过智能技术生成

上一节学习笔记地址
  上一节画三角形只有三个顶点,所以直接按照三个顶点顺序画即可。不过那里漏过了一个细节,那就是你的三角形的顶点顺序,这里要引入一个叫“背面消除(backface culling)”的概念。因为三角形有两个面,假如你的正面是背对着摄像机,那摄像机就不会渲染你三角形的正面的图像(被剔除掉),复习一下上节所传入的三角形顶点。

	// 设置三角形顶点
	VertexPosColor vertices[] =
	{
   
		{
    XMFLOAT3(0.0f, 0.5f, 0), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
		{
    XMFLOAT3(0.5f, -0.5f, 0), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) },
		{
    XMFLOAT3(-0.5f, -0.5f, 0), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) }
	};

在这里插入图片描述
  DX使用左手坐标系,并规定顶点顺序按照顺时针排序的为正面,那另一面就是反面。
  可以修改这种剔除方法Device->SetRenderState(D3DRS_CULLMODE,Value);
  可以传入三种参数

参数 描述
D3DCULL_NONE 表示不采用背面消除,那么此时,不过正面指向哪里都将不会被剔除掉
D3DCULL_CW 表示跟我们刚才说的相反,按右手顺时针方向指向的的方向指向我们的眼睛的话,那么剔除掉
D3DCULL_CCW 默认值,顺时针为正面

  所以,如果你把第一个顶点和第三个顶点调换,就显示不出东西了,因为你看到的是背面。
  如果你要渲染一个四边形,可以在三角形的基础上再加三个点,,这样就变成了两个三角形,6个顶点,表示一个四边形,但是实际上有两个顶点是重复的,在顶点比较多的时候,会引起巨大的浪费,比如渲染一个立方体,甚至一个顶点会重复更多次,所以为了节省资源,DX引入了索引这个概念。
  另外,由于我们现在渲染的是3维空间,必然要引入MVP变换,这个到着色器里再说。

顶点缓冲区

// ******************
	// 设置立方体顶点
	//    5________ 6
	//    /|      /|
	//   /_|_____/ |
	//  1|4|_ _ 2|_|7
	//   | /     | /
	//   |/______|/
	//  0       3
	VertexPosColor vertices[] =
	{
   
		{
    XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f) },
		{
    XMFLOAT3(-1.0f, 1.0f, -1.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) },
		{
    XMFLOAT3(1.0f, 1.0f, -1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
		{
    XMFLOAT3(1.0f, -1.0f, -1.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
		{
    XMFLOAT3(-1.0f, -1.0f, 1.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) },
		{
    XMFLOAT3(-1.0f, 1.0f, 1.0f), XMFLOAT4(1.0f, 0.0f, 1.0f, 1.0f) },
		{
    XMFLOAT3(1.0f, 1.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
		{
    XMFLOAT3(1.0f, -1.0f, 1.0f), XMFLOAT4(0.0f, 1.0f, 1.0f, 1.0f) }
	};
	// 设置顶点缓冲区描述
	D3D11_BUFFER_DESC vbd;
	ZeroMemory(&vbd, sizeof(vbd));
	vbd.Usage = D3D11_USAGE_IMMUTABLE;
	vbd.ByteWidth = sizeof vertices;
	vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	vbd.CPUAccessFlags = 0;
	// 新建顶点缓冲区
	D3D11_SUBRESOURCE_DATA InitData;
	ZeroMemory(&InitData, sizeof(InitData));
	InitData.pSysMem = vertices;
	HR(m_pd3dDevice->CreateBuffer(&vbd, &InitData, m_pVertexBuffer.GetAddressOf()));
	m_pd3dImmediateContext->IASetVertexBuffers(0, 1, m_pVertexBuffer.GetAddressOf(), &stride, &offset);

  方法与上一节的笔记一样,只不过变成了8个顶点,三维空间坐标。

索引缓冲区

  索引会引导DX选择渲染次序。

// ******************
	// 索引数组
	//
	WORD 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_pd3dDevice->CreateBuffer(&ibd, &InitData, m_pIndexBuffer.GetAddressOf()));
	// 输入装配阶段的索引缓冲区设置
	m_pd3dImmediateContext->IASetIndexBuffer(m_pIndexBuffer.Get(), DXGI_FORMAT_R16_UINT, 0);

  方法同上文的顶点缓冲区类似,简单比较一下就能看懂了。

void ID3D11DeviceContext::IASetIndexBuffer( 
    ID3D11Buffer *pIndexBuffer,     // [In]索引缓冲区
    DXGI_FORMAT Format,             // [In]数据格式
    UINT Offset);                   // [In]字节偏移量

  在装配的时候你需要指定每个索引所占的字节数:’

Format参数 字节数 索引范围
DXGI_FORMAT_R8_UINT 1 0-255
DXGI_FORMAT_R16_UINT 2 0-65535
DXGI_FORMAT_R32_UINT 4 0-2147483647

  使用16位的索引有利于节省空间,现阶段绝大多数模型的顶点数目都少于65535个。

数学基础

  补习一下向量和线代的知识

向量(vector)
  向量由模(magnitude)和方向(direction)组成,与标量(scalar)区分。
标量与向量积
在这里插入图片描述
向量加法
在这里插入图片描述
二维向量加法的几何意义
在这里插入图片描述
向量的模
在这里插入图片描述
向量单位化
在这里插入图片描述
向量点积(dot product)
在这里插入图片描述
在这里插入图片描述
  (ka)b=a(kb)=k(ab)
  a(b+c)=ab+ac
  vv=|v|^2
向量点积的几何意义
在这里插入图片描述
向量叉积(cross product)
在这里插入图片描述
  axb!=bxa
  axb=-(bxa)
  (axb)xc!=ax(bxc)
   叉积的几何意义: 得到垂直于a和b所在平面的向量。通过将a的头和b的尾相接,并检查从a到b是顺时针还是逆时针,能够确定a叉乘b的方向。左手坐标系中,如果a与b呈顺时针,则叉乘方向指向

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值