Driect3D初始化演示
初始化Direct3D演示(第四章内容)
初始化Driect3D类:
#include "Common\d3dApp.h"
#include <DirectXColors.h>
using namespace DirectX;
class InitDirect3DApp : public D3DApp
{
public:
InitDirect3DApp(HINSTANCE hInstance);
~InitDirect3DApp();
virtual bool Initialize()override;
private:
virtual void OnResize()override;
virtual void Update(const GameTimer& gt)override;
virtual void Draw(const GameTimer& gt)override;
};
InitDirect3DApp::InitDirect3DApp(HINSTANCE hInscance) :D3DApp(hInscance)
{
}
InitDirect3DApp::~InitDirect3DApp()
{
}
bool InitDirect3DApp::Initialize()
{
if (!D3DApp::Initialize())
{
return false;
}
return true;
}
void InitDirect3DApp::OnResize()
{
D3DApp::OnResize();
}
void InitDirect3DApp::Update(const GameTimer& gt)
{
}
void InitDirect3DApp::Draw(const GameTimer& gt)
{
//重置命令分配器
ThrowIfFailed(mDirectCmdListAlloc->Reset());
//重置命令列表
ThrowIfFailed(mCommandList->Reset(mDirectCmdListAlloc.Get(), nullptr));
//对资源的状态进行转变,将资源从呈现状态转变到渲染目标状态
mCommandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(
CurrentBackBuffer(),
D3D12_RESOURCE_STATE_PRESENT,
D3D12_RESOURCE_STATE_RENDER_TARGET
));
//设置视口和裁剪矩形,他们需要跟随命令列表的重置而重置
mCommandList->RSSetViewports(1, &mScreenViewport);
mCommandList->RSSetScissorRects(1, &mScissorRect);
//清除后台缓冲区和深度缓冲区
mCommandList->ClearRenderTargetView(CurrentBackBufferView(), Colors::LightSteelBlue, 0, nullptr);
mCommandList->ClearDepthStencilView(DepthStencilView(), D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL,
1.0f, 0, 0, nullptr);
//指定将要渲染的缓冲区
mCommandList->OMSetRenderTargets(1, &CurrentBackBufferView(), true, &DepthStencilView());
//再次对资源状态进行转变,将资源从渲染目标状态转变为呈现状态
mCommandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(
CurrentBackBuffer(), D3D12_RESOURCE_STATE_RENDER_TARGET,
D3D12_RESOURCE_STATE_PRESENT
));
//完成命令的记录
ThrowIfFailed(mCommandList->Close());
//将命令列表的命令加入到命令队列中
ID3D12CommandList* cmdsList[] = { mCommandList.Get() };
mCommandQueue->ExecuteCommandLists(_countof(cmdsList), cmdsList);
//交换前后台缓冲区
ThrowIfFailed(mSwapChain->Present(0, 0));;
mCurrBackBuffer = (mCurrBackBuffer + 1) % SwapChainBufferCount;
//等待此帧的命令执行完毕
FlushCommandQueue();
}
主函数:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
{
//为调试版本开启运行时内存检测,方便监督内存泄漏的情况
#if defined(DEBUG) | defined(_DEBUG)
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
try
{
InitDirect3DApp theApp(hInstance);
if (!theApp.Initialize())
{
return 0;
}
return theApp.Run();
}
catch (DxException& e)
{
MessageBox(nullptr, e.ToString().c_str(), L"HR Failed", MB_OK);
return 0;
}
}
运行结果
接下来我们将介绍一些在前面没有提到的方法:
1、ClearRenderTargetView():将指定的渲染目标清理为给定的颜色
2、ClearDepthStencilView():清理指定的深度/模板缓冲区
3、OMSetRenderTargets():设置我们希望在渲染流水线上使用的渲染目标和深度/模板缓冲区
调试Direct3D应用程序
大多数的Direct3D函数会返回HRESULT错误码,我们的示例程序则采用简单的错误处理机制检测返回的HRESULT值,如果检测失败。则抛出异常,显示调用出错的错误码,函数名,文件名以及发生错误的行号,这些操作都由d3dUtil.h中的代码实现:
class DxException
{
public:
DxException() = default;
DxException(HRESULT hr, const std::wstring& functionName, const std::wstring& filName, int lineNumber);
std::wstring ToString()const;
HRESULT ErrorCode = S_OK;
std::wstring FunctionName;
std::wstring FileName;
int LineNumber = -1;
};
#ifndef ThrowIfFailed
#define ThrowIfFailed(x) \
{ \
HRESULT hr__ = (x); \
std::wstring wfn = AnsiToWString(__FILE__); \
if(FAILED(hr__)) { throw DxException(hr__, L#x, wfn, __LINE__); } \
}
#endif
由上面的代码可以看出来,ThrowifFailed是一个宏而不是一个函数,如果ThrowifFailed是一个函数,那么__FILE__和__LINE__将会定位到ThrowifFailed函数所在的文件和行,而不是出错函数的文件和行。
L#x会将ThrowifFailed的参数转换为Unicode字符串,这样一来,我们就可以将函数调用的错误信息输出到消息框中。
第四章小结
- Direct3D是一种介于程序员和硬件之间的桥梁,通过这个桥梁,程序员可以通过调用Direct3D函数来实现把资源视图绑定到硬件渲染流水线中,配置渲染流水线的输出以及绘制3D几何体等操作
- 组件对象模型(COM)是一种可以使DirectX不依赖任何特定语言且向后兼容的技术
- 1D、2D、3D纹理类似于有数据元素构成的1D、2D、3D数组,纹理元素的格式必定是DXGI_FORAMT枚举类型中的其中一种,纹理除了可以存储图像数据之外,还可以存储想深度信息等其他类型的数据
- 前台缓冲区和后台缓冲区构成了交换链,交换链在代码中可以通过IDXGISwapChain接口表示,使用两个缓冲区的情况称之为双缓冲,交换链的存在可以避免出现动画中出现闪烁的问题(前台缓冲区和后台缓冲区互换的操作称之为呈现)
- 深度缓冲是一种用于确定物体在场景中离摄像机最近点的技术,通过深度缓冲,我们可以不用考虑物体在场景中绘制的先后顺序
- 在Driect3D中,资源不可以直接和渲染流水线相互绑定,因此我们需要为绘制调用时所引用的资源指定描述符,描述符可以视为GPU识别以及描述资源的一种轻量级结构体,我们还可以为一种资源创建不同的描述符,这样我们就可以让一种资源具有多种用途。应用程序可以通过创建描述符堆来存储描述符。
- ID3DDeviec是Direct3D最重要的接口,我们可以把它看作是图形硬件设备的软件控制器,我们可以通过ID3DDevice来创建GPU资源以及其他一些用于控制图形硬件设备的特定接口
- 每一个GPU都有一个命令队列,CPU可以通过Direct3D API用命令列表来向该队列提交命令,这些命令将指挥GPU进行各种操作,在命令没有到达队列首部之前,该命令是不会被执行的。
- GPU是系统中和CPU一起并行工作的第二种处理器,我们需要对CPU和GPU进行同步
- 性能计数器是一种高精度的计时器,它是测量微小时间差的一种有效工具,性能计数器使用的时间单位是计数,QueryPerformanceFrequency函数输出的是性能计数器每秒的计数,可以用它将计数单位转换为秒,QueryPerformanceCounter函数输出的是当前的时间值(以计数为单位)
- 通过统计时间段t内处理的帧数可以计算出每秒的平均帧数(FPS),不过为了更直观的对程序的性能进行考量,我们一般使用“处理一帧所花费的时间”这个统计信息。以秒为单位的每帧平均处理时间可以用帧率的倒数来进行计算,即:1/FPS
Driect3D初始化演示的更多相关文章
- Java三大器之监听器(Listener)的工作原理和代码演示
现在来说说Servlet的监听器Listener,它是实现了javax.servlet.ServletContextListener 接口的服务器端程序,它也是随web应用的启动而启动,只初始化一次, ...
- STL学习之路
本文面向的读者:学习过C++程序设计语言(也就是说学习过Template),但是还没有接触过STL的STL的初学者.这实际上是我学习STL的一篇笔记,老鸟就不用看了. 什么是泛型程序设计 我们可以简单 ...
- Vector示例一,二
#include <iostream> int main(void) { double a[] = {1, 2, 3, 4, 5}; std::cout<<mean(a, 5) ...
- Servlet,过滤器,监听器,拦截器的区别
1.过滤器 Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码.做一些业务逻辑判断等.其工作原理是,只要你在web.xml ...
- 027 hibernate查询语言(HQL)
概述:数据查询与检索是Hibernate中的一个亮点,相对其他ORM实现而言,Hibernate提供了灵活多样的查询机制. 标准化对象查询(Criteria Query):以对象的方式进行查询,将查询 ...
- java监听器(Listener)学习笔记
现在来说说Servlet的监听器Listener,它是实现了javax.servlet.ServletContextListener 接口的服务器端程序,它也是随web应用的启动而启动,只初始化一次, ...
- STL学习笔记(转,还是比较全的)
STL简介 1 概况 2 1.1 STL是什么 2 1.2 为什么我们需要学习STL 2 1.3 初识STL 2 1.4 STL 的组成 5 2 容器 6 2.1 基本容器——向量(vector) 6 ...
- web.xml中Listener的作用
Servlet的监听器Listener,它是实现了javax.servlet.ServletContextListener 接口的服务器端程序,它也是随web应用的启动而启动,只初始化一次,随web应 ...
- x86保护模式-六 控制转移
控制转移可以分为两大类 :同一任务内的控制转移 和 任务间的控制转移(任务切换) 同一个任务内的控制转移可以分为段内转移 .特权级不变的段间转移和特权级改变的段间转移 段内转移与实模式相同 ...
随机推荐
- 史上最全面的SignalR系列教程-5、SignalR 实现一对一聊天
1.概述 通过前面几篇文章 史上最全面的SignalR系列教程-1.认识SignalR 史上最全面的SignalR系列教程-2.SignalR 实现推送功能-永久连接类实现方式 史上最全面的Signa ...
- 枚举类&&注解&&反射
什么是枚举类? 枚举类是优化定义固定对象的一种特殊的类. 换句话说,在需要类的实例为一个或者多个并且相对固定的时候,使用枚举类.(枚举类可扩展) 类的实例相对来说固定的有日期,客观不变的一些数字等等. ...
- windows的磁盘操作之七——获取当前所有的物理磁盘号 加备注
windows的磁盘操作之七--获取当前所有的物理磁盘号 2011-07-28 17:47:56 标签:windows API DeviceIoControl 物理磁盘 驱动器号 原创作品,允许转载 ...
- 【在 Nervos CKB 上做开发】Nervos CKB 脚本编程简介[1]:验证模型
CKB 脚本编程简介[1]: 验证模型 本文作者:Xuejie 原文链接:Introduction to CKB Script Programming 1: Validation Model 本文译者 ...
- unity编辑器扩展_03(在组件中右击创建一个选项,并通过该选项修改该组件下面的字段的值)
在组件中右击创建一个选项代码: [MenuItem("CONTEXT/PlayerHealth/InitHealth")] static void Test5() { ...
- JNI开发流程
交叉编译 在一个平台上去编译另一个平台上可以执行的本地代码 cpu平台 arm x86 mips 操作系统平台 windows linux mac os 原理 模拟不同平台的特性去编译代码 jni开发 ...
- 业务代码的救星——Java 对象转换框架 MapStruct 妙用
简介 在业务项目的开发中,我们经常需要将 Java 对象进行转换,比如从将外部微服务得到的对象转换为本域的业务对象 domain object,将 domain object 转为数据持久层的 dat ...
- npm基本命令
1.npm是什么? npm(Node Package Manager)意思是 node 的包管理器,它是随着 NodeJs 安装时一起被安装的: 无论是在前端还是在前端开发中都会使用到 npm 包管理 ...
- P2564 [SCOI2009]生日礼物 贪心
https://www.luogu.org/problemnew/show/P2564) 题意 有n个珠子,包括k中颜色,找出长度最小的一个区间,使得这个区间中包含所有的颜色. 思路 把n个珠子按照位 ...
- 关于dijkstra的优化 及 多源最短路
先来看这样一道题目 给你N个点,M条双向边,要求求出1号点到其他所有点的距离.其中 2 <= N <= 1e5, 1 <=M <= 1e6. 对于这样的一道题目 我们当然不可 ...