/* ** Command & Conquer Renegade(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ /*********************************************************************************************** *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** *********************************************************************************************** * * * Project Name : WW3D * * * * $Archive:: /Commando/Code/ww3d2/ww3d.cpp $* * * * Author:: Greg_h * * * * $Modtime:: 2/14/02 3:00p $* * * * $Revision:: 97 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * WW3D::Init -- Initialize the WW3D Library * * WW3D::Shutdown -- shutdown the WW3D Library * * WW3D::Set_Render_Device -- set the render device being currently used * * WW3D::Set_Next_Render_Device -- just go to the next device in the list * * WW3D::Set_Device_Resolution -- set the current resolution and bitdepth * * WW3D::Get_Render_Device -- Get the index of the current render device * * WW3D::Get_Render_Device_Desc -- returns description of the current render device * * WW3D::Get_Render_Device_Count -- returns the number of render devices available * * WW3D::Get_Render_Device_Name -- returns the name of the n-th render device * * WW3D::Get_Render_Target_Resolution -- get the resolution and bitdepth of the current target* * WW3D::Get_Device_Resolution -- get the current resolution and bitdepth * * WW3D::Begin_Render -- mark the start of rendering for a new frame * * WW3D::Render -- Render a 3D Scene using the given camera * * WW3D::Render -- Render a single render object * * WW3D::End_Render -- Mark the completion of a frame * * WW3D::Sync -- Time sychronization * * WW3D::Set_Ext_Swap_Interval -- Sets the swap interval the device should aim sync for. * * WW3D::Get_Ext_Swap_Interval -- Queries the swap interval the device is aiming sync for. * * WW3D::Get_Polygon_Mode -- returns the current rendering mode * * WW3D::Set_Collision_Box_Display_Mask -- control rendering of collision boxes * * WW3D::Get_Collision_Box_Display_Mask -- returns the current display mask for collision bo * * WW3D::Normalize_Coordinates -- Convert pixel coords to normalized screen coords 0..1 * * WW3D::Update_Render_Device_Description -- updates the description of the current render d * * WW3D::Make_Screen_Shot -- saves a screenshot with the given base filename * * WW3D::Start_Movie_Capture -- begins dumping frames to a movie * * WW3D::Stop_Movie_Capture -- ends dumping frames to a movie * * WW3D::Toggle_Movie_Capture -- toggles movie capture... * * WW3D::Start_Single_Frame_Movie_Capture -- starts capturing a single frame movie * * WW3D::Capture_Next_Movie_Frame -- tells ww3d to grab another frame for the movie * * WW3D::Pause_Movie -- pauses/unpauses movie capturing * * WW3D::Is_Movie_Paused -- returns whether the movie capture system is paused * * WW3D::Is_Recording_Next_Frame -- returns whether the next frame will be dumped to a movie * * WW3D::Is_Movie_Ready -- returns whether the movie capture system is ready * * WW3D::Update_Movie_Capture -- dumps the current frame into the movie * * WW3D::Get_Movie_Capture_Frame_Rate -- returns the framerate at which the movie is being c * * WW3D::Set_Texture_Reduction -- sets the (hacky) texture reduction factor * * WW3D::Get_Texture_Reduction -- gets the (hacky) texture reduction factor * * WW3D::Flush_Texture_Cache -- dump all textures from the texture cache * * WW3D::Allocate_Debug_Resources -- allocates the debug resources * * WW3D::Release_Debug_Resources -- releases the debug resources * * WW3D::Get_Last_Frame_Poly_Count -- returns the number of polys submitted in the previous * * WW3D::Flush -- Process all pending rendering tasks * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "ww3d.h" #include "rinfo.h" #include "assetmgr.h" #include "boxrobj.h" #include "predlod.h" #include "camera.h" #include "scene.h" #include "texfcach.h" #include "registry.h" #include "segline.h" #include "shader.h" #include "vertmaterial.h" #include "wwdebug.h" #include "wwprofile.h" #include "wwmemlog.h" #include "shattersystem.h" #include "textureloader.h" #include "statistics.h" #include "pointgr.h" #include "ffactory.h" #include "ini.h" #include "dazzle.h" #include "meshmdl.h" #include "dx8renderer.h" #include "render2d.h" #include "bound.h" #include "rddesc.h" #include "vector3i.h" #include #include "dx8wrapper.h" #include "targa.h" #include "sortingrenderer.h" #include "thread.h" #include "cpudetect.h" #include "dx8texman.h" #include "formconv.h" #include "animatedsoundmgr.h" #ifndef _UNIX #include "framgrab.h" #endif const char* DAZZLE_INI_FILENAME="DAZZLE.INI"; #define DEFAULT_DEBUG_SHADER_BITS ( SHADE_CNST(\ ShaderClass::PASS_LEQUAL,\ ShaderClass::DEPTH_WRITE_ENABLE,\ ShaderClass::COLOR_WRITE_ENABLE,\ ShaderClass::SRCBLEND_ONE,\ ShaderClass::DSTBLEND_ZERO,\ ShaderClass::FOG_DISABLE,\ ShaderClass::GRADIENT_MODULATE,\ ShaderClass::SECONDARY_GRADIENT_DISABLE,\ ShaderClass::TEXTURING_DISABLE,\ ShaderClass::ALPHATEST_DISABLE,\ ShaderClass::CULL_MODE_ENABLE, \ ShaderClass::DETAILCOLOR_DISABLE,\ ShaderClass::DETAILALPHA_DISABLE) ) #define LIGHTMAP_DEBUG_SHADER_BITS ( SHADE_CNST(\ ShaderClass::PASS_LEQUAL,\ ShaderClass::DEPTH_WRITE_ENABLE,\ ShaderClass::COLOR_WRITE_ENABLE,\ ShaderClass::SRCBLEND_ONE,\ ShaderClass::DSTBLEND_ZERO,\ ShaderClass::FOG_DISABLE,\ ShaderClass::GRADIENT_DISABLE,\ ShaderClass::SECONDARY_GRADIENT_DISABLE,\ ShaderClass::TEXTURING_ENABLE,\ ShaderClass::ALPHATEST_DISABLE,\ ShaderClass::CULL_MODE_ENABLE, \ ShaderClass::DETAILCOLOR_DISABLE,\ ShaderClass::DETAILALPHA_DISABLE) ) /********************************************************************************** ** ** WW3D Static Globals ** ***********************************************************************************/ unsigned int WW3D::SyncTime = 0; unsigned int WW3D::PreviousSyncTime = 0; bool WW3D::IsSortingEnabled = true; float WW3D::PixelCenterX = 0.0f; float WW3D::PixelCenterY = 0.0f; bool WW3D::IsInitted = false; bool WW3D::IsRendering = false; bool WW3D::IsCapturing = false; bool WW3D::IsScreenUVBiased = false; bool WW3D::AreDecalsEnabled = true; float WW3D::DecalRejectionDistance = 1000000.0f; bool WW3D::AreStaticSortListsEnabled = false; bool WW3D::MungeSortOnLoad = false; FrameGrabClass * WW3D::Movie = NULL; bool WW3D::PauseRecord; bool WW3D::RecordNextFrame; int WW3D::FrameCount = 0; long WW3D::UserStat0 = 0; long WW3D::UserStat1 = 0; long WW3D::UserStat2 = 0; float WW3D::DefaultNativeScreenSize = 1.0f; RefRenderObjListClass * WW3D::DefaultStaticSortLists = NULL; RefRenderObjListClass * WW3D::CurrentStaticSortLists = NULL; unsigned int WW3D::MinStaticSortLevel = 1; // The 0 list is not used unsigned int WW3D::MaxStaticSortLevel = MAX_SORT_LEVEL; VertexMaterialClass * WW3D::DefaultDebugMaterial = NULL; ShaderClass WW3D::DefaultDebugShader(DEFAULT_DEBUG_SHADER_BITS); ShaderClass WW3D::LightmapDebugShader(LIGHTMAP_DEBUG_SHADER_BITS); WW3D::PrelitModeEnum WW3D::PrelitMode = PRELIT_MODE_LIGHTMAP_MULTI_PASS; bool WW3D::ExposePrelit = false; bool WW3D::SnapshotActivated=false; bool WW3D::ThumbnailEnabled=true; WW3D::MeshDrawModeEnum WW3D::MeshDrawMode = MESH_DRAW_MODE_OLD; WW3D::NPatchesGapFillingModeEnum WW3D::NPatchesGapFillingMode = NPATCHES_GAP_FILLING_ENABLED; unsigned WW3D::NPatchesLevel=1; bool WW3D::IsTexturingEnabled=true; static HWND _Hwnd = NULL; // Not a member to hide windows from WW3D users static int _TextureReduction = 0; int WW3D::LastFrameMemoryAllocations; int WW3D::LastFrameMemoryFrees; int WW3D::TextureFilter; bool WW3D::Lite = false; /********************************************************************************** ** ** WW3D Static Functions ** ***********************************************************************************/ void WW3D::Set_NPatches_Gap_Filling_Mode(NPatchesGapFillingModeEnum mode) { if (NPatchesGapFillingMode!=mode) { NPatchesGapFillingMode=mode; TheDX8MeshRenderer.Invalidate(); } } void WW3D::Set_NPatches_Level(unsigned level) { if (level>8) level=8; if (level<1) level=1; if (NPatchesLevel==1 && level>1) TheDX8MeshRenderer.Invalidate(); if (NPatchesLevel>1 && level==1) TheDX8MeshRenderer.Invalidate(); NPatchesLevel = level; } /*********************************************************************************************** * WW3D::Init -- Initialize the WW3D Library * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 3/24/98 GTH : Created. * *=============================================================================================*/ WW3DErrorType WW3D::Init(void *hwnd, char *defaultpal, bool lite) { assert(IsInitted == false); WWDEBUG_SAY(("WW3D::Init hwnd = %p\n",hwnd)); _Hwnd = (HWND)hwnd; Lite = lite; /* ** Initialize d3d, this also enumerates the available devices and resolutions. */ Init_D3D_To_WW3_Conversion(); WWDEBUG_SAY(("Init DX8Wrapper\n")); if (!DX8Wrapper::Init(_Hwnd, lite)) { return(WW3D_ERROR_DIRECTX8_INITIALIZATION_FAILED); } WWDEBUG_SAY(("Allocate Debug Resources\n")); Allocate_Debug_Resources(); MMRESULT r=timeBeginPeriod(1); WWASSERT(r==TIMERR_NOERROR); /* ** Initialize the dazzle system */ if (!lite) { WWDEBUG_SAY(("Init Dazzles\n")); FileClass * dazzle_ini_file = _TheFileFactory->Get_File(DAZZLE_INI_FILENAME); if (dazzle_ini_file) { INIClass dazzle_ini(*dazzle_ini_file); DazzleRenderObjClass::Init_From_INI(&dazzle_ini); _TheFileFactory->Return_File(dazzle_ini_file); } } /* ** Initialize the default static sort lists ** Note that DefaultStaticSortLists[0] is unused. */ DefaultStaticSortLists = new RefRenderObjListClass[MAX_SORT_LEVEL + 1]; Reset_Current_Static_Sort_Lists_To_Default(); /* ** Initialize the animation-triggered sound system */ if (!lite) { AnimatedSoundMgrClass::Initialize (); IsInitted = true; } WWDEBUG_SAY(("WW3D Init completed\n")); return WW3D_ERROR_OK; } /*********************************************************************************************** * WW3D::Shutdown -- shutdown the WW3D Library * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 3/24/98 GTH : Created. * *=============================================================================================*/ WW3DErrorType WW3D::Shutdown(void) { assert(Lite || IsInitted == true); // WWDEBUG_SAY(("WW3D::Shutdown\n")); #ifdef WW3D_DX8 if (IsCapturing) { Stop_Movie_Capture(); } #endif //WW3D_DX8 /* ** Free memory in predictive LOD optimizer */ PredictiveLODOptimizerClass::Free(); /* ** Free the DazzleRenderObject class stuff. Whatever it is. ST - 6/11/2001 8:20PM */ if (!Lite) { DazzleRenderObjClass::Deinit (); } /* ** Release all of our assets */ Release_Debug_Resources(); if (WW3DAssetManager::Get_Instance()) { WW3DAssetManager::Get_Instance()->Free_Assets(); } DX8TextureManagerClass::Shutdown(); if (!Lite) { DX8Wrapper::Shutdown(); } /* ** Clear the default static sort lists */ delete [] DefaultStaticSortLists; /* ** Release the animation-triggered sound data */ AnimatedSoundMgrClass::Shutdown (); IsInitted = false; return WW3D_ERROR_OK; } /*********************************************************************************************** * WW3D::Set_Render_Device -- set the render device being currently used * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 3/24/98 GTH : Created. * *=============================================================================================*/ WW3DErrorType WW3D::Set_Render_Device( const char * dev_name, int width, int height, int bits, int windowed, bool resize_window ) { bool success = DX8Wrapper::Set_Render_Device(dev_name,width,height,bits,windowed,resize_window); if (success) { return WW3D_ERROR_OK; } else { return WW3D_ERROR_INITIALIZATION_FAILED; } } /*********************************************************************************************** * WW3D::Set_Any_Render_Device -- set any render device you can find * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 3/24/98 GTH : Created. * *=============================================================================================*/ WW3DErrorType WW3D::Set_Any_Render_Device( void ) { bool success = DX8Wrapper::Set_Any_Render_Device(); if (success) { return WW3D_ERROR_OK; } else { return WW3D_ERROR_INITIALIZATION_FAILED; } } /*********************************************************************************************** * WW3D::Set_Render_Device -- set the render device being currently used * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 3/24/98 GTH : Created. * *=============================================================================================*/ WW3DErrorType WW3D::Set_Render_Device(int dev, int width, int height, int bits, int windowed, bool resize_window) { bool success = DX8Wrapper::Set_Render_Device(dev,width,height,bits,windowed,resize_window); if (success) { return WW3D_ERROR_OK; } else { return WW3D_ERROR_INITIALIZATION_FAILED; } } /*********************************************************************************************** * WW3D::Set_Next_Render_Device -- just go to the next device in the list * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 3/26/98 GTH : Created. * *=============================================================================================*/ WW3DErrorType WW3D::Set_Next_Render_Device(void) { bool success = DX8Wrapper::Set_Next_Render_Device(); if (success) { return WW3D_ERROR_OK; } else { return WW3D_ERROR_INITIALIZATION_FAILED; } } /*********************************************************************************************** * WW3D::Get_Window -- returns the handle of the render window. * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 3/28/2001 pds : Created. * *=============================================================================================*/ void *WW3D::Get_Window( void ) { return _Hwnd; } /*********************************************************************************************** * WW3D::Is_Windowed -- returns wether we are currently in a windowed mode * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 1/26/2001 gth : Created. * *=============================================================================================*/ bool WW3D::Is_Windowed( void ) { return DX8Wrapper::Is_Windowed(); } /*********************************************************************************************** * WW3D::Toggle_Windowed -- Toggle the current render device between fullscreen and windowed * * mode. Note: Its called '_Windowed' to be consistent with the * * other references inside WW3D, a more descriptive name would * * be Toggle_Fullscreen. * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 1/11/99 PDS : Created. * *=============================================================================================*/ WW3DErrorType WW3D::Toggle_Windowed (void) { bool success = DX8Wrapper::Toggle_Windowed(); if (success) { return WW3D_ERROR_OK; } else { return WW3D_ERROR_INITIALIZATION_FAILED; } } /*********************************************************************************************** * WW3D::Get_Render_Device -- Get the index of the current render device * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 3/24/98 GTH : Created. * * 1/25/2001 gth : converted to dx8 * *=============================================================================================*/ int WW3D::Get_Render_Device(void) { return DX8Wrapper::Get_Render_Device(); } /*********************************************************************************************** * WW3D::Get_Render_Device_Desc -- returns description of the current render device * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 3/26/98 GTH : Created. * * 1/25/2001 gth : converted to dx8 * *=============================================================================================*/ const RenderDeviceDescClass & WW3D::Get_Render_Device_Desc(int deviceidx) { return DX8Wrapper::Get_Render_Device_Desc(deviceidx); } /*********************************************************************************************** * WW3D::Get_Render_Device_Count -- returns the number of render devices available * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 5/19/99 GTH : Created. * * 1/25/2001 gth : converted to DX8 * *=============================================================================================*/ const int WW3D::Get_Render_Device_Count(void) { return DX8Wrapper::Get_Render_Device_Count(); } /*********************************************************************************************** * WW3D::Get_Render_Device_Name -- returns the name of the n-th render device * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 5/19/99 GTH : Created. * * 1/25/2001 gth : converted to dx8 * *=============================================================================================*/ const char * WW3D::Get_Render_Device_Name(int device_index) { return DX8Wrapper::Get_Render_Device_Name(device_index); } /*********************************************************************************************** * WW3D::Set_Device_Resolution -- set the current resolution and bitdepth * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 3/24/98 GTH : Created. * *=============================================================================================*/ WW3DErrorType WW3D::Set_Device_Resolution(int width,int height,int bits,int windowed, bool resize_window) { bool success = DX8Wrapper::Set_Device_Resolution(width,height,bits,windowed,resize_window); if (success) { return WW3D_ERROR_OK; } else { return WW3D_ERROR_INITIALIZATION_FAILED; } } /*********************************************************************************************** * WW3D::Get_Render_Target_Resolution -- get the resolution and bitdepth of the current target * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 3/24/98 GTH : Created. * * 1/25/2001 gth : converted to dx8 * *=============================================================================================*/ void WW3D::Get_Render_Target_Resolution(int & set_w,int & set_h,int & set_bits,bool & set_windowed) { DX8Wrapper::Get_Render_Target_Resolution(set_w,set_h,set_bits,set_windowed); } /*********************************************************************************************** * WW3D::Get_Device_Resolution -- get the current resolution and bitdepth * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 3/24/98 GTH : Created. * * 1/25/2001 gth : converted to dx8 * *=============================================================================================*/ void WW3D::Get_Device_Resolution(int & set_w,int & set_h,int & set_bits,bool & set_windowed) { DX8Wrapper::Get_Device_Resolution(set_w,set_h,set_bits,set_windowed); } /*********************************************************************************************** * WW3D::Registry_Save_Render_Device -- Saves settings to Registry * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 12/3/98 BMG : Created. * * 1/25/2001 gth : converted to dx8 * *=============================================================================================*/ WW3DErrorType WW3D::Registry_Save_Render_Device( const char * sub_key ) { bool success = DX8Wrapper::Registry_Save_Render_Device(sub_key); if (success) { return WW3D_ERROR_OK; } else { return WW3D_ERROR_INITIALIZATION_FAILED; } } /*********************************************************************************************** * WW3D::Registry_Save_Render_Device -- Saves settings to Registry * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 12/3/98 BMG : Created. * *=============================================================================================*/ WW3DErrorType WW3D::Registry_Save_Render_Device( const char *sub_key, int device, int width, int height, int depth, bool windowed, int texture_depth ) { bool success = DX8Wrapper::Registry_Save_Render_Device(sub_key,device,width,height,depth,windowed,texture_depth); if (success) { return WW3D_ERROR_OK; } else { return WW3D_ERROR_INITIALIZATION_FAILED; } } /*********************************************************************************************** * WW3D::Registry_Load_Render_Device -- Loads settings from Registry * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 12/3/98 BMG : Created. * *=============================================================================================*/ WW3DErrorType WW3D::Registry_Load_Render_Device( const char * sub_key, bool resize_window ) { bool success = DX8Wrapper::Registry_Load_Render_Device(sub_key,resize_window); if (success) { return WW3D_ERROR_OK; } else { return WW3D_ERROR_INITIALIZATION_FAILED; } } bool WW3D::Registry_Load_Render_Device( const char * sub_key, char *device, int device_len, int &width, int &height, int &depth, int &windowed, int &texture_depth) { return DX8Wrapper::Registry_Load_Render_Device(sub_key,device,device_len,width,height,depth,windowed,texture_depth); } void WW3D::_Invalidate_Mesh_Cache() { TheDX8MeshRenderer.Invalidate(); } void WW3D::_Invalidate_Textures() { if (!WW3DAssetManager::Get_Instance()) return; TextureLoader::Flush_Pending_Load_Tasks(); HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash()); // Loop through all the textures in the manager for (ite.First();!ite.Is_Done();ite.Next()) { // Get the current texture TextureClass* tex=ite.Peek_Value(); tex->Invalidate(); } } void WW3D::Set_Texture_Filter(int texture_filter) { if (texture_filter<0) texture_filter=0; if (texture_filter>TextureClass::TEXTURE_FILTER_ANISOTROPIC) texture_filter=TextureClass::TEXTURE_FILTER_ANISOTROPIC; TextureFilter=texture_filter; TextureClass::_Init_Filters((TextureClass::TextureFilterMode)TextureFilter); } /*********************************************************************************************** * WW3D::Begin_Render -- mark the start of rendering for a new frame * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 3/24/98 GTH : Created. * *=============================================================================================*/ WW3DErrorType WW3D::Begin_Render(bool clear,bool clearz,const Vector3 & color, void(*network_callback)(void)) { if (!IsInitted) { return(WW3D_ERROR_OK); } WWPROFILE("WW3D::Begin_Render"); WWASSERT(IsInitted); // Memory allocation statistics LastFrameMemoryAllocations=WWMemoryLogClass::Get_Allocate_Count(); LastFrameMemoryFrees=WWMemoryLogClass::Get_Free_Count(); WWMemoryLogClass::Reset_Counters(); TextureLoader::Update(network_callback); // TextureClass::_Reset_Time_Stamp(); DynamicVBAccessClass::_Reset(true); DynamicIBAccessClass::_Reset(true); #ifdef WW3D_DX8 TextureFileClass::Update_Texture_Flash(); #endif //WW3D_DX8 Debug_Statistics::Begin_Statistics(); if (IsCapturing && (!PauseRecord || RecordNextFrame)) { Update_Movie_Capture(); RecordNextFrame = false; } WWASSERT(!IsRendering); IsRendering = true; // If we want to clear the screen, we need to set the viewport to include the entire screen: if (clear || clearz) { D3DVIEWPORT8 vp; int width, height, bits; bool windowed; WW3D::Get_Render_Target_Resolution(width, height, bits, windowed); vp.X = 0; vp.Y = 0; vp.Width = width; vp.Height = height; vp.MinZ = 0.0f;; vp.MaxZ = 1.0f; DX8Wrapper::Set_Viewport(&vp); DX8Wrapper::Clear(clear, clearz, color); } // Notify D3D that we are beginning to render the frame DX8Wrapper::Begin_Scene(); return WW3D_ERROR_OK; } /*********************************************************************************************** * WW3D::Render -- Render a list of layers, starting at the back. * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 4/2/98 EHC : Created. * *=============================================================================================*/ WW3DErrorType WW3D::Render(const LayerListClass &LayerList) { if (!IsInitted) { return(WW3D_ERROR_OK); } WWASSERT(IsRendering); LayerClass *layer = LayerList.Last(); while (layer->Is_Valid()) { WW3DErrorType result = Render(*layer); if (result != WW3D_ERROR_OK) { return result; } layer = layer->Prev(); } return WW3D_ERROR_OK; } /*********************************************************************************************** * WW3D::Render -- Render a Layer * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 4/2/98 EHC : Created. * *=============================================================================================*/ WW3DErrorType WW3D::Render(const LayerClass &Layer) { if (!IsInitted) { return(WW3D_ERROR_OK); } WWASSERT(IsRendering); return Render(Layer.Scene, Layer.Camera, Layer.Clear, Layer.ClearZ, Layer.ClearColor); } /*********************************************************************************************** * WW3D::Render -- Render a 3D Scene using the given camera * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 3/24/98 GTH : Created. * *=============================================================================================*/ WW3DErrorType WW3D::Render(SceneClass * scene,CameraClass * cam,bool clear,bool clearz,const Vector3 & color) { if (!IsInitted) { return(WW3D_ERROR_OK); } WWPROFILE("WW3D::Render"); WWMEMLOG(MEM_GAMEDATA); WWASSERT(IsInitted); WWASSERT(IsRendering); WWASSERT(scene); WWASSERT(cam); cam->On_Frame_Update(); RenderInfoClass rinfo(*cam); // Apply the camera and viewport (including depth range) cam->Apply(); // Clear the viewport if (clear || clearz) { DX8Wrapper::Clear(clear, clearz, color); } // set the rendering mode switch(scene->Get_Polygon_Mode()) { case SceneClass::POINT: DX8Wrapper::Set_DX8_Render_State(D3DRS_FILLMODE,D3DFILL_POINT); break; case SceneClass::LINE: DX8Wrapper::Set_DX8_Render_State(D3DRS_FILLMODE,D3DFILL_WIREFRAME); break; case SceneClass::FILL: DX8Wrapper::Set_DX8_Render_State(D3DRS_FILLMODE,D3DFILL_SOLID); break; } // Set the global ambient light value here. If the scene is using the LightEnvironment system // this setting will get overriden. Vector3 ambient = scene->Get_Ambient_Light(); DX8Wrapper::Set_DX8_Render_State(D3DRS_AMBIENT, DX8Wrapper::Convert_Color(ambient,0.0f)); // render the scene TheDX8MeshRenderer.Set_Camera(&rinfo.Camera); scene->Render(rinfo); Flush(rinfo); return WW3D_ERROR_OK; } /*********************************************************************************************** * WW3D::Render -- Render a single render object * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 4/4/2001 gth : Created. * *=============================================================================================*/ WW3DErrorType WW3D::Render( RenderObjClass & obj, RenderInfoClass & rinfo ) { if (!IsInitted) { return(WW3D_ERROR_OK); } WWPROFILE("WW3D::Render"); WWASSERT(IsInitted); WWASSERT(IsRendering); { WWPROFILE("On_Frame_Update"); rinfo.Camera.On_Frame_Update(); } // Apply the camera and viewport (including depth range) rinfo.Camera.Apply(); // set the rendering mode DX8Wrapper::Set_DX8_Render_State(D3DRS_FILLMODE,D3DFILL_SOLID); // Install the lighting environment if one is supplied if (rinfo.light_environment != NULL) { DX8Wrapper::Set_Light_Environment(rinfo.light_environment); } // Render the object TheDX8MeshRenderer.Set_Camera(&rinfo.Camera); obj.Render(rinfo); Flush(rinfo); return WW3D_ERROR_OK; } /*********************************************************************************************** * WW3D::Flush -- Process all pending rendering tasks * * * * NOTE: This normally happens AUTOMATICALLY. The user should almost *NEVER* have to call * * this function. Anyway, this function causes all of the deferred rendering systems to * * actually perform all of their rendering tasks. This includes the DX8MeshRenderer and * * the sorting system. * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * Don't call this unless you know what you're doing * * * * HISTORY: * * 4/17/2001 gth : Created. * *=============================================================================================*/ void WW3D::Flush(RenderInfoClass & rinfo) { TheDX8MeshRenderer.Flush(); WW3D::Render_And_Clear_Static_Sort_Lists(rinfo); SortingRendererClass::Flush(); TheDX8MeshRenderer.Clear_Pending_Delete_Lists(); } /*********************************************************************************************** * WW3D::End_Render -- Mark the completion of a frame * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 3/24/98 GTH : Created. * *=============================================================================================*/ WW3DErrorType WW3D::End_Render(bool flip_frame) { if (!IsInitted) { return(WW3D_ERROR_OK); } WWPROFILE("WW3D::End_Render"); assert(IsRendering); assert(IsInitted); // If sorting renderer flush isn't called from within any of the render functions // the sorting arrays will overflow! SortingRendererClass::Flush(); IsRendering = false; { WWPROFILE("DX8Wrapper::End_Scene"); DX8Wrapper::End_Scene(flip_frame); } FrameCount++; { WWPROFILE("End_Statistics"); Debug_Statistics::End_Statistics(); } Activate_Snapshot(false); return WW3D_ERROR_OK; } /*********************************************************************************************** * WW3D::Flip_To_Primary * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 6/20/01 DEL : Created. * *=============================================================================================*/ void WW3D::Flip_To_Primary(void) { DX8Wrapper::Flip_To_Primary(); } /*********************************************************************************************** * WW3D::Get_Last_Frame_Poly_Count -- returns the number of polys submitted in the previous fr * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 7/28/99 GTH : Created. * *=============================================================================================*/ unsigned int WW3D::Get_Last_Frame_Poly_Count(void) { return Debug_Statistics::Get_DX8_Polygons(); } unsigned int WW3D::Get_Last_Frame_Vertex_Count(void) { return Debug_Statistics::Get_DX8_Vertices(); } /*********************************************************************************************** * WW3D::Sync -- Time sychronization * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 3/24/98 GTH : Created. * *=============================================================================================*/ void WW3D::Sync(unsigned int sync_time) { PreviousSyncTime = SyncTime; SyncTime = sync_time; } /*********************************************************************************************** * WW3D::Set_Ext_Swap_Interval -- Sets the swap interval the device should aim sync for. * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: Not supported by all rendering devices. * * * * HISTORY: * * 5/07/98 NH : Created. * *=============================================================================================*/ void WW3D::Set_Ext_Swap_Interval(long swap) { DX8Wrapper::Set_Swap_Interval(swap); } /*********************************************************************************************** * WW3D::Get_Ext_Swap_Interval -- Queries the swap interval the device is aiming sync for. * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: Not supported by all rendering devices. * * * * HISTORY: * * 5/07/98 NH : Created. * *=============================================================================================*/ long WW3D::Get_Ext_Swap_Interval(void) { return DX8Wrapper::Get_Swap_Interval(); } /*********************************************************************************************** * WW3D::Set_Collision_Box_Display_Mask -- control rendering of collision boxes * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 3/17/99 GTH : Created. * *=============================================================================================*/ void WW3D::Set_Collision_Box_Display_Mask(int mask) { BoxRenderObjClass::Set_Box_Display_Mask(mask); } /*********************************************************************************************** * WW3D::Get_Collision_Box_Display_Mask -- returns the current display mask for collision boxe * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 6/1/99 GTH : Created. * *=============================================================================================*/ int WW3D::Get_Collision_Box_Display_Mask(void) { return BoxRenderObjClass::Get_Box_Display_Mask(); } /*********************************************************************************************** * WW3D::Normalize_Coordinates -- Convert pixel coords to normalized screen coords 0..1 * * * * * * * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 7/27/99 EHC : Created. * *=============================================================================================*/ void WW3D::Normalize_Coordinates(int x, int y, float &fx, float &fy) { // clip the coordinates back into the resolution of the screen x = Bound(x, 0, DX8Wrapper::Get_Device_Resolution_Width()); y = Bound(y, 0, DX8Wrapper::Get_Device_Resolution_Height()); // now that the coordinates are clipped convert them to their normalized values. fx = (float)x / DX8Wrapper::Get_Device_Resolution_Width(); fy = (float)y / DX8Wrapper::Get_Device_Resolution_Height(); } /*********************************************************************************************** * WW3D::Make_Screen_Shot -- saves a screenshot with the given base filename * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 5/19/99 GTH : Created. * * 2/26/2001 hy : Updated to DX8 * *=============================================================================================*/ void WW3D::Make_Screen_Shot( const char * filename_base ) { WWASSERT(!IsRendering); char filename[80]; static int frame_number = 1; bool done = false; while (!done) { sprintf( filename, "%s%.2d.tga", filename_base, frame_number++); FileClass*file=_TheFileFactory->Get_File( filename ); if ( file ) { file->Open(); done = !file->Is_Available(); _TheFileFactory->Return_File( file ); } else { done = true; } } WWDEBUG_SAY(( "Creating Screen Shot %s\n", filename )); // Lock front buffer and copy IDirect3DSurface8 *fb; fb=DX8Wrapper::_Get_DX8_Front_Buffer(); D3DSURFACE_DESC desc; fb->GetDesc(&desc); RECT bounds; GetWindowRect(_Hwnd,&bounds); D3DLOCKED_RECT lrect; DX8_ErrorCode(fb->LockRect(&lrect,&bounds,D3DLOCK_READONLY)); unsigned int x,y,index,index2,width,height; width=bounds.right-bounds.left; height=bounds.bottom-bounds.top; char *image=new char[3*width*height]; for (y=0; yRelease(); Targa targ; memset(&targ.Header,0,sizeof(targ.Header)); targ.Header.Width=width; targ.Header.Height=height; targ.Header.PixelDepth=24; targ.Header.ImageType=TGA_TRUECOLOR; targ.SetImage(image); targ.YFlip(); FileClass*file=_TheWritingFileFactory->Get_File( filename ); if ( file ) { file->Create(); file->Close(); _TheWritingFileFactory->Return_File( file ); } targ.Save(filename,TGAF_IMAGE,false); delete [] image; } /*********************************************************************************************** * WW3D::Start_Movie_Capture -- begins dumping frames to a movie * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 5/19/99 GTH : Created. * * 2/26/2001 hy : updated to dx8 * *=============================================================================================*/ void WW3D::Start_Movie_Capture( const char * filename_base, float frame_rate ) { #ifdef _WINDOWS if (IsCapturing) { Stop_Movie_Capture(); } WWASSERT( !IsCapturing); IsCapturing = true; RECT bounds; GetWindowRect(_Hwnd,&bounds); int height=bounds.bottom-bounds.top; int width=bounds.right-bounds.left; int depth=24; WWASSERT( Movie == NULL); if (frame_rate == 0.0f) { frame_rate = 1.0f; PauseRecord = true; } else { PauseRecord = false; } Movie = new FrameGrabClass( filename_base, FrameGrabClass::AVI, width, height, depth, frame_rate); WWDEBUG_SAY(( "Starting Movie %s\n", filename_base )); #endif } /*********************************************************************************************** * WW3D::Stop_Movie_Capture -- ends dumping frames to a movie * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 5/19/99 GTH : Created. * *=============================================================================================*/ void WW3D::Stop_Movie_Capture( void ) { #ifdef _WINDOWS if (IsCapturing) { IsCapturing = false; WWDEBUG_SAY(( "Stoping Movie\n" )); WWASSERT( Movie != NULL); delete Movie; Movie = NULL; } #endif } /*********************************************************************************************** * WW3D::Toggle_Movie_Capture -- toggles movie capture... * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 5/19/99 GTH : Created. * *=============================================================================================*/ void WW3D::Toggle_Movie_Capture( const char * filename_base, float frame_rate ) { if (IsCapturing) { Stop_Movie_Capture(); } else { Start_Movie_Capture( filename_base, frame_rate); } } /*********************************************************************************************** * WW3D::Start_Single_Frame_Movie_Capture -- starts capturing a single frame movie * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 5/19/99 GTH : Created. * *=============================================================================================*/ void WW3D::Start_Single_Frame_Movie_Capture(const char *filename_base) { Start_Movie_Capture(filename_base, 0.0f); } /*********************************************************************************************** * WW3D::Capture_Next_Movie_Frame -- tells ww3d to grab another frame for the movie * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 5/19/99 GTH : Created. * *=============================================================================================*/ void WW3D::Capture_Next_Movie_Frame() { RecordNextFrame = true; } /*********************************************************************************************** * WW3D::Pause_Movie -- pauses/unpauses movie capturing * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 5/19/99 GTH : Created. * *=============================================================================================*/ void WW3D::Pause_Movie(bool mode) { PauseRecord = mode; } /*********************************************************************************************** * WW3D::Is_Movie_Paused -- returns whether the movie capture system is paused * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 5/19/99 GTH : Created. * *=============================================================================================*/ bool WW3D::Is_Movie_Paused() { return PauseRecord; } /*********************************************************************************************** * WW3D::Is_Recording_Next_Frame -- returns whether the next frame will be dumped to a movie * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 5/19/99 GTH : Created. * *=============================================================================================*/ bool WW3D::Is_Recording_Next_Frame() { return (Movie != 0) && (!PauseRecord || RecordNextFrame); } /*********************************************************************************************** * WW3D::Is_Movie_Ready -- returns whether the movie capture system is ready * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 5/19/99 GTH : Created. * *=============================================================================================*/ bool WW3D::Is_Movie_Ready() { return Movie != 0; } /*********************************************************************************************** * WW3D::Update_Movie_Capture -- dumps the current frame into the movie * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 5/19/99 GTH : Created. * * 2/26/2001 hy : Updated to dx8 * *=============================================================================================*/ void WW3D::Update_Movie_Capture( void ) { #ifdef _WINDOWS WWASSERT( IsCapturing); WWPROFILE("WW3D::Update_Movie_Capture"); WWDEBUG_SAY(( "Updating\n")); // Lock front buffer and copy IDirect3DSurface8 *fb; fb=DX8Wrapper::_Get_DX8_Front_Buffer(); D3DSURFACE_DESC desc; fb->GetDesc(&desc); RECT bounds; GetWindowRect(_Hwnd,&bounds); D3DLOCKED_RECT lrect; DX8_ErrorCode(fb->LockRect(&lrect,&bounds,D3DLOCK_READONLY)); unsigned int x,y,index,index2,width,height; width=bounds.right-bounds.left; height=bounds.bottom-bounds.top; char *image=(char *)Movie->GetBuffer(); for (y=0; yRelease(); Movie->Grab(image); #endif } /*********************************************************************************************** * WW3D::Get_Movie_Capture_Frame_Rate -- returns the framerate at which the movie is being cap * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 5/19/99 GTH : Created. * *=============================================================================================*/ float WW3D::Get_Movie_Capture_Frame_Rate( void ) { #ifdef _WINDOWS if (IsCapturing) { return Movie->GetFrameRate(); } #endif return 0; } /*********************************************************************************************** * WW3D::Set_Texture_Reduction -- sets the (hacky) texture reduction factor * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 5/19/99 GTH : Created. * *=============================================================================================*/ void WW3D::Set_Texture_Reduction( int value ) { if (_TextureReduction != value) { _TextureReduction=value; _Invalidate_Textures(); } } void WW3D::Enable_Texturing(bool b) { if (b==IsTexturingEnabled) return; IsTexturingEnabled=b; // _Invalidate_Textures(); } /*********************************************************************************************** * WW3D::Get_Texture_Reduction -- gets the (hacky) texture reduction factor * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 11/25/99 TSS : Created. * *=============================================================================================*/ int WW3D::Get_Texture_Reduction( void ) { return _TextureReduction; } /*********************************************************************************************** * WW3D::Peek_Default_Debug_Material -- returns a pointer to the default debug mtl * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 7/21/99 GTH : Created. * *=============================================================================================*/ VertexMaterialClass * WW3D::Peek_Default_Debug_Material(void) { #ifdef WWDEBUG WWASSERT(DefaultDebugMaterial); return DefaultDebugMaterial; #else return NULL; #endif } /*********************************************************************************************** * WW3D::Peek_Default_Debug_Shader -- returns the default shader for debugging. * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 7/21/99 GTH : Created. * *=============================================================================================*/ ShaderClass WW3D::Peek_Default_Debug_Shader(void) { return DefaultDebugShader; } /*********************************************************************************************** * WW3D::Peek_Lightmap_Debug_Shader -- returns the shader for lightmap debugging. * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 7/21/99 GTH : Created. * *=============================================================================================*/ ShaderClass WW3D::Peek_Lightmap_Debug_Shader(void) { return LightmapDebugShader; } /*********************************************************************************************** * WW3D::Allocate_Debug_Resources -- allocates the debug resources * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 7/21/99 GTH : Created. * *=============================================================================================*/ void WW3D::Allocate_Debug_Resources(void) { #ifdef WWDEBUG WWASSERT(DefaultDebugMaterial == NULL); DefaultDebugMaterial = new VertexMaterialClass; DefaultDebugMaterial->Set_Shininess(0.0f); DefaultDebugMaterial->Set_Opacity(1.0f); DefaultDebugMaterial->Set_Ambient(0,0,0); DefaultDebugMaterial->Set_Diffuse(0,0,0); DefaultDebugMaterial->Set_Specular(0,0,0); DefaultDebugMaterial->Set_Emissive(0,0,0); #endif } /*********************************************************************************************** * WW3D::Release_Debug_Resources -- releases the debug resources * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 7/21/99 GTH : Created. * *=============================================================================================*/ void WW3D::Release_Debug_Resources(void) { #ifdef WWDEBUG WWASSERT(DefaultDebugMaterial); REF_PTR_RELEASE(DefaultDebugMaterial); #endif } WW3DErrorType WW3D::On_Deactivate_App(void) { #ifdef WW3D_DX8 assert(!IsRendering); if ( Gerd == NULL ) return WW3D_ERROR_OK; if ( IsWindowed ) return WW3D_ERROR_OK; if ( !Gerd->isWindowOpen() ) return WW3D_ERROR_OK; Gerd->closeWindow(); #endif //WW3D_DX8 return WW3D_ERROR_OK; } WW3DErrorType WW3D::On_Activate_App(void) { #ifdef WW3D_DX8 if ( Gerd == NULL) return WW3D_ERROR_OK; if ( IsWindowed ) return WW3D_ERROR_OK; assert( !Gerd->isWindowOpen() ); srGERD::DisplayMode disp_mode; disp_mode = Gerd->getDisplayMode(ResolutionWidth,ResolutionHeight,BitDepth); if (Gerd->openWindow(disp_mode) != srGERD::ERROR_NONE) { return WW3D_ERROR_WINDOW_NOT_OPEN; } #endif //WW3D_DX8 return WW3D_ERROR_OK; } void WW3D::Get_Pixel_Center(float &x, float &y) { x = PixelCenterX; y = PixelCenterY; } void WW3D::Update_Pixel_Center(void) { #ifdef WW3D_DX8 const char *name = _RenderDeviceShortNameTable.getString(CurRenderDevice); if ( strstr(name, "OpenGL") ) { PixelCenterX = 0.0f; PixelCenterY = 0.0f; } else if ( strstr(name, "Glide") ) { PixelCenterX = 0.0f; PixelCenterY = 0.0f; } else if ( strstr(name, "DirectX") ) { PixelCenterX = 0.5f; PixelCenterY = 0.5f; } else if ( strstr(name, "Software") ) { PixelCenterX = 0.0f; PixelCenterY = 0.0f; } else if ( strstr(name, "Null") ) { PixelCenterX = 0.0f; PixelCenterY = 0.0f; } else { // unknown device PixelCenterX = 0.0f; PixelCenterY = 0.0f; } #endif //WW3D_DX8 } void WW3D::Set_Texture_Bitdepth(int bitdepth) { DX8Wrapper::Set_Texture_Bitdepth(bitdepth); } int WW3D::Get_Texture_Bitdepth() { return DX8Wrapper::Get_Texture_Bitdepth(); } void WW3D::Add_To_Static_Sort_List(RenderObjClass *robj, unsigned int sort_level) { if(sort_level < 1 || sort_level > MAX_SORT_LEVEL) { WWASSERT(0); return; } CurrentStaticSortLists[sort_level].Add_Tail(robj, false); } void WW3D::Render_And_Clear_Static_Sort_Lists(RenderInfoClass & rinfo) { // The ststic sort lists need to be disabled while we are rendering from them otherwise the // Render() function will just dump the objects right back on the same lists. bool old_enable = AreStaticSortListsEnabled; AreStaticSortListsEnabled = false; // We go from higher sort level to lower, since lower sort level means higher priority (in // front), so lower sort level meshes need to be rendered later. for(unsigned int sort_level = MaxStaticSortLevel; sort_level >= MinStaticSortLevel; sort_level--) { bool render=false; for ( RenderObjClass *robj = CurrentStaticSortLists[sort_level].Remove_Head(); robj; robj->Release_Ref(), robj = CurrentStaticSortLists[sort_level].Remove_Head()) { robj->Render(rinfo); render=true; } if (render) TheDX8MeshRenderer.Flush(); } AreStaticSortListsEnabled = old_enable; } void WW3D::Enable_Sorting(bool onoff) { IsSortingEnabled = onoff; // Have to invalidate mesh rendering system because // meshes are put into different fvfs depending on their sort state TheDX8MeshRenderer.Invalidate(); } void WW3D::Override_Current_Static_Sort_Lists(RefRenderObjListClass *sort_list, unsigned int min_sort, unsigned int max_sort) { CurrentStaticSortLists = sort_list; if (min_sort <= max_sort) { MinStaticSortLevel = min_sort; MaxStaticSortLevel = max_sort; } else { WWASSERT(0); MinStaticSortLevel = max_sort; MaxStaticSortLevel = min_sort; } } void WW3D::Reset_Current_Static_Sort_Lists_To_Default(void) { CurrentStaticSortLists = DefaultStaticSortLists; MinStaticSortLevel = 1; // The 0 list is not used MaxStaticSortLevel = MAX_SORT_LEVEL; }