第四 《Introduction to 3D G AME P ROGRAMMING WITH D IRECTX ® 11》关于D IRECT 3D I NITIALIZATION

        在《Introduction to 3D G AME P ROGRAMMING WITH D IRECTX ® 11》中,关于窗口的生成,进行了封装,所以不容易理解。下边,对经典的Windows生成与本书的3D初始化做一个比较。

#include <.........h>引用头文件这里不再累述  

本书与经典windows对照(红字为真正执行函数)
步骤功能作用《Introduction to 3D G AME P ROGRAMMING WITH D IRECTX ® 11》经典windows生成
    子  类父类(D3DApp)      调用路径
1函数的声明,参数的定义及赋值 D3DApp::D3DApp(HINSTANCE hInstance)进入子类入口函数(WinMain)后,调用父类构造函数,完成函数声明、参数定义及赋值在WinMain前声明函数,定义参数及赋值
2入口函数int WINAPI WinMain() 入口函数在子类,但窗口的生成是调用父类完成的int WINAPI WinMain()
2.1 Init()   
2.1.1  Init()通过子类调用父类 
2.1.1.1设计、创建、注册、显示及更新窗口InitMainWindow()在Init()内部调用在入口函数“int WINAPI WinMain()”内完成
2.1.1.23D初始化InitDirect3D()在Init()内部调用在入口函数“int WINAPI WinMain()”内调用
2.1.1.2.1设置投射矩阵OnResize()OnResize()在InitDirect3D()内首次调用,根据具体设置调用父类或子类在Direct3D()内调用
2.1.2编写图形  BuildGeometryBuffers();
    BuildFX();
    BuildVertexLayout();
在Init()内部调用在入口函数“int WINAPI WinMain()”内调用
2.3消息循环Run()入口函数(WinMain)内调用入口函数(WinMain)内运行
2.3.1  virtual void UpdateScene(float dt)=0;
    virtual void DrawScene()=0; 
父类为纯虚函数,调用子类消息循环内调用
2.3.1.1设置空间绘制图形UpdateScene(float dt);
   DrawScene()
   
3回调函数 MinWndproc调用MsgProc设计窗口时指定MinWndproc为回调函数,但MinWndproc内部有设定MsgProc为回调函数通过设计窗口时wc.lpfnWndProc   = MainWndProc; 完成指定

从上表可以看出(红字部分为真正执行的函数,上表为了显而易见,已将时间、贴数等函数省略,不影响比较),同经典的windows生成步骤一样

第一步:函数的声明,参数的定义及赋值,windows在入口函数前活在函数内部,而本书基本封装在了父类的构造函数(D3DApp::D3DApp(HINSTANCE hInstance))内;

第二部:窗口的设计、创建、注册、显示及更新窗口,windows在入口函数内部,而本书基本封装在了父类的InitMainWindow()内;

第三部:3D初始化,windows在入口函数内引用,而本书基本封装在了父类的InitDirect3D()内;

第四部:设置投射矩阵,OnResize(),父类子类都有作用(从下一章开始);

第五步:编写图形,子类完成,这才是真正工作的开始,体现你想编写什么;

第六步:设置空间绘制图形,在子类完成,这才是真正工作的第二部;

第七部:回调函数,重复工作,父类完成。

       从以上可以看出,工作的重复部分封装在父类,一般不需要改变,个性化的部分在子类,这才是真正的工作所在。

 

下面,实践一下,我将第四章的封装编码去繁从简,写在了一张.cpp上,供大家分享:(注意请建立英文路径,不要带中文,否则后期,特别是读写文件时,会很麻烦。)

1.建立工程,选择:文件---新建----项目----Win32控制台应用程序-----名称自己填-----下一步-----windows应用程序 空项目------完成

2.建立cpp:  选择:源文件--新建项---C++文件----名字自己起----添加

3.(若第一次)包含路径:右击解决方案下的项目名----属性-----VC++目录---包含目录----编辑----新行(文件夹图标)----找到SDK的include--选择文件夹          再选择新行----找到本书的代码----对Common进行包含

               然后选择库目录进行包含,在SDK的Lib----X86    再选择新行----找到本书的代码----对Common进行包含。

          总之,在VC++中包含两个包含目录及两个库目录,共4个,已经包含过就不用了。

4.属性页不要退出,衔接器----输入----附加依赖项--复制  d3d11.lib d3dx11d.lib D3DCompiler.lib Effects11d.lib dxerr.lib
dxgi.lib dxguid.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib
oleaut32.lib uuid.lib odbc32.lib odbccp32.lib,已经有了就不用这一步了。

5.复制下列代码:

#include <windows.h>

#include <string>

#include <d3dx11.h>

#include <cassert>

#include <xnamath.h>

HINSTANCE hInstance;
HINSTANCE mhAppInst=hInstance;
int mClientWidth(800);
int mClientHeight(600);
HWND      mhMainWnd=0;
std::wstring mMainWndCaption(L"D3D11 Application");
D3D_DRIVER_TYPE md3dDriverType(D3D_DRIVER_TYPE_HARDWARE);
ID3D11Device* md3dDevice(0);
ID3D11DeviceContext* md3dImmediateContext(0);
UINT      m4xMsaaQuality(0);
bool mEnable4xMsaa(false);
IDXGISwapChain* mSwapChain(0);
ID3D11RenderTargetView* mRenderTargetView=0;
ID3D11DepthStencilView* mDepthStencilView=0;
ID3D11Texture2D* mDepthStencilBuffer=0;
D3D11_VIEWPORT mScreenViewport;


namespace Colors
{
	XMGLOBALCONST XMVECTORF32 White     = {1.0f, 1.0f, 1.0f, 1.0f};
	XMGLOBALCONST XMVECTORF32 Black     = {0.0f, 0.0f, 0.0f, 1.0f};
	XMGLOBALCONST XMVECTORF32 Red       = {1.0f, 0.0f, 0.0f, 1.0f};
	XMGLOBALCONST XMVECTORF32 Green     = {0.0f, 1.0f, 0.0f, 1.0f};
	XMGLOBALCONST XMVECTORF32 Blue      = {0.0f, 0.0f, 1.0f, 1.0f};
	XMGLOBALCONST XMVECTORF32 Yellow    = {1.0f, 1.0f, 0.0f, 1.0f};
	XMGLOBALCONST XMVECTORF32 Cyan      = {0.0f, 1.0f, 1.0f, 1.0f};
	XMGLOBALCONST XMVECTORF32 Magenta   = {1.0f, 0.0f, 1.0f, 1.0f};

	XMGLOBALCONST XMVECTORF32 Silver    = {0.75f, 0.75f, 0.75f, 1.0f};
	XMGLOBALCONST XMVECTORF32 LightSteelBlue = {0.69f, 0.77f, 0.87f, 1.0f};
}




LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
bool InitDirect3D();
void DrawScene(); 


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance,
				   PSTR cmdLine, int showCmd)



{

	ZeroMemory(&mScreenViewport, sizeof(D3D11_VIEWPORT));
    WNDCLASS wc;
	wc.style         = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc   = MainWndProc; 
	wc.cbClsExtra    = 0;
	wc.cbWndExtra    = 0;
	wc.hInstance     = mhAppInst;
	wc.hIcon         = LoadIcon(0, IDI_APPLICATION);
	wc.hCursor       = LoadCursor(0, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
	wc.lpszMenuName  = 0;
	wc.lpszClassName = L"D3DWndClassName";

	if( !RegisterClass(&wc) )
	{
		MessageBox(0, L"RegisterClass Failed.", 0, 0);
		return false;
	}

	RECT R = { 0, 0, mClientWidth, mClientHeight };
    AdjustWindowRect(&R, WS_OVERLAPPEDWINDOW, false);
	int width  = R.right - R.left;
	int height = R.bottom - R.top;

	mhMainWnd = CreateWindow(L"D3DWndClassName", mMainWndCaption.c_str(), 
		WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, width, height, 0, 0, mhAppInst, 0); 

	if( !mhMainWnd )
	{
		MessageBox(0, L"CreateWindow Failed.", 0, 0);
		return false;
	}

	ShowWindow(mhMainWnd, SW_SHOW);
	UpdateWindow(mhMainWnd);
	InitDirect3D();
	
	MSG msg = {0};	

	while(msg.message != WM_QUIT)
	{
		// If there are Window messages then process them.
		if(PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
		{
            TranslateMessage( &msg );
            DispatchMessage( &msg );
		}
		// Otherwise, do animation/game stuff.	


		else DrawScene(); 

    
}


   return 0;
}

LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{



	switch( msg )
	{
	// WM_ACTIVATE is sent when the window is activated or deactivated.  
	// We pause the game when the window is deactivated and unpause it 
	// when it becomes active.  
	case WM_ACTIVATE:
		
		return 0;

	// WM_SIZE is sent when the user resizes the window.  
	case WM_SIZE:
		// Save the new client area dimensions.
		mClientWidth  = LOWORD(lParam);
		mClientHeight = HIWORD(lParam);
		
		return 0;

	// WM_EXITSIZEMOVE is sent when the user grabs the resize bars.
	
 
	// WM_DESTROY is sent when the window is being destroyed.
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;

	// The WM_MENUCHAR message is sent when a menu is active and the user presses 
	// a key that does not correspond to any mnemonic or accelerator key. 
	}

	return DefWindowProc(hwnd, msg, wParam, lParam);


}



bool InitDirect3D()
{
	UINT createDeviceFlags = 0;
	 D3D_FEATURE_LEVEL featureLevel;
	HRESULT hr = D3D11CreateDevice(
			0,                 // default adapter
			md3dDriverType,
			0,                 // no software device
			createDeviceFlags, 
			0, 0,              // default feature level array
			D3D11_SDK_VERSION,
			&md3dDevice,
			&featureLevel,
			&md3dImmediateContext);

	if( FAILED(hr) )
	{
		MessageBox(0, L"D3D11CreateDevice Failed.", 0, 0);
		return false;
	}

	if( featureLevel != D3D_FEATURE_LEVEL_11_0 )
	{
		MessageBox(0, L"Direct3D Feature Level 11 unsupported.", 0, 0);
		return false;
	}


	md3dDevice->CheckMultisampleQualityLevels(
		DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m4xMsaaQuality);

	assert( m4xMsaaQuality > 0 );


	DXGI_SWAP_CHAIN_DESC sd;
	sd.BufferDesc.Width  = mClientWidth;
	sd.BufferDesc.Height = mClientHeight;
	sd.BufferDesc.RefreshRate.Numerator = 60;
	sd.BufferDesc.RefreshRate.Denominator = 1;
	sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
	sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;

	if( mEnable4xMsaa )
	{
		sd.SampleDesc.Count   = 4;
		sd.SampleDesc.Quality = m4xMsaaQuality-1;
	}
	// No MSAA
	else
	{
		sd.SampleDesc.Count   = 1;
		sd.SampleDesc.Quality = 0;
	}

	sd.BufferUsage  = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	sd.BufferCount  = 1;
	sd.OutputWindow = mhMainWnd;
	sd.Windowed     = true;
	sd.SwapEffect   = DXGI_SWAP_EFFECT_DISCARD;
	sd.Flags        =DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;

	IDXGIDevice* dxgiDevice = 0;
	md3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
	IDXGIAdapter* dxgiAdapter = 0;
	dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter);
	IDXGIFactory* dxgiFactory = 0;
	dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory);
	dxgiFactory->CreateSwapChain(md3dDevice, &sd, &mSwapChain);

	
	if(dxgiDevice)   dxgiDevice=0;
	if(dxgiAdapter)  dxgiAdapter=0;
	if(dxgiFactory)  dxgiFactory=0;

	assert(md3dImmediateContext);
	assert(md3dDevice);
	assert(mSwapChain);

	if(mRenderTargetView)   mRenderTargetView=0;
	if(mDepthStencilView)  mDepthStencilView=0;
	if(mDepthStencilBuffer)  mDepthStencilBuffer=0;

	mSwapChain->ResizeBuffers(1, mClientWidth, mClientHeight, DXGI_FORMAT_R8G8B8A8_UNORM, 0);
	ID3D11Texture2D* backBuffer;
	mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&backBuffer));
	md3dDevice->CreateRenderTargetView(backBuffer, 0, &mRenderTargetView);
	if(backBuffer)  backBuffer=0;

	D3D11_TEXTURE2D_DESC depthStencilDesc;
	
	depthStencilDesc.Width     = mClientWidth;
	depthStencilDesc.Height    = mClientHeight;
	depthStencilDesc.MipLevels = 1;
	depthStencilDesc.ArraySize = 1;
	depthStencilDesc.Format    = DXGI_FORMAT_D24_UNORM_S8_UINT;

	if( mEnable4xMsaa )
	{
		depthStencilDesc.SampleDesc.Count   = 4;
		depthStencilDesc.SampleDesc.Quality = m4xMsaaQuality-1;
	}
	// No MSAA
	else
	{
		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;

	md3dDevice->CreateTexture2D(&depthStencilDesc, 0, &mDepthStencilBuffer);
	md3dDevice->CreateDepthStencilView(mDepthStencilBuffer, 0, &mDepthStencilView);
	md3dImmediateContext->OMSetRenderTargets(1, &mRenderTargetView, mDepthStencilView);

	mScreenViewport.TopLeftX = 0;
	mScreenViewport.TopLeftY = 0;
	mScreenViewport.Width    = static_cast<float>(mClientWidth);
	mScreenViewport.Height   = static_cast<float>(mClientHeight);
	mScreenViewport.MinDepth = 0.0f;
	mScreenViewport.MaxDepth = 1.0f;

	md3dImmediateContext->RSSetViewports(1, &mScreenViewport);

	return true;


}


void DrawScene()
{

	assert(md3dImmediateContext);
	assert(mSwapChain);
	md3dImmediateContext->ClearRenderTargetView(mRenderTargetView, reinterpret_cast<const float*>(&Colors::Blue));
	md3dImmediateContext->ClearDepthStencilView(mDepthStencilView, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 0);
	mSwapChain->Present(0, 0);

}

结果展示:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DirectX修复工具(DirectX Repair)是一款系统级工具软件,简便易用。本程序为绿色版,无需安装,可直接运行。 本程序的主要功能是检测当前系统的DirectX状态,如果发现异常则进行修复。程序主要针对0xc000007b问题设计,可以完美修复该问题。本程序中包含了最新版的DirectX redist(Jun2010),并且全部DX文件都有Microsoft的数字签名,安全放心。 本程序为了应对一般电脑用户的使用,采用了傻瓜式一键设计,只要点击主界面上的“检测并修复”按钮,程序就会自动完成校验、检测、下载、修复以及注册的全部功能,无需用户的介入,大大降低了使用难度。 本程序适用于多个操作系统,如Windows XP(需先安装.NET 2.0,详情请参阅“致Windows XP用户.txt”文件)、Windows Vista、Windows 7、Windows 8、Windows Blue(Windows 8.1),同时兼容32位操作系统和64位操作系统。本程序会根据系统的不同,自动调整任务模式,无需用户进行设置。 本程序的V3.2版分为标准版、增强版以及在线修复版。其中的标准版以及增强版都包含完整的DirectX组件。另外,增强版中还额外包含了c++ Redistributable Package,因此增强版不但能解决DirectX组件的问题,而且还能解决c++组件异常产生的问题。增强版适合无法自行解决c++相关问题的用户使用。在线修复版的功能与标准版相同,只是其所需的文件将通过Internet下载,因此大大减小了程序的体积。本程序的各个版本之间,主程序完全相同,只是配套使用的数据包不同。因此,当您使用标准版数据包时,程序将进行标准修复;当您使用增强版的数据包时,程序将进行增强修复;当数据包不全或没有数据包(即只有DirectX Repair.exe程序)时,程序将进行在线修复。在线修复、离线修复可自由灵活组合,充分满足不同用户的需要。 本程序自V2.0版起采用全新的底层程序架构,使用了异步多线程编程技术,使得检测、下载、修复单独进行,互不干扰,快速如飞。新程序更改了自我校验方式,因此使用新版本的程序时不会再出现自我校验失败的错误;但并非取消自我校验,因此程序安全性与之前版本相同,并未降低。 程序有自动更新c++功能。由于绝大多数软件运行时需要c++的支持,并且c++的异常也会导致0xc000007b错误,因此程序在检测修复的同时,也会根据需要更新系统中的c++组件。V3.2版本使用了全新的c++扩展包,可以大幅提高工业软件修复成功的概率。此功能仅限于增强版。 程序有两种窗口样式。正常模式即默认样式,适合绝大多数用户使用。另有一种简约模式,此时窗口将只显示最基本的内容,修复会自动进行,修复完成10秒钟后会自动退出。该窗口样式可以使修复工作变得更加简单快速,同时方便其他软件、游戏将本程序内嵌,即可进行无需人工参与的快速修复。开启简约模式的方法是:打开程序所在目录下的“Settings.ini”文件(如果没有可以自己创建),将其中的“FormStyle”一项的值改为“Simple”并保存即可。 程序有高级筛选功能,开启该功能后用户可以自主选择要修复的文件,避免了其他不必要的修复工作。同时,也支持通过文件进行辅助筛选,只要在程序目录下建立“Filter.dat”文件,其中的每一行写一个需要修复文件的序号即可。该功能仅针对高级用户使用,并且必须在正常窗口模式下才有效(简约模式时无效)。 本程序有自动记录日志功能,可以记录每一次检测修复结果,方便在出现问题时,及时分析和查找原因,以便找到解决办法。 程序的“选项”对话框中包含了4项高级功能。点击其中的“注册系统文件夹中所有dll文件”按钮可以自动注册系统文件夹下的所有dll文件。该项功能不仅能修复DirectX的问题,还可以修复系统中很多其他由于dll未注册而产生的问题,颇为实用。点击该按钮旁边的小箭头,还可以注册任意指定文件夹下的dll文件,方便用户对绿色版、硬盘版的程序组件进行注册。点击第二个按钮可以为dll文件的右键菜单添加“注册”和“卸载”项,方便对单独的dll文件进行注册。请注意,并不是所有的dll文件都可以通过这种方式注册。点击“DirectX版本”选项卡可以自行修改系统中DirectX的版本信息。点击“DirectX加速”选项卡可以控制系统中DirectX加速的开启与关闭。 新版程序集成了用户反馈程序,可以在用户允许的前提下发送检测修复结果。用户也可以在出现问题时通过反馈程序和软件作者进行交流,共同查找问题。反馈是完全自愿和匿名(如果不填写E-mail地址)的。 本程序的通用版基于Microsoft .NET Framework 2.0开发,对于Windows 2000、Windows XP、Windows 2003的用户需要首先安装.NET Framework 2.0或更高版本方可运行本程序。有关下载和安装的详细信息请参阅“致Windows XP用户.txt”文件。对于Windows Vista、Windows 7用户,可以直接运行本程序。 同时鉴于Windows 8(Windows Blue、Windows 8.1)系统中默认未包含.NET Framework 2.0,因此新版的程序文件夹内将包含一个DirectX_Repair_win8的特别版程序,该程序功能与通用版相同,基于.NET Framework 4.0开发,可以在Windows8(Windows Blue、Windows 8.1)系统中直接运行(其他系统如果安装了.NET Framework 4.0也可以运行这个特别版的程序)。 本程序的官方博客地址为:http://blog.csdn.net/vbcom/article/details/6962388所有的更新以及技术支持都可以到该博客上找到。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值