必须吐槽csdn的排版,真的是对不起它的名字!

抱了很大的决心,才决定写下这篇博文,笔者大三从其它专业转行,学习c c++也就一年多,因为入了游戏这坑,

故选择在游戏引擎这块泥泞的道路上前进,且行且开心吧。

不得不吐槽一句,国内想学游戏开发还真是有点难度,幸好有前辈的发掘,我们现在才好走一点。

前辈博客:https://blog.csdn.net/bonchoix?t=1 。

近来看了《大话设计模式》,觉得编者的讲解方式真是新奇有趣又贴入主题,故此笔者模仿其写法,试试能不能将DX11回顾的更有意思一些。

人物介绍:小白(熟悉win32,c++,c,数据结构与算法);

人物介绍: 老鸟(一名图形与游戏引擎大牛)。

小白:啦啦啦,(哼着歌开心的走进门)。

老鸟:发生什么事了?这么开心,是不是想请我吃饭啦。

小白:我今天开“阿卡丽神秘商店”开到了一折,而且里面还有我最想要的“刀妹”的皮肤,

只需9.9元就可以买到它啦。

老鸟:切,我还以为你涨工资,要请我吃饭了,原来是因为要花钱买皮肤,真是:土豪,这么有钱,

请我搓一顿怎么样? 不过3D游戏还真是有吸引力,能让你这么开心。

小白:是呀,但我不只玩游戏的,我还看它优异的画质,流畅的动画,精细的模型,打击的真实感,

引人入胜的剧情关卡设计..........

老鸟:看样子你对游戏还有一番见解呀,那你知道3d游戏底层是怎么实现的吗?你想不想一探

游戏引擎这个新大陆呢?了解之后就可以跟室友吹嘘啦。

小白:瞧你说的,我是显摆的人吗,你跟我讲讲呗,我也想开拓一下见识。

老鸟:3D游戏通常是由引擎写出来的,一个好的大型的游戏往往有其自己的引擎,现在比较优秀的

是“虚幻引擎”,但所有引擎都  有最基本的构建,就拿windows这个平台来说,我们最喜欢和

最该接触的就是DX,通常,我们讲到DirectX的时候,都是指的Direct3D,因为Direct3D

作为正面对抗OpenGL的重要武器,受到了微软最多的关怀与多次针对性的更新。所以Direct3D

在DirectX的 阵营中的认知度最高,它的光芒完全掩盖了其他DirectX API的发挥空间。DirectX

中其他的大多数 API有些被更新换代淘汰掉了,或者有轻微的变化,今天我们就来讲DX11。

小白:哇,感觉好庞大的样子。

老鸟:当然啦,不然怎么能做出这么多优秀的游戏了,

我记得你刚刚学习完win32,写一个简单窗口应该没问题吧。

小白:那当然了,我写给你看看。

五分钟后,小白写的代码如下:

#include <windows.h>#define  SCREEN_WIDTH  800
#define  SCREEN_HEIGHT 600
#define  WINDOW_TITLE    L"【D3D11初始化demo】"LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
{WCHAR className[32] = L"D3D11_demo_01";WNDCLASS Wnd;Wnd.cbClsExtra = NULL;Wnd.cbWndExtra = NULL;Wnd.hCursor = NULL;Wnd.style = CS_VREDRAW | CS_HREDRAW;Wnd.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);Wnd.hIcon = NULL;Wnd.hInstance = hInstance;Wnd.lpfnWndProc = WndProc;Wnd.lpszClassName = className;Wnd.lpszMenuName = NULL;if (!RegisterClass(&Wnd)){return -1;}int Posx = 200;int Posy = 100;HWND hWnd = CreateWindow(className, WINDOW_TITLE, WS_SYSMENU | WS_OVERLAPPED | WS_MINIMIZEBOX,Posx, Posy, SCREEN_WIDTH, SCREEN_HEIGHT,NULL, NULL, hInstance, NULL);ShowWindow(hWnd, nShowCmd);UpdateWindow(hWnd);MSG msg = { 0 };while (GetMessage(&msg, NULL, 0, 0)){TranslateMessage(&msg);DispatchMessage(&msg);}return 0;
}LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{switch (message){case WM_KEYDOWN:if (wParam == VK_ESCAPE)DestroyWindow(hWnd);break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hWnd, message, wParam, lParam);}return 0;
}

老鸟:嗯恩,不错,看来你win32还是掌握好基础了,学习DX也就需要这些,我先为你介绍DX11这座大营:

 ID3D11Device*     md3dDevice: 

           D3D11设备指针,掌管DX11的生死大权,为硬汉集团首领。

           ID3D11DeviceContext*   md3dImmediateContext:

           D3D11设备上下文,即为DX11的监军(副帅),为智囊团的代表。

           IDXGISwapChain* md3dSwapChain:          

           D3D交换链,为军队的兵器马匹,为战争需准备的资源。

DX11军营统兵调度需此三样,缺一不可。

但是我们第一步要做的只是指明这三人或物,即声明,但不着急着用。

#define HR(X) {if(FAILED(X)) { MessageBox(0,L"Create Failed",0,0); return false;}}
ID3D11Device* md3dDevice;//D3D11设备
ID3D11DeviceContext* md3dImmediateContext;//D3D11设备上下文
IDXGISwapChain* md3dSwapChain;//D3D交换链

俗话说,兵马未动,粮草先行,我们得先去要圣旨:   IDXGIFactory* factory;

//创建一个Directx图形接口factoryHR(CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory));

获得圣旨的许可权了,我们需派一个总领:IDXGIAdapter* adpter;//适配器,

//使用factory来为显卡创建一个adapterHR(factory->EnumAdapters(0, &adpter));

总领然后就开始点去粮仓的小弟:IDXGIOutput* adapterOutput;

//列举主要的适配器输出HR(adpter->EnumOutputs(0, &adapterOutput));

小弟就去粮仓了,然后记录并回报适合本次战役的粮仓信息。

首先记录符合初步规定粮仓的信息和数目: unsigned int numModes;

而后建立一个对应数量的记录本:DXGI_MODE_DESC* displayModeList;

再把相应数目的粮仓信息记录。

        unsigned int numModes;DXGI_MODE_DESC* displayModeList;//获取适应适配器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));

接下来计算最符合本次战役粮仓运粮的效率:

fps = numerator / denominator;

分子numerator:时间t内刷新次数    (运粮量)

分母denominator:t(时间)

unsigned int numerator, denominator;
for (int i = 0; i<(int)numModes; i++){if (displayModeList[i].Width == (unsigned int)SCREEN_WIDTH){if (displayModeList[i].Height == (unsigned int)SCREEN_HEIGHT){numerator = displayModeList[i].RefreshRate.Numerator;denominator = displayModeList[i].RefreshRate.Denominator;}}}

好了,这样事情也就做完了,该复命的复命,该释放的释放。

 //释放显示模式列表delete[] displayModeList;displayModeList = NULL;ReleaseCOM(adpter);ReleaseCOM(factory);

休息一下:

还记的笔者第一次玩lol选的就是寒冰,如今寒冰也从当年丛林小野猫变为了源战士,笔者更是度过了青春。

continue:

小白:挺有意思的,大哥,继续呀。

老鸟:好哒,粮草事宜准备好后,我们应该去准备兵马:

DXGI_SWAP_CHAIN_DESC sd;//交换链形容结构体

接下来就是配置属性:

    DXGI_SWAP_CHAIN_DESC sd;ZeroMemory(&sd, sizeof(sd));sd.BufferDesc.Width = SCREEN_WIDTH;sd.BufferDesc.Height = SCREEN_HEIGHT;sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;bool mVsyncEnable = true;  //是否限帧渲染if (mVsyncEnable) //限不限帧{sd.BufferDesc.RefreshRate.Numerator =60;sd.BufferDesc.RefreshRate.Denominator = 1;}else{sd.BufferDesc.RefreshRate.Numerator = numerator;sd.BufferDesc.RefreshRate.Denominator = denominator;}//关闭多重采样sd.SampleDesc.Count = 1;sd.SampleDesc.Quality = 0;//是否进行全屏bool fullscreen = false;if (fullscreen){sd.Windowed = false;}else{sd.Windowed = true;}sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;sd.BufferCount = 1;  //背后缓存数量sd.OutputWindow = g_hWnd; //交换链所属的窗口sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;sd.Flags = 0;

老鸟:小白,听说你英文不错,翻译翻译一下上面sd的属性呗。

小白:嘻嘻,那还不是手到擒来。

经老鸟修改后出炉:

sd.BufferCount = 1;  交换链下后台缓存区数量。

sd.BufferDesc.Format:  交换链下缓冲区结构体下的像素格式。 

sd.BufferDesc.ScanlineOrdering:交换链下缓冲区结构体下的排序扫描(光栅化)格式。 

sd.BufferDesc.Scaling:交换链下缓冲区结构体下的缩放格式。

sd.SampleDesc.Count:交换链下采样结构体下的每个像素的采样数量。

sd.SampleDesc.Quality:交换链下采样结构体下的像素采样质量级别。

sd.OutputWindow = g_hWnd; 交换链所属的窗口句柄。

sd.SwapEffect:交换链下显卡驱动程序选择的显示模式。

sd.Flags:交换链下的全屏显示模式的可选设置。

sd.BufferUsage:交换链下的后台缓冲去的去处。

老鸟:这样你基本上就能看懂了,

小白:完全不呀,我看不懂他们设置的意义。

老鸟:好吧,好吧,那我就把DX11的相关介绍给你贴上:

创建交换链,首先需要填充一个 DXGI_SWAP_CHAIN_DESC 结构体来描述,该结构体的定义如下:

typedef struct DXGI_SWAP_CHAIN_DESC {
DXGI_MODE_DESC BufferDesc;
DXGI_SAMPLE_DESC SampleDesc;
DXGI_USAGE BufferUsage;
UINT BufferCount;
HWND OutputWindow;
BOOL Windowed;
DXGI_SWAP_EFFECT SwapEffect;
UINT Flags;
} DXGI_SWAP_CHAIN_DESC;

DXGI_MODE_DESC 类型是另一个结构体,其定义如下:

typedef struct DXGI_MODE_DESC
{
UINT Width; // 后台缓冲区宽度
UINT Height; // 后台缓冲区高度
DXGI_RATIONAL RefreshRate; // 显示刷新率
DXGI_FORMAT Format; // 后台缓冲区像素格式
DXGI_MODE_SCANLINE_ORDER ScanlineOrdering;// display scanline mode
DXGI_MODE_SCALING Scaling; // display scaling mode
} DXGI_MODE_DESC;

注意:在下面的数据成员描述中,我们只涵盖了一些常用的标志值和选项,它们对于初学者来说

非常重要。对于其他标志值和选项的描述,请参阅 SDK 文档。

1.BufferDesc:    该结构体描述了我们所要创建的后台缓冲区的属性。我们主要关注的属性有:

宽度、高度和像素格式;其他属性的详情请参阅 SDK 文档。

2.SampleDesc:  多重采样数量和质量级别。

typedef struct DXGI_SAMPLE_DESC {
UINT Count;
UINT Quality;
} DXGI_SAMPLE_DESC, *LPDXGI_SAMPLE_DESC;

3.BufferUsage:   设为 DXGI_USAGE_RENDER_TARGET_OUTPUT,因为我们要将
                                场景渲染到后台缓冲区(即将它用作渲染目标)。

4.BufferCount:    交换链中的后台缓冲区数量;我们一般只用一个后台缓冲区来实现双
                                缓存。当然,你也可以使用两个后台缓冲区来实现三缓存。

5.OutputWindow: 我们将要渲染到的窗口的句柄。

6.Windowed:       当设为 true 时,程序以窗口模式运行;当设为 false 时,程序以全屏
                                 (full-screen)模式运行。

7.SwapEffect:      设为 DXGI_SWAP_EFFECT_DISCARD,让显卡驱动程序选择最高效
                                  的显示模式。

8.Flags : 可 选 的 标 志 值 ,如 果 设 为DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH,

那么当应用程序切换到全屏模式时,Direct3D 会自动选择与当前的后台缓冲区设置最匹配的显示模式。

如果未指定该标志值,那么当应用程序切换到全屏模式时,Direct3D 会使用当前的桌面显示模式。

我们在示例框架中没有使用该标志值,因为对于我们的演示程序来说,在全屏模式下使用当前的

桌面显示模式可以得到很好的效果。

老鸟:我不想贴出来的,以后这样的文档还是你自己去找才有意义,龙书11的资源写这篇博文的小主

上篇博文里就有,你去找吧。

小白:辛苦你啦。

老鸟:嗯恩,我接受了,承接上文,DX11的兵马粮草准备好了,我们的两员大将也该带着兵马动身了,

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

老鸟:下面是通过vs2013看函数源文件找到的,这是很常用的学习方法,跟查msdn一样。

HRESULT WINAPI D3D11CreateDeviceAndSwapChain(__in_opt IDXGIAdapter* pAdapter,//指定要为哪个物理显卡创建设备对象。当该参数设为空值时, //表示使用主显卡。在本书的示例程序中,我们只使用主显卡。D3D_DRIVER_TYPE DriverType,  //一般来讲,该参数总是指定为 D3D_DRIVER_TYPE_HARDWARE>HMODULE Software,//----------//用于支持软件光栅化设备(software rasterizer)。//我们总是将该参数设为0。UINT Flags,//----------------//可选的设备创建标志值。当以 release 模式生成程序时,//该参数通常设为 0。//当以 debug 模式生成程序时,该参数应设为://D3D11_CREATE_DEVICE_DEBUG:用以激活调试层。__in_ecount_opt( FeatureLevels ) CONST D3D_FEATURE_LEVEL* pFeatureLevels,UINT FeatureLevels,UINT SDKVersion,             //始终设为 D3D11_SDK_VERSION。__in_opt CONST DXGI_SWAP_CHAIN_DESC* pSwapChainDesc,__out_opt IDXGISwapChain** ppSwapChain,__out_opt ID3D11Device** ppDevice,__out_opt D3D_FEATURE_LEVEL* pFeatureLevel,__out_opt ID3D11DeviceContext** ppImmediateContext );

老鸟:这函数中FeatureLevels你可能看不懂,这里我给你详解一下:

Direct3D 11 提 出 了 特 征 等 级 ( feature levels , 在 代 码 中 由 枚 举 类 型D3D_FEATURE_LEVEL 表示)的概念,

对应了定义了 d3d11 中定义了如下几个等级以代表不同的 d3d 版本:

typedef enum D3D_FEATURE_LEVEL {
D3D_FEATURE_LEVEL_9_1 = 0x9100,
D3D_FEATURE_LEVEL_9_2 = 0x9200,
D3D_FEATURE_LEVEL_9_3 = 0x9300,
D3D_FEATURE_LEVEL_10_0 = 0xa000,
D3D_FEATURE_LEVEL_10_1 = 0xa100,
D3D_FEATURE_LEVEL_11_0 = 0xb000
} D3D_FEATURE_LEVEL;

特征等级定义了一系列支持不同 d3d 功能的相应的等级(每个特征等级支持的功能可参见 SDK

文档),用意即如果一个用户的硬件不支持某一特征等级,程序可以选择较低的等级。例如,

为了支持更多的用户,应用程序可能需要支持 Direct3D 11,10.1,9.3 硬件。程序会从

最新的硬件一直检查到最旧的,即首先检查是否支持 Direct3D 11,第二检查 Direct3D 10.1,

然后是Direct3D 10,最后是 Direct3D 9。要设置测试的顺序,可以使用下面的特征等级数组。
(数组内元素的顺序即特征等级测试的顺序):

D3D_FEATURE_LEVEL featureLevels [4] =
{
D3D_FEATURE_LEVEL_11_0, // First check D3D 11 support
D3D_FEATURE_LEVEL_10_1, // Second check D3D 10.1 support
D3D_FEATURE_LEVEL_10_0, // Next,check D3D 10 support
D3D_FEATURE_LEVEL_9_3 // Finally,check D3D 9.3 support
} ;

这个数组可以放置在 Direct3D 初始化方法中,方法会输出数组中第一个可被支持的特征等级。

例如,如果 Direct3D 报告数组中第一个可被支持的特征等级是D3D_FEATURE_LEVEL_10_0,

程序就会禁用 Direct3D 11 和 Direct3D 10.1 的特征,而使用 Direct3D 10 的绘制路径。

老鸟:下面我们就来实际用下:

D3D_FEATURE_LEVEL features[3] ={D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3};
D3D_FEATURE_LEVEL myFeatureLevel;HRESULT hr = D3D11CreateDevice(NULL,D3D_DRIVER_TYPE_HARDWARE,0,0,features,3,D3D11_SDK_VERSION,&g_device,&myFeatureLevel,&g_deviceContext);if(FAILED(hr)){MessageBox(NULL,L"创建d3d11设备失败!",L"错误",MB_OK);return FALSE;}

本例采用的是D3D11CreateDevice,跟D3D11CreateDeviceAndSwapChain相比其实就少了交换链的部分,很容易就能理解。

ps:

(函数第5个参数)

__in_ecount_opt( FeatureLevels ) CONST D3D_FEATURE_LEVEL* pFeatureLevels

就是特征数组。

(函数第6个参数)

       UINT FeatureLevels:数组元素个数。

(函数倒数第2个参数)

__out_opt D3D_FEATURE_LEVEL* pFeatureLevel

返回 pFeatureLevels 数组中第一个支持的特征等级
      (如果pFeatureLevels 为 null,则返回可支持的最高等级)。

老鸟:这样我们的大将就准备开拨了,但是他们之间并不熟悉,我们只是把他们全配置好了,但还没进行交互。

所以他们就有了第一次碰面,那是在军营的后台

ID3D11RenderTargetView* md3dRenderTargetView; //D3D11渲染目标视图

//--------------------------------------------------------------
//创建后台缓存视图
//--------------------------------------------------------------
ID3D11Texture2D*backBuffer;
ID3D11RenderTargetView* md3dRenderTargetView; //D3D11渲染目标视图md3dSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&backBuffer));md3dDevice->CreateRenderTargetView(backBuffer, 0, &md3dRenderTargetView);
ReleaseCOM(backBuffer);

官方解释:资源不能被直接绑定到一个管线阶段;我们必须为资源创建资源视图,然后把资源视图

绑定到不同的管线阶段。尤其是在把后台缓冲区绑定到管线的输出合并器阶段时

(使 Direct3D 可以在后台缓冲区上执行渲染工作),

我们必须为后台缓冲区创建一个渲染目标视图(render target view) )。

老鸟:第一次只是简单会面,第二次就是要商谈行军布阵事宜,更深一步的交流:

 ID3D11DepthStencilView* md3dDepthStencilView; //D3D11深度(模板)视图

        //--------------------------------------------------------------//填充2DTexture深度缓存(模板缓存)形容结构体,创建深度缓存(模板缓存)//--------------------------------------------------------------D3D11_TEXTURE2D_DESC depthStencilDesc;ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));depthStencilDesc.Width = SCREEN_WIDTH;   //纹理的宽度,单位为纹理元素(texel)。depthStencilDesc.Height = SCREEN_HEIGHT; //纹理的高度,单位为纹理元素(texel)。depthStencilDesc.MipLevels = 1;          //多级渐近纹理层(mipmap level)的数量。depthStencilDesc.ArraySize = 1;          //在纹理数组中的纹理数量。depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;//一个DXGI_FORMAT枚举类型成员,//它指定了纹理元素的格式。depthStencilDesc.SampleDesc.Count = 1;depthStencilDesc.SampleDesc.Quality = 0;depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;           //表示纹理用途的 D3D11_USAGE 枚举类型成员。depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;  //指定该资源将会绑定到管线的哪个阶段。depthStencilDesc.CPUAccessFlags = 0;                    //指定 CPU 对资源的访问权限。depthStencilDesc.MiscFlags = 0;                         //可选的标志值,与深度/模板缓冲区无关,所以设为 0。ID3D11Texture2D* md3dDepthStencilBuffer; //D3D11的“DepthStencil缓存”ID3D11DepthStencilView* md3dDepthStencilView; //D3D11深度(模板)视图HR(md3dDevice->CreateTexture2D(&depthStencilDesc,//已创建好的纹理的结构体0,&md3dDepthStencilBuffer)); //指向深度缓存的指针HR(md3dDevice->CreateDepthStencilView(md3dDepthStencilBuffer, //我们基于这个深度模板缓存创建一个视图0,&md3dDepthStencilView));//指向深度模板缓存的指针

老鸟:接下来就是通力合作:

 //把那些视图绑定到输出合并阶段md3dImmediateContext->OMSetRenderTargets(1, &md3dRenderTargetView, md3dDepthStencilView);//第一个参数是我们将要绑定的渲染目标的数量;

”沆瀣一气“,成为一个人,

我们这里只描述其眼睛(由智囊团指挥):D3D11_VIEWPORT viewport;

//第十,创建并设定视口D3D11_VIEWPORT viewport;viewport.Width = static_cast<float>(SCREEN_WIDTH);viewport.Height = static_cast<float>(SCREEN_HEIGHT);viewport.MinDepth = 0.0f;  //MinDepth 表示深度缓冲区的最小值(0),viewport.MaxDepth = 1.0f;  //MaxDepth 表示深度缓冲区的最大值(1)。viewport.TopLeftX = 0.0f;viewport.TopLeftY = 0.0f;md3dImmediateContext->RSSetViewports(1, &viewport);

老鸟:最后便是摆阵,蓄势以待:

float color[4];//设置清除缓存(backbuffer),设置每帧初始颜色color[0] = 0.0f;color[1] = 0.5f;color[2] = 0.5f;color[3] = 1.0f;//用color清除背后缓存md3dImmediateContext->ClearRenderTargetView(md3dRenderTargetView, color);//清除深度缓存和模板缓存,设置每帧初始值md3dImmediateContext->ClearDepthStencilView(md3dDepthStencilView,D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);//因为渲染已经完成,提交backbuffer到屏幕bool mVsyncEnable = true;  //是否限帧渲染if (mVsyncEnable){//限帧提交md3dSwapChain->Present(1, 0);}else{//尽可能快提交md3dSwapChain->Present(0, 0);}

老鸟:至此,我们dx11军形就摆好了,无论应对什么样的战役我们都可以应对了,

小白,检验一下你的学习态度,就由你做个总结吧。

小白:yes,sir。

DX基本框架流程:(1)声明大将与兵马;

(2)准备好粮草;

(3)配置好兵马;

(4)大将与兵马合并;

(5)大将在后台军营第一次正式见面;

(6)大将之间深入详谈;

(7)通力合作,观察敌情,摆阵。

老鸟:呀,总结的这么好,看来你学的很不错,孺子可教也。

铃铃铃(我们一起学猫叫,一起喵喵喵),小白的电话响了,

小白:哦哦,5黑,好,我马上来。 (挂掉电话)

小白:哥,我同学叫我玩游戏去了,我先走了,嘻嘻,我要让他们看看我的神级刀妹。

源码链接:https://pan.baidu.com/s/1h7Zt_1bPAbgKpXdQzn8eYA

下节我们将以D3D11龙书的类组织形式回顾代码。

当你打算放弃梦想的时候,告诉自己再多撑一天,一个星期,一个月,再多撑一年吧。

等到繁华落尽的时候,你会发现,拒绝退场的结果,是一种怎样的美好。(转自浅墨csdn)

DX11 游戏开发笔记 (二) DX11 基础框架 上相关推荐

  1. 【Visual C++】游戏开发笔记二十三 游戏基础物理建模 五 粒子系统模拟 二

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 本系列文 ...

  2. 【Visual C++】游戏开发笔记二十三 游戏基础物理建模(五) 粒子系统模拟(二)

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. http://blog.csdn.net/zhmxy555/article/details/7607916 作者:毛星云    邮箱: h ...

  3. 【Visual C++】游戏开发笔记二十七 Direct3D 11入门级知识介绍

    游戏开发笔记二十七 Direct3D 11入门级知识介绍 作者:毛星云    邮箱: happylifemxy@163.com    期待着与志同道合的朋友们相互交流 上一节里我们介绍了在迈入Dire ...

  4. 【Visual C++】游戏开发笔记二十七 Direct3D 11入门级知识介绍

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. http://blog.csdn.net/zhmxy555/article/details/7707628 作者:毛星云 邮箱: happ ...

  5. 【Visual C++】游戏开发笔记二十 游戏基础物理建模(二) 重力系统的模拟

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. http://blog.csdn.net/zhmxy555/article/details/7496200 作者:毛星云    邮箱: h ...

  6. 【Visual C++】游戏开发笔记二十一 游戏基础物理建模 三 摩擦力系统模拟

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 本系列文 ...

  7. 【Visual C++】游戏开发笔记二十二 游戏基础物理建模(四) 粒子系统模拟(一)

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. http://blog.csdn.net/zhmxy555/article/details/7585937 作者:毛星云    邮箱: h ...

  8. 【Visual C++】游戏开发笔记二十二 游戏基础物理建模 四 粒子系统模拟 一

    分享一下我老师大神的人工智能教程.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow 本系列文章由zhm ...

  9. 【Visual C++】游戏开发笔记二十二 游戏基础物理建模(四) 粒子系统模拟(一) .

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. http://blog.csdn.net/zhmxy555/article/details/7585937 作者:毛星云    邮箱: h ...

  10. 【Visual C++】游戏开发笔记二十六 DirectX 11各组件的介绍 第一个DirectX 11 Demo的创建

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 本系列文 ...

最新文章

  1. Android人脸识别App(带web上传注册信息)
  2. C++_标准模板库STL概念介绍5-其他库与总结
  3. Cracking The Coding Interview5.2
  4. 连接查询中的ON 子句和 WHERE 子句
  5. 深入netty源码解析之一数据结构
  6. 短网址有啥好处,用长网址不香吗?
  7. 全球及中国4-氨基-3-硝基苯酚行业前景趋势与投资规模格局报告2022版
  8. MCtalk对话抱抱星英语:从Diss在线英语教学乱象到回归教育本原
  9. [Unity] FlowCanvas 使用注意事项
  10. JavaScript学习笔记之BOM篇,认识几种常见的浏览器对象
  11. 浏览器兼容的JS写法总结
  12. CP/IP四层模型与OSI参考模型
  13. 机器学习和深度学习引用量最高的20篇论文(2014-2017)
  14. XP系统如何把文本转换成html,xp系统下将HTML文件设置为屏保的方法
  15. 2019每特教育蚂蚁课堂-Java互联网微服务架构面试宝典v1
  16. SOLD2算法之3: 特征点与heatmap结合检测有效线段(CVPR 2021)
  17. UI设计师都在用的4款UI设计软件
  18. Elasticsearch Ingest Pipeline
  19. 换元积分法和分部积分法
  20. 使用AppiumDesktop控制手机

热门文章

  1. 改cpp[1] Vscode Hex Editor,在vscode中查看内存
  2. 西门子PLC——CANopen系统通信解决方案
  3. csol c语言运行错误,CSOL非常卡之控制台优化.doc
  4. 【Unity】打包时异常 HideFlages.DontSave
  5. iview构建基本html页面,写前端页面步骤----vue+iview
  6. unity3d学习笔记-着色器(3.凹凸贴图Bump Maps)
  7. js实现视频直播,结合bilibili开源项目
  8. SQL解决最多同时在线人数问题(同时视频观看人数,同时浏览人数,同时等车人数)
  9. Using setJavaScriptEnabled can introduce XSS vulnerabilities into you application
  10. Deity is on the struggling road too!