【3D技术宅公社】XR数字艺术论坛  XR技术讨论 XR互动电影 定格动画

 找回密码
 立即注册

QQ登录

只需一步,快速开始

调查问卷
论坛即将给大家带来全新的技术服务,面向三围图形学、游戏、动画的全新服务论坛升级为UTF8版本后,中文用户名和用户密码中有中文的都无法登陆,请发邮件到324007255(at)QQ.com联系手动修改密码

3D技术论坛将以计算机图形学为核心,面向教育 推出国内的三维教育引擎该项目在持续研发当中,感谢大家的关注。

查看: 2435|回复: 0

HL2源码分析(框架篇)

[复制链接]
发表于 2005-1-18 22:50:00 | 显示全部楼层 |阅读模式
1.程序入口 作者:cproom (cproom) ------------------------------------------------------------------------- 程序入口在launcher_main\main.cpp中,装载launcher.dll

HINSTANCE launcher = LoadLibrary("launcher.dll");

定位并执行LauncherMain函数

LauncherMain_t main = (LauncherMain_t)GetProcAddress( launcher, "LauncherMain" ); return main( hInstance, hPrevInstance, lpCmdLine, nCmdShow );

LauncherMain函数完成部分初始化并进入游戏主函数Run

IEngineAPI *engineAPI = ( IEngineAPI * )LauncherFactory( VENGINE_LAUNCHER_API_VERSION, NULL ); if ( engineAPI ) { restart = engineAPI->Run( ( void * )hInstance, GetBaseDirectory(), LauncherFactory ); }

最关键的初始化函数是LoadAppSystems(),此函数查找定位各模块(.dll)的CreateInterface函数,这是各模块创建接口实例的工厂函数。此工厂函数的实现依赖于InterfaceReg类和与之配合的几个宏EXPOSE_INTERFACE_FN,EXPOSE_INTERFACE,EXPOSE_SINGLE_INTERFACE_GLOBALVAR,EXPOSE_SINGLE_INTERFACE创建的接口数据库来查找并创建接口。向接口数据库中加入一个接口实例的代码类似

static CEngineClient s_VEngineClient; IVEngineClient *engineClient = &s_VEngineClient; EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CEngineClient, IVEngineClient, VENGINE_CLIENT_INTERFACE_VERSION, s_VEngineClient );

每个模块都有独立的接口数据库,在模块载入时(LoadLibrary)由InterfaceReg的构造函数生成并链接起来。

有了这些工厂函数,就可以通过LauncherFactory函数查询需要的接口实例了。 上面用到的接口实例engineAPI就是这样得到的。

IEngineAPI *engineAPI = ( IEngineAPI * )LauncherFactory( VENGINE_LAUNCHER_API_VERSION, NULL );

这里说不太清楚,大家对照原码就清楚了。欢迎大家继续!

2.模块划分 作者:akun(疑无路) -------------------------------------------------------------------------- 我来说说hl2的模块划分, 每个模块中的接口(其他模块需要使用的)静态实例形成一个单向链表,对外暴露一个接口Factory, 通过这个Factory, 获得各个接口的实例指针。(每个模块dll都有一个CreateInterface的导出函数,通过这个函数获得接口Factory。接口单向链表的查找通过一个预定义的字符串,通过这个字符串还可以实现接口版本控制。具体大家可以参见 EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CEngineClient, IVEngineClient, VENGINE_CLIENT_INTERFACE_VERSION, s_VEngineClient ); 这个宏。 )

下面就是5大模块了~ 1. FileSystem.(Filesystem_stdio.dll)功能肯定是文件系统的包装了,打包解包咯~

2. MaterialSystem. (materialsystem.dll)这里是渲染的实现,包装了dx8,dx7等实现,包括是否可以使用shader, 以及相应的渲染方式。

3. Engine. (Engine.dll)这里就太庞大了,它的接口单向链表里面就有:CEngineTraceServer, CModelRender, CModelInfoServer, CModelInfoClient, CNetworkStringTableContainerClient,CNetworkStringTableContainerServer, CStaticPropMgr, CVEnginServer, CEngineSoundClient, CEnginSoundServer, CShadowManager, CVRednerView等等。太复杂,看名字可以知道大概干吗的,具体一点就不知道了~~^_^。

4. VGui2.(vgui2.dll) 5. vguimatsurface.(vguimatsurface.dll)这2个应该是gui了~

下面是游戏的具体实现了,使用client/server模式,这个模式具体什么样,还没看懂... client.dll 在源码cl_dll那个目录里面。 server.dll 在hl那个目录。 这2个dll里面要调用上面的几个模块里面的接口来实现n多的功能的... Tf2, hl2, hl1, cs的游戏规则都在这里实现,譬如Npc, 武器效果。

其他还有一些零散的模块。 tier0(tier0.dll),这个是比较底层的东东了,处理debug信息,时间,内存管理,游戏的录像,播放也在这里。 vphysics. 物理哦~~ivp目录里面是Ipion Virtual Physics SDK,有详细文档使用说明哦。 .......

下面大家补充。

请大家不要mark,不要up这些无意回复在里面。

3.游戏循环 作者:fohoo -------------------------------------------------------------------------- hl2.exe -> laucher.dll -> engine.dll (swds.dll)

到了engine.run(),然后调RunListenServer RunListenServer: { ... game->init //建主窗口 CreateMainWindow <Message Loop> //消息泵 }

<Message Loop> { ... game->DispatchAllStoredGameMessages()//发布消息给Gui的Controls,进行回调 eng->frame(); //游戏设计中常见的Frame动作 ... }

eng->frame { 调CHostState::FrameUpdate( float time, int iState ) //状态机的状态循环 { ... //看代码很清楚了 switch( m_currentState ) { case HS_NEW_GAME: State_NewGame(); break; case HS_LOAD_GAME: // State_LoadGame(); break; case HS_CHANGE_LEVEL_MP: State_ChangeLevelMP(); break; case HS_CHANGE_LEVEL_SP: State_ChangeLevelSP(); break; case HS_RUN: State_Run( time, iState ); break; case HS_GAME_SHUTDOWN: State_GameShutdown(); break; case HS_SHUTDOWN: State_Shutdown(); break; case HS_RESTART: State_Restart(); break; } ... }

State_Run( time, iState ) { ... Cbuf_execute //当你输入map test时,先放入buffer,然后在这execute ... }

hl2有一个重要ConCommand的类,可扩充要执行的命令

GUI的很多控件操作也就是将Command串放入command buffer中

每个Game有不同的server.dll,cient.dll server.dll 设计场景,NPC.. client.dll 玩家的控制,...研究中..

当new game时

engine.dll会回调server.dll中IServerGameDLL接口GameInit来给 每个GAME初始化的机会

回调IServerGameDLL中的LevelInit装BSP地图()

然后回调IServerGameDLL的ServerActivate来启动GAME

...研究...待续...

个人理解,不对之处,敬请指正

大家一起分享提高吧,早日成就中国的CS!!

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|3D数字艺术论坛 ( 沪ICP备14023054号 )

GMT+8, 2025-2-6 04:44

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表