阿辉DirectX 11学习笔记二
2016-01-31 17:10
155 查看
上一小节任务完成了窗口初始化的任务,接下来将完成初始化Direct3D的任务,如下:
1. 定义我们想要检查的设备类型和特征级别;
2. 创建Direct3D设备,渲染环境和交换链;
3. 创建渲染对象;
4. 设置视口观察区;
5. 屏幕的清除和显示;
硬件设备:运行在图形硬件上的D3D设备,在所有设备中时最快的;
引用设备:用于在CPU上执行图形硬件所不支持的特性渲染,换句话说,就是在软件中完全模拟硬件计算。
软件驱动设备:允许开发者编写自己的渲染驱动用于Direct3D中;
WARP设备:高效CPU渲染设备,可模拟Direct3D的全部特性。
GetClientRect:获得客户用户区的坐标;
D3D_DRIVER_TYPE:设备驱动类型;
D3D_FEATURE_TYPE: 特征级别类型
具体代码:
然后,我们需要告诉硬件我们需要渲染怎样的一个环境,设备又是如何去渲染的。针对这,我们有三个工作要做:
创建Direct3D设备:一种用于自身与硬件通信的设备;
渲染环境:一种告诉设备怎样去绘制的渲染环境;
创建交换链:绘制怎样的环境;
1.一个用于创建设备的视频适配器(显卡)的指针。如果传入空,则使用默认显卡。如果在机器上装有多个显卡,就可以使用该参数;
2.我们希望创建的驱动设备类型;
3.实现软件渲染设备的动态库句柄。如果我们使用的驱动设备类型是软件设备的话,则该参数不能为空;
4.创建标志。0用于我们游戏的发布,D3D11_CREATE_DEVICE_DEBUG允许我们创建可供调试的设备;
5.我们所希望创建的特征级别的地址;
6.特征级别数组中特征级别的数量;
7.SDK版本号;
8.交换链描述对象;
9.
10.设备对象地址;
11.被创建成功的特征级别;
12.渲染环境的地址;
GetBuffer:(得到贴图的指针)
1.缓存索引(0给出第一个缓存);
2.尝试操纵的接口类型(2D贴图类型就是ID3D11Texture2)
3.获取缓存地址,必须使用LPVOID类型获得
1.所创建的2D贴图视图;
2.渲染目标描述,设置为NULL;
3.要创建渲染目标ID3D11RenderTargetView的地址;
OMSetRenderTarget:
1.绑定的视图数量;
2.渲染目标视图列表;
3.深度/模板视图;
以上我们基本已经完成的整个项目的细节工作,接下来我们只需将所有代码连接起来即可:
全部代码:
头文件1:
源文件1:
源文件2:
源文件3:
运行结果:
1. 定义我们想要检查的设备类型和特征级别;
2. 创建Direct3D设备,渲染环境和交换链;
3. 创建渲染对象;
4. 设置视口观察区;
5. 屏幕的清除和显示;
定义我们想要检查的设备类型和特征级别:
在Direct3D11中我们可以使用四种设备类型和三种特征级别,他们的名称和作用分别如下:硬件设备:运行在图形硬件上的D3D设备,在所有设备中时最快的;
引用设备:用于在CPU上执行图形硬件所不支持的特性渲染,换句话说,就是在软件中完全模拟硬件计算。
软件驱动设备:允许开发者编写自己的渲染驱动用于Direct3D中;
WARP设备:高效CPU渲染设备,可模拟Direct3D的全部特性。
具体代码:
RECT dimensions; GetClientRect(hwnd,&dimensions); unsigned int width=dimensions.right-dimensions.left; unsigned int height=dimensions.bottom-dimensions.top; //驱动类型 D3D_DRIVER_TYPE driverTypes[]= { D3D_DRIVER_TYPE_HARDWARE,D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_REFERENCE,D3D_DRIVER_TYPE_SOFTWARE }; unsigned int totalDriverTypes=ARRAYSIZE(driverTypes);//返回设备类型的数目 //特征级别 D3D_FEATURE_LEVEL featureLevels[]= { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0 }; unsigned int totalFeatureLevels=ARRAYSIZE(featureLevels);//返回特征级别的数目
解释:
RECT:用来存储成对出现的参数;GetClientRect:获得客户用户区的坐标;
D3D_DRIVER_TYPE:设备驱动类型;
D3D_FEATURE_TYPE: 特征级别类型
创建Direct3D设备,渲染环境和交换链:
交换链是设备中渲染目标的集合,所谓渲染目标,就是你想将目的窗口渲染为何种风格,所以首先我们要初始化交换链,确定风格:具体代码:
DXGI_SWAP_CHAIN_DESC swapChainDesc; ZeroMemory(&swapChainDesc,sizeof(swapChainDesc));//用0来填充某一存储区,第一个参数代表填充的起始地址,第二个参数代表填充的长度 swapChainDesc.BufferCount=1;//缓存页的数量 swapChainDesc.BufferDesc.Width=width;//缓存页的宽度 swapChainDesc.BufferDesc.Height=height;//缓存页的高度 swapChainDesc.BufferDesc.Format=DXGI_FORMAT_R8G8B8A8_UNORM;//缓存格式 swapChainDesc.BufferDesc.RefreshRate.Numerator=60;//刷新率的分子 swapChainDesc.BufferDesc.RefreshRate.Denominator=1;// 刷新率的分母 swapChainDesc.BufferUsage=DXGI_USAGE_RENDER_TARGET_OUTPUT;//缓存器的使用方法 swapChainDesc.OutputWindow=hwnd;//窗口句柄 swapChainDesc.Windowed=true;//是否在全屏模式中D3D继续原来的尺寸还是resize swapChainDesc.SampleDesc.Count=1;//取样数量 swapChainDesc.SampleDesc.Quality=0;//取样质量
然后,我们需要告诉硬件我们需要渲染怎样的一个环境,设备又是如何去渲染的。针对这,我们有三个工作要做:
创建Direct3D设备:一种用于自身与硬件通信的设备;
渲染环境:一种告诉设备怎样去绘制的渲染环境;
创建交换链:绘制怎样的环境;
具体代码:
unsigned int creationFlags=0; #ifdef _DEBUG creationFlags|=D3D11_CREATE_DEVICE_DEBUG; #endif HRESULT result; unsigned int driver=0; for(driver=0;driver<totalDriverTypes;++driver) { result=D3D11CreateDeviceAndSwapChain(0,driverTypes[driver],0,creationFlags,featureLevels,totalFeatureLevels,D3D11_SDK_VERSION, &swapChainDesc,&swapChain_,&d3dDevice_,&featureLevel_,&d3dContext_); if(SUCCEEDED(result)) { driverType_=driverTypes[driver]; break; } } if(FAILED(result)) { DXTRACE_MSG("Failed to create the Direct3D device!"); return false; } ID3D11Texture2D* backBufferTexture; result=swapChain_->GetBuffer(0,_uuidof(ID3D11Texture2D),(LPVOID*)&backBufferTexture); if(FAILED(result)) { DXTRACE_MSG("Failed to get the swap chain back buffer!"); return false; }
解释:
D3DCreateDeviceAndSwapChain(各参数解释如下):1.一个用于创建设备的视频适配器(显卡)的指针。如果传入空,则使用默认显卡。如果在机器上装有多个显卡,就可以使用该参数;
2.我们希望创建的驱动设备类型;
3.实现软件渲染设备的动态库句柄。如果我们使用的驱动设备类型是软件设备的话,则该参数不能为空;
4.创建标志。0用于我们游戏的发布,D3D11_CREATE_DEVICE_DEBUG允许我们创建可供调试的设备;
5.我们所希望创建的特征级别的地址;
6.特征级别数组中特征级别的数量;
7.SDK版本号;
8.交换链描述对象;
9.
10.设备对象地址;
11.被创建成功的特征级别;
12.渲染环境的地址;
GetBuffer:(得到贴图的指针)
1.缓存索引(0给出第一个缓存);
2.尝试操纵的接口类型(2D贴图类型就是ID3D11Texture2)
3.获取缓存地址,必须使用LPVOID类型获得
创建渲染目标视图:
当做完了之前的基础工作后,我们就需要完成输出了,在完成输出时,我们要创建和绑定目标视图:具体代码:
result=d3dDevice_->CreateRenderTargetView(backBufferTexture,0,&backBufferTarget_); if(backBufferTexture) backBufferTexture->Release(); if(FAILED(result)) { DXTRACE_MSG("Failed to create the Direct3D device!"); return false; } d3dContext_->OMSetRenderTargets(1,&backBufferTarget_,0);
解释:
CreateRenderTargetView:1.所创建的2D贴图视图;
2.渲染目标描述,设置为NULL;
3.要创建渲染目标ID3D11RenderTargetView的地址;
OMSetRenderTarget:
1.绑定的视图数量;
2.渲染目标视图列表;
3.深度/模板视图;
视口 Viewport
定义:我们要渲染的区域
视口 Viewport可以通过填充D3D11_VIEWPORT对象来创建,通过调用RSSetViewports函数来设置它作为渲染环境。具体代码:(创建和设置全屏视口)
D3D11_VIEWPORT viewport; viewport.Width=static_cast<float>(width); viewport.Height=static_cast<float>(height); viewport.MinDepth=0.0f; viewport.MaxDepth=1.0f; viewport.TopLeftX=0.0f; viewport.TopLeftY=0.0f; d3dContext_->RSSetViewports(1,&viewport);
屏幕的清除和显示:
定义:清理并释放你创建的对象
首先确保对象不为NULL,再对他们调用Release函数进行释放:具体代码:
if(backBufferTarget_)backBufferTarget_->Release(); if(swapChain_)swapChain_->Release(); if(d3dContext_)d3dContext_->Release(); if(d3dDevice_)d3dDevice_->Release();
以上我们基本已经完成的整个项目的细节工作,接下来我们只需将所有代码连接起来即可:
全部代码:
头文件1:
#ifndef _BLANK_DEMO_H_ #define _BLANK_DEMO_H_ #include"Dx11DemoBase.h" class BlankDemo:public Dx11DemoBase { public: BlankDemo(); virtual ~BlankDemo(); bool LoadConent(); void UnloadContent(); void Update(float dt); void Render(); }; #endif 头文件2: #ifndef _DEMO_BASE_H_ #define _DEMD_BASE_H_ #include<d3d11.h> #include<d3dx11.h> #include<DxErr.h> class Dx11DemoBase { public: Dx11DemoBase(); virtual ~Dx11DemoBase(); bool Initialize(HINSTANCE hinstance,HWND hwnd); void Shutdown(); virtual bool LoadContent(); virtual void UnloadContent(); virtual void Update(float dt)=0; virtual void Render()=0; protected: HINSTANCE hinstance_; HWND hwnd_; D3D_DRIVER_TYPE driverType_; D3D_FEATURE_LEVEL featureLevel_; ID3D11Device* d3dDevice_; ID3D11DeviceContext* d3dContext_; IDXGISwapChain* swapChain_; ID3D11RenderTargetView* backBufferTarget_; }; #endif
源文件1:
#include"BlankDemo.h" BlankDemo::BlankDemo() {} BlankDemo::~BlankDemo() {} bool BlankDemo::LoadConent() { return true; } void BlankDemo::UnloadContent() {} void BlankDemo::Update(float dt) {} void BlankDemo::Render() { if(d3dContext_==0) return; float clearColor[4]={0.0f,0.0f,0.25f,1.0f}; d3dContext_->ClearRenderTargetView(backBufferTarget_,clearColor); swapChain_->Present(0,0); }
源文件2:
#include"Dx11DemoBase.h"
Dx11DemoBase::Dx11DemoBase():driverType_(D3D_DRIVER_TYPE_NULL),featureLevel_(D3D_FEATURE_LEVEL_11_0),
d3dDevice_(0),d3dContext_(0),swapChain_(0),backBufferTarget_(0)
{}
Dx11DemoBase::~Dx11DemoBase()
{
Shutdown();
}
bool Dx11DemoBase::LoadContent()
{
//Override with demo specifics,if any...
return true;
}
void Dx11DemoBase::UnloadContent()
{
//Override with demo specifics,if any...
}
void Dx11DemoBase::Shutdown()
{
UnloadContent();
if(backBufferTarget_)backBufferTarget_->Release(); if(swapChain_)swapChain_->Release(); if(d3dContext_)d3dContext_->Release(); if(d3dDevice_)d3dDevice_->Release();
backBufferTarget_=0;
swapChain_=0;
d3dContext_=0;
d3dDevice_=0;
}
bool Dx11DemoBase::Initialize(HINSTANCE hinstance,HWND hwnd)
{
hinstance_=hinstance;
hwnd_=hwnd;
RECT dimensions;
GetClientRect(hwnd,&dimensions);
unsigned int width=dimensions.right-dimensions.left;
unsigned int height=dimensions.bottom-dimensions.top;
D3D_DRIVER_TYPE driverTypes[]=
{
D3D_DRIVER_TYPE_HARDWARE,D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,D3D_DRIVER_TYPE_SOFTWARE
};
unsigned int totalDriverTypes=ARRAYSIZE(driverTypes);
D3D_FEATURE_LEVEL featureLevels[]=
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0
};
unsigned int totalFeatureLevels=ARRAYSIZE(featureLevels);
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory(&swapChainDesc,sizeof(swapChainDesc));
swapChainDesc.BufferCount=1;
swapChainDesc.BufferDesc.Width=width;
swapChainDesc.BufferDesc.Height=height;
swapChainDesc.BufferDesc.Format=DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferDesc.RefreshRate.Numerator=60;
swapChainDesc.BufferDesc.RefreshRate.Denominator=1;
swapChainDesc.BufferUsage=DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.OutputWindow=hwnd;
swapChainDesc.Windowed=true;
swapChainDesc.SampleDesc.Count=1;
swapChainDesc.SampleDesc.Quality=0;
unsigned int creationFlags=0;
#ifdef _DEBUG
creationFlags|=D3D11_CREATE_DEVICE_DEBUG;
#endif
HRESULT result;
unsigned int driver=0;
for(driver=0;driver<totalDriverTypes;++driver)
{
result=D3D11CreateDeviceAndSwapChain(0,driverTypes[driver],0,creationFlags,featureLevels,totalFeatureLevels,D3D11_SDK_VERSION,
&swapChainDesc,&swapChain_,&d3dDevice_,&featureLevel_,&d3dContext_);
if(SUCCEEDED(result))
{
driverType_=driverTypes[driver];
break;
}
}
if(FAILED(result))
{
DXTRACE_MSG("Failed to create the Direct3D device!");
return false;
}
ID3D11Texture2D* backBufferTexture;
result=swapChain_->GetBuffer(0,_uuidof(ID3D11Texture2D),(LPVOID*)&backBufferTexture);
if(FAILED(result))
{
DXTRACE_MSG("Failed to get the swap chain back buffer!");
return false;
}
result=d3dDevice_->CreateRenderTargetView(backBufferTexture,0,&backBufferTarget_); if(backBufferTexture) backBufferTexture->Release(); if(FAILED(result)) { DXTRACE_MSG("Failed to create the Direct3D device!"); return false; } d3dContext_->OMSetRenderTargets(1,&backBufferTarget_,0);
D3D11_VIEWPORT viewport; viewport.Width=static_cast<float>(width); viewport.Height=static_cast<float>(height); viewport.MinDepth=0.0f; viewport.MaxDepth=1.0f; viewport.TopLeftX=0.0f; viewport.TopLeftY=0.0f; d3dContext_->RSSetViewports(1,&viewport);
return LoadContent();
}
源文件3:
#include <Windows.h> #include<memory> #include"BlankDemo.h" LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hDC; switch(message) { case WM_PAINT: hDC = BeginPaint(hwnd, &ps); EndPaint(hwnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0; } int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR cmdLine, int nShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(cmdLine); WNDCLASSEX wndClass = {0}; wndClass.cbSize = sizeof(WNDCLASSEX); wndClass.style = CS_HREDRAW | CS_VREDRAW; wndClass.lpfnWndProc = WndProc; wndClass.hInstance = hinstance; wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wndClass.lpszMenuName = NULL; wndClass.lpszClassName = "DX11BookWindowClass"; if(!RegisterClassEx(&wndClass)) return -1; RECT rc = {0, 0, 640, 480}; AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, false); HWND hwnd = CreateWindow("Dx11BookWindowClass", "Blank Win32 Window", WS_OVERLAPPEDWINDOW, 0, 0, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hinstance, NULL); if(!hwnd) return -1; ShowWindow(hwnd, nShow); std::auto_ptr<Dx11DemoBase>demo(new BlankDemo()); bool result=demo->Initialize(hinstance,hwnd); if(result==false) return -1; MSG msg = {0}; while(msg.message != WM_QUIT) { if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } demo->Update(0.0f); demo->Render(); } demo->Shutdown(); return static_cast<int>(msg.wParam); }
运行结果:
相关文章推荐
- shell脚本读取ini配置文件的值
- LeetCode Algorithms #242 <Valid Anagram>
- slideDoor(学习某编程网站的,仅作记录和学习)
- 黑马12期day01之html&css
- java.sql.SQLException: General error, message from server: "Field 'ID' doesn't have a default value
- hdoj--1068--Girls and Boys(最大独立集)
- 2015结束,2016启航
- HLG 2163 方格取数 (最大网络流)
- hdoj--1068--Girls and Boys(最大独立集)
- javascript38种小技巧,推荐新手查看
- Handler、Looper、Message关系详解
- Windows平台网站图片服务器架构的演进
- poj1182 食物链(经典并查集)
- HDU 5617 Jam's maze(DP)
- SQL--触发器
- 2016年1月英语总结
- 数据结构基础之线性表
- hdu 5179 beautiful number【数位dp】
- javascript中的的getYear()问题
- 集体智慧学习笔记二——中文标点的去除