现在的位置: 首页 > 综合 > 正文

自己写游戏引擎(01)

2013年08月28日 ⁄ 综合 ⁄ 共 1780字 ⁄ 字号 评论关闭

 转载自:http://www.lihuasoft.net/article/show.php?id=4853

 

写了几个月的游戏引擎,有一些想法需要总结结一下,也想和同我水平差不多的朋友,或者比我水平还要菜的cn们分享一下,高手莫笑~~

这里的想法是,尽量和大家分享我的过程,我写的东西很烂(我的确这样觉得),我会在文中写下来我觉得还存在问题的地方,需要改进的地方,或者还没有想到很好解决的地方;希望同大家相互讨论,也非常欢迎高手们的建议和批评.Just for FUN! OK.
(ps:文中的代码都是片断,these don’t compile,如果你想要部分代码,可以和我联系,在引擎完成得差不多的时候我会邮给你,我的邮箱:xjyhust@gmail.com or xjyhust@126.com. )
 
  目标是写一个多渲染器的游戏引擎,先来谈其中的图形渲染部分,毕竟这个是关键,如果你想了解物理,网络或者其他的内容,很遗憾,这里没有(也许要等到很后面的了)。可以看一下我之前写的两篇blog,《游戏引擎中多渲染器的设计与实现》(1,2),里面讲到了用动态链接库实现的一种的方法,这里就不复习了,假设你已经完成了前面最基本的实现。
 
  引擎的核心部分是一切的前提,所以我们从这里开始。我强烈建议你在开始动手之前先看一下常用的3d模型的格式的解析——因为引擎的底层的基本数据类型的设计是非常重要,而且在后面是相当难以改动的——看一下常用的模型格式的解析,可以帮助你设计合理的底层数据类型(这里指的是像纹理,材质,三角形等的表示)。先以MilkShape 3D的格式MS3D为例。在他们的网站上,你可以下到一个C++解析组件,先看头文件中的数据类型:
 
  从代码中可以看出,Texture和Material都有name,都有fileName(指的是贴图文件名),Material中有4中颜色(这和图形学里面的物理意义也是一致的),然后就是Texture可以是alpha贴图,有属性transparency,这些都可以作为我们设计的参考。我们就停在这里,在后面我们还会看到这个经典的格式是怎样影响了我们的渲染批次的设计的。
 
  开始建立基础的数据类型:
 
  这里很奇怪的是,我在Texture里面用了一个void*。恩,这个是用来存储不同API中的纹理。比如,如果是用的DX,我会一直把这个 void*看成LPDIRECT3DTEXTURE9*。在引擎中,我会大量的用到指针间的静态转换(非运行时)(hard core c++高手看到我的代码会说应该用static_cast,而不是用c语言里面的(typename)(…)。恩,我同意,只是有时候我忘了,或者懒了)。
 
  有很多的引擎,会将Texture单独的抽象成一个类,有相应的行为(成员函数);但是,我觉得,Texture的实质是一堆数据,既然Texture Manager(纹理管理器,简记为TextureMng)是必要的,那么单独的Texture的类的设计似乎没有太多的必要,我们有TextureMng的管理,这样似乎足够了,我暂时不想把事情搞得太复杂。
(ps:面对对象是很好的方法,但是引擎中的很多“东西”的实质还是数据的集合,在把他们变成类之前,考虑一下于他们相关的操作,考虑一下用类实现一些很小的数据体的时候效率的影响。。。像Quake3和Ogre就是两个设计的极端,是不是有时候结合两者会好一些?)
 
  还有很多的数据类型要写,比如很多的3D中的数学类,像Vector3,Matrix4,先把他们放一下。我比较喜欢迭代开发的感觉——用比较短的周期,作出简单的可运行的程序,然后在改进。好,我们就以dx sdk里面的例子开始,先实现一个Vertex的例子。
 
  我们需要定义一个VertexBuffer的抽象类,来给GL和DX提供公共的接口。
 
(ps:多渲染器引擎中,用抽象类(纯虚类)是一种实现中的设计,即使用不同的API的底层实现,对于用户来说,都是同一接口)
  在DX9渲染器中我们加入文件,UHEDX9VertexBuffer.h和UHEDX9VertexBuffer.cpp。
 
  在UHEDX9VertexBuffer.cpp中,完成这些实现(看一下dx sdk,没有什么值得多说的了)
  先写到这里,明天继续。。。

抱歉!评论已关闭.