Carmark算法,我的实现

过去两年一直在公司做2D游戏移植,有一次遇上一个外包到公司的项目,项目原来的绘制算法没有用Carmack,导致当我们把它移植到某些性能很Pie的平台上时速度出现了问题。更遭的是由于是外包过来的项目,他们的游戏架构和我们的不同,本来我们的游戏SDK里有Carmack这个算法的,如果是自己的项目要用的话简直太简单了,现在只好自己写个Carmack算法来优化速度了。今天我重温了当时写的Carmack。

首先,场景是一个大大的TileSet,意思就是Tile的集合,场景是由一个个Tile拼成的。一个Tile往往是大约几十个像素乘以几十个像素的小块,如下图:

图1

其它的都好懂,需要关注的是CurrentTileX/CurrentTileY,这对坐标表示的是Camera(摄像机)的坐标所在的那个Tile的位置索引。在此图中CurrentTileX=3,CurrentTileY=2。然后另一个图:

图2

这个图表示的是Carmack Buffer,CarmackBuffer的宽高都要比Camera的宽高至少多一个Tile的宽高,注意是至少多一个,比如一个Tile宽高都是64,Camera宽640,高320,那么CarmackBuffer则宽为640+64=704,高为320+64=384。注意了,如果Camera宽是641,高是321,那么CarmackBuffer和宽就是640+63+64=768,高321+63+64=448 。注意buffer的宽高总是Tile的整数倍!

上图中的_cmkUnitW表示buffer的宽度有几个Tile宽度,图中_cmkUnitW=10,_cmkUnitH意义类似,图中_cmkUnitH=7。

_cmkUnitX/_cmkUnitY标示出了图中绿色的Tile,相信如果你了解Carmack算法的原理,已经猜到这是做什么用了,请看下图:

图3

然后,我们需要一对整形变量_cmkTileX/_cmkTileY来保存图中绿色Tile在整个Tileset中的位置索引,这对变量等于CurrentTileX/CurrentTileY(上文提到的),在Camera没有移动的前提下。CurrentTileX/CurrentTileY总是会随Camera位置的变化而改变,为了保持他们两对变量保持相等,程序中就对_cmkTileX/_cmkTileY进行相应的++或--,并且在这个过程中更新_cmkUnitX/_cmkUnitY所对应的行,列区域(_cmkUnitX对应的一整列,_cmkUnitY对应的一整行)

最后一步,就是把Carmack Buffer贴到屏幕上,贴粘方法如图3 。

源码: C++版,用VS2010编译,或者mingw

mapcreator用来创建一个默认的地图,tilesetcreator创建默认的tileset。关于Carmack算法的重点都在CMap::CMKRender(Map.cpp里)这个函数里面,这个函数每帧都调用。

PS:我没有讲Carmack的原理,嘴比较笨,不会说。网上可以搜到讲的比较清楚的。所以其实我是在讲我共享的这个代码里的Carmack的实现。

再PS,从点点手动搬过来的,图可能不清晰,看原文

posted on 2012-08-03 15:42 spencer24 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/spencer24/archive/2012/08/03/2621759.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值