网页功能: 加入收藏 设为首页 网站搜索  
关于图形数据在内存存放方式的思考
发表日期:2006-08-23作者:[转贴] 出处:  

  搞游戏设计,原来我一直以为,在DirectDraw下面使用Surface存放图形数据(特别是地图元素图形数据)就可以了。使用的时候,直接把图素Blit到BackSurface里面去。但是现在看来,这样其实是一种很不明智的做法。
  现在的游戏设计大多数使用的是斜视角的的地图图素。见下图:



这些图素是我从《帝国时代》里面挖出来打算用于《中国海军——铁翼横空》演示版的。从上图可以看出,地图的图素是一个一个的菱形小方块,如果直接放在Surface里面去,是必要占用绿色方格那么大的空间,实际上,方格里面黑色的部分在地图里面是透明的,也就是没有用到的部分,这样一来,一个菱形的图素占用的Surface要比他的实际面积大一倍。在游戏重要用到的图素远不止这么一些,每个图素浪费一点内存,总的内存浪费实在可观。即使是对于一个小游戏,这样的浪费也有可能严重的影响到游戏的速度。
  另外一个问题是,我们现在使用的地图图素是256色的,但是我们现在开始编写的游戏却已经基本上转向了65536色,这样,如果我们把这样的图素放入16位的Surface中去,浪费的内存更加可观:足足是原来图素大小的4倍!这样我们必须要找到一种方法来阻止或者说减小这种浪费,这样对我们的游戏运行速度也有很大的帮助(因为这样一来,大大减少了需要传输的数据量。
  怎样做到这一点呢?
  RLE压缩。RLE压缩是一种行压缩算法,他的工作原理是,如果一行里面连续有几个相同的数据,他就把他表示成这样的形式:
  [N]X
其中,N是表示连续数据的个数,X表示连续的数据。
  实际上,我们在内存里面使用的压缩算法远远没有这么复杂,我们所要做的只是:把图素方格内的黑色部分看作是空格,我们只要把空格压缩掉就可以了。这实际上是一种不完全的RLE压缩。我们来看一下它对内存节省的效率:(图素的宽高分别是:62,32像素)
  未压缩:
    占用空间=62*32*1(字节/8位)=1984字节

  压缩:当然我们首先要定义一个数据结构如下:
  typedef struct tagRLEBitMap{
    WORD width,height;
    void lpData;
    }RLEBitMap;
  typedef struct tagRLELine{
    WORD start;
    BYTE * data;
    void * NextLine;
    }RLELine;
然后在每行数据之前加上一个Word来表示这以行数据开始的地方,结尾加上一个指针来表示狭义行数据存放的地方。这样,我们每行需要6个字节来代替空格。以一个62*32的图素为例:
    占用空间=(1984/2)+6*32+sizeof(RLEBitMap)
        =992+192+8=1192字节
实际上,对于这种压缩算法,面积越大,空格越多(当然是连续空格),效率越高,越接近50%。但是对于过小的图素,还是不要压缩的好,以免反而浪费空间。我个人的看法,每行数据小于32个像素,就不要压缩了(这个数值不是计算出来的,我懒得算了。)其实更简单一点的方法是使用一个RLELine数组,我就不说了。实际使用时,很可能压缩的和不压缩的同时存在,我们还要做一个标记来确定图素是否压缩。
  另外,把256色的图素数据如此保存,对于使用16位色怎么办呢?很简单,使用一个16位的调色版就行了,使用的时候,直接把改数据对应的调色版值放上去,不过这样带来的另外一个问题是,我们不能使用DirectDraw的Blit函数,而要另外写我们自己的Blit了。不过这已经不属于本文要讨论的问题。

我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 关于图形数据在内存存放方式的思考
本类热点文章
  WIA模型及其参考
  游戏中如何读取压缩包文件
  游戏中的资源打包
  游戏中的资源打包技术
  数据结构在游戏中的简单应用
  Tile文件的组织
  管理项目的好助手——VSS入门
  怎样在VC++中读取INI文件
  ADO数据库编程入门
  数据打包格式
  VC中调用ADO的常用方法
  读取光盘
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2024 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00363