DirectX12(D3D12)基础教程五 3D入门旋转的立方体

在第二章的纹理程序基础上做简单的修改就可以显示旋转立方体效果如下:

做以下几点修改:

3D顶点坐标数据

我们从vertex.txt文件读取顶点数据与纹理,数据结构如下

cpp 复制代码
typedef struct _VertexData

{

       XMFLOAT4 position;

       XMFLOAT2 uv;

}VertexData;

这个立方体的3D坐标位置与纹理可以自已构建的(比较复杂模型由别人提供),这里为了简化代码从文件中读取,CVertexData类负责加载数据。代码:

cpp 复制代码
typedef struct _VertexData
{
	XMFLOAT4 position;
	XMFLOAT2 uv;
}VertexData;

typedef struct _SceneConstantBuffer
{
	XMFLOAT4X4 m_ModelViewProject;
	XMFLOAT4 offset;
	float padding[44];
}SceneConstantBuffer;

class CVertexData
{
public:
	void LoadData(const wchar_t*path);
	
	void* VertexDataPtr()
	{
		return m_listVertexData.data();
	}

	void* IndexDataPtr()
	{
		return m_listIndexData.data();
	}
	int VertexSize()
	{
		return m_listVertexData.size() * sizeof(VertexData);
		
	}
	int IndexSize()
	{
		return m_listIndexData.size() * sizeof(UINT32);
	}
	int IndexNumber()
	{
		return m_listIndexData.size();
	}

private:
	vector<VertexData> m_listVertexData;
	vector<UINT32>     m_listIndexData;
};

增加常量缓冲区视图 (CBV) 资源

存放3D模型数据, Cpu修改 世界空间模型,由于沿Y旋转, 改变角度达到自转目的。GPU-Shader读值,进行最后的运算。3D模型数据结构,数据对齐256,所以加float padding[44]

cpp 复制代码
typedef struct _SceneConstantBuffer
{
	XMFLOAT4X4 m_ModelViewProject;
	XMFLOAT4 offset;
	float padding[44];
}SceneConstantBuffer;

创建代码:

cpp 复制代码
void CD3D12Cube::CreateConstantBuffer(UINT64 bufferOffset, ComPtr<ID3D12Device>device, ComPtr<ID3D12Heap> uploadHeap, ComPtr<ID3D12DescriptorHeap>srvcbvHeap, ComPtr<ID3D12Resource>& cbvResource)
{
	UINT64 wSize = UPPER_ALING_DIV(sizeof(SceneConstantBuffer), 256);
	bufferOffset = UPPER_ALING_DIV(bufferOffset + wSize, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT);

	CreatePlacedResource(device
		, uploadHeap.Get()
		, bufferOffset
		, &CD3DX12_RESOURCE_DESC::Buffer(wSize)
		, D3D12_RESOURCE_STATE_GENERIC_READ
		, cbvResource);

	ThrowIfFailed(cbvResource->Map(0, nullptr, reinterpret_cast<void**>(&m_constantBufferData)));


	D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {};
	cbvDesc.BufferLocation = cbvResource->GetGPUVirtualAddress();
	cbvDesc.SizeInBytes = wSize;
	UINT nSRVSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
	D3D12_CPU_DESCRIPTOR_HANDLE stCPUCBVHandle = srvcbvHeap->GetCPUDescriptorHandleForHeapStart();
	stCPUCBVHandle.ptr += nSRVSize;
	m_device->CreateConstantBufferView(&cbvDesc, stCPUCBVHandle);

}

cbvResource->Map(,), 相连到内存,直接修改m_constantBufferData可以了。

3D模型转换

3D运算用的库.GitHub - microsoft/DirectXMath: DirectXMath is an all inline SIMD C++ linear algebra library for use in games and graphics apps

详情见第三章

裁剪空间 是我们最终目标

本地空间

本地空间 就是 顶点坐标

观察空间

XMMATRIX view = XMMatrixLookAtLH(m_vCameraPos, m_vLookAt, m_vUpDir); 自己构建,给特定值,写死的。

世界空间

XMMATRIX model = XMMatrixRotationY(static_cast<float>(m_dYAngle)); 给旋转角度。

观察空间

XMMATRIX view = XMMatrixLookAtLH(m_vCameraPos, m_vLookAt, m_vUpDir); 自己构建,给特定值,写死的。

投影空间

正射投影

正射投影矩阵定义了一个类似立方体的平截头箱,它定义了一个裁剪空间,在这空间之外的顶点都会被裁剪掉。创建一个正射投影矩阵需要指定可见平截头体的宽、高和长度。在使用正射投影矩阵变换至裁剪空间之后处于这个平截头体内的所有坐标将不会被裁剪掉。

透视投影

如果你曾经体验过实际生活给你带来的景象,你就会注意到离你越远的东西看起来更小。这个奇怪的效果称之为透视(Perspective)。这里用 透视投影.

cpp 复制代码
 XMMATRIX projection = XMMatrixPerspectiveFovLH(XM_PIDIV4, (FLOAT)m_nW / (FLOAT)m_nH, 0.1f, 1000.0f)

矩阵相乘

cpp 复制代码
XMMATRIX xmModelViewProject = XMMatrixMultiply(XMMatrixMultiply(model, view), projection);

XMStoreFloat4x4(&m_constantBufferData->m_ModelViewProject, xmModelViewProject);

UI刷新代码

cpp 复制代码
void CD3D12Cube::OnRender(void)
{

	UpdateConstantBufferData();

	PopulateCommandList();
}

//clip= projection*view*model*local
void CD3D12Cube::UpdateConstantBufferData()
{

	ULONGLONG n64tmCurrent = ::GetTickCount64();

	m_dYAngle += ((n64tmCurrent - m_n64tmFrameStart) / 1000.0f) * m_dbPalstance;
	m_n64tmFrameStart = n64tmCurrent;

	if (m_dYAngle > XM_2PI)
	{
		m_dYAngle = fmod(m_dYAngle, XM_2PI);
	}

	XMMATRIX model = XMMatrixRotationY(static_cast<float>(m_dYAngle));
	XMMATRIX view = XMMatrixLookAtLH(m_vCameraPos, m_vLookAt, m_vUpDir);
	XMMATRIX projection = XMMatrixPerspectiveFovLH(XM_PIDIV4, (FLOAT)m_nW / (FLOAT)m_nH, 0.1f, 1000.0f);

    //  从左向右读这个乘法 
    // 1.XMMatrixMultiply(model, view) 读法->  (model  * view)
    // 2. ((model *view ) )* projection
    // 3. XMMatrixMultiply 人性化了 
   
	XMMATRIX xmModelViewProject = XMMatrixMultiply(XMMatrixMultiply(model, view), projection);
	XMStoreFloat4x4(&m_constantBufferData->m_ModelViewProject, xmModelViewProject);
}

HelloCube.hlsl程序

cpp 复制代码
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

cbuffer SceneConstantBuffer : register(b0)
{
	float4x4 m_ModelViewProject;
	float4 offset;
	float padding[48];
};

struct PSInput
{
	float4 position : SV_POSITION;
	float2 uv : TEXCOORD;
};

Texture2D g_texture : register(t0);
SamplerState g_sampler : register(s0);

PSInput VSMain(float4 position : POSITION, float4 uv : TEXCOORD)
{
	PSInput result;
    //裁剪空间 = ModelViewProject 矩阵 乘 本地空间
    // 从左向右读这个乘法  position(本地空间) 乘 ModelViewProject 矩阵 
	result.position = mul(position, m_ModelViewProject);  
	result.uv = uv;
	return result;
}

float4 PSMain(PSInput input) : SV_TARGET
{
	return g_texture.Sample(g_sampler, input.uv);
}

注意

本章用CreatePlacedResource()替换CreateCommittedResource()分配资源

感谢大家的支持,如要问题欢迎提问指正。


相关推荐
daifgFuture18 小时前
Android 3D球形水平圆形旋转,旋转动态更换图片
android·3d
牧子川1 天前
【论文解读】CVPR2023 PoseFormerV2:3D人体姿态估计(附论文地址)
3d·cvpr2023·poseformerv2
资深设备全生命周期管理1 天前
优化版本,增加3D 视觉 查看前面的记录
3d
m0_748250741 天前
GPUCUDA 发展编年史:从 3D 渲染到 AI 大模型时代(上)
人工智能·3d
少林6592 天前
谷歌地图高清卫星地图2026中文版下载|谷歌地图3D卫星高清版 V7.3.6.9796 最新免费版下载 - 前端工具导航
3d·谷歌地图
LeonDL1682 天前
HALCON 深度学习训练 3D 图像的几种方式优缺点
人工智能·python·深度学习·3d·halcon·halcon训练3d图像·深度学习训练3d图像
xhload3d3 天前
图扑软件 | 带你体验 Low Poly 卡通三维世界
物联网·3d·智慧城市·html5·webgl·数字孪生·可视化·工业互联网·三维建模·工控·轻量化·中国风·卡通动画·写实风格·科技风·low poly
图扑数字孪生3 天前
基于 HT for Web 轻量化 3D 数字孪生数据中心解决方案
3d·数字孪生·三维可视化·数据中心·智慧机房
njsgcs3 天前
PolyGen:一个用于 3D 网格的自回归生成模型 论文阅读
3d
Angel Q.3 天前
PnP(Perspective-n-Point)算法 | 用于求解已知n个3D点及其对应2D投影点的相机位姿
数码相机·算法·3d·pnp