
第二人生
caimouse
在IT行业有20多年的经验。拥有20多年的C和C++开发经验,5年以上Python开发经验,资深数据库开发、上百G数据库优化经验。曾经任职嵌入式工程师、P2P开发工程师、银行信用卡交易系统工程师、全自动化电池测试部门经理。
展开
-
第二人生的源码分析(二十)显示人物名称
在第二人生里,每个人物显示都有一个名称,那么这个名称又是怎么样显示出来的呢?怎么样实现的呢?带着这两个问题,下面就去分析第二人生里面的实现代码。它的人物名称显示如下:蔡军生 2008/01/24 QQ:9073204 深圳从上面的图片上,可以看到人物的头上有一个名称显示,用来标识人物角色。要显示这个人物名称,肯定是在二维的空间里显示的。每个人都有一个名称显示,很多人在一起时,就需要原创 2008-01-24 23:17:00 · 5557 阅读 · 2 评论 -
第二人生的源码分析(二十一)显示人物名称的字体
前面已经介绍了显示人物名称的基本框架,但是使用OpenGL显示这个名称出来是需要很复杂的步骤。由于OpenGL是图形引擎显示,也就是说所有字符的显示都是基于图形来显示,而图形的显示,就需要获取字体的图片,即是获取字体的字模。由于不能使用Windows的标准GDI来显示,那么就需要实现GDI所做的所有功能,比如从字体里读取每个字符的轮廓,然后生成合适大小的位图,再把这幅位图当作纹理贴到3D的平面上去原创 2008-01-25 22:34:00 · 3762 阅读 · 0 评论 -
第二人生的源码分析(二十二)调用OpenGL显示人物名称的函数
继续前一次所介绍的人物名称显示,再来仔细地深入分析字体渲染,到底怎么样设置OpenGL函数才能显示出来呢?先来看下面一段代码:#001 void LLFontGL::renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const#002 {#003 glTexCoord2f原创 2008-01-29 21:29:00 · 5367 阅读 · 4 评论 -
第二人生的源码分析(二十三)人物行走的键盘消息处理
前面介绍了怎么样显示人物角色,包括名称等等。那么人物角色是怎么样在里面行走的呢?第二人生是通过方向键来控制人物角色的走动,也就是说它是通过接收键盘的消息后不断地计算新的位置来实现移动。下面就是第二人生的消息处理函数代码:#001 bool LLAppViewer::mainLoop()#002 {#003 //---------------------------------原创 2008-03-12 21:08:00 · 4266 阅读 · 1 评论 -
第二人生的源码分析(二十四)人物向前走的键盘消息处理
下面再来详细地分析一下,当玩家按下向上方向键时第二人生到底做了些什么呢?又是怎么样地控制人物向前行走的呢?下面的函数就是实现这样的功能:#001 void agent_push_forward( EKeystate s )#002 {#003 if( KEYSTATE_UP == s ) return;#004 F32 time = gKeyboard->ge原创 2008-03-13 23:16:00 · 5170 阅读 · 0 评论 -
第二人生的源码分析(二十五)人物行走与服务器同步
在网络游戏里,玩家的行走与平时单机版的游戏有着很大的差别,当你按下键盘时,人物角色并不能立即就向前行走,而是需要把它移动的请求发送到服务器,让服务器来作出判断是否可以行走,然后把行走位置通知视野里所有其它玩家,第二人生的客户端就会把这个人物按位置信息显示出来。下面就来分析怎么样发送玩家状态信息给服务器。 #001 void LLAppViewer::idle()#002 {#003原创 2008-03-14 22:12:00 · 6235 阅读 · 1 评论 -
第二人生的源码分析(1)第一个画面
第二人生是一款3D为界面的虚拟世界产品,下面先来感受一下这个界面带来巨大的真实性: 通过个画面,可以看到太阳,树,人,椅是那么的逼真,这些都是通过3D技术实时显示出来的,因此对电脑的硬件需求比较高,特别对显示卡的需求更高,同时对网络的带宽也要求比较高,不过,随着技术的发展,已经具备这样的条件了。现在最流行的配置,比如3000元左右的电脑,就已经显示得不错了。在第二人生这个虚拟世界里,强原创 2007-12-26 21:22:00 · 12240 阅读 · 10 评论 -
第二人生的源码分析(二十六)底层网络协议
为了理解第二人生的客户端与服务器的沟通,那么下面就来分析一下第二人生采用的网络协议。在目前的网络里,主要有两个协议:TCP和UDP,而第二人生里是采用UDP协议。TCP协议与UDP协议的主要区别,就是TCP有流量控制,可靠性控制,IP层组包功能,连接需要三次握手,而UDP没有这些保证,因此UDP发送的数据包需要自己来管理数据的有序性和可靠性。先来分析最底层的协议,它调用UDP发送数据的源码如下:原创 2008-03-20 21:59:00 · 6609 阅读 · 0 评论 -
第二人生的源码分析(2)第二人生的基本功能
第二人生的基功能可以定义为网络游戏、社交网络和Web2.0。作为网络游戏,它可以让人扮演角色,也就是第二人生里的居民。居民只要买到地,或者租到地后就可以建造各种各样的自己想得到的东西。比如建造游乐园,或者建造电影院,又或者建造过山车。同时,还可以实现居民在虚拟世界里飞行。作为社交网络,第二人生里的居民可以相互结交朋友,随时可以聊天。还可以组成各种各样的组织,比如举行音乐原创 2007-12-30 20:42:00 · 8981 阅读 · 3 评论 -
第二人生的源码分析(3)程序入口点
所有Windows图形应用程序都是拥有相同的入口点函数WinMain,因此第二人生的程序也不例外。下面先来看看这个函数的代码,如下: //蔡军生 2007/12/28 QQ:9073204 深圳#001 int APIENTRY WinMain(HINSTANCE hInstance,#002 HINSTANCE hPrevInstanc原创 2008-01-01 10:22:00 · 10857 阅读 · 12 评论 -
第二人生的源码分析(4)Log调试功能的实现
对于一个比较复杂的软件来说,没有Log调试系统,就像一个人没有眼睛一样,看不到任何东西。对于一个能稳健运行的软件来说,Log调试系统是必须有的,否则这个软件是开发不成功的。如果在开发软件过程里,没有强调Log系统的实现,就等于这个软件运行的不稳定性已经存在其中,后期调试工作和源码维护都存在严重的问题。在《第二人生》的源码里已经开发一个非常容易使用的Log系统,这个Log系统具有如下特点:1、原创 2008-01-02 23:51:00 · 7180 阅读 · 4 评论 -
第二人生的源码分析(5)类Log的实现
类Log定义如下:#001 class Log#002 {#003 public:#004 static bool shouldLog(CallSite&);#005 static std::ostringstream* out();#006 static void flush(std::ostringstream*, c原创 2008-01-03 22:26:00 · 7197 阅读 · 0 评论 -
第二人生的源码分析(6)类CallSite的实现
类CallSite提供了保存一行Log的信息,以便保存所有的LOG到容器里,方便管理以及输出到文件,同时输出到其它需要输出的界面。使用这个类是先调类CallSite的构造函数来保存Log所在的函数名称、类名称、文件名称和行号,还有是否需要输出Log等信息,接着就保存在类Log里保存到全局的容器里。它的代码如下:#001 namespace LLError#002 {#003 Call原创 2008-01-04 22:18:00 · 4503 阅读 · 0 评论 -
第二人生的源码分析(7)应用程序实例类
在用C++设计一个应用程序时,总会使用应用程序实例类来管理所有事情,也就是说所有应用程序实例对象只有一个,并且保存这个应用程序所有状态,跟踪这个应用程序的变化。在第二人生里,也毫无例外地采用这种方案,现在就来分析一下应用程序实例类。它们的继承关系如下:在文件llapp.h里定义类class LLApp,在文件llappviewer.h里定义类class LLAppViewer : publ原创 2008-01-06 11:14:00 · 4183 阅读 · 0 评论 -
第二人生的源码分析(8)登录状态界面显示
登录服务器是一个基本的功能,下面就来了解一下第二人生的登录界面设计与实现,先来分析一下登录状态界面的显示。它的界面如下图: 从上面的界面,就可以看到界面的基本组成有窗口、菜单和状态显示,由于登录时需要从服务器下载数据,这是一个比较漫长的过程,因此需要提示这个下载过程正在进行中。在第二人生里要显示上面一个界面,也是比较复杂的事情,因为它所有界面的显示都是基本OPENGL的显示实现原创 2008-01-06 22:40:00 · 5736 阅读 · 0 评论 -
第二人生的源码分析(9)登录界面显示
登录状态界面之后,就是登录界面出现了,这时需要用户输入用户名称和密码,然后再连接到第二人生的WEB服务器,并且把用户名称和密码发送过去进行验证。当验证成功后,就会返回合适的数据给客户端,让客户端进行下一步的工作。登录界面的图片如下:蔡军生 2008/1/7 QQ:9073204 深圳 在登录界面里是怎么样把用户名称和密码传送给浏览器的呢?其实,这个界面也是由网页构成,因此它就是通过原创 2008-01-07 21:52:00 · 6280 阅读 · 1 评论 -
第二人生的源码分析(10)登录授权的实现过程
在信息的社会里,越来越多东西实现了数字化,带给大家方便的同时,也面临着严重的信息安全挑战。特别是个人帐号信息的安全性,或者判别一个人是否合法登录服务器的问题,都极其艰难。特别像第二人生这样的系统,它的交易系统是跟实现生活里的金钱联系在一起的,这样对它的验证要求就更加严格了。下面的图片,就是显示正在验证登录过程。 蔡军生 2008/1/8 QQ:9073204 深圳在第二人生里,第一次验原创 2008-01-08 21:28:00 · 6193 阅读 · 0 评论 -
第二人生的源码分析(11)地面显示的实现
通过所有验证之后,第二人生就会连接到GRID服务器,从服务器上获取很多信息,比如角色的位置,虚拟世界的时间等等。接着就会根据这些信息去构造一帧帧的图片显示出来,在这里先看看下面的图片:蔡军生 2008/1/8 QQ:9073204 深圳从这幅图片上,就可以看到有天空,有地面,还有房子,人和树等等。这么多东西都是一样一样实时渲染出来的,现在就来看看地面是怎么构造出来的。目前的3D技术都是原创 2008-01-10 00:00:00 · 6994 阅读 · 0 评论 -
第二人生的源码分析(12)天空显示的实现
在虚拟世界里,自然现象的实现是最需要实现的,比如天空的实现,以便反映是白天还是晚上,这样才逼真反映现实世界。在第二人生里实现的天空,还是比较好的,如下图所示:蔡军生 2008/01/10 QQ:9073204 深圳从上面的图片里,可以看到太阳在远处,并具有雾化的效果,这是早上太阳升起的效果。看到远处是浅蓝色的天空,与海边连接成一体。在室外场境的模拟中,最重要的就是天空体的实现。目前实现原创 2008-01-10 22:33:00 · 11389 阅读 · 4 评论 -
第二人生的源码分析(13)树显示的实现
在室外场境的实现中,有很多植物是需要显示出来的,比如树和花草是最常见的植物。下面就来看看第二人生里树显示的实现,如下图所示: 蔡军生 2008/01/13 QQ:9073204 深圳看到如此优美的画面,让人感觉就是身临其境,快活如神仙一般。这样才提供给人们快乐的环境,度过美好的人生。那么这么优美的树是怎么样实现的呢?现在就来分析一下第二人生里树显示的实现,跟前面地面和天空一样原创 2008-01-13 21:19:00 · 5417 阅读 · 1 评论 -
第二人生的源码分析(三十一)接收数据的流量控制
数据接收回来后,本来就应立即处理掉,这样是比较简单的想法。但由于网络带宽有限,这时就需要限制UDP接收数据的速度。下面就来分析这种需求的实现,它的代码如下:#001 S32 LLPacketRing::receivePacket (S32 socket, char *datap)#002 {#003 S32 packet_size = 0;#004 下面判断是否原创 2008-04-08 21:52:00 · 4046 阅读 · 2 评论 -
第二人生的源码分析(二十八)UDP发送数据的可靠性控制
学习过网络编程的人,应该都知道UDP是“不可靠”的协议。不知道你有没有想过UDP为什么不可靠,不可靠在那些方面。其实,UDP和TCP协议一样都是建立在不可靠的IP协议之上,UDP的不可靠是指它不具备流量控制,不具备数据包顺序达到,不具备验证数据包是否丢失。那么在第二人生里使用UDP协议又是怎么样来实现可靠的数据传送的呢?现在就来分析下面这段代码:#001 // This can be call原创 2008-04-03 21:18:00 · 2993 阅读 · 4 评论 -
第二人生的源码分析(二十九)Windows网络初始化
上面已经介绍怎么样通过网络发送数据了,但心里又有一个问题,就是网络是怎么样进行初始化,才能发送数据呢?怎么样创建Windows下的UDP协议的呢?现在就来分析这段初始化的代码。#001 S32 start_net(S32& socket_out, int& nPort) #002 { #003 // Create socket, make no原创 2008-04-04 23:58:00 · 3272 阅读 · 0 评论 -
第二人生的源码分析(三十)UDP接收数据和Windows网络关闭
从上面的协议就知道,有发送数据,就肯定有接收数据;有初始化,就肯定有结束。跟人的生命是一样的,有始就有终。那么第二人生里是怎么样接收数据呢?又是怎么样关闭Windows网络呢?通过下面的代码就可以学会怎么样使用UDP接收数据,并且关闭网络,回收资源给Windows系统。 下面的代码先判断是否创建了socket,如果创建了,就接着先关闭网络通讯,再接着删除socket句柄。最后调用函数WSA原创 2008-04-07 22:30:00 · 7797 阅读 · 0 评论 -
第二人生的源码分析(十四)人物角色的实现
在第二人生里,最重要的实现就是人物角色的实现,它不是基于第一视角实现的,而是第三视角的方式实现,因此每个居民在第二人生里是有一个虚拟人物角色代表的。这样构造出来的社会是多姿多彩,先来看看下面人物角色的图片:蔡军生 2008/01/14 QQ:9073204 深圳蔡军生 2008/01/14 QQ:9073204 深圳从上面看到各种各样的人物角色,穿着不同的衣服,摆出原创 2008-01-14 22:14:00 · 5606 阅读 · 2 评论 -
第二人生的源码分析(三十二)消息解包的实现
从UDP接收到数据后,就会组装成一个完整的数据包,然后检验整个数据包是否有效,并且还处理收到回应的UDP包标识,这样构造一个完整的可靠性连接。具体处理代码如下:#001 BOOL LLMessageSystem::checkMessages( S64 frame_count )#002 {#003 // Pump #004 BOOL valid_packe原创 2008-04-09 23:23:00 · 6785 阅读 · 5 评论 -
第二人生的源码分析(十七)人物Mesh数据显示的实现
前面介绍了怎么样读取人物的Mesh数据,那么你也许会想到,读取数据之后是怎么样显示出来的呢?并且显示出活生活现的人物来。现在就来分析第二生里怎么样显示人物Mesh数据,它的显示流程如下:1、 LLAppViewer::mainLoop() 主线程的消息循环函数。2、 display() 主要渲染函数。3、 LLPipeline::renderGeom() 渲染管道显示函数。4、原创 2008-01-17 22:28:00 · 5468 阅读 · 0 评论 -
第二人生的源码分析(十五)Mesh文件的读取
从前面可以看到人物角色显示是比较重要的,也是比较复杂的。现在就来仔细地分析一下第二人生里的Mesh文件是怎么样读取的呢?可以显示出来如此逼真优秀的画面。如下图所示:蔡军生 2008/01/15 QQ:9073204 深圳在Mesh文件保存的格式里,最常用的有两种格式:文本格式和二进制格式。文本格式就是占用空间比较大,并且读取文件的数据也比较慢,但它便于查看。二进制格式是刚好原创 2008-01-15 22:14:00 · 6126 阅读 · 1 评论 -
第二人生的源码分析(十八)人物纹理显示的实现
上面已经介绍怎么样显示Mesh数据,也就是人物模型已经显示出来,那么同样的模型怎么样构造出各种各样的人物来呢?在第二人生里是使用各种各样的纹理图片来实现的。下面就来仔细地分析这段代码,如下:#001 U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass)#002 {#003 if (!mVali原创 2008-01-18 22:44:00 · 4511 阅读 · 0 评论 -
第二人生的源码分析(三十五)分析消息模板文件
这种灵活的通讯消息结构到底是怎么样实现的呢?下面就来仔细地分析它实现的代码,如下:#001 // Read file and build message templates#002 void LLMessageSystem::loadTemplateFile(const char* filename)#003 { 首先判断文件名称是否合法。#004 if(!fil原创 2008-04-12 23:27:00 · 3478 阅读 · 2 评论 -
第二人生的源码分析(三十三)消息解包的实现
下面的代码是实现数据包的有效性检验,先调用函数validateMessage来检验接收数据缓冲区里是否有效的数据包,然后调用getMessageName函数来查看是否属于这个环路的数据包,最后判断数据包是否值得信任的或者是否禁止接收的数据。#159 // UseCircuitCode can be a valid, off-circuit packet.原创 2008-04-10 22:22:00 · 4039 阅读 · 0 评论 -
第二人生的源码分析(三十四)读取通讯的消息模板
在开发通讯的软件里,要让通讯的两端程序相互对话,其实就跟人与人的交流是一样的,要使用共同语言,而不能一个人说英语,一个人说汉语。由于通讯两端是分别在不同的程序里,那么就需要定出一套相互认同的语言—协议定义。而定义协议的办法有很多种,比如直接写成C结构,这样的方式最直接了,但它有点不灵活。又有采用XML的方式,这样虽然灵活了,但它的通讯消息大小又太大了,不便于传送,对于中国慢慢网络来说,又太不现实。原创 2008-04-11 23:21:00 · 2744 阅读 · 0 评论 -
第二人生的源码分析(十六)保存人物角色的XML文件
前面介绍怎么样从文件里读取Mesh数据,那么怎么样知道数据从那里读取回来呢?这些信息又是记录在那里呢?现在就来分析这方面的问题。其实在第二人生里把这些信息保存在XML文件里的,可以在第二人生的目录character里找到文件avatar_lad.xml,这个文件就记录了人物角色组成信息。比如每个部位的组成文件名称,就可以通过下面XML片段可以找到: type="hairMes原创 2008-01-16 23:42:00 · 5031 阅读 · 0 评论 -
第二人生的源码分析(十九)人物组合显示
在第二人生里,人物的显示是比较复杂的,因为同一个网格模型可以显示为不同的人物出来,也就是人物每个部位的纹理不一样,比如不同的女孩子就有可能选择不同的头发,还可以穿着不同的衣服,不同的裤子等等。要实现这些功能,也就是说要把头、上身、下身、脚分开来显示。如下图所示:蔡军生 2008/01/22 QQ:9073204 深圳 现在就来仔细地分析一下第二人生里是怎么样分别显示不同身体部份的,原创 2008-01-22 22:04:00 · 4039 阅读 · 0 评论 -
第二人生的源码分析(三十六)获取消息包里每一个字段
上面介绍了怎么样构造消息模板,并用它来灵活地生成各种各样需要传送数据的数据结构,现在就来分析一下使用模板怎么样去分析缓冲区里的数据,然后获取消息各个字段数据,这样才可以让别的程序使用起来。#001 BOOL LLTemplateMessageReader::readMessage(const U8* buffer, #002原创 2008-04-14 21:53:00 · 3351 阅读 · 0 评论 -
第二人生的源码分析(三十八)构造一个消息包并发送
消息解包已经看得比较多了,现在就来分析一下怎么样打包一个消息包。上面已经介绍了通过UDP发送消息包给服务器,这里主要介绍打包的过程,它的代码如下:#001 void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_group,#002 S原创 2008-04-16 22:57:00 · 3928 阅读 · 0 评论 -
第二人生的源码分析(三十七)消息处理的完整流程
虽然上面介绍了这么多消息处理:从网络接收到数据,再从数据解释到数据获取,但没有一个清晰的流程,下面就来详细地分析这个数据流程是怎么样调用的。具体调用流程如下:1. LLAppViewer::idle() 空闲时处理函数。2. LLAppViewer::idleNetwork()空闲时处理网络事件。3. LLMessageSyste原创 2008-04-15 23:29:00 · 3673 阅读 · 0 评论 -
第二人生的源码分析(四十)创建多个工作线程
多线程的程序是比较常见的,更何况是网络程序。随着多核CPU的发展,想提高程序的性能,只能靠多线程工作了。下面就带你看看第二人生是怎么创建多线程工作的,每个线程又是做什么样的工作。由于线程类是主动类,线程的工作结构就是程序的工作结构了,写一个好的程序,往往就是线程类的结构安排,也就是整个程序的架构实现。并且每个线程之间的交互,都需要小心地进行着,一着不慎就全盘皆输,造成多个线程之间死锁的出现,因此写原创 2008-04-18 23:26:00 · 2781 阅读 · 0 评论 -
第二人生的源码分析(三十九)关闭WinXP的错误报告功能
在Windows XP系统里,如果一个程序出错了,就会产生一个程序错误报告,并且可以发送到微软去。对于用户自己开发的程序出错,并不需要发送到微软去,因为那样做是没有什么作用的,毕竟微软不会帮我们改正程序的,那么怎么样来修改出错时不发送到弹出程序出错报告呢?现在就来看看第二人生里是怎么样实现的吧。它的代码如下:#001 void LLAppViewerWin32::disableWinError原创 2008-04-17 22:57:00 · 4317 阅读 · 2 评论 -
第二人生的源码分析(四十一)使用Apache运行库线程
对于跨平台的应用程序设计,考虑的东西一般都需要比较多,比如线程的设计,在Windows平台和Linux平台就是不一样的API,要适应这两种平台,就需要把这两种API接口通过封装成统一的编程接口,做这样工作的任务也是比较艰难的,因为需要不断地在两个系统上测试。由于Apache基金软件里有这样的共享库,就不必自己再去开发一套,使用现成的Apache软件既提高了开发效率,又可以保证跨平台运行。下面就来分原创 2008-04-20 11:28:00 · 3081 阅读 · 0 评论