魔方英文名字叫作Rubik's Cube,是由匈牙利建筑学教授和雕塑家Ernő Rubik于1974年发明,最初叫作Magic Cube(这大概也是中文名字的来历吧),1980年Ideal Toys公司开始销售此玩具,并将名字改成Rubik's Cube。算法
魔方在80年代最为风靡,至今未衰。截至2009年1月,魔方在全世界已经售出了3亿五千多万个。最多见的魔方是三阶魔方,由27个小方块构成,共三层,每层9个小方块。个人Demo实现的就是三阶魔方。其余的魔方种类有二阶,四阶及更高阶,也有钻石魔方,五边形魔方,三角魔方等。app
三阶魔方全部可能的排列数是43252003274489856000,这个数实在是太大了,用中文不知道该如何表达。能够打一个比方,若是有这么多个三阶魔方,那么能够覆盖地球表面275次!框架
这是我之前学习DirectX的时候写的一个Demo,大概是2008年左右,当时写完之后高兴了好几天,如今拿出来看看,彼时的情景历历在目。随着年龄的增加,已经不能像之前那么拼命的写程序了,如今想安静下来干点事都是奢望呀,不过对于DirectX的热情却是有增无减,一有时间仍是会抽空写点代码。对于强大的DX来讲,这个Demo简直是小儿科了,不过麻雀虽小,五脏俱全。再小的东西也有值得学习和总结的地方,本着这个目的,我将这个Demo重新整理了一下,简化了一些代码,并改进了一些算法,拿出来和你们分享。说实话,这个Demo有不少地方我不是很满意,发出来也是为了能收集一下你们的意见,继续改进,欢迎你们多多指教。我打算分几个部分详细介绍一下这个Demo的编写原理。学习
程序采用C/C++语言+DirectX 9.0编写,用的仍是固定管线API,由于我对shader不太熟悉,稍后有空学习一下能够出个shader版本。也可能移植到DirectX 11上,就算是练练手吧。这个Demo涉及的技术有如下几个方面。设计
俗话说得好,有图有真相!先来个透视照(线框图)3d
而后来个素颜照(实体未贴图)blog
再来个有贴图的(穿上衣服后,好看多了),魔方的颜色采用国际标准配色。接口
旋转某一层图片
打乱顺序ip
起初,模型采用的是DirectX的.x文件格式,如今.x格式已经被微软抛弃了,尽管你仍然可使用它,可是在DirectX 11中,已经没有支持.x文件的接口了。要使用.x文件,只能使用旧版本的DirectX SDK或者用第三方库。因为魔方对应的几何模型比较简单,就是立方体,因此就干脆不用.x文件了,直接画,一个完整的魔方由27个小的立方体构成,因此若是能绘制一个小立方体,那么就能够绘制27个,拼成一个完整的魔方。
关于贴图,开始用的是纹理图片,后来简化了一下,直接在内存中生成纹理,由于单色的,并且只有六种颜色,并不麻烦。动态生成的一个好处是发布程序的时候也不一样发布纹理图片了,只有一个可执行文件。
旋转魔方是经过鼠标拖拽来完成的,分为以下两个部分:
前者经过变换视角来完成,实现采用Arcball技术,Arcball有不少优势,相比欧拉角来讲,Arcball更加平滑,并且没有抖动现象(这个本质是由于Arcball里面采用的是Quaternion)。变换视角而不是经过旋转魔方自己的好处是
后者经过旋转模型自己来实现,由于变换视角会影响场景中的全部模型,而旋转某一层要保证其余层不动,因此只能旋转模型自己,由于将魔方拆成了27个小的cube。这对于只操做某些部分而维持其余部分不变是十分方便的。旋转某一层的方法以下
主要有以下几个类及文件
先出个不太成熟的版本,bug必定很多,欢迎你们提出宝贵意见。
== Happy Coding ==