本系列文章由zhmxy555(毛星云)编写,转载请注明出处。

文章链接: http://blog.csdn.net/zhmxy555/article/details/8223965

作者:毛星云(浅墨)    邮箱: happylifemxy@163.com

------------------------------------------------------------------------------------------------------------------------------

浅墨历时一年为游戏编程爱好者锻造的著作:《逐梦旅程:Windows游戏编程之从零开始》
如果你喜欢浅墨写的【Visual C++】游戏开发系列博客文章,那么你一定会爱上这本书。
这是浅墨专门为热爱游戏编程的朋友们写的入门级游戏编程宝典。
彩版样章试读下载|配套源代码下载
书本维护页面|当当网|京东商城|亚马逊

------------------------------------------------------------------------------------------------------------------------------

这篇文章里,我们将迈出精通Direct3D的坚实步伐,先透彻理解Direct3D中动画显示方面的交换链技术的原理,然后看看GDI与Direct3D编程习惯的一些思想上的关联,接着简单学习Direct3D中二维文本的绘制方法,然后按照“五步曲”的思路,系统地学习Direct3D绘制的套路,且文章最后进行了相关源代码的赏析以及源代码的下载。看完这篇文章,也许你会豁然开朗,哦,原来Direct3D交换链技术可以这样来理解,原来Direct3D和GDI的编程套路其实差不多,原来Direct3D的绘制渲染过程是这样的按部就班,容易掌握。 需要说明的是,渲染过程暂时不考虑光照,矩阵变换等等,因为这是后面专门来展开细讲的内容。

由于文章比较长,浅墨依然在这里给大家配一个目录。这篇文章大体分为以下六个部分:

一、深入理解Direct3D动画显示技术——交换链:六道轮回

二、Direct3D中的“绘制金钥匙”——Direct3D设备接口

三、Direct3D中二维文本的绘制

四、起承转合的艺术——Direct3D渲染五步曲

Ⅰ.Direct3D渲染五步曲概述

Ⅱ. Direct3D渲染五步曲之一:清屏操作

Ⅲ.Direct3D渲染五步曲之二:开始绘制

Ⅳ. Direct3D渲染五步曲之三:正式绘制

Ⅴ. Direct3D渲染五步曲之四:结束绘制

Ⅵ. Direct3D渲染五步曲之五:翻转显示

Ⅶ.Direct3D渲染五步曲代码整体赏析

五、获取每秒帧数(FPS)函数的写法

六、详细注释的源代码欣赏

 

一、深入理解Direct3D动画显示技术——交换链:六道轮回

 

Direct3D的工作模式与电影的播放原理类似。当播放电影图像时,影片图像以每秒24帧的速度连续地闪动,由于这些图像之间的差别很小,以及人眼的滞留作用,所以实际看到的就好像是连续的动作画面。

Direct3D中,使用了一种称作交换链(Pape Flipping)的技术,来让画面能够平滑的过渡。交换链由两个或者两个以上的表面组成,而每个表面都是存储着2D图形的一个线性数组,其中每个元素都表示着屏幕上的一个像素。

刚刚我们讲到的只是2D图形,而对于三维物体呢,我们还需要一个称作深度的信息,Direct3D则使用深度缓冲区为最终绘制的图像的每个像素都存储一个深度信息,深度缓冲区只单单包含了特定像素的深度信息而不含图像数据的表面信息(表面信息上面讲过,由表面信息来存储,就是一个存储着2D图形的线性数组)。

前台缓冲区和后台缓冲区是位于系统内存或显存里的内存块,对应于将要显示的二维显示区域。前台缓冲区是显示在显示屏上的,我们可以看到的内容。而后台缓冲区则主要用于图形绘制的准备工作,属于我们熟知的“幕后”(想要上演一出完美而杰出的表演,幕后准备工作肯定是要准备充分的)。这样我们的图像在经过在后台缓冲区中的打理后,变得光鲜和毫无瑕疵,在后台缓冲区打理完成后,也就是后台缓冲区中的内容准备好之后,就可以和前台缓冲区进行一个交换操作,这就是我们所说的交换链页面翻转。通过前台缓冲区和后台缓冲区的配合,运用交换链技术,就可以流畅而高效地绘制出漂亮无瑕的动画图像来。

下面我们通过一幅图来具体看看这神奇的交换链翻转操作到底是怎样完成的:

对这幅多后台缓冲区编码翻转演示图,我们可以这样理解:

在Direct3D中,通常是通过在一系列后台缓冲区中生成动画帧(也就是一幅图像),然后再将他们通过交换链技术,逐个提交到前台来显示,实现华丽的动画效果。其中,这一系列的后台缓冲区被组织成交换链。所以我们可以这样说,交换就链是按顺序逐个提交到前台来显示的多个后台缓冲区的集合。

在Direct3D中创建的每一个渲染设备至少要有一个交换链,在我们的Direct3D初始化四步曲中的第三步里面,我们填充了D3DPRESENT_PARAMETERS结构体,其中我们设置的BackBufferCount            成员会告诉Direct3D我们创建的Direct3D设备对象的交换链中,有多少个后台缓冲区,图中我们就有两个后台缓冲区,就是这段代码:

D3DPRESENT_PARAMETERS d3dpp;d3dpp.BackBufferCount            = 2;

需要注意的是,上面这两句只是告诉了Direct3D相关的信息,没有真正的去创建,而交换链正式的创建,是在四步曲的第四步里面,调用IDirect3D9::CreateDevice()方法的时候。IDirect3D9::CreateDevice()方法完成了Direct3D设备对象和相应交换链的创建。

创建完成后,我们自然需要“驱动”交换链进行翻转操作,而交换链的翻转操作就是在我们今天主要讲解的Direct3D渲染五步曲里的最后一步“翻转显示”之中,也就是调用IDirect3DDevice9::Present()函数,进行页面的翻转和显示。这个函数在接下来会讲解具体用法,在这里我们知道它是进行页面翻转操作的就够了。正如图中所表示的,第一行中是原始的未进行翻转操作的交换链状态,前台缓冲区,第一后台缓冲区,第二后台缓冲区的顺序为ABC,我们调用一次IDirect3DDevice9::Present()函数之后,页面就发生了翻转,这样本来在前台缓冲区中的A就被B挤到了队伍最末尾,B代替了A原来的位置。C也顺利晋级,从第二缓冲区的位置晋升到第一缓冲区,也就是C到了B原来的位置,而我们苦逼的A,只能感叹美好的时光总是短暂的,因为它从最风光的前台缓冲区,一下子跌落到万丈深渊,到了地位最卑微的第二缓冲区。真可谓是辛辛苦苦几十年,一夜回到解放前啊。不过正所谓美好的时光总是短暂的,每一次IDirect3DDevice9::Present()函数的调用,都在进行着转盘式的轮回,正所谓风水轮流转,领导轮流做。经过三次的翻转,ABC这三位先生已经经过了一个轮回,历史总是惊人的相似,这三位先生又回到了第一次相遇的“那天”,也就是未经过翻转之前的状态。

经过上面的讲解,我们可以总结一下,交换链其实就是在进行一个风水轮流转的过程,按部就班,万年不变地进行着一次又一次的轮回。他们的轮回生命由IDirect3D9::CreateDevice()方法来赋予。演员个数由D3DPRESENT_PARAMETERS结构体中的BackBufferCount成员指定,而驱动这个轮回的,就是我们的IDirect3DDevice9::Present()函数。

其中Present函数位于我们接下来要讲解的渲染实现函数Direct3D_Render()中, 这个函数我们在消息循环进行了调用,这样就会驱动着我们的程序进行着每秒成千上万次的绘制操作,也就每秒钟进行着成千上万次的渲染五步曲挨着走,也就进行着每秒成千上万次的IDirect3DDevice9::Present()函数的调用(当然也同时进行着成千上万次的缓冲区内容的绘制工作),驱动着交换链进行着成千上万次的页面翻转操作,这样就完成了高质量的动画绘制。

最后我们需要知道的是,我们在调用IDirect3DDevice9::Present()函数函数,请求并进行页面翻转时,是指向前台缓冲区和后台缓冲区表面内存的指针在进行着调换操作。也就是说,页面翻转是经过交换指向表面内存的指针来实现的,而不是通过复制表面的内容实现的。我们都知道,指针这个东西,使用起来方便,环保,资源占用小。

交换链技术利用这样的指针交换操作,实现了高效而流畅的动画绘制。

 

二、Direct3D中的“绘制金钥匙”——Direct3D设备接口

 

其实,使用Direct3D绘制3D图形和我们之前使用的GDI绘制2D图形的方法是异曲同工的,毕竟都是微软那些强人们写出来的,风格或多或少会有一定的相似之处。

看过浅墨之前游戏开发笔记里GDI游戏编程讲解的朋友们应该都知道,在GDI编程中,有一把金钥匙叫hdc,也就是传说中的设备描述表的句柄。我们要在屏幕上采用GDI绘制图形,都是在与hdc这个家伙打交道。我们进行各种透明处理,搞什么双缓冲甚至多缓冲的最终目的,都是想要把流畅的动画绘制到hdc之中。

如果看过浅墨之前游戏开发笔记里GDI游戏编程讲解,大家肯定对这个句子非常的熟悉:

hdc = GetDC(hwnd);

就是这个语句让我们用CreateWindow创建出来的窗口句柄hwnd与hdc有了剪不断理还乱的联系。就是它,成就了hdc这把GDI中绘制的金钥匙。

我们再来看看Direct3D这边。

在上一讲,Direct3D初始化四步曲中我们讲到了初始化Direct3D的第三步是填内容,也就是填充D3DPRESENT_PARAMETERS结构体。

D3DPRESENT_PARAMETERS结构体的第八个参数,HWND类型的hDeviceWindow,很显然,就是我们熟知的窗口句柄,这里指定我们需要在哪个窗口上进行绘制,我们通常都填hwnd。也就是这样写:

D3DPRESENT_PARAMETERS d3dpp;d3dpp.hDeviceWindow = hwnd;  

然后在初始化Direct3D的第四步是创设备填内容中,我们这样写

pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,                                      hwnd, vp, &d3dpp, &g_pd3dDevice)))  

CreateDevice函数的倒数第二个参数中我们指定的就是D3DPRESENT_PARAMETERS的实例d3dpp。

然后最后一个参数,IDirect3DDevice9类型的**ppReturnedDeviceInterface就是我们指向Direct3D设备接口的句柄。

这样我们就间接地把hwnd和Direct3D设备联系起来了,这就是通过CreateDevice 方法创建出来的Direct3D设备能趾高气扬地作为Direct3D中“绘制金钥匙”的资本了。

举个具体例子,在浅墨为这篇文章写的配套demo之中,g_pd3dDevice就是我们的绘制金钥匙,后面的绘制操作就是通过它来完成的,比如拿起g_pd3dDevice指一下Present,也就是渲染五步曲的最终步骤了:

g_pd3dDevice->Present(NULL, NULL, NULL, NULL);  // 翻转与显示 

这个函数具体后面有作为重点讲到,这里只是提一下。

所以我们要Direct3D中进行绘制,拿起Direct3D中的金钥匙——“Direct3D设备”一番使用就好了。

 

 

 

三、Direct3D中二维文本的绘制

因为我们的Direct3D知识才开讲不久,目前浅墨觉得将文字显示相关内容全部拿出来讲比较的不现实,所以这一小节里我们先暂时讲解一下本篇文章配套程序中需要用到的地方,便于大家对本节配套源程序的理解。

在Direct3D中,ID3DXFont接口负责着Direct3D应用程序中创建字体以及实现二维文本的绘制,该接口封装了Windows字体和Direct3D设备指针。其实,ID3DXFont内部实际上还是借用的GDI实现的文本的绘制。

首先我们来看一下将要使用到的Direct3D中用于创建字体的一个函数,他很憨厚老实,人如其名,就叫D3DXCreateFont。我们可以在DirectX SDK中查到这个憨厚老实的D3DXCreateFont函数的声明是这样的:

HRESULT  D3DXCreateFont(  __in   LPDIRECT3DDEVICE9 pDevice,  __in   INT Height,  __in   UINT Width,  __in   UINT Weight,  __in   UINT MipLevels,  __in   BOOL Italic,  __in   DWORD CharSet,  __in   DWORD OutputPrecision,  __in   DWORD Quality,  __in   DWORD PitchAndFamily,  __in   LPCTSTR pFacename,  __out  LPD3DXFONT *ppFont);

然后是每个变量的依次介绍:

◆ 第一个参数,LPDIRECT3DDEVICE9类型的pDevice,也就是我们的Direct3D绘制金钥匙——Direct3D设备的指针

◆ 第二个参数,INT类型的Height,很显然,表示字体的高度。

◆ 第三个参数,UINT类型的Width,依然很显然,表示字体的宽度。

◆ 第四个参数,UINT类型的Weight,还是很显然,表示字体的权重值。

◆ 第五个参数,UINT类型的MipLevels,字体的过滤属性。

◆ 第六个参数,BOOL类型的Italic,表示是否为斜体,TRUE表示是斜体,FLASE表示不是斜体。

◆ 第七个参数,DWORD类型的CharSet,表示字体所使用的字符集,通常我们设为默认值DEFAULT_CHARSET,表示使用默认字符集。

◆ 第八个参数,DWORD类型的OutputPrecision,表示输出文本的精度,通常设为默认值OUT_DEFAULT_PRECIS。

◆ 第九个参数,DWORD类型的Quality,表示指定字符的输出质量,通常也设为DEFAULT_QUALITY。

◆ 第十个参数,DWORD类型的PitchAndFamily,用于指定字体的索引号,通常都设为0.

◆ 第十一个参数,LPCTSTR类型的pFacename,指定我们想要创建的字体名称,比如“微软雅黑”“浪漫雅圆”等等。

◆ 第十二个参数,LPD3DXFONT类型的*ppFont,用于存储我们新储存的字体指针。它也是一把钥匙,我们要进行字体绘制相关的操作,全都靠它了。

设置起来是非常简单的,也就是填空题,按部就班,一个一个填,而且有章可循,非常好写。

完成了字体的创建,下面就是要调用绘制文本的函数了。也就是ID3DXFont::DrawText的调用,下面看一下这个函数的原型:

 

INT DrawText(  [in]  LPD3DXSPRITE pSprite,  [in]  LPCTSTR pString,  [in]  INT Count,  [in]  LPRECT pRect,  [in]  DWORD Format,  [in]  D3DCOLOR Color);

这个函数的参数我们也介绍一下:

◆ 第一个参数,LPD3DXSPRITE类型的pSprite,指定字符串所属的ID3DXSprite对象接口,我们可以把它设为0,表示在当前窗口绘制字符串。

◆ 第二个参数,LPCTSTR类型的pString,指定我们将要绘制的字符串内容。

◆ 第三个参数,INT类型的Count,指定绘制字符的个数,如果取-1的话,就表示函数会自动绘制到字符串结束为止。

◆ 第四个参数,LPRECT类型的pRect,表示用于绘制字符串的矩形区域位置。

◆ 第五个参数,DWORD类型的Format,指定字符串在上面设置的这个参数,pRect矩形区域中的摆放属性。比较常用的属性浅墨打在了下面这张表上面了,他们之间用“|”符号联合起来使用,比如 DT_CENTER | DT_VCENTER。

Format参数的取值

精析

DT_BOTTOM

表示字符串位于rect底部,和DT_SINGLELINE共存

DT_CALCRECT

根据字符串长度自动调节矩形区域大小

DT_CENTER

表示字符串水平居中

DT_LEFT

表示字符串左对齐

DT_NOCLIP

表示不对字符串进行裁剪

DT_RIGHT

表示字符串右对齐

DT_SINGLELINE

表示字符串单行显示

DT_TOP

表示字符串位于矩形区域顶部

DT_VCENTER

表示字符串位于矩形区域垂直居中

◆ 第六个参数,D3DCOLOR类型的Color,显而易见,它是用于指定我们字符串显示的颜色值的,属于我们之前讲过的D3DCOLOR结构体,可以随意从中挑选并设置。

 

 

其实在Direct3D中绘制2D文本的方式并不只这一种,但是这种方式用起来最舒服。说起来就两步:

1. 调用D3DXCreateFont创建字体

2.拿起创建的字体,调用ID3DXFont::DrawText进行文本的绘制。

看到这里如果你觉得累了,就看几张精美的游戏画面截图吧,今天贴出的依然是来自EA的游戏大作,采用CryEngine3游戏引擎制作的《孤岛危机2》:

CryEngine3引擎作为目前全球顶尖的游戏引擎之一,有着相当震撼的画面效果:

好了,了解完周边知识,美图也欣赏了,下面我们来看看这篇文章中的主角。

 

四、起承转合的艺术——Direct3D渲染五步曲

开始正式讲解本篇文章的正餐了——Direct3D绘制五步曲。

Ⅰ.Direct3D渲染五步曲概述

上节的初始化五步曲与大家见面后,不少读者表示对Direct3D_Render()这个函数很感兴趣。因为上篇文章里篇幅有限,所以那时候Direct3D_Render()函数体里面是空的,这篇文章的主要目的,就是进行这个函数的书写。

其实Direct3D_Render()也就是浅墨自定义的一个用于完成我们Direct3D绘制过程的函数而已,名字可以随便取的,比如叫D3DRender(),叫Render(),叫Draw()都是可以的,这个要看心情,当然也要符合比较科学的命名规范,你取PlayDota()都没人会说你,不过这样取名的话显然除了你没人知道这个函数到底是要干嘛的- -,就不合适了。

我们准备在这个Direct3D_Render()函数中,简单干净的完成这渲染五步曲操作,不多做一点赘余的操作,因为我们在消息循环中是这样写的:

//消息循环过程            MSG msg = { 0 };  //初始化msg            while( msg.message != WM_QUIT )                             //使用while循环            {                        if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )   //查看应用程序消息队列,有消息时将队列中的消息派发出去。                        {                                   TranslateMessage( &msg );                  //将虚拟键消息转换为字符消息                                         DispatchMessage( &msg );                  //该函数分发一个消息给窗口程序。                        }                        else                        {                                   Direct3D_Render(hwnd);                                 //调用渲染函数,进行画面的渲染                        }            }

这就表示了,我们无时不刻地在调用Direct3D_Render()函数,每秒钟调用成千上万次都是可能的。所以为了写出执行效率高的程序,我们一定要保证Direct3D_Render()函数中的干净整洁。

下面我们就来看看,Direct3D_Render()函数需要些的渲染五步曲,是哪五步:

1. 渲染五步曲之一:清屏操作

2. 渲染五步曲之二:开始场景

3. 渲染五步曲之三:正式绘制

4. 渲染五步曲之四:结束场景

5. 渲染五步曲之五:翻转显示

所以,渲染五步曲连起来说,也就是简单的二十个字:

清屏操作,开始场景,正式绘制,结束场景,翻转显示

这五步非常的好理解,有点写文章里起承转合的味道。

值得提出的是,渲染五步曲都有一个统一的指挥棒,那就是Direct3D中的“绘制金钥匙”——Direct3D设备接口,我们可以看到,每一步里面都是拿着个IDirect3DDevice9接口的指针对象g_pd3dDevice->这样指一下。

下面我们进行各个击破,分别进行细讲。首先来看下第一步。

Ⅱ. Direct3D渲染五步曲之一:清屏操作

每当绘制画面之前呢,我们都需要通过IDirect3DDevice9接口的Clear方法将后台缓冲区中的内容进行清空,并设置我们喜欢的表面填充颜色等。

我们可以在DirectX SDK中查到。Direct3D渲染五步曲的第一步中的主角IDirect3DDevice9::Clear的原型声明是这样的:

HRESULT Clear(  [in]  DWORD Count,  [in]  const D3DRECT *pRects,  [in]  DWORD Flags,  [in]  D3DCOLOR Color,  [in]  float Z,  [in]  DWORD Stencil);

下面我们来分别进行各个成员的讲解。

◆ 第一个参数,DWORD类型的Count,指定了接下来的一个参数pRect指向的矩形数组中矩形的数量。我们可以这样说,Count和pRects是一对好基友-o-。如果pRects我们将其设为NULL的话,这参数必须设为0。而如果pRects为有效的矩形数组的指针的话,这个Count必须就为一个非零值了。

◆ 第二个参数,const D3DRECT类型的*pRects,指向一个D3DRECT结构体的数组指针,表明我们需要清空的目标矩形区域。

◆ 第三个参数,DWORD类型的Flags,指定我们需要清空的缓冲区。它为D3DCLEAR_STENCIL、D3DCLEAR_TARGET、D3DCLEAR_ZBUFFER的任意组合,分别表示模板缓冲区、颜色缓冲区、深度缓冲区,用“|”连接。

◆ 第四个参数,D3DCOLOR类型的Color,用于指定我们在清空颜色缓冲区之后每个像素对应的颜色值,这里的颜色用D3DCOLOR表示,后面我们会讲到,这里我们只需要知道一种D3DCOLOR_XRGB(R, G, B)就可以了,这里的R,G,B为我们设定的三原色的值,都在0到255之间取值,比如D3DCOLOR_XRGB(123, 76, 228)。

◆ 第五个参数,float类型的Z,用于指定清空深度缓冲区后每个像素对应的深度值。

◆ 第六个参数,DWORD类型的Stencil,用于指定清空模板缓冲区之后模板缓冲区中每个像素对应的模板值。

所以,渲染五步曲的第一步就是用一下这个Clear方法:

//其中g_pd3dDevice表示我们创建的有效的Direct3D绘制”金钥匙”——Direct3D设备对象g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

Ⅲ.Direct3D渲染五步曲之二:开始绘制

这个取名还真是不好取,浅墨想了半天,没办法,只好憨厚老实地给它取名叫“开始绘制”。

其实过程非常简单,就是简单地写一句:

//其中g_pd3dDevice表示我们创建的有效的Direct3D绘制”金钥匙”——Direct3D设备对象g_pd3dDevice->BeginScene();

其中IDirect3DDevice9::BeginScene()没有参数,如果调用成功,返回值就为HRESULT。这个函数和IDirect3DDevice9:: EndScene()是一对好基友,都是形影不离,要么都不出现,要么肯定是成对出现的。BeginScene(开始绘制)对EndScene(结束绘制),这不是天造地设的一对是什么呢?哈哈。

Ⅳ. Direct3D渲染五步曲之三:正式绘制

正式绘制的就像BeginScene()和EndScene()这对好基友的电灯泡一样,总是乐此不疲地出现在他们两者中间,而且通常是大段大段的代码,弄得BeginScene()和EndScene()经常是相隔千万里,君住长江头,我住长江尾。

正式绘制这一步并没有确切的固定代码,我们想绘制什么内容,就写什么样的句子。这也是我后面讲解的重点所在,能写出不同的句子来绘制不同的游戏画面。

如果是按我们本篇文章的配套程序来分析的话,这里我们就写的是如下的代码:

//在纵坐标100处,写第一段文字  g_FontPosition.top = 100;//指定文字的纵坐标 g_pFont->DrawText(0, _T("《浅墨DirectX提高班》之三"), -1, &g_FontPosition, DT_CENTER,   D3DCOLOR_XRGB(68,139,256)); //在纵坐标250处,写第二段文字 g_FontPosition.top = 250; g_pFont->DrawText(0, _T("游戏开发的世界,我们随浅墨来降服你了~!"), -1, &g_FontPosition,   DT_CENTER, D3DCOLOR_XRGB(255,255,255)); //在纵坐标400处,写第三段文字 g_FontPosition.top = 400; g_pFont->DrawText(0, _T("闪闪惹人爱"), -1, &g_FontPosition, DT_CENTER,   D3DCOLOR_XRGB(rand() % 256, rand() % 256, rand() % 256));//采用随机RGB值,做出“闪闪惹人爱”的特效 //在窗口右上角处,显示每秒帧数 int charCount = swprintf_s(g_strFPS, 20, _T("FPS:%0.3f"), Get_FPS() ); g_pFont->DrawText(NULL, g_strFPS, charCount , &formatRect, DT_TOP | DT_RIGHT, D3DCOLOR_XRGB(168,39,136));

【Visual C++】游戏开发笔记三十四 浅墨DirectX提高班之三 起承转合的艺术 Direct3D渲染五步曲相关推荐

  1. 【Visual C 】游戏开发笔记三十四 浅墨DirectX提高班之三 起承转合的艺术 Direct3D渲染五步曲

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

  2. 【Visual C++】游戏开发笔记三十四 浅墨DirectX提高班之三 起承转合的艺术:Direct3D渲染五步曲...

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8223965 作者:毛星云(浅墨 ...

  3. 【Visual C++】游戏开发笔记三十四 浅墨DirectX提高班之三 起承转合的艺术:Direct3D渲染五步曲

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8223965 作者:毛星云(浅墨 ...

  4. 【Visual C++】游戏开发笔记三十二 浅墨DirectX提高班之一 DirectX大局观认知篇

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

  5. 【Visual C++】游戏开发笔记三十六 浅墨DirectX提高班之四 顶点缓存的逆袭

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8276363 作者:毛星云(浅墨 ...

  6. 【Visual C++】游戏开发笔记三十八 浅墨DirectX提高班之六 携手迈向三维世界 四大变换展身手

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

  7. 【Visual C++】游戏开发笔记三十九 浅墨DirectX教程之七 他山之石:几种几何体的快捷绘制法

    本篇文章里,我们对Direct3D之中几种几何体的简洁绘制方法进行了详细的剖析,最后依旧是提供文章配套的详细注释的demo源代码的欣赏,并在文章末尾提供了源代码下载.(这标题有些歧义的,这个几种是修饰 ...

  8. 【Visual C++】游戏开发笔记三十七 浅墨DirectX提高班之五 顶点缓存的红颜知己 索引缓存的故事

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

  9. 【Visual C++】游戏开发笔记三十七 浅墨DirectX提高班之五 顶点缓存的红颜知己:索引缓存的故事

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8304741 作者:毛星云(浅墨 ...

最新文章

  1. linux shell中清理僵尸进程
  2. 虚幻UE4常见问题最全集合
  3. linux进程--fork详解(三)
  4. 2.7 RMSprop-深度学习第二课《改善深层神经网络》-Stanford吴恩达教授
  5. 策略模式、上下文与内部类的思考
  6. 使用JFace Viewer延迟获取模型元素
  7. jrebel、JavaRebel
  8. 《天天数学》连载22:一月二十二日
  9. 做不完了吧,做不出了吧!
  10. 直播电商要处理好五个关系
  11. kafka从入门到精通:Java设置全局变量传值
  12. 《软件测试自动化之道》读书笔记 之 目录导航
  13. 树莓派系统常用配置文件及常用软件
  14. Toggle和Slider组件
  15. Extjs项目实战视频教程
  16. 计算机端口怎么配置波特率,怎么查看车载导航端口号、波特率和取码方式?
  17. Mac安装MongoDB
  18. 通过网易云API爬取评论
  19. CSGO社区服搭建记录
  20. 三方平台与对象存储对接后的应用场景及接口说明

热门文章

  1. Win10无法输入中文的解决方法
  2. 周志华组最新论文提出“溯因学习”,受玛雅文字启发的神经逻辑机
  3. 待办事项是什么意思,怎么用?
  4. 如何培养职业道德素质
  5. WinRAR 5.71 正式版发布
  6. root用户无法登录,提示Module is unknown 原因和解决方法
  7. apache报错:Unclean shutdown of previous Apache run
  8. 小红花代表什么_【小红花的功效与作用】_小红花_好处_益处_营养价值-大众养生网...
  9. HTTP代理,代理服务器
  10. ORACLE 11g新特性中文版