//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // // $Workfile: $ // $Date: $ // $NoKeywords: $ //===========================================================================// // HDRFIXME: reduce the number of include files here. #include "render_pch.h" #include "cdll_int.h" #include "client_class.h" #include "icliententitylist.h" #include "traceinit.h" #include "server.h" #include "r_decal.h" #include "r_areaportal.h" #include "ispatialpartitioninternal.h" #include "cdll_engine_int.h" #include "ivtex.h" #include "materialsystem/itexture.h" #include "view.h" #include "tier0/dbg.h" #include "staticpropmgr.h" #include "icliententity.h" #include "gl_drawlights.h" #include "Overlay.h" #include "vmodes.h" #include "tier1/utlbuffer.h" #include "vtf/vtf.h" #include "bitmap/imageformat.h" #include "cbenchmark.h" #include "ivideomode.h" #include "materialsystem/imaterialsystemhardwareconfig.h" #include "../utils/common/bsplib.h" #include "ibsppack.h" #include "vprof.h" #include "paint.h" #if defined(_PS3) #include "buildindices_PS3.h" #include "buildworldlists_PS3.h" #endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" bool g_RendererInLevel = false; void Linefile_Read_f(void); /* ==================== // if( r_drawtranslucentworld ) // { // bSaveDrawTranslucentWorld = r_drawtranslucentworld->GetBool(); // NOTE! : We use to set this to 0 for HDR. // r_drawtranslucentworld->SetValue( 0 ); // } // if( r_drawtranslucentrenderables ) R_TimeRefresh_f For program optimization ==================== */ void R_TimeRefresh_f (void) { int i; float start, stop, time; CViewSetup view; materials->Flush( true ); Q_memset(&view, 0, sizeof(view)); view.origin = MainViewOrigin(); view.angles[0] = 0; view.angles[1] = 0; view.angles[2] = 0; view.x = 0; view.y = 0; view.width = videomode->GetModeWidth(); view.height = videomode->GetModeHeight(); view.fov = 75; view.fovViewmodel = 75; view.m_flAspectRatio = 1.0f; view.zNear = 4; view.zFar = MAX_COORD_FLOAT; view.zNearViewmodel = 4; view.zFarViewmodel = MAX_COORD_FLOAT; int savedeveloper = developer.GetInt(); developer.SetValue( 0 ); start = Sys_FloatTime (); for (i=0 ; i<128 ; i++) { view.angles[1] = i/128.0*360.0; g_ClientDLL->RenderView( view, VIEW_CLEAR_COLOR, RENDERVIEW_DRAWVIEWMODEL | RENDERVIEW_DRAWHUD ); Shader_SwapBuffers(); } materials->Flush( true ); Shader_SwapBuffers(); stop = Sys_FloatTime (); time = stop-start; developer.SetValue( savedeveloper ); ConMsg ("%f seconds (%f fps)\n", time, 128/time); } ConCommand timerefresh("timerefresh", R_TimeRefresh_f, "Profile the renderer.", FCVAR_CHEAT ); ConCommand linefile("linefile", Linefile_Read_f, "Parses map leak data from .lin file", FCVAR_CHEAT ); //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void R_Init (void) { extern byte *hunk_base; extern void InitMathlib( void ); InitMathlib(); UpdateMaterialSystemConfig(); #if defined( _PS3 ) g_pBuildIndicesJob->Init(); g_pBuildWorldListsJob->Init(); #endif } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void R_Shutdown( void ) { } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void R_ResetLightStyles( void ) { for ( int i=0 ; i<256 ; i++ ) { // normal light value d_lightstylevalue[i] = 264; d_lightstyleframe[i] = r_framecount; } } void R_RemoveAllDecalsFromAllModels(); //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- CON_COMMAND_F( r_cleardecals, "Usage r_cleardecals .", FCVAR_CLIENTCMD_CAN_EXECUTE ) { if ( host_state.worldmodel ) { bool bPermanent = false; if ( args.ArgC() == 2 ) { if ( !Q_stricmp( args[1], "permanent" ) ) { bPermanent = true; } } R_DecalTerm( host_state.worldmodel->brush.pShared, bPermanent, false ); } R_RemoveAllDecalsFromAllModels(); } //----------------------------------------------------------------------------- // Loads world geometry. Called when map changes or dx level changes //----------------------------------------------------------------------------- void R_LoadWorldGeometry( bool bDXChange ) { CUtlVector< uint32 > paintData; if ( g_PaintManager.m_bShouldRegister ) { g_PaintManager.GetPaintmapDataRLE( paintData ); } // Recreate the sortinfo arrays ( ack, uses new/delete right now ) because doing it with Hunk_AllocName will // leak through every connect that doesn't wipe the hunk ( "reconnect" ) MaterialSystem_DestroySortinfo(); //register paint maps MaterialSystem_RegisterPaintSurfaces(); MaterialSystem_RegisterLightmapSurfaces(); MaterialSystem_CreateSortinfo(); // UNDONE: This is a really crappy place to do this - shouldn't this stuff be in the modelloader? // If this is the first time we've tried to render this map, create a few one-time data structures // These all get cleared out if Map_UnloadModel is ever called by the modelloader interface ( and that happens // any time we free the Hunk down to the low mark since these things all use the Hunk for their data ). if ( !bDXChange ) { if ( !modelloader->Map_GetRenderInfoAllocated() ) { // create the displacement surfaces for the map modelloader->Map_LoadDisplacements( host_state.worldmodel, false ); //if( !DispInfo_CreateStaticBuffers( host_state.worldmodel, materialSortInfoArray, false ) ) // Sys_Error( "Can't create static meshes for displacements" ); modelloader->Map_SetRenderInfoAllocated( true ); } } else { // create the displacement surfaces for the map modelloader->Map_LoadDisplacements( host_state.worldmodel, true ); } if ( bDXChange ) { // Must be done before MarkWaterSurfaces modelloader->RecomputeSurfaceFlags( host_state.worldmodel ); } Mod_MarkWaterSurfaces( host_state.worldmodel ); // make sure and rebuild lightmaps when the level gets started. GL_RebuildLightmaps(); if ( bDXChange ) { R_BrushBatchInit(); R_DecalReSortMaterials(); OverlayMgr()->ReSortMaterials(); } if ( g_PaintManager.m_bShouldRegister ) { g_PaintManager.LoadPaintmapDataRLE( paintData ); paintData.Purge(); } } /* =============== R_LevelInit =============== */ void R_LevelInit( void ) { ConDMsg( "Initializing renderer...\n" ); COM_TimestampedLog( "R_LevelInit: Start" ); VPROF_BUDGET( "R_LevelInit", VPROF_BUDGETGROUP_OTHER_NETWORKING ); Assert( g_ClientDLL ); r_framecount = 1; R_ResetLightStyles(); R_DecalInit(); R_LoadSkys(); R_InitStudio(); // FIXME: Is this the best place to initialize the kd tree when we're client-only? if ( !sv.IsActive() ) { g_pShadowMgr->LevelShutdown(); StaticPropMgr()->LevelShutdown(); SpatialPartition()->Init( host_state.worldmodel->mins, host_state.worldmodel->maxs ); StaticPropMgr()->LevelInit(); g_pShadowMgr->LevelInit( host_state.worldbrush->numsurfaces ); } // We've fully loaded the new level, unload any models that we don't care about any more modelloader->UnloadUnreferencedModels(); // INFESTED_DLL - Alien Swarm doesn't want fullbright turned on when there are no lights (since it uses dynamic lights and skips vrad) static char gamedir[MAX_OSPATH]; Q_FileBase( com_gamedir, gamedir, sizeof( gamedir ) ); if ( host_state.worldmodel->brush.pShared->numworldlights == 0 && Q_stricmp( gamedir, "infested" ) ) { ConDMsg( "Level unlit, setting 'mat_fullbright 1'\n" ); mat_fullbright.SetValue( 1 ); } UpdateMaterialSystemConfig(); // FIXME: E3 2003 HACK if ( IsPC() && mat_levelflush.GetBool() ) { bool bOnLevelShutdown = false; materials->ResetTempHWMemory( bOnLevelShutdown ); } // precache any textures that are used in this map. // this is a no-op for textures that are already cached from the previous map. materials->CacheUsedMaterials(); // Loads the world geometry R_LoadWorldGeometry(); R_Surface_LevelInit(); R_Areaportal_LevelInit(); // Build the overlay fragments. OverlayMgr()->CreateFragments(); COM_TimestampedLog( "R_LevelInit: Finish" ); g_RendererInLevel = true; } void R_LevelShutdown() { R_Surface_LevelShutdown(); R_Areaportal_LevelShutdown(); g_DispLightmapSamplePositions.Purge(); g_RendererInLevel = false; }