首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络游戏 >

【Visual C++】游戏开发札记四十一 浅墨DirectX教程之九 为三维世界添彩:纹理映射技术(一)

2013-01-27 
【Visual C++】游戏开发笔记四十一 浅墨DirectX教程之九 为三维世界添彩:纹理映射技术(一)本系列文章由zhmxy

【Visual C++】游戏开发笔记四十一 浅墨DirectX教程之九 为三维世界添彩:纹理映射技术(一)


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

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

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

 


本篇文章里,我们对Direct3D之中固定功能流水线中的纹理映射相关的知识进行了详尽的剖析,文章末尾依旧是提供文章配套详细注释的demo源代码的欣赏,并在文章末尾给出了源代码的下载地址。由于纹理映射相关知识体系比较繁杂,所以需要分次进行介绍,此为上篇。



 

一、引言



 

江山如此多娇,风景如画。万物都有其独特的特点。真实世界中的物体,在计算机三维世界中如果单单用各种各样的几何体以及顶点坐标,顶点颜色来模拟的话,往往缺乏生机,往往差强人意。

比如说我们要绘制出如下效果的一个贴了瓷砖的立方体:

【Visual C++】游戏开发札记四十一 浅墨DirectX教程之九 为三维世界添彩:纹理映射技术(一)

综合我们之前讲过的知识,绘制一个立方体是小菜一碟。但关键就来了,如何绘制出像砖块那样坑坑洼洼的效果呢?难不成用成千上万的顶点坐标一个个去机械的模拟?这显然不现实。

相信正确的做法大家应该很容易想到,先绘制一个立方体,接着准备一副描绘着砖块状的2D图片,然后把这幅图片像贴画一样贴到这个立方体的六个面,这样绘制砖块立方体的效果就可以实现了。

其实上面我们讲到的这种方法,就是计算机图形学中“纹理映射”这套技术思想的真实写照。

在我们的计算机三维世界中,想要模拟出真实而复杂的三维物体,让他们从表面上看起来逼真,就需要请出“纹理映射”这套技术。

 



二、纹理映射的概念



 

一言以蔽之,纹理映射是一种将2D图像映射到3D物体上的技术。

一般来说,纹理是表示物体表面细节的一副或者几幅二维图形,也称纹理贴图(texture)。当我们把纹理按照特定的方式映射到物体表面上的时候,能使物体看上去更加真实。在当今流行的计算机图形系统中,纹理绘制已经成了渲染方法中的中流砥柱了。

想要理解纹理映射其实非常简单,把纹理看做是应用在物体表面上的像素颜色就可以了。

在真实世界中,纹理表示一个对象的颜色、图案或者触觉特性。但在计算机图形学中,纹理只表示对象表面的彩色图案,它不能改变对象的几何形式,换言之,就像贴在几何体表面上的贴画一样。


好了,基本概念应该讲明白了,下面我们来看看如果要使用这种纹理映射技术的话,需要了解的具体知识。


 



三、纹理映射使用四步曲


 

这一小节里面我们详细讲解了使用纹理映射的具体细节。



1. 纹理映射使用四步曲之一,纹理坐标的定义


 

我们一般把纹理映射所使用的2D图像称作纹理贴图。Direct3D支持多种的纹理贴图,比如有.bmp、.dds、.dib、.png以及.tga等等.虽然说Direct3D对纹理贴图的大小没有限制,但是为了提高程序使用纹理的效率,通常使用边长为2的N次方幂的正方形图片,比如128 x128,256 x 256,512 x 512等等。

纹理贴图往往都通过一个二维数组存储每个点的颜色值,该颜色值被称作纹理元素,而每个纹理元素在纹理中都有唯一的地址。而为了将纹理贴图映射到三维图形中,Direct3D使用了纹理坐标确定纹理贴图上的每个纹理元素。

纹理坐标由一个二维坐标系指定,这个坐标系由沿水平方向的u轴和沿垂直方向的v轴构成,他们两个合起来就是坐标对(u,v),其实和我们习惯的(x,y)坐标对是一个概念,只不过在纹理贴图中我们习惯用(u,v)而已。其中u轴正方向为水平向右,v轴正方向为垂直向下,且他们的取值范围都在[0,1]之间。

【Visual C++】游戏开发札记四十一 浅墨DirectX教程之九 为三维世界添彩:纹理映射技术(一)


纹理坐标位于纹理空间之中,是相对坐标,相对于纹理坐标系中的原点(0,0)。当把纹理贴到三维模型表面上时,纹理元素首先被映射到物体模型的局部坐标系中,然后再变换到屏幕坐标系中对应像素的位置处。

 

另外的一点,纹理坐标是通过纹理层和纹理联系到一起的,通常情况下只需使用一层纹理就够了。记得我们原来讲FVF灵活顶点格式的时候讲到过,一个灵活顶点格式中允许最多定义八组纹理坐标,而每组纹理坐标都对应一个纹理层,这就是说每个顶点最多可以使用八层纹理。

比如这样写:

HRESULT D3DXCreateTexture(  __in   LPDIRECT3DDEVICE9 pDevice,  __in   UINT Width,  __in   UINT Height,  __in   UINT MipLevels,  __in   DWORD Usage,  __in   D3DFORMAT Format,  __in   D3DPOOL Pool,  __out  LPDIRECT3DTEXTURE9 *ppTexture);

■ 第一个参数,LPDIRECT3DDEVICE9类型的pDevice,无需多言,这就是我们的绘制金钥匙——Direct3D设备对象了。

■ 第二个参数,UINT类型的Width,表示我们创建的纹理对象的宽度。

■ 第三个参数,UINT类型的Height,表示我们创建的纹理对象的高度。

■ 第四个参数,UINT类型的MipLevels,表示我们创建的纹理的渐进级别,通常取默认值D3DX_DEFAULT就可以了,表示创建一个完整MIP贴图链。。其实取0也无妨,和取默认值D3DX_DEFAULT效果是一样的。

■ 第五个参数,DWORD类型的Usage,指定了我们纹理的使用方式,取值在0、D3DUSAGE_RENDERTARGET、D3DUSAGE_DYMANIC中三取一。

■ 第六个参数,D3DFORMAT类型的Format,用于指定纹理中每个保存每个颜色成分所使用的位数,在D3DFORMAT枚举体中取值,这个参数也可以设为0,表示使用默认值。

■ 第七个参数,D3DPOOL类型的Pool,指定了纹理对象停驻的内存的类别,在D3DPOOL枚举体中取值,不过我们经常是在这个枚举体其中的两个成员D3DPOOL_DEFAULT和D3DPOOL_MANAGED之间取一个。

■ 第八个参数,LPDIRECT3DTEXTURE9类型的*ppTexture,指针的指针,也就是指向IDirect3DTexture9接口的地址,显然我们调用D3DXCreateTexture,就是把最终创建的纹理交给这个参数保管了,后面如果要使用我们创建的这个纹理的话,通过这个参数就可以了。

 

 

但更多情况下我们是从文件中读取纹理图形的,我们可以任意读取我们喜欢的图片文件到Direct3D中,这就用到


【Visual C++】游戏开发札记四十一 浅墨DirectX教程之九 为三维世界添彩:纹理映射技术(一)


【Visual C++】游戏开发札记四十一 浅墨DirectX教程之九 为三维世界添彩:纹理映射技术(一)


【Visual C++】游戏开发札记四十一 浅墨DirectX教程之九 为三维世界添彩:纹理映射技术(一)


【Visual C++】游戏开发札记四十一 浅墨DirectX教程之九 为三维世界添彩:纹理映射技术(一)



好了,美图看完了,继续来学习吧。另外提一点,《仙剑奇侠传五前传》就是用我们目前正在学习的DirectX 9.0c配合RenderWare游戏引擎来进行研发的,所以为了振兴国产游戏,大家共同努力学习吧~



4.纹理映射使用四步曲之四,纹理的启用


 

加载完纹理后,就可以调用IDirect3DDevice9接口的SetTexture方法,设置我们当前需要启用的纹理。我们可以在MSDN中查到SetTexture方法有如下原型:

大家可以发现,这是《仙剑奇侠传五前传》中可控角色之一凌波的2D头像,浅墨非常喜欢这个痴情的角色的。

好了,废话不多说,我们贴出源代码:





【Visual C++】游戏开发札记四十一 浅墨DirectX教程之九 为三维世界添彩:纹理映射技术(一)


文章最后,依旧是放出本篇文章配套源代码的下载:

 

本节笔记配套源代码请点击这里下载:

 

 

【浅墨DirectX提高班】配套源代码之九下载 


 其中图标素材依旧是上面用到的仙五前传中的凌波【Visual C++】游戏开发札记四十一 浅墨DirectX教程之九 为三维世界添彩:纹理映射技术(一)

以上就是本节笔记的全部内容,更多精彩内容,且听下回分解。

 

浅墨在这里,希望喜欢游戏开发系列文章的朋友们能留下你们的评论,每次浅墨登陆博客看到大家的留言的时候都会非常开心,感觉自己正在传递一种信仰,一种精神。但是有时候你们的评论太多了,浅墨一一回复不过来,在这里给大家说声抱歉~~

 

 文章最后,依然是【每文一语】栏目,今天的句子是: 


 

我们会觉得焦虑,无非是因为现在的我们,跟想象中的自己,很有距离。打败焦虑的最好方法,就是去做那些让你焦虑的事情。不要问,不要等,不要犹豫,不要回头,既然你认准了这条路,就不要去打听要走多久。电脑屏幕前的各位朋友,早安~


 【Visual C++】游戏开发札记四十一 浅墨DirectX教程之九 为三维世界添彩:纹理映射技术(一)

下周一,让我们离游戏开发的梦想更近一步。

下周一,游戏开发笔记,我们,不见不散。




23楼zw_124昨天 18:12
楼主强人啊,我也非常想学习游戏编程,就是不得其门而入,求楼主发一份学习资料,拜谢,支持!n651973994@qq.com
22楼nevermorewish昨天 12:14
头等沙发,支持
Re: zhmxy555昨天 18:10
回复nevermorewishn谢谢支持~~
21楼ji366006820昨天 10:34
mark
20楼zw_124昨天 21:44
楼主强人啊,我也非常想学习游戏编程,就是不得其门而入,求楼主发一份学习资料,拜谢!n651973994@qq.com
19楼Andreaw昨天 17:05
超高质量的博客,不但能够从中学到技术而且能够学到人生的哲学!赞!
18楼ZuoShouZuoHua昨天 16:25
对了楼主能麻烦说下Directx的学习思路么?最近准备开始学了但是一直找不到方法很是苦恼!!!!!
17楼xianzi01昨天 16:24
还是很不错!!!!
16楼woxiangnifrr昨天 15:42
楼主真大神也,真心崇拜!“我们会觉得焦虑,无非是因为现在的我们,跟想象中的自己,很有距离。打败焦虑的最好方法,就是去做那些让你焦虑的事情。”真心好,谢谢楼主,楼主保重身体!!!!!
15楼zhang415768974昨天 11:47
不容易啊,一直关注中,前排强势插入!!!
14楼lm8008前天 22:32
佣兵佣兵佣兵佣兵无可奈何花落去
13楼lihang29前天 21:34
牛逼啊,膜拜
12楼weijihai520前天 15:58
关注浅陌也有一段时间了,文章代码都浏览了下,希望能有机会学习一下~~~
11楼zuhoy318前天 15:51
其它的博文很喜欢,这个一般般了
10楼wuyandefeixue007前天 14:28
虽然目前在搞java,但是觉得楼主真心强大……
9楼Crawping前天 13:41
楼主要坚持呀, 精华总结的不错.....文风也略带戏谑.... 顶了 n以后 每个星期 都来观摩观摩
8楼startFromWeb3天前 17:50
弱弱的问一句 专科生能学吗?
Re: zhmxy5553天前 22:15
回复startFromWebn当然可以~
Re: startFromWeb前天 11:35
回复zhmxy555n谢谢浅墨,一直关注您很久了,很佩服您。一直想做学这方面的东西,但学历原因所以一直也没有勇气。感谢浅墨给我信心。
Re: zsc09_leaf前天 13:39
回复startFromWebn为什么不能?给自己一点信心.
7楼ljm_5039093783天前 16:46
前排,不容易啊,,支持!!看了浅墨的文章对游戏开发的信心就十足了!
6楼cheeryabc3天前 15:47
加 V
5楼hedi27879783天前 14:35
非常好!
4楼Funniest3天前 14:13
牛逼啊!!!
3楼john198611213天前 13:07
确实不错 ,持续关注
2楼y0740850244天前 09:38
浅墨,这个demo运行时是没有问题的,但是打开后长时间不动它,立方体的每个面的纹理图像就会变成一条对角线,这是为什么?我是win7系统
Re: zhmxy5554天前 10:01
回复y074085024n哈哈,你按一下键盘上的数字键“2”,图形就回来了啊。这是填充模式的设置问题,实体填充和线框填充模式这两种填充模式。n因为我们在D3D_Render中有这句代码n[code=cpp]n // 获取键盘消息并给予设置相应的填充模式 n if (::GetAsyncKeyState(0x31) & 0x8000f) // 若数字键1被按下,进行线框填充 n g_pd3dDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME); n if (::GetAsyncKeyState(0x32) & 0x8000f) // 若数字键2被按下,进行实体填充 n g_pd3dDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID); n[/code]
1楼GRAY_XIAOXIAO4天前 09:14
加深学习

热点排行