/***********************************
 *作者:蔡军生
 *出处:http://blog.csdn.net/caimouse/
 ************************************/

3D游戏从入门到精通-2
21   介绍游戏
2.11.1什么是游戏
在《高级汉语大词典》中,“游戏”意为游乐、玩耍等,“游”意为游玩、结交、闲逛、学习等,“戏”有游戏、戏剧、角力等解释,而“玩”则有玩耍、欣赏、投入、反复体会等含义。从这些林林总总的含义中,我们是否可以得出这样一些理解:
           游戏具有学习的特征――学习、投入、反复体会。
游戏具有社会的特征――结交。
游戏具有娱乐的特征――游乐、玩耍、欣赏、角力。
其实,游戏的种类多种多样,这里主要关心是电脑游戏,说得更精确一点,就是三维游戏。
2.11.2 3D游戏
在很长一段时间里,电脑游戏一直是2D的,随着计算机技术的发展,越来越复杂的图形也能轻易处理。目前大部游戏已经发展到3D游戏,随着硬件更进一步的发展,3D游戏肯定会成为主流的方向。因此学习3D游戏技术,是非常必要的。
站在游戏者的角度去看,肯定想玩那些非常逼真,非常生动,身临其境的游戏。由于我们现实世界是三维的空间,那么在计算机里就需要展现出一个非常逼真的三维空间出来,这样才会让人深刻体会到游戏快乐,如现实一般,就像睡了一个非常美妙的梦。
开发游戏的目的,就是让玩家可以快乐地享受游戏带来的快乐,让人可以轻松,或者让人过一个童话般的梦想,或者让人可以相互比赛,满足人类天然的本性--“适者生存”。从达尔文的进化论来看,自然界总是适者生存。游戏里可以让人实现这种天然本性,比如在《极品飞车》里,两个人就可以开着赛车,进行比赛,如果谁胜了,就会得到快乐。比如在《传奇世界》里,谁的武功好,谁就可以把谁打败。这也是一种适者生存,强者生存的本性体现。
因此,3D游戏就是用三维空间的图形表现各式各样场所出来,怎么样表现来呢?这就是本书的目的,本书从头开始指导你怎么样用Direct3D构造游戏
 3D游戏从入门到精通-3
 
2.10.1坐标系
在D3D里使用的坐标系是左手坐标系,就是当你看屏幕时,左手边是X轴的负方向,右手边是X轴的正方向。屏幕下边是Y轴的负方向,屏幕上边是Y轴的正方向。远离屏幕是Z轴的负方向,指向屏幕里面是Z轴的正方向。
坐标系还有右手坐标系,还有其它各种各样的坐标系。如果需要从其它坐标里的图形显示在D3D里,就需要进行转换。
2.10.2点
在三维空间里表示物体位置,就需要用坐标来表示。由上面的坐标系可知,任何一点,都可以用三个坐标轴的值来表示。比如表示零点,就是O(0,0,0)。只要给出三个坐标轴的值,就可以知道这个点在什么位置了。
从坐标系里,就知道我们定义的坐标轴是有方向的。那么在坐标系里的点,是否也有方向呢?为了表示方便,使用起来简单,在D3D里的点也是有方向的。用向量来表一个点的位置和方向。一个点的方向,都是从原点出发指向这点的方向。比如下面的图中,OA就是一个点的位置和方向。
从几何上知道这种表示方法了,但在程序里是怎么样表示一个向量呢?在编程里,是需要特定的编程语言来表达向量的。由于C++具有强大的功能和特别快的处理速度,目前大部份游戏都是采用C++来编写。因此D3D游戏也不例外地采用C++。如果你还不会使用C++,建议你先去找本C++的书来看看,然后再接着看本书,否则很多东西是看不懂的。
在C++里是使用结构(struct)或者类(class)来表达一个向量的。下面就是D3D里的向量表示方法:
typedef struct _D3DVECTOR {
    float x;
    float y;
    float z;
} D3DVECTOR;
D3DVECTOR向量定义了三个成员x,y,z来表示坐标系三个坐标轴的值。这里使用typedef来定义向量类型,以后就可以使用它来定义其它向量类型变量了。为了方便对它的操作,因此又需要继承它,生成一个新类D3DXVECTOR3。D3DXVECTOR3类有很多方法,使用起来非常方便。因而在程序里,主要使用它来定义变量,这样就有很函数可以使用了。比如赋值,相加,相减等等。它的定义如下:
typedef struct D3DXVECTOR3 : public D3DVECTOR
{
public:
    D3DXVECTOR3() {};
    D3DXVECTOR3( CONST FLOAT * );
    D3DXVECTOR3( CONST D3DVECTOR& );
    D3DXVECTOR3( CONST D3DXFLOAT16 * );
    D3DXVECTOR3( FLOAT x, FLOAT y, FLOAT z );
 
    // casting
    operator FLOAT* ();
    operator CONST FLOAT* () const;
 
    // assignment operators
    D3DXVECTOR3& operator += ( CONST D3DXVECTOR3& );
    D3DXVECTOR3& operator -= ( CONST D3DXVECTOR3& );
    D3DXVECTOR3& operator *= ( FLOAT );
    D3DXVECTOR3& operator /= ( FLOAT );
 
    // unary operators
    D3DXVECTOR3 operator + () const;
    D3DXVECTOR3 operator - () const;
 
    // binary operators
    D3DXVECTOR3 operator + ( CONST D3DXVECTOR3& ) const;
    D3DXVECTOR3 operator - ( CONST D3DXVECTOR3& ) const;
    D3DXVECTOR3 operator * ( FLOAT ) const;
    D3DXVECTOR3 operator / ( FLOAT ) const;
 
    friend D3DXVECTOR3 operator * ( FLOAT, CONST struct D3DXVECTOR3& );
 
    BOOL operator == ( CONST D3DXVECTOR3& ) const;
    BOOL operator != ( CONST D3DXVECTOR3& ) const;
 
} D3DXVECTOR3, *LPD3DXVECTOR3;
 
在这里已经实现向量的加减、数乘、数除,也许你发现这里有没有点积和叉积运算。它们是通过其它公共函数实现的。说到这里,如果你对点积和叉积运算不是很懂,看来又需要去看看《向量代数》了。在游戏里,要表示一个人沿着OA的方向行走,那么只需要对着OA向量数乘,就可以了。有了这样的向量类型定义,就可像下面那样方便使用:
D3DXVECTOR3 vOA(1.0f,1.0f,1.0f);

3D游戏从入门到精通-4
 
2.10.1平面的表示
3D空间里的物体都是实体的,主要由平面组成。比如正方体,就有6个平面。在D3D里组成三维物体的基本平面是三角形,无论是多么复杂的物体,都是有三角形组成的。并且D3D里支持显示最小的图形也是三角形,它是没有点和直线显示的。因此,要显示正方体,就需要把每个平面分成两个三角形,才能显示。如下图所示:
 
为什么选择三角形作为D3D里最小的平面呢?由于三个点组成的平面,肯定是共面的,是平坦的,并且显示效率是最高的。如果选择其它多边形的话,就存在点不共面的情况,这样变得非常复杂,所以目前显示卡也是针对三角形进行优化显示的。
要在D3D里显示物体,就是显示很多的三角形,让这些三角形连接起来,就组成游戏里的人体,动物,武器等等。在几何里就知道每个三角形都有三个顶点组成,那么只要设置了三个顶点的值,就可以在D3D里显示三角形出来了。用D3D里的向量表示三个顶点就是:
A: D3DXVECTOR3( -1.0f, -1.0f, 0.0f );
B: D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
C: D3DXVECTOR3( 1.0f, -1.0f, 0.0f );
只要把所有三角形的顶点,都按上面格式设置到顶点缓冲区里,就可以显示一个三角形出来。但这个三角形又可分为两个表面:前表面和后表面。在D3D缺省情况下,只会显示前表面。那么怎么样来区别前表面和后表面呢?由于D3D是采用左手坐标系,正对着平面看去是顺时针方向的顶点顺序就是前表面。如下图所示:
如果不小心把顶点的顺序搞反,就会看不到表面显示。并且还会关系到后面的灯光显示,纹理显示。
其实,前表面就是平面的法向量指向的表面。
只要认识到组成平面的顶点以及顶点排列顺序,就可以用平面构成三维物体了。不管多么复杂的物体,都可以由顶点组成平面,再有平面组成物体。不管是圆的物体,还是方的物体,都可以使用三角形去组成。其实这种三维物体是数字化的,永远都是尽可能逼近,不可能是完全相同的。比如要显示一个足球,它是圆的,需要非常多的三角形去构成它,但不可能完全一样的。并且使用过多的三角形,就会导致CPU或者GPU处理不过来。在目前的个人电脑里,虽然处理三角形的速度快了很多,但真的要显示大量三角形,还是不行的。
 3D游戏从入门到精通-5
21   使用Direct3D
2.11.1最简单三角形显示
前面已经学习了顶点、平面以及平面的法向量。接着下面就带你进入奇幻的3D世界,由你去创造这个美好的3D世界。任何美好的事物都是简单的东西组成的,所以也需要从最简单的物体构造开始。这里主要显示一个三角形,其它关于窗口和初始化D3D的设备都已经由MM3D引擎做好了,目前只要设置顶点、世界坐标变换矩阵、观察变换矩阵、投影变换矩阵,然后渲染这个三角形,就可以显示屏幕里了。最终显示效果如下图:
 
1、             顶点格式
顶点格式是可变的,是灵活的。由前面可知,顶点肯定是有三个值的,就是三个坐标轴的值。下面先来看看最简单的顶点格式,它定义如下:
 
//定义顶点缓冲区里用到的顶点格式。
struct VT_CAITRIANGLE
{
 D3DXVECTOR3 vPosition;       // 顶点位置。
 static const DWORD dwFVF = D3DFVF_XYZ;
};
这里使用一个结构来定义顶点的格式,后面就可使用这个结构来定义顶点了。看到这个结构里第一个成员vPosition是很熟悉的吧,前面已经说明过使用一个向量来表示一个顶点的。最简单的顶点格式,就是只有一个向量值,其它什么也没有。后面一个成员dwFVF是说明顶点的有什么样数据,这里只有顶点的坐标,所使用了宏定义D3DFVF_XYZ。其实顶点还可以有其它数据在里面的,比如要表示这个顶点的法向量,就需要加入法向量的成员,比如要显示纹理在这个表面上,就需要设置纹理坐标。

3D游戏从入门到精通-2 -5相关推荐

  1. 3D游戏从入门到精通-31 32 33

    当我们看到现实世界里,有很多山地.那么这种山地,在3D世界里又是怎么样显示出来的呢?要模拟现实中的山地,就需要研究它怎么样构成,然后采用各种方法创建出来.在游戏的世界里,对于地形的要求是不严谨的,只要 ...

  2. 3D游戏从入门到精通-32

    前面已经编译好OGRE库,现在编译Helloworld工程就很快了.当然,在这个程序里也是设置为Debug的方式编译的,这样才能使用前面的OGRE的调试方式的库文件.点一下编译运行按钮,很快就看到一个 ...

  3. python教程是用什么博客写的-用Python和Pygame写游戏-从入门到精通(目录)

    目光博客一开始,就有一个将pygame好好介绍一遍的宏伟计划,历时四个月,在各位朋友的关怀鞭策下,如今(2011/8/26)理论学习的部分似乎已经都完成了,在次列一个目录,方便查询.介绍还不是很全,下 ...

  4. 七夕福利 | 3D视觉从入门到精通系统学习教程

    写在前面 首先提前祝大家七夕快乐,感谢大家对工坊的陪伴与支持! 今天是七夕福利活动的最后一天,共100张券,已经送出去了60多张,还剩不到35张,大家可以抓住本次的活动机会,享受全年的最低价(优惠了7 ...

  5. 「3D视觉从入门到精通」知识星球

    写在前面 话不多说,送大家一张优惠券(今明两天有效,共60张),感谢大家一路的陪伴与支持. 什么是知识星球? 知识星球是一个高度活跃的社区平台,在这里你可以和相同研究方向的小伙伴一起探讨科研工作难题. ...

  6. 用Python和Pygame写游戏-从入门到精通(1)

    From: http://eyehere.net/2011/python-pygame-novice-professional-1/ 博客刚开,打算做一个Pygame的系列,翻译自Will McGug ...

  7. 3D游戏建模入门基础:3dmax常用功能详解

    你收藏了那么多教程,却不知道3dmax怎么入门?掌握3dmax常用功能是3dmax入门的基础之一,所以呢小编今天就为您盘点了一些3dmax最常用到的功能和使用方法,快来和小编一起学习3dmax入门基础 ...

  8. 视频+课件|3D视觉从入门到精通系统学习教程

    前言 很多粉丝在公众号后台留言,不知如何入门3D视觉.3D领域的主线是什么,一些难点该如何解决,有哪些方法,导师新开的3D视觉方向无人指导等等.这些痛点,工坊的许多童鞋都踩过坑,也为大家提出了许多非常 ...

  9. python游戏开发框架_用Python和Pygame写游戏-从入门到精通(实战二:恶搞俄罗斯方块1)...

    游戏是为了什么而存在的?Bingo,是为了娱乐~ 在这个最高主题之前,技术啥的什么都无所谓! 前一段时间,有位姓刘的网友用Pygame写了个俄罗斯方块,在用py2exe打包的时候遇到一些问题,和我交流 ...

  10. 用Python和Pygame写游戏-从入门到精通

    博客刚开,打算做一个Pygame的系列,翻译自Will McGugan的<Beginning Game Development with Python and Pygame –From Novi ...

最新文章

  1. 中国文学发展史思维导图
  2. bash 判断 os 版本_Kali Linux 2020.3开始用ZSH取代Bash旅程
  3. python装饰器作用-如何理解Python装饰器?
  4. JS关于时间的一些计算与获取
  5. Ubuntu下pip安装、升级、卸载
  6. php插入中文数据库乱码以及URL参数乱码
  7. Super详解(重点)
  8. Oracle中NVL2 和NULLIF的用法
  9. 多图详解Spring框架的设计理念与设计模式
  10. java764位_jdk7 64位下载
  11. 计算机网络自顶向下-第 8 版
  12. PhantomJS+Selenium+Scrapy抓取巨潮资讯网企业信息
  13. PHP合成生成GIF动图
  14. Java版俄罗斯方块
  15. java集合类set初解
  16. 交通运输综合管理信息平台建设方案(附下载)
  17. 一些通用 编程变量 单词(常用变量名;持续更新...)
  18. 骑行318、 2016.7.18
  19. 权威SSL证书的CA机构有哪些
  20. Unity流水账8:MeshComponents

热门文章

  1. 直播换脸后,我们来搞搞微信QQ聊天换脸!| avatarify
  2. 每日一面 - 从 innodb 的索引结构分析,为什么索引的 key 长度不能太长?
  3. 什么是java socket
  4. android inflate 方法,Android LayoutInflater中 Inflate()方法应用
  5. Mac外接显示器默认30hz
  6. Matlab 中 residuez函数的使用
  7. matlab两条曲线方程求交点_帮忙matlab求两条曲线交点程序,不知问题出在哪里。...
  8. python爬虫属于大数据吗_学Python可以从事大数据和爬虫工程师吗?
  9. 毕业设计 stm32车牌识别系统设计与实现 - 单片机 嵌入式
  10. 什么是瀑布图_什么是瀑布图以及为什么我需要一个