07 2010 档案
摘要:如果你自己都不清楚所谈论的东西,就根本不可能精确的描述它——冯诺依曼 今天我就试着来表述一件众人皆知的事情,以测试自己到底有没有明白这件事情。 OGRE是著名的设计模式大师,这已是不争的事实。可以说OGRE里将设计模式用得淋漓尽致。在这里我就不批判设计模式该不该用了。反正OGRE已经用了,并且没有出
阅读全文
摘要:赵青-《剑侠情缘网络版》开发回顾,(转自剑网1,作者应该是原剑网3技术总监)这篇文章首发于一本谈游戏研发的杂志,是赵青写的,写得非常不错。《剑侠情缘网络版》开发回顾 2003 年的1月,我刚刚开发完《天王》项目,正在休息、总结和规划下一个项目。《天王》是我开发的众多项目中最满意的一个,虽然这篇文字主要是对《剑侠情缘网络版》(以下简称《剑网》)这个项目的回顾,但作为《天王》的项目经理和主程序,我还是想简单谈谈它。《天王》有几个第一:它是西山居第一个采用外购引擎来开发的游戏,第一个3D游戏,第一个动作类游戏,第一个被我们自己的开发人员所认同、并且愿意自发测试的游戏。虽然由于开发时间短、人员少以及我
阅读全文
摘要:首先要说明的是资源格式。资源格式一般存放如下格式资源|--- part0|----part1|----part2|...一个很好的例子就是模型信息文件,在一个模型信息文件中,存放了整个物体的所有部分,每一个部分又是单独的信息。这样做的目的在于游戏中的换装。 还有一个例子就是特效文件,比如将一个门派的技能做为一个特效文件,而这个特效文件中包含了所有技能的技能特效。又或者说,当我们要实现不同等级的技能有不同特效的时候,就可以将一个技能做一个特效文件,而特效文件中存放的则是不同的等级的特效。接下来就是要说明逻辑和渲染部分的划分。有些游戏是直接将渲染和逻辑嵌在一起的。这样做我觉得非常不好,不便于后期扩
阅读全文
摘要:Intel的X86中的RDTSC即Read Time Stamp Counter 读取时间计数器的指令。这个指令读取CPU时间计数器,返回一个无符号的64位整数。它通过EDX EAX寄存器返回CPU被引导后,时钟所走的圈数。这意味着,你可以用它来计算时间间隔了多久。但是,由于这个指令还未被VC++采用,于是如果想要使用它,则必须用_emit伪指令嵌入它的OPCODE 0x0f 0x31。 于是可以写出一个取得时间计数器的代码如下inline unsigned __int64 GetCycleCount(){ _asm _emit 0x0f _asm _emit 0x31} 不难想象,如果我们取
阅读全文
摘要:打开WORD很久了,却始终无从下手。那种文字从指间流露出来的感觉,我是没有的。想说很多话,却又说不出来。若让我写上一篇关于如何做某某事的文章,或许我可以认真地做好,并且我很乐意那样。但让我表达自己的情感,一时间竟然不知所措。但是我告诉自己,我一定要写出来,写一篇关于自己的文章。毕业了,2010年6月29号那天。那一天,我回去了,并且,我也应该回去。至少群里人都是这么说的。大家都异常淡定,像往常一样聚餐,像往常一样不喝酒。像往常一样去网吧上会儿网,像往常一样回寝室休息。像往常一样,临走的前一天,有人通宵了。走的时候,像往常一样,大家悄悄地离开。就好像是期末结束,各自回家一样,并未曾感受到此次的分
阅读全文
摘要:Windows窗口消息不看不知道,一看吓一跳。原来就只是单单理解了SendMessage和PostMessage。前者是发送完要处理后再返回,后者是发送后立即返回,不管有没有处理。但今天仔细看了书上讲解后,才发现原来事情多着呢。窗口对象:线程里会有两种特别的对象,即窗口对象和挂钩对象。要知道,进程是分配资源的单位,因此,如果我们创建了某些资源,当我们没有明确要求释放的时候,这些资源只有在进程退出时才被释放。 但窗口对象和挂钩对象不同,他们是属于创建他们的线程的。原因是,窗口和挂钩对象的消除需要依靠WM_DESROY和WM_NCDESTROY消息,而如果线程退出了,消息循环不再继续,窗口收不到销
阅读全文
摘要:当我们要进行消息处理的时候,通常需要写出一系列的消息函数,然后再将这些函数指针赋值给一个函数指针数组。当要使用的时候,根据消息编号确定在数组中的位置。 在C++中,成员函数指针写着很不顺手。。于是做了一个基类。。这个基类有个限制,就是只能处理两个参数的消息处理函数。第一个是消息ID,第二个就是消息内容。不过多数情况下已经够用。。。#include "stdafx.h" #include iostream #include stdio.h #include assert.h enum EDataType { eData0, eData1, eData2, eData3, eData4
阅读全文
摘要:CPU为了更快的执行代码。于是当从内存中读取数据时,并不是只读自己想要的部分。而是读取足够的字节来填入高速缓存行。根据不同的CPU,高速缓存行大小不同。如X86是32BYTES,而ALPHA是64BYTES。并且始终在第32个字节或第64个字节处对齐。这样,当CPU访问相邻的数据时,就不必每次都从内存中读取,提高了速度。 因为访问内存要比访问高速缓存用的时间多得多。但是,多核发达的年代。情况就不能那么简单了。试想下面这样一个情况。1、 CPU1读取了一个字节,以及它和它相邻的字节被读入CPU1的高速缓存。2、 CPU2做了上面同样的工作。这样CPU1,CPU2的高速缓存拥有同样的数据。3、 C
阅读全文
摘要:WINDOWS中定义了一个CONTEXT结构,该结构包含了特定处理器上的寄存器数据。系统使用CONTEXT结构执行各种内部操作。目前,已经存在为Intel、MIPS、Alpha和PowerPC处理器定义的CONTEXT结构。若要了解这些结构的定义,可以去看WinNT.h。该结构并没有说明结构体内的成员,也没有描述这些成员是谁,因为这些成员要取决于WINDOWS运行在哪个平台上。在WINDOWS定义的所有数据结构中,CONTEXT结构是特定于CPU的唯一结构。在CONTEXT结构中,它包含了主机CPU上的每个寄存器的数据结构。在X86计算机上,数据成员是EAX,EBX,ECX,EDX等等。如果是
阅读全文
摘要:关于VOID Sleep(DWORD dwMilliseconds);函数,许多人都觉得,它是告诉系统,延迟多少毫秒来执行后面的代码。但是,在WINDOWS这样的非实时多任务系统中,我们是无法估算会睡眠多久的。因为一个线程不是总是被执行的。它会在执行一段时间后,被系统暂停,然后系统又去执行另外的线程代码。于是,Sleep函数的解释如下:当调用Sleep函数的时候,比如Sleep(400);它告诉系统,此线程将放弃此次运行的时间片,比方说现在线程只执行了10ms,按“有关部门规定”它被唤醒一次是要执行20ms的。这时它就说,这次机会我放弃,后面的10ms不要了。下次轮上我再叫我。 这样,系统便会
阅读全文
摘要:线程由两部分构成:线程内核对象:操作系统用它来对线程实施管理。内核对象也是系统用来存放线程统计信息的地方。线程堆栈:它用于维护线程在执行代码时需要的所有函数参数和局部变量。我们必需要知道一个事实-----进程(WINDOWS中)是不能被调度的。通常所说的调度,都是对线程而言的。进程仅仅是线程的容器,是系统统分配资源的单位。 这样,线程自身不会分配资源。同一进程中的多个线程共同使用它们父进程的资源。一个进程至少需一个线程,如果一个进程中不存在线程(所有线程都退出)。则系统认为这个进程没有存在的必要,于是便会撤消这个进程,并释放他占用的资源。在VC环境中,我们可以调用CreatThread来创建一
阅读全文