您的位置:首页 > 其它

阿辉DirectX 11学习笔记二

2016-01-31 17:10 155 查看
上一小节任务完成了窗口初始化的任务,接下来将完成初始化Direct3D的任务,如下:

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);
}


运行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: