Directx11基础教程二之Directx11初始化

      


一,看本节教程前应该掌握:

        (1)掌握  D3D11基础教程一之D3D11框架

 

二,程序的结构如下:

       Directx11基础教程二之Directx11初始化_第1张图片



具体在VS2015的代码:                                                                                               

Directx11基础教程二之Directx11初始化_第2张图片


三,程序的具体代码如下:


好的,下面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库


五,程序的运行结果如下:

Directx11基础教程二之Directx11初始化_第3张图片


六,源代码链接如下:

  点击打开链接


你可能感兴趣的:(directx11入门)