|
|
发表于 2005-7-25 16:58:00
|
显示全部楼层
quake2 的渲染调用过程
首先看quake2.exe工程中的WinMain() (\quake2-3.21\win32\sys_win.c) 见其中的初始化函数 Qcommon_Init (argc, argv);
见\quake2-3.21\qcommon\common.c 中的void Qcommon_Init (int argc, char **argv) 其中有函数 CL_Init ();
再看\quake2-3.21\client\cl_main.c 中的void CL_Init (void) 可看到 VID_Init (); 在这里有Linux和sgi的部分,声音驱动
是放在视频之前的,而到了window是声音必须放在后面的.
\quake2-3.21\win32\vid_dll.c 中 void VID_Init (void)
最下面就是视频的启动调用
/* Start the graphics mode and load refresh DLL */
VID_CheckChanges();
进入 VID_CheckChanges 函数,
Com_sprintf( name, sizeof(name), "ref_%s.dll", vid_ref->string );
这里就是根据参数进行调用视频模块的dll ref_gl.dll 和 ref_soft.dll
下面紧接着就是调用选定的dll进行初始化 if ( !VID_LoadRefresh( name ) )
qboolean VID_LoadRefresh( char *name )
{
refimport_t ri; //重要的结构,将视频dll的函数都定义在其中 见\quake2-3.21\client\ref.h
GetRefAPI_t GetRefAPI; //typedef refexport_t (*GetRefAPI_t) (refimport_t); 文件位置同上,dll的函数连接点
if ( reflib_active )
{
re.Shutdown();
VID_FreeReflib ();
}
Com_Printf( "------- Loading %s -------\n", name );
if ( ( reflib_library = LoadLibrary( name ) ) == 0 )
{
Com_Printf( "LoadLibrary(\"%s\") failed\n", name );
return false;
}
ri.Cmd_AddCommand = Cmd_AddCommand;
ri.Cmd_RemoveCommand = Cmd_RemoveCommand;
ri.Cmd_Argc = Cmd_Argc;
ri.Cmd_Argv = Cmd_Argv;
ri.Cmd_ExecuteText = Cbuf_ExecuteText;
ri.Con_Printf = VID_Printf;
ri.Sys_Error = VID_Error;
ri.FS_LoadFile = FS_LoadFile;
ri.FS_FreeFile = FS_FreeFile;
ri.FS_Gamedir = FS_Gamedir;
ri.Cvar_Get = Cvar_Get;
ri.Cvar_Set = Cvar_Set;
ri.Cvar_SetValue = Cvar_SetValue;
ri.Vid_GetModeInfo = VID_GetModeInfo;
ri.Vid_MenuInit = VID_MenuInit;
ri.Vid_NewWindow = VID_NewWindow;
//在这里将Dll中的GetRefAPI导出,所有的函数都获得,gl和soft的Dll其导出这里是一样的,
//具体实现函数在内部才有不同.可以看ref_gl和ref_soft两个工程就可知道.
if ( ( GetRefAPI = (void *) GetProcAddress( reflib_library, "GetRefAPI" ) ) == 0 )
Com_Error( ERR_FATAL, "GetProcAddress failed on %s", name );
re = GetRefAPI( ri );//获得成功
if (re.api_version != API_VERSION)
{
VID_FreeReflib ();
Com_Error (ERR_FATAL, "%s has incompatible api_version", name);
}
//调用初始化
if ( re.Init( global_hInstance, MainWndProc ) == -1 )
{
re.Shutdown();
VID_FreeReflib ();
return false;
}
Com_Printf( "------------------------------------\n");
reflib_active = true;
//======
//PGM
vidref_val = VIDREF_OTHER;
if(vid_ref)
{
if(!strcmp (vid_ref->string, "gl"))
vidref_val = VIDREF_GL;
else if(!strcmp(vid_ref->string, "soft"))
vidref_val = VIDREF_SOFT;
}
//PGM
//======
return true;
}
//quake2就这样开始了. |
|