程序的天空

我的学习心得

导航

Quake2源码分析(3)

Posted on 2008-08-15 16:16  帕托  阅读(1519)  评论(1)    收藏  举报

追踪SCR_UpdateScreen(客户端的主要负责渲染的函数):

为了追踪这个函数,我们给出了函数的每桢循环的主要部分:

 

for ( i = 0; i < numframes; i++ )              //一般只有1桢,当cl_stereo->value值不为0时有2桢
 {
     re.BeginFrame( separation[i] );
            //ref_export开始桢

 

       if (scr_draw_loading == 2)                    //这种情况下屏幕显示一个loading图像
       { //  loading plaque over black screen
        int  w, h;

        re.CinematicSetPalette(NULL);
        scr_draw_loading = false;
        re.DrawGetPicSize (&w, &h, "loading");                  //得到loading图像的位置
        re.DrawPic ((viddef.width-w)/2, (viddef.height-h)/2, "loading");             //画loading图像
     //   re.EndFrame();
     //   return;
       } 


       // if a cinematic is supposed to be running, handle menus
       // and console specially
       else if (cl.cinematictime > 0)             //cinematic时间,也就是非游戏运行时间,游戏等待用户的菜单,控制台或其他输入。
       {
             if (cls.key_dest == key_menu)         //处理菜单
             {
                   if (cl.cinematicpalette_active)
                   {
                    re.CinematicSetPalette(NULL);          //设置调色板
                    cl.cinematicpalette_active = false;
                   }
              M_Draw ();           //画菜单
            //    re.EndFrame();
           //    return;
             }


             else if (cls.key_dest == key_console)        //处理控制台
             {
                   if (cl.cinematicpalette_active)
                   {
                    re.CinematicSetPalette(NULL);          //设置调色板
                    cl.cinematicpalette_active = false;
                   }
              SCR_DrawConsole ();          //画控制台
          //    re.EndFrame();
          //    return;
             }
             

             else
             {
              SCR_DrawCinematic();           //画默认的图像
          //    re.EndFrame();
          //    return;
             }
       }


       else            //这种情况下渲染游戏场景
       {

        // make sure the game palette is active
        if (cl.cinematicpalette_active)             //设置cinematic的调色板为不活动的
        {
         re.CinematicSetPalette(NULL);
         cl.cinematicpalette_active = false;
        }

 

        // do 3D refresh drawing, and then update the screen
        SCR_CalcVrect ();           //计算垂直矩形的x,y坐标

 

        // clear any dirty part of the background
        SCR_TileClear ();           //计算背景的脏区域,调用re.DrawTileClear

 

        V_RenderView ( separation[i] );        //渲染视图区域,这个函数会调用re.RenderFrame (&cl.refdef);,稍候讨论

 

        SCR_DrawStats ();          //画一些统计数据


        if (cl.frame.playerstate.stats[STAT_LAYOUTS] & 1)

         SCR_DrawLayout ();              //画一些统计数据


        if (cl.frame.playerstate.stats[STAT_LAYOUTS] & 2)
         CL_DrawInventory ();           //画一些热键物品

 

        SCR_DrawNet ();               //画网络数据


        SCR_CheckDrawCenterString ();             //对scr_centerstring在屏幕中部绘画

 

        if (scr_timegraph->value)
         SCR_DebugGraph (cls.frametime*300, 0);       //计算调试图

 

        if (scr_debuggraph->value || scr_timegraph->value || scr_netgraph->value)
         SCR_DrawDebugGraph ();
           //画调试图

 

        SCR_DrawPause ();         //如果停止值被设定,画停止图

 

        SCR_DrawConsole ();        //画控制台

 

        M_Draw ();               //调用m_drawfunc ()绘画菜单

 

        SCR_DrawLoading ();          //如果正在加载,画加载图像
       }
    }  //循环结束


 re.EndFrame();        //结束这个桢

 

     在分析过这个函数后,我们会分析quake2模块和game,ref模块的交互,然后分析ref_gl和ref_soft模块。