具体在VS2015的代码:
好的,下面D3D11的初始化我分为十二个步骤,在源代码我我做出了标记,其实这跟D3D11龙书给出D3D11初始化的步骤差不多,就是多出了获取显卡信息的第一步.
好的,先贴出我的D3DClass.H代码
D3DClass.h
#ifndef D3D_CLASS_H
#define D3D_CLASS_H
#define HR(X) {if(FAILED(X)) { MessageBox(0,L"Create Failed",0,0); return false;}}
#define ReleaseCOM(x) { if (x) { x->Release(); x = 0; } }
#include
#include
#include //???
#include
#include
#include
#include
#include
#include
#include
using namespace std;
class D3DClass
{
private:
bool mVsyncEnable; //是否限帧渲染
int mVideoCardMemory; //显卡内存
char mVideoCardDescription[128]; //显卡名字
private:
ID3D11Device* md3dDevice;//D3D11设备
ID3D11DeviceContext* md3dImmediateContext;//D3D11设备上下文
IDXGISwapChain* md3dSwapChain;//D3D交换链
ID3D11RenderTargetView* md3dRenderTargetView; //D3D11渲染目标视图
ID3D11DepthStencilView* md3dDepthStencilView; //D3D11深度(模板)视图
ID3D11Texture2D* md3dDepthStencilBuffer; //D3D11的“DepthStencil缓存”
ID3D11DepthStencilState* md3dDepthStencilState; //深度(模板)缓存状态
ID3D11RasterizerState* md3dRasterizerState; //D3D的光栅化状态
private:
XMMATRIX mWorldMatrix; //世界变换矩阵
XMMATRIX mOrthoMatrix;; //正交矩阵??
XMMATRIX mProjMatrix; //投影矩阵
public:
//构造,拷贝构造,析构函数
D3DClass();
D3DClass(const D3DClass&);
~D3DClass();
//D3DClass初始化函数
bool Initialize(int ScreenWidth, int ScreenHeight, bool vsync, HWND hwnd, bool fullscreen, float ScreenDepth, float ScreenNear);
//关闭D3DClass函数
void Shutdown();
//绘制场景函数
void BeginScene(float red, float green, float blue, float alpha);
void EndScene();
//Get函数
ID3D11Device* GetDevice() { return md3dDevice; }
ID3D11DeviceContext* GetDeviceContext(){ return md3dImmediateContext; }
XMMATRIX GetWorldMatrix() { return mWorldMatrix; }
XMMATRIX GetOrthoMatrix() { return mOrthoMatrix; }
XMMATRIX GetmProjMatrix() { return mProjMatrix; };
void GetVideoCardInfo(char*, int&); //获取显卡信息
};
#endif // !D3D_CLASS_H
D3DClass.cpp
bool D3DClass::Initialize(int ScreenWidth, int ScreenHeight, bool vsync, HWND hwnd, bool fullscreen, float ScreenDepth, float ScreenNear)
{
float fieldOfView, screenAspect;
//--------------------------------------------------------------
//第一,获取显示模式信息和显卡信息
//---------------------------------------------------------------
IDXGIAdapter* adpter;//适配器
IDXGIFactory* factory;
IDXGIOutput* adapterOutput;
unsigned int numModes, numerator, denominator, stringLength;
DXGI_MODE_DESC* displayModeList;
DXGI_ADAPTER_DESC adapterDesc;
int error;
//存储vsyn设定
mVsyncEnable = vsync;
//创建一个Directx图形接口factory
HR(CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory));
//使用factory来为显卡创建一个adapter
HR(factory->EnumAdapters(0, &adpter));
//列举主要的适配器输出
HR(adpter->EnumOutputs(0, &adapterOutput));
//获取适应适配器DXGI_FORMAT_R8G8B8A8_UNORM显示格式的模式数目
HR(adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL));
//创建一个显示模式列表存放可能的显示模式(显卡,监视器)
displayModeList= new DXGI_MODE_DESC[numModes];
if (!displayModeList)
return false;
//填充显示模式列表结构体
HR(adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList));
//浏览所有的显示模式,找到适合屏幕宽度和高度的
//当一个模式匹配,存储监视器刷新速度的分子分母??
for (int i = 0; iGetDesc(&adapterDesc));
//获取显卡内存量
mVideoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024);
//将显卡名字转存在字符数组
error = wcstombs_s(&stringLength, mVideoCardDescription, 128, adapterDesc.Description, 128);
if (error != 0)
{
return false;
}
//释放显示模式列表
delete[] displayModeList;
displayModeList = NULL;
ReleaseCOM(adpter);
ReleaseCOM(factory);
//-----------------------------------------------------
//第二,填充交换链形容结构体
//-----------------------------------------------------
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferDesc.Width = ScreenWidth;
sd.BufferDesc.Height = ScreenHeight;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
if (mVsyncEnable) //限不限帧
{
sd.BufferDesc.RefreshRate.Numerator =numerator;
sd.BufferDesc.RefreshRate.Denominator = denominator;
}
else
{
sd.BufferDesc.RefreshRate.Numerator = 0;
sd.BufferDesc.RefreshRate.Denominator = 1;
}
//关闭多重采样
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
//是否进行全屏
if (fullscreen)
{
sd.Windowed = false;
}
else
{
sd.Windowed = true;
}
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.BufferCount = 1; //背后缓存数量
sd.OutputWindow = hwnd; //交换链所属的窗口
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
sd.Flags = 0;
sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
//---------------------------------------------------------------
//第三,创建交换链和D3D设备和D3D设备上下文
//---------------------------------------------------------------
D3D_FEATURE_LEVEL featureLevel;
featureLevel = D3D_FEATURE_LEVEL_11_0;
HR(D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1,
D3D11_SDK_VERSION, &sd, &md3dSwapChain, &md3dDevice, NULL, &md3dImmediateContext));
//--------------------------------------------------------------
//第四,创建背后缓存视图
//--------------------------------------------------------------
ID3D11Texture2D*backBuffer;
md3dSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast(&backBuffer));
md3dDevice->CreateRenderTargetView(backBuffer, 0, &md3dRenderTargetView);
ReleaseCOM(backBuffer);
//--------------------------------------------------------------
//第五,填充2DTexture深度缓存(模板缓存)形容结构体,创建深度缓存(模板缓存)
//--------------------------------------------------------------
D3D11_TEXTURE2D_DESC depthStencilDesc;
ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));
depthStencilDesc.Width=ScreenWidth;
depthStencilDesc.Height = ScreenHeight;
depthStencilDesc.MipLevels = 1;
depthStencilDesc.ArraySize = 1;
depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthStencilDesc.SampleDesc.Count = 1;
depthStencilDesc.SampleDesc.Quality = 0;
depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
depthStencilDesc.CPUAccessFlags = 0;
depthStencilDesc.MiscFlags = 0;
HR(md3dDevice->CreateTexture2D(&depthStencilDesc,//要创建的纹理的形容
0,
&md3dDepthStencilBuffer)); //指向深度缓存的指针
//-------------------------------------------------------------
//第六,创建并设定深度缓存(模板缓存)状态,指示如何使用Depth和stencil(Test)
//-------------------------------------------------------------
D3D11_DEPTH_STENCIL_DESC DSDESC;
ZeroMemory(&DSDESC, sizeof(DSDESC));
DSDESC.DepthEnable = true;
DSDESC.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
DSDESC.DepthFunc = D3D11_COMPARISON_LESS;
DSDESC.StencilEnable = true;
DSDESC.StencilReadMask = 0xff;
DSDESC.StencilWriteMask = 0xff;
//前面设定
DSDESC.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
DSDESC.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
DSDESC.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
DSDESC.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
//背面设定,在光栅化状态剔除背面时这个设定没用,但是依然要设定,不然无法创建深度(模板)状态
DSDESC.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
DSDESC.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
DSDESC.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
DSDESC.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
HR(md3dDevice->CreateDepthStencilState(&DSDESC, &md3dDepthStencilState));
md3dImmediateContext->OMSetDepthStencilState(md3dDepthStencilState, 1);
//--------------------------------------------------------------
//第七,创建深度缓存(模板缓存)视图
//--------------------------------------------------------------
HR(md3dDevice->CreateDepthStencilView(
md3dDepthStencilBuffer, //我们基于这个深度缓存/漏字板缓存创建一个视图
0,
&md3dDepthStencilView));//指向深度缓存/漏字板视图的指针
//-------------------------------------------------------------
//第八,把那些视图绑定到输出合并阶段
//-------------------------------------------------------------
md3dImmediateContext->OMSetRenderTargets(1, &md3dRenderTargetView, md3dDepthStencilView);
//-------------------------------------------------------------
//第九,创建并设定光栅化状态,用于控制如何渲染目标(以线框还是实体模式等等)
//-------------------------------------------------------------
D3D11_RASTERIZER_DESC rasterDesc;
rasterDesc.AntialiasedLineEnable = false;
rasterDesc.CullMode = D3D11_CULL_BACK; //背面剔除
rasterDesc.DepthBias = 0;
rasterDesc.DepthBiasClamp = 0.0f;
rasterDesc.DepthClipEnable = true; //深度裁剪开启
rasterDesc.FillMode = D3D11_FILL_SOLID; //实体渲染
rasterDesc.FrontCounterClockwise = false; //顺时针
rasterDesc.MultisampleEnable = false;
rasterDesc.ScissorEnable = false;
rasterDesc.SlopeScaledDepthBias = 0.0f;
HR(md3dDevice->CreateRasterizerState(&rasterDesc, &md3dRasterizerState));
md3dImmediateContext->RSSetState(md3dRasterizerState);
//-------------------------------------------------------------
//第十,创建并设定视口
//-------------------------------------------------------------
D3D11_VIEWPORT viewport;
viewport.Width = static_cast(ScreenWidth);
viewport.Height = static_cast(ScreenHeight);
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
viewport.TopLeftX = 0.0f;
viewport.TopLeftY = 0.0f;
md3dImmediateContext->RSSetViewports(1, &viewport);
//-------------------------------------------------------------
//第十一,创建投影矩阵,初始化世界矩阵和用户接口矩阵
//-------------------------------------------------------------
fieldOfView = (float)XM_PI / 4.0f;
screenAspect = (float)ScreenWidth / (float)ScreenHeight;
//投影矩阵
mProjMatrix = XMMatrixPerspectiveFovLH(fieldOfView, screenAspect, ScreenNear, ScreenDepth);
//世界矩阵
mWorldMatrix = XMMatrixIdentity();
//2D渲染矩阵,用于变换用户接口,正交投影矩阵
mOrthoMatrix = XMMatrixOrthographicLH(static_cast(ScreenWidth), static_cast(ScreenHeight), ScreenNear, ScreenDepth);
//第十二,输出一个Text文件保存显卡的信息
char CardInfo[128];
int memory;
GetVideoCardInfo(CardInfo, memory);
ofstream os("I:/1.txt");
os << "memory=" << memory << " " << " CardInfo= " << CardInfo;
return true;
}
(1)D3DClass的初始化第十二步显卡信息的文件"1.txt"输出在我的I盘上,这点大家请注意根据自己情况修改.
(2) 我用的是 xnamath.h 数学库,并非原作者的 d3dx10math.h库