diff --git a/.gitignore b/.gitignore index e5e550b48d..814dcc1b7f 100644 --- a/.gitignore +++ b/.gitignore @@ -55,4 +55,7 @@ cmake-build-*/ ## Ninja .ninja_deps .ninja_log -build.ninja \ No newline at end of file +build.ninja + +out/build/x64-debug +out/build/x86-debug diff --git a/Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt b/Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt index 628746e29f..84b3dc8776 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt +++ b/Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt @@ -62,8 +62,8 @@ set(WW3D2_SRC #dx8vertexbuffer.h dx8webbrowser.cpp dx8webbrowser.h - #dx8wrapper.cpp - #dx8wrapper.h + dx8wrapper.cpp + dx8wrapper.h dynamesh.cpp dynamesh.h font3d.cpp diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp b/Core/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp similarity index 54% rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp rename to Core/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp index 9b6584693f..2a709b2117 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp @@ -26,8 +26,8 @@ * * * Original Author:: Jani Penttinen * * * - * $Author:: Kenny Mitchell * - * * + * $Author:: Kenny Mitchell * + * * * $Modtime:: 08/05/02 1:27p $* * * * $Revision:: 170 $* @@ -35,14 +35,14 @@ * 06/26/02 KM Matrix name change to avoid MAX conflicts * * 06/27/02 KM Render to shadow buffer texture support * * 06/27/02 KM Shader system updates * - * 08/05/02 KM Texture class redesign + * 08/05/02 KM Texture class redesign *---------------------------------------------------------------------------------------------* * Functions: * * DX8Wrapper::_Update_Texture -- Copies a texture from system memory to video memory * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -//#define CREATE_DX8_MULTI_THREADED -//#define CREATE_DX8_FPU_PRESERVE + //#define CREATE_DX8_MULTI_THREADED + //#define CREATE_DX8_FPU_PRESERVE #define WW3D_DEVTYPE D3DDEVTYPE_HAL #if defined(_MSC_VER) && _MSC_VER < 1300 @@ -104,34 +104,34 @@ int DX8Wrapper_PreserveFPU = 0; ** ***********************************************************************************/ -static HWND _Hwnd = NULL; -bool DX8Wrapper::IsInitted = false; -bool DX8Wrapper::_EnableTriangleDraw = true; +static HWND _Hwnd = NULL; +bool DX8Wrapper::IsInitted = false; +bool DX8Wrapper::_EnableTriangleDraw = true; -int DX8Wrapper::CurRenderDevice = -1; -int DX8Wrapper::ResolutionWidth = DEFAULT_RESOLUTION_WIDTH; -int DX8Wrapper::ResolutionHeight = DEFAULT_RESOLUTION_HEIGHT; -int DX8Wrapper::BitDepth = DEFAULT_BIT_DEPTH; -int DX8Wrapper::TextureBitDepth = DEFAULT_TEXTURE_BIT_DEPTH; -bool DX8Wrapper::IsWindowed = false; -D3DFORMAT DX8Wrapper::DisplayFormat = D3DFMT_UNKNOWN; +int DX8Wrapper::CurRenderDevice = -1; +int DX8Wrapper::ResolutionWidth = DEFAULT_RESOLUTION_WIDTH; +int DX8Wrapper::ResolutionHeight = DEFAULT_RESOLUTION_HEIGHT; +int DX8Wrapper::BitDepth = DEFAULT_BIT_DEPTH; +int DX8Wrapper::TextureBitDepth = DEFAULT_TEXTURE_BIT_DEPTH; +bool DX8Wrapper::IsWindowed = false; +D3DFORMAT DX8Wrapper::DisplayFormat = D3DFMT_UNKNOWN; D3DMATRIX DX8Wrapper::old_world; D3DMATRIX DX8Wrapper::old_view; D3DMATRIX DX8Wrapper::old_prj; // shader system additions KJM v -DWORD DX8Wrapper::Vertex_Shader = 0; -DWORD DX8Wrapper::Pixel_Shader = 0; +DWORD DX8Wrapper::Vertex_Shader = 0; +DWORD DX8Wrapper::Pixel_Shader = 0; Vector4 DX8Wrapper::Vertex_Shader_Constants[MAX_VERTEX_SHADER_CONSTANTS]; Vector4 DX8Wrapper::Pixel_Shader_Constants[MAX_PIXEL_SHADER_CONSTANTS]; -LightEnvironmentClass* DX8Wrapper::Light_Environment = NULL; -RenderInfoClass* DX8Wrapper::Render_Info = NULL; +LightEnvironmentClass* DX8Wrapper::Light_Environment = NULL; +RenderInfoClass* DX8Wrapper::Render_Info = NULL; -DWORD DX8Wrapper::Vertex_Processing_Behavior = 0; -ZTextureClass* DX8Wrapper::Shadow_Map[MAX_SHADOW_MAPS]; +DWORD DX8Wrapper::Vertex_Processing_Behavior = 0; +ZTextureClass* DX8Wrapper::Shadow_Map[MAX_SHADOW_MAPS]; Vector3 DX8Wrapper::Ambient_Color; // shader system additions KJM ^ @@ -139,61 +139,61 @@ Vector3 DX8Wrapper::Ambient_Color; bool DX8Wrapper::world_identity; unsigned DX8Wrapper::RenderStates[256]; unsigned DX8Wrapper::TextureStageStates[MAX_TEXTURE_STAGES][32]; -IDirect3DBaseTexture8 * DX8Wrapper::Textures[MAX_TEXTURE_STAGES]; +IDirect3DBaseTexture8* DX8Wrapper::Textures[MAX_TEXTURE_STAGES]; RenderStateStruct DX8Wrapper::render_state; unsigned DX8Wrapper::render_state_changed; -bool DX8Wrapper::FogEnable = false; -D3DCOLOR DX8Wrapper::FogColor = 0; - -IDirect3D8 * DX8Wrapper::D3DInterface = NULL; -IDirect3DDevice8 * DX8Wrapper::D3DDevice = NULL; -IDirect3DSurface8 * DX8Wrapper::CurrentRenderTarget = NULL; -IDirect3DSurface8 * DX8Wrapper::CurrentDepthBuffer = NULL; -IDirect3DSurface8 * DX8Wrapper::DefaultRenderTarget = NULL; -IDirect3DSurface8 * DX8Wrapper::DefaultDepthBuffer = NULL; -bool DX8Wrapper::IsRenderToTexture = false; - -unsigned DX8Wrapper::matrix_changes = 0; -unsigned DX8Wrapper::material_changes = 0; -unsigned DX8Wrapper::vertex_buffer_changes = 0; -unsigned DX8Wrapper::index_buffer_changes = 0; -unsigned DX8Wrapper::light_changes = 0; -unsigned DX8Wrapper::texture_changes = 0; -unsigned DX8Wrapper::render_state_changes = 0; -unsigned DX8Wrapper::texture_stage_state_changes = 0; -unsigned DX8Wrapper::draw_calls = 0; -unsigned DX8Wrapper::_MainThreadID = 0; +bool DX8Wrapper::FogEnable = false; +D3DCOLOR DX8Wrapper::FogColor = 0; + +IDirect3D8* DX8Wrapper::D3DInterface = NULL; +IDirect3DDevice8* DX8Wrapper::D3DDevice = NULL; +IDirect3DSurface8* DX8Wrapper::CurrentRenderTarget = NULL; +IDirect3DSurface8* DX8Wrapper::CurrentDepthBuffer = NULL; +IDirect3DSurface8* DX8Wrapper::DefaultRenderTarget = NULL; +IDirect3DSurface8* DX8Wrapper::DefaultDepthBuffer = NULL; +bool DX8Wrapper::IsRenderToTexture = false; + +unsigned DX8Wrapper::matrix_changes = 0; +unsigned DX8Wrapper::material_changes = 0; +unsigned DX8Wrapper::vertex_buffer_changes = 0; +unsigned DX8Wrapper::index_buffer_changes = 0; +unsigned DX8Wrapper::light_changes = 0; +unsigned DX8Wrapper::texture_changes = 0; +unsigned DX8Wrapper::render_state_changes = 0; +unsigned DX8Wrapper::texture_stage_state_changes = 0; +unsigned DX8Wrapper::draw_calls = 0; +unsigned DX8Wrapper::_MainThreadID = 0; bool DX8Wrapper::CurrentDX8LightEnables[4]; bool DX8Wrapper::IsDeviceLost; int DX8Wrapper::ZBias; float DX8Wrapper::ZNear; float DX8Wrapper::ZFar; Matrix4x4 DX8Wrapper::ProjectionMatrix; -Matrix4x4 DX8Wrapper::DX8Transforms[D3DTS_WORLD+1]; +Matrix4x4 DX8Wrapper::DX8Transforms[D3DTS_WORLD + 1]; -DX8Caps* DX8Wrapper::CurrentCaps = 0; +DX8Caps* DX8Wrapper::CurrentCaps = 0; // Hack test... this disables rendering of batches of too few polygons. -unsigned DX8Wrapper::DrawPolygonLowBoundLimit=0; +unsigned DX8Wrapper::DrawPolygonLowBoundLimit = 0; D3DADAPTER_IDENTIFIER8 DX8Wrapper::CurrentAdapterIdentifier; unsigned long DX8Wrapper::FrameCount = 0; -bool _DX8SingleThreaded = false; +bool _DX8SingleThreaded = false; -unsigned number_of_DX8_calls = 0; -static unsigned last_frame_matrix_changes = 0; -static unsigned last_frame_material_changes = 0; -static unsigned last_frame_vertex_buffer_changes = 0; -static unsigned last_frame_index_buffer_changes = 0; -static unsigned last_frame_light_changes = 0; -static unsigned last_frame_texture_changes = 0; -static unsigned last_frame_render_state_changes = 0; -static unsigned last_frame_texture_stage_state_changes = 0; -static unsigned last_frame_number_of_DX8_calls = 0; -static unsigned last_frame_draw_calls = 0; +unsigned number_of_DX8_calls = 0; +static unsigned last_frame_matrix_changes = 0; +static unsigned last_frame_material_changes = 0; +static unsigned last_frame_vertex_buffer_changes = 0; +static unsigned last_frame_index_buffer_changes = 0; +static unsigned last_frame_light_changes = 0; +static unsigned last_frame_texture_changes = 0; +static unsigned last_frame_render_state_changes = 0; +static unsigned last_frame_texture_stage_state_changes = 0; +static unsigned last_frame_number_of_DX8_calls = 0; +static unsigned last_frame_draw_calls = 0; static D3DDISPLAYMODE DesktopMode; @@ -203,11 +203,11 @@ static DynamicVectorClass _RenderDeviceShortNameTable; static DynamicVectorClass _RenderDeviceDescriptionTable; -typedef IDirect3D8* (WINAPI *Direct3DCreate8Type) (UINT SDKVersion); +typedef IDirect3D8* (WINAPI* Direct3DCreate8Type) (UINT SDKVersion); Direct3DCreate8Type Direct3DCreate8Ptr = NULL; HINSTANCE D3D8Lib = NULL; -DX8_CleanupHook *DX8Wrapper::m_pCleanupHook=NULL; +DX8_CleanupHook* DX8Wrapper::m_pCleanupHook = NULL; #ifdef EXTENDED_STATS DX8_Stats DX8Wrapper::stats; #endif @@ -219,31 +219,31 @@ DX8_Stats DX8Wrapper::stats; void Log_DX8_ErrorCode(unsigned res) { - char tmp[256]=""; + char tmp[256] = ""; - HRESULT new_res=D3DXGetErrorStringA( + HRESULT new_res = D3DXGetErrorStringA( res, tmp, sizeof(tmp)); - if (new_res==D3D_OK) { + if (new_res == D3D_OK) { WWDEBUG_SAY((tmp)); } WWASSERT(0); } -void Non_Fatal_Log_DX8_ErrorCode(unsigned res,const char * file,int line) +void Non_Fatal_Log_DX8_ErrorCode(unsigned res, const char* file, int line) { - char tmp[256]=""; + char tmp[256] = ""; - HRESULT new_res=D3DXGetErrorStringA( + HRESULT new_res = D3DXGetErrorStringA( res, tmp, sizeof(tmp)); - if (new_res==D3D_OK) { - WWDEBUG_SAY(("DX8 Error: %s, File: %s, Line: %d",tmp,file,line)); + if (new_res == D3D_OK) { + WWDEBUG_SAY(("DX8 Error: %s, File: %s, Line: %d", tmp, file, line)); } } @@ -255,50 +255,49 @@ void MoveRectIntoOtherRect(const RECT& inner, const RECT& outer, int* x, int* y) { int dx = 0; if (inner.right > outer.right) - dx = outer.right-inner.right; + dx = outer.right - inner.right; if (inner.left < outer.left) - dx = outer.left-inner.left; + dx = outer.left - inner.left; int dy = 0; if (inner.bottom > outer.bottom) - dy = outer.bottom-inner.bottom; + dy = outer.bottom - inner.bottom; if (inner.top < outer.top) - dy = outer.top-inner.top; + dy = outer.top - inner.top; *x += dx; *y += dy; } - -bool DX8Wrapper::Init(void * hwnd, bool lite) +bool DX8Wrapper::Init(void* hwnd, bool lite) { WWASSERT(!IsInitted); // zero memory - memset(Textures,0,sizeof(IDirect3DBaseTexture8*)*MAX_TEXTURE_STAGES); - memset(RenderStates,0,sizeof(unsigned)*256); - memset(TextureStageStates,0,sizeof(unsigned)*32*MAX_TEXTURE_STAGES); - memset(Vertex_Shader_Constants,0,sizeof(Vector4)*MAX_VERTEX_SHADER_CONSTANTS); - memset(Pixel_Shader_Constants,0,sizeof(Vector4)*MAX_PIXEL_SHADER_CONSTANTS); - memset(&render_state,0,sizeof(RenderStateStruct)); - memset(Shadow_Map,0,sizeof(ZTextureClass*)*MAX_SHADOW_MAPS); + memset(Textures, 0, sizeof(IDirect3DBaseTexture8*) * MAX_TEXTURE_STAGES); + memset(RenderStates, 0, sizeof(unsigned) * 256); + memset(TextureStageStates, 0, sizeof(unsigned) * 32 * MAX_TEXTURE_STAGES); + memset(Vertex_Shader_Constants, 0, sizeof(Vector4) * MAX_VERTEX_SHADER_CONSTANTS); + memset(Pixel_Shader_Constants, 0, sizeof(Vector4) * MAX_PIXEL_SHADER_CONSTANTS); + memset(&render_state, 0, sizeof(RenderStateStruct)); + memset(Shadow_Map, 0, sizeof(ZTextureClass*) * MAX_SHADOW_MAPS); /* ** Initialize all variables! */ _Hwnd = (HWND)hwnd; - _MainThreadID=ThreadClass::_Get_Current_Thread_ID(); - WWDEBUG_SAY(("DX8Wrapper main thread: 0x%x",_MainThreadID)); + _MainThreadID = ThreadClass::_Get_Current_Thread_ID(); + WWDEBUG_SAY(("DX8Wrapper main thread: 0x%x", _MainThreadID)); CurRenderDevice = -1; ResolutionWidth = DEFAULT_RESOLUTION_WIDTH; ResolutionHeight = DEFAULT_RESOLUTION_HEIGHT; // Initialize Render2DClass Screen Resolution - Render2DClass::Set_Screen_Resolution( RectClass( 0, 0, ResolutionWidth, ResolutionHeight ) ); + Render2DClass::Set_Screen_Resolution(RectClass(0, 0, ResolutionWidth, ResolutionHeight)); BitDepth = DEFAULT_BIT_DEPTH; - IsWindowed = false; + IsWindowed = false; DX8Wrapper_IsWindowed = false; - for (int light=0;light<4;++light) CurrentDX8LightEnables[light]=false; + for (int light = 0; light < 4; ++light) CurrentDX8LightEnables[light] = false; ::ZeroMemory(&old_world, sizeof(D3DMATRIX)); ::ZeroMemory(&old_view, sizeof(D3DMATRIX)); @@ -324,7 +323,7 @@ bool DX8Wrapper::Init(void * hwnd, bool lite) if (D3D8Lib == NULL) return false; // Return false at this point if init failed - Direct3DCreate8Ptr = (Direct3DCreate8Type) GetProcAddress(D3D8Lib, "Direct3DCreate8"); + Direct3DCreate8Ptr = (Direct3DCreate8Type)GetProcAddress(D3D8Lib, "Direct3DCreate8"); if (Direct3DCreate8Ptr == NULL) return false; /* @@ -352,22 +351,22 @@ void DX8Wrapper::Shutdown(void) { if (D3DDevice) { - Set_Render_Target ((IDirect3DSurface8 *)NULL); + Set_Render_Target((IDirect3DSurface8*)NULL); Release_Device(); } if (D3DInterface) { D3DInterface->Release(); - D3DInterface=NULL; + D3DInterface = NULL; } if (CurrentCaps) { - int max=CurrentCaps->Get_Max_Textures_Per_Pass(); - for (int i = 0; i < max; i++) + int max = CurrentCaps->Get_Max_Textures_Per_Pass(); + for (int i = 0; i < max; i++) { - if (Textures[i]) + if (Textures[i]) { Textures[i]->Release(); Textures[i] = NULL; @@ -376,8 +375,8 @@ void DX8Wrapper::Shutdown(void) } if (D3DInterface) { - UINT newRefCount=D3DInterface->Release(); - D3DInterface=NULL; + D3DInterface->Release(); + D3DInterface = NULL; } if (D3D8Lib) { @@ -387,7 +386,7 @@ void DX8Wrapper::Shutdown(void) _RenderDeviceNameTable.Clear(); // note - Delete_All() resizes the vector, causing a reallocation. Clear is better. jba. _RenderDeviceShortNameTable.Clear(); - _RenderDeviceDescriptionTable.Clear(); + _RenderDeviceDescriptionTable.Clear(); DX8Caps::Shutdown(); IsInitted = false; // 010803 srj @@ -400,9 +399,9 @@ void DX8Wrapper::Do_Onetime_Device_Dependent_Inits(void) */ Compute_Caps(D3DFormat_To_WW3DFormat(DisplayFormat)); - /* - ** Initalize any other subsystems inside of WW3D - */ + /* + ** Initalize any other subsystems inside of WW3D + */ MissingTexture::_Init(); TextureFilterClass::_Init_Filters((TextureFilterClass::TextureFilterMode)WW3D::Get_Texture_Filter()); TheDX8MeshRenderer.Init(); @@ -420,57 +419,58 @@ inline DWORD F2DW(float f) { return *((unsigned*)&f); } void DX8Wrapper::Set_Default_Global_Render_States(void) { DX8_THREAD_ASSERT(); - const D3DCAPS8 &caps = Get_Current_Caps()->Get_DX8_Caps(); + const D3DCAPS8& caps = Get_Current_Caps()->Get_DX8_Caps(); Set_DX8_Render_State(D3DRS_RANGEFOGENABLE, (caps.RasterCaps & D3DPRASTERCAPS_FOGRANGE) ? TRUE : FALSE); Set_DX8_Render_State(D3DRS_FOGTABLEMODE, D3DFOG_NONE); Set_DX8_Render_State(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR); Set_DX8_Render_State(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL); Set_DX8_Render_State(D3DRS_COLORVERTEX, TRUE); - Set_DX8_Render_State(D3DRS_ZBIAS,0); + Set_DX8_Render_State(D3DRS_ZBIAS, 0); Set_DX8_Texture_Stage_State(1, D3DTSS_BUMPENVLSCALE, F2DW(1.0f)); Set_DX8_Texture_Stage_State(1, D3DTSS_BUMPENVLOFFSET, F2DW(0.0f)); - Set_DX8_Texture_Stage_State(0, D3DTSS_BUMPENVMAT00,F2DW(1.0f)); - Set_DX8_Texture_Stage_State(0, D3DTSS_BUMPENVMAT01,F2DW(0.0f)); - Set_DX8_Texture_Stage_State(0, D3DTSS_BUMPENVMAT10,F2DW(0.0f)); - Set_DX8_Texture_Stage_State(0, D3DTSS_BUMPENVMAT11,F2DW(1.0f)); + Set_DX8_Texture_Stage_State(0, D3DTSS_BUMPENVMAT00, F2DW(1.0f)); + Set_DX8_Texture_Stage_State(0, D3DTSS_BUMPENVMAT01, F2DW(0.0f)); + Set_DX8_Texture_Stage_State(0, D3DTSS_BUMPENVMAT10, F2DW(0.0f)); + Set_DX8_Texture_Stage_State(0, D3DTSS_BUMPENVMAT11, F2DW(1.0f)); -// Set_DX8_Render_State(D3DRS_CULLMODE, D3DCULL_CW); - // Set dither mode here? + // Set_DX8_Render_State(D3DRS_CULLMODE, D3DCULL_CW); + // Set dither mode here? } //MW: I added this for 'Generals'. bool DX8Wrapper::Validate_Device(void) -{ DWORD numPasses=0; +{ + DWORD numPasses = 0; HRESULT hRes; - hRes=_Get_D3D_Device8()->ValidateDevice(&numPasses); + hRes = _Get_D3D_Device8()->ValidateDevice(&numPasses); return (hRes == D3D_OK); } void DX8Wrapper::Invalidate_Cached_Render_States(void) { - render_state_changed=0; + render_state_changed = 0; int a; - for (a=0;aSetTexture(a,NULL); + _Get_D3D_Device8()->SetTexture(a, NULL); if (Textures[a] != NULL) { Textures[a]->Release(); } - Textures[a]=NULL; + Textures[a] = NULL; } ShaderClass::Invalidate(); @@ -479,11 +479,11 @@ void DX8Wrapper::Invalidate_Cached_Render_States(void) Release_Render_State(); // (gth) clear the matrix shadows too - for (int i=0; iRelease_Engine_Ref(); REF_PTR_RELEASE(render_state.vertex_buffers[i]); } if (render_state.index_buffer) render_state.index_buffer->Release_Engine_Ref(); REF_PTR_RELEASE(render_state.index_buffer); REF_PTR_RELEASE(render_state.material); - for (i=0;iGet_Max_Textures_Per_Pass();++i) REF_PTR_RELEASE(render_state.Textures[i]); + for (i = 0; i < CurrentCaps->Get_Max_Textures_Per_Pass(); ++i) REF_PTR_RELEASE(render_state.Textures[i]); TextureLoader::Deinit(); @@ -518,54 +518,53 @@ void DX8Wrapper::Do_Onetime_Device_Dependent_Shutdowns(void) if (CurrentCaps) { delete CurrentCaps; - CurrentCaps=NULL; + CurrentCaps = NULL; } } - bool DX8Wrapper::Create_Device(void) { - WWASSERT(D3DDevice==NULL); // for now, once you've created a device, you're stuck with it! + WWASSERT(D3DDevice == NULL); // for now, once you've created a device, you're stuck with it! D3DCAPS8 caps; - if - ( - FAILED + if ( - D3DInterface->GetDeviceCaps + FAILED ( - CurRenderDevice, - WW3D_DEVTYPE, - &caps + D3DInterface->GetDeviceCaps + ( + CurRenderDevice, + WW3D_DEVTYPE, + &caps + ) + ) ) - ) - ) { return false; } ::ZeroMemory(&CurrentAdapterIdentifier, sizeof(D3DADAPTER_IDENTIFIER8)); - + if - ( - FAILED - ( - D3DInterface->GetAdapterIdentifier + ( + FAILED ( - CurRenderDevice, - D3DENUM_NO_WHQL_LEVEL, - &CurrentAdapterIdentifier + D3DInterface->GetAdapterIdentifier + ( + CurRenderDevice, + D3DENUM_NO_WHQL_LEVEL, + &CurrentAdapterIdentifier + ) + ) ) - ) - ) { return false; } #ifndef _XBOX - - Vertex_Processing_Behavior=(caps.DevCaps&D3DDEVCAPS_HWTRANSFORMANDLIGHT) ? + + Vertex_Processing_Behavior = (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) ? D3DCREATE_MIXED_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING; // enable this when all 'get' dx calls are removed KJM @@ -575,46 +574,46 @@ bool DX8Wrapper::Create_Device(void) }*/ #else // XBOX - Vertex_Processing_Behavior=D3DCREATE_PUREDEVICE; + Vertex_Processing_Behavior = D3DCREATE_PUREDEVICE; #endif // XBOX #ifdef CREATE_DX8_MULTI_THREADED - Vertex_Processing_Behavior|=D3DCREATE_MULTITHREADED; - _DX8SingleThreaded=false; + Vertex_Processing_Behavior |= D3DCREATE_MULTITHREADED; + _DX8SingleThreaded = false; #else - _DX8SingleThreaded=true; + _DX8SingleThreaded = true; #endif if (DX8Wrapper_PreserveFPU) Vertex_Processing_Behavior |= D3DCREATE_FPU_PRESERVE; #ifdef CREATE_DX8_FPU_PRESERVE - Vertex_Processing_Behavior|=D3DCREATE_FPU_PRESERVE; + Vertex_Processing_Behavior |= D3DCREATE_FPU_PRESERVE; #endif - HRESULT hr=D3DInterface->CreateDevice + HRESULT hr = D3DInterface->CreateDevice ( CurRenderDevice, WW3D_DEVTYPE, _Hwnd, Vertex_Processing_Behavior, &_PresentParameters, - &D3DDevice + &D3DDevice ); - if (FAILED(hr)) + if (FAILED(hr)) { // The device selection may fail because the device lied that it supports 32 bit zbuffer with 16 bit // display. This happens at least on Voodoo2. - if ((_PresentParameters.BackBufferFormat==D3DFMT_R5G6B5 || - _PresentParameters.BackBufferFormat==D3DFMT_X1R5G5B5 || - _PresentParameters.BackBufferFormat==D3DFMT_A1R5G5B5) && - (_PresentParameters.AutoDepthStencilFormat==D3DFMT_D32 || - _PresentParameters.AutoDepthStencilFormat==D3DFMT_D24S8 || - _PresentParameters.AutoDepthStencilFormat==D3DFMT_D24X8)) + if ((_PresentParameters.BackBufferFormat == D3DFMT_R5G6B5 || + _PresentParameters.BackBufferFormat == D3DFMT_X1R5G5B5 || + _PresentParameters.BackBufferFormat == D3DFMT_A1R5G5B5) && + (_PresentParameters.AutoDepthStencilFormat == D3DFMT_D32 || + _PresentParameters.AutoDepthStencilFormat == D3DFMT_D24S8 || + _PresentParameters.AutoDepthStencilFormat == D3DFMT_D24X8)) { - _PresentParameters.AutoDepthStencilFormat=D3DFMT_D16; + _PresentParameters.AutoDepthStencilFormat = D3DFMT_D16; hr = D3DInterface->CreateDevice ( CurRenderDevice, @@ -622,17 +621,17 @@ bool DX8Wrapper::Create_Device(void) _Hwnd, Vertex_Processing_Behavior, &_PresentParameters, - &D3DDevice + &D3DDevice ); - if (FAILED(hr)) + if (FAILED(hr)) { return false; } - } - else + } + else { - return false; + return false; } } @@ -651,11 +650,11 @@ bool DX8Wrapper::Reset_Device(bool reload_assets) // Release all non-MANAGED stuff WW3D::_Invalidate_Textures(); - for (unsigned i=0;iReleaseResources(); } @@ -667,14 +666,15 @@ bool DX8Wrapper::Reset_Device(bool reload_assets) // Reset frame count to reflect the flipping chain being reset by Reset() FrameCount = 0; - memset(Vertex_Shader_Constants,0,sizeof(Vector4)*MAX_VERTEX_SHADER_CONSTANTS); - memset(Pixel_Shader_Constants,0,sizeof(Vector4)*MAX_PIXEL_SHADER_CONSTANTS); + memset(Vertex_Shader_Constants, 0, sizeof(Vector4) * MAX_VERTEX_SHADER_CONSTANTS); + memset(Pixel_Shader_Constants, 0, sizeof(Vector4) * MAX_PIXEL_SHADER_CONSTANTS); - HRESULT hr=_Get_D3D_Device8()->TestCooperativeLevel(); - if (hr != D3DERR_DEVICELOST ) - { DX8CALL_HRES(Reset(&_PresentParameters),hr) - if (hr != D3D_OK) - return false; //reset failed. + HRESULT hr = _Get_D3D_Device8()->TestCooperativeLevel(); + if (hr != D3DERR_DEVICELOST) + { + DX8CALL_HRES(Reset(&_PresentParameters), hr) + if (hr != D3D_OK) + return false; //reset failed. } else return false; //device is lost and can't be reset. @@ -700,19 +700,19 @@ void DX8Wrapper::Release_Device(void) { if (D3DDevice) { - for (int a=0;aRelease_Engine_Ref(); REF_PTR_RELEASE(render_state.vertex_buffers[i]); @@ -730,7 +730,7 @@ void DX8Wrapper::Release_Device(void) */ D3DDevice->Release(); - D3DDevice=NULL; + D3DDevice = NULL; } } @@ -739,11 +739,11 @@ void DX8Wrapper::Enumerate_Devices() DX8_Assert(); int adapter_count = D3DInterface->GetAdapterCount(); - for (int adapter_index=0; adapter_indexGetAdapterIdentifier(adapter_index,D3DENUM_NO_WHQL_LEVEL,&id); + HRESULT res = D3DInterface->GetAdapterIdentifier(adapter_index, D3DENUM_NO_WHQL_LEVEL, &id); if (res == D3D_OK) { @@ -756,7 +756,7 @@ void DX8Wrapper::Enumerate_Devices() desc.set_driver_name(id.Driver); char buf[64]; - sprintf(buf,"%d.%d.%d.%d", //"%04x.%04x.%04x.%04x", + sprintf(buf, "%d.%d.%d.%d", //"%04x.%04x.%04x.%04x", HIWORD(id.DriverVersion.HighPart), LOWORD(id.DriverVersion.HighPart), HIWORD(id.DriverVersion.LowPart), @@ -764,36 +764,36 @@ void DX8Wrapper::Enumerate_Devices() desc.set_driver_version(buf); - D3DInterface->GetDeviceCaps(adapter_index,WW3D_DEVTYPE,&desc.Caps); - D3DInterface->GetAdapterIdentifier(adapter_index,D3DENUM_NO_WHQL_LEVEL,&desc.AdapterIdentifier); + D3DInterface->GetDeviceCaps(adapter_index, WW3D_DEVTYPE, &desc.Caps); + D3DInterface->GetAdapterIdentifier(adapter_index, D3DENUM_NO_WHQL_LEVEL, &desc.AdapterIdentifier); - DX8Caps dx8caps(D3DInterface,desc.Caps,WW3D_FORMAT_UNKNOWN,desc.AdapterIdentifier); + DX8Caps dx8caps(D3DInterface, desc.Caps, WW3D_FORMAT_UNKNOWN, desc.AdapterIdentifier); /* ** Enumerate the resolutions */ desc.reset_resolution_list(); int mode_count = D3DInterface->GetAdapterModeCount(adapter_index); - for (int mode_index=0; mode_indexEnumAdapterModes(adapter_index,mode_index,&d3dmode); + HRESULT res = D3DInterface->EnumAdapterModes(adapter_index, mode_index, &d3dmode); if (res == D3D_OK) { int bits = 0; switch (d3dmode.Format) { - case D3DFMT_R8G8B8: - case D3DFMT_A8R8G8B8: - case D3DFMT_X8R8G8B8: bits = 32; break; + case D3DFMT_R8G8B8: + case D3DFMT_A8R8G8B8: + case D3DFMT_X8R8G8B8: bits = 32; break; - case D3DFMT_R5G6B5: - case D3DFMT_X1R5G5B5: bits = 16; break; + case D3DFMT_R5G6B5: + case D3DFMT_X1R5G5B5: bits = 16; break; } // Some cards fail in certain modes, DX8Caps keeps list of those. - if (!dx8caps.Is_Valid_Display_Format(d3dmode.Width,d3dmode.Height,D3DFormat_To_WW3DFormat(d3dmode.Format))) { - bits=0; + if (!dx8caps.Is_Valid_Display_Format(d3dmode.Width, d3dmode.Height, D3DFormat_To_WW3DFormat(d3dmode.Format))) { + bits = 0; } /* @@ -801,7 +801,7 @@ void DX8Wrapper::Enumerate_Devices() ** TODO: should we handle more formats? will any cards report more than 24 or 16 bit? */ if (bits != 0) { - desc.add_resolution(d3dmode.Width,d3dmode.Height,bits); + desc.add_resolution(d3dmode.Width, d3dmode.Height, bits); } } } @@ -813,7 +813,7 @@ void DX8Wrapper::Enumerate_Devices() /* ** Set up the device name */ - StringClass device_name(id.Description,true); + StringClass device_name(id.Description, true); _RenderDeviceNameTable.Add(device_name); _RenderDeviceShortNameTable.Add(device_name); // for now, just add the same name to the "pretty name table" @@ -826,19 +826,20 @@ void DX8Wrapper::Enumerate_Devices() } } + bool DX8Wrapper::Set_Any_Render_Device(void) { // Then fullscreen int dev_number = 0; for (; dev_number < _RenderDeviceNameTable.Count(); dev_number++) { - if (Set_Render_Device(dev_number,-1,-1,-1,0,false)) { + if (Set_Render_Device(dev_number, -1, -1, -1, 0, false)) { return true; } } // Try windowed first for (dev_number = 0; dev_number < _RenderDeviceNameTable.Count(); dev_number++) { - if (Set_Render_Device(dev_number,-1,-1,-1,1,false)) { + if (Set_Render_Device(dev_number, -1, -1, -1, 1, false)) { return true; } } @@ -848,7 +849,7 @@ bool DX8Wrapper::Set_Any_Render_Device(void) bool DX8Wrapper::Set_Render_Device ( - const char * dev_name, + const char* dev_name, int width, int height, int bits, @@ -856,82 +857,82 @@ bool DX8Wrapper::Set_Render_Device bool resize_window ) { - for ( int dev_number = 0; dev_number < _RenderDeviceNameTable.Count(); dev_number++) { - if ( strcmp( dev_name, _RenderDeviceNameTable[dev_number]) == 0) { - return Set_Render_Device( dev_number, width, height, bits, windowed, resize_window ); + for (int dev_number = 0; dev_number < _RenderDeviceNameTable.Count(); dev_number++) { + if (strcmp(dev_name, _RenderDeviceNameTable[dev_number]) == 0) { + return Set_Render_Device(dev_number, width, height, bits, windowed, resize_window); } - if ( strcmp( dev_name, _RenderDeviceShortNameTable[dev_number]) == 0) { - return Set_Render_Device( dev_number, width, height, bits, windowed, resize_window ); + if (strcmp(dev_name, _RenderDeviceShortNameTable[dev_number]) == 0) { + return Set_Render_Device(dev_number, width, height, bits, windowed, resize_window); } } return false; } -void DX8Wrapper::Get_Format_Name(unsigned int format, StringClass *tex_format) +void DX8Wrapper::Get_Format_Name(unsigned int format, StringClass* tex_format) { - *tex_format="Unknown"; - switch (format) { - case D3DFMT_A8R8G8B8: *tex_format="D3DFMT_A8R8G8B8"; break; - case D3DFMT_R8G8B8: *tex_format="D3DFMT_R8G8B8"; break; - case D3DFMT_A4R4G4B4: *tex_format="D3DFMT_A4R4G4B4"; break; - case D3DFMT_A1R5G5B5: *tex_format="D3DFMT_A1R5G5B5"; break; - case D3DFMT_R5G6B5: *tex_format="D3DFMT_R5G6B5"; break; - case D3DFMT_L8: *tex_format="D3DFMT_L8"; break; - case D3DFMT_A8: *tex_format="D3DFMT_A8"; break; - case D3DFMT_P8: *tex_format="D3DFMT_P8"; break; - case D3DFMT_X8R8G8B8: *tex_format="D3DFMT_X8R8G8B8"; break; - case D3DFMT_X1R5G5B5: *tex_format="D3DFMT_X1R5G5B5"; break; - case D3DFMT_R3G3B2: *tex_format="D3DFMT_R3G3B2"; break; - case D3DFMT_A8R3G3B2: *tex_format="D3DFMT_A8R3G3B2"; break; - case D3DFMT_X4R4G4B4: *tex_format="D3DFMT_X4R4G4B4"; break; - case D3DFMT_A8P8: *tex_format="D3DFMT_A8P8"; break; - case D3DFMT_A8L8: *tex_format="D3DFMT_A8L8"; break; - case D3DFMT_A4L4: *tex_format="D3DFMT_A4L4"; break; - case D3DFMT_V8U8: *tex_format="D3DFMT_V8U8"; break; - case D3DFMT_L6V5U5: *tex_format="D3DFMT_L6V5U5"; break; - case D3DFMT_X8L8V8U8: *tex_format="D3DFMT_X8L8V8U8"; break; - case D3DFMT_Q8W8V8U8: *tex_format="D3DFMT_Q8W8V8U8"; break; - case D3DFMT_V16U16: *tex_format="D3DFMT_V16U16"; break; - case D3DFMT_W11V11U10: *tex_format="D3DFMT_W11V11U10"; break; - case D3DFMT_UYVY: *tex_format="D3DFMT_UYVY"; break; - case D3DFMT_YUY2: *tex_format="D3DFMT_YUY2"; break; - case D3DFMT_DXT1: *tex_format="D3DFMT_DXT1"; break; - case D3DFMT_DXT2: *tex_format="D3DFMT_DXT2"; break; - case D3DFMT_DXT3: *tex_format="D3DFMT_DXT3"; break; - case D3DFMT_DXT4: *tex_format="D3DFMT_DXT4"; break; - case D3DFMT_DXT5: *tex_format="D3DFMT_DXT5"; break; - case D3DFMT_D16_LOCKABLE: *tex_format="D3DFMT_D16_LOCKABLE"; break; - case D3DFMT_D32: *tex_format="D3DFMT_D32"; break; - case D3DFMT_D15S1: *tex_format="D3DFMT_D15S1"; break; - case D3DFMT_D24S8: *tex_format="D3DFMT_D24S8"; break; - case D3DFMT_D16: *tex_format="D3DFMT_D16"; break; - case D3DFMT_D24X8: *tex_format="D3DFMT_D24X8"; break; - case D3DFMT_D24X4S4: *tex_format="D3DFMT_D24X4S4"; break; - default: break; - } + *tex_format = "Unknown"; + switch (format) { + case D3DFMT_A8R8G8B8: *tex_format = "D3DFMT_A8R8G8B8"; break; + case D3DFMT_R8G8B8: *tex_format = "D3DFMT_R8G8B8"; break; + case D3DFMT_A4R4G4B4: *tex_format = "D3DFMT_A4R4G4B4"; break; + case D3DFMT_A1R5G5B5: *tex_format = "D3DFMT_A1R5G5B5"; break; + case D3DFMT_R5G6B5: *tex_format = "D3DFMT_R5G6B5"; break; + case D3DFMT_L8: *tex_format = "D3DFMT_L8"; break; + case D3DFMT_A8: *tex_format = "D3DFMT_A8"; break; + case D3DFMT_P8: *tex_format = "D3DFMT_P8"; break; + case D3DFMT_X8R8G8B8: *tex_format = "D3DFMT_X8R8G8B8"; break; + case D3DFMT_X1R5G5B5: *tex_format = "D3DFMT_X1R5G5B5"; break; + case D3DFMT_R3G3B2: *tex_format = "D3DFMT_R3G3B2"; break; + case D3DFMT_A8R3G3B2: *tex_format = "D3DFMT_A8R3G3B2"; break; + case D3DFMT_X4R4G4B4: *tex_format = "D3DFMT_X4R4G4B4"; break; + case D3DFMT_A8P8: *tex_format = "D3DFMT_A8P8"; break; + case D3DFMT_A8L8: *tex_format = "D3DFMT_A8L8"; break; + case D3DFMT_A4L4: *tex_format = "D3DFMT_A4L4"; break; + case D3DFMT_V8U8: *tex_format = "D3DFMT_V8U8"; break; + case D3DFMT_L6V5U5: *tex_format = "D3DFMT_L6V5U5"; break; + case D3DFMT_X8L8V8U8: *tex_format = "D3DFMT_X8L8V8U8"; break; + case D3DFMT_Q8W8V8U8: *tex_format = "D3DFMT_Q8W8V8U8"; break; + case D3DFMT_V16U16: *tex_format = "D3DFMT_V16U16"; break; + case D3DFMT_W11V11U10: *tex_format = "D3DFMT_W11V11U10"; break; + case D3DFMT_UYVY: *tex_format = "D3DFMT_UYVY"; break; + case D3DFMT_YUY2: *tex_format = "D3DFMT_YUY2"; break; + case D3DFMT_DXT1: *tex_format = "D3DFMT_DXT1"; break; + case D3DFMT_DXT2: *tex_format = "D3DFMT_DXT2"; break; + case D3DFMT_DXT3: *tex_format = "D3DFMT_DXT3"; break; + case D3DFMT_DXT4: *tex_format = "D3DFMT_DXT4"; break; + case D3DFMT_DXT5: *tex_format = "D3DFMT_DXT5"; break; + case D3DFMT_D16_LOCKABLE: *tex_format = "D3DFMT_D16_LOCKABLE"; break; + case D3DFMT_D32: *tex_format = "D3DFMT_D32"; break; + case D3DFMT_D15S1: *tex_format = "D3DFMT_D15S1"; break; + case D3DFMT_D24S8: *tex_format = "D3DFMT_D24S8"; break; + case D3DFMT_D16: *tex_format = "D3DFMT_D16"; break; + case D3DFMT_D24X8: *tex_format = "D3DFMT_D24X8"; break; + case D3DFMT_D24X4S4: *tex_format = "D3DFMT_D24X4S4"; break; + default: break; + } } void DX8Wrapper::Resize_And_Position_Window() { // Get the current dimensions of the 'render area' of the window RECT rect = { 0 }; - ::GetClientRect (_Hwnd, &rect); + ::GetClientRect(_Hwnd, &rect); // Is the window the correct size for this resolution? - if ((rect.right-rect.left) != ResolutionWidth || - (rect.bottom-rect.top) != ResolutionHeight) { - + if ((rect.right - rect.left) != ResolutionWidth || + (rect.bottom - rect.top) != ResolutionHeight) { + // Calculate what the main window's bounding rectangle should be to // accommodate this resolution rect.left = 0; rect.top = 0; rect.right = ResolutionWidth; rect.bottom = ResolutionHeight; - DWORD dwstyle = ::GetWindowLong (_Hwnd, GWL_STYLE); - AdjustWindowRect (&rect, dwstyle, FALSE); - int width = rect.right-rect.left; - int height = rect.bottom-rect.top; + DWORD dwstyle = ::GetWindowLong(_Hwnd, GWL_STYLE); + AdjustWindowRect(&rect, dwstyle, FALSE); + int width = rect.right - rect.left; + int height = rect.bottom - rect.top; // Resize the window to fit this resolution if (!IsWindowed) @@ -944,10 +945,10 @@ void DX8Wrapper::Resize_And_Position_Window() { // TheSuperHackers @feature helmutbuhler 14/04/2025 // Center the window in the workarea of the monitor it is on. - MONITORINFO mi = {sizeof(MONITORINFO)}; + MONITORINFO mi = { sizeof(MONITORINFO) }; GetMonitorInfo(MonitorFromWindow(_Hwnd, MONITOR_DEFAULTTOPRIMARY), &mi); int left = (mi.rcWork.left + mi.rcWork.right - width) / 2; - int top = (mi.rcWork.top + mi.rcWork.bottom - height) / 2; + int top = (mi.rcWork.top + mi.rcWork.bottom - height) / 2; // TheSuperHackers @feature helmutbuhler 14/04/2025 // Move the window to try fit it into the monitor area, if one of its dimensions is larger than the work area. @@ -959,15 +960,17 @@ void DX8Wrapper::Resize_And_Position_Window() rectClient.bottom = rectClient.top + ResolutionHeight; MoveRectIntoOtherRect(rectClient, mi.rcMonitor, &left, &top); - ::SetWindowPos (_Hwnd, NULL, left, top, width, height, SWP_NOZORDER); + ::SetWindowPos(_Hwnd, NULL, left, top, width, height, SWP_NOZORDER); DEBUG_LOG(("Window positioned to x:%d y:%d, resized to w:%d h:%d", left, top, width, height)); } } } + + bool DX8Wrapper::Set_Render_Device(int dev, int width, int height, int bits, int windowed, - bool resize_window,bool reset_device, bool restore_assets) + bool resize_window, bool reset_device, bool restore_assets) { WWASSERT(IsInitted); WWASSERT(dev >= -1); @@ -978,27 +981,28 @@ bool DX8Wrapper::Set_Render_Device(int dev, int width, int height, int bits, int */ if ((CurRenderDevice == -1) && (dev == -1)) { CurRenderDevice = 0; - } else if (dev != -1) { + } + else if (dev != -1) { CurRenderDevice = dev; } - + /* - ** If user doesn't want to change res, set the res variables to match the + ** If user doesn't want to change res, set the res variables to match the ** current resolution */ if (width != -1) ResolutionWidth = width; if (height != -1) ResolutionHeight = height; - + // Initialize Render2DClass Screen Resolution - Render2DClass::Set_Screen_Resolution( RectClass( 0, 0, ResolutionWidth, ResolutionHeight ) ); + Render2DClass::Set_Screen_Resolution(RectClass(0, 0, ResolutionWidth, ResolutionHeight)); if (bits != -1) BitDepth = bits; if (windowed != -1) IsWindowed = (windowed != 0); DX8Wrapper_IsWindowed = IsWindowed; WWDEBUG_SAY(("Attempting Set_Render_Device: name: %s (%s:%s), width: %d, height: %d, windowed: %d", - _RenderDeviceNameTable[CurRenderDevice].str(),_RenderDeviceDescriptionTable[CurRenderDevice].Get_Driver_Name(), - _RenderDeviceDescriptionTable[CurRenderDevice].Get_Driver_Version(),ResolutionWidth,ResolutionHeight,(IsWindowed ? 1 : 0))); + _RenderDeviceNameTable[CurRenderDevice].str(), _RenderDeviceDescriptionTable[CurRenderDevice].Get_Driver_Name(), + _RenderDeviceDescriptionTable[CurRenderDevice].Get_Driver_Version(), ResolutionWidth, ResolutionHeight, (IsWindowed ? 1 : 0))); #ifdef _WINDOWS // PWG 4/13/2000 - changed so that if you say to resize the window it resizes @@ -1012,16 +1016,16 @@ bool DX8Wrapper::Set_Render_Device(int dev, int width, int height, int bits, int #endif //must be either resetting existing device or creating a new one. WWASSERT(reset_device || D3DDevice == NULL); - + /* - ** Initialize values for D3DPRESENT_PARAMETERS members. + ** Initialize values for D3DPRESENT_PARAMETERS members. */ ::ZeroMemory(&_PresentParameters, sizeof(D3DPRESENT_PARAMETERS)); _PresentParameters.BackBufferWidth = ResolutionWidth; _PresentParameters.BackBufferHeight = ResolutionHeight; _PresentParameters.BackBufferCount = IsWindowed ? 1 : 2; - + _PresentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; //I changed this to discard all the time (even when full-screen) since that the most efficient. 07-16-03 MW: _PresentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;//IsWindowed ? D3DSWAPEFFECT_DISCARD : D3DSWAPEFFECT_FLIP; // Shouldn't this be D3DSWAPEFFECT_FLIP? @@ -1029,41 +1033,41 @@ bool DX8Wrapper::Set_Render_Device(int dev, int width, int height, int bits, int _PresentParameters.Windowed = IsWindowed; _PresentParameters.EnableAutoDepthStencil = TRUE; // Driver will attempt to match Z-buffer depth - _PresentParameters.Flags=0; // We're not going to lock the backbuffer - + _PresentParameters.Flags = 0; // We're not going to lock the backbuffer + _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; _PresentParameters.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; /* ** Set up the buffer formats. Several issues here: ** - if in windowed mode, the backbuffer must use the current display format. - ** - the depth buffer must use + ** - the depth buffer must use */ if (IsWindowed) { D3DDISPLAYMODE desktop_mode; ::ZeroMemory(&desktop_mode, sizeof(D3DDISPLAYMODE)); - D3DInterface->GetAdapterDisplayMode( CurRenderDevice, &desktop_mode ); + D3DInterface->GetAdapterDisplayMode(CurRenderDevice, &desktop_mode); - DisplayFormat=_PresentParameters.BackBufferFormat = desktop_mode.Format; + DisplayFormat = _PresentParameters.BackBufferFormat = desktop_mode.Format; // In windowed mode, define the bitdepth from desktop mode (as it can't be changed) switch (_PresentParameters.BackBufferFormat) { case D3DFMT_X8R8G8B8: case D3DFMT_A8R8G8B8: - case D3DFMT_R8G8B8: BitDepth=32; break; + case D3DFMT_R8G8B8: BitDepth = 32; break; case D3DFMT_A4R4G4B4: case D3DFMT_A1R5G5B5: - case D3DFMT_R5G6B5: BitDepth=16; break; + case D3DFMT_R5G6B5: BitDepth = 16; break; case D3DFMT_L8: case D3DFMT_A8: - case D3DFMT_P8: BitDepth=8; break; + case D3DFMT_P8: BitDepth = 8; break; default: // Unknown backbuffer format probably means the device can't do windowed return false; } - if (BitDepth==32 && D3DInterface->CheckDeviceType(0,D3DDEVTYPE_HAL,desktop_mode.Format,D3DFMT_A8R8G8B8, TRUE) == D3D_OK) + if (BitDepth == 32 && D3DInterface->CheckDeviceType(0, D3DDEVTYPE_HAL, desktop_mode.Format, D3DFMT_A8R8G8B8, TRUE) == D3D_OK) { //promote 32-bit modes to include destination alpha _PresentParameters.BackBufferFormat = D3DFMT_A8R8G8B8; } @@ -1071,50 +1075,51 @@ bool DX8Wrapper::Set_Render_Device(int dev, int width, int height, int bits, int /* ** Find a appropriate Z buffer */ - if (!Find_Z_Mode(DisplayFormat,_PresentParameters.BackBufferFormat,&_PresentParameters.AutoDepthStencilFormat)) + if (!Find_Z_Mode(DisplayFormat, _PresentParameters.BackBufferFormat, &_PresentParameters.AutoDepthStencilFormat)) { // If opening 32 bit mode failed, try 16 bit, even if the desktop happens to be 32 bit - if (BitDepth==32) { - BitDepth=16; - _PresentParameters.BackBufferFormat=D3DFMT_R5G6B5; - if (!Find_Z_Mode(_PresentParameters.BackBufferFormat,_PresentParameters.BackBufferFormat,&_PresentParameters.AutoDepthStencilFormat)) { - _PresentParameters.AutoDepthStencilFormat=D3DFMT_UNKNOWN; + if (BitDepth == 32) { + BitDepth = 16; + _PresentParameters.BackBufferFormat = D3DFMT_R5G6B5; + if (!Find_Z_Mode(_PresentParameters.BackBufferFormat, _PresentParameters.BackBufferFormat, &_PresentParameters.AutoDepthStencilFormat)) { + _PresentParameters.AutoDepthStencilFormat = D3DFMT_UNKNOWN; } } else { - _PresentParameters.AutoDepthStencilFormat=D3DFMT_UNKNOWN; + _PresentParameters.AutoDepthStencilFormat = D3DFMT_UNKNOWN; } } - } else { + } + else { /* ** Try to find a mode that matches the user's desired bit-depth. */ - Find_Color_And_Z_Mode(ResolutionWidth,ResolutionHeight,BitDepth,&DisplayFormat, - &_PresentParameters.BackBufferFormat,&_PresentParameters.AutoDepthStencilFormat); + Find_Color_And_Z_Mode(ResolutionWidth, ResolutionHeight, BitDepth, &DisplayFormat, + &_PresentParameters.BackBufferFormat, &_PresentParameters.AutoDepthStencilFormat); } /* ** Time to actually create the device. */ - if (_PresentParameters.AutoDepthStencilFormat==D3DFMT_UNKNOWN) { - if (BitDepth==32) { - _PresentParameters.AutoDepthStencilFormat=D3DFMT_D32; + if (_PresentParameters.AutoDepthStencilFormat == D3DFMT_UNKNOWN) { + if (BitDepth == 32) { + _PresentParameters.AutoDepthStencilFormat = D3DFMT_D32; } else { - _PresentParameters.AutoDepthStencilFormat=D3DFMT_D16; + _PresentParameters.AutoDepthStencilFormat = D3DFMT_D16; } } StringClass displayFormat; StringClass backbufferFormat; - Get_Format_Name(DisplayFormat,&displayFormat); - Get_Format_Name(_PresentParameters.BackBufferFormat,&backbufferFormat); + Get_Format_Name(DisplayFormat, &displayFormat); + Get_Format_Name(_PresentParameters.BackBufferFormat, &backbufferFormat); + + WWDEBUG_SAY(("Using Display/BackBuffer Formats: %s/%s", displayFormat.str(), backbufferFormat.str())); - WWDEBUG_SAY(("Using Display/BackBuffer Formats: %s/%s",displayFormat.str(),backbufferFormat.str())); - bool ret; if (reset_device) @@ -1140,12 +1145,12 @@ bool DX8Wrapper::Toggle_Windowed(void) { #ifdef WW3D_DX8 // State OK? - assert (IsInitted); + assert(IsInitted); if (IsInitted) { // Get information about the current render device's resolutions - const RenderDeviceDescClass &render_device = Get_Render_Device_Desc (); - const DynamicVectorClass &resolutions = render_device.Enumerate_Resolutions (); + const RenderDeviceDescClass& render_device = Get_Render_Device_Desc(); + const DynamicVectorClass& resolutions = render_device.Enumerate_Resolutions(); // Loop through all the resolutions supported by the current device. // If we aren't currently running under one of these resolutions, @@ -1153,13 +1158,13 @@ bool DX8Wrapper::Toggle_Windowed(void) // toggling the windowed state. int curr_res = -1; for (int res = 0; - (res < resolutions.Count ()) && (curr_res == -1); - res ++) { + (res < resolutions.Count()) && (curr_res == -1); + res++) { // Is this the resolution we are looking for? if ((resolutions[res].Width == ResolutionWidth) && - (resolutions[res].Height == ResolutionHeight) && - (resolutions[res].BitDepth == BitDepth)) { + (resolutions[res].Height == ResolutionHeight) && + (resolutions[res].BitDepth == BitDepth)) { curr_res = res; } } @@ -1168,14 +1173,15 @@ bool DX8Wrapper::Toggle_Windowed(void) // We don't match any of the standard resolutions, // so set the first resolution and toggle the windowed state. - return Set_Device_Resolution (resolutions[0].Width, - resolutions[0].Height, - resolutions[0].BitDepth, - !IsWindowed, true); - } else { + return Set_Device_Resolution(resolutions[0].Width, + resolutions[0].Height, + resolutions[0].BitDepth, + !IsWindowed, true); + } + else { // Toggle the windowed state - return Set_Device_Resolution (-1, -1, -1, !IsWindowed, true); + return Set_Device_Resolution(-1, -1, -1, !IsWindowed, true); } } #endif //WW3D_DX8 @@ -1186,11 +1192,11 @@ bool DX8Wrapper::Toggle_Windowed(void) void DX8Wrapper::Set_Swap_Interval(int swap) { switch (swap) { - case 0: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; break; - case 1: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE ; break; - case 2: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_TWO; break; - case 3: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_THREE; break; - default: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE ; break; + case 0: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; break; + case 1: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE; break; + case 2: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_TWO; break; + case 3: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_THREE; break; + default: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE; break; } WWDEBUG_SAY(("DX8Wrapper::Set_Swap_Interval is resetting the device.")); @@ -1205,7 +1211,7 @@ int DX8Wrapper::Get_Swap_Interval(void) bool DX8Wrapper::Has_Stencil(void) { bool has_stencil = (_PresentParameters.AutoDepthStencilFormat == D3DFMT_D24S8 || - _PresentParameters.AutoDepthStencilFormat == D3DFMT_D24X4S4); + _PresentParameters.AutoDepthStencilFormat == D3DFMT_D24X4S4); return has_stencil; } @@ -1220,7 +1226,7 @@ int DX8Wrapper::Get_Render_Device(void) return CurRenderDevice; } -const RenderDeviceDescClass & DX8Wrapper::Get_Render_Device_Desc(int deviceidx) +const RenderDeviceDescClass& DX8Wrapper::Get_Render_Device_Desc(int deviceidx) { WWASSERT(IsInitted); @@ -1242,13 +1248,13 @@ const RenderDeviceDescClass & DX8Wrapper::Get_Render_Device_Desc(int deviceidx) return _RenderDeviceDescriptionTable[deviceidx]; } -const char * DX8Wrapper::Get_Render_Device_Name(int device_index) +const char* DX8Wrapper::Get_Render_Device_Name(int device_index) { device_index = device_index % _RenderDeviceShortNameTable.Count(); return _RenderDeviceShortNameTable[device_index]; } -bool DX8Wrapper::Set_Device_Resolution(int width,int height,int bits,int windowed, bool resize_window) +bool DX8Wrapper::Set_Device_Resolution(int width, int height, int bits, int windowed, bool resize_window) { if (D3DDevice != NULL) { @@ -1265,12 +1271,13 @@ bool DX8Wrapper::Set_Device_Resolution(int width,int height,int bits,int windowe #pragma message("TODO: support changing windowed status and changing the bit depth") WWDEBUG_SAY(("DX8Wrapper::Set_Device_Resolution is resetting the device.")); return Reset_Device(); - } else { + } + else { return false; } } -void DX8Wrapper::Get_Device_Resolution(int & set_w,int & set_h,int & set_bits,bool & set_windowed) +void DX8Wrapper::Get_Device_Resolution(int& set_w, int& set_h, int& set_bits, bool& set_windowed) { WWASSERT(IsInitted); @@ -1279,30 +1286,31 @@ void DX8Wrapper::Get_Device_Resolution(int & set_w,int & set_h,int & set_bits,bo set_bits = BitDepth; set_windowed = IsWindowed; - return ; + return; } -void DX8Wrapper::Get_Render_Target_Resolution(int & set_w,int & set_h,int & set_bits,bool & set_windowed) +void DX8Wrapper::Get_Render_Target_Resolution(int& set_w, int& set_h, int& set_bits, bool& set_windowed) { WWASSERT(IsInitted); if (CurrentRenderTarget != NULL) { D3DSURFACE_DESC info; - CurrentRenderTarget->GetDesc (&info); + CurrentRenderTarget->GetDesc(&info); - set_w = info.Width; - set_h = info.Height; - set_bits = BitDepth; // should we get the actual bit depth of the target? - set_windowed = IsWindowed; // this doesn't really make sense for render targets (shouldn't matter)... + set_w = info.Width; + set_h = info.Height; + set_bits = BitDepth; // should we get the actual bit depth of the target? + set_windowed = IsWindowed; // this doesn't really make sense for render targets (shouldn't matter)... - } else { - Get_Device_Resolution (set_w, set_h, set_bits, set_windowed); + } + else { + Get_Device_Resolution(set_w, set_h, set_bits, set_windowed); } - return ; + return; } -bool DX8Wrapper::Registry_Save_Render_Device( const char * sub_key ) +bool DX8Wrapper::Registry_Save_Render_Device(const char* sub_key) { int width, height, depth; bool windowed; @@ -1310,108 +1318,109 @@ bool DX8Wrapper::Registry_Save_Render_Device( const char * sub_key ) return Registry_Save_Render_Device(sub_key, CurRenderDevice, ResolutionWidth, ResolutionHeight, BitDepth, IsWindowed, TextureBitDepth); } -bool DX8Wrapper::Registry_Save_Render_Device( const char *sub_key, int device, int width, int height, int depth, bool windowed, int texture_depth) +bool DX8Wrapper::Registry_Save_Render_Device(const char* sub_key, int device, int width, int height, int depth, bool windowed, int texture_depth) { - RegistryClass * registry = W3DNEW RegistryClass( sub_key ); - WWASSERT( registry ); + RegistryClass* registry = W3DNEW RegistryClass(sub_key); + WWASSERT(registry); - if ( !registry->Is_Valid() ) { + if (!registry->Is_Valid()) { delete registry; - WWDEBUG_SAY(( "Error getting Registry" )); + WWDEBUG_SAY(("Error getting Registry")); return false; } - registry->Set_String( VALUE_NAME_RENDER_DEVICE_NAME, - _RenderDeviceShortNameTable[device] ); - registry->Set_Int( VALUE_NAME_RENDER_DEVICE_WIDTH, width ); - registry->Set_Int( VALUE_NAME_RENDER_DEVICE_HEIGHT, height ); - registry->Set_Int( VALUE_NAME_RENDER_DEVICE_DEPTH, depth ); - registry->Set_Int( VALUE_NAME_RENDER_DEVICE_WINDOWED, windowed ); - registry->Set_Int( VALUE_NAME_RENDER_DEVICE_TEXTURE_DEPTH, texture_depth ); + registry->Set_String(VALUE_NAME_RENDER_DEVICE_NAME, + _RenderDeviceShortNameTable[device]); + registry->Set_Int(VALUE_NAME_RENDER_DEVICE_WIDTH, width); + registry->Set_Int(VALUE_NAME_RENDER_DEVICE_HEIGHT, height); + registry->Set_Int(VALUE_NAME_RENDER_DEVICE_DEPTH, depth); + registry->Set_Int(VALUE_NAME_RENDER_DEVICE_WINDOWED, windowed); + registry->Set_Int(VALUE_NAME_RENDER_DEVICE_TEXTURE_DEPTH, texture_depth); delete registry; return true; } -bool DX8Wrapper::Registry_Load_Render_Device( const char * sub_key, bool resize_window ) +bool DX8Wrapper::Registry_Load_Render_Device(const char* sub_key, bool resize_window) { - char name[ 200 ]; - int width,height,depth,windowed; - - if ( Registry_Load_Render_Device( sub_key, - name, - sizeof(name), - width, - height, - depth, - windowed, - TextureBitDepth) && - (*name != 0)) + char name[200]; + int width, height, depth, windowed; + + if (Registry_Load_Render_Device(sub_key, + name, + sizeof(name), + width, + height, + depth, + windowed, + TextureBitDepth) && + (*name != 0)) { - WWDEBUG_SAY(( "Device %s (%d X %d) %d bit windowed:%d", name,width,height,depth,windowed)); + WWDEBUG_SAY(("Device %s (%d X %d) %d bit windowed:%d", name, width, height, depth, windowed)); - if (TextureBitDepth==16 || TextureBitDepth==32) { -// WWDEBUG_SAY(( "Texture depth %d", TextureBitDepth)); - } else { - WWDEBUG_SAY(( "Invalid texture depth %d, switching to 16 bits", TextureBitDepth)); - TextureBitDepth=16; + if (TextureBitDepth == 16 || TextureBitDepth == 32) { + // WWDEBUG_SAY(( "Texture depth %d", TextureBitDepth)); + } + else { + WWDEBUG_SAY(("Invalid texture depth %d, switching to 16 bits", TextureBitDepth)); + TextureBitDepth = 16; } -// _RenderDeviceDescriptionTable. + // _RenderDeviceDescriptionTable. - if ( Set_Render_Device( name, width,height,depth,windowed, resize_window ) != true) { - if (depth==16) depth=32; - else depth=16; - if ( Set_Render_Device( name, width,height,depth,windowed, resize_window ) == true) { + if (Set_Render_Device(name, width, height, depth, windowed, resize_window) != true) { + if (depth == 16) depth = 32; + else depth = 16; + if (Set_Render_Device(name, width, height, depth, windowed, resize_window) == true) { return true; } - if (depth==16) depth=32; - else depth=16; + if (depth == 16) depth = 32; + else depth = 16; // we'll test resolutions down, so if start is 640, increase to begin with... - if (width==640) { - width=1024; - height=768; + if (width == 640) { + width = 1024; + height = 768; } - for(;;) { - if (width>2048) { - width=2048; - height=1536; + for (;;) { + if (width > 2048) { + width = 2048; + height = 1536; } - else if (width>1920) { - width=1920; - height=1440; + else if (width > 1920) { + width = 1920; + height = 1440; } - else if (width>1600) { - width=1600; - height=1200; + else if (width > 1600) { + width = 1600; + height = 1200; } - else if (width>1280) { - width=1280; - height=1024; + else if (width > 1280) { + width = 1280; + height = 1024; } - else if (width>1024) { - width=1024; - height=768; + else if (width > 1024) { + width = 1024; + height = 768; } - else if (width>800) { - width=800; - height=600; + else if (width > 800) { + width = 800; + height = 600; } - else if (width!=640) { - width=640; - height=480; + else if (width != 640) { + width = 640; + height = 480; } else { return Set_Any_Render_Device(); } - for (int i=0;i<2;++i) { - if ( Set_Render_Device( name, width,height,depth,windowed, resize_window ) == true) { + for (int i = 0; i < 2; ++i) { + if (Set_Render_Device(name, width, height, depth, windowed, resize_window) == true) { return true; } - if (depth==16) depth=32; - else depth=16; + if (depth == 16) depth = 32; + else depth = 16; } } } @@ -1419,37 +1428,37 @@ bool DX8Wrapper::Registry_Load_Render_Device( const char * sub_key, bool resize_ return true; } - WWDEBUG_SAY(( "Error getting Registry" )); + WWDEBUG_SAY(("Error getting Registry")); return Set_Any_Render_Device(); } -bool DX8Wrapper::Registry_Load_Render_Device( const char * sub_key, char *device, int device_len, int &width, int &height, int &depth, int &windowed, int &texture_depth) +bool DX8Wrapper::Registry_Load_Render_Device(const char* sub_key, char* device, int device_len, int& width, int& height, int& depth, int& windowed, int& texture_depth) { - RegistryClass registry( sub_key ); + RegistryClass registry(sub_key); - if ( registry.Is_Valid() ) { - registry.Get_String( VALUE_NAME_RENDER_DEVICE_NAME, + if (registry.Is_Valid()) { + registry.Get_String(VALUE_NAME_RENDER_DEVICE_NAME, device, device_len); - width = registry.Get_Int( VALUE_NAME_RENDER_DEVICE_WIDTH, -1 ); - height = registry.Get_Int( VALUE_NAME_RENDER_DEVICE_HEIGHT, -1 ); - depth = registry.Get_Int( VALUE_NAME_RENDER_DEVICE_DEPTH, -1 ); - windowed = registry.Get_Int( VALUE_NAME_RENDER_DEVICE_WINDOWED, -1 ); - texture_depth = registry.Get_Int( VALUE_NAME_RENDER_DEVICE_TEXTURE_DEPTH, -1 ); + width = registry.Get_Int(VALUE_NAME_RENDER_DEVICE_WIDTH, -1); + height = registry.Get_Int(VALUE_NAME_RENDER_DEVICE_HEIGHT, -1); + depth = registry.Get_Int(VALUE_NAME_RENDER_DEVICE_DEPTH, -1); + windowed = registry.Get_Int(VALUE_NAME_RENDER_DEVICE_WINDOWED, -1); + texture_depth = registry.Get_Int(VALUE_NAME_RENDER_DEVICE_TEXTURE_DEPTH, -1); return true; } - *device=0; - width=-1; - height=-1; - depth=-1; - windowed=-1; - texture_depth=-1; + *device = 0; + width = -1; + height = -1; + depth = -1; + windowed = -1; + texture_depth = -1; return false; } -bool DX8Wrapper::Find_Color_And_Z_Mode(int resx,int resy,int bitdepth,D3DFORMAT * set_colorbuffer,D3DFORMAT * set_backbuffer,D3DFORMAT * set_zmode) +bool DX8Wrapper::Find_Color_And_Z_Mode(int resx, int resy, int bitdepth, D3DFORMAT* set_colorbuffer, D3DFORMAT* set_backbuffer, D3DFORMAT* set_zmode) { static D3DFORMAT _formats16[] = { @@ -1468,13 +1477,14 @@ bool DX8Wrapper::Find_Color_And_Z_Mode(int resx,int resy,int bitdepth,D3DFORMAT /* ** Select the table that we're going to use to search for a valid backbuffer format */ - D3DFORMAT * format_table = NULL; + D3DFORMAT* format_table = NULL; int format_count = 0; if (BitDepth == 16) { format_table = _formats16; format_count = sizeof(_formats16) / sizeof(D3DFORMAT); - } else { + } + else { format_table = _formats32; format_count = sizeof(_formats32) / sizeof(D3DFORMAT); } @@ -1485,19 +1495,20 @@ bool DX8Wrapper::Find_Color_And_Z_Mode(int resx,int resy,int bitdepth,D3DFORMAT bool found = false; unsigned int mode = 0; - int format_index=0; + int format_index = 0; for (; format_index < format_count; format_index++) { - found |= Find_Color_Mode(format_table[format_index],resx,resy,&mode); + found |= Find_Color_Mode(format_table[format_index], resx, resy, &mode); if (found) break; } if (!found) { return false; - } else { - *set_backbuffer=*set_colorbuffer = format_table[format_index]; + } + else { + *set_backbuffer = *set_colorbuffer = format_table[format_index]; } - if (bitdepth==32 && *set_colorbuffer == D3DFMT_X8R8G8B8 && D3DInterface->CheckDeviceType(0,D3DDEVTYPE_HAL,*set_colorbuffer,D3DFMT_A8R8G8B8, TRUE) == D3D_OK) + if (bitdepth == 32 && *set_colorbuffer == D3DFMT_X8R8G8B8 && D3DInterface->CheckDeviceType(0, D3DDEVTYPE_HAL, *set_colorbuffer, D3DFMT_A8R8G8B8, TRUE) == D3D_OK) { //promote 32-bit modes to include destination alpha when supported *set_backbuffer = D3DFMT_A8R8G8B8; } @@ -1505,34 +1516,34 @@ bool DX8Wrapper::Find_Color_And_Z_Mode(int resx,int resy,int bitdepth,D3DFORMAT /* ** We found a backbuffer format, now find a zbuffer format */ - return Find_Z_Mode(*set_colorbuffer,*set_backbuffer, set_zmode); + return Find_Z_Mode(*set_colorbuffer, *set_backbuffer, set_zmode); }; // find the resolution mode with at least resx,resy with the highest supported // refresh rate -bool DX8Wrapper::Find_Color_Mode(D3DFORMAT colorbuffer, int resx, int resy, UINT *mode) +bool DX8Wrapper::Find_Color_Mode(D3DFORMAT colorbuffer, int resx, int resy, UINT* mode) { - UINT i,j,modemax; - UINT rx,ry; + UINT i, j, modemax; + UINT rx, ry; D3DDISPLAYMODE dmode; ::ZeroMemory(&dmode, sizeof(D3DDISPLAYMODE)); - rx=(unsigned int) resx; - ry=(unsigned int) resy; + rx = (unsigned int)resx; + ry = (unsigned int)resy; - bool found=false; + bool found = false; - modemax=D3DInterface->GetAdapterModeCount(D3DADAPTER_DEFAULT); + modemax = D3DInterface->GetAdapterModeCount(D3DADAPTER_DEFAULT); - i=0; + i = 0; - while (iEnumAdapterModes(D3DADAPTER_DEFAULT, i, &dmode); - if (dmode.Width==rx && dmode.Height==ry && dmode.Format==colorbuffer) { - WWDEBUG_SAY(("Found valid color mode. Width = %d Height = %d Format = %d",dmode.Width,dmode.Height,dmode.Format)); - found=true; + if (dmode.Width == rx && dmode.Height == ry && dmode.Format == colorbuffer) { + WWDEBUG_SAY(("Found valid color mode. Width = %d Height = %d Format = %d", dmode.Width, dmode.Height, dmode.Format)); + found = true; } i++; } @@ -1546,66 +1557,66 @@ bool DX8Wrapper::Find_Color_Mode(D3DFORMAT colorbuffer, int resx, int resy, UINT } // go to the highest refresh rate in this mode - bool stillok=true; + bool stillok = true; - j=i; - while (jEnumAdapterModes(D3DADAPTER_DEFAULT, j, &dmode); - if (dmode.Width==rx && dmode.Height==ry && dmode.Format==colorbuffer) - stillok=true; else stillok=false; + if (dmode.Width == rx && dmode.Height == ry && dmode.Format == colorbuffer) + stillok = true; else stillok = false; j++; } - if (stillok==false) *mode=j-2; - else *mode=i; + if (stillok == false) *mode = j - 2; + else *mode = i; return true; } // Helper function to find a Z buffer mode for the colorbuffer // Will look for greatest Z precision -bool DX8Wrapper::Find_Z_Mode(D3DFORMAT colorbuffer,D3DFORMAT backbuffer, D3DFORMAT *zmode) +bool DX8Wrapper::Find_Z_Mode(D3DFORMAT colorbuffer, D3DFORMAT backbuffer, D3DFORMAT* zmode) { //MW: Swapped the next 2 tests so that Stencil modes get tested first. - if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D24S8)) + if (Test_Z_Mode(colorbuffer, backbuffer, D3DFMT_D24S8)) { - *zmode=D3DFMT_D24S8; + *zmode = D3DFMT_D24S8; WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D24S8")); return true; } - if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D32)) + if (Test_Z_Mode(colorbuffer, backbuffer, D3DFMT_D32)) { - *zmode=D3DFMT_D32; + *zmode = D3DFMT_D32; WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D32")); return true; } - if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D24X8)) + if (Test_Z_Mode(colorbuffer, backbuffer, D3DFMT_D24X8)) { - *zmode=D3DFMT_D24X8; + *zmode = D3DFMT_D24X8; WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D24X8")); return true; } - if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D24X4S4)) + if (Test_Z_Mode(colorbuffer, backbuffer, D3DFMT_D24X4S4)) { - *zmode=D3DFMT_D24X4S4; + *zmode = D3DFMT_D24X4S4; WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D24X4S4")); return true; } - if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D16)) + if (Test_Z_Mode(colorbuffer, backbuffer, D3DFMT_D16)) { - *zmode=D3DFMT_D16; + *zmode = D3DFMT_D16; WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D16")); return true; } - if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D15S1)) + if (Test_Z_Mode(colorbuffer, backbuffer, D3DFMT_D15S1)) { - *zmode=D3DFMT_D15S1; + *zmode = D3DFMT_D15S1; WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D15S1")); return true; } @@ -1615,21 +1626,21 @@ bool DX8Wrapper::Find_Z_Mode(D3DFORMAT colorbuffer,D3DFORMAT backbuffer, D3DFORM return false; } -bool DX8Wrapper::Test_Z_Mode(D3DFORMAT colorbuffer,D3DFORMAT backbuffer, D3DFORMAT zmode) +bool DX8Wrapper::Test_Z_Mode(D3DFORMAT colorbuffer, D3DFORMAT backbuffer, D3DFORMAT zmode) { // See if we have this mode first - if (FAILED(D3DInterface->CheckDeviceFormat(D3DADAPTER_DEFAULT,WW3D_DEVTYPE, - colorbuffer,D3DUSAGE_DEPTHSTENCIL,D3DRTYPE_SURFACE,zmode))) + if (FAILED(D3DInterface->CheckDeviceFormat(D3DADAPTER_DEFAULT, WW3D_DEVTYPE, + colorbuffer, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, zmode))) { - WWDEBUG_SAY(("CheckDeviceFormat failed. Colorbuffer format = %d Zbufferformat = %d",colorbuffer,zmode)); + WWDEBUG_SAY(("CheckDeviceFormat failed. Colorbuffer format = %d Zbufferformat = %d", colorbuffer, zmode)); return false; } // Then see if it matches the color buffer - if(FAILED(D3DInterface->CheckDepthStencilMatch(D3DADAPTER_DEFAULT, WW3D_DEVTYPE, - colorbuffer,backbuffer,zmode))) + if (FAILED(D3DInterface->CheckDepthStencilMatch(D3DADAPTER_DEFAULT, WW3D_DEVTYPE, + colorbuffer, backbuffer, zmode))) { - WWDEBUG_SAY(("CheckDepthStencilMatch failed. Colorbuffer format = %d Backbuffer format = %d Zbufferformat = %d",colorbuffer,backbuffer,zmode)); + WWDEBUG_SAY(("CheckDepthStencilMatch failed. Colorbuffer format = %d Backbuffer format = %d Zbufferformat = %d", colorbuffer, backbuffer, zmode)); return false; } return true; @@ -1638,15 +1649,15 @@ bool DX8Wrapper::Test_Z_Mode(D3DFORMAT colorbuffer,D3DFORMAT backbuffer, D3DFORM void DX8Wrapper::Reset_Statistics() { - matrix_changes = 0; + matrix_changes = 0; material_changes = 0; vertex_buffer_changes = 0; index_buffer_changes = 0; light_changes = 0; texture_changes = 0; - render_state_changes =0; - texture_stage_state_changes =0; - draw_calls =0; + render_state_changes = 0; + texture_stage_state_changes = 0; + draw_calls = 0; number_of_DX8_calls = 0; last_frame_matrix_changes = 0; @@ -1658,48 +1669,48 @@ void DX8Wrapper::Reset_Statistics() last_frame_render_state_changes = 0; last_frame_texture_stage_state_changes = 0; last_frame_number_of_DX8_calls = 0; - last_frame_draw_calls =0; + last_frame_draw_calls = 0; } void DX8Wrapper::Begin_Statistics() { - matrix_changes=0; - material_changes=0; - vertex_buffer_changes=0; - index_buffer_changes=0; - light_changes=0; + matrix_changes = 0; + material_changes = 0; + vertex_buffer_changes = 0; + index_buffer_changes = 0; + light_changes = 0; texture_changes = 0; - render_state_changes =0; - texture_stage_state_changes =0; - number_of_DX8_calls=0; - draw_calls=0; + render_state_changes = 0; + texture_stage_state_changes = 0; + number_of_DX8_calls = 0; + draw_calls = 0; } void DX8Wrapper::End_Statistics() { - last_frame_matrix_changes=matrix_changes; - last_frame_material_changes=material_changes; - last_frame_vertex_buffer_changes=vertex_buffer_changes; - last_frame_index_buffer_changes=index_buffer_changes; - last_frame_light_changes=light_changes; + last_frame_matrix_changes = matrix_changes; + last_frame_material_changes = material_changes; + last_frame_vertex_buffer_changes = vertex_buffer_changes; + last_frame_index_buffer_changes = index_buffer_changes; + last_frame_light_changes = light_changes; last_frame_texture_changes = texture_changes; last_frame_render_state_changes = render_state_changes; last_frame_texture_stage_state_changes = texture_stage_state_changes; - last_frame_number_of_DX8_calls=number_of_DX8_calls; - last_frame_draw_calls=draw_calls; + last_frame_number_of_DX8_calls = number_of_DX8_calls; + last_frame_draw_calls = draw_calls; } -unsigned DX8Wrapper::Get_Last_Frame_Matrix_Changes() { return last_frame_matrix_changes; } -unsigned DX8Wrapper::Get_Last_Frame_Material_Changes() { return last_frame_material_changes; } -unsigned DX8Wrapper::Get_Last_Frame_Vertex_Buffer_Changes() { return last_frame_vertex_buffer_changes; } -unsigned DX8Wrapper::Get_Last_Frame_Index_Buffer_Changes() { return last_frame_index_buffer_changes; } -unsigned DX8Wrapper::Get_Last_Frame_Light_Changes() { return last_frame_light_changes; } -unsigned DX8Wrapper::Get_Last_Frame_Texture_Changes() { return last_frame_texture_changes; } -unsigned DX8Wrapper::Get_Last_Frame_Render_State_Changes() { return last_frame_render_state_changes; } -unsigned DX8Wrapper::Get_Last_Frame_Texture_Stage_State_Changes() { return last_frame_texture_stage_state_changes; } -unsigned DX8Wrapper::Get_Last_Frame_DX8_Calls() { return last_frame_number_of_DX8_calls; } -unsigned DX8Wrapper::Get_Last_Frame_Draw_Calls() { return last_frame_draw_calls; } -unsigned long DX8Wrapper::Get_FrameCount(void) {return FrameCount;} +unsigned DX8Wrapper::Get_Last_Frame_Matrix_Changes() { return last_frame_matrix_changes; } +unsigned DX8Wrapper::Get_Last_Frame_Material_Changes() { return last_frame_material_changes; } +unsigned DX8Wrapper::Get_Last_Frame_Vertex_Buffer_Changes() { return last_frame_vertex_buffer_changes; } +unsigned DX8Wrapper::Get_Last_Frame_Index_Buffer_Changes() { return last_frame_index_buffer_changes; } +unsigned DX8Wrapper::Get_Last_Frame_Light_Changes() { return last_frame_light_changes; } +unsigned DX8Wrapper::Get_Last_Frame_Texture_Changes() { return last_frame_texture_changes; } +unsigned DX8Wrapper::Get_Last_Frame_Render_State_Changes() { return last_frame_render_state_changes; } +unsigned DX8Wrapper::Get_Last_Frame_Texture_Stage_State_Changes() { return last_frame_texture_stage_state_changes; } +unsigned DX8Wrapper::Get_Last_Frame_DX8_Calls() { return last_frame_number_of_DX8_calls; } +unsigned DX8Wrapper::Get_Last_Frame_Draw_Calls() { return last_frame_draw_calls; } +unsigned long DX8Wrapper::Get_FrameCount(void) { return FrameCount; } void DX8_Assert() { @@ -1714,7 +1725,7 @@ void DX8Wrapper::Begin_Scene(void) #if ENABLE_EMBEDDED_BROWSER DX8WebBrowser::Update(); #endif - + DX8CALL(BeginScene()); DX8WebBrowser::Update(); @@ -1732,7 +1743,7 @@ void DX8Wrapper::End_Scene(bool flip_frames) HRESULT hr; { WWPROFILE("DX8Device::Present()"); - hr=_Get_D3D_Device8()->Present(NULL, NULL, NULL, NULL); + hr = _Get_D3D_Device8()->Present(NULL, NULL, NULL, NULL); } number_of_DX8_calls++; @@ -1743,17 +1754,17 @@ void DX8Wrapper::End_Scene(bool flip_frames) ::Sleep(stats.m_sleepTime); } #endif - IsDeviceLost=false; + IsDeviceLost = false; FrameCount++; } else { - IsDeviceLost=true; + IsDeviceLost = true; } // If the device was lost we need to check for cooperative level and possibly reset the device - if (hr==D3DERR_DEVICELOST) { - hr=_Get_D3D_Device8()->TestCooperativeLevel(); - if (hr==D3DERR_DEVICENOTRESET) { + if (hr == D3DERR_DEVICELOST) { + hr = _Get_D3D_Device8()->TestCooperativeLevel(); + if (hr == D3DERR_DEVICENOTRESET) { WWDEBUG_SAY(("DX8Wrapper::End_Scene is resetting the device.")); Reset_Device(); } @@ -1769,8 +1780,8 @@ void DX8Wrapper::End_Scene(bool flip_frames) // Each frame, release all of the buffers and textures. Set_Vertex_Buffer(NULL); - Set_Index_Buffer(NULL,0); - for (int i=0;iGet_Max_Textures_Per_Pass();++i) Set_Texture(i,NULL); + Set_Index_Buffer(NULL, 0); + for (int i = 0; i < CurrentCaps->Get_Max_Textures_Per_Pass(); ++i) Set_Texture(i, NULL); Set_Material(NULL); } @@ -1795,28 +1806,29 @@ void DX8Wrapper::Flip_To_Primary(void) WWDEBUG_SAY(("TestCooperativeLevel Failed!")); if (D3DERR_DEVICELOST == hr) { - IsDeviceLost=true; + IsDeviceLost = true; WWDEBUG_SAY(("DEVICELOST: Cannot flip to primary.")); return; } - IsDeviceLost=false; + IsDeviceLost = false; if (D3DERR_DEVICENOTRESET == hr) { WWDEBUG_SAY(("DEVICENOTRESET")); Reset_Device(); resetAttempts++; } - } else { + } + else { WWDEBUG_SAY(("Flipping: %ld", FrameCount)); hr = _Get_D3D_Device8()->Present(NULL, NULL, NULL, NULL); if (SUCCEEDED(hr)) { - IsDeviceLost=false; + IsDeviceLost = false; FrameCount++; WWDEBUG_SAY(("Flip to primary succeeded %ld", FrameCount)); } else { - IsDeviceLost=true; + IsDeviceLost = true; } } @@ -1826,12 +1838,13 @@ void DX8Wrapper::Flip_To_Primary(void) } + //********************************************************************************************** //! Clear current render device /*! KM /* 5/17/02 KM Fixed support for render to texture with depth/stencil buffers */ -void DX8Wrapper::Clear(bool clear_color, bool clear_z_stencil, const Vector3 &color, float dest_alpha, float z, unsigned int stencil) +void DX8Wrapper::Clear(bool clear_color, bool clear_z_stencil, const Vector3& color, float dest_alpha, float z, unsigned int stencil) { DX8_THREAD_ASSERT(); @@ -1840,7 +1853,7 @@ void DX8Wrapper::Clear(bool clear_color, bool clear_z_stencil, const Vector3 &co /*bool has_stencil = ( _PresentParameters.AutoDepthStencilFormat == D3DFMT_D15S1 || _PresentParameters.AutoDepthStencilFormat == D3DFMT_D24S8 || _PresentParameters.AutoDepthStencilFormat == D3DFMT_D24X4S4);*/ - bool has_stencil=false; + bool has_stencil = false; IDirect3DSurface8* depthbuffer; _Get_D3D_Device8()->GetDepthStencilSurface(&depthbuffer); @@ -1850,12 +1863,12 @@ void DX8Wrapper::Clear(bool clear_color, bool clear_z_stencil, const Vector3 &co { D3DSURFACE_DESC desc; depthbuffer->GetDesc(&desc); - has_stencil= - ( - desc.Format==D3DFMT_D15S1 || - desc.Format==D3DFMT_D24S8 || - desc.Format==D3DFMT_D24X4S4 - ); + has_stencil = + ( + desc.Format == D3DFMT_D15S1 || + desc.Format == D3DFMT_D24S8 || + desc.Format == D3DFMT_D24X4S4 + ); // release ref depthbuffer->Release(); @@ -1867,7 +1880,7 @@ void DX8Wrapper::Clear(bool clear_color, bool clear_z_stencil, const Vector3 &co if (clear_z_stencil && has_stencil) flags |= D3DCLEAR_STENCIL; if (flags) { - DX8CALL(Clear(0, NULL, flags, Convert_Color(color,dest_alpha), z, stencil)); + DX8CALL(Clear(0, NULL, flags, Convert_Color(color, dest_alpha), z, stencil)); } } @@ -1887,20 +1900,20 @@ void DX8Wrapper::Set_Viewport(CONST D3DVIEWPORT8* pViewport) void DX8Wrapper::Set_Vertex_Buffer(const VertexBufferClass* vb, unsigned stream) { - render_state.vba_offset=0; - render_state.vba_count=0; + render_state.vba_offset = 0; + render_state.vba_count = 0; if (render_state.vertex_buffers[stream]) { render_state.vertex_buffers[stream]->Release_Engine_Ref(); } - REF_PTR_SET(render_state.vertex_buffers[stream],const_cast(vb)); + REF_PTR_SET(render_state.vertex_buffers[stream], const_cast(vb)); if (vb) { vb->Add_Engine_Ref(); - render_state.vertex_buffer_types[stream]=vb->Type(); + render_state.vertex_buffer_types[stream] = vb->Type(); } else { - render_state.vertex_buffer_types[stream]=BUFFER_TYPE_INVALID; + render_state.vertex_buffer_types[stream] = BUFFER_TYPE_INVALID; } - render_state_changed|=VERTEX_BUFFER_CHANGED; + render_state_changed |= VERTEX_BUFFER_CHANGED; } // ---------------------------------------------------------------------------- @@ -1911,22 +1924,22 @@ void DX8Wrapper::Set_Vertex_Buffer(const VertexBufferClass* vb, unsigned stream) // // ---------------------------------------------------------------------------- -void DX8Wrapper::Set_Index_Buffer(const IndexBufferClass* ib,unsigned short index_base_offset) +void DX8Wrapper::Set_Index_Buffer(const IndexBufferClass* ib, unsigned short index_base_offset) { - render_state.iba_offset=0; + render_state.iba_offset = 0; if (render_state.index_buffer) { render_state.index_buffer->Release_Engine_Ref(); } - REF_PTR_SET(render_state.index_buffer,const_cast(ib)); - render_state.index_base_offset=index_base_offset; + REF_PTR_SET(render_state.index_buffer, const_cast(ib)); + render_state.index_base_offset = index_base_offset; if (ib) { ib->Add_Engine_Ref(); - render_state.index_buffer_type=ib->Type(); + render_state.index_buffer_type = ib->Type(); } else { - render_state.index_buffer_type=BUFFER_TYPE_INVALID; + render_state.index_buffer_type = BUFFER_TYPE_INVALID; } - render_state_changed|=INDEX_BUFFER_CHANGED; + render_state_changed |= INDEX_BUFFER_CHANGED; } // ---------------------------------------------------------------------------- @@ -1938,19 +1951,19 @@ void DX8Wrapper::Set_Index_Buffer(const IndexBufferClass* ib,unsigned short inde void DX8Wrapper::Set_Vertex_Buffer(const DynamicVBAccessClass& vba_) { // Release all streams (only one stream allowed in the legacy pipeline) - for (int i=1;iRelease_Engine_Ref(); - DynamicVBAccessClass& vba=const_cast(vba_); - render_state.vertex_buffer_types[0]=vba.Get_Type(); - render_state.vba_offset=vba.VertexBufferOffset; - render_state.vba_count=vba.Get_Vertex_Count(); - REF_PTR_SET(render_state.vertex_buffers[0],vba.VertexBuffer); + DynamicVBAccessClass& vba = const_cast(vba_); + render_state.vertex_buffer_types[0] = vba.Get_Type(); + render_state.vba_offset = vba.VertexBufferOffset; + render_state.vba_count = vba.Get_Vertex_Count(); + REF_PTR_SET(render_state.vertex_buffers[0], vba.VertexBuffer); render_state.vertex_buffers[0]->Add_Engine_Ref(); - render_state_changed|=VERTEX_BUFFER_CHANGED; - render_state_changed|=INDEX_BUFFER_CHANGED; // vba_offset changes so index buffer needs to be reset as well. + render_state_changed |= VERTEX_BUFFER_CHANGED; + render_state_changed |= INDEX_BUFFER_CHANGED; // vba_offset changes so index buffer needs to be reset as well. } // ---------------------------------------------------------------------------- @@ -1959,17 +1972,17 @@ void DX8Wrapper::Set_Vertex_Buffer(const DynamicVBAccessClass& vba_) // // ---------------------------------------------------------------------------- -void DX8Wrapper::Set_Index_Buffer(const DynamicIBAccessClass& iba_,unsigned short index_base_offset) +void DX8Wrapper::Set_Index_Buffer(const DynamicIBAccessClass& iba_, unsigned short index_base_offset) { if (render_state.index_buffer) render_state.index_buffer->Release_Engine_Ref(); - DynamicIBAccessClass& iba=const_cast(iba_); - render_state.index_base_offset=index_base_offset; - render_state.index_buffer_type=iba.Get_Type(); - render_state.iba_offset=iba.IndexBufferOffset; - REF_PTR_SET(render_state.index_buffer,iba.IndexBuffer); + DynamicIBAccessClass& iba = const_cast(iba_); + render_state.index_base_offset = index_base_offset; + render_state.index_buffer_type = iba.Get_Type(); + render_state.iba_offset = iba.IndexBufferOffset; + REF_PTR_SET(render_state.index_buffer, iba.IndexBuffer); render_state.index_buffer->Add_Engine_Ref(); - render_state_changed|=INDEX_BUFFER_CHANGED; + render_state_changed |= INDEX_BUFFER_CHANGED; } // ---------------------------------------------------------------------------- @@ -1986,22 +1999,22 @@ void DX8Wrapper::Draw_Sorting_IB_VB( unsigned short min_vertex_index, unsigned short vertex_count) { - WWASSERT(render_state.vertex_buffer_types[0]==BUFFER_TYPE_SORTING || render_state.vertex_buffer_types[0]==BUFFER_TYPE_DYNAMIC_SORTING); - WWASSERT(render_state.index_buffer_type==BUFFER_TYPE_SORTING || render_state.index_buffer_type==BUFFER_TYPE_DYNAMIC_SORTING); + WWASSERT(render_state.vertex_buffer_types[0] == BUFFER_TYPE_SORTING || render_state.vertex_buffer_types[0] == BUFFER_TYPE_DYNAMIC_SORTING); + WWASSERT(render_state.index_buffer_type == BUFFER_TYPE_SORTING || render_state.index_buffer_type == BUFFER_TYPE_DYNAMIC_SORTING); // Fill dynamic vertex buffer with sorting vertex buffer vertices - DynamicVBAccessClass dyn_vb_access(BUFFER_TYPE_DYNAMIC_DX8,dynamic_fvf_type,vertex_count); + DynamicVBAccessClass dyn_vb_access(BUFFER_TYPE_DYNAMIC_DX8, dynamic_fvf_type, vertex_count); { DynamicVBAccessClass::WriteLockClass lock(&dyn_vb_access); VertexFormatXYZNDUV2* src = static_cast(render_state.vertex_buffers[0])->VertexBuffer; - VertexFormatXYZNDUV2* dest= lock.Get_Formatted_Vertex_Array(); + VertexFormatXYZNDUV2* dest = lock.Get_Formatted_Vertex_Array(); src += render_state.vba_offset + render_state.index_base_offset + min_vertex_index; - unsigned size = dyn_vb_access.FVF_Info().Get_FVF_Size()*vertex_count/sizeof(unsigned); - unsigned *dest_u =(unsigned*) dest; - unsigned *src_u = (unsigned*) src; + unsigned size = dyn_vb_access.FVF_Info().Get_FVF_Size() * vertex_count / sizeof(unsigned); + unsigned* dest_u = (unsigned*)dest; + unsigned* src_u = (unsigned*)src; - for (unsigned i=0;i(dyn_vb_access.VertexBuffer)->Get_DX8_Vertex_Buffer(), dyn_vb_access.FVF_Info().Get_FVF_Size())); // If using FVF format VB, set the FVF as vertex shader (may not be needed here KM) - unsigned fvf=dyn_vb_access.FVF_Info().Get_FVF(); - if (fvf!=0) { + unsigned fvf = dyn_vb_access.FVF_Info().Get_FVF(); + if (fvf != 0) { DX8CALL(SetVertexShader(fvf)); } DX8_RECORD_VERTEX_BUFFER_CHANGE(); - unsigned index_count=0; + unsigned index_count = 0; switch (primitive_type) { - case D3DPT_TRIANGLELIST: index_count=polygon_count*3; break; - case D3DPT_TRIANGLESTRIP: index_count=polygon_count+2; break; - case D3DPT_TRIANGLEFAN: index_count=polygon_count+2; break; + case D3DPT_TRIANGLELIST: index_count = polygon_count * 3; break; + case D3DPT_TRIANGLESTRIP: index_count = polygon_count + 2; break; + case D3DPT_TRIANGLEFAN: index_count = polygon_count + 2; break; default: WWASSERT(0); break; // Unsupported primitive type } // Fill dynamic index buffer with sorting index buffer vertices - DynamicIBAccessClass dyn_ib_access(BUFFER_TYPE_DYNAMIC_DX8,index_count); + DynamicIBAccessClass dyn_ib_access(BUFFER_TYPE_DYNAMIC_DX8, index_count); { DynamicIBAccessClass::WriteLockClass lock(&dyn_ib_access); - unsigned short* dest=lock.Get_Index_Array(); - unsigned short* src=NULL; - src=static_cast(render_state.index_buffer)->index_buffer; - src+=render_state.iba_offset+start_index; - - for (unsigned short i=0;i(render_state.index_buffer)->index_buffer; + src += render_state.iba_offset + start_index; + + for (unsigned short i = 0; i < index_count; ++i) { + unsigned short index = *src++; + index -= min_vertex_index; + WWASSERT(index < vertex_count); + *dest++ = index; } } @@ -2054,7 +2067,7 @@ void DX8Wrapper::Draw_Sorting_IB_VB( dyn_ib_access.IndexBufferOffset, polygon_count)); - DX8_RECORD_RENDER(polygon_count,vertex_count,render_state.shader); + DX8_RECORD_RENDER(polygon_count, vertex_count, render_state.shader); } // ---------------------------------------------------------------------------- @@ -2070,7 +2083,7 @@ void DX8Wrapper::Draw( unsigned short min_vertex_index, unsigned short vertex_count) { - if (DrawPolygonLowBoundLimit && DrawPolygonLowBoundLimit>=polygon_count) return; + if (DrawPolygonLowBoundLimit && DrawPolygonLowBoundLimit >= polygon_count) return; DX8_THREAD_ASSERT(); SNAPSHOT_SAY(("DX8 - draw")); @@ -2082,9 +2095,9 @@ void DX8Wrapper::Draw( #ifdef MESH_RENDER_SNAPSHOT_ENABLED if (WW3D::Is_Snapshot_Activated()) { - unsigned long passes=0; + unsigned long passes = 0; SNAPSHOT_SAY(("ValidateDevice:")); - HRESULT res=D3DDevice->ValidateDevice(&passes); + HRESULT res = D3DDevice->ValidateDevice(&passes); switch (res) { case D3D_OK: SNAPSHOT_SAY(("OK")); @@ -2131,18 +2144,18 @@ void DX8Wrapper::Draw( #endif // MESH_RENDER_SHAPSHOT_ENABLED - SNAPSHOT_SAY(("DX8 - draw %d polygons (%d vertices)",polygon_count,vertex_count)); + SNAPSHOT_SAY(("DX8 - draw %d polygons (%d vertices)", polygon_count, vertex_count)); - if (vertex_count<3) { - min_vertex_index=0; + if (vertex_count < 3) { + min_vertex_index = 0; switch (render_state.vertex_buffer_types[0]) { case BUFFER_TYPE_DX8: case BUFFER_TYPE_SORTING: - vertex_count=render_state.vertex_buffers[0]->Get_Vertex_Count()-render_state.index_base_offset-render_state.vba_offset-min_vertex_index; + vertex_count = render_state.vertex_buffers[0]->Get_Vertex_Count() - render_state.index_base_offset - render_state.vba_offset - min_vertex_index; break; case BUFFER_TYPE_DYNAMIC_DX8: case BUFFER_TYPE_DYNAMIC_SORTING: - vertex_count=render_state.vba_count; + vertex_count = render_state.vba_count; break; } } @@ -2153,25 +2166,25 @@ void DX8Wrapper::Draw( switch (render_state.index_buffer_type) { case BUFFER_TYPE_DX8: case BUFFER_TYPE_DYNAMIC_DX8: - { -/* if ((start_index+render_state.iba_offset+polygon_count*3) > render_state.index_buffer->Get_Index_Count()) - { WWASSERT_PRINT(0,"OVERFLOWING INDEX BUFFER"); - ///@todo: MUST FIND OUT WHY THIS HAPPENS WITH LOTS OF PARTICLES ON BIG FIGHT! -MW - break; - }*/ - DX8_RECORD_RENDER(polygon_count,vertex_count,render_state.shader); - DX8_RECORD_DRAW_CALLS(); - DX8CALL(DrawIndexedPrimitive( - (D3DPRIMITIVETYPE)primitive_type, - min_vertex_index, - vertex_count, - start_index+render_state.iba_offset, - polygon_count)); - } - break; + { + /* if ((start_index+render_state.iba_offset+polygon_count*3) > render_state.index_buffer->Get_Index_Count()) + { WWASSERT_PRINT(0,"OVERFLOWING INDEX BUFFER"); + ///@todo: MUST FIND OUT WHY THIS HAPPENS WITH LOTS OF PARTICLES ON BIG FIGHT! -MW + break; + }*/ + DX8_RECORD_RENDER(polygon_count, vertex_count, render_state.shader); + DX8_RECORD_DRAW_CALLS(); + DX8CALL(DrawIndexedPrimitive( + (D3DPRIMITIVETYPE)primitive_type, + min_vertex_index, + vertex_count, + start_index + render_state.iba_offset, + polygon_count)); + } + break; case BUFFER_TYPE_SORTING: case BUFFER_TYPE_DYNAMIC_SORTING: - WWASSERT_PRINT(0,"VB and IB must of same type (sorting or dx8)"); + WWASSERT_PRINT(0, "VB and IB must of same type (sorting or dx8)"); break; case BUFFER_TYPE_INVALID: WWASSERT(0); @@ -2183,11 +2196,11 @@ void DX8Wrapper::Draw( switch (render_state.index_buffer_type) { case BUFFER_TYPE_DX8: case BUFFER_TYPE_DYNAMIC_DX8: - WWASSERT_PRINT(0,"VB and IB must of same type (sorting or dx8)"); + WWASSERT_PRINT(0, "VB and IB must of same type (sorting or dx8)"); break; case BUFFER_TYPE_SORTING: case BUFFER_TYPE_DYNAMIC_SORTING: - Draw_Sorting_IB_VB(primitive_type,start_index,polygon_count,min_vertex_index,vertex_count); + Draw_Sorting_IB_VB(primitive_type, start_index, polygon_count, min_vertex_index, vertex_count); break; case BUFFER_TYPE_INVALID: WWASSERT(0); @@ -2213,11 +2226,11 @@ void DX8Wrapper::Draw_Triangles( unsigned short min_vertex_index, unsigned short vertex_count) { - if (buffer_type==BUFFER_TYPE_SORTING || buffer_type==BUFFER_TYPE_DYNAMIC_SORTING) { - SortingRendererClass::Insert_Triangles(start_index,polygon_count,min_vertex_index,vertex_count); + if (buffer_type == BUFFER_TYPE_SORTING || buffer_type == BUFFER_TYPE_DYNAMIC_SORTING) { + SortingRendererClass::Insert_Triangles(start_index, polygon_count, min_vertex_index, vertex_count); } else { - Draw(D3DPT_TRIANGLELIST,start_index,polygon_count,min_vertex_index,vertex_count); + Draw(D3DPT_TRIANGLELIST, start_index, polygon_count, min_vertex_index, vertex_count); } } @@ -2233,7 +2246,7 @@ void DX8Wrapper::Draw_Triangles( unsigned short min_vertex_index, unsigned short vertex_count) { - Draw(D3DPT_TRIANGLELIST,start_index,polygon_count,min_vertex_index,vertex_count); + Draw(D3DPT_TRIANGLELIST, start_index, polygon_count, min_vertex_index, vertex_count); } // ---------------------------------------------------------------------------- @@ -2248,9 +2261,11 @@ void DX8Wrapper::Draw_Strip( unsigned short min_vertex_index, unsigned short vertex_count) { - Draw(D3DPT_TRIANGLESTRIP,start_index,polygon_count,min_vertex_index,vertex_count); + Draw(D3DPT_TRIANGLESTRIP, start_index, polygon_count, min_vertex_index, vertex_count); } + + // ---------------------------------------------------------------------------- // // @@ -2260,88 +2275,88 @@ void DX8Wrapper::Draw_Strip( void DX8Wrapper::Apply_Render_State_Changes() { SNAPSHOT_SAY(("DX8Wrapper::Apply_Render_State_Changes()")); - + if (!render_state_changed) return; - if (render_state_changed&SHADER_CHANGED) { + if (render_state_changed & SHADER_CHANGED) { SNAPSHOT_SAY(("DX8 - apply shader")); render_state.shader.Apply(); } - unsigned mask=TEXTURE0_CHANGED; - int i=0; - for (;iGet_Max_Textures_Per_Pass();++i,mask<<=1) + unsigned mask = TEXTURE0_CHANGED; + int i = 0; + for (; i < CurrentCaps->Get_Max_Textures_Per_Pass(); ++i, mask <<= 1) { - if (render_state_changed&mask) + if (render_state_changed & mask) { - SNAPSHOT_SAY(("DX8 - apply texture %d (%s)",i,render_state.Textures[i] ? render_state.Textures[i]->Get_Full_Path().str() : "NULL")); + SNAPSHOT_SAY(("DX8 - apply texture %d (%s)", i, render_state.Textures[i] ? render_state.Textures[i]->Get_Full_Path().str() : "NULL")); - if (render_state.Textures[i]) + if (render_state.Textures[i]) { render_state.Textures[i]->Apply(i); } - else + else { TextureBaseClass::Apply_Null(i); } } } - if (render_state_changed&MATERIAL_CHANGED) + if (render_state_changed & MATERIAL_CHANGED) { SNAPSHOT_SAY(("DX8 - apply material")); - VertexMaterialClass* material=const_cast(render_state.material); - if (material) + VertexMaterialClass* material = const_cast(render_state.material); + if (material) { material->Apply(); } else VertexMaterialClass::Apply_Null(); } - if (render_state_changed&LIGHTS_CHANGED) + if (render_state_changed & LIGHTS_CHANGED) { - unsigned mask=LIGHT0_CHANGED; - for (unsigned index=0;index<4;++index,mask<<=1) { - if (render_state_changed&mask) { - SNAPSHOT_SAY(("DX8 - apply light %d",index)); + unsigned mask = LIGHT0_CHANGED; + for (unsigned index = 0; index < 4; ++index, mask <<= 1) { + if (render_state_changed & mask) { + SNAPSHOT_SAY(("DX8 - apply light %d", index)); if (render_state.LightEnable[index]) { #ifdef MESH_RENDER_SNAPSHOT_ENABLED - if ( WW3D::Is_Snapshot_Activated() ) { - D3DLIGHT8 * light = &(render_state.Lights[index]); - static const char * _light_types[] = { "Unknown", "Point","Spot", "Directional" }; - WWASSERT((light->Type >= 0) && (light->Type <= 3)); + if (WW3D::Is_Snapshot_Activated()) { + D3DLIGHT8* light = &(render_state.Lights[index]); + static const char* _light_types[] = { "Unknown", "Point","Spot", "Directional" }; + WWASSERT((light->Type >= 0) && (light->Type <= 3)); SNAPSHOT_SAY((" type = %s amb = %4.2f,%4.2f,%4.2f diff = %4.2f,%4.2f,%4.2f spec = %4.2f, %4.2f, %4.2f", _light_types[light->Type], - light->Ambient.r,light->Ambient.g,light->Ambient.b, - light->Diffuse.r,light->Diffuse.g,light->Diffuse.b, - light->Specular.r,light->Specular.g,light->Specular.b )); + light->Ambient.r, light->Ambient.g, light->Ambient.b, + light->Diffuse.r, light->Diffuse.g, light->Diffuse.b, + light->Specular.r, light->Specular.g, light->Specular.b)); SNAPSHOT_SAY((" pos = %f, %f, %f dir = %f, %f, %f", light->Position.x, light->Position.y, light->Position.z, - light->Direction.x, light->Direction.y, light->Direction.z )); + light->Direction.x, light->Direction.y, light->Direction.z)); } #endif - Set_DX8_Light(index,&render_state.Lights[index]); + Set_DX8_Light(index, &render_state.Lights[index]); } else { - Set_DX8_Light(index,NULL); + Set_DX8_Light(index, NULL); SNAPSHOT_SAY((" clearing light to NULL")); } } } } - if (render_state_changed&WORLD_CHANGED) { + if (render_state_changed & WORLD_CHANGED) { SNAPSHOT_SAY(("DX8 - apply world matrix")); - _Set_DX8_Transform(D3DTS_WORLD,render_state.world); + _Set_DX8_Transform(D3DTS_WORLD, render_state.world); } - if (render_state_changed&VIEW_CHANGED) { + if (render_state_changed & VIEW_CHANGED) { SNAPSHOT_SAY(("DX8 - apply view matrix")); - _Set_DX8_Transform(D3DTS_VIEW,render_state.view); + _Set_DX8_Transform(D3DTS_VIEW, render_state.view); } - if (render_state_changed&VERTEX_BUFFER_CHANGED) { + if (render_state_changed & VERTEX_BUFFER_CHANGED) { SNAPSHOT_SAY(("DX8 - apply vb change")); - for (i=0;iType()) { case BUFFER_TYPE_DX8: @@ -2353,8 +2368,8 @@ void DX8Wrapper::Apply_Render_State_Changes() DX8_RECORD_VERTEX_BUFFER_CHANGE(); { // If the VB format is FVF, set the FVF as a vertex shader - unsigned fvf=render_state.vertex_buffers[i]->FVF_Info().Get_FVF(); - if (fvf!=0) { + unsigned fvf = render_state.vertex_buffers[i]->FVF_Info().Get_FVF(); + if (fvf != 0) { Set_Vertex_Shader(fvf); } } @@ -2365,13 +2380,14 @@ void DX8Wrapper::Apply_Render_State_Changes() default: WWASSERT(0); } - } else { - DX8CALL(SetStreamSource(i,NULL,0)); + } + else { + DX8CALL(SetStreamSource(i, NULL, 0)); DX8_RECORD_VERTEX_BUFFER_CHANGE(); } } } - if (render_state_changed&INDEX_BUFFER_CHANGED) { + if (render_state_changed & INDEX_BUFFER_CHANGED) { SNAPSHOT_SAY(("DX8 - apply ib change")); if (render_state.index_buffer) { switch (render_state.index_buffer_type) {//->Type()) { @@ -2379,7 +2395,7 @@ void DX8Wrapper::Apply_Render_State_Changes() case BUFFER_TYPE_DYNAMIC_DX8: DX8CALL(SetIndices( static_cast(render_state.index_buffer)->Get_DX8_Index_Buffer(), - render_state.index_base_offset+render_state.vba_offset)); + render_state.index_base_offset + render_state.vba_offset)); DX8_RECORD_INDEX_BUFFER_CHANGE(); break; case BUFFER_TYPE_SORTING: @@ -2397,12 +2413,12 @@ void DX8Wrapper::Apply_Render_State_Changes() } } - render_state_changed&=((unsigned)WORLD_IDENTITY|(unsigned)VIEW_IDENTITY); + render_state_changed &= ((unsigned)WORLD_IDENTITY | (unsigned)VIEW_IDENTITY); SNAPSHOT_SAY(("DX8Wrapper::Apply_Render_State_Changes() - finished")); } -IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture +IDirect3DTexture8* DX8Wrapper::_Create_DX8_Texture ( unsigned int width, unsigned int height, @@ -2414,10 +2430,10 @@ IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture { DX8_THREAD_ASSERT(); DX8_Assert(); - IDirect3DTexture8 *texture = NULL; + IDirect3DTexture8* texture = NULL; // Paletted textures not supported! - WWASSERT(format!=D3DFMT_P8); + WWASSERT(format != D3DFMT_P8); // NOTE: If 'format' is not supported as a texture format, this function will find the closest // format that is supported and use that instead. @@ -2425,7 +2441,7 @@ IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture // Render target may return NOTAVAILABLE, in // which case we return NULL. if (rendertarget) { - unsigned ret=D3DXCreateTexture( + unsigned ret = D3DXCreateTexture( DX8Wrapper::_Get_D3D_Device8(), width, height, @@ -2435,13 +2451,13 @@ IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture pool, &texture); - if (ret==D3DERR_NOTAVAILABLE) { - Non_Fatal_Log_DX8_ErrorCode(ret,__FILE__,__LINE__); + if (ret == D3DERR_NOTAVAILABLE) { + Non_Fatal_Log_DX8_ErrorCode(ret, __FILE__, __LINE__); return NULL; } // If ran out of texture ram, try invalidating some textures and mesh cache. - if (ret==D3DERR_OUTOFVIDEOMEMORY) { + if (ret == D3DERR_OUTOFVIDEOMEMORY) { WWDEBUG_SAY(("Error: Out of memory while creating render target. Trying to release assets...")); // Free all textures that haven't been used in the last 5 seconds TextureClass::Invalidate_Old_Unused_Textures(5000); @@ -2449,7 +2465,7 @@ IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture // Invalidate the mesh cache WW3D::_Invalidate_Mesh_Cache(); - ret=D3DXCreateTexture( + ret = D3DXCreateTexture( DX8Wrapper::_Get_D3D_Device8(), width, height, @@ -2465,8 +2481,8 @@ IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture else { WWDEBUG_SAY(("...Render target creation failed.")); } - if (ret==D3DERR_OUTOFVIDEOMEMORY) { - Non_Fatal_Log_DX8_ErrorCode(ret,__FILE__,__LINE__); + if (ret == D3DERR_OUTOFVIDEOMEMORY) { + Non_Fatal_Log_DX8_ErrorCode(ret, __FILE__, __LINE__); return NULL; } } @@ -2480,7 +2496,7 @@ IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture // We should never run out of video memory when allocating a non-rendertarget texture. // However, it seems to happen sometimes when there are a lot of textures in memory and so // if it happens we'll release assets and try again (anything is better than crashing). - unsigned ret=D3DXCreateTexture( + unsigned ret = D3DXCreateTexture( DX8Wrapper::_Get_D3D_Device8(), width, height, @@ -2491,7 +2507,7 @@ IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture &texture); // If ran out of texture ram, try invalidating some textures and mesh cache. - if (ret==D3DERR_OUTOFVIDEOMEMORY) { + if (ret == D3DERR_OUTOFVIDEOMEMORY) { WWDEBUG_SAY(("Error: Out of memory while creating texture. Trying to release assets...")); // Free all textures that haven't been used in the last 5 seconds TextureClass::Invalidate_Old_Unused_Textures(5000); @@ -2499,7 +2515,7 @@ IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture // Invalidate the mesh cache WW3D::_Invalidate_Mesh_Cache(); - ret=D3DXCreateTexture( + ret = D3DXCreateTexture( DX8Wrapper::_Get_D3D_Device8(), width, height, @@ -2512,9 +2528,9 @@ IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture WWDEBUG_SAY(("...Texture creation succesful.")); } else { - StringClass format_name(0,true); + StringClass format_name(0, true); Get_WW3D_Format_Name(format, format_name); - WWDEBUG_SAY(("...Texture creation failed. (%d x %d, format: %s, mips: %d",width,height,format_name.str(),mip_level_count)); + WWDEBUG_SAY(("...Texture creation failed. (%d x %d, format: %s, mips: %d", width, height, format_name.str(), mip_level_count)); } } @@ -2523,15 +2539,15 @@ IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture return texture; } -IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture +IDirect3DTexture8* DX8Wrapper::_Create_DX8_Texture ( - const char *filename, + const char* filename, MipCountType mip_level_count ) { DX8_THREAD_ASSERT(); DX8_Assert(); - IDirect3DTexture8 *texture = NULL; + IDirect3DTexture8* texture = NULL; // NOTE: If the original image format is not supported as a texture format, it will // automatically be converted to an appropriate format. @@ -2560,23 +2576,23 @@ IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture // Make sure texture wasn't paletted! D3DSURFACE_DESC desc; - texture->GetLevelDesc(0,&desc); - if (desc.Format==D3DFMT_P8) { + texture->GetLevelDesc(0, &desc); + if (desc.Format == D3DFMT_P8) { texture->Release(); return MissingTexture::_Get_Missing_Texture(); } return texture; } -IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture +IDirect3DTexture8* DX8Wrapper::_Create_DX8_Texture ( - IDirect3DSurface8 *surface, + IDirect3DSurface8* surface, MipCountType mip_level_count ) { DX8_THREAD_ASSERT(); DX8_Assert(); - IDirect3DTexture8 *texture = NULL; + IDirect3DTexture8* texture = NULL; D3DSURFACE_DESC surface_desc; ::ZeroMemory(&surface_desc, sizeof(D3DSURFACE_DESC)); @@ -2584,17 +2600,17 @@ IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture // This function will create a texture with a different (but similar) format if the surface is // not in a supported texture format. - WW3DFormat format=D3DFormat_To_WW3DFormat(surface_desc.Format); + WW3DFormat format = D3DFormat_To_WW3DFormat(surface_desc.Format); texture = _Create_DX8_Texture(surface_desc.Width, surface_desc.Height, format, mip_level_count); // Copy the surface to the texture - IDirect3DSurface8 *tex_surface = NULL; + IDirect3DSurface8* tex_surface = NULL; texture->GetSurfaceLevel(0, &tex_surface); DX8_ErrorCode(D3DXLoadSurfaceFromSurface(tex_surface, NULL, NULL, surface, NULL, NULL, D3DX_FILTER_BOX, 0)); tex_surface->Release(); // Create mipmaps if needed - if (mip_level_count!=MIP_LEVELS_1) + if (mip_level_count != MIP_LEVELS_1) { DX8_ErrorCode(D3DXFilterTexture(texture, NULL, 0, D3DX_FILTER_BOX)); } @@ -2606,7 +2622,7 @@ IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture /*! * KJM create depth stencil texture */ -IDirect3DTexture8 * DX8Wrapper::_Create_DX8_ZTexture +IDirect3DTexture8* DX8Wrapper::_Create_DX8_ZTexture ( unsigned int width, unsigned int height, @@ -2619,27 +2635,27 @@ IDirect3DTexture8 * DX8Wrapper::_Create_DX8_ZTexture DX8_Assert(); IDirect3DTexture8* texture = NULL; - D3DFORMAT zfmt=WW3DZFormat_To_D3DFormat(zformat); + D3DFORMAT zfmt = WW3DZFormat_To_D3DFormat(zformat); - unsigned ret=DX8Wrapper::_Get_D3D_Device8()->CreateTexture + unsigned ret = DX8Wrapper::_Get_D3D_Device8()->CreateTexture ( width, height, mip_level_count, - D3DUSAGE_DEPTHSTENCIL, - zfmt, + D3DUSAGE_DEPTHSTENCIL, + zfmt, pool, &texture ); - if (ret==D3DERR_NOTAVAILABLE) + if (ret == D3DERR_NOTAVAILABLE) { - Non_Fatal_Log_DX8_ErrorCode(ret,__FILE__,__LINE__); + Non_Fatal_Log_DX8_ErrorCode(ret, __FILE__, __LINE__); return NULL; } // If ran out of texture ram, try invalidating some textures and mesh cache. - if (ret==D3DERR_OUTOFVIDEOMEMORY) + if (ret == D3DERR_OUTOFVIDEOMEMORY) { WWDEBUG_SAY(("Error: Out of memory while creating render target. Trying to release assets...")); // Free all textures that haven't been used in the last 5 seconds @@ -2648,28 +2664,28 @@ IDirect3DTexture8 * DX8Wrapper::_Create_DX8_ZTexture // Invalidate the mesh cache WW3D::_Invalidate_Mesh_Cache(); - ret=DX8Wrapper::_Get_D3D_Device8()->CreateTexture + ret = DX8Wrapper::_Get_D3D_Device8()->CreateTexture ( width, height, mip_level_count, - D3DUSAGE_DEPTHSTENCIL, - zfmt, + D3DUSAGE_DEPTHSTENCIL, + zfmt, pool, &texture ); - if (SUCCEEDED(ret)) + if (SUCCEEDED(ret)) { WWDEBUG_SAY(("...Render target creation succesful.")); } - else + else { WWDEBUG_SAY(("...Render target creation failed.")); } - if (ret==D3DERR_OUTOFVIDEOMEMORY) + if (ret == D3DERR_OUTOFVIDEOMEMORY) { - Non_Fatal_Log_DX8_ErrorCode(ret,__FILE__,__LINE__); + Non_Fatal_Log_DX8_ErrorCode(ret, __FILE__, __LINE__); return NULL; } } @@ -2697,22 +2713,22 @@ IDirect3DCubeTexture8* DX8Wrapper::_Create_DX8_Cube_Texture bool rendertarget ) { - WWASSERT(width==height); + WWASSERT(width == height); DX8_THREAD_ASSERT(); DX8_Assert(); - IDirect3DCubeTexture8* texture=NULL; + IDirect3DCubeTexture8* texture = NULL; // Paletted textures not supported! - WWASSERT(format!=D3DFMT_P8); + WWASSERT(format != D3DFMT_P8); // NOTE: If 'format' is not supported as a texture format, this function will find the closest // format that is supported and use that instead. // Render target may return NOTAVAILABLE, in // which case we return NULL. - if (rendertarget) + if (rendertarget) { - unsigned ret=D3DXCreateCubeTexture + unsigned ret = D3DXCreateCubeTexture ( DX8Wrapper::_Get_D3D_Device8(), width, @@ -2723,14 +2739,14 @@ IDirect3DCubeTexture8* DX8Wrapper::_Create_DX8_Cube_Texture &texture ); - if (ret==D3DERR_NOTAVAILABLE) + if (ret == D3DERR_NOTAVAILABLE) { - Non_Fatal_Log_DX8_ErrorCode(ret,__FILE__,__LINE__); + Non_Fatal_Log_DX8_ErrorCode(ret, __FILE__, __LINE__); return NULL; } // If ran out of texture ram, try invalidating some textures and mesh cache. - if (ret==D3DERR_OUTOFVIDEOMEMORY) + if (ret == D3DERR_OUTOFVIDEOMEMORY) { WWDEBUG_SAY(("Error: Out of memory while creating render target. Trying to release assets...")); // Free all textures that haven't been used in the last 5 seconds @@ -2739,7 +2755,7 @@ IDirect3DCubeTexture8* DX8Wrapper::_Create_DX8_Cube_Texture // Invalidate the mesh cache WW3D::_Invalidate_Mesh_Cache(); - ret=D3DXCreateCubeTexture + ret = D3DXCreateCubeTexture ( DX8Wrapper::_Get_D3D_Device8(), width, @@ -2754,13 +2770,13 @@ IDirect3DCubeTexture8* DX8Wrapper::_Create_DX8_Cube_Texture { WWDEBUG_SAY(("...Render target creation succesful.")); } - else + else { WWDEBUG_SAY(("...Render target creation failed.")); } - if (ret==D3DERR_OUTOFVIDEOMEMORY) + if (ret == D3DERR_OUTOFVIDEOMEMORY) { - Non_Fatal_Log_DX8_ErrorCode(ret,__FILE__,__LINE__); + Non_Fatal_Log_DX8_ErrorCode(ret, __FILE__, __LINE__); return NULL; } } @@ -2774,7 +2790,7 @@ IDirect3DCubeTexture8* DX8Wrapper::_Create_DX8_Cube_Texture // We should never run out of video memory when allocating a non-rendertarget texture. // However, it seems to happen sometimes when there are a lot of textures in memory and so // if it happens we'll release assets and try again (anything is better than crashing). - unsigned ret=D3DXCreateCubeTexture + unsigned ret = D3DXCreateCubeTexture ( DX8Wrapper::_Get_D3D_Device8(), width, @@ -2786,7 +2802,7 @@ IDirect3DCubeTexture8* DX8Wrapper::_Create_DX8_Cube_Texture ); // If ran out of texture ram, try invalidating some textures and mesh cache. - if (ret==D3DERR_OUTOFVIDEOMEMORY) + if (ret == D3DERR_OUTOFVIDEOMEMORY) { WWDEBUG_SAY(("Error: Out of memory while creating texture. Trying to release assets...")); // Free all textures that haven't been used in the last 5 seconds @@ -2795,7 +2811,7 @@ IDirect3DCubeTexture8* DX8Wrapper::_Create_DX8_Cube_Texture // Invalidate the mesh cache WW3D::_Invalidate_Mesh_Cache(); - ret=D3DXCreateCubeTexture + ret = D3DXCreateCubeTexture ( DX8Wrapper::_Get_D3D_Device8(), width, @@ -2805,15 +2821,15 @@ IDirect3DCubeTexture8* DX8Wrapper::_Create_DX8_Cube_Texture pool, &texture ); - if (SUCCEEDED(ret)) + if (SUCCEEDED(ret)) { WWDEBUG_SAY(("...Texture creation succesful.")); } - else + else { - StringClass format_name(0,true); + StringClass format_name(0, true); Get_WW3D_Format_Name(format, format_name); - WWDEBUG_SAY(("...Texture creation failed. (%d x %d, format: %s, mips: %d",width,height,format_name.str(),mip_level_count)); + WWDEBUG_SAY(("...Texture creation failed. (%d x %d, format: %s, mips: %d", width, height, format_name.str(), mip_level_count)); } } @@ -2837,10 +2853,10 @@ IDirect3DVolumeTexture8* DX8Wrapper::_Create_DX8_Volume_Texture { DX8_THREAD_ASSERT(); DX8_Assert(); - IDirect3DVolumeTexture8* texture=NULL; + IDirect3DVolumeTexture8* texture = NULL; // Paletted textures not supported! - WWASSERT(format!=D3DFMT_P8); + WWASSERT(format != D3DFMT_P8); // NOTE: If 'format' is not supported as a texture format, this function will find the closest // format that is supported and use that instead. @@ -2849,7 +2865,7 @@ IDirect3DVolumeTexture8* DX8Wrapper::_Create_DX8_Volume_Texture // We should never run out of video memory when allocating a non-rendertarget texture. // However, it seems to happen sometimes when there are a lot of textures in memory and so // if it happens we'll release assets and try again (anything is better than crashing). - unsigned ret=D3DXCreateVolumeTexture + unsigned ret = D3DXCreateVolumeTexture ( DX8Wrapper::_Get_D3D_Device8(), width, @@ -2863,7 +2879,7 @@ IDirect3DVolumeTexture8* DX8Wrapper::_Create_DX8_Volume_Texture ); // If ran out of texture ram, try invalidating some textures and mesh cache. - if (ret==D3DERR_OUTOFVIDEOMEMORY) + if (ret == D3DERR_OUTOFVIDEOMEMORY) { WWDEBUG_SAY(("Error: Out of memory while creating texture. Trying to release assets...")); // Free all textures that haven't been used in the last 5 seconds @@ -2872,7 +2888,7 @@ IDirect3DVolumeTexture8* DX8Wrapper::_Create_DX8_Volume_Texture // Invalidate the mesh cache WW3D::_Invalidate_Mesh_Cache(); - ret=D3DXCreateVolumeTexture + ret = D3DXCreateVolumeTexture ( DX8Wrapper::_Get_D3D_Device8(), width, @@ -2884,15 +2900,15 @@ IDirect3DVolumeTexture8* DX8Wrapper::_Create_DX8_Volume_Texture pool, &texture ); - if (SUCCEEDED(ret)) + if (SUCCEEDED(ret)) { WWDEBUG_SAY(("...Texture creation succesful.")); } - else + else { - StringClass format_name(0,true); + StringClass format_name(0, true); Get_WW3D_Format_Name(format, format_name); - WWDEBUG_SAY(("...Texture creation failed. (%d x %d, format: %s, mips: %d",width,height,format_name.str(),mip_level_count)); + WWDEBUG_SAY(("...Texture creation failed. (%d x %d, format: %s, mips: %d", width, height, format_name.str(), mip_level_count)); } } @@ -2902,22 +2918,22 @@ IDirect3DVolumeTexture8* DX8Wrapper::_Create_DX8_Volume_Texture } -IDirect3DSurface8 * DX8Wrapper::_Create_DX8_Surface(unsigned int width, unsigned int height, WW3DFormat format) +IDirect3DSurface8* DX8Wrapper::_Create_DX8_Surface(unsigned int width, unsigned int height, WW3DFormat format) { DX8_THREAD_ASSERT(); DX8_Assert(); - IDirect3DSurface8 *surface = NULL; + IDirect3DSurface8* surface = NULL; // Paletted surfaces not supported! - WWASSERT(format!=D3DFMT_P8); + WWASSERT(format != D3DFMT_P8); DX8CALL(CreateImageSurface(width, height, WW3DFormat_To_D3DFormat(format), &surface)); return surface; } -IDirect3DSurface8 * DX8Wrapper::_Create_DX8_Surface(const char *filename_) +IDirect3DSurface8* DX8Wrapper::_Create_DX8_Surface(const char* filename_) { DX8_THREAD_ASSERT(); DX8_Assert(); @@ -2931,36 +2947,36 @@ IDirect3DSurface8 * DX8Wrapper::_Create_DX8_Surface(const char *filename_) // the file data and use D3DXLoadSurfaceFromFile. This is a horrible hack, but it saves us // having to write file loaders. Will fix this when D3DX provides us with the right functions. // Create a surface the size of the file image data - IDirect3DSurface8 *surface = NULL; + IDirect3DSurface8* surface = NULL; { - file_auto_ptr myfile(_TheFileFactory,filename_); + file_auto_ptr myfile(_TheFileFactory, filename_); // If file not found, create a surface with missing texture in it if (!myfile->Is_Available()) { // If file not found, try the dds format // else create a surface with missing texture in it char compressed_name[200]; - strncpy(compressed_name,filename_, ARRAY_SIZE(compressed_name)); - compressed_name[ARRAY_SIZE(compressed_name)-1] = '\0'; - char *ext = strstr(compressed_name, "."); - if ( ext && (strlen(ext)==4) && - ( (ext[1] == 't') || (ext[1] == 'T') ) && - ( (ext[2] == 'g') || (ext[2] == 'G') ) && - ( (ext[3] == 'a') || (ext[3] == 'A') ) ) { - ext[1]='d'; - ext[2]='d'; - ext[3]='s'; + strncpy(compressed_name, filename_, ARRAY_SIZE(compressed_name)); + compressed_name[ARRAY_SIZE(compressed_name) - 1] = '\0'; + char* ext = strstr(compressed_name, "."); + if (ext && (strlen(ext) == 4) && + ((ext[1] == 't') || (ext[1] == 'T')) && + ((ext[2] == 'g') || (ext[2] == 'G')) && + ((ext[3] == 'a') || (ext[3] == 'A'))) { + ext[1] = 'd'; + ext[2] = 'd'; + ext[3] = 's'; } - file_auto_ptr myfile2(_TheFileFactory,compressed_name); + file_auto_ptr myfile2(_TheFileFactory, compressed_name); if (!myfile2->Is_Available()) return MissingTexture::_Create_Missing_Surface(); } } - StringClass filename_string(filename_,true); - surface=TextureLoader::Load_Surface_Immediate( + StringClass filename_string(filename_, true); + surface = TextureLoader::Load_Surface_Immediate( filename_string, WW3D_FORMAT_UNKNOWN, true); @@ -2983,13 +2999,13 @@ IDirect3DSurface8 * DX8Wrapper::_Create_DX8_Surface(const char *filename_) * HISTORY: * * 4/26/2001 hy : Created. * *=============================================================================================*/ -void DX8Wrapper::_Update_Texture(TextureClass *system, TextureClass *video) +void DX8Wrapper::_Update_Texture(TextureClass* system, TextureClass* video) { WWASSERT(system); WWASSERT(video); - WWASSERT(system->Get_Pool()==TextureClass::POOL_SYSTEMMEM); - WWASSERT(video->Get_Pool()==TextureClass::POOL_DEFAULT); - DX8CALL(UpdateTexture(system->Peek_D3D_Base_Texture(),video->Peek_D3D_Base_Texture())); + WWASSERT(system->Get_Pool() == TextureClass::POOL_SYSTEMMEM); + WWASSERT(video->Get_Pool() == TextureClass::POOL_DEFAULT); + DX8CALL(UpdateTexture(system->Peek_D3D_Base_Texture(), video->Peek_D3D_Base_Texture())); } void DX8Wrapper::Compute_Caps(WW3DFormat display_format) @@ -2997,92 +3013,92 @@ void DX8Wrapper::Compute_Caps(WW3DFormat display_format) DX8_THREAD_ASSERT(); DX8_Assert(); delete CurrentCaps; - CurrentCaps=new DX8Caps(_Get_D3D8(),D3DDevice,display_format,Get_Current_Adapter_Identifier()); + CurrentCaps = new DX8Caps(_Get_D3D8(), D3DDevice, display_format, Get_Current_Adapter_Identifier()); } void DX8Wrapper::Set_Light(unsigned index, const D3DLIGHT8* light) { if (light) { - render_state.Lights[index]=*light; - render_state.LightEnable[index]=true; + render_state.Lights[index] = *light; + render_state.LightEnable[index] = true; } else { - render_state.LightEnable[index]=false; + render_state.LightEnable[index] = false; } - render_state_changed|=(LIGHT0_CHANGED<Get_Light_Count(); - unsigned int color=Convert_Color(light_env->Get_Equivalent_Ambient(),0.0f); - if (RenderStates[D3DRS_AMBIENT]!=color) + unsigned int color = Convert_Color(light_env->Get_Equivalent_Ambient(), 0.0f); + if (RenderStates[D3DRS_AMBIENT] != color) { - Set_DX8_Render_State(D3DRS_AMBIENT,color); -//buggy Radeon 9700 driver doesn't apply new ambient unless the material also changes. + Set_DX8_Render_State(D3DRS_AMBIENT, color); + //buggy Radeon 9700 driver doesn't apply new ambient unless the material also changes. #if 1 - render_state_changed|=MATERIAL_CHANGED; + render_state_changed |= MATERIAL_CHANGED; #endif } - D3DLIGHT8 light; - int l=0; - for (;lGet_Light_Diffuse(l); - Vector3 dir=-light_env->Get_Light_Direction(l); - light.Direction=(const D3DVECTOR&)(dir); + + light.Type = D3DLIGHT_DIRECTIONAL; + (Vector3&)light.Diffuse = light_env->Get_Light_Diffuse(l); + Vector3 dir = -light_env->Get_Light_Direction(l); + light.Direction = (const D3DVECTOR&)(dir); // (gth) TODO: put specular into LightEnvironment? Much work to be done on lights :-)' - if (l==0) { + if (l == 0) { light.Specular.r = light.Specular.g = light.Specular.b = 1.0f; } if (light_env->isPointLight(l)) { light.Type = D3DLIGHT_POINT; - (Vector3&)light.Diffuse=light_env->getPointDiffuse(l); - (Vector3&)light.Ambient=light_env->getPointAmbient(l); + (Vector3&)light.Diffuse = light_env->getPointDiffuse(l); + (Vector3&)light.Ambient = light_env->getPointAmbient(l); light.Position = (const D3DVECTOR&)light_env->getPointCenter(l); light.Range = light_env->getPointOrad(l); - + // Inverse linear light 1/(1+D) - double a,b; + double a, b; b = light_env->getPointOrad(l); a = light_env->getPointIrad(l); -//(gth) CNC3 Generals code for the attenuation factors is causing the lights to over-brighten -//I'm changing the Attenuation0 parameter to 1.0 to avoid this problem. + //(gth) CNC3 Generals code for the attenuation factors is causing the lights to over-brighten + //I'm changing the Attenuation0 parameter to 1.0 to avoid this problem. #if 0 - light.Attenuation0=0.01f; + light.Attenuation0 = 0.01f; #else - light.Attenuation0=1.0f; + light.Attenuation0 = 1.0f; #endif - if (fabs(a-b)<1e-5) + if (fabs(a - b) < 1e-5) // if the attenuation range is too small assume uniform with cutoff - light.Attenuation1=0.0f; + light.Attenuation1 = 0.0f; else // this will cause the light to drop to half intensity at the first far attenuation - light.Attenuation1=(float) 0.1/a; - - light.Attenuation2=8.0f/(b*b); + light.Attenuation1 = (float)0.1 / a; + + light.Attenuation2 = 8.0f / (b * b); } - Set_Light(l,&light); + Set_Light(l, &light); } - for (;l<4;++l) { - Set_Light(l,NULL); + for (; l < 4; ++l) { + Set_Light(l, NULL); } } -/* else { - for (int l=0;l<4;++l) { - Set_Light(l,NULL); + /* else { + for (int l=0;l<4;++l) { + Set_Light(l,NULL); + } } - } -*/ + */ } -IDirect3DSurface8 * DX8Wrapper::_Get_DX8_Front_Buffer() + +IDirect3DSurface8* DX8Wrapper::_Get_DX8_Front_Buffer() { DX8_THREAD_ASSERT(); D3DDISPLAYMODE mode; DX8CALL(GetDisplayMode(&mode)); - IDirect3DSurface8 * fb=NULL; + IDirect3DSurface8* fb = NULL; - DX8CALL(CreateImageSurface(mode.Width,mode.Height,D3DFMT_A8R8G8B8,&fb)); + DX8CALL(CreateImageSurface(mode.Width, mode.Height, D3DFMT_A8R8G8B8, &fb)); DX8CALL(GetFrontBuffer(fb)); return fb; } -SurfaceClass * DX8Wrapper::_Get_DX8_Back_Buffer(unsigned int num) +SurfaceClass* DX8Wrapper::_Get_DX8_Back_Buffer(unsigned int num) { DX8_THREAD_ASSERT(); - IDirect3DSurface8 * bb; - SurfaceClass *surf=NULL; - DX8CALL(GetBackBuffer(num,D3DBACKBUFFER_TYPE_MONO,&bb)); + IDirect3DSurface8* bb; + SurfaceClass* surf = NULL; + DX8CALL(GetBackBuffer(num, D3DBACKBUFFER_TYPE_MONO, &bb)); if (bb) { - surf=NEW_REF(SurfaceClass,(bb)); + surf = NEW_REF(SurfaceClass, (bb)); bb->Release(); } return surf; } - -TextureClass * -DX8Wrapper::Create_Render_Target (int width, int height, WW3DFormat format) +TextureClass* +DX8Wrapper::Create_Render_Target(int width, int height, WW3DFormat format) { DX8_THREAD_ASSERT(); DX8_Assert(); number_of_DX8_calls++; // Use the current display format if format isn't specified - if (format==WW3D_FORMAT_UNKNOWN) { + if (format == WW3D_FORMAT_UNKNOWN) { D3DDISPLAYMODE mode; DX8CALL(GetDisplayMode(&mode)); - format=D3DFormat_To_WW3DFormat(mode.Format); + format = D3DFormat_To_WW3DFormat(mode.Format); } // If render target format isn't supported return NULL @@ -3225,18 +3241,18 @@ DX8Wrapper::Create_Render_Target (int width, int height, WW3DFormat format) // // Note: We're going to force the width and height to be powers of two and equal // - const D3DCAPS8& dx8caps=Get_Current_Caps()->Get_DX8_Caps(); + const D3DCAPS8& dx8caps = Get_Current_Caps()->Get_DX8_Caps(); float poweroftwosize = width; if (height > 0 && height < width) { poweroftwosize = height; } - poweroftwosize = ::Find_POT (poweroftwosize); + poweroftwosize = ::Find_POT(poweroftwosize); - if (poweroftwosize>dx8caps.MaxTextureWidth) { - poweroftwosize=dx8caps.MaxTextureWidth; + if (poweroftwosize > dx8caps.MaxTextureWidth) { + poweroftwosize = dx8caps.MaxTextureWidth; } - if (poweroftwosize>dx8caps.MaxTextureHeight) { - poweroftwosize=dx8caps.MaxTextureHeight; + if (poweroftwosize > dx8caps.MaxTextureHeight) { + poweroftwosize = dx8caps.MaxTextureHeight; } width = height = poweroftwosize; @@ -3244,11 +3260,11 @@ DX8Wrapper::Create_Render_Target (int width, int height, WW3DFormat format) // // Attempt to create the render target // - TextureClass * tex = NEW_REF(TextureClass,(width,height,format,MIP_LEVELS_1,TextureClass::POOL_DEFAULT,true)); + TextureClass* tex = NEW_REF(TextureClass, (width, height, format, MIP_LEVELS_1, TextureClass::POOL_DEFAULT, true)); // 3dfx drivers are lying in the CheckDeviceFormat call and claiming // that they support render targets! - if (tex->Peek_D3D_Base_Texture() == NULL) + if (tex->Peek_D3D_Base_Texture() == NULL) { WWDEBUG_SAY(("DX8Wrapper - Render target creation failed!")); REF_PTR_RELEASE(tex); @@ -3263,8 +3279,8 @@ DX8Wrapper::Create_Render_Target (int width, int height, WW3DFormat format) */ void DX8Wrapper::Create_Render_Target ( - int width, - int height, + int width, + int height, WW3DFormat format, WW3DZFormat zformat, TextureClass** target, @@ -3276,60 +3292,60 @@ void DX8Wrapper::Create_Render_Target number_of_DX8_calls++; // Use the current display format if format isn't specified - if (format==WW3D_FORMAT_UNKNOWN) + if (format == WW3D_FORMAT_UNKNOWN) { - *target=NULL; - *depth_buffer=NULL; + *target = NULL; + *depth_buffer = NULL; return; -/* D3DDISPLAYMODE mode; - DX8CALL(GetDisplayMode(&mode)); - format=D3DFormat_To_WW3DFormat(mode.Format);*/ + /* D3DDISPLAYMODE mode; + DX8CALL(GetDisplayMode(&mode)); + format=D3DFormat_To_WW3DFormat(mode.Format);*/ } // If render target format isn't supported return NULL if (!Get_Current_Caps()->Support_Render_To_Texture_Format(format) || - !Get_Current_Caps()->Support_Depth_Stencil_Format(zformat)) + !Get_Current_Caps()->Support_Depth_Stencil_Format(zformat)) { WWDEBUG_SAY(("DX8Wrapper - Render target with depth format is not supported")); return; } // Note: We're going to force the width and height to be powers of two and equal - const D3DCAPS8& dx8caps=Get_Current_Caps()->Get_DX8_Caps(); + const D3DCAPS8& dx8caps = Get_Current_Caps()->Get_DX8_Caps(); float poweroftwosize = width; - if (height > 0 && height < width) + if (height > 0 && height < width) { poweroftwosize = height; } - poweroftwosize = ::Find_POT (poweroftwosize); + poweroftwosize = ::Find_POT(poweroftwosize); - if (poweroftwosize>dx8caps.MaxTextureWidth) + if (poweroftwosize > dx8caps.MaxTextureWidth) { - poweroftwosize=dx8caps.MaxTextureWidth; + poweroftwosize = dx8caps.MaxTextureWidth; } - if (poweroftwosize>dx8caps.MaxTextureHeight) + if (poweroftwosize > dx8caps.MaxTextureHeight) { - poweroftwosize=dx8caps.MaxTextureHeight; + poweroftwosize = dx8caps.MaxTextureHeight; } width = height = poweroftwosize; // Attempt to create the render target - TextureClass* tex=NEW_REF(TextureClass,(width,height,format,MIP_LEVELS_1,TextureClass::POOL_DEFAULT,true)); + TextureClass* tex = NEW_REF(TextureClass, (width, height, format, MIP_LEVELS_1, TextureClass::POOL_DEFAULT, true)); // 3dfx drivers are lying in the CheckDeviceFormat call and claiming // that they support render targets! - if (tex->Peek_D3D_Base_Texture() == NULL) + if (tex->Peek_D3D_Base_Texture() == NULL) { WWDEBUG_SAY(("DX8Wrapper - Render target creation failed!")); REF_PTR_RELEASE(tex); } - *target=tex; + *target = tex; // attempt to create the depth stencil buffer - *depth_buffer=NEW_REF + *depth_buffer = NEW_REF ( ZTextureClass, ( @@ -3338,7 +3354,7 @@ void DX8Wrapper::Create_Render_Target zformat, MIP_LEVELS_1, TextureClass::POOL_DEFAULT - ) + ) ); } @@ -3352,22 +3368,22 @@ void DX8Wrapper::Set_Render_Target_With_Z ZTextureClass* ztexture ) { - WWASSERT(texture!=NULL); - IDirect3DSurface8 * d3d_surf = texture->Get_D3D_Surface_Level(); + WWASSERT(texture != NULL); + IDirect3DSurface8* d3d_surf = texture->Get_D3D_Surface_Level(); WWASSERT(d3d_surf != NULL); - IDirect3DSurface8* d3d_zbuf=NULL; - if (ztexture!=NULL) + IDirect3DSurface8* d3d_zbuf = NULL; + if (ztexture != NULL) { - d3d_zbuf=ztexture->Get_D3D_Surface_Level(); - WWASSERT(d3d_zbuf!=NULL); - Set_Render_Target(d3d_surf,d3d_zbuf); + d3d_zbuf = ztexture->Get_D3D_Surface_Level(); + WWASSERT(d3d_zbuf != NULL); + Set_Render_Target(d3d_surf, d3d_zbuf); d3d_zbuf->Release(); } else { - Set_Render_Target(d3d_surf,true); + Set_Render_Target(d3d_surf, true); } d3d_surf->Release(); @@ -3375,64 +3391,64 @@ void DX8Wrapper::Set_Render_Target_With_Z } void -DX8Wrapper::Set_Render_Target(IDirect3DSwapChain8 *swap_chain) +DX8Wrapper::Set_Render_Target(IDirect3DSwapChain8* swap_chain) { DX8_THREAD_ASSERT(); - WWASSERT (swap_chain != NULL); + WWASSERT(swap_chain != NULL); // // Get the back buffer for the swap chain // LPDIRECT3DSURFACE8 render_target = NULL; - swap_chain->GetBackBuffer (0, D3DBACKBUFFER_TYPE_MONO, &render_target); + swap_chain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &render_target); // // Set this back buffer as the render targer // - Set_Render_Target (render_target, true); + Set_Render_Target(render_target, true); // // Release our hold on the back buffer // if (render_target != NULL) { - render_target->Release (); + render_target->Release(); render_target = NULL; } IsRenderToTexture = false; - return ; + return; } void -DX8Wrapper::Set_Render_Target(IDirect3DSurface8 *render_target, bool use_default_depth_buffer) +DX8Wrapper::Set_Render_Target(IDirect3DSurface8* render_target, bool use_default_depth_buffer) { -//#ifndef _XBOX + //#ifndef _XBOX DX8_THREAD_ASSERT(); DX8_Assert(); // // Should we restore the default render target set a new one? // - if (render_target == NULL || render_target == DefaultRenderTarget) + if (render_target == NULL || render_target == DefaultRenderTarget) { // If there is currently a custom render target, default must NOT be NULL. - if (CurrentRenderTarget) + if (CurrentRenderTarget) { - WWASSERT(DefaultRenderTarget!=NULL); + WWASSERT(DefaultRenderTarget != NULL); } // // Restore the default render target // - if (DefaultRenderTarget != NULL) + if (DefaultRenderTarget != NULL) { - DX8CALL(SetRenderTarget (DefaultRenderTarget, DefaultDepthBuffer)); - DefaultRenderTarget->Release (); + DX8CALL(SetRenderTarget(DefaultRenderTarget, DefaultDepthBuffer)); + DefaultRenderTarget->Release(); DefaultRenderTarget = NULL; - if (DefaultDepthBuffer) + if (DefaultDepthBuffer) { - DefaultDepthBuffer->Release (); + DefaultDepthBuffer->Release(); DefaultDepthBuffer = NULL; } } @@ -3440,74 +3456,74 @@ DX8Wrapper::Set_Render_Target(IDirect3DSurface8 *render_target, bool use_default // // Release our hold on the "current" render target // - if (CurrentRenderTarget != NULL) + if (CurrentRenderTarget != NULL) { - CurrentRenderTarget->Release (); + CurrentRenderTarget->Release(); CurrentRenderTarget = NULL; } - if (CurrentDepthBuffer!=NULL) + if (CurrentDepthBuffer != NULL) { CurrentDepthBuffer->Release(); - CurrentDepthBuffer=NULL; + CurrentDepthBuffer = NULL; } - } - else if (render_target != CurrentRenderTarget) + } + else if (render_target != CurrentRenderTarget) { - WWASSERT(DefaultRenderTarget==NULL); + WWASSERT(DefaultRenderTarget == NULL); // // We'll need the depth buffer later... // - if (DefaultDepthBuffer == NULL) + if (DefaultDepthBuffer == NULL) { -// IDirect3DSurface8 *depth_buffer = NULL; - DX8CALL(GetDepthStencilSurface (&DefaultDepthBuffer)); + // IDirect3DSurface8 *depth_buffer = NULL; + DX8CALL(GetDepthStencilSurface(&DefaultDepthBuffer)); } // // Get a pointer to the default render target (if necessary) // - if (DefaultRenderTarget == NULL) + if (DefaultRenderTarget == NULL) { - DX8CALL(GetRenderTarget (&DefaultRenderTarget)); + DX8CALL(GetRenderTarget(&DefaultRenderTarget)); } // // Release our hold on the old "current" render target // - if (CurrentRenderTarget != NULL) + if (CurrentRenderTarget != NULL) { - CurrentRenderTarget->Release (); + CurrentRenderTarget->Release(); CurrentRenderTarget = NULL; } - if (CurrentDepthBuffer!=NULL) + if (CurrentDepthBuffer != NULL) { CurrentDepthBuffer->Release(); - CurrentDepthBuffer=NULL; + CurrentDepthBuffer = NULL; } // // Keep a copy of the current render target (for housekeeping) // CurrentRenderTarget = render_target; - WWASSERT (CurrentRenderTarget != NULL); - if (CurrentRenderTarget != NULL) + WWASSERT(CurrentRenderTarget != NULL); + if (CurrentRenderTarget != NULL) { - CurrentRenderTarget->AddRef (); + CurrentRenderTarget->AddRef(); // // Switch render targets // - if (use_default_depth_buffer) + if (use_default_depth_buffer) { - DX8CALL(SetRenderTarget (CurrentRenderTarget, DefaultDepthBuffer)); + DX8CALL(SetRenderTarget(CurrentRenderTarget, DefaultDepthBuffer)); } - else + else { - DX8CALL(SetRenderTarget (CurrentRenderTarget, NULL)); + DX8CALL(SetRenderTarget(CurrentRenderTarget, NULL)); } } } @@ -3521,8 +3537,8 @@ DX8Wrapper::Set_Render_Target(IDirect3DSurface8 *render_target, bool use_default // } IsRenderToTexture = false; - return ; -//#endif // XBOX + return; + //#endif // XBOX } @@ -3532,36 +3548,36 @@ DX8Wrapper::Set_Render_Target(IDirect3DSurface8 *render_target, bool use_default */ void DX8Wrapper::Set_Render_Target ( - IDirect3DSurface8* render_target, - IDirect3DSurface8* depth_buffer + IDirect3DSurface8* render_target, + IDirect3DSurface8* depth_buffer ) { -//#ifndef _XBOX + //#ifndef _XBOX DX8_THREAD_ASSERT(); DX8_Assert(); // // Should we restore the default render target set a new one? // - if (render_target == NULL || render_target == DefaultRenderTarget) + if (render_target == NULL || render_target == DefaultRenderTarget) { // If there is currently a custom render target, default must NOT be NULL. - if (CurrentRenderTarget) + if (CurrentRenderTarget) { - WWASSERT(DefaultRenderTarget!=NULL); + WWASSERT(DefaultRenderTarget != NULL); } // // Restore the default render target // - if (DefaultRenderTarget != NULL) + if (DefaultRenderTarget != NULL) { - DX8CALL(SetRenderTarget (DefaultRenderTarget, DefaultDepthBuffer)); - DefaultRenderTarget->Release (); + DX8CALL(SetRenderTarget(DefaultRenderTarget, DefaultDepthBuffer)); + DefaultRenderTarget->Release(); DefaultRenderTarget = NULL; - if (DefaultDepthBuffer) + if (DefaultDepthBuffer) { - DefaultDepthBuffer->Release (); + DefaultDepthBuffer->Release(); DefaultDepthBuffer = NULL; } } @@ -3569,52 +3585,52 @@ void DX8Wrapper::Set_Render_Target // // Release our hold on the "current" render target // - if (CurrentRenderTarget != NULL) + if (CurrentRenderTarget != NULL) { - CurrentRenderTarget->Release (); + CurrentRenderTarget->Release(); CurrentRenderTarget = NULL; } - if (CurrentDepthBuffer!=NULL) + if (CurrentDepthBuffer != NULL) { CurrentDepthBuffer->Release(); - CurrentDepthBuffer=NULL; + CurrentDepthBuffer = NULL; } } - else if (render_target != CurrentRenderTarget) + else if (render_target != CurrentRenderTarget) { - WWASSERT(DefaultRenderTarget==NULL); + WWASSERT(DefaultRenderTarget == NULL); // // We'll need the depth buffer later... // - if (DefaultDepthBuffer == NULL) + if (DefaultDepthBuffer == NULL) { -// IDirect3DSurface8 *depth_buffer = NULL; - DX8CALL(GetDepthStencilSurface (&DefaultDepthBuffer)); + // IDirect3DSurface8 *depth_buffer = NULL; + DX8CALL(GetDepthStencilSurface(&DefaultDepthBuffer)); } // // Get a pointer to the default render target (if necessary) // - if (DefaultRenderTarget == NULL) + if (DefaultRenderTarget == NULL) { - DX8CALL(GetRenderTarget (&DefaultRenderTarget)); + DX8CALL(GetRenderTarget(&DefaultRenderTarget)); } // // Release our hold on the old "current" render target // - if (CurrentRenderTarget != NULL) + if (CurrentRenderTarget != NULL) { - CurrentRenderTarget->Release (); + CurrentRenderTarget->Release(); CurrentRenderTarget = NULL; } - if (CurrentDepthBuffer!=NULL) + if (CurrentDepthBuffer != NULL) { CurrentDepthBuffer->Release(); - CurrentDepthBuffer=NULL; + CurrentDepthBuffer = NULL; } // @@ -3622,49 +3638,49 @@ void DX8Wrapper::Set_Render_Target // CurrentRenderTarget = render_target; CurrentDepthBuffer = depth_buffer; - WWASSERT (CurrentRenderTarget != NULL); - if (CurrentRenderTarget != NULL) + WWASSERT(CurrentRenderTarget != NULL); + if (CurrentRenderTarget != NULL) { - CurrentRenderTarget->AddRef (); + CurrentRenderTarget->AddRef(); CurrentDepthBuffer->AddRef(); // // Switch render targets // - DX8CALL(SetRenderTarget (CurrentRenderTarget, CurrentDepthBuffer)); + DX8CALL(SetRenderTarget(CurrentRenderTarget, CurrentDepthBuffer)); } } - IsRenderToTexture=true; -//#endif // XBOX + IsRenderToTexture = true; + //#endif // XBOX } -IDirect3DSwapChain8 * -DX8Wrapper::Create_Additional_Swap_Chain (HWND render_window) +IDirect3DSwapChain8* +DX8Wrapper::Create_Additional_Swap_Chain(HWND render_window) { DX8_Assert(); // // Configure the presentation parameters for a windowed render target // - D3DPRESENT_PARAMETERS params = { 0 }; - params.BackBufferFormat = _PresentParameters.BackBufferFormat; - params.BackBufferCount = 1; - params.MultiSampleType = D3DMULTISAMPLE_NONE; - params.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC; - params.hDeviceWindow = render_window; - params.Windowed = TRUE; - params.EnableAutoDepthStencil = TRUE; - params.AutoDepthStencilFormat = _PresentParameters.AutoDepthStencilFormat; - params.Flags = 0; - params.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; - params.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + D3DPRESENT_PARAMETERS params = { 0 }; + params.BackBufferFormat = _PresentParameters.BackBufferFormat; + params.BackBufferCount = 1; + params.MultiSampleType = D3DMULTISAMPLE_NONE; + params.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC; + params.hDeviceWindow = render_window; + params.Windowed = TRUE; + params.EnableAutoDepthStencil = TRUE; + params.AutoDepthStencilFormat = _PresentParameters.AutoDepthStencilFormat; + params.Flags = 0; + params.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; + params.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; // // Create the swap chain // - IDirect3DSwapChain8 *swap_chain = NULL; + IDirect3DSwapChain8* swap_chain = NULL; DX8CALL(CreateAdditionalSwapChain(¶ms, &swap_chain)); return swap_chain; } @@ -3686,51 +3702,53 @@ unsigned int DX8Wrapper::Get_Free_Texture_RAM() // Gamma - controls the curvature of the middle of the curve // Bright - controls the minimum value of the curve // Contrast - controls the difference between the maximum and the minimum of the curve -void DX8Wrapper::Set_Gamma(float gamma,float bright,float contrast,bool calibrate,bool uselimit) +void DX8Wrapper::Set_Gamma(float gamma, float bright, float contrast, bool calibrate, bool uselimit) { - gamma=Bound(gamma,0.6f,6.0f); - bright=Bound(bright,-0.5f,0.5f); - contrast=Bound(contrast,0.5f,2.0f); - float oo_gamma=1.0f/gamma; + gamma = Bound(gamma, 0.6f, 6.0f); + bright = Bound(bright, -0.5f, 0.5f); + contrast = Bound(contrast, 0.5f, 2.0f); + float oo_gamma = 1.0f / gamma; DX8_Assert(); number_of_DX8_calls++; - DWORD flag=(calibrate?D3DSGR_CALIBRATE:D3DSGR_NO_CALIBRATION); + DWORD flag = (calibrate ? D3DSGR_CALIBRATE : D3DSGR_NO_CALIBRATION); D3DGAMMARAMP ramp; - float limit; + float limit; // IML: I'm not really sure what the intent of the 'limit' variable is. It does not produce useful results for my purposes. if (uselimit) { - limit=(contrast-1)/2*contrast; - } else { + limit = (contrast - 1) / 2 * contrast; + } + else { limit = 0.0f; } // HY - arrived at this equation after much trial and error. - for (int i=0; i<256; i++) { - float in,out; - in=i/256.0f; - float x=in-limit; - x=Bound(x,0.0f,1.0f); - x=powf(x,oo_gamma); - out=contrast*x+bright; - out=Bound(out,0.0f,1.0f); - ramp.red[i]=(WORD) (out*65535); - ramp.green[i]=(WORD) (out*65535); - ramp.blue[i]=(WORD) (out*65535); - } - - if (Get_Current_Caps()->Support_Gamma()) { - DX8Wrapper::_Get_D3D_Device8()->SetGammaRamp(flag,&ramp); - } else { + for (int i = 0; i < 256; i++) { + float in, out; + in = i / 256.0f; + float x = in - limit; + x = Bound(x, 0.0f, 1.0f); + x = powf(x, oo_gamma); + out = contrast * x + bright; + out = Bound(out, 0.0f, 1.0f); + ramp.red[i] = (WORD)(out * 65535); + ramp.green[i] = (WORD)(out * 65535); + ramp.blue[i] = (WORD)(out * 65535); + } + + if (Get_Current_Caps()->Support_Gamma()) { + DX8Wrapper::_Get_D3D_Device8()->SetGammaRamp(flag, &ramp); + } + else { HWND hwnd = GetDesktopWindow(); HDC hdc = GetDC(hwnd); if (hdc) { - SetDeviceGammaRamp (hdc, &ramp); - ReleaseDC (hwnd, hdc); + SetDeviceGammaRamp(hdc, &ramp); + ReleaseDC(hwnd, hdc); } } } @@ -3742,10 +3760,10 @@ void DX8Wrapper::Set_Gamma(float gamma,float bright,float contrast,bool calibrat void DX8Wrapper::Apply_Default_State() { SNAPSHOT_SAY(("DX8Wrapper::Apply_Default_State()")); - + // only set states used in game Set_DX8_Render_State(D3DRS_ZENABLE, TRUE); -// Set_DX8_Render_State(D3DRS_FILLMODE, D3DFILL_SOLID); + // Set_DX8_Render_State(D3DRS_FILLMODE, D3DFILL_SOLID); Set_DX8_Render_State(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); //Set_DX8_Render_State(D3DRS_LINEPATTERN, 0); Set_DX8_Render_State(D3DRS_ZWRITEENABLE, TRUE); @@ -3761,17 +3779,17 @@ void DX8Wrapper::Apply_Default_State() Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE, FALSE); Set_DX8_Render_State(D3DRS_FOGENABLE, FALSE); Set_DX8_Render_State(D3DRS_SPECULARENABLE, FALSE); -// Set_DX8_Render_State(D3DRS_ZVISIBLE, FALSE); -// Set_DX8_Render_State(D3DRS_FOGCOLOR, 0); -// Set_DX8_Render_State(D3DRS_FOGTABLEMODE, D3DFOG_NONE); -// Set_DX8_Render_State(D3DRS_FOGSTART, 0); + // Set_DX8_Render_State(D3DRS_ZVISIBLE, FALSE); + // Set_DX8_Render_State(D3DRS_FOGCOLOR, 0); + // Set_DX8_Render_State(D3DRS_FOGTABLEMODE, D3DFOG_NONE); + // Set_DX8_Render_State(D3DRS_FOGSTART, 0); -// Set_DX8_Render_State(D3DRS_FOGEND, WWMath::Float_As_Int(1.0f)); -// Set_DX8_Render_State(D3DRS_FOGDENSITY, WWMath::Float_As_Int(1.0f)); + // Set_DX8_Render_State(D3DRS_FOGEND, WWMath::Float_As_Int(1.0f)); + // Set_DX8_Render_State(D3DRS_FOGDENSITY, WWMath::Float_As_Int(1.0f)); - //Set_DX8_Render_State(D3DRS_EDGEANTIALIAS, FALSE); + //Set_DX8_Render_State(D3DRS_EDGEANTIALIAS, FALSE); Set_DX8_Render_State(D3DRS_ZBIAS, 0); -// Set_DX8_Render_State(D3DRS_RANGEFOGENABLE, FALSE); + // Set_DX8_Render_State(D3DRS_RANGEFOGENABLE, FALSE); Set_DX8_Render_State(D3DRS_STENCILENABLE, FALSE); Set_DX8_Render_State(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); Set_DX8_Render_State(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); @@ -3781,27 +3799,27 @@ void DX8Wrapper::Apply_Default_State() Set_DX8_Render_State(D3DRS_STENCILMASK, 0xffffffff); Set_DX8_Render_State(D3DRS_STENCILWRITEMASK, 0xffffffff); Set_DX8_Render_State(D3DRS_TEXTUREFACTOR, 0); -/* Set_DX8_Render_State(D3DRS_WRAP0, D3DWRAP_U| D3DWRAP_V); - Set_DX8_Render_State(D3DRS_WRAP1, D3DWRAP_U| D3DWRAP_V); - Set_DX8_Render_State(D3DRS_WRAP2, D3DWRAP_U| D3DWRAP_V); - Set_DX8_Render_State(D3DRS_WRAP3, D3DWRAP_U| D3DWRAP_V); - Set_DX8_Render_State(D3DRS_WRAP4, D3DWRAP_U| D3DWRAP_V); - Set_DX8_Render_State(D3DRS_WRAP5, D3DWRAP_U| D3DWRAP_V); - Set_DX8_Render_State(D3DRS_WRAP6, D3DWRAP_U| D3DWRAP_V); - Set_DX8_Render_State(D3DRS_WRAP7, D3DWRAP_U| D3DWRAP_V);*/ + /* Set_DX8_Render_State(D3DRS_WRAP0, D3DWRAP_U| D3DWRAP_V); + Set_DX8_Render_State(D3DRS_WRAP1, D3DWRAP_U| D3DWRAP_V); + Set_DX8_Render_State(D3DRS_WRAP2, D3DWRAP_U| D3DWRAP_V); + Set_DX8_Render_State(D3DRS_WRAP3, D3DWRAP_U| D3DWRAP_V); + Set_DX8_Render_State(D3DRS_WRAP4, D3DWRAP_U| D3DWRAP_V); + Set_DX8_Render_State(D3DRS_WRAP5, D3DWRAP_U| D3DWRAP_V); + Set_DX8_Render_State(D3DRS_WRAP6, D3DWRAP_U| D3DWRAP_V); + Set_DX8_Render_State(D3DRS_WRAP7, D3DWRAP_U| D3DWRAP_V);*/ Set_DX8_Render_State(D3DRS_CLIPPING, TRUE); Set_DX8_Render_State(D3DRS_LIGHTING, FALSE); //Set_DX8_Render_State(D3DRS_AMBIENT, 0); // Set_DX8_Render_State(D3DRS_FOGVERTEXMODE, D3DFOG_NONE); Set_DX8_Render_State(D3DRS_COLORVERTEX, TRUE); -/* Set_DX8_Render_State(D3DRS_LOCALVIEWER, TRUE); - Set_DX8_Render_State(D3DRS_NORMALIZENORMALS, FALSE); - Set_DX8_Render_State(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1); - Set_DX8_Render_State(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2); - Set_DX8_Render_State(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL); - Set_DX8_Render_State(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL); - Set_DX8_Render_State(D3DRS_VERTEXBLEND, D3DVBF_DISABLE);*/ - //Set_DX8_Render_State(D3DRS_CLIPPLANEENABLE, 0); + /* Set_DX8_Render_State(D3DRS_LOCALVIEWER, TRUE); + Set_DX8_Render_State(D3DRS_NORMALIZENORMALS, FALSE); + Set_DX8_Render_State(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1); + Set_DX8_Render_State(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2); + Set_DX8_Render_State(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL); + Set_DX8_Render_State(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL); + Set_DX8_Render_State(D3DRS_VERTEXBLEND, D3DVBF_DISABLE);*/ + //Set_DX8_Render_State(D3DRS_CLIPPLANEENABLE, 0); Set_DX8_Render_State(D3DRS_SOFTWAREVERTEXPROCESSING, FALSE); //Set_DX8_Render_State(D3DRS_POINTSIZE, 0x3f800000); //Set_DX8_Render_State(D3DRS_POINTSIZE_MIN, 0); @@ -3825,7 +3843,7 @@ void DX8Wrapper::Apply_Default_State() // disable TSS stages int i; - for (i=0; iGet_Max_Textures_Per_Pass(); i++) + for (i = 0; i < CurrentCaps->Get_Max_Textures_Per_Pass(); i++) { Set_DX8_Texture_Stage_State(i, D3DTSS_COLOROP, D3DTOP_DISABLE); Set_DX8_Texture_Stage_State(i, D3DTSS_COLORARG1, D3DTA_TEXTURE); @@ -3834,7 +3852,7 @@ void DX8Wrapper::Apply_Default_State() Set_DX8_Texture_Stage_State(i, D3DTSS_ALPHAOP, D3DTOP_DISABLE); Set_DX8_Texture_Stage_State(i, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); Set_DX8_Texture_Stage_State(i, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - + /*Set_DX8_Texture_Stage_State(i, D3DTSS_BUMPENVMAT00, 0); Set_DX8_Texture_Stage_State(i, D3DTSS_BUMPENVMAT01, 0); Set_DX8_Texture_Stage_State(i, D3DTSS_BUMPENVMAT10, 0); @@ -3843,41 +3861,41 @@ void DX8Wrapper::Apply_Default_State() Set_DX8_Texture_Stage_State(i, D3DTSS_BUMPENVLOFFSET, 0);*/ Set_DX8_Texture_Stage_State(i, D3DTSS_TEXCOORDINDEX, i); - + Set_DX8_Texture_Stage_State(i, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); Set_DX8_Texture_Stage_State(i, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); Set_DX8_Texture_Stage_State(i, D3DTSS_BORDERCOLOR, 0); -// Set_DX8_Texture_Stage_State(i, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); -// Set_DX8_Texture_Stage_State(i, D3DTSS_MINFILTER, D3DTEXF_LINEAR); -// Set_DX8_Texture_Stage_State(i, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); -// Set_DX8_Texture_Stage_State(i, D3DTSS_MIPMAPLODBIAS, 0); -// Set_DX8_Texture_Stage_State(i, D3DTSS_MAXMIPLEVEL, 0); -// Set_DX8_Texture_Stage_State(i, D3DTSS_MAXANISOTROPY, 1); - //Set_DX8_Texture_Stage_State(i, D3DTSS_ADDRESSW, D3DTADDRESS_WRAP); - //Set_DX8_Texture_Stage_State(i, D3DTSS_COLORARG0, D3DTA_CURRENT); - //Set_DX8_Texture_Stage_State(i, D3DTSS_ALPHAARG0, D3DTA_CURRENT); - //Set_DX8_Texture_Stage_State(i, D3DTSS_RESULTARG, D3DTA_CURRENT); + // Set_DX8_Texture_Stage_State(i, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + // Set_DX8_Texture_Stage_State(i, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + // Set_DX8_Texture_Stage_State(i, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); + // Set_DX8_Texture_Stage_State(i, D3DTSS_MIPMAPLODBIAS, 0); + // Set_DX8_Texture_Stage_State(i, D3DTSS_MAXMIPLEVEL, 0); + // Set_DX8_Texture_Stage_State(i, D3DTSS_MAXANISOTROPY, 1); + //Set_DX8_Texture_Stage_State(i, D3DTSS_ADDRESSW, D3DTADDRESS_WRAP); + //Set_DX8_Texture_Stage_State(i, D3DTSS_COLORARG0, D3DTA_CURRENT); + //Set_DX8_Texture_Stage_State(i, D3DTSS_ALPHAARG0, D3DTA_CURRENT); + //Set_DX8_Texture_Stage_State(i, D3DTSS_RESULTARG, D3DTA_CURRENT); Set_DX8_Texture_Stage_State(i, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - Set_Texture(i,NULL); + Set_Texture(i, NULL); } -// DX8Wrapper::Set_Material(NULL); + // DX8Wrapper::Set_Material(NULL); VertexMaterialClass::Apply_Null(); - for (unsigned index=0;index<4;++index) { - SNAPSHOT_SAY(("Clearing light %d to NULL",index)); - Set_DX8_Light(index,NULL); + for (unsigned index = 0; index < 4; ++index) { + SNAPSHOT_SAY(("Clearing light %d to NULL", index)); + Set_DX8_Light(index, NULL); } // set up simple default TSS Vector4 vconst[MAX_VERTEX_SHADER_CONSTANTS]; - memset(vconst,0,sizeof(Vector4)*MAX_VERTEX_SHADER_CONSTANTS); + memset(vconst, 0, sizeof(Vector4) * MAX_VERTEX_SHADER_CONSTANTS); Set_Vertex_Shader_Constant(0, vconst, MAX_VERTEX_SHADER_CONSTANTS); Vector4 pconst[MAX_PIXEL_SHADER_CONSTANTS]; - memset(pconst,0,sizeof(Vector4)*MAX_PIXEL_SHADER_CONSTANTS); + memset(pconst, 0, sizeof(Vector4) * MAX_PIXEL_SHADER_CONSTANTS); Set_Pixel_Shader_Constant(0, pconst, MAX_PIXEL_SHADER_CONSTANTS); Set_Vertex_Shader(DX8_FVF_XYZNDUV2); @@ -3889,117 +3907,117 @@ void DX8Wrapper::Apply_Default_State() const char* DX8Wrapper::Get_DX8_Render_State_Name(D3DRENDERSTATETYPE state) { switch (state) { - case D3DRS_ZENABLE : return "D3DRS_ZENABLE"; - case D3DRS_FILLMODE : return "D3DRS_FILLMODE"; - case D3DRS_SHADEMODE : return "D3DRS_SHADEMODE"; - case D3DRS_LINEPATTERN : return "D3DRS_LINEPATTERN"; - case D3DRS_ZWRITEENABLE : return "D3DRS_ZWRITEENABLE"; - case D3DRS_ALPHATESTENABLE : return "D3DRS_ALPHATESTENABLE"; - case D3DRS_LASTPIXEL : return "D3DRS_LASTPIXEL"; - case D3DRS_SRCBLEND : return "D3DRS_SRCBLEND"; - case D3DRS_DESTBLEND : return "D3DRS_DESTBLEND"; - case D3DRS_CULLMODE : return "D3DRS_CULLMODE"; - case D3DRS_ZFUNC : return "D3DRS_ZFUNC"; - case D3DRS_ALPHAREF : return "D3DRS_ALPHAREF"; - case D3DRS_ALPHAFUNC : return "D3DRS_ALPHAFUNC"; - case D3DRS_DITHERENABLE : return "D3DRS_DITHERENABLE"; - case D3DRS_ALPHABLENDENABLE : return "D3DRS_ALPHABLENDENABLE"; - case D3DRS_FOGENABLE : return "D3DRS_FOGENABLE"; - case D3DRS_SPECULARENABLE : return "D3DRS_SPECULARENABLE"; - case D3DRS_ZVISIBLE : return "D3DRS_ZVISIBLE"; - case D3DRS_FOGCOLOR : return "D3DRS_FOGCOLOR"; - case D3DRS_FOGTABLEMODE : return "D3DRS_FOGTABLEMODE"; - case D3DRS_FOGSTART : return "D3DRS_FOGSTART"; - case D3DRS_FOGEND : return "D3DRS_FOGEND"; - case D3DRS_FOGDENSITY : return "D3DRS_FOGDENSITY"; - case D3DRS_EDGEANTIALIAS : return "D3DRS_EDGEANTIALIAS"; - case D3DRS_ZBIAS : return "D3DRS_ZBIAS"; - case D3DRS_RANGEFOGENABLE : return "D3DRS_RANGEFOGENABLE"; - case D3DRS_STENCILENABLE : return "D3DRS_STENCILENABLE"; - case D3DRS_STENCILFAIL : return "D3DRS_STENCILFAIL"; - case D3DRS_STENCILZFAIL : return "D3DRS_STENCILZFAIL"; - case D3DRS_STENCILPASS : return "D3DRS_STENCILPASS"; - case D3DRS_STENCILFUNC : return "D3DRS_STENCILFUNC"; - case D3DRS_STENCILREF : return "D3DRS_STENCILREF"; - case D3DRS_STENCILMASK : return "D3DRS_STENCILMASK"; - case D3DRS_STENCILWRITEMASK : return "D3DRS_STENCILWRITEMASK"; - case D3DRS_TEXTUREFACTOR : return "D3DRS_TEXTUREFACTOR"; - case D3DRS_WRAP0 : return "D3DRS_WRAP0"; - case D3DRS_WRAP1 : return "D3DRS_WRAP1"; - case D3DRS_WRAP2 : return "D3DRS_WRAP2"; - case D3DRS_WRAP3 : return "D3DRS_WRAP3"; - case D3DRS_WRAP4 : return "D3DRS_WRAP4"; - case D3DRS_WRAP5 : return "D3DRS_WRAP5"; - case D3DRS_WRAP6 : return "D3DRS_WRAP6"; - case D3DRS_WRAP7 : return "D3DRS_WRAP7"; - case D3DRS_CLIPPING : return "D3DRS_CLIPPING"; - case D3DRS_LIGHTING : return "D3DRS_LIGHTING"; - case D3DRS_AMBIENT : return "D3DRS_AMBIENT"; - case D3DRS_FOGVERTEXMODE : return "D3DRS_FOGVERTEXMODE"; - case D3DRS_COLORVERTEX : return "D3DRS_COLORVERTEX"; - case D3DRS_LOCALVIEWER : return "D3DRS_LOCALVIEWER"; - case D3DRS_NORMALIZENORMALS : return "D3DRS_NORMALIZENORMALS"; - case D3DRS_DIFFUSEMATERIALSOURCE : return "D3DRS_DIFFUSEMATERIALSOURCE"; - case D3DRS_SPECULARMATERIALSOURCE : return "D3DRS_SPECULARMATERIALSOURCE"; - case D3DRS_AMBIENTMATERIALSOURCE : return "D3DRS_AMBIENTMATERIALSOURCE"; - case D3DRS_EMISSIVEMATERIALSOURCE : return "D3DRS_EMISSIVEMATERIALSOURCE"; - case D3DRS_VERTEXBLEND : return "D3DRS_VERTEXBLEND"; - case D3DRS_CLIPPLANEENABLE : return "D3DRS_CLIPPLANEENABLE"; - case D3DRS_SOFTWAREVERTEXPROCESSING : return "D3DRS_SOFTWAREVERTEXPROCESSING"; - case D3DRS_POINTSIZE : return "D3DRS_POINTSIZE"; - case D3DRS_POINTSIZE_MIN : return "D3DRS_POINTSIZE_MIN"; - case D3DRS_POINTSPRITEENABLE : return "D3DRS_POINTSPRITEENABLE"; - case D3DRS_POINTSCALEENABLE : return "D3DRS_POINTSCALEENABLE"; - case D3DRS_POINTSCALE_A : return "D3DRS_POINTSCALE_A"; - case D3DRS_POINTSCALE_B : return "D3DRS_POINTSCALE_B"; - case D3DRS_POINTSCALE_C : return "D3DRS_POINTSCALE_C"; - case D3DRS_MULTISAMPLEANTIALIAS : return "D3DRS_MULTISAMPLEANTIALIAS"; - case D3DRS_MULTISAMPLEMASK : return "D3DRS_MULTISAMPLEMASK"; - case D3DRS_PATCHEDGESTYLE : return "D3DRS_PATCHEDGESTYLE"; - case D3DRS_PATCHSEGMENTS : return "D3DRS_PATCHSEGMENTS"; - case D3DRS_DEBUGMONITORTOKEN : return "D3DRS_DEBUGMONITORTOKEN"; - case D3DRS_POINTSIZE_MAX : return "D3DRS_POINTSIZE_MAX"; - case D3DRS_INDEXEDVERTEXBLENDENABLE : return "D3DRS_INDEXEDVERTEXBLENDENABLE"; - case D3DRS_COLORWRITEENABLE : return "D3DRS_COLORWRITEENABLE"; - case D3DRS_TWEENFACTOR : return "D3DRS_TWEENFACTOR"; - case D3DRS_BLENDOP : return "D3DRS_BLENDOP"; -// case D3DRS_POSITIONORDER : return "D3DRS_POSITIONORDER"; -// case D3DRS_NORMALORDER : return "D3DRS_NORMALORDER"; - default : return "UNKNOWN"; + case D3DRS_ZENABLE: return "D3DRS_ZENABLE"; + case D3DRS_FILLMODE: return "D3DRS_FILLMODE"; + case D3DRS_SHADEMODE: return "D3DRS_SHADEMODE"; + case D3DRS_LINEPATTERN: return "D3DRS_LINEPATTERN"; + case D3DRS_ZWRITEENABLE: return "D3DRS_ZWRITEENABLE"; + case D3DRS_ALPHATESTENABLE: return "D3DRS_ALPHATESTENABLE"; + case D3DRS_LASTPIXEL: return "D3DRS_LASTPIXEL"; + case D3DRS_SRCBLEND: return "D3DRS_SRCBLEND"; + case D3DRS_DESTBLEND: return "D3DRS_DESTBLEND"; + case D3DRS_CULLMODE: return "D3DRS_CULLMODE"; + case D3DRS_ZFUNC: return "D3DRS_ZFUNC"; + case D3DRS_ALPHAREF: return "D3DRS_ALPHAREF"; + case D3DRS_ALPHAFUNC: return "D3DRS_ALPHAFUNC"; + case D3DRS_DITHERENABLE: return "D3DRS_DITHERENABLE"; + case D3DRS_ALPHABLENDENABLE: return "D3DRS_ALPHABLENDENABLE"; + case D3DRS_FOGENABLE: return "D3DRS_FOGENABLE"; + case D3DRS_SPECULARENABLE: return "D3DRS_SPECULARENABLE"; + case D3DRS_ZVISIBLE: return "D3DRS_ZVISIBLE"; + case D3DRS_FOGCOLOR: return "D3DRS_FOGCOLOR"; + case D3DRS_FOGTABLEMODE: return "D3DRS_FOGTABLEMODE"; + case D3DRS_FOGSTART: return "D3DRS_FOGSTART"; + case D3DRS_FOGEND: return "D3DRS_FOGEND"; + case D3DRS_FOGDENSITY: return "D3DRS_FOGDENSITY"; + case D3DRS_EDGEANTIALIAS: return "D3DRS_EDGEANTIALIAS"; + case D3DRS_ZBIAS: return "D3DRS_ZBIAS"; + case D3DRS_RANGEFOGENABLE: return "D3DRS_RANGEFOGENABLE"; + case D3DRS_STENCILENABLE: return "D3DRS_STENCILENABLE"; + case D3DRS_STENCILFAIL: return "D3DRS_STENCILFAIL"; + case D3DRS_STENCILZFAIL: return "D3DRS_STENCILZFAIL"; + case D3DRS_STENCILPASS: return "D3DRS_STENCILPASS"; + case D3DRS_STENCILFUNC: return "D3DRS_STENCILFUNC"; + case D3DRS_STENCILREF: return "D3DRS_STENCILREF"; + case D3DRS_STENCILMASK: return "D3DRS_STENCILMASK"; + case D3DRS_STENCILWRITEMASK: return "D3DRS_STENCILWRITEMASK"; + case D3DRS_TEXTUREFACTOR: return "D3DRS_TEXTUREFACTOR"; + case D3DRS_WRAP0: return "D3DRS_WRAP0"; + case D3DRS_WRAP1: return "D3DRS_WRAP1"; + case D3DRS_WRAP2: return "D3DRS_WRAP2"; + case D3DRS_WRAP3: return "D3DRS_WRAP3"; + case D3DRS_WRAP4: return "D3DRS_WRAP4"; + case D3DRS_WRAP5: return "D3DRS_WRAP5"; + case D3DRS_WRAP6: return "D3DRS_WRAP6"; + case D3DRS_WRAP7: return "D3DRS_WRAP7"; + case D3DRS_CLIPPING: return "D3DRS_CLIPPING"; + case D3DRS_LIGHTING: return "D3DRS_LIGHTING"; + case D3DRS_AMBIENT: return "D3DRS_AMBIENT"; + case D3DRS_FOGVERTEXMODE: return "D3DRS_FOGVERTEXMODE"; + case D3DRS_COLORVERTEX: return "D3DRS_COLORVERTEX"; + case D3DRS_LOCALVIEWER: return "D3DRS_LOCALVIEWER"; + case D3DRS_NORMALIZENORMALS: return "D3DRS_NORMALIZENORMALS"; + case D3DRS_DIFFUSEMATERIALSOURCE: return "D3DRS_DIFFUSEMATERIALSOURCE"; + case D3DRS_SPECULARMATERIALSOURCE: return "D3DRS_SPECULARMATERIALSOURCE"; + case D3DRS_AMBIENTMATERIALSOURCE: return "D3DRS_AMBIENTMATERIALSOURCE"; + case D3DRS_EMISSIVEMATERIALSOURCE: return "D3DRS_EMISSIVEMATERIALSOURCE"; + case D3DRS_VERTEXBLEND: return "D3DRS_VERTEXBLEND"; + case D3DRS_CLIPPLANEENABLE: return "D3DRS_CLIPPLANEENABLE"; + case D3DRS_SOFTWAREVERTEXPROCESSING: return "D3DRS_SOFTWAREVERTEXPROCESSING"; + case D3DRS_POINTSIZE: return "D3DRS_POINTSIZE"; + case D3DRS_POINTSIZE_MIN: return "D3DRS_POINTSIZE_MIN"; + case D3DRS_POINTSPRITEENABLE: return "D3DRS_POINTSPRITEENABLE"; + case D3DRS_POINTSCALEENABLE: return "D3DRS_POINTSCALEENABLE"; + case D3DRS_POINTSCALE_A: return "D3DRS_POINTSCALE_A"; + case D3DRS_POINTSCALE_B: return "D3DRS_POINTSCALE_B"; + case D3DRS_POINTSCALE_C: return "D3DRS_POINTSCALE_C"; + case D3DRS_MULTISAMPLEANTIALIAS: return "D3DRS_MULTISAMPLEANTIALIAS"; + case D3DRS_MULTISAMPLEMASK: return "D3DRS_MULTISAMPLEMASK"; + case D3DRS_PATCHEDGESTYLE: return "D3DRS_PATCHEDGESTYLE"; + case D3DRS_PATCHSEGMENTS: return "D3DRS_PATCHSEGMENTS"; + case D3DRS_DEBUGMONITORTOKEN: return "D3DRS_DEBUGMONITORTOKEN"; + case D3DRS_POINTSIZE_MAX: return "D3DRS_POINTSIZE_MAX"; + case D3DRS_INDEXEDVERTEXBLENDENABLE: return "D3DRS_INDEXEDVERTEXBLENDENABLE"; + case D3DRS_COLORWRITEENABLE: return "D3DRS_COLORWRITEENABLE"; + case D3DRS_TWEENFACTOR: return "D3DRS_TWEENFACTOR"; + case D3DRS_BLENDOP: return "D3DRS_BLENDOP"; + // case D3DRS_POSITIONORDER : return "D3DRS_POSITIONORDER"; + // case D3DRS_NORMALORDER : return "D3DRS_NORMALORDER"; + default: return "UNKNOWN"; } } const char* DX8Wrapper::Get_DX8_Texture_Stage_State_Name(D3DTEXTURESTAGESTATETYPE state) { switch (state) { - case D3DTSS_COLOROP : return "D3DTSS_COLOROP"; - case D3DTSS_COLORARG1 : return "D3DTSS_COLORARG1"; - case D3DTSS_COLORARG2 : return "D3DTSS_COLORARG2"; - case D3DTSS_ALPHAOP : return "D3DTSS_ALPHAOP"; - case D3DTSS_ALPHAARG1 : return "D3DTSS_ALPHAARG1"; - case D3DTSS_ALPHAARG2 : return "D3DTSS_ALPHAARG2"; - case D3DTSS_BUMPENVMAT00 : return "D3DTSS_BUMPENVMAT00"; - case D3DTSS_BUMPENVMAT01 : return "D3DTSS_BUMPENVMAT01"; - case D3DTSS_BUMPENVMAT10 : return "D3DTSS_BUMPENVMAT10"; - case D3DTSS_BUMPENVMAT11 : return "D3DTSS_BUMPENVMAT11"; - case D3DTSS_TEXCOORDINDEX : return "D3DTSS_TEXCOORDINDEX"; - case D3DTSS_ADDRESSU : return "D3DTSS_ADDRESSU"; - case D3DTSS_ADDRESSV : return "D3DTSS_ADDRESSV"; - case D3DTSS_BORDERCOLOR : return "D3DTSS_BORDERCOLOR"; - case D3DTSS_MAGFILTER : return "D3DTSS_MAGFILTER"; - case D3DTSS_MINFILTER : return "D3DTSS_MINFILTER"; - case D3DTSS_MIPFILTER : return "D3DTSS_MIPFILTER"; - case D3DTSS_MIPMAPLODBIAS : return "D3DTSS_MIPMAPLODBIAS"; - case D3DTSS_MAXMIPLEVEL : return "D3DTSS_MAXMIPLEVEL"; - case D3DTSS_MAXANISOTROPY : return "D3DTSS_MAXANISOTROPY"; - case D3DTSS_BUMPENVLSCALE : return "D3DTSS_BUMPENVLSCALE"; - case D3DTSS_BUMPENVLOFFSET : return "D3DTSS_BUMPENVLOFFSET"; - case D3DTSS_TEXTURETRANSFORMFLAGS : return "D3DTSS_TEXTURETRANSFORMFLAGS"; - case D3DTSS_ADDRESSW : return "D3DTSS_ADDRESSW"; - case D3DTSS_COLORARG0 : return "D3DTSS_COLORARG0"; - case D3DTSS_ALPHAARG0 : return "D3DTSS_ALPHAARG0"; - case D3DTSS_RESULTARG : return "D3DTSS_RESULTARG"; - default : return "UNKNOWN"; + case D3DTSS_COLOROP: return "D3DTSS_COLOROP"; + case D3DTSS_COLORARG1: return "D3DTSS_COLORARG1"; + case D3DTSS_COLORARG2: return "D3DTSS_COLORARG2"; + case D3DTSS_ALPHAOP: return "D3DTSS_ALPHAOP"; + case D3DTSS_ALPHAARG1: return "D3DTSS_ALPHAARG1"; + case D3DTSS_ALPHAARG2: return "D3DTSS_ALPHAARG2"; + case D3DTSS_BUMPENVMAT00: return "D3DTSS_BUMPENVMAT00"; + case D3DTSS_BUMPENVMAT01: return "D3DTSS_BUMPENVMAT01"; + case D3DTSS_BUMPENVMAT10: return "D3DTSS_BUMPENVMAT10"; + case D3DTSS_BUMPENVMAT11: return "D3DTSS_BUMPENVMAT11"; + case D3DTSS_TEXCOORDINDEX: return "D3DTSS_TEXCOORDINDEX"; + case D3DTSS_ADDRESSU: return "D3DTSS_ADDRESSU"; + case D3DTSS_ADDRESSV: return "D3DTSS_ADDRESSV"; + case D3DTSS_BORDERCOLOR: return "D3DTSS_BORDERCOLOR"; + case D3DTSS_MAGFILTER: return "D3DTSS_MAGFILTER"; + case D3DTSS_MINFILTER: return "D3DTSS_MINFILTER"; + case D3DTSS_MIPFILTER: return "D3DTSS_MIPFILTER"; + case D3DTSS_MIPMAPLODBIAS: return "D3DTSS_MIPMAPLODBIAS"; + case D3DTSS_MAXMIPLEVEL: return "D3DTSS_MAXMIPLEVEL"; + case D3DTSS_MAXANISOTROPY: return "D3DTSS_MAXANISOTROPY"; + case D3DTSS_BUMPENVLSCALE: return "D3DTSS_BUMPENVLSCALE"; + case D3DTSS_BUMPENVLOFFSET: return "D3DTSS_BUMPENVLOFFSET"; + case D3DTSS_TEXTURETRANSFORMFLAGS: return "D3DTSS_TEXTURETRANSFORMFLAGS"; + case D3DTSS_ADDRESSW: return "D3DTSS_ADDRESSW"; + case D3DTSS_COLORARG0: return "D3DTSS_COLORARG0"; + case D3DTSS_ALPHAARG0: return "D3DTSS_ALPHAARG0"; + case D3DTSS_RESULTARG: return "D3DTSS_RESULTARG"; + default: return "UNKNOWN"; } } @@ -4007,15 +4025,15 @@ void DX8Wrapper::Get_DX8_Render_State_Value_Name(StringClass& name, D3DRENDERSTA { switch (state) { case D3DRS_ZENABLE: - name=Get_DX8_ZBuffer_Type_Name(value); + name = Get_DX8_ZBuffer_Type_Name(value); break; case D3DRS_FILLMODE: - name=Get_DX8_Fill_Mode_Name(value); + name = Get_DX8_Fill_Mode_Name(value); break; case D3DRS_SHADEMODE: - name=Get_DX8_Shade_Mode_Name(value); + name = Get_DX8_Shade_Mode_Name(value); break; case D3DRS_LINEPATTERN: @@ -4027,7 +4045,7 @@ void DX8Wrapper::Get_DX8_Render_State_Value_Name(StringClass& name, D3DRENDERSTA case D3DRS_AMBIENT: case D3DRS_CLIPPLANEENABLE: case D3DRS_MULTISAMPLEMASK: - name.Format("0x%x",value); + name.Format("0x%x", value); break; case D3DRS_ZWRITEENABLE: @@ -4050,31 +4068,31 @@ void DX8Wrapper::Get_DX8_Render_State_Value_Name(StringClass& name, D3DRENDERSTA case D3DRS_POINTSCALEENABLE: case D3DRS_MULTISAMPLEANTIALIAS: case D3DRS_INDEXEDVERTEXBLENDENABLE: - name=value ? "TRUE" : "FALSE"; + name = value ? "TRUE" : "FALSE"; break; case D3DRS_SRCBLEND: case D3DRS_DESTBLEND: - name=Get_DX8_Blend_Name(value); + name = Get_DX8_Blend_Name(value); break; case D3DRS_CULLMODE: - name=Get_DX8_Cull_Mode_Name(value); + name = Get_DX8_Cull_Mode_Name(value); break; case D3DRS_ZFUNC: case D3DRS_ALPHAFUNC: case D3DRS_STENCILFUNC: - name=Get_DX8_Cmp_Func_Name(value); + name = Get_DX8_Cmp_Func_Name(value); break; case D3DRS_ZVISIBLE: - name="NOTSUPPORTED"; + name = "NOTSUPPORTED"; break; case D3DRS_FOGTABLEMODE: case D3DRS_FOGVERTEXMODE: - name=Get_DX8_Fog_Mode_Name(value); + name = Get_DX8_Fog_Mode_Name(value); break; case D3DRS_FOGSTART: @@ -4088,18 +4106,18 @@ void DX8Wrapper::Get_DX8_Render_State_Value_Name(StringClass& name, D3DRENDERSTA case D3DRS_PATCHSEGMENTS: case D3DRS_POINTSIZE_MAX: case D3DRS_TWEENFACTOR: - name.Format("%f",*(float*)&value); + name.Format("%f", *(float*)&value); break; case D3DRS_ZBIAS: case D3DRS_STENCILREF: - name.Format("%d",value); + name.Format("%d", value); break; case D3DRS_STENCILFAIL: case D3DRS_STENCILZFAIL: case D3DRS_STENCILPASS: - name=Get_DX8_Stencil_Op_Name(value); + name = Get_DX8_Stencil_Op_Name(value); break; case D3DRS_WRAP0: @@ -4110,43 +4128,43 @@ void DX8Wrapper::Get_DX8_Render_State_Value_Name(StringClass& name, D3DRENDERSTA case D3DRS_WRAP5: case D3DRS_WRAP6: case D3DRS_WRAP7: - name="0"; - if (value&D3DWRAP_U) name+="|D3DWRAP_U"; - if (value&D3DWRAP_V) name+="|D3DWRAP_V"; - if (value&D3DWRAP_W) name+="|D3DWRAP_W"; + name = "0"; + if (value & D3DWRAP_U) name += "|D3DWRAP_U"; + if (value & D3DWRAP_V) name += "|D3DWRAP_V"; + if (value & D3DWRAP_W) name += "|D3DWRAP_W"; break; case D3DRS_DIFFUSEMATERIALSOURCE: case D3DRS_SPECULARMATERIALSOURCE: case D3DRS_AMBIENTMATERIALSOURCE: case D3DRS_EMISSIVEMATERIALSOURCE: - name=Get_DX8_Material_Source_Name(value); + name = Get_DX8_Material_Source_Name(value); break; case D3DRS_VERTEXBLEND: - name=Get_DX8_Vertex_Blend_Flag_Name(value); + name = Get_DX8_Vertex_Blend_Flag_Name(value); break; case D3DRS_PATCHEDGESTYLE: - name=Get_DX8_Patch_Edge_Style_Name(value); + name = Get_DX8_Patch_Edge_Style_Name(value); break; case D3DRS_DEBUGMONITORTOKEN: - name=Get_DX8_Debug_Monitor_Token_Name(value); + name = Get_DX8_Debug_Monitor_Token_Name(value); break; case D3DRS_COLORWRITEENABLE: - name="0"; - if (value&D3DCOLORWRITEENABLE_RED) name+="|D3DCOLORWRITEENABLE_RED"; - if (value&D3DCOLORWRITEENABLE_GREEN) name+="|D3DCOLORWRITEENABLE_GREEN"; - if (value&D3DCOLORWRITEENABLE_BLUE) name+="|D3DCOLORWRITEENABLE_BLUE"; - if (value&D3DCOLORWRITEENABLE_ALPHA) name+="|D3DCOLORWRITEENABLE_ALPHA"; + name = "0"; + if (value & D3DCOLORWRITEENABLE_RED) name += "|D3DCOLORWRITEENABLE_RED"; + if (value & D3DCOLORWRITEENABLE_GREEN) name += "|D3DCOLORWRITEENABLE_GREEN"; + if (value & D3DCOLORWRITEENABLE_BLUE) name += "|D3DCOLORWRITEENABLE_BLUE"; + if (value & D3DCOLORWRITEENABLE_ALPHA) name += "|D3DCOLORWRITEENABLE_ALPHA"; break; case D3DRS_BLENDOP: - name=Get_DX8_Blend_Op_Name(value); + name = Get_DX8_Blend_Op_Name(value); break; default: - name.Format("UNKNOWN (%d)",value); + name.Format("UNKNOWN (%d)", value); break; } } @@ -4156,7 +4174,7 @@ void DX8Wrapper::Get_DX8_Texture_Stage_State_Value_Name(StringClass& name, D3DTE switch (state) { case D3DTSS_COLOROP: case D3DTSS_ALPHAOP: - name=Get_DX8_Texture_Op_Name(value); + name = Get_DX8_Texture_Op_Name(value); break; case D3DTSS_COLORARG0: @@ -4166,26 +4184,26 @@ void DX8Wrapper::Get_DX8_Texture_Stage_State_Value_Name(StringClass& name, D3DTE case D3DTSS_ALPHAARG1: case D3DTSS_ALPHAARG2: case D3DTSS_RESULTARG: - name=Get_DX8_Texture_Arg_Name(value); + name = Get_DX8_Texture_Arg_Name(value); break; case D3DTSS_ADDRESSU: case D3DTSS_ADDRESSV: case D3DTSS_ADDRESSW: - name=Get_DX8_Texture_Address_Name(value); + name = Get_DX8_Texture_Address_Name(value); break; case D3DTSS_MAGFILTER: case D3DTSS_MINFILTER: case D3DTSS_MIPFILTER: - name=Get_DX8_Texture_Filter_Name(value); + name = Get_DX8_Texture_Filter_Name(value); break; case D3DTSS_TEXTURETRANSFORMFLAGS: - name=Get_DX8_Texture_Transform_Flag_Name(value); + name = Get_DX8_Texture_Transform_Flag_Name(value); break; - // Floating point values + // Floating point values case D3DTSS_MIPMAPLODBIAS: case D3DTSS_BUMPENVMAT00: case D3DTSS_BUMPENVMAT01: @@ -4193,36 +4211,36 @@ void DX8Wrapper::Get_DX8_Texture_Stage_State_Value_Name(StringClass& name, D3DTE case D3DTSS_BUMPENVMAT11: case D3DTSS_BUMPENVLSCALE: case D3DTSS_BUMPENVLOFFSET: - name.Format("%f",*(float*)&value); + name.Format("%f", *(float*)&value); break; case D3DTSS_TEXCOORDINDEX: - if ((value&0xffff0000)==D3DTSS_TCI_CAMERASPACENORMAL) { - name.Format("D3DTSS_TCI_CAMERASPACENORMAL|%d",value&0xffff); + if ((value & 0xffff0000) == D3DTSS_TCI_CAMERASPACENORMAL) { + name.Format("D3DTSS_TCI_CAMERASPACENORMAL|%d", value & 0xffff); } - else if ((value&0xffff0000)==D3DTSS_TCI_CAMERASPACEPOSITION) { - name.Format("D3DTSS_TCI_CAMERASPACEPOSITION|%d",value&0xffff); + else if ((value & 0xffff0000) == D3DTSS_TCI_CAMERASPACEPOSITION) { + name.Format("D3DTSS_TCI_CAMERASPACEPOSITION|%d", value & 0xffff); } - else if ((value&0xffff0000)==D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR) { - name.Format("D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR|%d",value&0xffff); + else if ((value & 0xffff0000) == D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR) { + name.Format("D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR|%d", value & 0xffff); } else { - name.Format("%d",value); + name.Format("%d", value); } break; - // Integer value + // Integer value case D3DTSS_MAXMIPLEVEL: case D3DTSS_MAXANISOTROPY: - name.Format("%d",value); + name.Format("%d", value); break; - // Hex values + // Hex values case D3DTSS_BORDERCOLOR: - name.Format("0x%x",value); + name.Format("0x%x", value); break; default: - name.Format("UNKNOWN (%d)",value); + name.Format("UNKNOWN (%d)", value); break; } } @@ -4230,241 +4248,241 @@ void DX8Wrapper::Get_DX8_Texture_Stage_State_Value_Name(StringClass& name, D3DTE const char* DX8Wrapper::Get_DX8_Texture_Op_Name(unsigned value) { switch (value) { - case D3DTOP_DISABLE : return "D3DTOP_DISABLE"; - case D3DTOP_SELECTARG1 : return "D3DTOP_SELECTARG1"; - case D3DTOP_SELECTARG2 : return "D3DTOP_SELECTARG2"; - case D3DTOP_MODULATE : return "D3DTOP_MODULATE"; - case D3DTOP_MODULATE2X : return "D3DTOP_MODULATE2X"; - case D3DTOP_MODULATE4X : return "D3DTOP_MODULATE4X"; - case D3DTOP_ADD : return "D3DTOP_ADD"; - case D3DTOP_ADDSIGNED : return "D3DTOP_ADDSIGNED"; - case D3DTOP_ADDSIGNED2X : return "D3DTOP_ADDSIGNED2X"; - case D3DTOP_SUBTRACT : return "D3DTOP_SUBTRACT"; - case D3DTOP_ADDSMOOTH : return "D3DTOP_ADDSMOOTH"; - case D3DTOP_BLENDDIFFUSEALPHA : return "D3DTOP_BLENDDIFFUSEALPHA"; - case D3DTOP_BLENDTEXTUREALPHA : return "D3DTOP_BLENDTEXTUREALPHA"; - case D3DTOP_BLENDFACTORALPHA : return "D3DTOP_BLENDFACTORALPHA"; - case D3DTOP_BLENDTEXTUREALPHAPM : return "D3DTOP_BLENDTEXTUREALPHAPM"; - case D3DTOP_BLENDCURRENTALPHA : return "D3DTOP_BLENDCURRENTALPHA"; - case D3DTOP_PREMODULATE : return "D3DTOP_PREMODULATE"; - case D3DTOP_MODULATEALPHA_ADDCOLOR : return "D3DTOP_MODULATEALPHA_ADDCOLOR"; - case D3DTOP_MODULATECOLOR_ADDALPHA : return "D3DTOP_MODULATECOLOR_ADDALPHA"; - case D3DTOP_MODULATEINVALPHA_ADDCOLOR : return "D3DTOP_MODULATEINVALPHA_ADDCOLOR"; - case D3DTOP_MODULATEINVCOLOR_ADDALPHA : return "D3DTOP_MODULATEINVCOLOR_ADDALPHA"; - case D3DTOP_BUMPENVMAP : return "D3DTOP_BUMPENVMAP"; - case D3DTOP_BUMPENVMAPLUMINANCE : return "D3DTOP_BUMPENVMAPLUMINANCE"; - case D3DTOP_DOTPRODUCT3 : return "D3DTOP_DOTPRODUCT3"; - case D3DTOP_MULTIPLYADD : return "D3DTOP_MULTIPLYADD"; - case D3DTOP_LERP : return "D3DTOP_LERP"; - default : return "UNKNOWN"; + case D3DTOP_DISABLE: return "D3DTOP_DISABLE"; + case D3DTOP_SELECTARG1: return "D3DTOP_SELECTARG1"; + case D3DTOP_SELECTARG2: return "D3DTOP_SELECTARG2"; + case D3DTOP_MODULATE: return "D3DTOP_MODULATE"; + case D3DTOP_MODULATE2X: return "D3DTOP_MODULATE2X"; + case D3DTOP_MODULATE4X: return "D3DTOP_MODULATE4X"; + case D3DTOP_ADD: return "D3DTOP_ADD"; + case D3DTOP_ADDSIGNED: return "D3DTOP_ADDSIGNED"; + case D3DTOP_ADDSIGNED2X: return "D3DTOP_ADDSIGNED2X"; + case D3DTOP_SUBTRACT: return "D3DTOP_SUBTRACT"; + case D3DTOP_ADDSMOOTH: return "D3DTOP_ADDSMOOTH"; + case D3DTOP_BLENDDIFFUSEALPHA: return "D3DTOP_BLENDDIFFUSEALPHA"; + case D3DTOP_BLENDTEXTUREALPHA: return "D3DTOP_BLENDTEXTUREALPHA"; + case D3DTOP_BLENDFACTORALPHA: return "D3DTOP_BLENDFACTORALPHA"; + case D3DTOP_BLENDTEXTUREALPHAPM: return "D3DTOP_BLENDTEXTUREALPHAPM"; + case D3DTOP_BLENDCURRENTALPHA: return "D3DTOP_BLENDCURRENTALPHA"; + case D3DTOP_PREMODULATE: return "D3DTOP_PREMODULATE"; + case D3DTOP_MODULATEALPHA_ADDCOLOR: return "D3DTOP_MODULATEALPHA_ADDCOLOR"; + case D3DTOP_MODULATECOLOR_ADDALPHA: return "D3DTOP_MODULATECOLOR_ADDALPHA"; + case D3DTOP_MODULATEINVALPHA_ADDCOLOR: return "D3DTOP_MODULATEINVALPHA_ADDCOLOR"; + case D3DTOP_MODULATEINVCOLOR_ADDALPHA: return "D3DTOP_MODULATEINVCOLOR_ADDALPHA"; + case D3DTOP_BUMPENVMAP: return "D3DTOP_BUMPENVMAP"; + case D3DTOP_BUMPENVMAPLUMINANCE: return "D3DTOP_BUMPENVMAPLUMINANCE"; + case D3DTOP_DOTPRODUCT3: return "D3DTOP_DOTPRODUCT3"; + case D3DTOP_MULTIPLYADD: return "D3DTOP_MULTIPLYADD"; + case D3DTOP_LERP: return "D3DTOP_LERP"; + default: return "UNKNOWN"; } } const char* DX8Wrapper::Get_DX8_Texture_Arg_Name(unsigned value) { switch (value) { - case D3DTA_CURRENT : return "D3DTA_CURRENT"; - case D3DTA_DIFFUSE : return "D3DTA_DIFFUSE"; - case D3DTA_SELECTMASK : return "D3DTA_SELECTMASK"; - case D3DTA_SPECULAR : return "D3DTA_SPECULAR"; - case D3DTA_TEMP : return "D3DTA_TEMP"; - case D3DTA_TEXTURE : return "D3DTA_TEXTURE"; - case D3DTA_TFACTOR : return "D3DTA_TFACTOR"; - case D3DTA_ALPHAREPLICATE : return "D3DTA_ALPHAREPLICATE"; - case D3DTA_COMPLEMENT : return "D3DTA_COMPLEMENT"; - default : return "UNKNOWN"; + case D3DTA_CURRENT: return "D3DTA_CURRENT"; + case D3DTA_DIFFUSE: return "D3DTA_DIFFUSE"; + case D3DTA_SELECTMASK: return "D3DTA_SELECTMASK"; + case D3DTA_SPECULAR: return "D3DTA_SPECULAR"; + case D3DTA_TEMP: return "D3DTA_TEMP"; + case D3DTA_TEXTURE: return "D3DTA_TEXTURE"; + case D3DTA_TFACTOR: return "D3DTA_TFACTOR"; + case D3DTA_ALPHAREPLICATE: return "D3DTA_ALPHAREPLICATE"; + case D3DTA_COMPLEMENT: return "D3DTA_COMPLEMENT"; + default: return "UNKNOWN"; } } const char* DX8Wrapper::Get_DX8_Texture_Filter_Name(unsigned value) { switch (value) { - case D3DTEXF_NONE : return "D3DTEXF_NONE"; - case D3DTEXF_POINT : return "D3DTEXF_POINT"; - case D3DTEXF_LINEAR : return "D3DTEXF_LINEAR"; - case D3DTEXF_ANISOTROPIC : return "D3DTEXF_ANISOTROPIC"; - case D3DTEXF_FLATCUBIC : return "D3DTEXF_FLATCUBIC"; - case D3DTEXF_GAUSSIANCUBIC : return "D3DTEXF_GAUSSIANCUBIC"; - default : return "UNKNOWN"; + case D3DTEXF_NONE: return "D3DTEXF_NONE"; + case D3DTEXF_POINT: return "D3DTEXF_POINT"; + case D3DTEXF_LINEAR: return "D3DTEXF_LINEAR"; + case D3DTEXF_ANISOTROPIC: return "D3DTEXF_ANISOTROPIC"; + case D3DTEXF_FLATCUBIC: return "D3DTEXF_FLATCUBIC"; + case D3DTEXF_GAUSSIANCUBIC: return "D3DTEXF_GAUSSIANCUBIC"; + default: return "UNKNOWN"; } } const char* DX8Wrapper::Get_DX8_Texture_Address_Name(unsigned value) { switch (value) { - case D3DTADDRESS_WRAP : return "D3DTADDRESS_WRAP"; - case D3DTADDRESS_MIRROR : return "D3DTADDRESS_MIRROR"; - case D3DTADDRESS_CLAMP : return "D3DTADDRESS_CLAMP"; - case D3DTADDRESS_BORDER : return "D3DTADDRESS_BORDER"; + case D3DTADDRESS_WRAP: return "D3DTADDRESS_WRAP"; + case D3DTADDRESS_MIRROR: return "D3DTADDRESS_MIRROR"; + case D3DTADDRESS_CLAMP: return "D3DTADDRESS_CLAMP"; + case D3DTADDRESS_BORDER: return "D3DTADDRESS_BORDER"; case D3DTADDRESS_MIRRORONCE: return "D3DTADDRESS_MIRRORONCE"; - default : return "UNKNOWN"; + default: return "UNKNOWN"; } } const char* DX8Wrapper::Get_DX8_Texture_Transform_Flag_Name(unsigned value) { switch (value) { - case D3DTTFF_DISABLE : return "D3DTTFF_DISABLE"; - case D3DTTFF_COUNT1 : return "D3DTTFF_COUNT1"; - case D3DTTFF_COUNT2 : return "D3DTTFF_COUNT2"; - case D3DTTFF_COUNT3 : return "D3DTTFF_COUNT3"; - case D3DTTFF_COUNT4 : return "D3DTTFF_COUNT4"; - case D3DTTFF_PROJECTED : return "D3DTTFF_PROJECTED"; - default : return "UNKNOWN"; + case D3DTTFF_DISABLE: return "D3DTTFF_DISABLE"; + case D3DTTFF_COUNT1: return "D3DTTFF_COUNT1"; + case D3DTTFF_COUNT2: return "D3DTTFF_COUNT2"; + case D3DTTFF_COUNT3: return "D3DTTFF_COUNT3"; + case D3DTTFF_COUNT4: return "D3DTTFF_COUNT4"; + case D3DTTFF_PROJECTED: return "D3DTTFF_PROJECTED"; + default: return "UNKNOWN"; } } const char* DX8Wrapper::Get_DX8_ZBuffer_Type_Name(unsigned value) { switch (value) { - case D3DZB_FALSE : return "D3DZB_FALSE"; - case D3DZB_TRUE : return "D3DZB_TRUE"; - case D3DZB_USEW : return "D3DZB_USEW"; - default : return "UNKNOWN"; + case D3DZB_FALSE: return "D3DZB_FALSE"; + case D3DZB_TRUE: return "D3DZB_TRUE"; + case D3DZB_USEW: return "D3DZB_USEW"; + default: return "UNKNOWN"; } } const char* DX8Wrapper::Get_DX8_Fill_Mode_Name(unsigned value) { switch (value) { - case D3DFILL_POINT : return "D3DFILL_POINT"; - case D3DFILL_WIREFRAME : return "D3DFILL_WIREFRAME"; - case D3DFILL_SOLID : return "D3DFILL_SOLID"; - default : return "UNKNOWN"; + case D3DFILL_POINT: return "D3DFILL_POINT"; + case D3DFILL_WIREFRAME: return "D3DFILL_WIREFRAME"; + case D3DFILL_SOLID: return "D3DFILL_SOLID"; + default: return "UNKNOWN"; } } const char* DX8Wrapper::Get_DX8_Shade_Mode_Name(unsigned value) { switch (value) { - case D3DSHADE_FLAT : return "D3DSHADE_FLAT"; - case D3DSHADE_GOURAUD : return "D3DSHADE_GOURAUD"; - case D3DSHADE_PHONG : return "D3DSHADE_PHONG"; - default : return "UNKNOWN"; + case D3DSHADE_FLAT: return "D3DSHADE_FLAT"; + case D3DSHADE_GOURAUD: return "D3DSHADE_GOURAUD"; + case D3DSHADE_PHONG: return "D3DSHADE_PHONG"; + default: return "UNKNOWN"; } } const char* DX8Wrapper::Get_DX8_Blend_Name(unsigned value) { switch (value) { - case D3DBLEND_ZERO : return "D3DBLEND_ZERO"; - case D3DBLEND_ONE : return "D3DBLEND_ONE"; - case D3DBLEND_SRCCOLOR : return "D3DBLEND_SRCCOLOR"; - case D3DBLEND_INVSRCCOLOR : return "D3DBLEND_INVSRCCOLOR"; - case D3DBLEND_SRCALPHA : return "D3DBLEND_SRCALPHA"; - case D3DBLEND_INVSRCALPHA : return "D3DBLEND_INVSRCALPHA"; - case D3DBLEND_DESTALPHA : return "D3DBLEND_DESTALPHA"; - case D3DBLEND_INVDESTALPHA : return "D3DBLEND_INVDESTALPHA"; - case D3DBLEND_DESTCOLOR : return "D3DBLEND_DESTCOLOR"; - case D3DBLEND_INVDESTCOLOR : return "D3DBLEND_INVDESTCOLOR"; - case D3DBLEND_SRCALPHASAT : return "D3DBLEND_SRCALPHASAT"; - case D3DBLEND_BOTHSRCALPHA : return "D3DBLEND_BOTHSRCALPHA"; - case D3DBLEND_BOTHINVSRCALPHA : return "D3DBLEND_BOTHINVSRCALPHA"; - default : return "UNKNOWN"; + case D3DBLEND_ZERO: return "D3DBLEND_ZERO"; + case D3DBLEND_ONE: return "D3DBLEND_ONE"; + case D3DBLEND_SRCCOLOR: return "D3DBLEND_SRCCOLOR"; + case D3DBLEND_INVSRCCOLOR: return "D3DBLEND_INVSRCCOLOR"; + case D3DBLEND_SRCALPHA: return "D3DBLEND_SRCALPHA"; + case D3DBLEND_INVSRCALPHA: return "D3DBLEND_INVSRCALPHA"; + case D3DBLEND_DESTALPHA: return "D3DBLEND_DESTALPHA"; + case D3DBLEND_INVDESTALPHA: return "D3DBLEND_INVDESTALPHA"; + case D3DBLEND_DESTCOLOR: return "D3DBLEND_DESTCOLOR"; + case D3DBLEND_INVDESTCOLOR: return "D3DBLEND_INVDESTCOLOR"; + case D3DBLEND_SRCALPHASAT: return "D3DBLEND_SRCALPHASAT"; + case D3DBLEND_BOTHSRCALPHA: return "D3DBLEND_BOTHSRCALPHA"; + case D3DBLEND_BOTHINVSRCALPHA: return "D3DBLEND_BOTHINVSRCALPHA"; + default: return "UNKNOWN"; } } const char* DX8Wrapper::Get_DX8_Cull_Mode_Name(unsigned value) { switch (value) { - case D3DCULL_NONE : return "D3DCULL_NONE"; - case D3DCULL_CW : return "D3DCULL_CW"; - case D3DCULL_CCW : return "D3DCULL_CCW"; - default : return "UNKNOWN"; + case D3DCULL_NONE: return "D3DCULL_NONE"; + case D3DCULL_CW: return "D3DCULL_CW"; + case D3DCULL_CCW: return "D3DCULL_CCW"; + default: return "UNKNOWN"; } } const char* DX8Wrapper::Get_DX8_Cmp_Func_Name(unsigned value) { switch (value) { - case D3DCMP_NEVER : return "D3DCMP_NEVER"; - case D3DCMP_LESS : return "D3DCMP_LESS"; - case D3DCMP_EQUAL : return "D3DCMP_EQUAL"; - case D3DCMP_LESSEQUAL : return "D3DCMP_LESSEQUAL"; - case D3DCMP_GREATER : return "D3DCMP_GREATER"; - case D3DCMP_NOTEQUAL : return "D3DCMP_NOTEQUAL"; - case D3DCMP_GREATEREQUAL : return "D3DCMP_GREATEREQUAL"; - case D3DCMP_ALWAYS : return "D3DCMP_ALWAYS"; - default : return "UNKNOWN"; + case D3DCMP_NEVER: return "D3DCMP_NEVER"; + case D3DCMP_LESS: return "D3DCMP_LESS"; + case D3DCMP_EQUAL: return "D3DCMP_EQUAL"; + case D3DCMP_LESSEQUAL: return "D3DCMP_LESSEQUAL"; + case D3DCMP_GREATER: return "D3DCMP_GREATER"; + case D3DCMP_NOTEQUAL: return "D3DCMP_NOTEQUAL"; + case D3DCMP_GREATEREQUAL: return "D3DCMP_GREATEREQUAL"; + case D3DCMP_ALWAYS: return "D3DCMP_ALWAYS"; + default: return "UNKNOWN"; } } const char* DX8Wrapper::Get_DX8_Fog_Mode_Name(unsigned value) { switch (value) { - case D3DFOG_NONE : return "D3DFOG_NONE"; - case D3DFOG_EXP : return "D3DFOG_EXP"; - case D3DFOG_EXP2 : return "D3DFOG_EXP2"; - case D3DFOG_LINEAR : return "D3DFOG_LINEAR"; - default : return "UNKNOWN"; + case D3DFOG_NONE: return "D3DFOG_NONE"; + case D3DFOG_EXP: return "D3DFOG_EXP"; + case D3DFOG_EXP2: return "D3DFOG_EXP2"; + case D3DFOG_LINEAR: return "D3DFOG_LINEAR"; + default: return "UNKNOWN"; } } const char* DX8Wrapper::Get_DX8_Stencil_Op_Name(unsigned value) { switch (value) { - case D3DSTENCILOP_KEEP : return "D3DSTENCILOP_KEEP"; - case D3DSTENCILOP_ZERO : return "D3DSTENCILOP_ZERO"; - case D3DSTENCILOP_REPLACE : return "D3DSTENCILOP_REPLACE"; - case D3DSTENCILOP_INCRSAT : return "D3DSTENCILOP_INCRSAT"; - case D3DSTENCILOP_DECRSAT : return "D3DSTENCILOP_DECRSAT"; - case D3DSTENCILOP_INVERT : return "D3DSTENCILOP_INVERT"; - case D3DSTENCILOP_INCR : return "D3DSTENCILOP_INCR"; - case D3DSTENCILOP_DECR : return "D3DSTENCILOP_DECR"; - default : return "UNKNOWN"; + case D3DSTENCILOP_KEEP: return "D3DSTENCILOP_KEEP"; + case D3DSTENCILOP_ZERO: return "D3DSTENCILOP_ZERO"; + case D3DSTENCILOP_REPLACE: return "D3DSTENCILOP_REPLACE"; + case D3DSTENCILOP_INCRSAT: return "D3DSTENCILOP_INCRSAT"; + case D3DSTENCILOP_DECRSAT: return "D3DSTENCILOP_DECRSAT"; + case D3DSTENCILOP_INVERT: return "D3DSTENCILOP_INVERT"; + case D3DSTENCILOP_INCR: return "D3DSTENCILOP_INCR"; + case D3DSTENCILOP_DECR: return "D3DSTENCILOP_DECR"; + default: return "UNKNOWN"; } } const char* DX8Wrapper::Get_DX8_Material_Source_Name(unsigned value) { switch (value) { - case D3DMCS_MATERIAL : return "D3DMCS_MATERIAL"; - case D3DMCS_COLOR1 : return "D3DMCS_COLOR1"; - case D3DMCS_COLOR2 : return "D3DMCS_COLOR2"; - default : return "UNKNOWN"; + case D3DMCS_MATERIAL: return "D3DMCS_MATERIAL"; + case D3DMCS_COLOR1: return "D3DMCS_COLOR1"; + case D3DMCS_COLOR2: return "D3DMCS_COLOR2"; + default: return "UNKNOWN"; } } const char* DX8Wrapper::Get_DX8_Vertex_Blend_Flag_Name(unsigned value) { switch (value) { - case D3DVBF_DISABLE : return "D3DVBF_DISABLE"; - case D3DVBF_1WEIGHTS : return "D3DVBF_1WEIGHTS"; - case D3DVBF_2WEIGHTS : return "D3DVBF_2WEIGHTS"; - case D3DVBF_3WEIGHTS : return "D3DVBF_3WEIGHTS"; - case D3DVBF_TWEENING : return "D3DVBF_TWEENING"; - case D3DVBF_0WEIGHTS : return "D3DVBF_0WEIGHTS"; - default : return "UNKNOWN"; + case D3DVBF_DISABLE: return "D3DVBF_DISABLE"; + case D3DVBF_1WEIGHTS: return "D3DVBF_1WEIGHTS"; + case D3DVBF_2WEIGHTS: return "D3DVBF_2WEIGHTS"; + case D3DVBF_3WEIGHTS: return "D3DVBF_3WEIGHTS"; + case D3DVBF_TWEENING: return "D3DVBF_TWEENING"; + case D3DVBF_0WEIGHTS: return "D3DVBF_0WEIGHTS"; + default: return "UNKNOWN"; } } const char* DX8Wrapper::Get_DX8_Patch_Edge_Style_Name(unsigned value) { switch (value) { - case D3DPATCHEDGE_DISCRETE : return "D3DPATCHEDGE_DISCRETE"; - case D3DPATCHEDGE_CONTINUOUS:return "D3DPATCHEDGE_CONTINUOUS"; - default : return "UNKNOWN"; + case D3DPATCHEDGE_DISCRETE: return "D3DPATCHEDGE_DISCRETE"; + case D3DPATCHEDGE_CONTINUOUS:return "D3DPATCHEDGE_CONTINUOUS"; + default: return "UNKNOWN"; } } const char* DX8Wrapper::Get_DX8_Debug_Monitor_Token_Name(unsigned value) { switch (value) { - case D3DDMT_ENABLE : return "D3DDMT_ENABLE"; - case D3DDMT_DISABLE : return "D3DDMT_DISABLE"; - default : return "UNKNOWN"; + case D3DDMT_ENABLE: return "D3DDMT_ENABLE"; + case D3DDMT_DISABLE: return "D3DDMT_DISABLE"; + default: return "UNKNOWN"; } } const char* DX8Wrapper::Get_DX8_Blend_Op_Name(unsigned value) { switch (value) { - case D3DBLENDOP_ADD : return "D3DBLENDOP_ADD"; - case D3DBLENDOP_SUBTRACT : return "D3DBLENDOP_SUBTRACT"; + case D3DBLENDOP_ADD: return "D3DBLENDOP_ADD"; + case D3DBLENDOP_SUBTRACT: return "D3DBLENDOP_SUBTRACT"; case D3DBLENDOP_REVSUBTRACT: return "D3DBLENDOP_REVSUBTRACT"; - case D3DBLENDOP_MIN : return "D3DBLENDOP_MIN"; - case D3DBLENDOP_MAX : return "D3DBLENDOP_MAX"; - default : return "UNKNOWN"; + case D3DBLENDOP_MIN: return "D3DBLENDOP_MIN"; + case D3DBLENDOP_MAX: return "D3DBLENDOP_MAX"; + default: return "UNKNOWN"; } } @@ -4473,7 +4491,7 @@ const char* DX8Wrapper::Get_DX8_Blend_Op_Name(unsigned value) // DX8Wrapper::getBackBufferFormat //============================================================================ -WW3DFormat DX8Wrapper::getBackBufferFormat( void ) +WW3DFormat DX8Wrapper::getBackBufferFormat(void) { - return D3DFormat_To_WW3DFormat( _PresentParameters.BackBufferFormat ); + return D3DFormat_To_WW3DFormat(_PresentParameters.BackBufferFormat); } diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h b/Core/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h similarity index 61% rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h rename to Core/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h index 9f643d89b6..414256e15a 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h +++ b/Core/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h @@ -26,15 +26,15 @@ * * * Original Author:: Jani Penttinen * * * - * Author : Kenny Mitchell * - * * + * Author : Kenny Mitchell * + * * * $Modtime:: 08/05/02 2:40p $* * * * $Revision:: 92 $* * * * 06/26/02 KM Matrix name change to avoid MAX conflicts * * 06/27/02 KM Render to shadow buffer texture support * - * 08/05/02 KM Texture class redesign + * 08/05/02 KM Texture class redesign *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -63,9 +63,9 @@ #include "dx8indexbuffer.h" #include "vertmaterial.h" -/* -** Registry value names -*/ + /* + ** Registry value names + */ #define VALUE_NAME_RENDER_DEVICE_NAME "RenderDeviceName" #define VALUE_NAME_RENDER_DEVICE_WIDTH "RenderDeviceWidth" #define VALUE_NAME_RENDER_DEVICE_HEIGHT "RenderDeviceHeight" @@ -73,11 +73,11 @@ #define VALUE_NAME_RENDER_DEVICE_WINDOWED "RenderDeviceWindowed" #define VALUE_NAME_RENDER_DEVICE_TEXTURE_DEPTH "RenderDeviceTextureDepth" -const unsigned MAX_TEXTURE_STAGES=8; -const unsigned MAX_VERTEX_STREAMS=2; -const unsigned MAX_VERTEX_SHADER_CONSTANTS=96; -const unsigned MAX_PIXEL_SHADER_CONSTANTS=8; -const unsigned MAX_SHADOW_MAPS=1; +const unsigned MAX_TEXTURE_STAGES = 8; +const unsigned MAX_VERTEX_STREAMS = 2; +const unsigned MAX_VERTEX_SHADER_CONSTANTS = 96; +const unsigned MAX_PIXEL_SHADER_CONSTANTS = 8; +const unsigned MAX_SHADOW_MAPS = 1; #define prevVer #define nextVer @@ -123,7 +123,7 @@ void Log_DX8_ErrorCode(unsigned res); WWINLINE void DX8_ErrorCode(unsigned res) { - if (res==D3D_OK) return; + if (res == D3D_OK) return; Log_DX8_ErrorCode(res); } @@ -171,8 +171,8 @@ class DX8_Stats class DX8_CleanupHook { public: - virtual void ReleaseResources(void)=0; - virtual void ReAcquireResources(void)=0; + virtual void ReleaseResources(void) = 0; + virtual void ReAcquireResources(void) = 0; }; @@ -180,10 +180,10 @@ struct RenderStateStruct { ShaderClass shader; VertexMaterialClass* material; - TextureBaseClass * Textures[MAX_TEXTURE_STAGES]; + TextureBaseClass* Textures[MAX_TEXTURE_STAGES]; D3DLIGHT8 Lights[4]; bool LightEnable[4]; - //unsigned lightsHash; + //unsigned lightsHash; Matrix4x4 world; Matrix4x4 view; unsigned vertex_buffer_types[MAX_VERTEX_STREAMS]; @@ -212,27 +212,27 @@ struct RenderStateStruct class DX8Wrapper { enum ChangedStates { - WORLD_CHANGED = 1<<0, - VIEW_CHANGED = 1<<1, - LIGHT0_CHANGED = 1<<2, - LIGHT1_CHANGED = 1<<3, - LIGHT2_CHANGED = 1<<4, - LIGHT3_CHANGED = 1<<5, - TEXTURE0_CHANGED= 1<<6, - TEXTURE1_CHANGED= 1<<7, - TEXTURE2_CHANGED= 1<<8, - TEXTURE3_CHANGED= 1<<9, - MATERIAL_CHANGED= 1<<14, - SHADER_CHANGED = 1<<15, - VERTEX_BUFFER_CHANGED = 1<<16, + WORLD_CHANGED = 1 << 0, + VIEW_CHANGED = 1 << 1, + LIGHT0_CHANGED = 1 << 2, + LIGHT1_CHANGED = 1 << 3, + LIGHT2_CHANGED = 1 << 4, + LIGHT3_CHANGED = 1 << 5, + TEXTURE0_CHANGED = 1 << 6, + TEXTURE1_CHANGED = 1 << 7, + TEXTURE2_CHANGED = 1 << 8, + TEXTURE3_CHANGED = 1 << 9, + MATERIAL_CHANGED = 1 << 14, + SHADER_CHANGED = 1 << 15, + VERTEX_BUFFER_CHANGED = 1 << 16, INDEX_BUFFER_CHANGED = 1 << 17, - WORLD_IDENTITY= 1<<18, - VIEW_IDENTITY= 1<<19, + WORLD_IDENTITY = 1 << 18, + VIEW_IDENTITY = 1 << 19, - TEXTURES_CHANGED= - TEXTURE0_CHANGED|TEXTURE1_CHANGED|TEXTURE2_CHANGED|TEXTURE3_CHANGED, - LIGHTS_CHANGED= - LIGHT0_CHANGED|LIGHT1_CHANGED|LIGHT2_CHANGED|LIGHT3_CHANGED, + TEXTURES_CHANGED = + TEXTURE0_CHANGED | TEXTURE1_CHANGED | TEXTURE2_CHANGED | TEXTURE3_CHANGED, + LIGHTS_CHANGED = + LIGHT0_CHANGED | LIGHT1_CHANGED | LIGHT2_CHANGED | LIGHT3_CHANGED, }; static void Draw_Sorting_IB_VB( @@ -246,18 +246,18 @@ class DX8Wrapper unsigned primitive_type, unsigned short start_index, unsigned short polygon_count, - unsigned short min_vertex_index=0, - unsigned short vertex_count=0); + unsigned short min_vertex_index = 0, + unsigned short vertex_count = 0); public: #ifdef EXTENDED_STATS static DX8_Stats stats; #endif - static bool Init(void * hwnd, bool lite = false); + static bool Init(void* hwnd, bool lite = false); static void Shutdown(void); - static void SetCleanupHook(DX8_CleanupHook *pCleanupHook) {m_pCleanupHook = pCleanupHook;}; + static void SetCleanupHook(DX8_CleanupHook* pCleanupHook) { m_pCleanupHook = pCleanupHook; }; /* ** Some WW3D sub-systems need to be initialized after the device is created and shutdown ** before the device is released. @@ -268,8 +268,8 @@ class DX8Wrapper static bool Is_Device_Lost() { return IsDeviceLost; } static bool Is_Initted(void) { return IsInitted; } - static bool Has_Stencil (void); - static void Get_Format_Name(unsigned int format, StringClass *tex_format); + static bool Has_Stencil(void); + static void Get_Format_Name(unsigned int format, StringClass* tex_format); /* ** Rendering @@ -280,14 +280,14 @@ class DX8Wrapper // Flip until the primary buffer is visible. static void Flip_To_Primary(void); - static void Clear(bool clear_color, bool clear_z_stencil, const Vector3 &color, float dest_alpha=0.0f, float z=1.0f, unsigned int stencil=0); + static void Clear(bool clear_color, bool clear_z_stencil, const Vector3& color, float dest_alpha = 0.0f, float z = 1.0f, unsigned int stencil = 0); static void Set_Viewport(CONST D3DVIEWPORT8* pViewport); - static void Set_Vertex_Buffer(const VertexBufferClass* vb, unsigned stream=0); + static void Set_Vertex_Buffer(const VertexBufferClass* vb, unsigned stream = 0); static void Set_Vertex_Buffer(const DynamicVBAccessClass& vba); - static void Set_Index_Buffer(const IndexBufferClass* ib,unsigned short index_base_offset); - static void Set_Index_Buffer(const DynamicIBAccessClass& iba,unsigned short index_base_offset); + static void Set_Index_Buffer(const IndexBufferClass* ib, unsigned short index_base_offset); + static void Set_Index_Buffer(const DynamicIBAccessClass& iba, unsigned short index_base_offset); static void Set_Index_Buffer_Index_Offset(unsigned offset); static void Get_Render_State(RenderStateStruct& state); @@ -296,15 +296,15 @@ class DX8Wrapper static void Set_DX8_Material(const D3DMATERIAL8* mat); - static void Set_Gamma(float gamma,float bright,float contrast,bool calibrate=true,bool uselimit=true); + static void Set_Gamma(float gamma, float bright, float contrast, bool calibrate = true, bool uselimit = true); // Set_ and Get_Transform() functions take the matrix in Westwood convention format. static void Set_DX8_ZBias(int zbias); - static void Set_Projection_Transform_With_Z_Bias(const Matrix4x4& matrix,float znear, float zfar); // pointer to 16 matrices + static void Set_Projection_Transform_With_Z_Bias(const Matrix4x4& matrix, float znear, float zfar); // pointer to 16 matrices - static void Set_Transform(D3DTRANSFORMSTATETYPE transform,const Matrix4x4& m); - static void Set_Transform(D3DTRANSFORMSTATETYPE transform,const Matrix3D& m); + static void Set_Transform(D3DTRANSFORMSTATETYPE transform, const Matrix4x4& m); + static void Set_Transform(D3DTRANSFORMSTATETYPE transform, const Matrix3D& m); static void Get_Transform(D3DTRANSFORMSTATETYPE transform, Matrix4x4& m); static void Set_World_Identity(); static void Set_View_Identity(); @@ -313,18 +313,18 @@ class DX8Wrapper // Note that *_DX8_Transform() functions take the matrix in DX8 format - transposed from Westwood convention. - static void _Set_DX8_Transform(D3DTRANSFORMSTATETYPE transform,const Matrix4x4& m); - static void _Set_DX8_Transform(D3DTRANSFORMSTATETYPE transform,const Matrix3D& m); + static void _Set_DX8_Transform(D3DTRANSFORMSTATETYPE transform, const Matrix4x4& m); + static void _Set_DX8_Transform(D3DTRANSFORMSTATETYPE transform, const Matrix3D& m); static void _Get_DX8_Transform(D3DTRANSFORMSTATETYPE transform, Matrix4x4& m); - static void Set_DX8_Light(int index,D3DLIGHT8* light); + static void Set_DX8_Light(int index, D3DLIGHT8* light); static void Set_DX8_Render_State(D3DRENDERSTATETYPE state, unsigned value); static void Set_DX8_Clip_Plane(DWORD Index, CONST float* pPlane); static void Set_DX8_Texture_Stage_State(unsigned stage, D3DTEXTURESTAGESTATETYPE state, unsigned value); static void Set_DX8_Texture(unsigned int stage, IDirect3DBaseTexture8* texture); static void Set_Light_Environment(LightEnvironmentClass* light_env); static LightEnvironmentClass* Get_Light_Environment() { return Light_Environment; } - static void Set_Fog(bool enable, const Vector3 &color, float start, float end); + static void Set_Fog(bool enable, const Vector3& color, float start, float end); static WWINLINE const D3DLIGHT8& Peek_Light(unsigned index); static WWINLINE bool Is_Light_Enabled(unsigned index); @@ -335,10 +335,10 @@ class DX8Wrapper static void Set_Shader(const ShaderClass& shader); static void Get_Shader(ShaderClass& shader); - static void Set_Texture(unsigned stage,TextureBaseClass* texture); + static void Set_Texture(unsigned stage, TextureBaseClass* texture); static void Set_Material(const VertexMaterialClass* material); - static void Set_Light(unsigned index,const D3DLIGHT8* light); - static void Set_Light(unsigned index,const LightClass &light); + static void Set_Light(unsigned index, const D3DLIGHT8* light); + static void Set_Light(unsigned index, const LightClass& light); static void Apply_Render_State_Changes(); // Apply deferred render state changes (will be called automatically by Draw...) @@ -370,7 +370,7 @@ class DX8Wrapper unsigned int depth, WW3DFormat format, MipCountType mip_level_count, - D3DPOOL pool=D3DPOOL_MANAGED + D3DPOOL pool = D3DPOOL_MANAGED ); static IDirect3DCubeTexture8* _Create_DX8_Cube_Texture @@ -379,8 +379,8 @@ class DX8Wrapper unsigned int height, WW3DFormat format, MipCountType mip_level_count, - D3DPOOL pool=D3DPOOL_MANAGED, - bool rendertarget=false + D3DPOOL pool = D3DPOOL_MANAGED, + bool rendertarget = false ); @@ -390,37 +390,37 @@ class DX8Wrapper unsigned int height, WW3DZFormat zformat, MipCountType mip_level_count, - D3DPOOL pool=D3DPOOL_MANAGED + D3DPOOL pool = D3DPOOL_MANAGED ); - static IDirect3DTexture8 * _Create_DX8_Texture + static IDirect3DTexture8* _Create_DX8_Texture ( unsigned int width, unsigned int height, WW3DFormat format, MipCountType mip_level_count, - D3DPOOL pool=D3DPOOL_MANAGED, - bool rendertarget=false + D3DPOOL pool = D3DPOOL_MANAGED, + bool rendertarget = false ); - static IDirect3DTexture8 * _Create_DX8_Texture(const char *filename, MipCountType mip_level_count); - static IDirect3DTexture8 * _Create_DX8_Texture(IDirect3DSurface8 *surface, MipCountType mip_level_count); + static IDirect3DTexture8* _Create_DX8_Texture(const char* filename, MipCountType mip_level_count); + static IDirect3DTexture8* _Create_DX8_Texture(IDirect3DSurface8* surface, MipCountType mip_level_count); - static IDirect3DSurface8 * _Create_DX8_Surface(unsigned int width, unsigned int height, WW3DFormat format); - static IDirect3DSurface8 * _Create_DX8_Surface(const char *filename); - static IDirect3DSurface8 * _Get_DX8_Front_Buffer(); - static SurfaceClass * _Get_DX8_Back_Buffer(unsigned int num=0); + static IDirect3DSurface8* _Create_DX8_Surface(unsigned int width, unsigned int height, WW3DFormat format); + static IDirect3DSurface8* _Create_DX8_Surface(const char* filename); + static IDirect3DSurface8* _Get_DX8_Front_Buffer(); + static SurfaceClass* _Get_DX8_Back_Buffer(unsigned int num = 0); static void _Copy_DX8_Rects( - IDirect3DSurface8* pSourceSurface, - CONST RECT* pSourceRectsArray, - UINT cRects, - IDirect3DSurface8* pDestinationSurface, - CONST POINT* pDestPointsArray + IDirect3DSurface8* pSourceSurface, + CONST RECT* pSourceRectsArray, + UINT cRects, + IDirect3DSurface8* pDestinationSurface, + CONST POINT* pDestPointsArray ); - static void _Update_Texture(TextureClass *system, TextureClass *video); - static void Flush_DX8_Resource_Manager(unsigned int bytes=0); + static void _Update_Texture(TextureClass* system, TextureClass* video); + static void Flush_DX8_Resource_Manager(unsigned int bytes = 0); static unsigned int Get_Free_Texture_RAM(); static unsigned _Get_Main_Thread_ID() { return _MainThreadID; } @@ -455,9 +455,9 @@ class DX8Wrapper static void Clamp_Color(Vector4& color); static unsigned int Convert_Color_Clamp(const Vector4& color); - static void Set_Alpha (const float alpha, unsigned int &color); + static void Set_Alpha(const float alpha, unsigned int& color); - static void _Enable_Triangle_Draw(bool enable) { _EnableTriangleDraw=enable; } + static void _Enable_Triangle_Draw(bool enable) { _EnableTriangleDraw = enable; } static bool _Is_Triangle_Draw_Enabled() { return _EnableTriangleDraw; } /* @@ -478,32 +478,32 @@ class DX8Wrapper ** DX8Wrapper::Set_Render_Target ((IDirect3DSurface8 *)NULL); ** */ - static IDirect3DSwapChain8 * Create_Additional_Swap_Chain (HWND render_window); + static IDirect3DSwapChain8* Create_Additional_Swap_Chain(HWND render_window); /* ** Render target interface. If render target format is WW3D_FORMAT_UNKNOWN, current display format is used. */ - static TextureClass * Create_Render_Target (int width, int height, WW3DFormat format = WW3D_FORMAT_UNKNOWN); + static TextureClass* Create_Render_Target(int width, int height, WW3DFormat format = WW3D_FORMAT_UNKNOWN); - static void Set_Render_Target (IDirect3DSurface8 *render_target, bool use_default_depth_buffer = false); - static void Set_Render_Target (IDirect3DSurface8* render_target, IDirect3DSurface8* dpeth_buffer); + static void Set_Render_Target(IDirect3DSurface8* render_target, bool use_default_depth_buffer = false); + static void Set_Render_Target(IDirect3DSurface8* render_target, IDirect3DSurface8* dpeth_buffer); - static void Set_Render_Target (IDirect3DSwapChain8 *swap_chain); + static void Set_Render_Target(IDirect3DSwapChain8* swap_chain); static bool Is_Render_To_Texture(void) { return IsRenderToTexture; } // for depth map support KJM V static void Create_Render_Target ( - int width, - int height, + int width, + int height, WW3DFormat format, WW3DZFormat zformat, TextureClass** target, ZTextureClass** depth_buffer ); - static void Set_Render_Target_With_Z (TextureClass * texture, ZTextureClass* ztexture=NULL); + static void Set_Render_Target_With_Z(TextureClass* texture, ZTextureClass* ztexture = NULL); - static void Set_Shadow_Map(int idx, ZTextureClass* ztex) { Shadow_Map[idx]=ztex; } + static void Set_Shadow_Map(int idx, ZTextureClass* ztex) { Shadow_Map[idx] = ztex; } static ZTextureClass* Get_Shadow_Map(int idx) { return Shadow_Map[idx]; } // for depth map support KJM ^ @@ -520,7 +520,7 @@ class DX8Wrapper // Needed by scene lighting class static void Set_Ambient(const Vector3& color); - static const Vector3& Get_Ambient() { return Ambient_Color; } + static const Vector3& Get_Ambient() { return Ambient_Color; } // shader system updates KJM ^ @@ -529,13 +529,13 @@ class DX8Wrapper static IDirect3DDevice8* _Get_D3D_Device8() { return D3DDevice; } static IDirect3D8* _Get_D3D8() { return D3DInterface; } /// Returns the display format - added by TR for video playback - not part of W3D - static WW3DFormat getBackBufferFormat( void ); - static bool Reset_Device(bool reload_assets=true); + static WW3DFormat getBackBufferFormat(void); + static bool Reset_Device(bool reload_assets = true); - static const DX8Caps* Get_Current_Caps() { WWASSERT(CurrentCaps); return CurrentCaps; } + static const DX8Caps* Get_Current_Caps() { WWASSERT(CurrentCaps); return CurrentCaps; } - static bool Registry_Save_Render_Device( const char * sub_key ); - static bool Registry_Load_Render_Device( const char * sub_key, bool resize_window ); + static bool Registry_Save_Render_Device(const char* sub_key); + static bool Registry_Load_Render_Device(const char* sub_key, bool resize_window); static const char* Get_DX8_Render_State_Name(D3DRENDERSTATETYPE state); static const char* Get_DX8_Texture_Stage_State_Name(D3DTEXTURESTAGESTATETYPE state); @@ -566,7 +566,7 @@ class DX8Wrapper static void Invalidate_Cached_Render_States(void); - static void Set_Draw_Polygon_Low_Bound_Limit(unsigned n) { DrawPolygonLowBoundLimit=n; } + static void Set_Draw_Polygon_Low_Bound_Limit(unsigned n) { DrawPolygonLowBoundLimit = n; } protected: @@ -583,27 +583,27 @@ class DX8Wrapper ** header file. These functions are protected so that we aren't exposing two interfaces. */ static bool Set_Any_Render_Device(void); - static bool Set_Render_Device(const char * dev_name,int width=-1,int height=-1,int bits=-1,int windowed=-1,bool resize_window=false); - static bool Set_Render_Device(int dev=-1,int resx=-1,int resy=-1,int bits=-1,int windowed=-1,bool resize_window = false, bool reset_device = false, bool restore_assets=true); + static bool Set_Render_Device(const char* dev_name, int width = -1, int height = -1, int bits = -1, int windowed = -1, bool resize_window = false); + static bool Set_Render_Device(int dev = -1, int resx = -1, int resy = -1, int bits = -1, int windowed = -1, bool resize_window = false, bool reset_device = false, bool restore_assets = true); static bool Set_Next_Render_Device(void); static bool Toggle_Windowed(void); static int Get_Render_Device_Count(void); static int Get_Render_Device(void); - static const RenderDeviceDescClass & Get_Render_Device_Desc(int deviceidx); - static const char * Get_Render_Device_Name(int device_index); - static bool Set_Device_Resolution(int width=-1,int height=-1,int bits=-1,int windowed=-1, bool resize_window=false); - static void Get_Device_Resolution(int & set_w,int & set_h,int & set_bits,bool & set_windowed); - static void Get_Render_Target_Resolution(int & set_w,int & set_h,int & set_bits,bool & set_windowed); + static const RenderDeviceDescClass& Get_Render_Device_Desc(int deviceidx); + static const char* Get_Render_Device_Name(int device_index); + static bool Set_Device_Resolution(int width = -1, int height = -1, int bits = -1, int windowed = -1, bool resize_window = false); + static void Get_Device_Resolution(int& set_w, int& set_h, int& set_bits, bool& set_windowed); + static void Get_Render_Target_Resolution(int& set_w, int& set_h, int& set_bits, bool& set_windowed); static int Get_Device_Resolution_Width(void) { return ResolutionWidth; } static int Get_Device_Resolution_Height(void) { return ResolutionHeight; } - static bool Registry_Save_Render_Device( const char *sub_key, int device, int width, int height, int depth, bool windowed, int texture_depth); - static bool Registry_Load_Render_Device( const char * sub_key, char *device, int device_len, int &width, int &height, int &depth, int &windowed, int &texture_depth); + static bool Registry_Save_Render_Device(const char* sub_key, int device, int width, int height, int depth, bool windowed, int texture_depth); + static bool Registry_Load_Render_Device(const char* sub_key, char* device, int device_len, int& width, int& height, int& depth, int& windowed, int& texture_depth); static bool Is_Windowed(void) { return IsWindowed; } - static void Set_Texture_Bitdepth(int depth) { WWASSERT(depth==16 || depth==32); TextureBitDepth = depth; } - static int Get_Texture_Bitdepth(void) { return TextureBitDepth; } + static void Set_Texture_Bitdepth(int depth) { WWASSERT(depth == 16 || depth == 32); TextureBitDepth = depth; } + static int Get_Texture_Bitdepth(void) { return TextureBitDepth; } static void Set_Swap_Interval(int swap); static int Get_Swap_Interval(void); @@ -613,25 +613,25 @@ class DX8Wrapper ** Internal functions */ static void Resize_And_Position_Window(); - static bool Find_Color_And_Z_Mode(int resx,int resy,int bitdepth,D3DFORMAT * set_colorbuffer,D3DFORMAT * set_backbuffer, D3DFORMAT * set_zmode); - static bool Find_Color_Mode(D3DFORMAT colorbuffer, int resx, int resy, UINT *mode); - static bool Find_Z_Mode(D3DFORMAT colorbuffer,D3DFORMAT backbuffer, D3DFORMAT *zmode); - static bool Test_Z_Mode(D3DFORMAT colorbuffer,D3DFORMAT backbuffer, D3DFORMAT zmode); + static bool Find_Color_And_Z_Mode(int resx, int resy, int bitdepth, D3DFORMAT* set_colorbuffer, D3DFORMAT* set_backbuffer, D3DFORMAT* set_zmode); + static bool Find_Color_Mode(D3DFORMAT colorbuffer, int resx, int resy, UINT* mode); + static bool Find_Z_Mode(D3DFORMAT colorbuffer, D3DFORMAT backbuffer, D3DFORMAT* zmode); + static bool Test_Z_Mode(D3DFORMAT colorbuffer, D3DFORMAT backbuffer, D3DFORMAT zmode); static void Compute_Caps(WW3DFormat display_format); /* ** Protected Member Variables */ - static DX8_CleanupHook *m_pCleanupHook; + static DX8_CleanupHook* m_pCleanupHook; static RenderStateStruct render_state; static unsigned render_state_changed; - static Matrix4x4 DX8Transforms[D3DTS_WORLD+1]; + static Matrix4x4 DX8Transforms[D3DTS_WORLD + 1]; static bool IsInitted; static bool IsDeviceLost; - static void * Hwnd; + static void* Hwnd; static unsigned _MainThreadID; static bool _EnableTriangleDraw; @@ -643,7 +643,7 @@ class DX8Wrapper static int TextureBitDepth; static bool IsWindowed; static D3DFORMAT DisplayFormat; - + static D3DMATRIX old_world; static D3DMATRIX old_view; static D3DMATRIX old_prj; @@ -655,12 +655,12 @@ class DX8Wrapper static Vector4 Vertex_Shader_Constants[MAX_VERTEX_SHADER_CONSTANTS]; static Vector4 Pixel_Shader_Constants[MAX_PIXEL_SHADER_CONSTANTS]; - static LightEnvironmentClass* Light_Environment; - static RenderInfoClass* Render_Info; + static LightEnvironmentClass* Light_Environment; + static RenderInfoClass* Render_Info; static DWORD Vertex_Processing_Behavior; - static ZTextureClass* Shadow_Map[MAX_SHADOW_MAPS]; + static ZTextureClass* Shadow_Map[MAX_SHADOW_MAPS]; static Vector3 Ambient_Color; // shader system updates KJM ^ @@ -668,7 +668,7 @@ class DX8Wrapper static bool world_identity; static unsigned RenderStates[256]; static unsigned TextureStageStates[MAX_TEXTURE_STAGES][32]; - static IDirect3DBaseTexture8 * Textures[MAX_TEXTURE_STAGES]; + static IDirect3DBaseTexture8* Textures[MAX_TEXTURE_STAGES]; // These fog settings are constant for all objects in a given scene, // unlike the matching renderstates which vary based on shader settings. @@ -688,17 +688,17 @@ class DX8Wrapper static unsigned long FrameCount; - static DX8Caps* CurrentCaps; + static DX8Caps* CurrentCaps; static D3DADAPTER_IDENTIFIER8 CurrentAdapterIdentifier; - static IDirect3D8 * D3DInterface; //d3d8; - static IDirect3DDevice8 * D3DDevice; //d3ddevice8; + static IDirect3D8* D3DInterface; //d3d8; + static IDirect3DDevice8* D3DDevice; //d3ddevice8; - static IDirect3DSurface8 * CurrentRenderTarget; - static IDirect3DSurface8 * CurrentDepthBuffer; - static IDirect3DSurface8 * DefaultRenderTarget; - static IDirect3DSurface8 * DefaultDepthBuffer; + static IDirect3DSurface8* CurrentRenderTarget; + static IDirect3DSurface8* CurrentDepthBuffer; + static IDirect3DSurface8* DefaultRenderTarget; + static IDirect3DSurface8* DefaultDepthBuffer; static unsigned DrawPolygonLowBoundLimit; @@ -720,79 +720,79 @@ WWINLINE void DX8Wrapper::Set_Vertex_Shader(DWORD vertex_shader) { #if 0 //(gth) some code is bypassing this acessor function so we can't count on this variable... // may be incorrect if shaders are created and destroyed dynamically - if (Vertex_Shader==vertex_shader) return; + if (Vertex_Shader == vertex_shader) return; #endif - Vertex_Shader=vertex_shader; + Vertex_Shader = vertex_shader; DX8CALL(SetVertexShader(Vertex_Shader)); } WWINLINE void DX8Wrapper::Set_Pixel_Shader(DWORD pixel_shader) { // may be incorrect if shaders are created and destroyed dynamically - if (Pixel_Shader==pixel_shader) return; + if (Pixel_Shader == pixel_shader) return; - Pixel_Shader=pixel_shader; + Pixel_Shader = pixel_shader; DX8CALL(SetPixelShader(Pixel_Shader)); } WWINLINE void DX8Wrapper::Set_Vertex_Shader_Constant(int reg, const void* data, int count) { - int memsize=sizeof(Vector4)*count; + int memsize = sizeof(Vector4) * count; // may be incorrect if shaders are created and destroyed dynamically - if (memcmp(data, &Vertex_Shader_Constants[reg],memsize)==0) return; + if (memcmp(data, &Vertex_Shader_Constants[reg], memsize) == 0) return; - memcpy(&Vertex_Shader_Constants[reg],data,memsize); - DX8CALL(SetVertexShaderConstant(reg,data,count)); + memcpy(&Vertex_Shader_Constants[reg], data, memsize); + DX8CALL(SetVertexShaderConstant(reg, data, count)); } WWINLINE void DX8Wrapper::Set_Pixel_Shader_Constant(int reg, const void* data, int count) { - int memsize=sizeof(Vector4)*count; + int memsize = sizeof(Vector4) * count; // may be incorrect if shaders are created and destroyed dynamically - if (memcmp(data, &Pixel_Shader_Constants[reg],memsize)==0) return; + if (memcmp(data, &Pixel_Shader_Constants[reg], memsize) == 0) return; - memcpy(&Pixel_Shader_Constants[reg],data,memsize); - DX8CALL(SetPixelShaderConstant(reg,data,count)); + memcpy(&Pixel_Shader_Constants[reg], data, memsize); + DX8CALL(SetPixelShaderConstant(reg, data, count)); } // shader system updates KJM ^ -WWINLINE void DX8Wrapper::_Set_DX8_Transform(D3DTRANSFORMSTATETYPE transform,const Matrix4x4& m) +WWINLINE void DX8Wrapper::_Set_DX8_Transform(D3DTRANSFORMSTATETYPE transform, const Matrix4x4& m) { - WWASSERT(transform<=D3DTS_WORLD); + WWASSERT(transform <= D3DTS_WORLD); #if 0 // (gth) this optimization is breaking generals because they set the transform behind our backs. - if (m!=DX8Transforms[transform]) + if (m != DX8Transforms[transform]) #endif { - DX8Transforms[transform]=m; - SNAPSHOT_SAY(("DX8 - SetTransform %d [%f,%f,%f,%f][%f,%f,%f,%f][%f,%f,%f,%f][%f,%f,%f,%f]",transform,m[0][0],m[0][1],m[0][2],m[0][3],m[1][0],m[1][1],m[1][2],m[1][3],m[2][0],m[2][1],m[2][2],m[2][3],m[3][0],m[3][1],m[3][2],m[3][3])); + DX8Transforms[transform] = m; + SNAPSHOT_SAY(("DX8 - SetTransform %d [%f,%f,%f,%f][%f,%f,%f,%f][%f,%f,%f,%f][%f,%f,%f,%f]", transform, m[0][0], m[0][1], m[0][2], m[0][3], m[1][0], m[1][1], m[1][2], m[1][3], m[2][0], m[2][1], m[2][2], m[2][3], m[3][0], m[3][1], m[3][2], m[3][3])); DX8_RECORD_MATRIX_CHANGE(); - DX8CALL(SetTransform(transform,(D3DMATRIX*)&m)); + DX8CALL(SetTransform(transform, (D3DMATRIX*)&m)); } } -WWINLINE void DX8Wrapper::_Set_DX8_Transform(D3DTRANSFORMSTATETYPE transform,const Matrix3D& m) +WWINLINE void DX8Wrapper::_Set_DX8_Transform(D3DTRANSFORMSTATETYPE transform, const Matrix3D& m) { - WWASSERT(transform<=D3DTS_WORLD); + WWASSERT(transform <= D3DTS_WORLD); Matrix4x4 mtx(m); #if 0 // (gth) this optimization is breaking generals because they set the transform behind our backs. - if (mtx!=DX8Transforms[transform]) + if (mtx != DX8Transforms[transform]) #endif { - DX8Transforms[transform]=mtx; - SNAPSHOT_SAY(("DX8 - SetTransform %d [%f,%f,%f,%f][%f,%f,%f,%f][%f,%f,%f,%f]",transform,m[0][0],m[0][1],m[0][2],m[0][3],m[1][0],m[1][1],m[1][2],m[1][3],m[2][0],m[2][1],m[2][2],m[2][3])); + DX8Transforms[transform] = mtx; + SNAPSHOT_SAY(("DX8 - SetTransform %d [%f,%f,%f,%f][%f,%f,%f,%f][%f,%f,%f,%f]", transform, m[0][0], m[0][1], m[0][2], m[0][3], m[1][0], m[1][1], m[1][2], m[1][3], m[2][0], m[2][1], m[2][2], m[2][3])); DX8_RECORD_MATRIX_CHANGE(); - DX8CALL(SetTransform(transform,(D3DMATRIX*)&m)); + DX8CALL(SetTransform(transform, (D3DMATRIX*)&m)); } } WWINLINE void DX8Wrapper::_Get_DX8_Transform(D3DTRANSFORMSTATETYPE transform, Matrix4x4& m) { - DX8CALL(GetTransform(transform,(D3DMATRIX*)&m)); + DX8CALL(GetTransform(transform, (D3DMATRIX*)&m)); } // ---------------------------------------------------------------------------- @@ -803,9 +803,9 @@ WWINLINE void DX8Wrapper::_Get_DX8_Transform(D3DTRANSFORMSTATETYPE transform, Ma WWINLINE void DX8Wrapper::Set_Index_Buffer_Index_Offset(unsigned offset) { - if (render_state.index_base_offset==offset) return; - render_state.index_base_offset=offset; - render_state_changed|=INDEX_BUFFER_CHANGED; + if (render_state.index_base_offset == offset) return; + render_state.index_base_offset = offset; + render_state_changed |= INDEX_BUFFER_CHANGED; } // ---------------------------------------------------------------------------- @@ -816,26 +816,26 @@ WWINLINE void DX8Wrapper::Set_Index_Buffer_Index_Offset(unsigned offset) // This function should be called rarely - once per scene would be appropriate. // ---------------------------------------------------------------------------- -WWINLINE void DX8Wrapper::Set_Fog(bool enable, const Vector3 &color, float start, float end) +WWINLINE void DX8Wrapper::Set_Fog(bool enable, const Vector3& color, float start, float end) { // Set global states FogEnable = enable; - FogColor = Convert_Color(color,0.0f); + FogColor = Convert_Color(color, 0.0f); // Invalidate the current shader (since the renderstates set by the shader // depend on the global fog settings as well as the actual shader settings) ShaderClass::Invalidate(); // Set renderstates which are not affected by the shader - Set_DX8_Render_State(D3DRS_FOGSTART, *(DWORD *)(&start)); - Set_DX8_Render_State(D3DRS_FOGEND, *(DWORD *)(&end)); + Set_DX8_Render_State(D3DRS_FOGSTART, *(DWORD*)(&start)); + Set_DX8_Render_State(D3DRS_FOGEND, *(DWORD*)(&end)); } WWINLINE void DX8Wrapper::Set_Ambient(const Vector3& color) { - Ambient_Color=color; - Set_DX8_Render_State(D3DRS_AMBIENT, DX8Wrapper::Convert_Color(color,0.0f)); + Ambient_Color = color; + Set_DX8_Render_State(D3DRS_AMBIENT, DX8Wrapper::Convert_Color(color, 0.0f)); } // ---------------------------------------------------------------------------- @@ -858,57 +858,58 @@ WWINLINE void DX8Wrapper::Set_DX8_Light(int index, D3DLIGHT8* light) { if (light) { DX8_RECORD_LIGHT_CHANGE(); - DX8CALL(SetLight(index,light)); - DX8CALL(LightEnable(index,TRUE)); - CurrentDX8LightEnables[index]=true; - SNAPSHOT_SAY(("DX8 - SetLight %d",index)); + DX8CALL(SetLight(index, light)); + DX8CALL(LightEnable(index, TRUE)); + CurrentDX8LightEnables[index] = true; + SNAPSHOT_SAY(("DX8 - SetLight %d", index)); } else if (CurrentDX8LightEnables[index]) { DX8_RECORD_LIGHT_CHANGE(); - CurrentDX8LightEnables[index]=false; - DX8CALL(LightEnable(index,FALSE)); - SNAPSHOT_SAY(("DX8 - DisableLight %d",index)); + CurrentDX8LightEnables[index] = false; + DX8CALL(LightEnable(index, FALSE)); + SNAPSHOT_SAY(("DX8 - DisableLight %d", index)); } } WWINLINE void DX8Wrapper::Set_DX8_Render_State(D3DRENDERSTATETYPE state, unsigned value) { // Can't monitor state changes because setShader call to GERD may change the states! - if (RenderStates[state]==value) return; + if (RenderStates[state] == value) return; #ifdef MESH_RENDER_SNAPSHOT_ENABLED if (WW3D::Is_Snapshot_Activated()) { - StringClass value_name(0,true); - Get_DX8_Render_State_Value_Name(value_name,state,value); + StringClass value_name(0, true); + Get_DX8_Render_State_Value_Name(value_name, state, value); SNAPSHOT_SAY(("DX8 - SetRenderState(state: %s, value: %s)", Get_DX8_Render_State_Name(state), value_name.str())); } #endif - RenderStates[state]=value; - DX8CALL(SetRenderState( state, value )); + RenderStates[state] = value; + DX8CALL(SetRenderState(state, value)); DX8_RECORD_RENDER_STATE_CHANGE(); } WWINLINE void DX8Wrapper::Set_DX8_Clip_Plane(DWORD Index, CONST float* pPlane) { - DX8CALL(SetClipPlane( Index, pPlane )); + DX8CALL(SetClipPlane(Index, pPlane)); } WWINLINE void DX8Wrapper::Set_DX8_Texture_Stage_State(unsigned stage, D3DTEXTURESTAGESTATETYPE state, unsigned value) { - if (stage >= MAX_TEXTURE_STAGES) - { DX8CALL(SetTextureStageState( stage, state, value )); - return; - } + if (stage >= MAX_TEXTURE_STAGES) + { + DX8CALL(SetTextureStageState(stage, state, value)); + return; + } // Can't monitor state changes because setShader call to GERD may change the states! - if (TextureStageStates[stage][(unsigned int)state]==value) return; + if (TextureStageStates[stage][(unsigned int)state] == value) return; #ifdef MESH_RENDER_SNAPSHOT_ENABLED if (WW3D::Is_Snapshot_Activated()) { - StringClass value_name(0,true); - Get_DX8_Texture_Stage_State_Value_Name(value_name,state,value); + StringClass value_name(0, true); + Get_DX8_Texture_Stage_State_Value_Name(value_name, state, value); SNAPSHOT_SAY(("DX8 - SetTextureStageState(stage: %d, state: %s, value: %s)", stage, Get_DX8_Texture_Stage_State_Name(state), @@ -916,21 +917,22 @@ WWINLINE void DX8Wrapper::Set_DX8_Texture_Stage_State(unsigned stage, D3DTEXTURE } #endif - TextureStageStates[stage][(unsigned int)state]=value; - DX8CALL(SetTextureStageState( stage, state, value )); + TextureStageStates[stage][(unsigned int)state] = value; + DX8CALL(SetTextureStageState(stage, state, value)); DX8_RECORD_TEXTURE_STAGE_STATE_CHANGE(); } WWINLINE void DX8Wrapper::Set_DX8_Texture(unsigned int stage, IDirect3DBaseTexture8* texture) { - if (stage >= MAX_TEXTURE_STAGES) - { DX8CALL(SetTexture(stage, texture)); - return; - } + if (stage >= MAX_TEXTURE_STAGES) + { + DX8CALL(SetTexture(stage, texture)); + return; + } - if (Textures[stage]==texture) return; + if (Textures[stage] == texture) return; - SNAPSHOT_SAY(("DX8 - SetTexture(%x) ",texture)); + SNAPSHOT_SAY(("DX8 - SetTexture(%x) ", texture)); if (Textures[stage]) Textures[stage]->Release(); Textures[stage] = texture; @@ -940,58 +942,58 @@ WWINLINE void DX8Wrapper::Set_DX8_Texture(unsigned int stage, IDirect3DBaseTextu } WWINLINE void DX8Wrapper::_Copy_DX8_Rects( - IDirect3DSurface8* pSourceSurface, - CONST RECT* pSourceRectsArray, - UINT cRects, - IDirect3DSurface8* pDestinationSurface, - CONST POINT* pDestPointsArray + IDirect3DSurface8* pSourceSurface, + CONST RECT* pSourceRectsArray, + UINT cRects, + IDirect3DSurface8* pDestinationSurface, + CONST POINT* pDestPointsArray ) { DX8CALL(CopyRects( - pSourceSurface, - pSourceRectsArray, - cRects, - pDestinationSurface, - pDestPointsArray)); + pSourceSurface, + pSourceRectsArray, + cRects, + pDestinationSurface, + pDestPointsArray)); } WWINLINE Vector4 DX8Wrapper::Convert_Color(unsigned color) { Vector4 col; - col[3]=((color&0xff000000)>>24)/255.0f; - col[0]=((color&0xff0000)>>16)/255.0f; - col[1]=((color&0xff00)>>8)/255.0f; - col[2]=((color&0xff)>>0)/255.0f; -// col=Vector4(1.0f,1.0f,1.0f,1.0f); + col[3] = ((color & 0xff000000) >> 24) / 255.0f; + col[0] = ((color & 0xff0000) >> 16) / 255.0f; + col[1] = ((color & 0xff00) >> 8) / 255.0f; + col[2] = ((color & 0xff) >> 0) / 255.0f; + // col=Vector4(1.0f,1.0f,1.0f,1.0f); return col; } #if 0 WWINLINE unsigned int DX8Wrapper::Convert_Color(const Vector3& color, const float alpha) { - WWASSERT(color.X<=1.0f); - WWASSERT(color.Y<=1.0f); - WWASSERT(color.Z<=1.0f); - WWASSERT(alpha<=1.0f); - WWASSERT(color.X>=0.0f); - WWASSERT(color.Y>=0.0f); - WWASSERT(color.Z>=0.0f); - WWASSERT(alpha>=0.0f); - - return D3DCOLOR_COLORVALUE(color.X,color.Y,color.Z,alpha); + WWASSERT(color.X <= 1.0f); + WWASSERT(color.Y <= 1.0f); + WWASSERT(color.Z <= 1.0f); + WWASSERT(alpha <= 1.0f); + WWASSERT(color.X >= 0.0f); + WWASSERT(color.Y >= 0.0f); + WWASSERT(color.Z >= 0.0f); + WWASSERT(alpha >= 0.0f); + + return D3DCOLOR_COLORVALUE(color.X, color.Y, color.Z, alpha); } WWINLINE unsigned int DX8Wrapper::Convert_Color(const Vector4& color) { - WWASSERT(color.X<=1.0f); - WWASSERT(color.Y<=1.0f); - WWASSERT(color.Z<=1.0f); - WWASSERT(color.W<=1.0f); - WWASSERT(color.X>=0.0f); - WWASSERT(color.Y>=0.0f); - WWASSERT(color.Z>=0.0f); - WWASSERT(color.W>=0.0f); - - return D3DCOLOR_COLORVALUE(color.X,color.Y,color.Z,color.W); + WWASSERT(color.X <= 1.0f); + WWASSERT(color.Y <= 1.0f); + WWASSERT(color.Z <= 1.0f); + WWASSERT(color.W <= 1.0f); + WWASSERT(color.X >= 0.0f); + WWASSERT(color.Y >= 0.0f); + WWASSERT(color.Z >= 0.0f); + WWASSERT(color.W >= 0.0f); + + return D3DCOLOR_COLORVALUE(color.X, color.Y, color.Z, color.W); } #else @@ -1002,7 +1004,7 @@ WWINLINE unsigned int DX8Wrapper::Convert_Color(const Vector4& color) // // ---------------------------------------------------------------------------- -WWINLINE unsigned int DX8Wrapper::Convert_Color(const Vector3& color,float alpha) +WWINLINE unsigned int DX8Wrapper::Convert_Color(const Vector3& color, float alpha) { #if defined(_MSC_VER) && _MSC_VER < 1300 const float scale = 255.0; @@ -1012,63 +1014,63 @@ WWINLINE unsigned int DX8Wrapper::Convert_Color(const Vector3& color,float alpha // such that 32 bit ingeger has AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB. __asm { - sub esp,20 // space for a, r, g and b float plus fpu rounding mode + sub esp, 20 // space for a, r, g and b float plus fpu rounding mode // Store the fpu rounding mode fwait - fstcw [esp+16] // store control word to stack - mov eax,[esp+16] // load it to eax - mov edi,eax // take copy - and eax,~(1024|2048) // mask out certain bits - or eax,(1024|2048) // or with precision control value "truncate" - sub edi,eax // did it change? + fstcw[esp + 16] // store control word to stack + mov eax, [esp + 16] // load it to eax + mov edi, eax // take copy + and eax, ~(1024 | 2048) // mask out certain bits + or eax, (1024 | 2048) // or with precision control value "truncate" + sub edi, eax // did it change? jz skip // .. if not, skip - mov [esp],eax // .. change control word - fldcw [esp] -skip: + mov[esp], eax // .. change control word + fldcw[esp] + skip: // Convert the color - mov esi,dword ptr color - fld dword ptr[scale] - - fld dword ptr[esi] // r - fld dword ptr[esi+4] // g - fld dword ptr[esi+8] // b - fld dword ptr[alpha] // a - fld st(4) - fmul st(4),st - fmul st(3),st - fmul st(2),st - fmulp st(1),st - fistp dword ptr[esp+0] // a - fistp dword ptr[esp+4] // b - fistp dword ptr[esp+8] // g - fistp dword ptr[esp+12] // r - mov ecx,[esp] // a - mov eax,[esp+4] // b - mov edx,[esp+8] // g - mov ebx,[esp+12] // r - shl ecx,24 // a << 24 - shl ebx,16 // r << 16 - shl edx,8 // g << 8 - or eax,ecx // (a << 24) | b - or eax,ebx // (a << 24) | (r << 16) | b - or eax,edx // (a << 24) | (r << 16) | (g << 8) | b - - fstp st(0) - - // Restore fpu rounding mode - - cmp edi,0 // did we change the value? - je not_changed // nope... skip now... - fwait - fldcw [esp+16]; -not_changed: - add esp,20 - - mov col,eax + mov esi, dword ptr color + fld dword ptr[scale] + + fld dword ptr[esi] // r + fld dword ptr[esi + 4] // g + fld dword ptr[esi + 8] // b + fld dword ptr[alpha] // a + fld st(4) + fmul st(4), st + fmul st(3), st + fmul st(2), st + fmulp st(1), st + fistp dword ptr[esp + 0] // a + fistp dword ptr[esp + 4] // b + fistp dword ptr[esp + 8] // g + fistp dword ptr[esp + 12] // r + mov ecx, [esp] // a + mov eax, [esp + 4] // b + mov edx, [esp + 8] // g + mov ebx, [esp + 12] // r + shl ecx, 24 // a << 24 + shl ebx, 16 // r << 16 + shl edx, 8 // g << 8 + or eax, ecx // (a << 24) | b + or eax, ebx // (a << 24) | (r << 16) | b + or eax, edx // (a << 24) | (r << 16) | (g << 8) | b + + fstp st(0) + + // Restore fpu rounding mode + + cmp edi, 0 // did we change the value? + je not_changed // nope... skip now... + fwait + fldcw[esp + 16]; + not_changed: + add esp, 20 + + mov col, eax } return col; #else @@ -1086,55 +1088,55 @@ WWINLINE void DX8Wrapper::Clamp_Color(Vector4& color) { #if defined(_MSC_VER) && _MSC_VER < 1300 if (CPUDetectClass::Has_CMOV_Instruction()) { - __asm - { - mov esi,dword ptr color - - mov edx,0x3f800000 - - mov edi,dword ptr[esi] - mov ebx,edi - sar edi,31 - not edi // mask is now zero if negative value - and edi,ebx - cmp edi,edx // if no less than 1.0 set to 1.0 - cmovnb edi,edx - mov dword ptr[esi],edi - - mov edi,dword ptr[esi+4] - mov ebx,edi - sar edi,31 - not edi // mask is now zero if negative value - and edi,ebx - cmp edi,edx // if no less than 1.0 set to 1.0 - cmovnb edi,edx - mov dword ptr[esi+4],edi - - mov edi,dword ptr[esi+8] - mov ebx,edi - sar edi,31 - not edi // mask is now zero if negative value - and edi,ebx - cmp edi,edx // if no less than 1.0 set to 1.0 - cmovnb edi,edx - mov dword ptr[esi+8],edi - - mov edi,dword ptr[esi+12] - mov ebx,edi - sar edi,31 - not edi // mask is now zero if negative value - and edi,ebx - cmp edi,edx // if no less than 1.0 set to 1.0 - cmovnb edi,edx - mov dword ptr[esi+12],edi - } - return; + __asm + { + mov esi, dword ptr color + + mov edx, 0x3f800000 + + mov edi, dword ptr[esi] + mov ebx, edi + sar edi, 31 + not edi // mask is now zero if negative value + and edi, ebx + cmp edi, edx // if no less than 1.0 set to 1.0 + cmovnb edi, edx + mov dword ptr[esi], edi + + mov edi, dword ptr[esi + 4] + mov ebx, edi + sar edi, 31 + not edi // mask is now zero if negative value + and edi, ebx + cmp edi, edx // if no less than 1.0 set to 1.0 + cmovnb edi, edx + mov dword ptr[esi + 4], edi + + mov edi, dword ptr[esi + 8] + mov ebx, edi + sar edi, 31 + not edi // mask is now zero if negative value + and edi, ebx + cmp edi, edx // if no less than 1.0 set to 1.0 + cmovnb edi, edx + mov dword ptr[esi + 8], edi + + mov edi, dword ptr[esi + 12] + mov ebx, edi + sar edi, 31 + not edi // mask is now zero if negative value + and edi, ebx + cmp edi, edx // if no less than 1.0 set to 1.0 + cmovnb edi, edx + mov dword ptr[esi + 12], edi + } + return; } #endif // defined(_MSC_VER) && _MSC_VER < 1300 - for (int i=0;i<4;++i) { - float f=(color[i]<0.0f) ? 0.0f : color[i]; - color[i]=(f>1.0f) ? 1.0f : f; + for (int i = 0; i < 4; ++i) { + float f = (color[i] < 0.0f) ? 0.0f : color[i]; + color[i] = (f > 1.0f) ? 1.0f : f; } } @@ -1146,185 +1148,185 @@ WWINLINE void DX8Wrapper::Clamp_Color(Vector4& color) WWINLINE unsigned int DX8Wrapper::Convert_Color(const Vector4& color) { - return Convert_Color(reinterpret_cast(color),color[3]); + return Convert_Color(reinterpret_cast(color), color[3]); } WWINLINE unsigned int DX8Wrapper::Convert_Color_Clamp(const Vector4& color) { - Vector4 clamped_color=color; + Vector4 clamped_color = color; DX8Wrapper::Clamp_Color(clamped_color); - return Convert_Color(reinterpret_cast(clamped_color),clamped_color[3]); + return Convert_Color(reinterpret_cast(clamped_color), clamped_color[3]); } #endif -WWINLINE void DX8Wrapper::Set_Alpha (const float alpha, unsigned int &color) +WWINLINE void DX8Wrapper::Set_Alpha(const float alpha, unsigned int& color) { - unsigned char *component = (unsigned char*) &color; + unsigned char* component = (unsigned char*)&color; - component [3] = 255.0f * alpha; + component[3] = 255.0f * alpha; } WWINLINE void DX8Wrapper::Get_Render_State(RenderStateStruct& state) { - state=render_state; + state = render_state; } WWINLINE void DX8Wrapper::Get_Shader(ShaderClass& shader) { - shader=render_state.shader; + shader = render_state.shader; } -WWINLINE void DX8Wrapper::Set_Texture(unsigned stage,TextureBaseClass* texture) +WWINLINE void DX8Wrapper::Set_Texture(unsigned stage, TextureBaseClass* texture) { - WWASSERT(stage<(unsigned int)CurrentCaps->Get_Max_Textures_Per_Pass()); - if (texture==render_state.Textures[stage]) return; - REF_PTR_SET(render_state.Textures[stage],texture); - render_state_changed|=(TEXTURE0_CHANGED<Get_Max_Textures_Per_Pass()); + if (texture == render_state.Textures[stage]) return; + REF_PTR_SET(render_state.Textures[stage], texture); + render_state_changed |= (TEXTURE0_CHANGED << stage); } WWINLINE void DX8Wrapper::Set_Material(const VertexMaterialClass* material) { -/* if (material && render_state.material && - // !stricmp(material->Get_Name(),render_state.material->Get_Name())) { - material->Get_CRC()!=render_state.material->Get_CRC()) { - return; - } -*/ -// if (material==render_state.material) { -// return; -// } - REF_PTR_SET(render_state.material,const_cast(material)); - render_state_changed|=MATERIAL_CHANGED; - SNAPSHOT_SAY(("DX8Wrapper::Set_Material(%s)",material ? material->Get_Name() : "NULL")); + /* if (material && render_state.material && + // !stricmp(material->Get_Name(),render_state.material->Get_Name())) { + material->Get_CRC()!=render_state.material->Get_CRC()) { + return; + } + */ + // if (material==render_state.material) { + // return; + // } + REF_PTR_SET(render_state.material, const_cast(material)); + render_state_changed |= MATERIAL_CHANGED; + SNAPSHOT_SAY(("DX8Wrapper::Set_Material(%s)", material ? material->Get_Name() : "NULL")); } WWINLINE void DX8Wrapper::Set_Shader(const ShaderClass& shader) { - if (!ShaderClass::ShaderDirty && ((unsigned&)shader==(unsigned&)render_state.shader)) { + if (!ShaderClass::ShaderDirty && ((unsigned&)shader == (unsigned&)render_state.shader)) { return; } - render_state.shader=shader; - render_state_changed|=SHADER_CHANGED; + render_state.shader = shader; + render_state_changed |= SHADER_CHANGED; #ifdef MESH_RENDER_SNAPSHOT_ENABLED StringClass str; #endif - SNAPSHOT_SAY(("DX8Wrapper::Set_Shader(%s)",shader.Get_Description(str).str())); + SNAPSHOT_SAY(("DX8Wrapper::Set_Shader(%s)", shader.Get_Description(str).str())); } WWINLINE void DX8Wrapper::Set_Projection_Transform_With_Z_Bias(const Matrix4x4& matrix, float znear, float zfar) { - ZFar=zfar; - ZNear=znear; - ProjectionMatrix=matrix.Transpose(); - - if (!Get_Current_Caps()->Support_ZBias() && ZNear!=ZFar) { - Matrix4x4 tmp=ProjectionMatrix; - float tmp_zbias=ZBias; - tmp_zbias*=(1.0f/16.0f); - tmp_zbias*=1.0f / (ZFar - ZNear); - tmp[2][2]-=tmp_zbias*tmp[3][2]; - DX8CALL(SetTransform(D3DTS_PROJECTION,(D3DMATRIX*)&tmp)); + ZFar = zfar; + ZNear = znear; + ProjectionMatrix = matrix.Transpose(); + + if (!Get_Current_Caps()->Support_ZBias() && ZNear != ZFar) { + Matrix4x4 tmp = ProjectionMatrix; + float tmp_zbias = ZBias; + tmp_zbias *= (1.0f / 16.0f); + tmp_zbias *= 1.0f / (ZFar - ZNear); + tmp[2][2] -= tmp_zbias * tmp[3][2]; + DX8CALL(SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)&tmp)); } else { - DX8CALL(SetTransform(D3DTS_PROJECTION,(D3DMATRIX*)&ProjectionMatrix)); + DX8CALL(SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)&ProjectionMatrix)); } } WWINLINE void DX8Wrapper::Set_DX8_ZBias(int zbias) { - if (zbias==ZBias) return; - if (zbias>15) zbias=15; - if (zbias<0) zbias=0; - ZBias=zbias; - - if (!Get_Current_Caps()->Support_ZBias() && ZNear!=ZFar) { - Matrix4x4 tmp=ProjectionMatrix; - float tmp_zbias=ZBias; - tmp_zbias*=(1.0f/16.0f); - tmp_zbias*=1.0f / (ZFar - ZNear); - tmp[2][2]-=tmp_zbias*tmp[3][2]; - DX8CALL(SetTransform(D3DTS_PROJECTION,(D3DMATRIX*)&tmp)); + if (zbias == ZBias) return; + if (zbias > 15) zbias = 15; + if (zbias < 0) zbias = 0; + ZBias = zbias; + + if (!Get_Current_Caps()->Support_ZBias() && ZNear != ZFar) { + Matrix4x4 tmp = ProjectionMatrix; + float tmp_zbias = ZBias; + tmp_zbias *= (1.0f / 16.0f); + tmp_zbias *= 1.0f / (ZFar - ZNear); + tmp[2][2] -= tmp_zbias * tmp[3][2]; + DX8CALL(SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)&tmp)); } else { - Set_DX8_Render_State (D3DRS_ZBIAS, ZBias); + Set_DX8_Render_State(D3DRS_ZBIAS, ZBias); } } -WWINLINE void DX8Wrapper::Set_Transform(D3DTRANSFORMSTATETYPE transform,const Matrix4x4& m) +WWINLINE void DX8Wrapper::Set_Transform(D3DTRANSFORMSTATETYPE transform, const Matrix4x4& m) { switch ((int)transform) { case D3DTS_WORLD: - render_state.world=m.Transpose(); - render_state_changed|=(unsigned)WORLD_CHANGED; - render_state_changed&=~(unsigned)WORLD_IDENTITY; + render_state.world = m.Transpose(); + render_state_changed |= (unsigned)WORLD_CHANGED; + render_state_changed &= ~(unsigned)WORLD_IDENTITY; break; case D3DTS_VIEW: - render_state.view=m.Transpose(); - render_state_changed|=(unsigned)VIEW_CHANGED; - render_state_changed&=~(unsigned)VIEW_IDENTITY; + render_state.view = m.Transpose(); + render_state_changed |= (unsigned)VIEW_CHANGED; + render_state_changed &= ~(unsigned)VIEW_IDENTITY; break; case D3DTS_PROJECTION: - { - Matrix4x4 ProjectionMatrix=m.Transpose(); - ZFar=0.0f; - ZNear=0.0f; - DX8CALL(SetTransform(D3DTS_PROJECTION,(D3DMATRIX*)&ProjectionMatrix)); - } - break; + { + Matrix4x4 ProjectionMatrix = m.Transpose(); + ZFar = 0.0f; + ZNear = 0.0f; + DX8CALL(SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)&ProjectionMatrix)); + } + break; default: DX8_RECORD_MATRIX_CHANGE(); - Matrix4x4 m2=m.Transpose(); - DX8CALL(SetTransform(transform,(D3DMATRIX*)&m2)); + Matrix4x4 m2 = m.Transpose(); + DX8CALL(SetTransform(transform, (D3DMATRIX*)&m2)); break; } } -WWINLINE void DX8Wrapper::Set_Transform(D3DTRANSFORMSTATETYPE transform,const Matrix3D& m) +WWINLINE void DX8Wrapper::Set_Transform(D3DTRANSFORMSTATETYPE transform, const Matrix3D& m) { Matrix4x4 m2(m); switch ((int)transform) { case D3DTS_WORLD: - render_state.world=m2.Transpose(); - render_state_changed|=(unsigned)WORLD_CHANGED; - render_state_changed&=~(unsigned)WORLD_IDENTITY; + render_state.world = m2.Transpose(); + render_state_changed |= (unsigned)WORLD_CHANGED; + render_state_changed &= ~(unsigned)WORLD_IDENTITY; break; case D3DTS_VIEW: - render_state.view=m2.Transpose(); - render_state_changed|=(unsigned)VIEW_CHANGED; - render_state_changed&=~(unsigned)VIEW_IDENTITY; + render_state.view = m2.Transpose(); + render_state_changed |= (unsigned)VIEW_CHANGED; + render_state_changed &= ~(unsigned)VIEW_IDENTITY; break; default: DX8_RECORD_MATRIX_CHANGE(); - m2=m2.Transpose(); - DX8CALL(SetTransform(transform,(D3DMATRIX*)&m2)); + m2 = m2.Transpose(); + DX8CALL(SetTransform(transform, (D3DMATRIX*)&m2)); break; } } WWINLINE void DX8Wrapper::Set_World_Identity() { - if (render_state_changed&(unsigned)WORLD_IDENTITY) return; + if (render_state_changed & (unsigned)WORLD_IDENTITY) return; render_state.world.Make_Identity(); - render_state_changed|=(unsigned)WORLD_CHANGED|(unsigned)WORLD_IDENTITY; + render_state_changed |= (unsigned)WORLD_CHANGED | (unsigned)WORLD_IDENTITY; } WWINLINE void DX8Wrapper::Set_View_Identity() { - if (render_state_changed&(unsigned)VIEW_IDENTITY) return; + if (render_state_changed & (unsigned)VIEW_IDENTITY) return; render_state.view.Make_Identity(); - render_state_changed|=(unsigned)VIEW_CHANGED|(unsigned)VIEW_IDENTITY; + render_state_changed |= (unsigned)VIEW_CHANGED | (unsigned)VIEW_IDENTITY; } WWINLINE bool DX8Wrapper::Is_World_Identity() { - return !!(render_state_changed&(unsigned)WORLD_IDENTITY); + return !!(render_state_changed & (unsigned)WORLD_IDENTITY); } WWINLINE bool DX8Wrapper::Is_View_Identity() { - return !!(render_state_changed&(unsigned)VIEW_IDENTITY); + return !!(render_state_changed & (unsigned)VIEW_IDENTITY); } WWINLINE void DX8Wrapper::Get_Transform(D3DTRANSFORMSTATETYPE transform, Matrix4x4& m) @@ -1333,17 +1335,17 @@ WWINLINE void DX8Wrapper::Get_Transform(D3DTRANSFORMSTATETYPE transform, Matrix4 switch ((int)transform) { case D3DTS_WORLD: - if (render_state_changed&WORLD_IDENTITY) m.Make_Identity(); - else m=render_state.world.Transpose(); + if (render_state_changed & WORLD_IDENTITY) m.Make_Identity(); + else m = render_state.world.Transpose(); break; case D3DTS_VIEW: - if (render_state_changed&VIEW_IDENTITY) m.Make_Identity(); - else m=render_state.view.Transpose(); + if (render_state_changed & VIEW_IDENTITY) m.Make_Identity(); + else m = render_state.view.Transpose(); break; default: - DX8CALL(GetTransform(transform,&mat)); - m=*(Matrix4x4*)&mat; - m=m.Transpose(); + DX8CALL(GetTransform(transform, &mat)); + m = *(Matrix4x4*)&mat; + m = m.Transpose(); break; } } @@ -1367,24 +1369,24 @@ WWINLINE void DX8Wrapper::Set_Render_State(const RenderStateStruct& state) render_state.index_buffer->Release_Engine_Ref(); } - for (i=0;iRelease_Engine_Ref(); } } - render_state=state; - render_state_changed=0xffffffff; + render_state = state; + render_state_changed = 0xffffffff; if (render_state.index_buffer) { render_state.index_buffer->Add_Engine_Ref(); } - for (i=0;iAdd_Engine_Ref(); } @@ -1399,20 +1401,20 @@ WWINLINE void DX8Wrapper::Release_Render_State() render_state.index_buffer->Release_Engine_Ref(); } - for (i=0;iRelease_Engine_Ref(); } } - for (i=0;iIs_Initialized()) - TextureLoader::Request_High_Priority_Loading(texture, (MipCountType)texture->Get_Mip_Level_Count()); + TextureLoader::Request_Foreground_Loading(texture); SurfaceClass::SurfaceDescription desc; SurfaceClass *newsurf, *oldsurf; diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp index a03ed940b8..b8a6cfb498 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp @@ -412,7 +412,6 @@ W3DDisplay::~W3DDisplay() // shutdown Debug_Statistics::Shutdown_Statistics(); - TextureLoadTaskClass::shutdown(); if (!TheGlobalData->m_headless) W3DShaderManager::shutdown(); m_assetManager->Free_Assets(); diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DShroud.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DShroud.cpp index be441cbf74..9a5a0a613b 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DShroud.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DShroud.cpp @@ -127,9 +127,14 @@ void W3DShroud::init(WorldHeightMap *pMap, Real worldCellSizeX, Real worldCellSi //shroud cells are larger than terrain cells). dstTextureWidth=m_numMaxVisibleCellsX=REAL_TO_INT_FLOOR((Real)(pMap->getDrawWidth()-1)*MAP_XY_FACTOR/m_cellWidth)+1; dstTextureHeight=m_numMaxVisibleCellsY=REAL_TO_INT_FLOOR((Real)(pMap->getDrawHeight()-1)*MAP_XY_FACTOR/m_cellHeight)+1; + + dstTextureWidth = m_numCellsX; + dstTextureHeight = m_numCellsY; + dstTextureWidth += 2; //enlarge by 2 pixels so we can have a border color all the way around. + unsigned int depth = 1; dstTextureHeight += 2; //enlarge by 2 pixels so we can have border color all the way around. - TextureLoader::Validate_Texture_Size((unsigned int &)dstTextureWidth,(unsigned int &)dstTextureHeight); + TextureLoader::Validate_Texture_Size((unsigned int&)dstTextureWidth, (unsigned int&)dstTextureHeight, depth); } UnsignedInt srcWidth,srcHeight; diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DVideoBuffer.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DVideoBuffer.cpp index 4f7701d094..b3a04ae629 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DVideoBuffer.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DVideoBuffer.cpp @@ -122,7 +122,8 @@ Bool W3DVideoBuffer::allocate( UnsignedInt width, UnsignedInt height ) m_height = height; m_textureWidth = width;; m_textureHeight = height;; - TextureLoader::Validate_Texture_Size( m_textureWidth, m_textureHeight); + unsigned int temp_depth = 1; + TextureLoader::Validate_Texture_Size(m_textureWidth, m_textureHeight, temp_depth); WW3DFormat w3dFormat = TypeToW3DFormat( m_format ); diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWater.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWater.cpp index ee1d7fab7f..1e2b3855c9 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWater.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWater.cpp @@ -1438,7 +1438,7 @@ void WaterRenderObjClass::renderMirror(CameraClass *cam) Matrix3D reflectedTransform(rRight,rUp,rN,rPos); - DX8Wrapper::Set_Render_Target(m_pReflectionTexture); + DX8Wrapper::Set_Render_Target_With_Z((TextureClass*)m_pReflectionTexture); // Clear the backbuffer WW3D::Begin_Render(false,true,Vector3(0.0f,0.0f,0.0f)); //clearing only z-buffer since background always filled with clouds diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt b/Generals/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt index e4e14e3d9a..aabf6bf5be 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt @@ -60,8 +60,8 @@ set(WW3D2_SRC dx8vertexbuffer.h #dx8webbrowser.cpp #dx8webbrowser.h - dx8wrapper.cpp - dx8wrapper.h + #dx8wrapper.cpp + #dx8wrapper.h #dynamesh.cpp #dynamesh.h #font3d.cpp diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.cpp index c731064a32..5f9b8ca053 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.cpp @@ -1044,46 +1044,6 @@ HTreeClass * WW3DAssetManager::Get_HTree(const char * name) return htree; } -/*********************************************************************************************** - * WW3DAssetManager::Get_Bumpmap_Based_On_Texture -- Generate a bumpmap from texture. The * - * resulting texture is stored to the hash table so that any further requests will share it. * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 1/31/2001 NH : Created. * - *=============================================================================================*/ - -TextureClass* WW3DAssetManager::Get_Bumpmap_Based_On_Texture(TextureClass* texture) -{ - WWASSERT(texture->Get_Texture_Name() && strlen(texture->Get_Texture_Name())); - StringClass bump_name="__Bumpmap-"; - bump_name+=texture->Get_Texture_Name(); - _strlwr(bump_name.Peek_Buffer()); // lower case - - /* - ** See if the texture has already been generated. - */ - - TextureClass* tex = TextureHash.Get(bump_name); - - /* - ** Didn't have it so we have to create a new texture - */ - if (!tex) { - tex = NEW_REF(BumpmapTextureClass,(texture)); - tex->Set_Texture_Name(bump_name); - TextureHash.Insert(tex->Get_Texture_Name(),tex); - } - - tex->Add_Ref(); - return tex; -} - /*********************************************************************************************** * WW3DAssetManager::Get_Texture -- get a TextureClass from the specified file * * * diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h index 36e8446dee..db7d3a3c3d 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h @@ -271,7 +271,6 @@ class WW3DAssetManager TextureBaseClass::TexAssetType type=TextureBaseClass::TEX_REGULAR, bool allow_reduction=true ); - TextureClass* Get_Bumpmap_Based_On_Texture(TextureClass* texture); virtual void Release_All_Textures(void); virtual void Release_Unused_Textures(void); diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp index f8c67f1906..e9a4735ce6 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp @@ -481,6 +481,27 @@ DX8Caps::DX8Caps( Compute_Caps(display_format, adapter_id); } +DX8Caps::DX8Caps( + IDirect3D8* direct3d, + const D3DCAPS8& caps, + WW3DFormat display_format, + const D3DADAPTER_IDENTIFIER8& adapter_id) + : + Direct3D(direct3d), + Caps(caps), + MaxDisplayWidth(0), + MaxDisplayHeight(0) +{ + if ((Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == D3DDEVCAPS_HWTRANSFORMANDLIGHT) { + SupportTnL = true; + } + else { + SupportTnL = false; + } + + Compute_Caps(display_format, adapter_id); +} + //Don't really need this but I added this function to free static variables so //they don't show up in our memory manager as a leak. -MW 7-22-03 void DX8Caps::Shutdown(void) @@ -526,6 +547,8 @@ void DX8Caps::Compute_Caps(WW3DFormat display_format, const D3DADAPTER_IDENTIFIE SupportNPatches=false; } + SupportZBias = ((Caps.RasterCaps & D3DPRASTERCAPS_ZBIAS) == D3DPRASTERCAPS_ZBIAS); + if ((caps.TextureOpCaps&D3DTEXOPCAPS_DOTPRODUCT3)==D3DTEXOPCAPS_DOTPRODUCT3) { SupportDot3=true; @@ -680,6 +703,15 @@ void DX8Caps::Check_Shader_Support(const D3DCAPS8& caps) PixelShaderVersion=caps.PixelShaderVersion; } +bool DX8Caps::Is_Valid_Display_Format(int width, int height, WW3DFormat format) +{ + // If nothing limits the maximum resolution, accept any resolution + if (MaxDisplayWidth == 0 && MaxDisplayHeight == 0) return true; + + if (width > MaxDisplayWidth || height > MaxDisplayHeight) return false; + return true; +} + // ---------------------------------------------------------------------------- // // Implement some vendor-specific hacks to fix certain driver bugs that can't be diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.h index 28c1b983b1..7c1579f268 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.h +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.h @@ -206,7 +206,7 @@ class DX8Caps DEVICE_INTEL_815 }; - + DX8Caps(IDirect3D8* direct3d, const D3DCAPS8& caps, WW3DFormat display_format, const D3DADAPTER_IDENTIFIER8& adapter_id); DX8Caps(IDirect3D8* direct3d, IDirect3DDevice8* D3DDevice,WW3DFormat display_format, const D3DADAPTER_IDENTIFIER8& adapter_id); static void Shutdown(void); @@ -217,9 +217,12 @@ class DX8Caps bool Support_NPatches() const { return SupportNPatches; } bool Support_Bump_Envmap() const { return SupportBumpEnvmap; } bool Support_Bump_Envmap_Luminance() const { return SupportBumpEnvmapLuminance; } + bool Support_ZBias() const { return SupportZBias; } bool Support_Dot3() const { return SupportDot3; } int Get_Max_Textures_Per_Pass() const { return MaxTexturesPerPass; } + bool Is_Valid_Display_Format(int width, int height, WW3DFormat format); + // ------------------------------------------------------------------------- // // Vertex shader support. Version number is split in major and minor, such that 1.0 would @@ -266,6 +269,8 @@ class DX8Caps int MaxDisplayWidth; int MaxDisplayHeight; + D3DCAPS8 Caps; + D3DCAPS8 hwVPCaps; D3DCAPS8 swVPCaps; bool SupportTnL; @@ -277,6 +282,7 @@ class DX8Caps bool SupportTextureFormat[WW3D_FORMAT_COUNT]; bool SupportRenderToTextureFormat[WW3D_FORMAT_COUNT]; bool SupportDepthStencilFormat[WW3D_ZFORMAT_COUNT]; + bool SupportZBias; bool SupportDot3; int MaxTexturesPerPass; int VertexShaderVersion; diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp index 85d831483a..f6a22d1f8e 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp @@ -186,7 +186,7 @@ inline static bool Equal_Material(const VertexMaterialClass* mat1,const VertexMa DX8TextureCategoryClass::DX8TextureCategoryClass( DX8FVFCategoryContainer* container_, TextureClass** texs, - ShaderClass shd, + ShaderClass shd, VertexMaterialClass* mat, int pass_) : @@ -196,13 +196,13 @@ DX8TextureCategoryClass::DX8TextureCategoryClass( material(mat), container(container_) { - WWASSERT(pass>=0); - WWASSERT(pass= 0); + WWASSERT(pass < DX8FVFCategoryContainer::MAX_PASSES); - - for (int a=0;aAdd_Ref(); @@ -1175,7 +1175,8 @@ void DX8FVFCategoryContainer::Generate_Texture_Categories(Vertex_Split_Table& sp for (int i=0;iPeek_D3D_Base_Texture() == NULL); + Texture->Poke_Texture + ( + DX8Wrapper::_Create_DX8_ZTexture + ( + Width, + Height, + ZFormat, + Mip_level_count, + D3DPOOL_DEFAULT + ) + ); + } + + +private: + WW3DZFormat ZFormat; +}; + + class DX8TextureManagerClass { public: diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp deleted file mode 100644 index 002b71a4e1..0000000000 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp +++ /dev/null @@ -1,3694 +0,0 @@ -/* -** Command & Conquer Generals(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:: /VSS_Sync/ww3d2/dx8wrapper.cpp $* - * * - * Original Author:: Jani Penttinen * - * * - * $Author:: Vss_sync $* - * * - * $Modtime:: 8/29/01 7:29p $* - * * - * $Revision:: 134 $* - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * DX8Wrapper::_Update_Texture -- Copies a texture from system memory to video memory * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -//#define CREATE_DX8_MULTI_THREADED -//#define CREATE_DX8_FPU_PRESERVE -#define WW3D_DEVTYPE D3DDEVTYPE_HAL - -#if defined(_MSC_VER) && _MSC_VER < 1300 -#undef WINVER -#define WINVER 0x0500 // Required to access GetMonitorInfo in VC6. -#endif - -#include "dx8wrapper.h" -#include "dx8webbrowser.h" -#include "dx8fvf.h" -#include "dx8vertexbuffer.h" -#include "dx8indexbuffer.h" -#include "dx8renderer.h" -#include "ww3d.h" -#include "camera.h" -#include "wwstring.h" -#include "matrix4.h" -#include "vertmaterial.h" -#include "rddesc.h" -#include "lightenvironment.h" -#include "statistics.h" -#include "registry.h" -#include "boxrobj.h" -#include "pointgr.h" -#include "render2d.h" -#include "sortingrenderer.h" -#include "shattersystem.h" -#include "light.h" -#include "assetmgr.h" -#include "textureloader.h" -#include "missingtexture.h" -#include "thread.h" -#include -#include -#include "pot.h" -#include "wwprofile.h" -#include "ffactory.h" -#include "dx8caps.h" -#include "formconv.h" -#include "dx8texman.h" -#include "bound.h" -#include "dx8webbrowser.h" - - -const int DEFAULT_RESOLUTION_WIDTH = 640; -const int DEFAULT_RESOLUTION_HEIGHT = 480; -const int DEFAULT_BIT_DEPTH = 32; -const int DEFAULT_TEXTURE_BIT_DEPTH = 16; - -bool DX8Wrapper_IsWindowed = true; - -// FPU_PRESERVE -int DX8Wrapper_PreserveFPU = 0; - -/*********************************************************************************** -** -** DX8Wrapper Static Variables -** -***********************************************************************************/ - -static HWND _Hwnd = NULL; -bool DX8Wrapper::IsInitted = false; -bool DX8Wrapper::_EnableTriangleDraw = true; - -int DX8Wrapper::CurRenderDevice = -1; -int DX8Wrapper::ResolutionWidth = DEFAULT_RESOLUTION_WIDTH; -int DX8Wrapper::ResolutionHeight = DEFAULT_RESOLUTION_HEIGHT; -int DX8Wrapper::BitDepth = DEFAULT_BIT_DEPTH; -int DX8Wrapper::TextureBitDepth = DEFAULT_TEXTURE_BIT_DEPTH; -bool DX8Wrapper::IsWindowed = false; -D3DFORMAT DX8Wrapper::DisplayFormat = D3DFMT_UNKNOWN; - -D3DMATRIX DX8Wrapper::old_world; -D3DMATRIX DX8Wrapper::old_view; -D3DMATRIX DX8Wrapper::old_prj; - -// shader system additions KJM v -DWORD DX8Wrapper::Vertex_Shader = 0; -DWORD DX8Wrapper::Pixel_Shader = 0; - -Vector4 DX8Wrapper::Vertex_Shader_Constants[MAX_VERTEX_SHADER_CONSTANTS]; -Vector4 DX8Wrapper::Pixel_Shader_Constants[MAX_PIXEL_SHADER_CONSTANTS]; - -LightEnvironmentClass* DX8Wrapper::Light_Environment = NULL; -RenderInfoClass* DX8Wrapper::Render_Info = NULL; - -DWORD DX8Wrapper::Vertex_Processing_Behavior = 0; -Vector3 DX8Wrapper::Ambient_Color; -// shader system additions KJM ^ -bool DX8Wrapper::world_identity; -unsigned DX8Wrapper::RenderStates[256]; -unsigned DX8Wrapper::TextureStageStates[MAX_TEXTURE_STAGES][32]; -IDirect3DBaseTexture8 * DX8Wrapper::Textures[MAX_TEXTURE_STAGES]; -RenderStateStruct DX8Wrapper::render_state; -unsigned DX8Wrapper::render_state_changed; - -bool DX8Wrapper::FogEnable = false; -D3DCOLOR DX8Wrapper::FogColor = 0; - -IDirect3D8 * DX8Wrapper::D3DInterface = NULL; -IDirect3DDevice8 * DX8Wrapper::D3DDevice = NULL; -IDirect3DSurface8 * DX8Wrapper::CurrentRenderTarget = NULL; -IDirect3DSurface8 * DX8Wrapper::DefaultRenderTarget = NULL; -bool DX8Wrapper::IsRenderToTexture = false; - -unsigned DX8Wrapper::matrix_changes = 0; -unsigned DX8Wrapper::material_changes = 0; -unsigned DX8Wrapper::vertex_buffer_changes = 0; -unsigned DX8Wrapper::index_buffer_changes = 0; -unsigned DX8Wrapper::light_changes = 0; -unsigned DX8Wrapper::texture_changes = 0; -unsigned DX8Wrapper::render_state_changes = 0; -unsigned DX8Wrapper::texture_stage_state_changes = 0; -unsigned DX8Wrapper::draw_calls = 0; -unsigned DX8Wrapper::_MainThreadID = 0; -bool DX8Wrapper::CurrentDX8LightEnables[4]; -bool DX8Wrapper::IsDeviceLost; -int DX8Wrapper::ZBias; -float DX8Wrapper::ZNear; -float DX8Wrapper::ZFar; -Matrix4x4 DX8Wrapper::ProjectionMatrix; -Matrix4x4 DX8Wrapper::DX8Transforms[D3DTS_WORLD+1]; - -DX8Caps* DX8Wrapper::CurrentCaps = 0; - -// Hack test... this disables rendering of batches of too few polygons. -unsigned DX8Wrapper::DrawPolygonLowBoundLimit=0; - -D3DADAPTER_IDENTIFIER8 DX8Wrapper::CurrentAdapterIdentifier; - -unsigned long DX8Wrapper::FrameCount = 0; - -bool _DX8SingleThreaded = false; - -unsigned number_of_DX8_calls = 0; -static unsigned last_frame_matrix_changes = 0; -static unsigned last_frame_material_changes = 0; -static unsigned last_frame_vertex_buffer_changes = 0; -static unsigned last_frame_index_buffer_changes = 0; -static unsigned last_frame_light_changes = 0; -static unsigned last_frame_texture_changes = 0; -static unsigned last_frame_render_state_changes = 0; -static unsigned last_frame_texture_stage_state_changes = 0; -static unsigned last_frame_number_of_DX8_calls = 0; -static unsigned last_frame_draw_calls = 0; - -static D3DPRESENT_PARAMETERS _PresentParameters; -static DynamicVectorClass _RenderDeviceNameTable; -static DynamicVectorClass _RenderDeviceShortNameTable; -static DynamicVectorClass _RenderDeviceDescriptionTable; - - -typedef IDirect3D8* (WINAPI *Direct3DCreate8Type) (UINT SDKVersion); -Direct3DCreate8Type Direct3DCreate8Ptr = NULL; -HINSTANCE D3D8Lib = NULL; - -DX8_CleanupHook *DX8Wrapper::m_pCleanupHook=NULL; -#ifdef EXTENDED_STATS -DX8_Stats DX8Wrapper::stats; -#endif -/*********************************************************************************** -** -** DX8Wrapper Implementation -** -***********************************************************************************/ - -void Log_DX8_ErrorCode(unsigned res) -{ - char tmp[256]=""; - - HRESULT new_res=D3DXGetErrorStringA( - res, - tmp, - sizeof(tmp)); - - if (new_res==D3D_OK) { - WWDEBUG_SAY((tmp)); - } - - WWASSERT(0); -} - -void Non_Fatal_Log_DX8_ErrorCode(unsigned res,const char * file,int line) -{ - char tmp[256]=""; - - HRESULT new_res=D3DXGetErrorStringA( - res, - tmp, - sizeof(tmp)); - - if (new_res==D3D_OK) { - WWDEBUG_SAY(("DX8 Error: %s, File: %s, Line: %d",tmp,file,line)); - } -} - -// TheSuperHackers @info helmutbuhler 14/04/2025 -// Helper function that moves x and y such that the inner rect fits into the outer rect. -// If the inner rect already is in the outer rect, then this does nothing. -// If the inner rect is larger than the outer rect, then the inner rect will be aligned to the top left of the outer rect. -void MoveRectIntoOtherRect(const RECT& inner, const RECT& outer, int* x, int* y) -{ - int dx = 0; - if (inner.right > outer.right) - dx = outer.right-inner.right; - if (inner.left < outer.left) - dx = outer.left-inner.left; - - int dy = 0; - if (inner.bottom > outer.bottom) - dy = outer.bottom-inner.bottom; - if (inner.top < outer.top) - dy = outer.top-inner.top; - - *x += dx; - *y += dy; -} - - -bool DX8Wrapper::Init(void * hwnd, bool lite) -{ - WWASSERT(!IsInitted); - - memset(Vertex_Shader_Constants,0,sizeof(Vector4)*MAX_VERTEX_SHADER_CONSTANTS); - memset(Pixel_Shader_Constants,0,sizeof(Vector4)*MAX_PIXEL_SHADER_CONSTANTS); - /* - ** Initialize all variables! - */ - _Hwnd = (HWND)hwnd; - _MainThreadID=ThreadClass::_Get_Current_Thread_ID(); - WWDEBUG_SAY(("DX8Wrapper main thread: 0x%x",_MainThreadID)); - CurRenderDevice = -1; - ResolutionWidth = DEFAULT_RESOLUTION_WIDTH; - ResolutionHeight = DEFAULT_RESOLUTION_HEIGHT; - // Initialize Render2DClass Screen Resolution - Render2DClass::Set_Screen_Resolution( RectClass( 0, 0, ResolutionWidth, ResolutionHeight ) ); - BitDepth = DEFAULT_BIT_DEPTH; - IsWindowed = false; - DX8Wrapper_IsWindowed = false; - - for (int light=0;light<4;++light) CurrentDX8LightEnables[light]=false; - - ::ZeroMemory(&old_world, sizeof(D3DMATRIX)); - ::ZeroMemory(&old_view, sizeof(D3DMATRIX)); - ::ZeroMemory(&old_prj, sizeof(D3DMATRIX)); - - //old_vertex_shader; TODO - //old_sr_shader; - //current_shader; - - //world_identity; - //CurrentFogColor; - - D3DInterface = NULL; - D3DDevice = NULL; - - WWDEBUG_SAY(("Reset DX8Wrapper statistics")); - Reset_Statistics(); - - Invalidate_Cached_Render_States(); - - if (!lite) { - D3D8Lib = LoadLibrary("D3D8.DLL"); - - if (D3D8Lib == NULL) return false; // Return false at this point if init failed - - Direct3DCreate8Ptr = (Direct3DCreate8Type) GetProcAddress(D3D8Lib, "Direct3DCreate8"); - if (Direct3DCreate8Ptr == NULL) return false; - - /* - ** Create the D3D interface object - */ - WWDEBUG_SAY(("Create Direct3D8")); - D3DInterface = Direct3DCreate8Ptr(D3D_SDK_VERSION); // TODO: handle failure cases... - if (D3DInterface == NULL) { - return(false); - } - IsInitted = true; - - /* - ** Enumerate the available devices - */ - WWDEBUG_SAY(("Enumerate devices")); - Enumerate_Devices(); - WWDEBUG_SAY(("DX8Wrapper Init completed")); - } - - return(true); -} - -void DX8Wrapper::Shutdown(void) -{ - if (D3DDevice) { - - Set_Render_Target ((IDirect3DSurface8 *)NULL); - Release_Device(); - } - - if (D3DInterface) { - D3DInterface->Release(); - D3DInterface=NULL; - - } - - if (CurrentCaps) - { - int max=CurrentCaps->Get_Max_Textures_Per_Pass(); - for (int i = 0; i < max; i++) - { - if (Textures[i]) - { - Textures[i]->Release(); - Textures[i] = NULL; - } - } - } - - if (D3DInterface) { - UINT newRefCount=D3DInterface->Release(); - D3DInterface=NULL; - } - - if (D3D8Lib) { - FreeLibrary(D3D8Lib); - D3D8Lib = NULL; - } - - _RenderDeviceNameTable.Clear(); // note - Delete_All() resizes the vector, causing a reallocation. Clear is better. jba. - _RenderDeviceShortNameTable.Clear(); - _RenderDeviceDescriptionTable.Clear(); - - DX8Caps::Shutdown(); - IsInitted = false; // 010803 srj -} - -void DX8Wrapper::Do_Onetime_Device_Dependent_Inits(void) -{ - /* - ** Set Global render states (some of which depend on caps) - */ - Compute_Caps(D3DFormat_To_WW3DFormat(DisplayFormat)); - - /* - ** Initalize any other subsystems inside of WW3D - */ - MissingTexture::_Init(); - TextureFilterClass::_Init_Filters(); - TheDX8MeshRenderer.Init(); - BoxRenderObjClass::Init(); - VertexMaterialClass::Init(); - PointGroupClass::_Init(); // This needs the VertexMaterialClass to be initted - ShatterSystem::Init(); - TextureLoader::Init(); - - Set_Default_Global_Render_States(); -} - -inline DWORD F2DW(float f) { return *((unsigned*)&f); } -void DX8Wrapper::Set_Default_Global_Render_States(void) -{ - DX8_THREAD_ASSERT(); - const D3DCAPS8 &caps = Get_Current_Caps()->Get_DX8_Caps(); - - Set_DX8_Render_State(D3DRS_RANGEFOGENABLE, (caps.RasterCaps & D3DPRASTERCAPS_FOGRANGE) ? TRUE : FALSE); - Set_DX8_Render_State(D3DRS_FOGTABLEMODE, D3DFOG_NONE); - Set_DX8_Render_State(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR); - Set_DX8_Render_State(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL); - Set_DX8_Render_State(D3DRS_COLORVERTEX, TRUE); - Set_DX8_Render_State(D3DRS_ZBIAS,0); - Set_DX8_Texture_Stage_State(1, D3DTSS_BUMPENVLSCALE, F2DW(1.0f)); - Set_DX8_Texture_Stage_State(1, D3DTSS_BUMPENVLOFFSET, F2DW(0.0f)); - Set_DX8_Texture_Stage_State(0, D3DTSS_BUMPENVMAT00,F2DW(1.0f)); - Set_DX8_Texture_Stage_State(0, D3DTSS_BUMPENVMAT01,F2DW(0.0f)); - Set_DX8_Texture_Stage_State(0, D3DTSS_BUMPENVMAT10,F2DW(0.0f)); - Set_DX8_Texture_Stage_State(0, D3DTSS_BUMPENVMAT11,F2DW(1.0f)); - -// Set_DX8_Render_State(D3DRS_CULLMODE, D3DCULL_CW); - // Set dither mode here? -} - -//MW: I added this for 'Generals'. -bool DX8Wrapper::Validate_Device(void) -{ DWORD numPasses=0; - HRESULT hRes; - - hRes=_Get_D3D_Device8()->ValidateDevice(&numPasses); - - return (hRes == D3D_OK); -} - -void DX8Wrapper::Invalidate_Cached_Render_States(void) -{ - render_state_changed=0; - - int a; - for (a=0;aSetTexture(a,NULL); - if (Textures[a] != NULL) { - Textures[a]->Release(); - } - Textures[a]=NULL; - } - - ShaderClass::Invalidate(); - - //Need to explicitly set render_state texture pointers to NULL. MW - Release_Render_State(); - - // (gth) clear the matrix shadows too - for (int i=0; iRelease_Engine_Ref(); - REF_PTR_RELEASE(render_state.vertex_buffer); - if (render_state.index_buffer) render_state.index_buffer->Release_Engine_Ref(); - REF_PTR_RELEASE(render_state.index_buffer); - REF_PTR_RELEASE(render_state.material); - for (i=0;iGet_Max_Textures_Per_Pass();++i) REF_PTR_RELEASE(render_state.Textures[i]); - - - TextureLoader::Deinit(); - SortingRendererClass::Deinit(); - DynamicVBAccessClass::_Deinit(); - DynamicIBAccessClass::_Deinit(); - ShatterSystem::Shutdown(); - PointGroupClass::_Shutdown(); - VertexMaterialClass::Shutdown(); - BoxRenderObjClass::Shutdown(); - TheDX8MeshRenderer.Shutdown(); - MissingTexture::_Deinit(); - - if (CurrentCaps) { - delete CurrentCaps; - CurrentCaps=NULL; - } - -} - - -bool DX8Wrapper::Create_Device(void) -{ - WWASSERT(D3DDevice==NULL); // for now, once you've created a device, you're stuck with it! - - D3DCAPS8 caps; - if - ( - FAILED - ( - D3DInterface->GetDeviceCaps - ( - CurRenderDevice, - WW3D_DEVTYPE, - &caps - ) - ) - ) - { - return false; - } - - ::ZeroMemory(&CurrentAdapterIdentifier, sizeof(D3DADAPTER_IDENTIFIER8)); - - if - ( - FAILED - ( - D3DInterface->GetAdapterIdentifier - ( - CurRenderDevice, - D3DENUM_NO_WHQL_LEVEL, - &CurrentAdapterIdentifier - ) - ) - ) - { - return false; - } - - Vertex_Processing_Behavior=D3DCREATE_SOFTWARE_VERTEXPROCESSING; - if (caps.DevCaps&D3DDEVCAPS_HWTRANSFORMANDLIGHT) - { - Vertex_Processing_Behavior=D3DCREATE_MIXED_VERTEXPROCESSING; - } - -#ifdef CREATE_DX8_MULTI_THREADED - Vertex_Processing_Behavior|=D3DCREATE_MULTITHREADED; - _DX8SingleThreaded=false; -#else - _DX8SingleThreaded=true; -#endif - - if (DX8Wrapper_PreserveFPU) - Vertex_Processing_Behavior |= D3DCREATE_FPU_PRESERVE; - -#ifdef CREATE_DX8_FPU_PRESERVE - Vertex_Processing_Behavior|=D3DCREATE_FPU_PRESERVE; -#endif - - HRESULT hr=D3DInterface->CreateDevice - ( - CurRenderDevice, - WW3D_DEVTYPE, - _Hwnd, - Vertex_Processing_Behavior, - &_PresentParameters, - &D3DDevice - ); - - if (FAILED(hr)) - { - return false; - } - - /* - ** Initialize all subsystems - */ - Do_Onetime_Device_Dependent_Inits(); - return true; -} - -bool DX8Wrapper::Reset_Device(bool reload_assets) -{ - WWDEBUG_SAY(("Resetting device.")); - DX8_THREAD_ASSERT(); - if ((IsInitted) && (D3DDevice != NULL)) { - // Release all non-MANAGED stuff - Set_Vertex_Buffer (NULL); - Set_Index_Buffer (NULL, 0); - if (m_pCleanupHook) { - m_pCleanupHook->ReleaseResources(); - } - DynamicVBAccessClass::_Deinit(); - DynamicIBAccessClass::_Deinit(); - DX8TextureManagerClass::Release_Textures(); - - memset(Vertex_Shader_Constants,0,sizeof(Vector4)*MAX_VERTEX_SHADER_CONSTANTS); - memset(Pixel_Shader_Constants,0,sizeof(Vector4)*MAX_PIXEL_SHADER_CONSTANTS); - - HRESULT hr=_Get_D3D_Device8()->TestCooperativeLevel(); - if (hr != D3DERR_DEVICELOST ) - { DX8CALL_HRES(Reset(&_PresentParameters),hr) - if (hr != D3D_OK) - return false; //reset failed. - } - else - return false; //device is lost and can't be reset. - - if (reload_assets) - { - DX8TextureManagerClass::Recreate_Textures(); - if (m_pCleanupHook) { - m_pCleanupHook->ReAcquireResources(); - } - } - Invalidate_Cached_Render_States(); - Set_Default_Global_Render_States(); - WWDEBUG_SAY(("Device reset completed")); - return true; - } - WWDEBUG_SAY(("Device reset failed")); - return false; -} - -void DX8Wrapper::Release_Device(void) -{ - if (D3DDevice) { - - for (int a=0;aRelease_Engine_Ref(); - REF_PTR_RELEASE(render_state.vertex_buffer); - if (render_state.index_buffer) render_state.index_buffer->Release_Engine_Ref(); - REF_PTR_RELEASE(render_state.index_buffer); - - /* - ** Shutdown all subsystems - */ - Do_Onetime_Device_Dependent_Shutdowns(); - - /* - ** Release the device - */ - - D3DDevice->Release(); - D3DDevice=NULL; - } -} - -void DX8Wrapper::Enumerate_Devices() -{ - DX8_Assert(); - - int adapter_count = D3DInterface->GetAdapterCount(); - for (int adapter_index=0; adapter_indexGetAdapterIdentifier(adapter_index,D3DENUM_NO_WHQL_LEVEL,&id); - - if (res == D3D_OK) { - - /* - ** Set up the device name - */ - StringClass device_name = id.Description; - _RenderDeviceNameTable.Add(device_name); - _RenderDeviceShortNameTable.Add(device_name); // for now, just add the same name to the "pretty name table" - - /* - ** Set up the render device description - ** TODO: Fill in more fields of the render device description? (need some lookup tables) - */ - RenderDeviceDescClass desc; - desc.set_device_name(id.Description); - desc.set_driver_name(id.Driver); - - char buf[64]; - sprintf(buf,"%d.%d.%d.%d", //"%04x.%04x.%04x.%04x", - HIWORD(id.DriverVersion.HighPart), - LOWORD(id.DriverVersion.HighPart), - HIWORD(id.DriverVersion.LowPart), - LOWORD(id.DriverVersion.LowPart)); - - desc.set_driver_version(buf); - - /* - ** Enumerate the resolutions - */ - desc.reset_resolution_list(); - int mode_count = D3DInterface->GetAdapterModeCount(adapter_index); - for (int mode_index=0; mode_indexEnumAdapterModes(adapter_index,mode_index,&d3dmode); - - if (res == D3D_OK) { - int bits = 0; - switch (d3dmode.Format) - { - case D3DFMT_R8G8B8: - case D3DFMT_A8R8G8B8: - case D3DFMT_X8R8G8B8: bits = 32; break; - - case D3DFMT_R5G6B5: - case D3DFMT_X1R5G5B5: bits = 16; break; - } - - /* - ** If we recognize the format, add it to the list - ** TODO: should we handle more formats? will any cards report more than 24 or 16 bit? - */ - if (bits != 0) { - desc.add_resolution(d3dmode.Width,d3dmode.Height,bits); - } - } - } - - /* - ** Add the render device to our table - */ - _RenderDeviceDescriptionTable.Add(desc); - } - } -} - -bool DX8Wrapper::Set_Any_Render_Device(void) -{ - // Try windowed first - int dev_number = 0; - for (; dev_number < _RenderDeviceNameTable.Count(); dev_number++) { - if (Set_Render_Device(dev_number,-1,-1,-1,1,false)) { - return true; - } - } - - // Then fullscreen - for (dev_number = 0; dev_number < _RenderDeviceNameTable.Count(); dev_number++) { - if (Set_Render_Device(dev_number,-1,-1,-1,0,false)) { - return true; - } - } - - return false; -} - -bool DX8Wrapper::Set_Render_Device -( - const char * dev_name, - int width, - int height, - int bits, - int windowed, - bool resize_window -) -{ - for ( int dev_number = 0; dev_number < _RenderDeviceNameTable.Count(); dev_number++) { - if ( strcmp( dev_name, _RenderDeviceNameTable[dev_number]) == 0) { - return Set_Render_Device( dev_number, width, height, bits, windowed, resize_window ); - } - - if ( strcmp( dev_name, _RenderDeviceShortNameTable[dev_number]) == 0) { - return Set_Render_Device( dev_number, width, height, bits, windowed, resize_window ); - } - } - return false; -} - -void DX8Wrapper::Get_Format_Name(unsigned int format, StringClass *tex_format) -{ - *tex_format="Unknown"; - switch (format) { - case D3DFMT_A8R8G8B8: *tex_format="D3DFMT_A8R8G8B8"; break; - case D3DFMT_R8G8B8: *tex_format="D3DFMT_R8G8B8"; break; - case D3DFMT_A4R4G4B4: *tex_format="D3DFMT_A4R4G4B4"; break; - case D3DFMT_A1R5G5B5: *tex_format="D3DFMT_A1R5G5B5"; break; - case D3DFMT_R5G6B5: *tex_format="D3DFMT_R5G6B5"; break; - case D3DFMT_L8: *tex_format="D3DFMT_L8"; break; - case D3DFMT_A8: *tex_format="D3DFMT_A8"; break; - case D3DFMT_P8: *tex_format="D3DFMT_P8"; break; - case D3DFMT_X8R8G8B8: *tex_format="D3DFMT_X8R8G8B8"; break; - case D3DFMT_X1R5G5B5: *tex_format="D3DFMT_X1R5G5B5"; break; - case D3DFMT_R3G3B2: *tex_format="D3DFMT_R3G3B2"; break; - case D3DFMT_A8R3G3B2: *tex_format="D3DFMT_A8R3G3B2"; break; - case D3DFMT_X4R4G4B4: *tex_format="D3DFMT_X4R4G4B4"; break; - case D3DFMT_A8P8: *tex_format="D3DFMT_A8P8"; break; - case D3DFMT_A8L8: *tex_format="D3DFMT_A8L8"; break; - case D3DFMT_A4L4: *tex_format="D3DFMT_A4L4"; break; - case D3DFMT_V8U8: *tex_format="D3DFMT_V8U8"; break; - case D3DFMT_L6V5U5: *tex_format="D3DFMT_L6V5U5"; break; - case D3DFMT_X8L8V8U8: *tex_format="D3DFMT_X8L8V8U8"; break; - case D3DFMT_Q8W8V8U8: *tex_format="D3DFMT_Q8W8V8U8"; break; - case D3DFMT_V16U16: *tex_format="D3DFMT_V16U16"; break; - case D3DFMT_W11V11U10: *tex_format="D3DFMT_W11V11U10"; break; - case D3DFMT_UYVY: *tex_format="D3DFMT_UYVY"; break; - case D3DFMT_YUY2: *tex_format="D3DFMT_YUY2"; break; - case D3DFMT_DXT1: *tex_format="D3DFMT_DXT1"; break; - case D3DFMT_DXT2: *tex_format="D3DFMT_DXT2"; break; - case D3DFMT_DXT3: *tex_format="D3DFMT_DXT3"; break; - case D3DFMT_DXT4: *tex_format="D3DFMT_DXT4"; break; - case D3DFMT_DXT5: *tex_format="D3DFMT_DXT5"; break; - case D3DFMT_D16_LOCKABLE: *tex_format="D3DFMT_D16_LOCKABLE"; break; - case D3DFMT_D32: *tex_format="D3DFMT_D32"; break; - case D3DFMT_D15S1: *tex_format="D3DFMT_D15S1"; break; - case D3DFMT_D24S8: *tex_format="D3DFMT_D24S8"; break; - case D3DFMT_D16: *tex_format="D3DFMT_D16"; break; - case D3DFMT_D24X8: *tex_format="D3DFMT_D24X8"; break; - case D3DFMT_D24X4S4: *tex_format="D3DFMT_D24X4S4"; break; - default: break; - } -} - -void DX8Wrapper::Resize_And_Position_Window() -{ - // Get the current dimensions of the 'render area' of the window - RECT rect = { 0 }; - ::GetClientRect (_Hwnd, &rect); - - // Is the window the correct size for this resolution? - if ((rect.right-rect.left) != ResolutionWidth || - (rect.bottom-rect.top) != ResolutionHeight) { - - // Calculate what the main window's bounding rectangle should be to - // accommodate this resolution - rect.left = 0; - rect.top = 0; - rect.right = ResolutionWidth; - rect.bottom = ResolutionHeight; - DWORD dwstyle = ::GetWindowLong (_Hwnd, GWL_STYLE); - AdjustWindowRect (&rect, dwstyle, FALSE); - int width = rect.right-rect.left; - int height = rect.bottom-rect.top; - - // Resize the window to fit this resolution - if (!IsWindowed) - { - ::SetWindowPos(_Hwnd, HWND_TOPMOST, 0, 0, width, height, SWP_NOSIZE | SWP_NOMOVE); - - DEBUG_LOG(("Window resized to w:%d h:%d", width, height)); - } - else - { - // TheSuperHackers @feature helmutbuhler 14/04/2025 - // Center the window in the workarea of the monitor it is on. - MONITORINFO mi = {sizeof(MONITORINFO)}; - GetMonitorInfo(MonitorFromWindow(_Hwnd, MONITOR_DEFAULTTOPRIMARY), &mi); - int left = (mi.rcWork.left + mi.rcWork.right - width) / 2; - int top = (mi.rcWork.top + mi.rcWork.bottom - height) / 2; - - // TheSuperHackers @feature helmutbuhler 14/04/2025 - // Move the window to try fit it into the monitor area, if one of its dimensions is larger than the work area. - // Otherwise align the window to the top left edges, if it is even larger than the monitor area. - RECT rectClient; - rectClient.left = left - rect.left; - rectClient.top = top - rect.top; - rectClient.right = rectClient.left + ResolutionWidth; - rectClient.bottom = rectClient.top + ResolutionHeight; - MoveRectIntoOtherRect(rectClient, mi.rcMonitor, &left, &top); - - ::SetWindowPos (_Hwnd, NULL, left, top, width, height, SWP_NOZORDER); - - DEBUG_LOG(("Window positioned to x:%d y:%d, resized to w:%d h:%d", left, top, width, height)); - } - } -} - -bool DX8Wrapper::Set_Render_Device(int dev, int width, int height, int bits, int windowed, - bool resize_window,bool reset_device, bool restore_assets) -{ - WWASSERT(IsInitted); - WWASSERT(dev >= -1); - WWASSERT(dev < _RenderDeviceNameTable.Count()); - - /* - ** If user has never selected a render device, start out with device 0 - */ - if ((CurRenderDevice == -1) && (dev == -1)) { - CurRenderDevice = 0; - } else if (dev != -1) { - CurRenderDevice = dev; - } - - /* - ** If user doesn't want to change res, set the res variables to match the - ** current resolution - */ - if (width != -1) ResolutionWidth = width; - if (height != -1) ResolutionHeight = height; - - // Initialize Render2DClass Screen Resolution - Render2DClass::Set_Screen_Resolution( RectClass( 0, 0, ResolutionWidth, ResolutionHeight ) ); - - if (bits != -1) BitDepth = bits; - if (windowed != -1) IsWindowed = (windowed != 0); - DX8Wrapper_IsWindowed = IsWindowed; - - WWDEBUG_SAY(("Attempting Set_Render_Device: name: %s (%s:%s), width: %d, height: %d, windowed: %d", - _RenderDeviceNameTable[CurRenderDevice].str(),_RenderDeviceDescriptionTable[CurRenderDevice].Get_Driver_Name(), - _RenderDeviceDescriptionTable[CurRenderDevice].Get_Driver_Version(),ResolutionWidth,ResolutionHeight,(IsWindowed ? 1 : 0))); - -#ifdef _WINDOWS - // PWG 4/13/2000 - changed so that if you say to resize the window it resizes - // regardless of whether its windowed or not as OpenGL resizes its self around - // the caption and edges of the window type you provide, so its important to - // push the client area to be the size you really want. - // if ( resize_window && windowed ) { - if (resize_window) { - Resize_And_Position_Window(); - } -#endif - //must be either resetting existing device or creating a new one. - WWASSERT(reset_device || D3DDevice == NULL); - - /* - ** Initialize values for D3DPRESENT_PARAMETERS members. - */ - ::ZeroMemory(&_PresentParameters, sizeof(D3DPRESENT_PARAMETERS)); - - _PresentParameters.BackBufferWidth = ResolutionWidth; - _PresentParameters.BackBufferHeight = ResolutionHeight; - _PresentParameters.BackBufferCount = IsWindowed ? 1 : 2; - - _PresentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; - _PresentParameters.SwapEffect = IsWindowed ? D3DSWAPEFFECT_DISCARD : D3DSWAPEFFECT_FLIP; // Shouldn't this be D3DSWAPEFFECT_FLIP? - _PresentParameters.hDeviceWindow = _Hwnd; - _PresentParameters.Windowed = IsWindowed; - - _PresentParameters.EnableAutoDepthStencil = TRUE; // Driver will attempt to match Z-buffer depth - _PresentParameters.Flags=0; // We're not going to lock the backbuffer - - _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; - _PresentParameters.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; - - /* - ** Set up the buffer formats. Several issues here: - ** - if in windowed mode, the backbuffer must use the current display format. - ** - the depth buffer must use - */ - if (IsWindowed) { - - D3DDISPLAYMODE desktop_mode; - ::ZeroMemory(&desktop_mode, sizeof(D3DDISPLAYMODE)); - D3DInterface->GetAdapterDisplayMode( CurRenderDevice, &desktop_mode ); - - DisplayFormat=_PresentParameters.BackBufferFormat = desktop_mode.Format; - - // In windowed mode, define the bitdepth from desktop mode (as it can't be changed) - switch (_PresentParameters.BackBufferFormat) { - case D3DFMT_X8R8G8B8: - case D3DFMT_A8R8G8B8: - case D3DFMT_R8G8B8: BitDepth=32; break; - case D3DFMT_A4R4G4B4: - case D3DFMT_A1R5G5B5: - case D3DFMT_R5G6B5: BitDepth=16; break; - case D3DFMT_L8: - case D3DFMT_A8: - case D3DFMT_P8: BitDepth=8; break; - default: - // Unknown backbuffer format probably means the device can't do windowed - return false; - } - - if (BitDepth==32 && D3DInterface->CheckDeviceType(0,D3DDEVTYPE_HAL,desktop_mode.Format,D3DFMT_A8R8G8B8, TRUE) == D3D_OK) - { //promote 32-bit modes to include destination alpha - _PresentParameters.BackBufferFormat = D3DFMT_A8R8G8B8; - } - - /* - ** Find a appropriate Z buffer - */ - if (!Find_Z_Mode(DisplayFormat,_PresentParameters.BackBufferFormat,&_PresentParameters.AutoDepthStencilFormat)) - { - // If opening 32 bit mode failed, try 16 bit, even if the desktop happens to be 32 bit - if (BitDepth==32) { - BitDepth=16; - _PresentParameters.BackBufferFormat=D3DFMT_R5G6B5; - if (!Find_Z_Mode(_PresentParameters.BackBufferFormat,_PresentParameters.BackBufferFormat,&_PresentParameters.AutoDepthStencilFormat)) { - _PresentParameters.AutoDepthStencilFormat=D3DFMT_UNKNOWN; - } - } - else { - _PresentParameters.AutoDepthStencilFormat=D3DFMT_UNKNOWN; - } - } - - } else { - - /* - ** Try to find a mode that matches the user's desired bit-depth. - */ - Find_Color_And_Z_Mode(ResolutionWidth,ResolutionHeight,BitDepth,&DisplayFormat, - &_PresentParameters.BackBufferFormat,&_PresentParameters.AutoDepthStencilFormat); - } - - /* - ** Time to actually create the device. - */ - if (_PresentParameters.AutoDepthStencilFormat==D3DFMT_UNKNOWN) { - if (BitDepth==32) { - _PresentParameters.AutoDepthStencilFormat=D3DFMT_D32; - } - else { - _PresentParameters.AutoDepthStencilFormat=D3DFMT_D16; - } - } - - StringClass displayFormat; - StringClass backbufferFormat; - - Get_Format_Name(DisplayFormat,&displayFormat); - Get_Format_Name(_PresentParameters.BackBufferFormat,&backbufferFormat); - - WWDEBUG_SAY(("Using Display/BackBuffer Formats: %s/%s",displayFormat.str(),backbufferFormat.str())); - - bool ret; - - if (reset_device) - { - WWDEBUG_SAY(("DX8Wrapper::Set_Render_Device is resetting the device.")); - ret = Reset_Device(restore_assets); //reset device without restoring data - we're likely switching out of the app. - } - else - ret = Create_Device(); - - WWDEBUG_SAY(("Reset/Create_Device done, reset_device=%d, restore_assets=%d", reset_device, restore_assets)); - - return ret; -} - -bool DX8Wrapper::Set_Next_Render_Device(void) -{ - int new_dev = (CurRenderDevice + 1) % _RenderDeviceNameTable.Count(); - return Set_Render_Device(new_dev); -} - -bool DX8Wrapper::Toggle_Windowed(void) -{ -#ifdef WW3D_DX8 - // State OK? - assert (IsInitted); - if (IsInitted) { - - // Get information about the current render device's resolutions - const RenderDeviceDescClass &render_device = Get_Render_Device_Desc (); - const DynamicVectorClass &resolutions = render_device.Enumerate_Resolutions (); - - // Loop through all the resolutions supported by the current device. - // If we aren't currently running under one of these resolutions, - // then we should probably to the closest resolution before - // toggling the windowed state. - int curr_res = -1; - for (int res = 0; - (res < resolutions.Count ()) && (curr_res == -1); - res ++) { - - // Is this the resolution we are looking for? - if ((resolutions[res].Width == ResolutionWidth) && - (resolutions[res].Height == ResolutionHeight) && - (resolutions[res].BitDepth == BitDepth)) { - curr_res = res; - } - } - - if (curr_res == -1) { - - // We don't match any of the standard resolutions, - // so set the first resolution and toggle the windowed state. - return Set_Device_Resolution (resolutions[0].Width, - resolutions[0].Height, - resolutions[0].BitDepth, - !IsWindowed, true); - } else { - - // Toggle the windowed state - return Set_Device_Resolution (-1, -1, -1, !IsWindowed, true); - } - } -#endif //WW3D_DX8 - - return false; -} - -void DX8Wrapper::Set_Swap_Interval(int swap) -{ - switch (swap) { - case 0: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; break; - case 1: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE ; break; - case 2: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_TWO; break; - case 3: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_THREE; break; - default: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE ; break; - } - - WWDEBUG_SAY(("DX8Wrapper::Set_Swap_Interval is resetting the device.")); - Reset_Device(); -} - -int DX8Wrapper::Get_Swap_Interval(void) -{ - return _PresentParameters.FullScreen_PresentationInterval; -} - -bool DX8Wrapper::Has_Stencil(void) -{ - bool has_stencil = (_PresentParameters.AutoDepthStencilFormat == D3DFMT_D24S8 || - _PresentParameters.AutoDepthStencilFormat == D3DFMT_D24X4S4); - return has_stencil; -} - -int DX8Wrapper::Get_Render_Device_Count(void) -{ - return _RenderDeviceNameTable.Count(); - -} -int DX8Wrapper::Get_Render_Device(void) -{ - assert(IsInitted); - return CurRenderDevice; -} - -const RenderDeviceDescClass & DX8Wrapper::Get_Render_Device_Desc(int deviceidx) -{ - WWASSERT(IsInitted); - - if ((deviceidx == -1) && (CurRenderDevice == -1)) { - CurRenderDevice = 0; - } - - // if the device index is -1 then we want the current device - if (deviceidx == -1) { - WWASSERT(CurRenderDevice >= 0); - WWASSERT(CurRenderDevice < _RenderDeviceNameTable.Count()); - return _RenderDeviceDescriptionTable[CurRenderDevice]; - } - - // We can only ask for multiple device information if the devices - // have been detected. - WWASSERT(deviceidx >= 0); - WWASSERT(deviceidx < _RenderDeviceNameTable.Count()); - return _RenderDeviceDescriptionTable[deviceidx]; -} - -const char * DX8Wrapper::Get_Render_Device_Name(int device_index) -{ - device_index = device_index % _RenderDeviceShortNameTable.Count(); - return _RenderDeviceShortNameTable[device_index]; -} - -bool DX8Wrapper::Set_Device_Resolution(int width,int height,int bits,int windowed, bool resize_window) -{ - if (D3DDevice != NULL) { - - if (width != -1) { - _PresentParameters.BackBufferWidth = ResolutionWidth = width; - } - if (height != -1) { - _PresentParameters.BackBufferHeight = ResolutionHeight = height; - } - if (resize_window) - { - Resize_And_Position_Window(); - } -#pragma message("TODO: support changing windowed status and changing the bit depth") - WWDEBUG_SAY(("DX8Wrapper::Set_Device_Resolution is resetting the device.")); - return Reset_Device(); - } else { - return false; - } -} - -void DX8Wrapper::Get_Device_Resolution(int & set_w,int & set_h,int & set_bits,bool & set_windowed) -{ - WWASSERT(IsInitted); - - set_w = ResolutionWidth; - set_h = ResolutionHeight; - set_bits = BitDepth; - set_windowed = IsWindowed; - - return ; -} - -void DX8Wrapper::Get_Render_Target_Resolution(int & set_w,int & set_h,int & set_bits,bool & set_windowed) -{ - WWASSERT(IsInitted); - - if (CurrentRenderTarget != NULL) { - D3DSURFACE_DESC info; - CurrentRenderTarget->GetDesc (&info); - - set_w = info.Width; - set_h = info.Height; - set_bits = BitDepth; // should we get the actual bit depth of the target? - set_windowed = IsWindowed; // this doesn't really make sense for render targets (shouldn't matter)... - - } else { - Get_Device_Resolution (set_w, set_h, set_bits, set_windowed); - } - - return ; -} - -bool DX8Wrapper::Registry_Save_Render_Device( const char * sub_key ) -{ - int width, height, depth; - bool windowed; - Get_Device_Resolution(width, height, depth, windowed); - return Registry_Save_Render_Device(sub_key, CurRenderDevice, ResolutionWidth, ResolutionHeight, BitDepth, IsWindowed, TextureBitDepth); -} - -bool DX8Wrapper::Registry_Save_Render_Device( const char *sub_key, int device, int width, int height, int depth, bool windowed, int texture_depth) -{ - RegistryClass * registry = W3DNEW RegistryClass( sub_key ); - WWASSERT( registry ); - - if ( !registry->Is_Valid() ) { - delete registry; - WWDEBUG_SAY(( "Error getting Registry" )); - return false; - } - - registry->Set_String( VALUE_NAME_RENDER_DEVICE_NAME, - _RenderDeviceShortNameTable[device] ); - registry->Set_Int( VALUE_NAME_RENDER_DEVICE_WIDTH, width ); - registry->Set_Int( VALUE_NAME_RENDER_DEVICE_HEIGHT, height ); - registry->Set_Int( VALUE_NAME_RENDER_DEVICE_DEPTH, depth ); - registry->Set_Int( VALUE_NAME_RENDER_DEVICE_WINDOWED, windowed ); - registry->Set_Int( VALUE_NAME_RENDER_DEVICE_TEXTURE_DEPTH, texture_depth ); - - delete registry; - return true; -} - -bool DX8Wrapper::Registry_Load_Render_Device( const char * sub_key, bool resize_window ) -{ - char name[ 200 ]; - int width,height,depth,windowed; - - if ( Registry_Load_Render_Device( sub_key, - name, - sizeof(name), - width, - height, - depth, - windowed, - TextureBitDepth) && - (*name != 0)) - { - WWDEBUG_SAY(( "Device %s (%d X %d) %d bit windowed:%d", name,width,height,depth,windowed)); - - if (TextureBitDepth==16 || TextureBitDepth==32) { -// WWDEBUG_SAY(( "Texture depth %d", TextureBitDepth)); - } else { - WWDEBUG_SAY(( "Invalid texture depth %d, switching to 16 bits", TextureBitDepth)); - TextureBitDepth=16; - } - - if ( Set_Render_Device( name, width,height,depth,windowed, resize_window ) != true) { - return Set_Any_Render_Device(); - } - - return true; - } - - WWDEBUG_SAY(( "Error getting Registry" )); - - return Set_Any_Render_Device(); -} - -bool DX8Wrapper::Registry_Load_Render_Device( const char * sub_key, char *device, int device_len, int &width, int &height, int &depth, int &windowed, int &texture_depth) -{ - RegistryClass registry( sub_key ); - - if ( registry.Is_Valid() ) { - registry.Get_String( VALUE_NAME_RENDER_DEVICE_NAME, - device, device_len); - - width = registry.Get_Int( VALUE_NAME_RENDER_DEVICE_WIDTH, -1 ); - height = registry.Get_Int( VALUE_NAME_RENDER_DEVICE_HEIGHT, -1 ); - depth = registry.Get_Int( VALUE_NAME_RENDER_DEVICE_DEPTH, -1 ); - windowed = registry.Get_Int( VALUE_NAME_RENDER_DEVICE_WINDOWED, -1 ); - texture_depth = registry.Get_Int( VALUE_NAME_RENDER_DEVICE_TEXTURE_DEPTH, -1 ); - return true; - } - *device=0; - width=-1; - height=-1; - depth=-1; - windowed=-1; - texture_depth=-1; - return false; -} - - -bool DX8Wrapper::Find_Color_And_Z_Mode(int resx,int resy,int bitdepth,D3DFORMAT * set_colorbuffer,D3DFORMAT * set_backbuffer,D3DFORMAT * set_zmode) -{ - static D3DFORMAT _formats16[] = - { - D3DFMT_R5G6B5, - D3DFMT_X1R5G5B5, - D3DFMT_A1R5G5B5 - }; - - static D3DFORMAT _formats32[] = - { - D3DFMT_A8R8G8B8, - D3DFMT_X8R8G8B8, - D3DFMT_R8G8B8, - }; - - /* - ** Select the table that we're going to use to search for a valid backbuffer format - */ - D3DFORMAT * format_table = NULL; - int format_count = 0; - - if (BitDepth == 16) { - format_table = _formats16; - format_count = sizeof(_formats16) / sizeof(D3DFORMAT); - } else { - format_table = _formats32; - format_count = sizeof(_formats32) / sizeof(D3DFORMAT); - } - - /* - ** now search for a valid format - */ - bool found = false; - unsigned int mode = 0; - - int format_index=0; - for (; format_index < format_count; format_index++) { - found |= Find_Color_Mode(format_table[format_index],resx,resy,&mode); - if (found) break; - } - - if (!found) { - return false; - } else { - *set_backbuffer=*set_colorbuffer = format_table[format_index]; - } - - if (bitdepth==32 && *set_colorbuffer == D3DFMT_X8R8G8B8 && D3DInterface->CheckDeviceType(0,D3DDEVTYPE_HAL,*set_colorbuffer,D3DFMT_A8R8G8B8, TRUE) == D3D_OK) - { //promote 32-bit modes to include destination alpha when supported - *set_backbuffer = D3DFMT_A8R8G8B8; - } - - /* - ** We found a backbuffer format, now find a zbuffer format - */ - return Find_Z_Mode(*set_colorbuffer,*set_backbuffer, set_zmode); -}; - - -// find the resolution mode with at least resx,resy with the highest supported -// refresh rate -bool DX8Wrapper::Find_Color_Mode(D3DFORMAT colorbuffer, int resx, int resy, UINT *mode) -{ - UINT i,j,modemax; - UINT rx,ry; - D3DDISPLAYMODE dmode; - ::ZeroMemory(&dmode, sizeof(D3DDISPLAYMODE)); - - rx=(unsigned int) resx; - ry=(unsigned int) resy; - - bool found=false; - - modemax=D3DInterface->GetAdapterModeCount(D3DADAPTER_DEFAULT); - - i=0; - - while (iEnumAdapterModes(D3DADAPTER_DEFAULT, i, &dmode); - if (dmode.Width==rx && dmode.Height==ry && dmode.Format==colorbuffer) { - WWDEBUG_SAY(("Found valid color mode. Width = %d Height = %d Format = %d",dmode.Width,dmode.Height,dmode.Format)); - found=true; - } - i++; - } - - i--; // this is the first valid mode - - // no match - if (!found) { - WWDEBUG_SAY(("Failed to find a valid color mode")); - return false; - } - - // go to the highest refresh rate in this mode - bool stillok=true; - - j=i; - while (jEnumAdapterModes(D3DADAPTER_DEFAULT, j, &dmode); - if (dmode.Width==rx && dmode.Height==ry && dmode.Format==colorbuffer) - stillok=true; else stillok=false; - j++; - } - - if (stillok==false) *mode=j-2; - else *mode=i; - - return true; -} - -// Helper function to find a Z buffer mode for the colorbuffer -// Will look for greatest Z precision -bool DX8Wrapper::Find_Z_Mode(D3DFORMAT colorbuffer,D3DFORMAT backbuffer, D3DFORMAT *zmode) -{ - //MW: Swapped the next 2 tests so that Stencil modes get tested first. - if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D24S8)) - { - *zmode=D3DFMT_D24S8; - WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D24S8")); - return true; - } - - if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D32)) - { - *zmode=D3DFMT_D32; - WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D32")); - return true; - } - - if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D24X8)) - { - *zmode=D3DFMT_D24X8; - WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D24X8")); - return true; - } - - if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D24X4S4)) - { - *zmode=D3DFMT_D24X4S4; - WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D24X4S4")); - return true; - } - - if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D16)) - { - *zmode=D3DFMT_D16; - WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D16")); - return true; - } - - if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D15S1)) - { - *zmode=D3DFMT_D15S1; - WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D15S1")); - return true; - } - - // can't find a match - WWDEBUG_SAY(("Failed to find a valid zbuffer mode")); - return false; -} - -bool DX8Wrapper::Test_Z_Mode(D3DFORMAT colorbuffer,D3DFORMAT backbuffer, D3DFORMAT zmode) -{ - // See if we have this mode first - if (FAILED(D3DInterface->CheckDeviceFormat(D3DADAPTER_DEFAULT,WW3D_DEVTYPE, - colorbuffer,D3DUSAGE_DEPTHSTENCIL,D3DRTYPE_SURFACE,zmode))) - { - WWDEBUG_SAY(("CheckDeviceFormat failed. Colorbuffer format = %d Zbufferformat = %d",colorbuffer,zmode)); - return false; - } - - // Then see if it matches the color buffer - if(FAILED(D3DInterface->CheckDepthStencilMatch(D3DADAPTER_DEFAULT, WW3D_DEVTYPE, - colorbuffer,backbuffer,zmode))) - { - WWDEBUG_SAY(("CheckDepthStencilMatch failed. Colorbuffer format = %d Backbuffer format = %d Zbufferformat = %d",colorbuffer,backbuffer,zmode)); - return false; - } - return true; -} - - -void DX8Wrapper::Reset_Statistics() -{ - matrix_changes = 0; - material_changes = 0; - vertex_buffer_changes = 0; - index_buffer_changes = 0; - light_changes = 0; - texture_changes = 0; - render_state_changes =0; - texture_stage_state_changes =0; - draw_calls =0; - - number_of_DX8_calls = 0; - last_frame_matrix_changes = 0; - last_frame_material_changes = 0; - last_frame_vertex_buffer_changes = 0; - last_frame_index_buffer_changes = 0; - last_frame_light_changes = 0; - last_frame_texture_changes = 0; - last_frame_render_state_changes = 0; - last_frame_texture_stage_state_changes = 0; - last_frame_number_of_DX8_calls = 0; - last_frame_draw_calls =0; -} - -void DX8Wrapper::Begin_Statistics() -{ - matrix_changes=0; - material_changes=0; - vertex_buffer_changes=0; - index_buffer_changes=0; - light_changes=0; - texture_changes = 0; - render_state_changes =0; - texture_stage_state_changes =0; - number_of_DX8_calls=0; - draw_calls=0; -} - -void DX8Wrapper::End_Statistics() -{ - last_frame_matrix_changes=matrix_changes; - last_frame_material_changes=material_changes; - last_frame_vertex_buffer_changes=vertex_buffer_changes; - last_frame_index_buffer_changes=index_buffer_changes; - last_frame_light_changes=light_changes; - last_frame_texture_changes = texture_changes; - last_frame_render_state_changes = render_state_changes; - last_frame_texture_stage_state_changes = texture_stage_state_changes; - last_frame_number_of_DX8_calls=number_of_DX8_calls; - last_frame_draw_calls=draw_calls; -} - -unsigned DX8Wrapper::Get_Last_Frame_Matrix_Changes() { return last_frame_matrix_changes; } -unsigned DX8Wrapper::Get_Last_Frame_Material_Changes() { return last_frame_material_changes; } -unsigned DX8Wrapper::Get_Last_Frame_Vertex_Buffer_Changes() { return last_frame_vertex_buffer_changes; } -unsigned DX8Wrapper::Get_Last_Frame_Index_Buffer_Changes() { return last_frame_index_buffer_changes; } -unsigned DX8Wrapper::Get_Last_Frame_Light_Changes() { return last_frame_light_changes; } -unsigned DX8Wrapper::Get_Last_Frame_Texture_Changes() { return last_frame_texture_changes; } -unsigned DX8Wrapper::Get_Last_Frame_Render_State_Changes() { return last_frame_render_state_changes; } -unsigned DX8Wrapper::Get_Last_Frame_Texture_Stage_State_Changes() { return last_frame_texture_stage_state_changes; } -unsigned DX8Wrapper::Get_Last_Frame_DX8_Calls() { return last_frame_number_of_DX8_calls; } -unsigned DX8Wrapper::Get_Last_Frame_Draw_Calls() { return last_frame_draw_calls; } -unsigned long DX8Wrapper::Get_FrameCount(void) {return FrameCount;} - -void DX8_Assert() -{ - WWASSERT(DX8Wrapper::_Get_D3D8()); - DX8_THREAD_ASSERT(); -} - -void DX8Wrapper::Begin_Scene(void) -{ - DX8_THREAD_ASSERT(); - -#if ENABLE_EMBEDDED_BROWSER - DX8WebBrowser::Update(); -#endif - - DX8CALL(BeginScene()); - - DX8WebBrowser::Update(); -} - -void DX8Wrapper::End_Scene(bool flip_frames) -{ - DX8_THREAD_ASSERT(); - DX8CALL(EndScene()); - - DX8WebBrowser::Render(0); - - if (flip_frames) { - DX8_Assert(); - HRESULT hr; - { - WWPROFILE("DX8Device::Present()"); - hr=_Get_D3D_Device8()->Present(NULL, NULL, NULL, NULL); - } - - number_of_DX8_calls++; - - if (SUCCEEDED(hr)) { -#ifdef EXTENDED_STATS - if (stats.m_sleepTime) { - ::Sleep(stats.m_sleepTime); - } -#endif - IsDeviceLost=false; - FrameCount++; - } - else { - IsDeviceLost=true; - } - - // If the device was lost we need to check for cooperative level and possibly reset the device - if (hr==D3DERR_DEVICELOST) { - hr=_Get_D3D_Device8()->TestCooperativeLevel(); - if (hr==D3DERR_DEVICENOTRESET) { - WWDEBUG_SAY(("DX8Wrapper::End_Scene is resetting the device.")); - Reset_Device(); - } - else { - // Sleep it not active - ThreadClass::Sleep_Ms(200); - } - } - else { - DX8_ErrorCode(hr); - } - } - - // Each frame, release all of the buffers and textures. - Set_Vertex_Buffer(NULL); - Set_Index_Buffer(NULL,0); - for (int i=0;iGet_Max_Textures_Per_Pass();++i) Set_Texture(i,NULL); - Set_Material(NULL); -} - - -void DX8Wrapper::Flip_To_Primary(void) -{ - // If we are fullscreen and the current frame is odd then we need - // to force a page flip to ensure that the first buffer in the flipping - // chain is the one visible. - if (!IsWindowed) { - DX8_Assert(); - - int numBuffers = (_PresentParameters.BackBufferCount + 1); - int visibleBuffer = (FrameCount % numBuffers); - int flipCount = ((numBuffers - visibleBuffer) % numBuffers); - int resetAttempts = 0; - - while ((flipCount > 0) && (resetAttempts < 3)) { - HRESULT hr = _Get_D3D_Device8()->TestCooperativeLevel(); - - if (FAILED(hr)) { - WWDEBUG_SAY(("TestCooperativeLevel Failed!")); - - if (D3DERR_DEVICELOST == hr) { - IsDeviceLost=true; - WWDEBUG_SAY(("DEVICELOST: Cannot flip to primary.")); - return; - } - IsDeviceLost=false; - - if (D3DERR_DEVICENOTRESET == hr) { - WWDEBUG_SAY(("DEVICENOTRESET")); - Reset_Device(); - resetAttempts++; - } - } else { - WWDEBUG_SAY(("Flipping: %ld", FrameCount)); - hr = _Get_D3D_Device8()->Present(NULL, NULL, NULL, NULL); - - if (SUCCEEDED(hr)) { - IsDeviceLost=false; - FrameCount++; - WWDEBUG_SAY(("Flip to primary succeeded %ld", FrameCount)); - } - else { - IsDeviceLost=true; - } - } - - --flipCount; - } - } -} - - -void DX8Wrapper::Clear(bool clear_color, bool clear_z_stencil, const Vector3 &color, float dest_alpha, float z, unsigned int stencil) -{ - DX8_THREAD_ASSERT(); - // If we try to clear a stencil buffer which is not there, the entire call will fail - bool has_stencil = ( _PresentParameters.AutoDepthStencilFormat == D3DFMT_D15S1 || - _PresentParameters.AutoDepthStencilFormat == D3DFMT_D24S8 || - _PresentParameters.AutoDepthStencilFormat == D3DFMT_D24X4S4); - - DWORD flags = 0; - if (clear_color) flags |= D3DCLEAR_TARGET; - if (clear_z_stencil) flags |= D3DCLEAR_ZBUFFER; - if (clear_z_stencil && has_stencil) flags |= D3DCLEAR_STENCIL; - if (flags) - { - DX8CALL(Clear(0, NULL, flags, Convert_Color(color,dest_alpha), z, stencil)); - } -} - -void DX8Wrapper::Set_Viewport(CONST D3DVIEWPORT8* pViewport) -{ - DX8_THREAD_ASSERT(); - DX8CALL(SetViewport(pViewport)); -} - -// ---------------------------------------------------------------------------- -// -// Set vertex buffer. A reference to previous vertex buffer is released and -// this one is assigned the current vertex buffer. The DX8 vertex buffer will -// actually be set in Apply() which is called by Draw_Indexed_Triangles(). -// -// ---------------------------------------------------------------------------- - -void DX8Wrapper::Set_Vertex_Buffer(const VertexBufferClass* vb) -{ - render_state.vba_offset=0; - render_state.vba_count=0; - if (render_state.vertex_buffer) { - render_state.vertex_buffer->Release_Engine_Ref(); - } - REF_PTR_SET(render_state.vertex_buffer,const_cast(vb)); - if (vb) { - vb->Add_Engine_Ref(); - render_state.vertex_buffer_type=vb->Type(); - } - else { - render_state.index_buffer_type=BUFFER_TYPE_INVALID; - } - render_state_changed|=VERTEX_BUFFER_CHANGED; -} - -// ---------------------------------------------------------------------------- -// -// Set index buffer. A reference to previous index buffer is released and -// this one is assigned the current index buffer. The DX8 index buffer will -// actually be set in Apply() which is called by Draw_Indexed_Triangles(). -// -// ---------------------------------------------------------------------------- - -void DX8Wrapper::Set_Index_Buffer(const IndexBufferClass* ib,unsigned short index_base_offset) -{ - render_state.iba_offset=0; - if (render_state.index_buffer) { - render_state.index_buffer->Release_Engine_Ref(); - } - REF_PTR_SET(render_state.index_buffer,const_cast(ib)); - render_state.index_base_offset=index_base_offset; - if (ib) { - ib->Add_Engine_Ref(); - render_state.index_buffer_type=ib->Type(); - } - else { - render_state.index_buffer_type=BUFFER_TYPE_INVALID; - } - render_state_changed|=INDEX_BUFFER_CHANGED; -} - -// ---------------------------------------------------------------------------- -// -// Set vertex buffer using dynamic access object. -// -// ---------------------------------------------------------------------------- - -void DX8Wrapper::Set_Vertex_Buffer(const DynamicVBAccessClass& vba_) -{ - if (render_state.vertex_buffer) render_state.vertex_buffer->Release_Engine_Ref(); - - DynamicVBAccessClass& vba=const_cast(vba_); - render_state.vertex_buffer_type=vba.Get_Type(); - render_state.vba_offset=vba.VertexBufferOffset; - render_state.vba_count=vba.Get_Vertex_Count(); - REF_PTR_SET(render_state.vertex_buffer,vba.VertexBuffer); - render_state.vertex_buffer->Add_Engine_Ref(); - render_state_changed|=VERTEX_BUFFER_CHANGED; - render_state_changed|=INDEX_BUFFER_CHANGED; // vba_offset changes so index buffer needs to be reset as well. -} - -// ---------------------------------------------------------------------------- -// -// Set index buffer using dynamic access object. -// -// ---------------------------------------------------------------------------- - -void DX8Wrapper::Set_Index_Buffer(const DynamicIBAccessClass& iba_,unsigned short index_base_offset) -{ - if (render_state.index_buffer) render_state.index_buffer->Release_Engine_Ref(); - - DynamicIBAccessClass& iba=const_cast(iba_); - render_state.index_base_offset=index_base_offset; - render_state.index_buffer_type=iba.Get_Type(); - render_state.iba_offset=iba.IndexBufferOffset; - REF_PTR_SET(render_state.index_buffer,iba.IndexBuffer); - render_state.index_buffer->Add_Engine_Ref(); - render_state_changed|=INDEX_BUFFER_CHANGED; -} - -// ---------------------------------------------------------------------------- -// -// Private function for the special case of rendering polygons from sorting -// index and vertex buffers. -// -// ---------------------------------------------------------------------------- - -void DX8Wrapper::Draw_Sorting_IB_VB( - unsigned primitive_type, - unsigned short start_index, - unsigned short polygon_count, - unsigned short min_vertex_index, - unsigned short vertex_count) -{ - WWASSERT(render_state.vertex_buffer_type==BUFFER_TYPE_SORTING || render_state.vertex_buffer_type==BUFFER_TYPE_DYNAMIC_SORTING); - WWASSERT(render_state.index_buffer_type==BUFFER_TYPE_SORTING || render_state.index_buffer_type==BUFFER_TYPE_DYNAMIC_SORTING); - - // Fill dynamic vertex buffer with sorting vertex buffer vertices - DynamicVBAccessClass dyn_vb_access(BUFFER_TYPE_DYNAMIC_DX8,dynamic_fvf_type,vertex_count); - { - DynamicVBAccessClass::WriteLockClass lock(&dyn_vb_access); - VertexFormatXYZNDUV2* src = static_cast(render_state.vertex_buffer)->VertexBuffer; - VertexFormatXYZNDUV2* dest= lock.Get_Formatted_Vertex_Array(); - src += render_state.vba_offset + render_state.index_base_offset + min_vertex_index; - unsigned size = dyn_vb_access.FVF_Info().Get_FVF_Size()*vertex_count/sizeof(unsigned); - unsigned *dest_u =(unsigned*) dest; - unsigned *src_u = (unsigned*) src; - - for (unsigned i=0;i(dyn_vb_access.VertexBuffer)->Get_DX8_Vertex_Buffer(), - dyn_vb_access.FVF_Info().Get_FVF_Size())); - DX8CALL(SetVertexShader(dyn_vb_access.FVF_Info().Get_FVF())); - DX8_RECORD_VERTEX_BUFFER_CHANGE(); - - unsigned index_count=0; - switch (primitive_type) { - case D3DPT_TRIANGLELIST: index_count=polygon_count*3; break; - case D3DPT_TRIANGLESTRIP: index_count=polygon_count+2; break; - case D3DPT_TRIANGLEFAN: index_count=polygon_count+2; break; - default: WWASSERT(0); break; // Unsupported primitive type - } - - // Fill dynamic index buffer with sorting index buffer vertices - DynamicIBAccessClass dyn_ib_access(BUFFER_TYPE_DYNAMIC_DX8,index_count); - { - DynamicIBAccessClass::WriteLockClass lock(&dyn_ib_access); - unsigned short* dest=lock.Get_Index_Array(); - unsigned short* src=NULL; - src=static_cast(render_state.index_buffer)->index_buffer; - src+=render_state.iba_offset+start_index; - - for (unsigned short i=0;i(dyn_ib_access.IndexBuffer)->Get_DX8_Index_Buffer(), - dyn_vb_access.VertexBufferOffset)); - DX8_RECORD_INDEX_BUFFER_CHANGE(); - - DX8_RECORD_DRAW_CALLS(); - DX8CALL(DrawIndexedPrimitive( - D3DPT_TRIANGLELIST, - 0, // start vertex - vertex_count, - dyn_ib_access.IndexBufferOffset, - polygon_count)); - - DX8_RECORD_RENDER(polygon_count,vertex_count,render_state.shader); -} - -// ---------------------------------------------------------------------------- -// -// -// -// ---------------------------------------------------------------------------- - -void DX8Wrapper::Draw( - unsigned primitive_type, - unsigned short start_index, - unsigned short polygon_count, - unsigned short min_vertex_index, - unsigned short vertex_count) -{ - if (DrawPolygonLowBoundLimit && DrawPolygonLowBoundLimit>=polygon_count) return; - - DX8_THREAD_ASSERT(); - SNAPSHOT_SAY(("DX8 - draw")); - - Apply_Render_State_Changes(); - - // Debug feature to disable triangle drawing... - if (!_Is_Triangle_Draw_Enabled()) return; - -#ifdef MESH_RENDER_SNAPSHOT_ENABLED - if (WW3D::Is_Snapshot_Activated()) { - unsigned long passes=0; - SNAPSHOT_SAY(("ValidateDevice:")); - HRESULT res=D3DDevice->ValidateDevice(&passes); - switch (res) { - case D3D_OK: - SNAPSHOT_SAY(("OK")); - break; - - case D3DERR_CONFLICTINGTEXTUREFILTER: - SNAPSHOT_SAY(("D3DERR_CONFLICTINGTEXTUREFILTER")); - break; - case D3DERR_CONFLICTINGTEXTUREPALETTE: - SNAPSHOT_SAY(("D3DERR_CONFLICTINGTEXTUREPALETTE")); - break; - case D3DERR_DEVICELOST: - SNAPSHOT_SAY(("D3DERR_DEVICELOST")); - break; - case D3DERR_TOOMANYOPERATIONS: - SNAPSHOT_SAY(("D3DERR_TOOMANYOPERATIONS")); - break; - case D3DERR_UNSUPPORTEDALPHAARG: - SNAPSHOT_SAY(("D3DERR_UNSUPPORTEDALPHAARG")); - break; - case D3DERR_UNSUPPORTEDALPHAOPERATION: - SNAPSHOT_SAY(("D3DERR_UNSUPPORTEDALPHAOPERATION")); - break; - case D3DERR_UNSUPPORTEDCOLORARG: - SNAPSHOT_SAY(("D3DERR_UNSUPPORTEDCOLORARG")); - break; - case D3DERR_UNSUPPORTEDCOLOROPERATION: - SNAPSHOT_SAY(("D3DERR_UNSUPPORTEDCOLOROPERATION")); - break; - case D3DERR_UNSUPPORTEDFACTORVALUE: - SNAPSHOT_SAY(("D3DERR_UNSUPPORTEDFACTORVALUE")); - break; - case D3DERR_UNSUPPORTEDTEXTUREFILTER: - SNAPSHOT_SAY(("D3DERR_UNSUPPORTEDTEXTUREFILTER")); - break; - case D3DERR_WRONGTEXTUREFORMAT: - SNAPSHOT_SAY(("D3DERR_WRONGTEXTUREFORMAT")); - break; - default: - SNAPSHOT_SAY(("UNKNOWN Error")); - break; - } - } -#endif // MESH_RENDER_SHAPSHOT_ENABLED - - - SNAPSHOT_SAY(("DX8 - draw %d polygons (%d vertices)",polygon_count,vertex_count)); - - if (vertex_count<3) { - min_vertex_index=0; - switch (render_state.vertex_buffer_type) { - case BUFFER_TYPE_DX8: - case BUFFER_TYPE_SORTING: - vertex_count=render_state.vertex_buffer->Get_Vertex_Count()-render_state.index_base_offset-render_state.vba_offset-min_vertex_index; - break; - case BUFFER_TYPE_DYNAMIC_DX8: - case BUFFER_TYPE_DYNAMIC_SORTING: - vertex_count=render_state.vba_count; - break; - } - } - - switch (render_state.vertex_buffer_type) { - case BUFFER_TYPE_DX8: - case BUFFER_TYPE_DYNAMIC_DX8: - switch (render_state.index_buffer_type) { - case BUFFER_TYPE_DX8: - case BUFFER_TYPE_DYNAMIC_DX8: - { -/* if ((start_index+render_state.iba_offset+polygon_count*3) > render_state.index_buffer->Get_Index_Count()) - { WWASSERT_PRINT(0,"OVERFLOWING INDEX BUFFER"); - ///@todo: MUST FIND OUT WHY THIS HAPPENS WITH LOTS OF PARTICLES ON BIG FIGHT! -MW - break; - }*/ - DX8_RECORD_RENDER(polygon_count,vertex_count,render_state.shader); - DX8_RECORD_DRAW_CALLS(); - DX8CALL(DrawIndexedPrimitive( - (D3DPRIMITIVETYPE)primitive_type, - min_vertex_index, - vertex_count, - start_index+render_state.iba_offset, - polygon_count)); - } - break; - case BUFFER_TYPE_SORTING: - case BUFFER_TYPE_DYNAMIC_SORTING: - WWASSERT_PRINT(0,"VB and IB must of same type (sorting or dx8)"); - break; - case BUFFER_TYPE_INVALID: - WWASSERT(0); - break; - } - break; - case BUFFER_TYPE_SORTING: - case BUFFER_TYPE_DYNAMIC_SORTING: - switch (render_state.index_buffer_type) { - case BUFFER_TYPE_DX8: - case BUFFER_TYPE_DYNAMIC_DX8: - WWASSERT_PRINT(0,"VB and IB must of same type (sorting or dx8)"); - break; - case BUFFER_TYPE_SORTING: - case BUFFER_TYPE_DYNAMIC_SORTING: - Draw_Sorting_IB_VB(primitive_type,start_index,polygon_count,min_vertex_index,vertex_count); - break; - case BUFFER_TYPE_INVALID: - WWASSERT(0); - break; - } - break; - case BUFFER_TYPE_INVALID: - WWASSERT(0); - break; - } -} - -// ---------------------------------------------------------------------------- -// -// -// -// ---------------------------------------------------------------------------- - -void DX8Wrapper::Draw_Triangles( - unsigned buffer_type, - unsigned short start_index, - unsigned short polygon_count, - unsigned short min_vertex_index, - unsigned short vertex_count) -{ - if (buffer_type==BUFFER_TYPE_SORTING || buffer_type==BUFFER_TYPE_DYNAMIC_SORTING) { - SortingRendererClass::Insert_Triangles(start_index,polygon_count,min_vertex_index,vertex_count); - } - else { - Draw(D3DPT_TRIANGLELIST,start_index,polygon_count,min_vertex_index,vertex_count); - } -} - -// ---------------------------------------------------------------------------- -// -// -// -// ---------------------------------------------------------------------------- - -void DX8Wrapper::Draw_Triangles( - unsigned short start_index, - unsigned short polygon_count, - unsigned short min_vertex_index, - unsigned short vertex_count) -{ - Draw(D3DPT_TRIANGLELIST,start_index,polygon_count,min_vertex_index,vertex_count); -} - -// ---------------------------------------------------------------------------- -// -// -// -// ---------------------------------------------------------------------------- - -void DX8Wrapper::Draw_Strip( - unsigned short start_index, - unsigned short polygon_count, - unsigned short min_vertex_index, - unsigned short vertex_count) -{ - Draw(D3DPT_TRIANGLESTRIP,start_index,polygon_count,min_vertex_index,vertex_count); -} - -// ---------------------------------------------------------------------------- -// -// -// -// ---------------------------------------------------------------------------- - -void DX8Wrapper::Apply_Render_State_Changes() -{ - SNAPSHOT_SAY(("DX8Wrapper::Apply_Render_State_Changes()")); - - if (!render_state_changed) return; - if (render_state_changed&SHADER_CHANGED) { - SNAPSHOT_SAY(("DX8 - apply shader")); - render_state.shader.Apply(); - } - - unsigned mask=TEXTURE0_CHANGED; - int i=0; - for (;iGet_Max_Textures_Per_Pass();++i,mask<<=1) - { - if (render_state_changed&mask) - { - SNAPSHOT_SAY(("DX8 - apply texture %d",i)); - - if (render_state.Textures[i]) - { - render_state.Textures[i]->Apply(i); - } - else - { - TextureBaseClass::Apply_Null(i); - } - } - } - - if (render_state_changed&MATERIAL_CHANGED) - { - SNAPSHOT_SAY(("DX8 - apply material")); - VertexMaterialClass* material=const_cast(render_state.material); - if (material) - { - material->Apply(); - } - else VertexMaterialClass::Apply_Null(); - } - - if (render_state_changed&LIGHTS_CHANGED) - { - unsigned mask=LIGHT0_CHANGED; - for (unsigned index=0;index<4;++index,mask<<=1) { - if (render_state_changed&mask) { - SNAPSHOT_SAY(("DX8 - apply light %d",index)); - if (render_state.LightEnable[index]) { -#ifdef MESH_RENDER_SNAPSHOT_ENABLED - if ( WW3D::Is_Snapshot_Activated() ) { - D3DLIGHT8 * light = &(render_state.Lights[index]); - static const char * _light_types[] = { "Unknown", "Point","Spot", "Directional" }; - WWASSERT((light->Type >= 0) && (light->Type <= 3)); - - SNAPSHOT_SAY((" type = %s amb = %4.2f,%4.2f,%4.2f diff = %4.2f,%4.2f,%4.2f spec = %4.2f, %4.2f, %4.2f", - _light_types[light->Type], - light->Ambient.r,light->Ambient.g,light->Ambient.b, - light->Diffuse.r,light->Diffuse.g,light->Diffuse.b, - light->Specular.r,light->Specular.g,light->Specular.b )); - SNAPSHOT_SAY((" pos = %f, %f, %f dir = %f, %f, %f", - light->Position.x, light->Position.y, light->Position.z, - light->Direction.x, light->Direction.y, light->Direction.z )); - } -#endif - - Set_DX8_Light(index,&render_state.Lights[index]); - } - else { - Set_DX8_Light(index,NULL); - SNAPSHOT_SAY((" clearing light to NULL")); - } - } - } - } - - if (render_state_changed&WORLD_CHANGED) { - SNAPSHOT_SAY(("DX8 - apply world matrix")); - _Set_DX8_Transform(D3DTS_WORLD,render_state.world); - } - if (render_state_changed&VIEW_CHANGED) { - SNAPSHOT_SAY(("DX8 - apply view matrix")); - _Set_DX8_Transform(D3DTS_VIEW,render_state.view); - } - if (render_state_changed&VERTEX_BUFFER_CHANGED) { - SNAPSHOT_SAY(("DX8 - apply vb change")); - if (render_state.vertex_buffer) { - switch (render_state.vertex_buffer_type) {//->Type()) { - case BUFFER_TYPE_DX8: - case BUFFER_TYPE_DYNAMIC_DX8: - DX8CALL(SetStreamSource( - 0, - static_cast(render_state.vertex_buffer)->Get_DX8_Vertex_Buffer(), - render_state.vertex_buffer->FVF_Info().Get_FVF_Size())); - DX8_RECORD_VERTEX_BUFFER_CHANGE(); - DX8CALL(SetVertexShader(render_state.vertex_buffer->FVF_Info().Get_FVF())); - break; - case BUFFER_TYPE_SORTING: - case BUFFER_TYPE_DYNAMIC_SORTING: - break; - default: - WWASSERT(0); - } - } else { - DX8CALL(SetStreamSource(0,NULL,0)); - DX8_RECORD_VERTEX_BUFFER_CHANGE(); - } - } - if (render_state_changed&INDEX_BUFFER_CHANGED) { - SNAPSHOT_SAY(("DX8 - apply ib change")); - if (render_state.index_buffer) { - switch (render_state.index_buffer_type) {//->Type()) { - case BUFFER_TYPE_DX8: - case BUFFER_TYPE_DYNAMIC_DX8: - DX8CALL(SetIndices( - static_cast(render_state.index_buffer)->Get_DX8_Index_Buffer(), - render_state.index_base_offset+render_state.vba_offset)); - DX8_RECORD_INDEX_BUFFER_CHANGE(); - break; - case BUFFER_TYPE_SORTING: - case BUFFER_TYPE_DYNAMIC_SORTING: - break; - default: - WWASSERT(0); - } - } - else { - DX8CALL(SetIndices( - NULL, - 0)); - DX8_RECORD_INDEX_BUFFER_CHANGE(); - } - } - - render_state_changed&=((unsigned)WORLD_IDENTITY|(unsigned)VIEW_IDENTITY); - - SNAPSHOT_SAY(("DX8Wrapper::Apply_Render_State_Changes() - finished")); -} - -IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture -( - unsigned int width, - unsigned int height, - WW3DFormat format, - MipCountType mip_level_count, - D3DPOOL pool, - bool rendertarget -) -{ - DX8_THREAD_ASSERT(); - DX8_Assert(); - IDirect3DTexture8 *texture = NULL; - - // Paletted textures not supported! - WWASSERT(format!=D3DFMT_P8); - - // NOTE: If 'format' is not supported as a texture format, this function will find the closest - // format that is supported and use that instead. - - // Render target may return NOTAVAILABLE, in - // which case we return NULL. - if (rendertarget) { - unsigned ret=D3DXCreateTexture( - DX8Wrapper::_Get_D3D_Device8(), - width, - height, - mip_level_count, - D3DUSAGE_RENDERTARGET, - WW3DFormat_To_D3DFormat(format), - pool, - &texture); - - if (ret==D3DERR_NOTAVAILABLE) { - Non_Fatal_Log_DX8_ErrorCode(ret,__FILE__,__LINE__); - return NULL; - } - - if (ret==D3DERR_OUTOFVIDEOMEMORY) { - Non_Fatal_Log_DX8_ErrorCode(ret,__FILE__,__LINE__); - return NULL; - } - - DX8_ErrorCode(ret); - // Just return the texture, no reduction - // allowed for render targets. - return texture; - } - - // Don't allow any errors in non-render target - // texture creation. - DX8_ErrorCode(D3DXCreateTexture( - DX8Wrapper::_Get_D3D_Device8(), - width, - height, - mip_level_count, - 0, - WW3DFormat_To_D3DFormat(format), - pool, - &texture)); - -// unsigned reduction=WW3D::Get_Texture_Reduction(); -// unsigned level_count=texture->GetLevelCount(); -// if (reduction>=level_count) reduction=level_count-1; -// texture->SetLOD(reduction); - - return texture; -} - -IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture -( - const char *filename, - MipCountType mip_level_count -) -{ - DX8_THREAD_ASSERT(); - DX8_Assert(); - IDirect3DTexture8 *texture = NULL; - - // NOTE: If the original image format is not supported as a texture format, it will - // automatically be converted to an appropriate format. - // NOTE: It is possible to get the size and format of the original image file from this - // function as well, so if we later want to second-guess D3DX's format conversion decisions - // we can do so after this function is called.. - unsigned result = D3DXCreateTextureFromFileExA( - _Get_D3D_Device8(), - filename, - D3DX_DEFAULT, - D3DX_DEFAULT, - mip_level_count,//create_mipmaps ? 0 : 1, - 0, - D3DFMT_UNKNOWN, - D3DPOOL_MANAGED, - D3DX_FILTER_BOX, - D3DX_FILTER_BOX, - 0, - NULL, - NULL, - &texture); - - if (result != D3D_OK) { - return MissingTexture::_Get_Missing_Texture(); - } - - // Make sure texture wasn't paletted! - D3DSURFACE_DESC desc; - texture->GetLevelDesc(0,&desc); - if (desc.Format==D3DFMT_P8) { - texture->Release(); - return MissingTexture::_Get_Missing_Texture(); - } - return texture; -} - -IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture -( - IDirect3DSurface8 *surface, - MipCountType mip_level_count -) -{ - DX8_THREAD_ASSERT(); - DX8_Assert(); - IDirect3DTexture8 *texture = NULL; - - D3DSURFACE_DESC surface_desc; - ::ZeroMemory(&surface_desc, sizeof(D3DSURFACE_DESC)); - surface->GetDesc(&surface_desc); - - // This function will create a texture with a different (but similar) format if the surface is - // not in a supported texture format. - WW3DFormat format=D3DFormat_To_WW3DFormat(surface_desc.Format); - texture = _Create_DX8_Texture(surface_desc.Width, surface_desc.Height, format, mip_level_count); - - // Copy the surface to the texture - IDirect3DSurface8 *tex_surface = NULL; - texture->GetSurfaceLevel(0, &tex_surface); - DX8_ErrorCode(D3DXLoadSurfaceFromSurface(tex_surface, NULL, NULL, surface, NULL, NULL, D3DX_FILTER_BOX, 0)); - tex_surface->Release(); - - // Create mipmaps if needed - if (mip_level_count!=MIP_LEVELS_1) - { - DX8_ErrorCode(D3DXFilterTexture(texture, NULL, 0, D3DX_FILTER_BOX)); - } - - return texture; - -} - -IDirect3DSurface8 * DX8Wrapper::_Create_DX8_Surface(unsigned int width, unsigned int height, WW3DFormat format) -{ - DX8_THREAD_ASSERT(); - DX8_Assert(); - - IDirect3DSurface8 *surface = NULL; - - // Paletted surfaces not supported! - WWASSERT(format!=D3DFMT_P8); - - DX8CALL(CreateImageSurface(width, height, WW3DFormat_To_D3DFormat(format), &surface)); - - return surface; -} - -IDirect3DSurface8 * DX8Wrapper::_Create_DX8_Surface(const char *filename_) -{ - DX8_THREAD_ASSERT(); - DX8_Assert(); - - // Note: Since there is no "D3DXCreateSurfaceFromFile" and no "GetSurfaceInfoFromFile" (the - // latter is supposed to be added to D3DX in a future version), we create a texture from the - // file (w/o mipmaps), check that its surface is equal to the original file data (which it - // will not be if the file is not in a texture-supported format or size). If so, copy its - // surface (we might be able to just get its surface and add a ref to it but I'm not sure so - // I'm not going to risk it) and release the texture. If not, create a surface according to - // the file data and use D3DXLoadSurfaceFromFile. This is a horrible hack, but it saves us - // having to write file loaders. Will fix this when D3DX provides us with the right functions. - // Create a surface the size of the file image data - IDirect3DSurface8 *surface = NULL; - - { - - file_auto_ptr myfile(_TheFileFactory,filename_); - // If file not found, create a surface with missing texture in it - - if (!myfile->Is_Available()) { - // If file not found, try the dds format - // else create a surface with missing texture in it - char compressed_name[200]; - strncpy(compressed_name,filename_, ARRAY_SIZE(compressed_name)); - compressed_name[ARRAY_SIZE(compressed_name)-1] = '\0'; - char *ext = strstr(compressed_name, "."); - if ( ext && (strlen(ext)==4) && - ( (ext[1] == 't') || (ext[1] == 'T') ) && - ( (ext[2] == 'g') || (ext[2] == 'G') ) && - ( (ext[3] == 'a') || (ext[3] == 'A') ) ) { - ext[1]='d'; - ext[2]='d'; - ext[3]='s'; - } - file_auto_ptr myfile2(_TheFileFactory,compressed_name); - if (!myfile2->Is_Available()) - return MissingTexture::_Create_Missing_Surface(); - } - } - - StringClass filename_string(filename_,true); - surface=TextureLoader::Load_Surface_Immediate( - filename_string, - WW3D_FORMAT_UNKNOWN, - true); - return surface; -} - - -/*********************************************************************************************** - * DX8Wrapper::_Update_Texture -- Copies a texture from system memory to video memory * - * * - * * - * * - * * - * INPUT: * - * * - * OUTPUT: * - * * - * WARNINGS: * - * * - * HISTORY: * - * 4/26/2001 hy : Created. * - *=============================================================================================*/ -void DX8Wrapper::_Update_Texture(TextureClass *system, TextureClass *video) -{ - WWASSERT(system); - WWASSERT(video); - WWASSERT(system->Get_Pool()==TextureClass::POOL_SYSTEMMEM); - WWASSERT(video->Get_Pool()==TextureClass::POOL_DEFAULT); - DX8CALL(UpdateTexture(system->Peek_D3D_Base_Texture(),video->Peek_D3D_Base_Texture())); -} - -void DX8Wrapper::Compute_Caps(WW3DFormat display_format) -{ - DX8_THREAD_ASSERT(); - DX8_Assert(); - delete CurrentCaps; - CurrentCaps=new DX8Caps(_Get_D3D8(),D3DDevice,display_format,Get_Current_Adapter_Identifier()); -} - - -void DX8Wrapper::Set_Light(unsigned index, const D3DLIGHT8* light) -{ - if (light) { - render_state.Lights[index]=*light; - render_state.LightEnable[index]=true; - } - else { - render_state.LightEnable[index]=false; - } - render_state_changed|=(LIGHT0_CHANGED<Get_Light_Count(); - unsigned int color=Convert_Color(light_env->Get_Equivalent_Ambient(),0.0f); - if (RenderStates[D3DRS_AMBIENT]!=color) - { - Set_DX8_Render_State(D3DRS_AMBIENT,color); -//buggy Radeon 9700 driver doesn't apply new ambient unless the material also changes. -#if 1 - render_state_changed|=MATERIAL_CHANGED; -#endif - } - - D3DLIGHT8 light; - int l=0; - for (;lGet_Light_Diffuse(l); - Vector3 dir=-light_env->Get_Light_Direction(l); - light.Direction=(const D3DVECTOR&)(dir); - if (light_env->isPointLight(l)) { - light.Type = D3DLIGHT_POINT; - (Vector3&)light.Diffuse=light_env->getPointDiffuse(l); - (Vector3&)light.Ambient=light_env->getPointAmbient(l); - light.Position = (const D3DVECTOR&)light_env->getPointCenter(l); - light.Range = light_env->getPointOrad(l); - - // Inverse linear light 1/(1+D) - double a,b; - b = light_env->getPointOrad(l); - a = light_env->getPointIrad(l); - light.Attenuation0=0.01f; - if (fabs(a-b)<1e-5) - // if the attenuation range is too small assume uniform with cutoff - light.Attenuation1=0.0f; - else - // this will cause the light to drop to half intensity at the first far attenuation - light.Attenuation1=(float) 0.1/a; - - light.Attenuation2=8.0f/(b*b); - } - - Set_Light(l,&light); - } - - for (;l<4;++l) { - Set_Light(l,NULL); - } - } -/* else { - for (int l=0;l<4;++l) { - Set_Light(l,NULL); - } - } -*/ -} - -IDirect3DSurface8 * DX8Wrapper::_Get_DX8_Front_Buffer() -{ - DX8_THREAD_ASSERT(); - D3DDISPLAYMODE mode; - - DX8CALL(GetDisplayMode(&mode)); - - IDirect3DSurface8 * fb=NULL; - - DX8CALL(CreateImageSurface(mode.Width,mode.Height,D3DFMT_A8R8G8B8,&fb)); - - DX8CALL(GetFrontBuffer(fb)); - return fb; -} - -SurfaceClass * DX8Wrapper::_Get_DX8_Back_Buffer(unsigned int num) -{ - DX8_THREAD_ASSERT(); - - IDirect3DSurface8 * bb; - SurfaceClass *surf=NULL; - DX8CALL(GetBackBuffer(num,D3DBACKBUFFER_TYPE_MONO,&bb)); - if (bb) - { - surf=NEW_REF(SurfaceClass,(bb)); - bb->Release(); - } - - return surf; -} - - -TextureClass * -DX8Wrapper::Create_Render_Target (int width, int height, bool alpha) -{ - DX8_THREAD_ASSERT(); - DX8_Assert(); - - // - // Note: We're going to force the width and height to be powers of two and equal - // - const D3DCAPS8& dx8caps=Get_Current_Caps()->Get_DX8_Caps(); - float poweroftwosize = width; - if (height > 0 && height < width) { - poweroftwosize = height; - } - poweroftwosize = ::Find_POT (poweroftwosize); - - if (poweroftwosize>dx8caps.MaxTextureWidth) { - poweroftwosize=dx8caps.MaxTextureWidth; - } - if (poweroftwosize>dx8caps.MaxTextureHeight) { - poweroftwosize=dx8caps.MaxTextureHeight; - } - - width = height = poweroftwosize; - - // - // Get the current format of the display - // - D3DDISPLAYMODE mode; - DX8CALL(GetDisplayMode(&mode)); - - // If the user requested a render-target texture and this device does not support that - // feature, return NULL - HRESULT hr; - - if (alpha) - { - //user wants a texture with destination alpha channel - only 1 such format - //ever exists on current hardware - D3DFMT_A8R8G8B8 - hr = D3DInterface->CheckDeviceFormat( D3DADAPTER_DEFAULT, - WW3D_DEVTYPE, - mode.Format, - D3DUSAGE_RENDERTARGET, - D3DRTYPE_TEXTURE, - D3DFMT_A8R8G8B8 ); - mode.Format=D3DFMT_A8R8G8B8; - } - else - { - hr = D3DInterface->CheckDeviceFormat( D3DADAPTER_DEFAULT, - WW3D_DEVTYPE, - mode.Format, - D3DUSAGE_RENDERTARGET, - D3DRTYPE_TEXTURE, - mode.Format ); - } - - number_of_DX8_calls++; - if (hr != D3D_OK) { - WWDEBUG_SAY(("DX8Wrapper - Driver cannot create render target!")); - return NULL; - } - - // - // Attempt to create the render target - // - DX8_Assert(); - WW3DFormat format=D3DFormat_To_WW3DFormat(mode.Format); - TextureClass * tex = NEW_REF(TextureClass,(width,height,format,MIP_LEVELS_1,TextureClass::POOL_DEFAULT,true)); - - // 3dfx drivers are lying in the CheckDeviceFormat call and claiming - // that they support render targets! - if (tex->Peek_D3D_Base_Texture() == NULL) - { - WWDEBUG_SAY(("DX8Wrapper - Render target creation failed!")); - REF_PTR_RELEASE(tex); - } - - return tex; -} - - -void -DX8Wrapper::Set_Render_Target -(TextureClass * texture) -{ - WWASSERT(texture != NULL); - SurfaceClass * surf = texture->Get_Surface_Level(); - WWASSERT(surf != NULL); - Set_Render_Target(surf->Peek_D3D_Surface()); - REF_PTR_RELEASE(surf); -} - -void -DX8Wrapper::Set_Render_Target(IDirect3DSwapChain8 *swap_chain) -{ - DX8_THREAD_ASSERT(); - WWASSERT (swap_chain != NULL); - - // - // Get the back buffer for the swap chain - // - LPDIRECT3DSURFACE8 render_target = NULL; - swap_chain->GetBackBuffer (0, D3DBACKBUFFER_TYPE_MONO, &render_target); - - // - // Set this back buffer as the render targer - // - Set_Render_Target (render_target); - - // - // Release our hold on the back buffer - // - if (render_target != NULL) { - render_target->Release (); - render_target = NULL; - } - - IsRenderToTexture = false; - - return ; -} - -void -DX8Wrapper::Set_Render_Target(IDirect3DSurface8 *render_target) -{ - DX8_THREAD_ASSERT(); - DX8_Assert(); - - // - // We'll need the depth buffer later... - // - IDirect3DSurface8 *depth_buffer = NULL; - DX8CALL(GetDepthStencilSurface (&depth_buffer)); - - // - // Should we restore the default render target set a new one? - // - if (render_target == NULL || render_target == DefaultRenderTarget) - { - - // - // Restore the default render target - // - if (DefaultRenderTarget != NULL) - { - DX8CALL(SetRenderTarget (DefaultRenderTarget, depth_buffer)); - DefaultRenderTarget->Release (); - DefaultRenderTarget = NULL; - } - - // - // Release our hold on the "current" render target - // - if (CurrentRenderTarget != NULL) - { - CurrentRenderTarget->Release (); - CurrentRenderTarget = NULL; - } - - } - else if (render_target != CurrentRenderTarget) - { - - // - // Get a pointer to the default render target (if necessary) - // - if (DefaultRenderTarget == NULL) - { - DX8CALL(GetRenderTarget (&DefaultRenderTarget)); - } - - // - // Release our hold on the old "current" render target - // - if (CurrentRenderTarget != NULL) - { - CurrentRenderTarget->Release (); - CurrentRenderTarget = NULL; - } - - // - // Keep a copy of the current render target (for housekeeping) - // - CurrentRenderTarget = render_target; - WWASSERT (CurrentRenderTarget != NULL); - if (CurrentRenderTarget != NULL) - { - CurrentRenderTarget->AddRef (); - - // - // Switch render targets - // - DX8CALL(SetRenderTarget (CurrentRenderTarget, depth_buffer)); - } - } - - // - // Free our hold on the depth buffer - // - if (depth_buffer != NULL) { - depth_buffer->Release (); - depth_buffer = NULL; - } - - IsRenderToTexture = false; - return ; -} - - -IDirect3DSwapChain8 * -DX8Wrapper::Create_Additional_Swap_Chain (HWND render_window) -{ - DX8_Assert(); - - // - // Configure the presentation parameters for a windowed render target - // - D3DPRESENT_PARAMETERS params = { 0 }; - params.BackBufferFormat = _PresentParameters.BackBufferFormat; - params.BackBufferCount = 1; - params.MultiSampleType = D3DMULTISAMPLE_NONE; - params.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC; - params.hDeviceWindow = render_window; - params.Windowed = TRUE; - params.EnableAutoDepthStencil = TRUE; - params.AutoDepthStencilFormat = _PresentParameters.AutoDepthStencilFormat; - params.Flags = 0; - params.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; - params.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; - - // - // Create the swap chain - // - IDirect3DSwapChain8 *swap_chain = NULL; - DX8CALL(CreateAdditionalSwapChain(¶ms, &swap_chain)); - return swap_chain; -} - -void DX8Wrapper::Flush_DX8_Resource_Manager(unsigned int bytes) -{ - DX8_Assert(); - DX8CALL(ResourceManagerDiscardBytes(bytes)); -} - -unsigned int DX8Wrapper::Get_Free_Texture_RAM() -{ - DX8_Assert(); - number_of_DX8_calls++; - return DX8Wrapper::_Get_D3D_Device8()->GetAvailableTextureMem(); -} - -// Converts a linear gamma ramp to one that is controlled by: -// Gamma - controls the curvature of the middle of the curve -// Bright - controls the minimum value of the curve -// Contrast - controls the difference between the maximum and the minimum of the curve -void DX8Wrapper::Set_Gamma(float gamma,float bright,float contrast,bool calibrate,bool uselimit) -{ - gamma=Bound(gamma,0.6f,6.0f); - bright=Bound(bright,-0.5f,0.5f); - contrast=Bound(contrast,0.5f,2.0f); - float oo_gamma=1.0f/gamma; - - DX8_Assert(); - number_of_DX8_calls++; - - DWORD flag=(calibrate?D3DSGR_CALIBRATE:D3DSGR_NO_CALIBRATION); - - D3DGAMMARAMP ramp; - float limit; - - // IML: I'm not really sure what the intent of the 'limit' variable is. It does not produce useful results for my purposes. - if (uselimit) { - limit=(contrast-1)/2*contrast; - } else { - limit = 0.0f; - } - - // HY - arrived at this equation after much trial and error. - for (int i=0; i<256; i++) { - float in,out; - in=i/256.0f; - float x=in-limit; - x=Bound(x,0.0f,1.0f); - x=powf(x,oo_gamma); - out=contrast*x+bright; - out=Bound(out,0.0f,1.0f); - ramp.red[i]=(WORD) (out*65535); - ramp.green[i]=(WORD) (out*65535); - ramp.blue[i]=(WORD) (out*65535); - } - - if (Get_Current_Caps()->Support_Gamma()) { - DX8Wrapper::_Get_D3D_Device8()->SetGammaRamp(flag,&ramp); - } else { - HWND hwnd = GetDesktopWindow(); - HDC hdc = GetDC(hwnd); - if (hdc) - { - SetDeviceGammaRamp (hdc, &ramp); - ReleaseDC (hwnd, hdc); - } - } -} - -//********************************************************************************************** -//! Resets render device to default state -/*! -*/ -void DX8Wrapper::Apply_Default_State() -{ - SNAPSHOT_SAY(("DX8Wrapper::Apply_Default_State()")); - - // only set states used in game - Set_DX8_Render_State(D3DRS_ZENABLE, TRUE); -// Set_DX8_Render_State(D3DRS_FILLMODE, D3DFILL_SOLID); - Set_DX8_Render_State(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); - //Set_DX8_Render_State(D3DRS_LINEPATTERN, 0); - Set_DX8_Render_State(D3DRS_ZWRITEENABLE, TRUE); - Set_DX8_Render_State(D3DRS_ALPHATESTENABLE, FALSE); - //Set_DX8_Render_State(D3DRS_LASTPIXEL, FALSE); - Set_DX8_Render_State(D3DRS_SRCBLEND, D3DBLEND_ONE); - Set_DX8_Render_State(D3DRS_DESTBLEND, D3DBLEND_ZERO); - Set_DX8_Render_State(D3DRS_CULLMODE, D3DCULL_CW); - Set_DX8_Render_State(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); - Set_DX8_Render_State(D3DRS_ALPHAREF, 0); - Set_DX8_Render_State(D3DRS_ALPHAFUNC, D3DCMP_LESSEQUAL); - Set_DX8_Render_State(D3DRS_DITHERENABLE, FALSE); - Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE, FALSE); - Set_DX8_Render_State(D3DRS_FOGENABLE, FALSE); - Set_DX8_Render_State(D3DRS_SPECULARENABLE, FALSE); -// Set_DX8_Render_State(D3DRS_ZVISIBLE, FALSE); -// Set_DX8_Render_State(D3DRS_FOGCOLOR, 0); -// Set_DX8_Render_State(D3DRS_FOGTABLEMODE, D3DFOG_NONE); -// Set_DX8_Render_State(D3DRS_FOGSTART, 0); - -// Set_DX8_Render_State(D3DRS_FOGEND, WWMath::Float_As_Int(1.0f)); -// Set_DX8_Render_State(D3DRS_FOGDENSITY, WWMath::Float_As_Int(1.0f)); - - //Set_DX8_Render_State(D3DRS_EDGEANTIALIAS, FALSE); - Set_DX8_Render_State(D3DRS_ZBIAS, 0); -// Set_DX8_Render_State(D3DRS_RANGEFOGENABLE, FALSE); - Set_DX8_Render_State(D3DRS_STENCILENABLE, FALSE); - Set_DX8_Render_State(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); - Set_DX8_Render_State(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); - Set_DX8_Render_State(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); - Set_DX8_Render_State(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); - Set_DX8_Render_State(D3DRS_STENCILREF, 0); - Set_DX8_Render_State(D3DRS_STENCILMASK, 0xffffffff); - Set_DX8_Render_State(D3DRS_STENCILWRITEMASK, 0xffffffff); - Set_DX8_Render_State(D3DRS_TEXTUREFACTOR, 0); -/* Set_DX8_Render_State(D3DRS_WRAP0, D3DWRAP_U| D3DWRAP_V); - Set_DX8_Render_State(D3DRS_WRAP1, D3DWRAP_U| D3DWRAP_V); - Set_DX8_Render_State(D3DRS_WRAP2, D3DWRAP_U| D3DWRAP_V); - Set_DX8_Render_State(D3DRS_WRAP3, D3DWRAP_U| D3DWRAP_V); - Set_DX8_Render_State(D3DRS_WRAP4, D3DWRAP_U| D3DWRAP_V); - Set_DX8_Render_State(D3DRS_WRAP5, D3DWRAP_U| D3DWRAP_V); - Set_DX8_Render_State(D3DRS_WRAP6, D3DWRAP_U| D3DWRAP_V); - Set_DX8_Render_State(D3DRS_WRAP7, D3DWRAP_U| D3DWRAP_V);*/ - Set_DX8_Render_State(D3DRS_CLIPPING, TRUE); - Set_DX8_Render_State(D3DRS_LIGHTING, FALSE); - //Set_DX8_Render_State(D3DRS_AMBIENT, 0); -// Set_DX8_Render_State(D3DRS_FOGVERTEXMODE, D3DFOG_NONE); - Set_DX8_Render_State(D3DRS_COLORVERTEX, TRUE); -/* Set_DX8_Render_State(D3DRS_LOCALVIEWER, TRUE); - Set_DX8_Render_State(D3DRS_NORMALIZENORMALS, FALSE); - Set_DX8_Render_State(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1); - Set_DX8_Render_State(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2); - Set_DX8_Render_State(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL); - Set_DX8_Render_State(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL); - Set_DX8_Render_State(D3DRS_VERTEXBLEND, D3DVBF_DISABLE);*/ - //Set_DX8_Render_State(D3DRS_CLIPPLANEENABLE, 0); - Set_DX8_Render_State(D3DRS_SOFTWAREVERTEXPROCESSING, FALSE); - //Set_DX8_Render_State(D3DRS_POINTSIZE, 0x3f800000); - //Set_DX8_Render_State(D3DRS_POINTSIZE_MIN, 0); - //Set_DX8_Render_State(D3DRS_POINTSPRITEENABLE, FALSE); - //Set_DX8_Render_State(D3DRS_POINTSCALEENABLE, FALSE); - //Set_DX8_Render_State(D3DRS_POINTSCALE_A, 0); - //Set_DX8_Render_State(D3DRS_POINTSCALE_B, 0); - //Set_DX8_Render_State(D3DRS_POINTSCALE_C, 0); - //Set_DX8_Render_State(D3DRS_MULTISAMPLEANTIALIAS, TRUE); - //Set_DX8_Render_State(D3DRS_MULTISAMPLEMASK, 0xffffffff); - //Set_DX8_Render_State(D3DRS_PATCHEDGESTYLE, D3DPATCHEDGE_DISCRETE); - //Set_DX8_Render_State(D3DRS_PATCHSEGMENTS, 0x3f800000); - //Set_DX8_Render_State(D3DRS_DEBUGMONITORTOKEN, D3DDMT_ENABLE); - //Set_DX8_Render_State(D3DRS_POINTSIZE_MAX, Float_At_Int(64.0f)); - //Set_DX8_Render_State(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE); - Set_DX8_Render_State(D3DRS_COLORWRITEENABLE, 0x0000000f); - //Set_DX8_Render_State(D3DRS_TWEENFACTOR, 0); - Set_DX8_Render_State(D3DRS_BLENDOP, D3DBLENDOP_ADD); - //Set_DX8_Render_State(D3DRS_POSITIONORDER, D3DORDER_CUBIC); - //Set_DX8_Render_State(D3DRS_NORMALORDER, D3DORDER_LINEAR); - - // disable TSS stages - int i; - for (i=0; iGet_Max_Textures_Per_Pass(); i++) - { - Set_DX8_Texture_Stage_State(i, D3DTSS_COLOROP, D3DTOP_DISABLE); - Set_DX8_Texture_Stage_State(i, D3DTSS_COLORARG1, D3DTA_TEXTURE); - Set_DX8_Texture_Stage_State(i, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - - Set_DX8_Texture_Stage_State(i, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - Set_DX8_Texture_Stage_State(i, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - Set_DX8_Texture_Stage_State(i, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - - /*Set_DX8_Texture_Stage_State(i, D3DTSS_BUMPENVMAT00, 0); - Set_DX8_Texture_Stage_State(i, D3DTSS_BUMPENVMAT01, 0); - Set_DX8_Texture_Stage_State(i, D3DTSS_BUMPENVMAT10, 0); - Set_DX8_Texture_Stage_State(i, D3DTSS_BUMPENVMAT11, 0); - Set_DX8_Texture_Stage_State(i, D3DTSS_BUMPENVLSCALE, 0); - Set_DX8_Texture_Stage_State(i, D3DTSS_BUMPENVLOFFSET, 0);*/ - - Set_DX8_Texture_Stage_State(i, D3DTSS_TEXCOORDINDEX, i); - - - Set_DX8_Texture_Stage_State(i, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); - Set_DX8_Texture_Stage_State(i, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); - Set_DX8_Texture_Stage_State(i, D3DTSS_BORDERCOLOR, 0); -// Set_DX8_Texture_Stage_State(i, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); -// Set_DX8_Texture_Stage_State(i, D3DTSS_MINFILTER, D3DTEXF_LINEAR); -// Set_DX8_Texture_Stage_State(i, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); -// Set_DX8_Texture_Stage_State(i, D3DTSS_MIPMAPLODBIAS, 0); -// Set_DX8_Texture_Stage_State(i, D3DTSS_MAXMIPLEVEL, 0); -// Set_DX8_Texture_Stage_State(i, D3DTSS_MAXANISOTROPY, 1); - //Set_DX8_Texture_Stage_State(i, D3DTSS_ADDRESSW, D3DTADDRESS_WRAP); - //Set_DX8_Texture_Stage_State(i, D3DTSS_COLORARG0, D3DTA_CURRENT); - //Set_DX8_Texture_Stage_State(i, D3DTSS_ALPHAARG0, D3DTA_CURRENT); - //Set_DX8_Texture_Stage_State(i, D3DTSS_RESULTARG, D3DTA_CURRENT); - - Set_DX8_Texture_Stage_State(i, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - Set_Texture(i,NULL); - } - -// DX8Wrapper::Set_Material(NULL); - VertexMaterialClass::Apply_Null(); - - for (unsigned index=0;index<4;++index) { - SNAPSHOT_SAY(("Clearing light %d to NULL",index)); - Set_DX8_Light(index,NULL); - } - - // set up simple default TSS - Vector4 vconst[MAX_VERTEX_SHADER_CONSTANTS]; - memset(vconst,0,sizeof(Vector4)*MAX_VERTEX_SHADER_CONSTANTS); - Set_Vertex_Shader_Constant(0, vconst, MAX_VERTEX_SHADER_CONSTANTS); - - Vector4 pconst[MAX_PIXEL_SHADER_CONSTANTS]; - memset(pconst,0,sizeof(Vector4)*MAX_PIXEL_SHADER_CONSTANTS); - Set_Pixel_Shader_Constant(0, pconst, MAX_PIXEL_SHADER_CONSTANTS); - - Set_Vertex_Shader(DX8_FVF_XYZNDUV2); - Set_Pixel_Shader(0); - - ShaderClass::Invalidate(); -} - -const char* DX8Wrapper::Get_DX8_Render_State_Name(D3DRENDERSTATETYPE state) -{ - switch (state) { - case D3DRS_ZENABLE : return "D3DRS_ZENABLE"; - case D3DRS_FILLMODE : return "D3DRS_FILLMODE"; - case D3DRS_SHADEMODE : return "D3DRS_SHADEMODE"; - case D3DRS_LINEPATTERN : return "D3DRS_LINEPATTERN"; - case D3DRS_ZWRITEENABLE : return "D3DRS_ZWRITEENABLE"; - case D3DRS_ALPHATESTENABLE : return "D3DRS_ALPHATESTENABLE"; - case D3DRS_LASTPIXEL : return "D3DRS_LASTPIXEL"; - case D3DRS_SRCBLEND : return "D3DRS_SRCBLEND"; - case D3DRS_DESTBLEND : return "D3DRS_DESTBLEND"; - case D3DRS_CULLMODE : return "D3DRS_CULLMODE"; - case D3DRS_ZFUNC : return "D3DRS_ZFUNC"; - case D3DRS_ALPHAREF : return "D3DRS_ALPHAREF"; - case D3DRS_ALPHAFUNC : return "D3DRS_ALPHAFUNC"; - case D3DRS_DITHERENABLE : return "D3DRS_DITHERENABLE"; - case D3DRS_ALPHABLENDENABLE : return "D3DRS_ALPHABLENDENABLE"; - case D3DRS_FOGENABLE : return "D3DRS_FOGENABLE"; - case D3DRS_SPECULARENABLE : return "D3DRS_SPECULARENABLE"; - case D3DRS_ZVISIBLE : return "D3DRS_ZVISIBLE"; - case D3DRS_FOGCOLOR : return "D3DRS_FOGCOLOR"; - case D3DRS_FOGTABLEMODE : return "D3DRS_FOGTABLEMODE"; - case D3DRS_FOGSTART : return "D3DRS_FOGSTART"; - case D3DRS_FOGEND : return "D3DRS_FOGEND"; - case D3DRS_FOGDENSITY : return "D3DRS_FOGDENSITY"; - case D3DRS_EDGEANTIALIAS : return "D3DRS_EDGEANTIALIAS"; - case D3DRS_ZBIAS : return "D3DRS_ZBIAS"; - case D3DRS_RANGEFOGENABLE : return "D3DRS_RANGEFOGENABLE"; - case D3DRS_STENCILENABLE : return "D3DRS_STENCILENABLE"; - case D3DRS_STENCILFAIL : return "D3DRS_STENCILFAIL"; - case D3DRS_STENCILZFAIL : return "D3DRS_STENCILZFAIL"; - case D3DRS_STENCILPASS : return "D3DRS_STENCILPASS"; - case D3DRS_STENCILFUNC : return "D3DRS_STENCILFUNC"; - case D3DRS_STENCILREF : return "D3DRS_STENCILREF"; - case D3DRS_STENCILMASK : return "D3DRS_STENCILMASK"; - case D3DRS_STENCILWRITEMASK : return "D3DRS_STENCILWRITEMASK"; - case D3DRS_TEXTUREFACTOR : return "D3DRS_TEXTUREFACTOR"; - case D3DRS_WRAP0 : return "D3DRS_WRAP0"; - case D3DRS_WRAP1 : return "D3DRS_WRAP1"; - case D3DRS_WRAP2 : return "D3DRS_WRAP2"; - case D3DRS_WRAP3 : return "D3DRS_WRAP3"; - case D3DRS_WRAP4 : return "D3DRS_WRAP4"; - case D3DRS_WRAP5 : return "D3DRS_WRAP5"; - case D3DRS_WRAP6 : return "D3DRS_WRAP6"; - case D3DRS_WRAP7 : return "D3DRS_WRAP7"; - case D3DRS_CLIPPING : return "D3DRS_CLIPPING"; - case D3DRS_LIGHTING : return "D3DRS_LIGHTING"; - case D3DRS_AMBIENT : return "D3DRS_AMBIENT"; - case D3DRS_FOGVERTEXMODE : return "D3DRS_FOGVERTEXMODE"; - case D3DRS_COLORVERTEX : return "D3DRS_COLORVERTEX"; - case D3DRS_LOCALVIEWER : return "D3DRS_LOCALVIEWER"; - case D3DRS_NORMALIZENORMALS : return "D3DRS_NORMALIZENORMALS"; - case D3DRS_DIFFUSEMATERIALSOURCE : return "D3DRS_DIFFUSEMATERIALSOURCE"; - case D3DRS_SPECULARMATERIALSOURCE : return "D3DRS_SPECULARMATERIALSOURCE"; - case D3DRS_AMBIENTMATERIALSOURCE : return "D3DRS_AMBIENTMATERIALSOURCE"; - case D3DRS_EMISSIVEMATERIALSOURCE : return "D3DRS_EMISSIVEMATERIALSOURCE"; - case D3DRS_VERTEXBLEND : return "D3DRS_VERTEXBLEND"; - case D3DRS_CLIPPLANEENABLE : return "D3DRS_CLIPPLANEENABLE"; - case D3DRS_SOFTWAREVERTEXPROCESSING : return "D3DRS_SOFTWAREVERTEXPROCESSING"; - case D3DRS_POINTSIZE : return "D3DRS_POINTSIZE"; - case D3DRS_POINTSIZE_MIN : return "D3DRS_POINTSIZE_MIN"; - case D3DRS_POINTSPRITEENABLE : return "D3DRS_POINTSPRITEENABLE"; - case D3DRS_POINTSCALEENABLE : return "D3DRS_POINTSCALEENABLE"; - case D3DRS_POINTSCALE_A : return "D3DRS_POINTSCALE_A"; - case D3DRS_POINTSCALE_B : return "D3DRS_POINTSCALE_B"; - case D3DRS_POINTSCALE_C : return "D3DRS_POINTSCALE_C"; - case D3DRS_MULTISAMPLEANTIALIAS : return "D3DRS_MULTISAMPLEANTIALIAS"; - case D3DRS_MULTISAMPLEMASK : return "D3DRS_MULTISAMPLEMASK"; - case D3DRS_PATCHEDGESTYLE : return "D3DRS_PATCHEDGESTYLE"; - case D3DRS_PATCHSEGMENTS : return "D3DRS_PATCHSEGMENTS"; - case D3DRS_DEBUGMONITORTOKEN : return "D3DRS_DEBUGMONITORTOKEN"; - case D3DRS_POINTSIZE_MAX : return "D3DRS_POINTSIZE_MAX"; - case D3DRS_INDEXEDVERTEXBLENDENABLE : return "D3DRS_INDEXEDVERTEXBLENDENABLE"; - case D3DRS_COLORWRITEENABLE : return "D3DRS_COLORWRITEENABLE"; - case D3DRS_TWEENFACTOR : return "D3DRS_TWEENFACTOR"; - case D3DRS_BLENDOP : return "D3DRS_BLENDOP"; -// case D3DRS_POSITIONORDER : return "D3DRS_POSITIONORDER"; -// case D3DRS_NORMALORDER : return "D3DRS_NORMALORDER"; - default : return "UNKNOWN"; - } -} - -const char* DX8Wrapper::Get_DX8_Texture_Stage_State_Name(D3DTEXTURESTAGESTATETYPE state) -{ - switch (state) { - case D3DTSS_COLOROP : return "D3DTSS_COLOROP"; - case D3DTSS_COLORARG1 : return "D3DTSS_COLORARG1"; - case D3DTSS_COLORARG2 : return "D3DTSS_COLORARG2"; - case D3DTSS_ALPHAOP : return "D3DTSS_ALPHAOP"; - case D3DTSS_ALPHAARG1 : return "D3DTSS_ALPHAARG1"; - case D3DTSS_ALPHAARG2 : return "D3DTSS_ALPHAARG2"; - case D3DTSS_BUMPENVMAT00 : return "D3DTSS_BUMPENVMAT00"; - case D3DTSS_BUMPENVMAT01 : return "D3DTSS_BUMPENVMAT01"; - case D3DTSS_BUMPENVMAT10 : return "D3DTSS_BUMPENVMAT10"; - case D3DTSS_BUMPENVMAT11 : return "D3DTSS_BUMPENVMAT11"; - case D3DTSS_TEXCOORDINDEX : return "D3DTSS_TEXCOORDINDEX"; - case D3DTSS_ADDRESSU : return "D3DTSS_ADDRESSU"; - case D3DTSS_ADDRESSV : return "D3DTSS_ADDRESSV"; - case D3DTSS_BORDERCOLOR : return "D3DTSS_BORDERCOLOR"; - case D3DTSS_MAGFILTER : return "D3DTSS_MAGFILTER"; - case D3DTSS_MINFILTER : return "D3DTSS_MINFILTER"; - case D3DTSS_MIPFILTER : return "D3DTSS_MIPFILTER"; - case D3DTSS_MIPMAPLODBIAS : return "D3DTSS_MIPMAPLODBIAS"; - case D3DTSS_MAXMIPLEVEL : return "D3DTSS_MAXMIPLEVEL"; - case D3DTSS_MAXANISOTROPY : return "D3DTSS_MAXANISOTROPY"; - case D3DTSS_BUMPENVLSCALE : return "D3DTSS_BUMPENVLSCALE"; - case D3DTSS_BUMPENVLOFFSET : return "D3DTSS_BUMPENVLOFFSET"; - case D3DTSS_TEXTURETRANSFORMFLAGS : return "D3DTSS_TEXTURETRANSFORMFLAGS"; - case D3DTSS_ADDRESSW : return "D3DTSS_ADDRESSW"; - case D3DTSS_COLORARG0 : return "D3DTSS_COLORARG0"; - case D3DTSS_ALPHAARG0 : return "D3DTSS_ALPHAARG0"; - case D3DTSS_RESULTARG : return "D3DTSS_RESULTARG"; - default : return "UNKNOWN"; - } -} - -void DX8Wrapper::Get_DX8_Render_State_Value_Name(StringClass& name, D3DRENDERSTATETYPE state, unsigned value) -{ - switch (state) { - case D3DRS_ZENABLE: - name=Get_DX8_ZBuffer_Type_Name(value); - break; - - case D3DRS_FILLMODE: - name=Get_DX8_Fill_Mode_Name(value); - break; - - case D3DRS_SHADEMODE: - name=Get_DX8_Shade_Mode_Name(value); - break; - - case D3DRS_LINEPATTERN: - case D3DRS_FOGCOLOR: - case D3DRS_ALPHAREF: - case D3DRS_STENCILMASK: - case D3DRS_STENCILWRITEMASK: - case D3DRS_TEXTUREFACTOR: - case D3DRS_AMBIENT: - case D3DRS_CLIPPLANEENABLE: - case D3DRS_MULTISAMPLEMASK: - name.Format("0x%x",value); - break; - - case D3DRS_ZWRITEENABLE: - case D3DRS_ALPHATESTENABLE: - case D3DRS_LASTPIXEL: - case D3DRS_DITHERENABLE: - case D3DRS_ALPHABLENDENABLE: - case D3DRS_FOGENABLE: - case D3DRS_SPECULARENABLE: - case D3DRS_STENCILENABLE: - case D3DRS_RANGEFOGENABLE: - case D3DRS_EDGEANTIALIAS: - case D3DRS_CLIPPING: - case D3DRS_LIGHTING: - case D3DRS_COLORVERTEX: - case D3DRS_LOCALVIEWER: - case D3DRS_NORMALIZENORMALS: - case D3DRS_SOFTWAREVERTEXPROCESSING: - case D3DRS_POINTSPRITEENABLE: - case D3DRS_POINTSCALEENABLE: - case D3DRS_MULTISAMPLEANTIALIAS: - case D3DRS_INDEXEDVERTEXBLENDENABLE: - name=value ? "TRUE" : "FALSE"; - break; - - case D3DRS_SRCBLEND: - case D3DRS_DESTBLEND: - name=Get_DX8_Blend_Name(value); - break; - - case D3DRS_CULLMODE: - name=Get_DX8_Cull_Mode_Name(value); - break; - - case D3DRS_ZFUNC: - case D3DRS_ALPHAFUNC: - case D3DRS_STENCILFUNC: - name=Get_DX8_Cmp_Func_Name(value); - break; - - case D3DRS_ZVISIBLE: - name="NOTSUPPORTED"; - break; - - case D3DRS_FOGTABLEMODE: - case D3DRS_FOGVERTEXMODE: - name=Get_DX8_Fog_Mode_Name(value); - break; - - case D3DRS_FOGSTART: - case D3DRS_FOGEND: - case D3DRS_FOGDENSITY: - case D3DRS_POINTSIZE: - case D3DRS_POINTSIZE_MIN: - case D3DRS_POINTSCALE_A: - case D3DRS_POINTSCALE_B: - case D3DRS_POINTSCALE_C: - case D3DRS_PATCHSEGMENTS: - case D3DRS_POINTSIZE_MAX: - case D3DRS_TWEENFACTOR: - name.Format("%f",*(float*)&value); - break; - - case D3DRS_ZBIAS: - case D3DRS_STENCILREF: - name.Format("%d",value); - break; - - case D3DRS_STENCILFAIL: - case D3DRS_STENCILZFAIL: - case D3DRS_STENCILPASS: - name=Get_DX8_Stencil_Op_Name(value); - break; - - case D3DRS_WRAP0: - case D3DRS_WRAP1: - case D3DRS_WRAP2: - case D3DRS_WRAP3: - case D3DRS_WRAP4: - case D3DRS_WRAP5: - case D3DRS_WRAP6: - case D3DRS_WRAP7: - name="0"; - if (value&D3DWRAP_U) name+="|D3DWRAP_U"; - if (value&D3DWRAP_V) name+="|D3DWRAP_V"; - if (value&D3DWRAP_W) name+="|D3DWRAP_W"; - break; - - case D3DRS_DIFFUSEMATERIALSOURCE: - case D3DRS_SPECULARMATERIALSOURCE: - case D3DRS_AMBIENTMATERIALSOURCE: - case D3DRS_EMISSIVEMATERIALSOURCE: - name=Get_DX8_Material_Source_Name(value); - break; - - case D3DRS_VERTEXBLEND: - name=Get_DX8_Vertex_Blend_Flag_Name(value); - break; - - case D3DRS_PATCHEDGESTYLE: - name=Get_DX8_Patch_Edge_Style_Name(value); - break; - - case D3DRS_DEBUGMONITORTOKEN: - name=Get_DX8_Debug_Monitor_Token_Name(value); - break; - - case D3DRS_COLORWRITEENABLE: - name="0"; - if (value&D3DCOLORWRITEENABLE_RED) name+="|D3DCOLORWRITEENABLE_RED"; - if (value&D3DCOLORWRITEENABLE_GREEN) name+="|D3DCOLORWRITEENABLE_GREEN"; - if (value&D3DCOLORWRITEENABLE_BLUE) name+="|D3DCOLORWRITEENABLE_BLUE"; - if (value&D3DCOLORWRITEENABLE_ALPHA) name+="|D3DCOLORWRITEENABLE_ALPHA"; - break; - case D3DRS_BLENDOP: - name=Get_DX8_Blend_Op_Name(value); - break; - default: - name.Format("UNKNOWN (%d)",value); - break; - } -} - -void DX8Wrapper::Get_DX8_Texture_Stage_State_Value_Name(StringClass& name, D3DTEXTURESTAGESTATETYPE state, unsigned value) -{ - switch (state) { - case D3DTSS_COLOROP: - case D3DTSS_ALPHAOP: - name=Get_DX8_Texture_Op_Name(value); - break; - - case D3DTSS_COLORARG0: - case D3DTSS_COLORARG1: - case D3DTSS_COLORARG2: - case D3DTSS_ALPHAARG0: - case D3DTSS_ALPHAARG1: - case D3DTSS_ALPHAARG2: - case D3DTSS_RESULTARG: - name=Get_DX8_Texture_Arg_Name(value); - break; - - case D3DTSS_ADDRESSU: - case D3DTSS_ADDRESSV: - case D3DTSS_ADDRESSW: - name=Get_DX8_Texture_Address_Name(value); - break; - - case D3DTSS_MAGFILTER: - case D3DTSS_MINFILTER: - case D3DTSS_MIPFILTER: - name=Get_DX8_Texture_Filter_Name(value); - break; - - case D3DTSS_TEXTURETRANSFORMFLAGS: - name=Get_DX8_Texture_Transform_Flag_Name(value); - break; - - // Floating point values - case D3DTSS_MIPMAPLODBIAS: - case D3DTSS_BUMPENVMAT00: - case D3DTSS_BUMPENVMAT01: - case D3DTSS_BUMPENVMAT10: - case D3DTSS_BUMPENVMAT11: - case D3DTSS_BUMPENVLSCALE: - case D3DTSS_BUMPENVLOFFSET: - name.Format("%f",*(float*)&value); - break; - - case D3DTSS_TEXCOORDINDEX: - if ((value&0xffff0000)==D3DTSS_TCI_CAMERASPACENORMAL) { - name.Format("D3DTSS_TCI_CAMERASPACENORMAL|%d",value&0xffff); - } - else if ((value&0xffff0000)==D3DTSS_TCI_CAMERASPACEPOSITION) { - name.Format("D3DTSS_TCI_CAMERASPACEPOSITION|%d",value&0xffff); - } - else if ((value&0xffff0000)==D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR) { - name.Format("D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR|%d",value&0xffff); - } - else { - name.Format("%d",value); - } - break; - - // Integer value - case D3DTSS_MAXMIPLEVEL: - case D3DTSS_MAXANISOTROPY: - name.Format("%d",value); - break; - // Hex values - case D3DTSS_BORDERCOLOR: - name.Format("0x%x",value); - break; - - default: - name.Format("UNKNOWN (%d)",value); - break; - } -} - -const char* DX8Wrapper::Get_DX8_Texture_Op_Name(unsigned value) -{ - switch (value) { - case D3DTOP_DISABLE : return "D3DTOP_DISABLE"; - case D3DTOP_SELECTARG1 : return "D3DTOP_SELECTARG1"; - case D3DTOP_SELECTARG2 : return "D3DTOP_SELECTARG2"; - case D3DTOP_MODULATE : return "D3DTOP_MODULATE"; - case D3DTOP_MODULATE2X : return "D3DTOP_MODULATE2X"; - case D3DTOP_MODULATE4X : return "D3DTOP_MODULATE4X"; - case D3DTOP_ADD : return "D3DTOP_ADD"; - case D3DTOP_ADDSIGNED : return "D3DTOP_ADDSIGNED"; - case D3DTOP_ADDSIGNED2X : return "D3DTOP_ADDSIGNED2X"; - case D3DTOP_SUBTRACT : return "D3DTOP_SUBTRACT"; - case D3DTOP_ADDSMOOTH : return "D3DTOP_ADDSMOOTH"; - case D3DTOP_BLENDDIFFUSEALPHA : return "D3DTOP_BLENDDIFFUSEALPHA"; - case D3DTOP_BLENDTEXTUREALPHA : return "D3DTOP_BLENDTEXTUREALPHA"; - case D3DTOP_BLENDFACTORALPHA : return "D3DTOP_BLENDFACTORALPHA"; - case D3DTOP_BLENDTEXTUREALPHAPM : return "D3DTOP_BLENDTEXTUREALPHAPM"; - case D3DTOP_BLENDCURRENTALPHA : return "D3DTOP_BLENDCURRENTALPHA"; - case D3DTOP_PREMODULATE : return "D3DTOP_PREMODULATE"; - case D3DTOP_MODULATEALPHA_ADDCOLOR : return "D3DTOP_MODULATEALPHA_ADDCOLOR"; - case D3DTOP_MODULATECOLOR_ADDALPHA : return "D3DTOP_MODULATECOLOR_ADDALPHA"; - case D3DTOP_MODULATEINVALPHA_ADDCOLOR : return "D3DTOP_MODULATEINVALPHA_ADDCOLOR"; - case D3DTOP_MODULATEINVCOLOR_ADDALPHA : return "D3DTOP_MODULATEINVCOLOR_ADDALPHA"; - case D3DTOP_BUMPENVMAP : return "D3DTOP_BUMPENVMAP"; - case D3DTOP_BUMPENVMAPLUMINANCE : return "D3DTOP_BUMPENVMAPLUMINANCE"; - case D3DTOP_DOTPRODUCT3 : return "D3DTOP_DOTPRODUCT3"; - case D3DTOP_MULTIPLYADD : return "D3DTOP_MULTIPLYADD"; - case D3DTOP_LERP : return "D3DTOP_LERP"; - default : return "UNKNOWN"; - } -} - -const char* DX8Wrapper::Get_DX8_Texture_Arg_Name(unsigned value) -{ - switch (value) { - case D3DTA_CURRENT : return "D3DTA_CURRENT"; - case D3DTA_DIFFUSE : return "D3DTA_DIFFUSE"; - case D3DTA_SELECTMASK : return "D3DTA_SELECTMASK"; - case D3DTA_SPECULAR : return "D3DTA_SPECULAR"; - case D3DTA_TEMP : return "D3DTA_TEMP"; - case D3DTA_TEXTURE : return "D3DTA_TEXTURE"; - case D3DTA_TFACTOR : return "D3DTA_TFACTOR"; - case D3DTA_ALPHAREPLICATE : return "D3DTA_ALPHAREPLICATE"; - case D3DTA_COMPLEMENT : return "D3DTA_COMPLEMENT"; - default : return "UNKNOWN"; - } -} - -const char* DX8Wrapper::Get_DX8_Texture_Filter_Name(unsigned value) -{ - switch (value) { - case D3DTEXF_NONE : return "D3DTEXF_NONE"; - case D3DTEXF_POINT : return "D3DTEXF_POINT"; - case D3DTEXF_LINEAR : return "D3DTEXF_LINEAR"; - case D3DTEXF_ANISOTROPIC : return "D3DTEXF_ANISOTROPIC"; - case D3DTEXF_FLATCUBIC : return "D3DTEXF_FLATCUBIC"; - case D3DTEXF_GAUSSIANCUBIC : return "D3DTEXF_GAUSSIANCUBIC"; - default : return "UNKNOWN"; - } -} - -const char* DX8Wrapper::Get_DX8_Texture_Address_Name(unsigned value) -{ - switch (value) { - case D3DTADDRESS_WRAP : return "D3DTADDRESS_WRAP"; - case D3DTADDRESS_MIRROR : return "D3DTADDRESS_MIRROR"; - case D3DTADDRESS_CLAMP : return "D3DTADDRESS_CLAMP"; - case D3DTADDRESS_BORDER : return "D3DTADDRESS_BORDER"; - case D3DTADDRESS_MIRRORONCE: return "D3DTADDRESS_MIRRORONCE"; - default : return "UNKNOWN"; - } -} - -const char* DX8Wrapper::Get_DX8_Texture_Transform_Flag_Name(unsigned value) -{ - switch (value) { - case D3DTTFF_DISABLE : return "D3DTTFF_DISABLE"; - case D3DTTFF_COUNT1 : return "D3DTTFF_COUNT1"; - case D3DTTFF_COUNT2 : return "D3DTTFF_COUNT2"; - case D3DTTFF_COUNT3 : return "D3DTTFF_COUNT3"; - case D3DTTFF_COUNT4 : return "D3DTTFF_COUNT4"; - case D3DTTFF_PROJECTED : return "D3DTTFF_PROJECTED"; - default : return "UNKNOWN"; - } -} - -const char* DX8Wrapper::Get_DX8_ZBuffer_Type_Name(unsigned value) -{ - switch (value) { - case D3DZB_FALSE : return "D3DZB_FALSE"; - case D3DZB_TRUE : return "D3DZB_TRUE"; - case D3DZB_USEW : return "D3DZB_USEW"; - default : return "UNKNOWN"; - } -} - -const char* DX8Wrapper::Get_DX8_Fill_Mode_Name(unsigned value) -{ - switch (value) { - case D3DFILL_POINT : return "D3DFILL_POINT"; - case D3DFILL_WIREFRAME : return "D3DFILL_WIREFRAME"; - case D3DFILL_SOLID : return "D3DFILL_SOLID"; - default : return "UNKNOWN"; - } -} - -const char* DX8Wrapper::Get_DX8_Shade_Mode_Name(unsigned value) -{ - switch (value) { - case D3DSHADE_FLAT : return "D3DSHADE_FLAT"; - case D3DSHADE_GOURAUD : return "D3DSHADE_GOURAUD"; - case D3DSHADE_PHONG : return "D3DSHADE_PHONG"; - default : return "UNKNOWN"; - } -} - -const char* DX8Wrapper::Get_DX8_Blend_Name(unsigned value) -{ - switch (value) { - case D3DBLEND_ZERO : return "D3DBLEND_ZERO"; - case D3DBLEND_ONE : return "D3DBLEND_ONE"; - case D3DBLEND_SRCCOLOR : return "D3DBLEND_SRCCOLOR"; - case D3DBLEND_INVSRCCOLOR : return "D3DBLEND_INVSRCCOLOR"; - case D3DBLEND_SRCALPHA : return "D3DBLEND_SRCALPHA"; - case D3DBLEND_INVSRCALPHA : return "D3DBLEND_INVSRCALPHA"; - case D3DBLEND_DESTALPHA : return "D3DBLEND_DESTALPHA"; - case D3DBLEND_INVDESTALPHA : return "D3DBLEND_INVDESTALPHA"; - case D3DBLEND_DESTCOLOR : return "D3DBLEND_DESTCOLOR"; - case D3DBLEND_INVDESTCOLOR : return "D3DBLEND_INVDESTCOLOR"; - case D3DBLEND_SRCALPHASAT : return "D3DBLEND_SRCALPHASAT"; - case D3DBLEND_BOTHSRCALPHA : return "D3DBLEND_BOTHSRCALPHA"; - case D3DBLEND_BOTHINVSRCALPHA : return "D3DBLEND_BOTHINVSRCALPHA"; - default : return "UNKNOWN"; - } -} - -const char* DX8Wrapper::Get_DX8_Cull_Mode_Name(unsigned value) -{ - switch (value) { - case D3DCULL_NONE : return "D3DCULL_NONE"; - case D3DCULL_CW : return "D3DCULL_CW"; - case D3DCULL_CCW : return "D3DCULL_CCW"; - default : return "UNKNOWN"; - } -} - -const char* DX8Wrapper::Get_DX8_Cmp_Func_Name(unsigned value) -{ - switch (value) { - case D3DCMP_NEVER : return "D3DCMP_NEVER"; - case D3DCMP_LESS : return "D3DCMP_LESS"; - case D3DCMP_EQUAL : return "D3DCMP_EQUAL"; - case D3DCMP_LESSEQUAL : return "D3DCMP_LESSEQUAL"; - case D3DCMP_GREATER : return "D3DCMP_GREATER"; - case D3DCMP_NOTEQUAL : return "D3DCMP_NOTEQUAL"; - case D3DCMP_GREATEREQUAL : return "D3DCMP_GREATEREQUAL"; - case D3DCMP_ALWAYS : return "D3DCMP_ALWAYS"; - default : return "UNKNOWN"; - } -} - -const char* DX8Wrapper::Get_DX8_Fog_Mode_Name(unsigned value) -{ - switch (value) { - case D3DFOG_NONE : return "D3DFOG_NONE"; - case D3DFOG_EXP : return "D3DFOG_EXP"; - case D3DFOG_EXP2 : return "D3DFOG_EXP2"; - case D3DFOG_LINEAR : return "D3DFOG_LINEAR"; - default : return "UNKNOWN"; - } -} - -const char* DX8Wrapper::Get_DX8_Stencil_Op_Name(unsigned value) -{ - switch (value) { - case D3DSTENCILOP_KEEP : return "D3DSTENCILOP_KEEP"; - case D3DSTENCILOP_ZERO : return "D3DSTENCILOP_ZERO"; - case D3DSTENCILOP_REPLACE : return "D3DSTENCILOP_REPLACE"; - case D3DSTENCILOP_INCRSAT : return "D3DSTENCILOP_INCRSAT"; - case D3DSTENCILOP_DECRSAT : return "D3DSTENCILOP_DECRSAT"; - case D3DSTENCILOP_INVERT : return "D3DSTENCILOP_INVERT"; - case D3DSTENCILOP_INCR : return "D3DSTENCILOP_INCR"; - case D3DSTENCILOP_DECR : return "D3DSTENCILOP_DECR"; - default : return "UNKNOWN"; - } -} - -const char* DX8Wrapper::Get_DX8_Material_Source_Name(unsigned value) -{ - switch (value) { - case D3DMCS_MATERIAL : return "D3DMCS_MATERIAL"; - case D3DMCS_COLOR1 : return "D3DMCS_COLOR1"; - case D3DMCS_COLOR2 : return "D3DMCS_COLOR2"; - default : return "UNKNOWN"; - } -} - -const char* DX8Wrapper::Get_DX8_Vertex_Blend_Flag_Name(unsigned value) -{ - switch (value) { - case D3DVBF_DISABLE : return "D3DVBF_DISABLE"; - case D3DVBF_1WEIGHTS : return "D3DVBF_1WEIGHTS"; - case D3DVBF_2WEIGHTS : return "D3DVBF_2WEIGHTS"; - case D3DVBF_3WEIGHTS : return "D3DVBF_3WEIGHTS"; - case D3DVBF_TWEENING : return "D3DVBF_TWEENING"; - case D3DVBF_0WEIGHTS : return "D3DVBF_0WEIGHTS"; - default : return "UNKNOWN"; - } -} - -const char* DX8Wrapper::Get_DX8_Patch_Edge_Style_Name(unsigned value) -{ - switch (value) { - case D3DPATCHEDGE_DISCRETE : return "D3DPATCHEDGE_DISCRETE"; - case D3DPATCHEDGE_CONTINUOUS:return "D3DPATCHEDGE_CONTINUOUS"; - default : return "UNKNOWN"; - } -} - -const char* DX8Wrapper::Get_DX8_Debug_Monitor_Token_Name(unsigned value) -{ - switch (value) { - case D3DDMT_ENABLE : return "D3DDMT_ENABLE"; - case D3DDMT_DISABLE : return "D3DDMT_DISABLE"; - default : return "UNKNOWN"; - } -} - -const char* DX8Wrapper::Get_DX8_Blend_Op_Name(unsigned value) -{ - switch (value) { - case D3DBLENDOP_ADD : return "D3DBLENDOP_ADD"; - case D3DBLENDOP_SUBTRACT : return "D3DBLENDOP_SUBTRACT"; - case D3DBLENDOP_REVSUBTRACT: return "D3DBLENDOP_REVSUBTRACT"; - case D3DBLENDOP_MIN : return "D3DBLENDOP_MIN"; - case D3DBLENDOP_MAX : return "D3DBLENDOP_MAX"; - default : return "UNKNOWN"; - } -} - - -//============================================================================ -// DX8Wrapper::getBackBufferFormat -//============================================================================ - -WW3DFormat DX8Wrapper::getBackBufferFormat( void ) -{ - return D3DFormat_To_WW3DFormat( _PresentParameters.BackBufferFormat ); -} diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h deleted file mode 100644 index 3956b85fc9..0000000000 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h +++ /dev/null @@ -1,1347 +0,0 @@ -/* -** Command & Conquer Generals(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:: /VSS_Sync/ww3d2/dx8wrapper.h $* - * * - * Original Author:: Jani Penttinen * - * * - * $Author:: Vss_sync $* - * * - * $Modtime:: 8/29/01 7:29p $* - * * - * $Revision:: 76 $* - * * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#if defined(_MSC_VER) -#pragma once -#endif - -#ifndef DX8_WRAPPER_H -#define DX8_WRAPPER_H - -#include "always.h" -#include "dllist.h" -#include "d3d8.h" -#include "matrix4.h" -#include "statistics.h" -#include "wwstring.h" -#include "lightenvironment.h" -#include "shader.h" -#include "vector4.h" -#include "cpudetect.h" -#include "dx8caps.h" - -#include "texture.h" -#include "dx8vertexbuffer.h" -#include "dx8indexbuffer.h" -#include "vertmaterial.h" - -/* -** Registry value names -*/ -#define VALUE_NAME_RENDER_DEVICE_NAME "RenderDeviceName" -#define VALUE_NAME_RENDER_DEVICE_WIDTH "RenderDeviceWidth" -#define VALUE_NAME_RENDER_DEVICE_HEIGHT "RenderDeviceHeight" -#define VALUE_NAME_RENDER_DEVICE_DEPTH "RenderDeviceDepth" -#define VALUE_NAME_RENDER_DEVICE_WINDOWED "RenderDeviceWindowed" -#define VALUE_NAME_RENDER_DEVICE_TEXTURE_DEPTH "RenderDeviceTextureDepth" - -const unsigned MAX_TEXTURE_STAGES=2; -const unsigned MAX_VERTEX_STREAMS=2; -const unsigned MAX_VERTEX_SHADER_CONSTANTS=96; -const unsigned MAX_PIXEL_SHADER_CONSTANTS=8; -const unsigned MAX_SHADOW_MAPS=1; - -#define prevVer -#define nextVer - - -enum { - BUFFER_TYPE_DX8, - BUFFER_TYPE_SORTING, - BUFFER_TYPE_DYNAMIC_DX8, - BUFFER_TYPE_DYNAMIC_SORTING, - BUFFER_TYPE_INVALID -}; - -class VertexMaterialClass; -class CameraClass; -class LightEnvironmentClass; -class RenderDeviceDescClass; -class VertexBufferClass; -class DynamicVBAccessClass; -class IndexBufferClass; -class DynamicIBAccessClass; -class TextureClass; -class LightClass; -class SurfaceClass; - -#define DX8_RECORD_MATRIX_CHANGE() matrix_changes++ -#define DX8_RECORD_MATERIAL_CHANGE() material_changes++ -#define DX8_RECORD_VERTEX_BUFFER_CHANGE() vertex_buffer_changes++ -#define DX8_RECORD_INDEX_BUFFER_CHANGE() index_buffer_changes++ -#define DX8_RECORD_LIGHT_CHANGE() light_changes++ -#define DX8_RECORD_TEXTURE_CHANGE() texture_changes++ -#define DX8_RECORD_RENDER_STATE_CHANGE() render_state_changes++ -#define DX8_RECORD_TEXTURE_STAGE_STATE_CHANGE() texture_stage_state_changes++ -#define DX8_RECORD_DRAW_CALLS() draw_calls++ - -extern unsigned number_of_DX8_calls; -extern bool _DX8SingleThreaded; - -void DX8_Assert(); -void Log_DX8_ErrorCode(unsigned res); - -WWINLINE void DX8_ErrorCode(unsigned res) -{ - if (res==D3D_OK) return; - Log_DX8_ErrorCode(res); -} - -#ifdef WWDEBUG -#define DX8CALL_HRES(x,res) DX8_Assert(); res = DX8Wrapper::_Get_D3D_Device8()->x; DX8_ErrorCode(res); number_of_DX8_calls++; -#define DX8CALL(x) DX8_Assert(); DX8_ErrorCode(DX8Wrapper::_Get_D3D_Device8()->x); number_of_DX8_calls++; -#define DX8CALL_D3D(x) DX8_Assert(); DX8_ErrorCode(DX8Wrapper::_Get_D3D8()->x); number_of_DX8_calls++; -#define DX8_THREAD_ASSERT() if (_DX8SingleThreaded) { WWASSERT_PRINT(DX8Wrapper::_Get_Main_Thread_ID()==ThreadClass::_Get_Current_Thread_ID(),"DX8Wrapper::DX8 calls must be called from the main thread!"); } -#else -#define DX8CALL_HRES(x,res) res = DX8Wrapper::_Get_D3D_Device8()->x; number_of_DX8_calls++; -#define DX8CALL(x) DX8Wrapper::_Get_D3D_Device8()->x; number_of_DX8_calls++; -#define DX8CALL_D3D(x) DX8Wrapper::_Get_D3D8()->x; number_of_DX8_calls++; -#define DX8_THREAD_ASSERT() ; -#endif - - -#define no_EXTENDED_STATS -// EXTENDED_STATS collects additional timing statistics by turning off parts -// of the 3D drawing system (terrain, objects, etc.) -#ifdef EXTENDED_STATS -class DX8_Stats -{ -public: - bool m_showingStats; - bool m_disableTerrain; - bool m_disableWater; - bool m_disableObjects; - bool m_disableOverhead; - bool m_disableConsole; - int m_debugLinesToShow; - int m_sleepTime; -public: - DX8_Stats::DX8_Stats(void) { - m_disableConsole = m_showingStats = m_disableTerrain = m_disableWater = m_disableOverhead = m_disableObjects = false; - m_sleepTime = 0; - m_debugLinesToShow = -1; // -1 means show all expected lines of output - } -}; -#endif - - -// This virtual interface was added for the Generals RTS. -// It is called before resetting the dx8 device to ensure -// that all dx8 resources are released. Otherwise reset fails. jba. -class DX8_CleanupHook -{ -public: - virtual void ReleaseResources(void)=0; - virtual void ReAcquireResources(void)=0; -}; - - -struct RenderStateStruct -{ - ShaderClass shader; - VertexMaterialClass* material; - TextureBaseClass * Textures[MAX_TEXTURE_STAGES]; - D3DLIGHT8 Lights[4]; - bool LightEnable[4]; - Matrix4x4 world; - Matrix4x4 view; - unsigned vertex_buffer_type; - unsigned index_buffer_type; - unsigned short vba_offset; - unsigned short vba_count; - unsigned short iba_offset; - VertexBufferClass* vertex_buffer; - IndexBufferClass* index_buffer; - unsigned short index_base_offset; - - RenderStateStruct(); - ~RenderStateStruct(); - - RenderStateStruct& operator= (const RenderStateStruct& src); -}; - -/** -** DX8Wrapper -** -** DX8 interface wrapper class. This encapsulates the DX8 interface; adding redundant state -** detection, stat tracking, etc etc. In general, we will wrap all DX8 calls with at least -** an WWINLINE function so that we can add stat tracking, etc if needed. Direct access to the -** D3D device will require "friend" status and should be granted only in extreme circumstances :-) -*/ -class DX8Wrapper -{ - enum ChangedStates { - WORLD_CHANGED = 1<<0, - VIEW_CHANGED = 1<<1, - LIGHT0_CHANGED = 1<<2, - LIGHT1_CHANGED = 1<<3, - LIGHT2_CHANGED = 1<<4, - LIGHT3_CHANGED = 1<<5, - TEXTURE0_CHANGED= 1<<6, - TEXTURE1_CHANGED= 1<<7, - TEXTURE2_CHANGED= 1<<8, - TEXTURE3_CHANGED= 1<<9, - MATERIAL_CHANGED= 1<<14, - SHADER_CHANGED = 1<<15, - VERTEX_BUFFER_CHANGED = 1<<16, - INDEX_BUFFER_CHANGED = 1 << 17, - WORLD_IDENTITY= 1<<18, - VIEW_IDENTITY= 1<<19, - - TEXTURES_CHANGED= - TEXTURE0_CHANGED|TEXTURE1_CHANGED|TEXTURE2_CHANGED|TEXTURE3_CHANGED, - LIGHTS_CHANGED= - LIGHT0_CHANGED|LIGHT1_CHANGED|LIGHT2_CHANGED|LIGHT3_CHANGED, - }; - - static void Draw_Sorting_IB_VB( - unsigned primitive_type, - unsigned short start_index, - unsigned short polygon_count, - unsigned short min_vertex_index, - unsigned short vertex_count); - - static void Draw( - unsigned primitive_type, - unsigned short start_index, - unsigned short polygon_count, - unsigned short min_vertex_index=0, - unsigned short vertex_count=0); - -public: -#ifdef EXTENDED_STATS - static DX8_Stats stats; -#endif - - static bool Init(void * hwnd, bool lite = false); - static void Shutdown(void); - - static void SetCleanupHook(DX8_CleanupHook *pCleanupHook) {m_pCleanupHook = pCleanupHook;}; - /* - ** Some WW3D sub-systems need to be initialized after the device is created and shutdown - ** before the device is released. - */ - static void Do_Onetime_Device_Dependent_Inits(void); - static void Do_Onetime_Device_Dependent_Shutdowns(void); - - static bool Is_Device_Lost() { return IsDeviceLost; } - static bool Is_Initted(void) { return IsInitted; } - - static bool Has_Stencil (void); - static void Get_Format_Name(unsigned int format, StringClass *tex_format); - - /* - ** Rendering - */ - static void Begin_Scene(void); - static void End_Scene(bool flip_frame = true); - - // Flip until the primary buffer is visible. - static void Flip_To_Primary(void); - - static void Clear(bool clear_color, bool clear_z_stencil, const Vector3 &color, float dest_alpha=0.0f, float z=1.0f, unsigned int stencil=0); - - static void Set_Viewport(CONST D3DVIEWPORT8* pViewport); - - static void Set_Vertex_Buffer(const VertexBufferClass* vb); - static void Set_Vertex_Buffer(const DynamicVBAccessClass& vba); - static void Set_Index_Buffer(const IndexBufferClass* ib,unsigned short index_base_offset); - static void Set_Index_Buffer(const DynamicIBAccessClass& iba,unsigned short index_base_offset); - static void Set_Index_Buffer_Index_Offset(unsigned offset); - - static void Get_Render_State(RenderStateStruct& state); - static void Set_Render_State(const RenderStateStruct& state); - static void Release_Render_State(); - - static void Set_DX8_Material(const D3DMATERIAL8* mat); - - static void Set_Gamma(float gamma,float bright,float contrast,bool calibrate=true,bool uselimit=true); - - // Set_ and Get_Transform() functions take the matrix in Westwood convention format. - - static void Set_Transform(D3DTRANSFORMSTATETYPE transform,const Matrix4x4& m); - static void Set_Transform(D3DTRANSFORMSTATETYPE transform,const Matrix3D& m); - static void Get_Transform(D3DTRANSFORMSTATETYPE transform, Matrix4x4& m); - static void Set_World_Identity(); - static void Set_View_Identity(); - static bool Is_World_Identity(); - static bool Is_View_Identity(); - - // Note that *_DX8_Transform() functions take the matrix in DX8 format - transposed from Westwood convention. - - static void _Set_DX8_Transform(D3DTRANSFORMSTATETYPE transform,const Matrix4x4& m); - static void _Set_DX8_Transform(D3DTRANSFORMSTATETYPE transform,const Matrix3D& m); - static void _Get_DX8_Transform(D3DTRANSFORMSTATETYPE transform, Matrix4x4& m); - - static void Set_DX8_Light(int index,D3DLIGHT8* light); - static void Set_DX8_Render_State(D3DRENDERSTATETYPE state, unsigned value); - static void Set_DX8_Clip_Plane(DWORD Index, CONST float* pPlane); - static void Set_DX8_Texture_Stage_State(unsigned stage, D3DTEXTURESTAGESTATETYPE state, unsigned value); - static void Set_DX8_Texture(unsigned int stage, IDirect3DBaseTexture8* texture); - static void Set_Light_Environment(LightEnvironmentClass* light_env); - static LightEnvironmentClass* Get_Light_Environment() { return Light_Environment; } - static void Set_Fog(bool enable, const Vector3 &color, float start, float end); - - static WWINLINE const D3DLIGHT8& Peek_Light(unsigned index); - static WWINLINE bool Is_Light_Enabled(unsigned index); - - static bool Validate_Device(void); - - // Deferred - - static void Set_Shader(const ShaderClass& shader); - static void Get_Shader(ShaderClass& shader); - static void Set_Texture(unsigned stage,TextureBaseClass* texture); - static void Set_Material(const VertexMaterialClass* material); - static void Set_Light(unsigned index,const D3DLIGHT8* light); - static void Set_Light(unsigned index,const LightClass &light); - - static void Apply_Render_State_Changes(); // Apply deferred render state changes (will be called automatically by Draw...) - - static void Draw_Triangles( - unsigned buffer_type, - unsigned short start_index, - unsigned short polygon_count, - unsigned short min_vertex_index, - unsigned short vertex_count); - static void Draw_Triangles( - unsigned short start_index, - unsigned short polygon_count, - unsigned short min_vertex_index, - unsigned short vertex_count); - static void Draw_Strip( - unsigned short start_index, - unsigned short index_count, - unsigned short min_vertex_index, - unsigned short vertex_count); - - /* - ** Resources - */ - - static IDirect3DTexture8 * _Create_DX8_Texture - ( - unsigned int width, - unsigned int height, - WW3DFormat format, - MipCountType mip_level_count, - D3DPOOL pool=D3DPOOL_MANAGED, - bool rendertarget=false - ); - static IDirect3DTexture8 * _Create_DX8_Texture(const char *filename, MipCountType mip_level_count); - static IDirect3DTexture8 * _Create_DX8_Texture(IDirect3DSurface8 *surface, MipCountType mip_level_count); - - static IDirect3DSurface8 * _Create_DX8_Surface(unsigned int width, unsigned int height, WW3DFormat format); - static IDirect3DSurface8 * _Create_DX8_Surface(const char *filename); - static IDirect3DSurface8 * _Get_DX8_Front_Buffer(); - static SurfaceClass * _Get_DX8_Back_Buffer(unsigned int num=0); - - static void _Copy_DX8_Rects( - IDirect3DSurface8* pSourceSurface, - CONST RECT* pSourceRectsArray, - UINT cRects, - IDirect3DSurface8* pDestinationSurface, - CONST POINT* pDestPointsArray - ); - - static void _Update_Texture(TextureClass *system, TextureClass *video); - static void Flush_DX8_Resource_Manager(unsigned int bytes=0); - static unsigned int Get_Free_Texture_RAM(); - - static unsigned _Get_Main_Thread_ID() { return _MainThreadID; } - static const D3DADAPTER_IDENTIFIER8& Get_Current_Adapter_Identifier() { return CurrentAdapterIdentifier; } - - /* - ** Statistics - */ - static void Begin_Statistics(); - static void End_Statistics(); - static unsigned Get_Last_Frame_Matrix_Changes(); - static unsigned Get_Last_Frame_Material_Changes(); - static unsigned Get_Last_Frame_Vertex_Buffer_Changes(); - static unsigned Get_Last_Frame_Index_Buffer_Changes(); - static unsigned Get_Last_Frame_Light_Changes(); - static unsigned Get_Last_Frame_Texture_Changes(); - static unsigned Get_Last_Frame_Render_State_Changes(); - static unsigned Get_Last_Frame_Texture_Stage_State_Changes(); - static unsigned Get_Last_Frame_DX8_Calls(); - static unsigned Get_Last_Frame_Draw_Calls(); - - static unsigned long Get_FrameCount(void); - - // Needed by shader class - static bool Get_Fog_Enable() { return FogEnable; } - static D3DCOLOR Get_Fog_Color() { return FogColor; } - - // Utilities - static Vector4 Convert_Color(unsigned color); - static unsigned int Convert_Color(const Vector4& color); - static unsigned int Convert_Color(const Vector3& color, const float alpha); - static void Clamp_Color(Vector4& color); - static unsigned int Convert_Color_Clamp(const Vector4& color); - - static void Set_Alpha (const float alpha, unsigned int &color); - - static void _Enable_Triangle_Draw(bool enable) { _EnableTriangleDraw=enable; } - static bool _Is_Triangle_Draw_Enabled() { return _EnableTriangleDraw; } - - /* - ** Additional swap chain interface - ** - ** Use this interface to render to multiple windows (in windowed mode). - ** To render to an additional window, the sequence of calls should look - ** something like this: - ** - ** DX8Wrapper::Set_Render_Target (swap_chain_ptr); - ** - ** WW3D::Begin_Render (true, true, Vector3 (0, 0, 0)); - ** WW3D::Render (scene, camera, FALSE, FALSE); - ** WW3D::End_Render (); - ** - ** swap_chain_ptr->Present (NULL, NULL, NULL, NULL); - ** - ** DX8Wrapper::Set_Render_Target ((IDirect3DSurface8 *)NULL); - ** - */ - static IDirect3DSwapChain8 * Create_Additional_Swap_Chain (HWND render_window); - - /* - ** Render target interface - */ - static TextureClass * Create_Render_Target (int width, int height, bool alpha=false); - - static void Set_Render_Target (TextureBaseClass * texture); - static void Set_Render_Target (IDirect3DSurface8 *render_target); - static void Set_Render_Target (IDirect3DSwapChain8 *swap_chain); - static bool Is_Render_To_Texture(void) { return IsRenderToTexture; } - - // shader system udpates KJM v - static void Apply_Default_State(); - - static void Set_Vertex_Shader(DWORD vertex_shader); - static void Set_Pixel_Shader(DWORD pixel_shader); - - static void Set_Vertex_Shader_Constant(int reg, const void* data, int count); - static void Set_Pixel_Shader_Constant(int reg, const void* data, int count); - - static DWORD Get_Vertex_Processing_Behavior() { return Vertex_Processing_Behavior; } - - // Needed by scene lighting class - static void Set_Ambient(const Vector3& color); - static const Vector3& Get_Ambient() { return Ambient_Color; } - // shader system updates KJM ^ - - - - - static IDirect3DDevice8* _Get_D3D_Device8() { return D3DDevice; } - static IDirect3D8* _Get_D3D8() { return D3DInterface; } - /// Returns the display format - added by TR for video playback - not part of W3D - static WW3DFormat getBackBufferFormat( void ); - static bool Reset_Device(bool reload_assets=true); - - static const DX8Caps* Get_Current_Caps() { WWASSERT(CurrentCaps); return CurrentCaps; } - - static bool Registry_Save_Render_Device( const char * sub_key ); - static bool Registry_Load_Render_Device( const char * sub_key, bool resize_window ); - - static const char* Get_DX8_Render_State_Name(D3DRENDERSTATETYPE state); - static const char* Get_DX8_Texture_Stage_State_Name(D3DTEXTURESTAGESTATETYPE state); - static unsigned Get_DX8_Render_State(D3DRENDERSTATETYPE state) { return RenderStates[state]; } - - // Names of the specific values of render states and texture stage states - static void Get_DX8_Texture_Stage_State_Value_Name(StringClass& name, D3DTEXTURESTAGESTATETYPE state, unsigned value); - static void Get_DX8_Render_State_Value_Name(StringClass& name, D3DRENDERSTATETYPE state, unsigned value); - - static const char* Get_DX8_Texture_Address_Name(unsigned value); - static const char* Get_DX8_Texture_Filter_Name(unsigned value); - static const char* Get_DX8_Texture_Arg_Name(unsigned value); - static const char* Get_DX8_Texture_Op_Name(unsigned value); - static const char* Get_DX8_Texture_Transform_Flag_Name(unsigned value); - static const char* Get_DX8_ZBuffer_Type_Name(unsigned value); - static const char* Get_DX8_Fill_Mode_Name(unsigned value); - static const char* Get_DX8_Shade_Mode_Name(unsigned value); - static const char* Get_DX8_Blend_Name(unsigned value); - static const char* Get_DX8_Cull_Mode_Name(unsigned value); - static const char* Get_DX8_Cmp_Func_Name(unsigned value); - static const char* Get_DX8_Fog_Mode_Name(unsigned value); - static const char* Get_DX8_Stencil_Op_Name(unsigned value); - static const char* Get_DX8_Material_Source_Name(unsigned value); - static const char* Get_DX8_Vertex_Blend_Flag_Name(unsigned value); - static const char* Get_DX8_Patch_Edge_Style_Name(unsigned value); - static const char* Get_DX8_Debug_Monitor_Token_Name(unsigned value); - static const char* Get_DX8_Blend_Op_Name(unsigned value); - - static void Invalidate_Cached_Render_States(void); - - static void Set_Draw_Polygon_Low_Bound_Limit(unsigned n) { DrawPolygonLowBoundLimit=n; } - -protected: - - static bool Create_Device(void); - static void Release_Device(void); - - static void Reset_Statistics(); - static void Enumerate_Devices(); - static void Set_Default_Global_Render_States(void); - - /* - ** Device Selection Code. - ** For backward compatibility, the public interface for these functions is in the ww3d. - ** header file. These functions are protected so that we aren't exposing two interfaces. - */ - static bool Set_Any_Render_Device(void); - static bool Set_Render_Device(const char * dev_name,int width=-1,int height=-1,int bits=-1,int windowed=-1,bool resize_window=false); - static bool Set_Render_Device(int dev=-1,int resx=-1,int resy=-1,int bits=-1,int windowed=-1,bool resize_window = false, bool reset_device = false, bool restore_assets=true); - static bool Set_Next_Render_Device(void); - static bool Toggle_Windowed(void); - - static int Get_Render_Device_Count(void); - static int Get_Render_Device(void); - static const RenderDeviceDescClass & Get_Render_Device_Desc(int deviceidx); - static const char * Get_Render_Device_Name(int device_index); - static bool Set_Device_Resolution(int width=-1,int height=-1,int bits=-1,int windowed=-1, bool resize_window=false); - static void Get_Device_Resolution(int & set_w,int & set_h,int & set_bits,bool & set_windowed); - static void Get_Render_Target_Resolution(int & set_w,int & set_h,int & set_bits,bool & set_windowed); - static int Get_Device_Resolution_Width(void) { return ResolutionWidth; } - static int Get_Device_Resolution_Height(void) { return ResolutionHeight; } - - static bool Registry_Save_Render_Device( const char *sub_key, int device, int width, int height, int depth, bool windowed, int texture_depth); - static bool Registry_Load_Render_Device( const char * sub_key, char *device, int device_len, int &width, int &height, int &depth, int &windowed, int &texture_depth); - static bool Is_Windowed(void) { return IsWindowed; } - - static void Set_Texture_Bitdepth(int depth) { WWASSERT(depth==16 || depth==32); TextureBitDepth = depth; } - static int Get_Texture_Bitdepth(void) { return TextureBitDepth; } - - static void Set_Swap_Interval(int swap); - static int Get_Swap_Interval(void); - static void Set_Polygon_Mode(int mode); - - /* - ** Internal functions - */ - static void Resize_And_Position_Window(); - static bool Find_Color_And_Z_Mode(int resx,int resy,int bitdepth,D3DFORMAT * set_colorbuffer,D3DFORMAT * set_backbuffer, D3DFORMAT * set_zmode); - static bool Find_Color_Mode(D3DFORMAT colorbuffer, int resx, int resy, UINT *mode); - static bool Find_Z_Mode(D3DFORMAT colorbuffer,D3DFORMAT backbuffer, D3DFORMAT *zmode); - static bool Test_Z_Mode(D3DFORMAT colorbuffer,D3DFORMAT backbuffer, D3DFORMAT zmode); - static void Compute_Caps(WW3DFormat display_format); - - /* - ** Protected Member Variables - */ - - static DX8_CleanupHook *m_pCleanupHook; - - static RenderStateStruct render_state; - static unsigned render_state_changed; - static Matrix4x4 DX8Transforms[D3DTS_WORLD+1]; - - static bool IsInitted; - static bool IsDeviceLost; - static void * Hwnd; - static unsigned _MainThreadID; - - static bool _EnableTriangleDraw; - - static int CurRenderDevice; - static int ResolutionWidth; - static int ResolutionHeight; - static int BitDepth; - static int TextureBitDepth; - static bool IsWindowed; - static D3DFORMAT DisplayFormat; - - static D3DMATRIX old_world; - static D3DMATRIX old_view; - static D3DMATRIX old_prj; - - // shader system updates KJM v - static DWORD Vertex_Shader; - static DWORD Pixel_Shader; - - static Vector4 Vertex_Shader_Constants[MAX_VERTEX_SHADER_CONSTANTS]; - static Vector4 Pixel_Shader_Constants[MAX_PIXEL_SHADER_CONSTANTS]; - - static LightEnvironmentClass* Light_Environment; - static RenderInfoClass* Render_Info; - - static DWORD Vertex_Processing_Behavior; - static Vector3 Ambient_Color; - // shader system updates KJM ^ - - static bool world_identity; - static unsigned RenderStates[256]; - static unsigned TextureStageStates[MAX_TEXTURE_STAGES][32]; - static IDirect3DBaseTexture8 * Textures[MAX_TEXTURE_STAGES]; - - // These fog settings are constant for all objects in a given scene, - // unlike the matching renderstates which vary based on shader settings. - static bool FogEnable; - static D3DCOLOR FogColor; - - static unsigned matrix_changes; - static unsigned material_changes; - static unsigned vertex_buffer_changes; - static unsigned index_buffer_changes; - static unsigned light_changes; - static unsigned texture_changes; - static unsigned render_state_changes; - static unsigned texture_stage_state_changes; - static unsigned draw_calls; - static bool CurrentDX8LightEnables[4]; - - static unsigned long FrameCount; - - static DX8Caps* CurrentCaps; - - static D3DADAPTER_IDENTIFIER8 CurrentAdapterIdentifier; - - static IDirect3D8 * D3DInterface; //d3d8; - static IDirect3DDevice8 * D3DDevice; //d3ddevice8; - - static IDirect3DSurface8 * CurrentRenderTarget; - static IDirect3DSurface8 * DefaultRenderTarget; - static unsigned DrawPolygonLowBoundLimit; - - static bool IsRenderToTexture; - - static int ZBias; - static float ZNear; - static float ZFar; - static Matrix4x4 ProjectionMatrix; - - friend void DX8_Assert(); - friend class WW3D; - friend class DX8IndexBufferClass; - friend class DX8VertexBufferClass; -}; - -// shader system updates KJM v -WWINLINE void DX8Wrapper::Set_Vertex_Shader(DWORD vertex_shader) -{ -#if 0 //(gth) some code is bypassing this acessor function so we can't count on this variable... - // may be incorrect if shaders are created and destroyed dynamically - if (Vertex_Shader==vertex_shader) return; -#endif - - Vertex_Shader=vertex_shader; - DX8CALL(SetVertexShader(Vertex_Shader)); -} - -WWINLINE void DX8Wrapper::Set_Pixel_Shader(DWORD pixel_shader) -{ - // may be incorrect if shaders are created and destroyed dynamically - if (Pixel_Shader==pixel_shader) return; - - Pixel_Shader=pixel_shader; - DX8CALL(SetPixelShader(Pixel_Shader)); -} - -WWINLINE void DX8Wrapper::Set_Vertex_Shader_Constant(int reg, const void* data, int count) -{ - int memsize=sizeof(Vector4)*count; - - // may be incorrect if shaders are created and destroyed dynamically - if (memcmp(data, &Vertex_Shader_Constants[reg],memsize)==0) return; - - memcpy(&Vertex_Shader_Constants[reg],data,memsize); - DX8CALL(SetVertexShaderConstant(reg,data,count)); -} - -WWINLINE void DX8Wrapper::Set_Pixel_Shader_Constant(int reg, const void* data, int count) -{ - int memsize=sizeof(Vector4)*count; - - // may be incorrect if shaders are created and destroyed dynamically - if (memcmp(data, &Pixel_Shader_Constants[reg],memsize)==0) return; - - memcpy(&Pixel_Shader_Constants[reg],data,memsize); - DX8CALL(SetPixelShaderConstant(reg,data,count)); -} -// shader system updates KJM ^ - - -WWINLINE void DX8Wrapper::_Set_DX8_Transform(D3DTRANSFORMSTATETYPE transform,const Matrix4x4& m) -{ - WWASSERT(transform<=D3DTS_WORLD); -#if 0 // (gth) this optimization is breaking generals because they set the transform behind our backs. - if (m!=DX8Transforms[transform]) -#endif - { - DX8Transforms[transform]=m; - SNAPSHOT_SAY(("DX8 - SetTransform %d [%f,%f,%f,%f][%f,%f,%f,%f][%f,%f,%f,%f][%f,%f,%f,%f]",transform,m[0][0],m[0][1],m[0][2],m[0][3],m[1][0],m[1][1],m[1][2],m[1][3],m[2][0],m[2][1],m[2][2],m[2][3],m[3][0],m[3][1],m[3][2],m[3][3])); - DX8_RECORD_MATRIX_CHANGE(); - DX8CALL(SetTransform(transform,(D3DMATRIX*)&m)); - } -} - - -WWINLINE void DX8Wrapper::_Set_DX8_Transform(D3DTRANSFORMSTATETYPE transform,const Matrix3D& m) -{ - WWASSERT(transform<=D3DTS_WORLD); - Matrix4x4 mtx(m); -#if 0 // (gth) this optimization is breaking generals because they set the transform behind our backs. - if (mtx!=DX8Transforms[transform]) -#endif - { - DX8Transforms[transform]=mtx; - SNAPSHOT_SAY(("DX8 - SetTransform %d [%f,%f,%f,%f][%f,%f,%f,%f][%f,%f,%f,%f]",transform,m[0][0],m[0][1],m[0][2],m[0][3],m[1][0],m[1][1],m[1][2],m[1][3],m[2][0],m[2][1],m[2][2],m[2][3])); - DX8_RECORD_MATRIX_CHANGE(); - DX8CALL(SetTransform(transform,(D3DMATRIX*)&m)); - } -} - -WWINLINE void DX8Wrapper::_Get_DX8_Transform(D3DTRANSFORMSTATETYPE transform, Matrix4x4& m) -{ - DX8CALL(GetTransform(transform,(D3DMATRIX*)&m)); -} - -// ---------------------------------------------------------------------------- -// -// Set the index offset for the current index buffer -// -// ---------------------------------------------------------------------------- - -WWINLINE void DX8Wrapper::Set_Index_Buffer_Index_Offset(unsigned offset) -{ - if (render_state.index_base_offset==offset) return; - render_state.index_base_offset=offset; - render_state_changed|=INDEX_BUFFER_CHANGED; -} - -// ---------------------------------------------------------------------------- -// Set the fog settings. This function should be used, rather than setting the -// appropriate renderstates directly, because the shader sets some of the -// renderstates on a per-mesh / per-pass basis depending on global fog states -// (stored in the wrapper) as well as the shader settings. -// This function should be called rarely - once per scene would be appropriate. -// ---------------------------------------------------------------------------- - -WWINLINE void DX8Wrapper::Set_Fog(bool enable, const Vector3 &color, float start, float end) -{ - // Set global states - FogEnable = enable; - FogColor = Convert_Color(color,0.0f); - - // Invalidate the current shader (since the renderstates set by the shader - // depend on the global fog settings as well as the actual shader settings) - ShaderClass::Invalidate(); - - // Set renderstates which are not affected by the shader - Set_DX8_Render_State(D3DRS_FOGSTART, *(DWORD *)(&start)); - Set_DX8_Render_State(D3DRS_FOGEND, *(DWORD *)(&end)); -} - - -WWINLINE void DX8Wrapper::Set_Ambient(const Vector3& color) -{ - Ambient_Color=color; - Set_DX8_Render_State(D3DRS_AMBIENT, DX8Wrapper::Convert_Color(color,0.0f)); -} - -// ---------------------------------------------------------------------------- -// -// Set vertex buffer to be used in the subsequent render calls. If there was -// a vertex buffer being used earlier, release the reference to it. Passing -// NULL just will release the vertex buffer. -// -// ---------------------------------------------------------------------------- - -WWINLINE void DX8Wrapper::Set_DX8_Material(const D3DMATERIAL8* mat) -{ - DX8_RECORD_MATERIAL_CHANGE(); - WWASSERT(mat); - SNAPSHOT_SAY(("DX8 - SetMaterial")); - DX8CALL(SetMaterial(mat)); -} - -WWINLINE void DX8Wrapper::Set_DX8_Light(int index, D3DLIGHT8* light) -{ - if (light) { - DX8_RECORD_LIGHT_CHANGE(); - DX8CALL(SetLight(index,light)); - DX8CALL(LightEnable(index,TRUE)); - CurrentDX8LightEnables[index]=true; - SNAPSHOT_SAY(("DX8 - SetLight %d",index)); - } - else if (CurrentDX8LightEnables[index]) { - DX8_RECORD_LIGHT_CHANGE(); - CurrentDX8LightEnables[index]=false; - DX8CALL(LightEnable(index,FALSE)); - SNAPSHOT_SAY(("DX8 - DisableLight %d",index)); - } -} - -WWINLINE void DX8Wrapper::Set_DX8_Render_State(D3DRENDERSTATETYPE state, unsigned value) -{ - // Can't monitor state changes because setShader call to GERD may change the states! - if (RenderStates[state]==value) return; - -#ifdef MESH_RENDER_SNAPSHOT_ENABLED - if (WW3D::Is_Snapshot_Activated()) { - StringClass value_name(0,true); - Get_DX8_Render_State_Value_Name(value_name,state,value); - SNAPSHOT_SAY(("DX8 - SetRenderState(state: %s, value: %s)", - Get_DX8_Render_State_Name(state), - value_name.str())); - } -#endif - - RenderStates[state]=value; - DX8CALL(SetRenderState( state, value )); - DX8_RECORD_RENDER_STATE_CHANGE(); -} - -WWINLINE void DX8Wrapper::Set_DX8_Clip_Plane(DWORD Index, CONST float* pPlane) -{ - DX8CALL(SetClipPlane( Index, pPlane )); -} - -WWINLINE void DX8Wrapper::Set_DX8_Texture_Stage_State(unsigned stage, D3DTEXTURESTAGESTATETYPE state, unsigned value) -{ - if (stage >= MAX_TEXTURE_STAGES) - { DX8CALL(SetTextureStageState( stage, state, value )); - return; - } - - // Can't monitor state changes because setShader call to GERD may change the states! - if (TextureStageStates[stage][(unsigned int)state]==value) return; -#ifdef MESH_RENDER_SNAPSHOT_ENABLED - if (WW3D::Is_Snapshot_Activated()) { - StringClass value_name(0,true); - Get_DX8_Texture_Stage_State_Value_Name(value_name,state,value); - SNAPSHOT_SAY(("DX8 - SetTextureStageState(stage: %d, state: %s, value: %s)", - stage, - Get_DX8_Texture_Stage_State_Name(state), - value_name.str())); - } -#endif - - TextureStageStates[stage][(unsigned int)state]=value; - DX8CALL(SetTextureStageState( stage, state, value )); - DX8_RECORD_TEXTURE_STAGE_STATE_CHANGE(); -} - -WWINLINE void DX8Wrapper::Set_DX8_Texture(unsigned int stage, IDirect3DBaseTexture8* texture) -{ - if (stage >= MAX_TEXTURE_STAGES) - { DX8CALL(SetTexture(stage, texture)); - return; - } - - if (Textures[stage]==texture) return; - - SNAPSHOT_SAY(("DX8 - SetTexture(%x) ",texture)); - - if (Textures[stage]) Textures[stage]->Release(); - Textures[stage] = texture; - if (Textures[stage]) Textures[stage]->AddRef(); - DX8CALL(SetTexture(stage, texture)); - DX8_RECORD_TEXTURE_CHANGE(); -} - -WWINLINE void DX8Wrapper::_Copy_DX8_Rects( - IDirect3DSurface8* pSourceSurface, - CONST RECT* pSourceRectsArray, - UINT cRects, - IDirect3DSurface8* pDestinationSurface, - CONST POINT* pDestPointsArray -) -{ - DX8CALL(CopyRects( - pSourceSurface, - pSourceRectsArray, - cRects, - pDestinationSurface, - pDestPointsArray)); -} - -WWINLINE Vector4 DX8Wrapper::Convert_Color(unsigned color) -{ - Vector4 col; - col[3]=((color&0xff000000)>>24)/255.0f; - col[0]=((color&0xff0000)>>16)/255.0f; - col[1]=((color&0xff00)>>8)/255.0f; - col[2]=((color&0xff)>>0)/255.0f; -// col=Vector4(1.0f,1.0f,1.0f,1.0f); - return col; -} - -#if 0 -WWINLINE unsigned int DX8Wrapper::Convert_Color(const Vector3& color, const float alpha) -{ - WWASSERT(color.X<=1.0f); - WWASSERT(color.Y<=1.0f); - WWASSERT(color.Z<=1.0f); - WWASSERT(alpha<=1.0f); - WWASSERT(color.X>=0.0f); - WWASSERT(color.Y>=0.0f); - WWASSERT(color.Z>=0.0f); - WWASSERT(alpha>=0.0f); - - return D3DCOLOR_COLORVALUE(color.X,color.Y,color.Z,alpha); -} -WWINLINE unsigned int DX8Wrapper::Convert_Color(const Vector4& color) -{ - WWASSERT(color.X<=1.0f); - WWASSERT(color.Y<=1.0f); - WWASSERT(color.Z<=1.0f); - WWASSERT(color.W<=1.0f); - WWASSERT(color.X>=0.0f); - WWASSERT(color.Y>=0.0f); - WWASSERT(color.Z>=0.0f); - WWASSERT(color.W>=0.0f); - - return D3DCOLOR_COLORVALUE(color.X,color.Y,color.Z,color.W); -} -#else - -// ---------------------------------------------------------------------------- -// -// Convert RGBA color from float vector to 32 bit integer -// Note: Color vector needs to be clamped to [0...1] range! -// -// ---------------------------------------------------------------------------- - -WWINLINE unsigned int DX8Wrapper::Convert_Color(const Vector3& color,float alpha) -{ -#if defined(_MSC_VER) && _MSC_VER < 1300 - const float scale = 255.0; - unsigned int col; - - // Multiply r, g, b and a components (0.0,...,1.0) by 255 and convert to integer. Or the integer values togerher - // such that 32 bit ingeger has AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB. - __asm - { - sub esp,20 // space for a, r, g and b float plus fpu rounding mode - - // Store the fpu rounding mode - - fwait - fstcw [esp+16] // store control word to stack - mov eax,[esp+16] // load it to eax - mov edi,eax // take copy - and eax,~(1024|2048) // mask out certain bits - or eax,(1024|2048) // or with precision control value "truncate" - sub edi,eax // did it change? - jz skip // .. if not, skip - mov [esp],eax // .. change control word - fldcw [esp] -skip: - - // Convert the color - - mov esi,dword ptr color - fld dword ptr[scale] - - fld dword ptr[esi] // r - fld dword ptr[esi+4] // g - fld dword ptr[esi+8] // b - fld dword ptr[alpha] // a - fld st(4) - fmul st(4),st - fmul st(3),st - fmul st(2),st - fmulp st(1),st - fistp dword ptr[esp+0] // a - fistp dword ptr[esp+4] // b - fistp dword ptr[esp+8] // g - fistp dword ptr[esp+12] // r - mov ecx,[esp] // a - mov eax,[esp+4] // b - mov edx,[esp+8] // g - mov ebx,[esp+12] // r - shl ecx,24 // a << 24 - shl ebx,16 // r << 16 - shl edx,8 // g << 8 - or eax,ecx // (a << 24) | b - or eax,ebx // (a << 24) | (r << 16) | b - or eax,edx // (a << 24) | (r << 16) | (g << 8) | b - - fstp st(0) - - // Restore fpu rounding mode - - cmp edi,0 // did we change the value? - je not_changed // nope... skip now... - fwait - fldcw [esp+16]; -not_changed: - add esp,20 - - mov col,eax - } - return col; -#else - return color.Convert_To_ARGB(alpha); -#endif // defined(_MSC_VER) && _MSC_VER < 1300 -} - -// ---------------------------------------------------------------------------- -// -// Clamp color vector to [0...1] range -// -// ---------------------------------------------------------------------------- - -WWINLINE void DX8Wrapper::Clamp_Color(Vector4& color) -{ -#if defined(_MSC_VER) && _MSC_VER < 1300 - if (CPUDetectClass::Has_CMOV_Instruction()) { - __asm - { - mov esi,dword ptr color - - mov edx,0x3f800000 - - mov edi,dword ptr[esi] - mov ebx,edi - sar edi,31 - not edi // mask is now zero if negative value - and edi,ebx - cmp edi,edx // if no less than 1.0 set to 1.0 - cmovnb edi,edx - mov dword ptr[esi],edi - - mov edi,dword ptr[esi+4] - mov ebx,edi - sar edi,31 - not edi // mask is now zero if negative value - and edi,ebx - cmp edi,edx // if no less than 1.0 set to 1.0 - cmovnb edi,edx - mov dword ptr[esi+4],edi - - mov edi,dword ptr[esi+8] - mov ebx,edi - sar edi,31 - not edi // mask is now zero if negative value - and edi,ebx - cmp edi,edx // if no less than 1.0 set to 1.0 - cmovnb edi,edx - mov dword ptr[esi+8],edi - - mov edi,dword ptr[esi+12] - mov ebx,edi - sar edi,31 - not edi // mask is now zero if negative value - and edi,ebx - cmp edi,edx // if no less than 1.0 set to 1.0 - cmovnb edi,edx - mov dword ptr[esi+12],edi - } - return; - } -#endif // defined(_MSC_VER) && _MSC_VER < 1300 - - for (int i=0;i<4;++i) { - float f=(color[i]<0.0f) ? 0.0f : color[i]; - color[i]=(f>1.0f) ? 1.0f : f; - } -} - -// ---------------------------------------------------------------------------- -// -// Convert RGBA color from float vector to 32 bit integer -// -// ---------------------------------------------------------------------------- - -WWINLINE unsigned int DX8Wrapper::Convert_Color(const Vector4& color) -{ - return Convert_Color(reinterpret_cast(color),color[3]); -} - -WWINLINE unsigned int DX8Wrapper::Convert_Color_Clamp(const Vector4& color) -{ - Vector4 clamped_color=color; - DX8Wrapper::Clamp_Color(clamped_color); - return Convert_Color(reinterpret_cast(clamped_color),clamped_color[3]); -} - -#endif - - -WWINLINE void DX8Wrapper::Set_Alpha (const float alpha, unsigned int &color) -{ - unsigned char *component = (unsigned char*) &color; - - component [3] = 255.0f * alpha; -} - -WWINLINE void DX8Wrapper::Get_Render_State(RenderStateStruct& state) -{ - state=render_state; -} - -WWINLINE void DX8Wrapper::Get_Shader(ShaderClass& shader) -{ - shader=render_state.shader; -} - -WWINLINE void DX8Wrapper::Set_Texture(unsigned stage,TextureBaseClass* texture) -{ - WWASSERT(stage<(unsigned int)CurrentCaps->Get_Max_Textures_Per_Pass()); - if (texture==render_state.Textures[stage]) return; - REF_PTR_SET(render_state.Textures[stage],texture); - render_state_changed|=(TEXTURE0_CHANGED<(material)); - render_state_changed|=MATERIAL_CHANGED; -} - -WWINLINE void DX8Wrapper::Set_Shader(const ShaderClass& shader) -{ - if (!ShaderClass::ShaderDirty && ((unsigned&)shader==(unsigned&)render_state.shader)) { - return; - } - render_state.shader=shader; - render_state_changed|=SHADER_CHANGED; -#ifdef MESH_RENDER_SNAPSHOT_ENABLED - StringClass str; -#endif - SNAPSHOT_SAY(("DX8Wrapper::Set_Shader(%s)",shader.Get_Description(str).str())); -} - - -WWINLINE void DX8Wrapper::Set_Transform(D3DTRANSFORMSTATETYPE transform,const Matrix4x4& m) -{ - switch ((int)transform) { - case D3DTS_WORLD: - render_state.world=m.Transpose(); - render_state_changed|=(unsigned)WORLD_CHANGED; - render_state_changed&=~(unsigned)WORLD_IDENTITY; - break; - case D3DTS_VIEW: - render_state.view=m.Transpose(); - render_state_changed|=(unsigned)VIEW_CHANGED; - render_state_changed&=~(unsigned)VIEW_IDENTITY; - break; - case D3DTS_PROJECTION: - { - Matrix4x4 ProjectionMatrix=m.Transpose(); - ZFar=0.0f; - ZNear=0.0f; - DX8CALL(SetTransform(D3DTS_PROJECTION,(D3DMATRIX*)&ProjectionMatrix)); - } - break; - default: - DX8_RECORD_MATRIX_CHANGE(); - Matrix4x4 m2=m.Transpose(); - DX8CALL(SetTransform(transform,(D3DMATRIX*)&m2)); - break; - } -} - -WWINLINE void DX8Wrapper::Set_Transform(D3DTRANSFORMSTATETYPE transform,const Matrix3D& m) -{ - Matrix4x4 m2(m); - switch ((int)transform) { - case D3DTS_WORLD: - render_state.world=m2.Transpose(); - render_state_changed|=(unsigned)WORLD_CHANGED; - render_state_changed&=~(unsigned)WORLD_IDENTITY; - break; - case D3DTS_VIEW: - render_state.view=m2.Transpose(); - render_state_changed|=(unsigned)VIEW_CHANGED; - render_state_changed&=~(unsigned)VIEW_IDENTITY; - break; - default: - DX8_RECORD_MATRIX_CHANGE(); - m2=m2.Transpose(); - DX8CALL(SetTransform(transform,(D3DMATRIX*)&m2)); - break; - } -} - -WWINLINE void DX8Wrapper::Set_World_Identity() -{ - if (render_state_changed&(unsigned)WORLD_IDENTITY) return; - render_state.world.Make_Identity(); - render_state_changed|=(unsigned)WORLD_CHANGED|(unsigned)WORLD_IDENTITY; -} - -WWINLINE void DX8Wrapper::Set_View_Identity() -{ - if (render_state_changed&(unsigned)VIEW_IDENTITY) return; - render_state.view.Make_Identity(); - render_state_changed|=(unsigned)VIEW_CHANGED|(unsigned)VIEW_IDENTITY; -} - -WWINLINE bool DX8Wrapper::Is_World_Identity() -{ - return !!(render_state_changed&(unsigned)WORLD_IDENTITY); -} - -WWINLINE bool DX8Wrapper::Is_View_Identity() -{ - return !!(render_state_changed&(unsigned)VIEW_IDENTITY); -} - -WWINLINE void DX8Wrapper::Get_Transform(D3DTRANSFORMSTATETYPE transform, Matrix4x4& m) -{ - D3DMATRIX mat; - - switch ((int)transform) { - case D3DTS_WORLD: - if (render_state_changed&WORLD_IDENTITY) m.Make_Identity(); - else m=render_state.world.Transpose(); - break; - case D3DTS_VIEW: - if (render_state_changed&VIEW_IDENTITY) m.Make_Identity(); - else m=render_state.view.Transpose(); - break; - default: - DX8CALL(GetTransform(transform,&mat)); - m=*(Matrix4x4*)&mat; - m=m.Transpose(); - break; - } -} - -WWINLINE const D3DLIGHT8& DX8Wrapper::Peek_Light(unsigned index) -{ - return render_state.Lights[index];; -} - -WWINLINE bool DX8Wrapper::Is_Light_Enabled(unsigned index) -{ - return render_state.LightEnable[index]; -} - - -WWINLINE void DX8Wrapper::Set_Render_State(const RenderStateStruct& state) -{ - if (render_state.index_buffer) { - render_state.index_buffer->Release_Engine_Ref(); - } - - if (render_state.vertex_buffer) { - render_state.vertex_buffer->Release_Engine_Ref(); - } - - render_state=state; - render_state_changed=0xffffffff; - - if (render_state.index_buffer) { - render_state.index_buffer->Add_Engine_Ref(); - } - - if (render_state.vertex_buffer) { - render_state.vertex_buffer->Add_Engine_Ref(); - } -} - -WWINLINE void DX8Wrapper::Release_Render_State() -{ - if (render_state.index_buffer) { - render_state.index_buffer->Release_Engine_Ref(); - } - - if (render_state.vertex_buffer) { - render_state.vertex_buffer->Release_Engine_Ref(); - } - - REF_PTR_RELEASE(render_state.vertex_buffer); - REF_PTR_RELEASE(render_state.index_buffer); - REF_PTR_RELEASE(render_state.material); - for (unsigned i=0;i. +*/ + + /*********************************************************************************************** + *** 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/wwshade/shdlib.h $* + * + * Org Author:: Kenny Mitchell + * * + * $Author:: Kenny_m + * + * $Modtime:: 07/01/02 9:58p $* + * * + * $Revision:: 1 $* + * * + *---------------------------------------------------------------------------------------------* + * Functions: * + * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +#ifndef SHDLIB_H +#define SHDLIB_H + +// TheSuperHackers @compile Removes the unused WWShade code. (#596) +// If there is a desire to revive this, then the WWShade library needs to be re-added. + +#ifdef USE_WWSHADE + +extern void SHD_Init(); +extern void SHD_Shutdown(); +extern void SHD_Init_Shaders(); +extern void SHD_Shutdown_Shaders(); +extern void SHD_Flush(); +extern void SHD_Register_Loader(); + +#define SHD_INIT SHD_Init() +#define SHD_SHUTDOWN SHD_Shutdown() +#define SHD_INIT_SHADERS SHD_Init_Shaders() +#define SHD_SHUTDOWN_SHADERS SHD_Shutdown_Shaders() +#define SHD_FLUSH SHD_Flush() +#define SHD_REG_LOADER SHD_Register_Loader() + +#else // USE_WWSHADE + +#define SHD_INIT +#define SHD_SHUTDOWN +#define SHD_INIT_SHADERS +#define SHD_SHUTDOWN_SHADERS +#define SHD_FLUSH +#define SHD_REG_LOADER + +#endif // USE_WWSHADE + + +#endif // SHDLIB_H \ No newline at end of file diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp index 80c88a34e2..d33dae7adf 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp @@ -25,6 +25,7 @@ #include "d3d8.h" #include "d3dx8math.h" #include "statistics.h" +#include bool SortingRendererClass::_EnableTriangleDraw=true; unsigned DEFAULT_SORTING_POLY_COUNT = 16384; // (count * 3) must be less than 65536 @@ -338,7 +339,7 @@ void SortingRendererClass::Insert_Triangles( WWASSERT( ((state->sorting_state.index_buffer_type==BUFFER_TYPE_SORTING || state->sorting_state.index_buffer_type==BUFFER_TYPE_DYNAMIC_SORTING) && - (state->sorting_state.vertex_buffer_type==BUFFER_TYPE_SORTING || state->sorting_state.vertex_buffer_type==BUFFER_TYPE_DYNAMIC_SORTING))); + (state->sorting_state.vertex_buffer_types[0] == BUFFER_TYPE_SORTING || state->sorting_state.vertex_buffer_types[0] == BUFFER_TYPE_DYNAMIC_SORTING))); state->bounding_sphere=bounding_sphere; @@ -347,7 +348,7 @@ void SortingRendererClass::Insert_Triangles( state->min_vertex_index=min_vertex_index; state->vertex_count=vertex_count; - SortingVertexBufferClass* vertex_buffer=static_cast(state->sorting_state.vertex_buffer); + SortingVertexBufferClass* vertex_buffer=static_cast(state->sorting_state.vertex_buffers[0]); WWASSERT(vertex_buffer); WWASSERT(state->vertex_count<=vertex_buffer->Get_Vertex_Count()); @@ -421,10 +422,12 @@ void SortingRendererClass::Insert_Triangles( void Release_Refs(SortingNodeStruct* state) { int i; - REF_PTR_RELEASE(state->sorting_state.vertex_buffer); + for (i = 0; i < MAX_VERTEX_STREAMS; ++i) { + REF_PTR_RELEASE(state->sorting_state.vertex_buffers[i]); + } REF_PTR_RELEASE(state->sorting_state.index_buffer); REF_PTR_RELEASE(state->sorting_state.material); - for (i=0;iGet_Max_Textures_Per_Pass();++i) + for (i = 0; i < DX8Wrapper::Get_Current_Caps()->Get_Max_Textures_Per_Pass(); ++i) { REF_PTR_RELEASE(state->sorting_state.Textures[i]); } @@ -544,7 +547,7 @@ void SortingRendererClass::Flush_Sorting_Pool() float* vertex_z_array=Get_Vertex_Z_Array(state->vertex_count); VertexFormatXYZNDUV2* src_verts=NULL; - SortingVertexBufferClass* vertex_buffer=static_cast(state->sorting_state.vertex_buffer); + SortingVertexBufferClass* vertex_buffer=static_cast(state->sorting_state.vertex_buffers[0]); WWASSERT(vertex_buffer); src_verts=vertex_buffer->VertexBuffer; WWASSERT(src_verts); @@ -696,42 +699,47 @@ void SortingRendererClass::Flush_Sorting_Pool() void SortingRendererClass::Flush() { + WWPROFILE("SortingRenderer::Flush"); Matrix4x4 old_view; Matrix4x4 old_world; - DX8Wrapper::Get_Transform(D3DTS_VIEW,old_view); - DX8Wrapper::Get_Transform(D3DTS_WORLD,old_world); + DX8Wrapper::Get_Transform(D3DTS_VIEW, old_view); + DX8Wrapper::Get_Transform(D3DTS_WORLD, old_world); - while (SortingNodeStruct* state=sorted_list.Head()) { + while (SortingNodeStruct* state = sorted_list.Head()) { state->Remove(); - - if ((state->sorting_state.index_buffer_type==BUFFER_TYPE_SORTING || state->sorting_state.index_buffer_type==BUFFER_TYPE_DYNAMIC_SORTING) && - (state->sorting_state.vertex_buffer_type==BUFFER_TYPE_SORTING || state->sorting_state.vertex_buffer_type==BUFFER_TYPE_DYNAMIC_SORTING)) { + + if ((state->sorting_state.index_buffer_type == BUFFER_TYPE_SORTING || state->sorting_state.index_buffer_type == BUFFER_TYPE_DYNAMIC_SORTING) && + (state->sorting_state.vertex_buffer_types[0] == BUFFER_TYPE_SORTING || state->sorting_state.vertex_buffer_types[0] == BUFFER_TYPE_DYNAMIC_SORTING)) { Insert_To_Sorting_Pool(state); } else { DX8Wrapper::Set_Render_State(state->sorting_state); - DX8Wrapper::Draw_Triangles(state->start_index,state->polygon_count,state->min_vertex_index,state->vertex_count); + DX8Wrapper::Draw_Triangles(state->start_index, state->polygon_count, state->min_vertex_index, state->vertex_count); DX8Wrapper::Release_Render_State(); Release_Refs(state); clean_list.Add_Head(state); } } + bool old_enable = DX8Wrapper::_Is_Triangle_Draw_Enabled(); + DX8Wrapper::_Enable_Triangle_Draw(_EnableTriangleDraw); Flush_Sorting_Pool(); + DX8Wrapper::_Enable_Triangle_Draw(old_enable); - DX8Wrapper::Set_Index_Buffer(0,0); + DX8Wrapper::Set_Index_Buffer(0, 0); DX8Wrapper::Set_Vertex_Buffer(0); - total_sorting_vertices=0; + total_sorting_vertices = 0; DynamicIBAccessClass::_Reset(false); DynamicVBAccessClass::_Reset(false); - DX8Wrapper::Set_Transform(D3DTS_VIEW,old_view); - DX8Wrapper::Set_Transform(D3DTS_WORLD,old_world); + DX8Wrapper::Set_Transform(D3DTS_VIEW, old_view); + DX8Wrapper::Set_Transform(D3DTS_WORLD, old_world); } + // ---------------------------------------------------------------------------- void SortingRendererClass::Deinit() @@ -803,7 +811,7 @@ void SortingRendererClass::Insert_VolumeParticle( WWASSERT( ((state->sorting_state.index_buffer_type==BUFFER_TYPE_SORTING || state->sorting_state.index_buffer_type==BUFFER_TYPE_DYNAMIC_SORTING) && - (state->sorting_state.vertex_buffer_type==BUFFER_TYPE_SORTING || state->sorting_state.vertex_buffer_type==BUFFER_TYPE_DYNAMIC_SORTING))); + (state->sorting_state.vertex_buffer_types[0] ==BUFFER_TYPE_SORTING || state->sorting_state.vertex_buffer_types[0] ==BUFFER_TYPE_DYNAMIC_SORTING))); state->bounding_sphere=bounding_sphere; state->start_index=start_index; @@ -811,7 +819,7 @@ void SortingRendererClass::Insert_VolumeParticle( state->polygon_count=polygon_count * layerCount;//THIS IS VOLUME_PARTICLE SPECIFIC state->vertex_count=vertex_count * layerCount;//THIS IS VOLUME_PARTICLE SPECIFIC - SortingVertexBufferClass* vertex_buffer=static_cast(state->sorting_state.vertex_buffer); + SortingVertexBufferClass* vertex_buffer=static_cast(state->sorting_state.vertex_buffers[0]); WWASSERT(vertex_buffer); WWASSERT(state->vertex_count<=vertex_buffer->Get_Vertex_Count()); diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texproject.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/texproject.cpp index ef95a7f6ad..914d664eb0 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texproject.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/texproject.cpp @@ -1111,45 +1111,56 @@ bool TexProjectClass::Compute_Ortho_Projection *=============================================================================================*/ bool TexProjectClass::Compute_Texture ( - RenderObjClass * model, - SpecialRenderInfoClass * context + RenderObjClass* model, + SpecialRenderInfoClass* context ) { - if ((model == NULL) || (context == NULL)) + if ((model == NULL) || (context == NULL)) { return false; } /* ** Render to texture */ - TextureClass * rtarget = Peek_Render_Target(); + TextureClass* rtarget = NULL; + ZTextureClass* ztarget = NULL; - if (rtarget != NULL) + Peek_Render_Target(&rtarget, &ztarget); + + if (rtarget != NULL) { + // set projector for render context KJM + context->Texture_Projector = this; /* ** Set the render target */ - DX8Wrapper::Set_Render_Target(rtarget); + DX8Wrapper::Set_Render_Target_With_Z(rtarget, ztarget); /* ** Set up the camera */ Configure_Camera(context->Camera); - + /* ** Render the object */ - Vector3 color(0.0f,0.0f,0.0f); + Vector3 color(0.0f, 0.0f, 0.0f); if (Get_Flag(ADDITIVE) == false) { - color.Set(1.0f,1.0f,1.0f); + color.Set(1.0f, 1.0f, 1.0f); } - WW3D::Begin_Render(true,true,color); - WW3D::Render(*model,*context); + bool zclear = ztarget != NULL; + + bool snapshot = WW3D::Is_Snapshot_Activated(); + SNAPSHOT_SAY(("TexProjectCLass::Begin_Render()")); + WW3D::Begin_Render(true, zclear, color); // false to zclear as we don't have z-buffer + WW3D::Render(*model, *context); + SNAPSHOT_SAY(("TexProjectCLass::End_Render()")); WW3D::End_Render(false); + WW3D::Activate_Snapshot(snapshot); // End_Render() ends the shapsnot, so restore the state - DX8Wrapper::Set_Render_Target((IDirect3DSurface8 *)NULL); + DX8Wrapper::Set_Render_Target((IDirect3DSurface8*)NULL); } @@ -1218,12 +1229,23 @@ void TexProjectClass::Set_Render_Target * * * HISTORY: * * 4/5/2001 gth : Created. * + * 5/16/2002 kjm : Added optional custom zbuffer * *=============================================================================================*/ TextureClass* TexProjectClass::Peek_Render_Target ( - void + TextureClass** rtarget, + ZTextureClass** ztarget ) { + // some uses of this function just want to know if a render target exists + if (rtarget == NULL) return RenderTarget; + + *rtarget = RenderTarget; + + // don't set if pointer isn't supplied + if (ztarget != NULL) + *ztarget = DepthStencilTarget; + return RenderTarget; } diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texproject.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/texproject.h index 994fec4432..d37d28eaa9 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texproject.h +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/texproject.h @@ -58,7 +58,7 @@ class SpecialRenderInfoClass; class RenderObjClass; class MaterialPassClass; class SurfaceClass; - +class ZTextureClass; /** @@ -156,7 +156,7 @@ class TexProjectClass : public ProjectorClass, public CullableClass, public Mult bool Needs_Render_Target(void); void Set_Render_Target(TextureClass * render_target); - TextureClass * Peek_Render_Target(void); + TextureClass* Peek_Render_Target(TextureClass** rtarget = NULL, ZTextureClass** ztarget = NULL); bool Compute_Texture(RenderObjClass * model,SpecialRenderInfoClass * context); @@ -213,7 +213,8 @@ class TexProjectClass : public ProjectorClass, public CullableClass, public Mult MaterialPassClass * MaterialPass; MatrixMapperClass * Mapper1; TextureClass * RenderTarget; - + ZTextureClass* DepthStencilTarget; + /* ** I have to remember all of these values so that I can properly initialize a CameraClass ** when we do render-to-texture. Some day we will merge CameraClass and ProjectorClass. diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texture.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/texture.cpp index 2ddbdb085e..1abc2ef03e 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texture.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/texture.cpp @@ -1,5 +1,5 @@ /* -** Command & Conquer Generals(tm) +** Command & Conquer Generals Zero Hour(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify @@ -24,15 +24,19 @@ * * * $Archive:: /Commando/Code/ww3d2/texture.cpp $* * * - * $Author:: Jani_p $* + * $Org Author:: Steve_t $* * * - * $Modtime:: 8/29/01 7:06p $* + * Author : Kenny Mitchell * * * - * $Revision:: 65 $* + * $Modtime:: 08/05/02 1:27p $* * * + * $Revision:: 85 $* + * * + * 06/27/02 KM Texture class abstraction * + * 08/05/02 KM Texture class redesign (revisited) *---------------------------------------------------------------------------------------------* * Functions: * - * FileListTextureClass::Load_Frame_Surface -- Load source texture * + * FileListTextureClass::Load_Frame_Surface -- Load source texture * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "texture.h" @@ -52,6 +56,13 @@ #include "dx8caps.h" #include "dx8texman.h" #include "meshmatdesc.h" +#include "texturethumbnail.h" +#include "wwprofile.h" + + //#pragma optimize("", off) + //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") + +const unsigned DEFAULT_INACTIVATION_TIME = 20000; /* ** Definitions of static members: @@ -59,337 +70,207 @@ static unsigned unused_texture_id; -// ---------------------------------------------------------------------------- - -static int Calculate_Texture_Memory_Usage(const TextureClass* texture,int red_factor=0) -{ - // Set performance statistics - - int size=0; - IDirect3DTexture8* d3d_texture=const_cast(texture)->Peek_D3D_Texture(); - if (!d3d_texture) return 0; - for (unsigned i=red_factor;iGetLevelCount();++i) { - D3DSURFACE_DESC desc; - DX8_ErrorCode(d3d_texture->GetLevelDesc(i,&desc)); - size+=desc.Size; - } - return size; -} +// This throttles submissions to the background texture loading queue. +static unsigned TexturesAppliedPerFrame; +const unsigned MAX_TEXTURES_APPLIED_PER_FRAME = 2; -/************************************************************************* -** TextureClass -*************************************************************************/ -TextureClass::TextureClass(unsigned width, unsigned height, WW3DFormat format, MipCountType mip_level_count, PoolType pool,bool rendertarget) - : +/*! + * KM General base constructor for texture classes + */ +TextureBaseClass::TextureBaseClass +( + unsigned int width, + unsigned int height, + enum MipCountType mip_level_count, + enum PoolType pool, + bool rendertarget, + bool reducible +) + : MipLevelCount(mip_level_count), D3DTexture(NULL), + Initialized(false), + Name(""), + FullPath(""), texture_id(unused_texture_id++), - Initialized(true), - Filter(mip_level_count), - MipLevelCount(mip_level_count), - Pool(pool), - Dirty(false), IsLightmap(false), - IsProcedural(true), - Name(""), - TextureFormat(format), + IsProcedural(false), + IsReducible(reducible), IsCompressionAllowed(false), - TextureLoadTask(NULL), + InactivationTime(0), + ExtendedInactivationTime(0), + LastInactivationSyncTime(0), + LastAccessed(0), Width(width), - Height(height) + Height(height), + Pool(pool), + Dirty(false), + TextureLoadTask(NULL), + ThumbnailLoadTask(NULL), + HSVShift(0.0f, 0.0f, 0.0f) { - switch (format) - { - case WW3D_FORMAT_DXT1: - case WW3D_FORMAT_DXT2: - case WW3D_FORMAT_DXT3: - case WW3D_FORMAT_DXT4: - case WW3D_FORMAT_DXT5: - IsCompressionAllowed=true; - break; - default : break; - } - - D3DPOOL d3dpool=(D3DPOOL)0; - switch(pool) - { - case POOL_DEFAULT : d3dpool=D3DPOOL_DEFAULT; break; - case POOL_MANAGED : d3dpool=D3DPOOL_MANAGED; break; - case POOL_SYSTEMMEM : d3dpool=D3DPOOL_SYSTEMMEM; break; - default: WWASSERT(0); - } - D3DTexture = DX8Wrapper::_Create_DX8_Texture(width, height, format, mip_level_count,d3dpool,rendertarget); - if (pool==POOL_DEFAULT) - { - Dirty=true; - DX8TextureTrackerClass *track=W3DNEW DX8TextureTrackerClass - ( - width, - height, - format, - mip_level_count, - this, - rendertarget - ); - DX8TextureManagerClass::Add(track); - } - LastAccessed=WW3D::Get_Sync_Time(); } -// ---------------------------------------------------------------------------- -TextureClass::TextureClass -( - const char *name, - const char *full_path, - MipCountType mip_level_count, - WW3DFormat texture_format, - bool allow_compression) - : - D3DTexture(NULL), - texture_id(unused_texture_id++), - Initialized(false), - Filter(mip_level_count), - MipLevelCount(mip_level_count), - Pool(POOL_MANAGED), - Dirty(false), - IsLightmap(false), - IsProcedural(false), - TextureFormat(texture_format), - IsCompressionAllowed(allow_compression), - TextureLoadTask(NULL), - Width(0), - Height(0) +//********************************************************************************************** +//! Base texture class destructor +/*! KJM +*/ +TextureBaseClass::~TextureBaseClass(void) { - switch (TextureFormat) - { - case WW3D_FORMAT_DXT1: - case WW3D_FORMAT_DXT2: - case WW3D_FORMAT_DXT3: - case WW3D_FORMAT_DXT4: - case WW3D_FORMAT_DXT5: - IsCompressionAllowed=true; - break; - case WW3D_FORMAT_U8V8: // Bumpmap - case WW3D_FORMAT_L6V5U5: // Bumpmap - case WW3D_FORMAT_X8L8V8U8: // Bumpmap - // If requesting bumpmap format that isn't available we'll just return the surface in whatever color - // format the texture file is in. (This is illegal case, the format support should always be queried - // before creating a bump texture!) - if (!DX8Wrapper::Get_Current_Caps()->Support_Texture_Format(TextureFormat)) - { - TextureFormat=WW3D_FORMAT_UNKNOWN; - } - // If bump format is valid, make sure compression is not allowed so that we don't even attempt to load - // from a compressed file (quality isn't good enough for bump map). Also disable mipmapping. - else - { - IsCompressionAllowed=false; - MipLevelCount=MIP_LEVELS_1; - Filter.Set_Mip_Mapping(TextureFilterClass::FILTER_TYPE_NONE); - } - break; - default: break; - } - - WWASSERT_PRINT(name && name[0], "TextureClass CTor: NULL or empty texture name"); - int len=strlen(name); - for (int i=0;iRelease(); + D3DTexture = NULL; } - LastAccessed=WW3D::Get_Sync_Time(); + + DX8TextureManagerClass::Remove(this); } -// ---------------------------------------------------------------------------- -TextureClass::TextureClass(SurfaceClass *surface, MipCountType mip_level_count) - : - D3DTexture(NULL), - texture_id(unused_texture_id++), - Initialized(true), - Filter(mip_level_count), - MipLevelCount(mip_level_count), - Pool(POOL_MANAGED), - Dirty(false), - IsLightmap(false), - Name(""), - IsProcedural(true), - TextureFormat(surface->Get_Surface_Format()), - IsCompressionAllowed(false), - TextureLoadTask(NULL), - Width(0), - Height(0) + + +//********************************************************************************************** +//! Invalidate old unused textures +/*! +*/ +void TextureBaseClass::Invalidate_Old_Unused_Textures(unsigned invalidation_time_override) { - SurfaceClass::SurfaceDescription sd; - surface->Get_Description(sd); - Width=sd.Width; - Height=sd.Height; - switch (sd.Format) - { - case WW3D_FORMAT_DXT1: - case WW3D_FORMAT_DXT2: - case WW3D_FORMAT_DXT3: - case WW3D_FORMAT_DXT4: - case WW3D_FORMAT_DXT5: - IsCompressionAllowed=true; - break; - default: break; + // (gth) If thumbnails are not enabled, then we don't run this code. + if (WW3D::Get_Thumbnail_Enabled() == false) { + return; } - - D3DTexture = DX8Wrapper::_Create_DX8_Texture(surface->Peek_D3D_Surface(), mip_level_count); - LastAccessed=WW3D::Get_Sync_Time(); -} -// ---------------------------------------------------------------------------- + // Zero the texture apply count in this function because this is called every frame...(this wasn't in E&B main branch KJM) + TexturesAppliedPerFrame = 0; -TextureClass::TextureClass(IDirect3DTexture8* d3d_texture) - : - D3DTexture(d3d_texture), - texture_id(unused_texture_id++), - Initialized(true), - Filter((MipCountType)d3d_texture->GetLevelCount()), - MipLevelCount((MipCountType)d3d_texture->GetLevelCount()), - Pool(POOL_MANAGED), - Dirty(false), - IsLightmap(false), - Name(""), - IsProcedural(true), - IsCompressionAllowed(false), - TextureLoadTask(NULL), - Width(0), - Height(0) -{ - D3DTexture->AddRef(); - IDirect3DSurface8* surface; - DX8_ErrorCode(Peek_D3D_Texture()->GetSurfaceLevel(0,&surface)); - D3DSURFACE_DESC d3d_desc; - ::ZeroMemory(&d3d_desc, sizeof(D3DSURFACE_DESC)); - DX8_ErrorCode(surface->GetDesc(&d3d_desc)); - Width=d3d_desc.Width; - Height=d3d_desc.Height; - TextureFormat=D3DFormat_To_WW3DFormat(d3d_desc.Format); - switch (TextureFormat) + unsigned synctime = WW3D::Get_Sync_Time(); + HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash()); + // Loop through all the textures in the manager + + for (ite.First(); !ite.Is_Done(); ite.Next()) { - case WW3D_FORMAT_DXT1: - case WW3D_FORMAT_DXT2: - case WW3D_FORMAT_DXT3: - case WW3D_FORMAT_DXT4: - case WW3D_FORMAT_DXT5: - IsCompressionAllowed=true; - break; - default: break; - } + TextureClass* tex = ite.Peek_Value(); + + // Consider invalidating if texture has been initialized and defines inactivation time + if (tex->Initialized && tex->InactivationTime) + { + unsigned age = synctime - tex->LastAccessed; - LastAccessed=WW3D::Get_Sync_Time(); + if (invalidation_time_override) + { + if (age > invalidation_time_override) + { + tex->Invalidate(); + tex->LastInactivationSyncTime = synctime; + } + } + else + { + // Not used in the last n milliseconds? + if (age > (tex->InactivationTime + tex->ExtendedInactivationTime)) + { + tex->Invalidate(); + tex->LastInactivationSyncTime = synctime; + } + } + } + } } -// ---------------------------------------------------------------------------- -TextureClass::~TextureClass(void) + + + +//********************************************************************************************** +//! Invalidate this texture +/*! +*/ +void TextureBaseClass::Invalidate() { - TextureLoadTaskClass::Release_Instance(TextureLoadTask); - TextureLoadTask=NULL; + if (TextureLoadTask) { + return; + } + if (ThumbnailLoadTask) { + return; + } - if (!Initialized) { - WWDEBUG_SAY(("Warning: Texture %s was loaded but never used",Get_Texture_Name().str())); + // Don't invalidate procedural textures + if (IsProcedural) { + return; } - if (D3DTexture) { + if (D3DTexture) + { D3DTexture->Release(); D3DTexture = NULL; } - DX8TextureManagerClass::Remove(this); -} -// ---------------------------------------------------------------------------- + Initialized = false; -void TextureClass::Init() -{ - // If the texture has already been initialised we should exit now - if (Initialized) return; + LastAccessed = WW3D::Get_Sync_Time(); + /* was battlefield version// If the texture has already been initialised we should exit now + if (Initialized) return; - TextureLoader::Add_Load_Task(this); - LastAccessed=WW3D::Get_Sync_Time(); -} + WWPROFILE(("TextureClass::Init()")); -void TextureClass::Invalidate() -{ - // Don't invalidate procedural textures - if (IsProcedural) return; + // If the texture has recently been inactivated, increase the inactivation time (this texture obviously + // should not have been inactivated yet). - // Don't invalidate missing texture - if (Is_Missing_Texture()) return; + if (InactivationTime && LastInactivationSyncTime) { + if ((WW3D::Get_Sync_Time()-LastInactivationSyncTime)Release(); - D3DTexture = NULL; - } + if (ThumbnailLoadTask) + { + return; + } + + // Don't invalidate procedural textures + if (IsProcedural) + { + return; + } + + if (D3DTexture) + { + D3DTexture->Release(); + D3DTexture = NULL; + } - if (!WW3D::Is_Texturing_Enabled()) { - Initialized=true; - D3DTexture=0; - } - else if (WW3D::Get_Thumbnail_Enabled()==false || MipLevelCount==MIP_LEVELS_1) - { - Initialized=true; - D3DTexture=0; - TextureLoader::Request_High_Priority_Loading(this,MipLevelCount); - } - else { Initialized=false; - Load_Locked_Surface(); - } + + LastAccessed=WW3D::Get_Sync_Time();*/ } //********************************************************************************************** //! Returns a pointer to the d3d texture -/*! +/*! */ -IDirect3DBaseTexture8 * TextureClass::Peek_D3D_Base_Texture() const -{ - LastAccessed=WW3D::Get_Sync_Time(); - return D3DTexture; +IDirect3DBaseTexture8* TextureBaseClass::Peek_D3D_Base_Texture() const +{ + LastAccessed = WW3D::Get_Sync_Time(); + return D3DTexture; } //********************************************************************************************** //! Set the d3d texture pointer. Handles ref counts properly. -/*! +/*! */ -void TextureClass::Set_D3D_Base_Texture(IDirect3DBaseTexture8* tex) -{ +void TextureBaseClass::Set_D3D_Base_Texture(IDirect3DBaseTexture8* tex) +{ // (gth) Generals does stuff directly with the D3DTexture pointer so lets // reset the access timer whenever someon messes with this pointer. - LastAccessed=WW3D::Get_Sync_Time(); - + LastAccessed = WW3D::Get_Sync_Time(); + if (D3DTexture != NULL) { D3DTexture->Release(); } @@ -399,262 +280,241 @@ void TextureClass::Set_D3D_Base_Texture(IDirect3DBaseTexture8* tex) } } -// ---------------------------------------------------------------------------- -void TextureClass::Load_Locked_Surface() +//********************************************************************************************** +//! Load locked surface +/*! +*/ +void TextureBaseClass::Load_Locked_Surface() { + WWPROFILE(("TextureClass::Load_Locked_Surface()")); if (D3DTexture) D3DTexture->Release(); - D3DTexture=0; + D3DTexture = 0; TextureLoader::Request_Thumbnail(this); - Initialized=false; + Initialized = false; } -// ---------------------------------------------------------------------------- -bool TextureClass::Is_Missing_Texture() +//********************************************************************************************** +//! Is missing texture +/*! +*/ +bool TextureBaseClass::Is_Missing_Texture() { bool flag = false; - IDirect3DTexture8 *missing_texture = MissingTexture::_Get_Missing_Texture(); - - if(D3DTexture == missing_texture) + IDirect3DBaseTexture8* missing_texture = MissingTexture::_Get_Missing_Texture(); + + if (D3DTexture == missing_texture) flag = true; - if(missing_texture) + if (missing_texture) + { missing_texture->Release(); - - return flag; -} - -// ---------------------------------------------------------------------------- - -void TextureClass::Set_Texture_Name(const char * name) -{ - Name=name; -} - -// ---------------------------------------------------------------------------- - -unsigned int TextureClass::Get_Mip_Level_Count(void) -{ - if (!D3DTexture) { - WWASSERT_PRINT(0, "Get_Mip_Level_Count: D3DTexture is NULL!"); - return 0; } - return D3DTexture->GetLevelCount(); + return flag; } -// ---------------------------------------------------------------------------- -void TextureClass::Get_Level_Description(SurfaceClass::SurfaceDescription &surface_desc, unsigned int level) +//********************************************************************************************** +//! Set texture name +/*! +*/ +void TextureBaseClass::Set_Texture_Name(const char* name) { - if (!D3DTexture) { - WWASSERT_PRINT(0, "Get_Surface_Description: D3DTexture is NULL!"); - } - - D3DSURFACE_DESC d3d_surf_desc; - DX8_ErrorCode(Peek_D3D_Texture()->GetLevelDesc(level, &d3d_surf_desc)); - surface_desc.Format = D3DFormat_To_WW3DFormat(d3d_surf_desc.Format); - surface_desc.Height = d3d_surf_desc.Height; - surface_desc.Width = d3d_surf_desc.Width; + Name = name; } -// ---------------------------------------------------------------------------- -SurfaceClass *TextureClass::Get_Surface_Level(unsigned int level) -{ - IDirect3DSurface8 *d3d_surface = NULL; - DX8_ErrorCode(Peek_D3D_Texture()->GetSurfaceLevel(level, &d3d_surface)); - SurfaceClass *surface = W3DNEW SurfaceClass(d3d_surface); - d3d_surface->Release(); - return surface; -} -// ---------------------------------------------------------------------------- -unsigned int TextureClass::Get_Priority(void) +//********************************************************************************************** +//! Get priority +/*! +*/ +unsigned int TextureBaseClass::Get_Priority(void) { - if (!D3DTexture) { + if (!D3DTexture) + { WWASSERT_PRINT(0, "Get_Priority: D3DTexture is NULL!"); return 0; } +#ifndef _XBOX return D3DTexture->GetPriority(); +#else + return 0; +#endif } -// ---------------------------------------------------------------------------- -unsigned int TextureClass::Set_Priority(unsigned int priority) +//********************************************************************************************** +//! Set priority +/*! +*/ +unsigned int TextureBaseClass::Set_Priority(unsigned int priority) { - if (!D3DTexture) { + if (!D3DTexture) + { WWASSERT_PRINT(0, "Set_Priority: D3DTexture is NULL!"); return 0; } +#ifndef _XBOX return D3DTexture->SetPriority(priority); +#else + return 0; +#endif } -unsigned TextureClass::Get_Reduction() const + +//********************************************************************************************** +//! Get reduction mip levels +/*! +*/ +unsigned TextureBaseClass::Get_Reduction() const { - if (MipLevelCount==MIP_LEVELS_1) return 0; + // don't reduce if the texture is too small already or + // has no mip map levels + if (MipLevelCount == MIP_LEVELS_1) return 0; + if (Width <= 32 || Height <= 32) return 0; - int reduction=WW3D::Get_Texture_Reduction(); - if (MipLevelCount && reduction>MipLevelCount) { - reduction=MipLevelCount; + int reduction = WW3D::Get_Texture_Reduction(); + + // 'large texture extra reduction' causes textures above 256x256 to be reduced one more step. + if (WW3D::Is_Large_Texture_Extra_Reduction_Enabled() && (Width > 256 || Height > 256)) { + reduction++; + } + if (MipLevelCount && reduction > MipLevelCount) { + reduction = MipLevelCount; } return reduction; } -// ---------------------------------------------------------------------------- - -void TextureClass::Apply(unsigned int stage) -{ - if (!Initialized) - { - Init(); - } - LastAccessed=WW3D::Get_Sync_Time(); - DX8_RECORD_TEXTURE(this); - // Set texture itself - if (WW3D::Is_Texturing_Enabled()) - { - DX8Wrapper::Set_DX8_Texture(stage, D3DTexture); - } - else - { - DX8Wrapper::Set_DX8_Texture(stage, NULL); - } - - Filter.Apply(stage); -} - -// ---------------------------------------------------------------------------- - -void TextureClass::Apply_Null(unsigned int stage) +//********************************************************************************************** +//! Apply NULL texture state +/*! +*/ +void TextureBaseClass::Apply_Null(unsigned int stage) { // This function sets the render states for a "NULL" texture DX8Wrapper::Set_DX8_Texture(stage, NULL); } // ---------------------------------------------------------------------------- - -void TextureClass::Apply_New_Surface(bool initialized) -{ - if (D3DTexture) D3DTexture->Release(); - D3DTexture=TextureLoadTask->Peek_D3D_Texture(); - D3DTexture->AddRef(); - if (initialized) Initialized=true; - - WWASSERT(D3DTexture); - IDirect3DSurface8* surface; - DX8_ErrorCode(Peek_D3D_Texture()->GetSurfaceLevel(0,&surface)); - D3DSURFACE_DESC d3d_desc; - ::ZeroMemory(&d3d_desc, sizeof(D3DSURFACE_DESC)); - DX8_ErrorCode(surface->GetDesc(&d3d_desc)); -// if (TextureFormat==WW3D_FORMAT_UNKNOWN) { - TextureFormat=D3DFormat_To_WW3DFormat(d3d_desc.Format); - Width=d3d_desc.Width; - Height=d3d_desc.Height; -// } -// else { -// WWASSERT(D3DFormat_To_WW3DFormat(d3d_desc.Format)==TextureFormat); -// } - surface->Release(); -} - +// Setting HSV_Shift value is always relative to the original texture. This function invalidates the +// texture surface and causes the texture to be reloaded. For thumbnailable textures, the hue shifting +// is done in the background loading thread. // ---------------------------------------------------------------------------- - -unsigned TextureClass::Get_Texture_Memory_Usage() const +void TextureBaseClass::Set_HSV_Shift(const Vector3& hsv_shift) { - if (/*!ReductionEnabled || */!Initialized) return Calculate_Texture_Memory_Usage(this,0); -// unsigned reduction=WW3D::Get_Texture_Reduction(); -// if (CurrentReductionFactor>reduction) reduction=CurrentReductionFactor; - return Calculate_Texture_Memory_Usage(this,0);//reduction); + Invalidate(); + HSVShift = hsv_shift; } -// ---------------------------------------------------------------------------- - -int TextureClass::_Get_Total_Locked_Surface_Size() +//********************************************************************************************** +//! Get total locked surface size +/*! KM +*/ +int TextureBaseClass::_Get_Total_Locked_Surface_Size() { - int total_locked_surface_size=0; + int total_locked_surface_size = 0; - HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash()); + HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash()); // Loop through all the textures in the manager - for (ite.First ();!ite.Is_Done();ite.Next ()) { - + for (ite.First(); !ite.Is_Done(); ite.Next()) + { // Get the current texture - TextureClass* tex=ite.Peek_Value(); - if (!tex->Initialized) { -// total_locked_surface_size+=tex->Get_Non_Reduced_Texture_Memory_Usage(); - total_locked_surface_size+=tex->Get_Texture_Memory_Usage(); + TextureBaseClass* tex = ite.Peek_Value(); + if (!tex->Initialized) + { + total_locked_surface_size += tex->Get_Texture_Memory_Usage(); } } return total_locked_surface_size; } -// ---------------------------------------------------------------------------- - -int TextureClass::_Get_Total_Texture_Size() +//********************************************************************************************** +//! Get total texture size +/*! KM +*/ +int TextureBaseClass::_Get_Total_Texture_Size() { - int total_texture_size=0; + int total_texture_size = 0; - HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash()); + HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash()); // Loop through all the textures in the manager - for (ite.First ();!ite.Is_Done();ite.Next ()) { + for (ite.First(); !ite.Is_Done(); ite.Next()) + { // Get the current texture - TextureClass* tex=ite.Peek_Value(); - total_texture_size+=tex->Get_Texture_Memory_Usage(); + TextureBaseClass* tex = ite.Peek_Value(); + total_texture_size += tex->Get_Texture_Memory_Usage(); } return total_texture_size; } // ---------------------------------------------------------------------------- -int TextureClass::_Get_Total_Lightmap_Texture_Size() + +//********************************************************************************************** +//! Get total lightmap texture size +/*! +*/ +int TextureBaseClass::_Get_Total_Lightmap_Texture_Size() { - int total_texture_size=0; + int total_texture_size = 0; - HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash()); + HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash()); // Loop through all the textures in the manager - for (ite.First ();!ite.Is_Done();ite.Next ()) { + for (ite.First(); !ite.Is_Done(); ite.Next()) + { // Get the current texture - TextureClass* tex=ite.Peek_Value(); - if (tex->Is_Lightmap()) { - total_texture_size+=tex->Get_Texture_Memory_Usage(); + TextureBaseClass* tex = ite.Peek_Value(); + if (tex->Is_Lightmap()) + { + total_texture_size += tex->Get_Texture_Memory_Usage(); } } return total_texture_size; } -// ---------------------------------------------------------------------------- -int TextureClass::_Get_Total_Procedural_Texture_Size() +//********************************************************************************************** +//! Get total procedural texture size +/*! +*/ +int TextureBaseClass::_Get_Total_Procedural_Texture_Size() { - int total_texture_size=0; + int total_texture_size = 0; - HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash()); + HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash()); // Loop through all the textures in the manager - for (ite.First ();!ite.Is_Done();ite.Next ()) { + for (ite.First(); !ite.Is_Done(); ite.Next()) + { // Get the current texture - TextureClass* tex=ite.Peek_Value(); - if (tex->Is_Procedural()) { - total_texture_size+=tex->Get_Texture_Memory_Usage(); + TextureBaseClass* tex = ite.Peek_Value(); + if (tex->Is_Procedural()) + { + total_texture_size += tex->Get_Texture_Memory_Usage(); } } return total_texture_size; } -// ---------------------------------------------------------------------------- - -int TextureClass::_Get_Total_Texture_Count() +//********************************************************************************************** +//! Get total texture count +/*! +*/ +int TextureBaseClass::_Get_Total_Texture_Count() { - int texture_count=0; + int texture_count = 0; - HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash()); + HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash()); // Loop through all the textures in the manager - for (ite.First ();!ite.Is_Done();ite.Next ()) { + for (ite.First(); !ite.Is_Done(); ite.Next()) + { texture_count++; } @@ -663,14 +523,21 @@ int TextureClass::_Get_Total_Texture_Count() // ---------------------------------------------------------------------------- -int TextureClass::_Get_Total_Lightmap_Texture_Count() + +//********************************************************************************************** +//! Get total light map texture count +/*! +*/ +int TextureBaseClass::_Get_Total_Lightmap_Texture_Count() { - int texture_count=0; + int texture_count = 0; - HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash()); + HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash()); // Loop through all the textures in the manager - for (ite.First ();!ite.Is_Done();ite.Next ()) { - if (ite.Peek_Value()->Is_Lightmap()) { + for (ite.First(); !ite.Is_Done(); ite.Next()) + { + if (ite.Peek_Value()->Is_Lightmap()) + { texture_count++; } } @@ -678,16 +545,20 @@ int TextureClass::_Get_Total_Lightmap_Texture_Count() return texture_count; } -// ---------------------------------------------------------------------------- - -int TextureClass::_Get_Total_Procedural_Texture_Count() +//********************************************************************************************** +//! Get total procedural texture count +/*! +*/ +int TextureBaseClass::_Get_Total_Procedural_Texture_Count() { - int texture_count=0; + int texture_count = 0; - HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash()); + HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash()); // Loop through all the textures in the manager - for (ite.First ();!ite.Is_Done();ite.Next ()) { - if (ite.Peek_Value()->Is_Procedural()) { + for (ite.First(); !ite.Is_Done(); ite.Next()) + { + if (ite.Peek_Value()->Is_Procedural()) + { texture_count++; } } @@ -695,159 +566,615 @@ int TextureClass::_Get_Total_Procedural_Texture_Count() return texture_count; } -// ---------------------------------------------------------------------------- -int TextureClass::_Get_Total_Locked_Surface_Count() +//********************************************************************************************** +//! Get total locked surface count +/*! +*/ +int TextureBaseClass::_Get_Total_Locked_Surface_Count() { - int texture_count=0; + int texture_count = 0; - HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash()); + HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash()); // Loop through all the textures in the manager - for (ite.First ();!ite.Is_Done();ite.Next ()) { + for (ite.First(); !ite.Is_Done(); ite.Next()) + { // Get the current texture - TextureClass* tex=ite.Peek_Value(); - if (!tex->Initialized) { + TextureBaseClass* tex = ite.Peek_Value(); + if (!tex->Initialized) + { texture_count++; } } return texture_count; } -/* -bool Validate_Filters(unsigned type) + +/************************************************************************* +** TextureClass +*************************************************************************/ +TextureClass::TextureClass +( + unsigned width, + unsigned height, + WW3DFormat format, + MipCountType mip_level_count, + PoolType pool, + bool rendertarget, + bool allow_reduction +) + : TextureBaseClass(width, height, mip_level_count, pool, rendertarget, allow_reduction), + Filter(mip_level_count), + TextureFormat(format) { - ShaderClass shader=ShaderClass::_PresetOpaqueShader; - shader.Apply(); - DX8Wrapper::Set_DX8_Texture(0, MissingTexture::_Get_Missing_Texture()); - DX8Wrapper::Set_DX8_Texture_Stage_State(0,D3DTSS_MINFILTER,_MinTextureFilters[type]); - DX8Wrapper::Set_DX8_Texture_Stage_State(0,D3DTSS_MAGFILTER,_MagTextureFilters[type]); - DX8Wrapper::Set_DX8_Texture_Stage_State(0,D3DTSS_MIPFILTER,_MipMapFilters[type]); - unsigned long passes; - HRESULT hres=DX8Wrapper::_Get_D3D_Device8()->ValidateDevice(&passes); - return !FAILED(hres); -} -*/ + Initialized = true; + IsProcedural = true; + IsReducible = false; + switch (format) + { + case WW3D_FORMAT_DXT1: + case WW3D_FORMAT_DXT2: + case WW3D_FORMAT_DXT3: + case WW3D_FORMAT_DXT4: + case WW3D_FORMAT_DXT5: + IsCompressionAllowed = true; + break; + default: break; + } -// Utility functions -TextureClass* Load_Texture(ChunkLoadClass & cload) -{ - // Assume failure - TextureClass *newtex = NULL; + D3DPOOL d3dpool = (D3DPOOL)0; + switch (pool) + { + case POOL_DEFAULT: d3dpool = D3DPOOL_DEFAULT; break; + case POOL_MANAGED: d3dpool = D3DPOOL_MANAGED; break; + case POOL_SYSTEMMEM: d3dpool = D3DPOOL_SYSTEMMEM; break; + default: WWASSERT(0); + } - char name[256]; - if (cload.Open_Chunk () && (cload.Cur_Chunk_ID () == W3D_CHUNK_TEXTURE)) + Poke_Texture + ( + DX8Wrapper::_Create_DX8_Texture + ( + width, + height, + format, + mip_level_count, + d3dpool, + rendertarget + ) + ); + + if (pool == POOL_DEFAULT) { + Set_Dirty(); + DX8TextureTrackerClass* track = new DX8TextureTrackerClass + ( + width, + height, + format, + mip_level_count, + this, + rendertarget + ); + DX8TextureManagerClass::Add(track); + } + LastAccessed = WW3D::Get_Sync_Time(); +} - W3dTextureInfoStruct texinfo; - bool hastexinfo = false; - /* - ** Read in the texture filename, and a possible texture info structure. - */ - while (cload.Open_Chunk()) { - switch (cload.Cur_Chunk_ID()) { - case W3D_CHUNK_TEXTURE_NAME: - cload.Read(&name,cload.Cur_Chunk_Length()); - break; - case W3D_CHUNK_TEXTURE_INFO: - cload.Read(&texinfo,sizeof(W3dTextureInfoStruct)); - hastexinfo = true; - break; - }; - cload.Close_Chunk(); +// ---------------------------------------------------------------------------- +TextureClass::TextureClass +( + const char* name, + const char* full_path, + MipCountType mip_level_count, + WW3DFormat texture_format, + bool allow_compression, + bool allow_reduction +) + : TextureBaseClass(0, 0, mip_level_count), + Filter(mip_level_count), + TextureFormat(texture_format) +{ + IsCompressionAllowed = allow_compression; + InactivationTime = DEFAULT_INACTIVATION_TIME; // Default inactivation time 30 seconds + IsReducible = allow_reduction; + + switch (TextureFormat) + { + case WW3D_FORMAT_DXT1: + case WW3D_FORMAT_DXT2: + case WW3D_FORMAT_DXT3: + case WW3D_FORMAT_DXT4: + case WW3D_FORMAT_DXT5: + IsCompressionAllowed = true; + break; + case WW3D_FORMAT_U8V8: // Bumpmap + case WW3D_FORMAT_L6V5U5: // Bumpmap + case WW3D_FORMAT_X8L8V8U8: // Bumpmap + // If requesting bumpmap format that isn't available we'll just return the surface in whatever color + // format the texture file is in. (This is illegal case, the format support should always be queried + // before creating a bump texture!) + if (!DX8Wrapper::Is_Initted() || !DX8Wrapper::Get_Current_Caps()->Support_Texture_Format(TextureFormat)) + { + TextureFormat = WW3D_FORMAT_UNKNOWN; } - cload.Close_Chunk(); + // If bump format is valid, make sure compression is not allowed so that we don't even attempt to load + // from a compressed file (quality isn't good enough for bump map). Also disable mipmapping. + else + { + IsCompressionAllowed = false; + MipLevelCount = MIP_LEVELS_1; + Filter.Set_Mip_Mapping(TextureFilterClass::FILTER_TYPE_NONE); + } + break; + default: break; + } - /* - ** Get the texture from the asset manager - */ - if (hastexinfo) + WWASSERT_PRINT(name && name[0], "TextureClass CTor: NULL or empty texture name"); + int len = strlen(name); + for (int i = 0; i < len; ++i) + { + if (name[i] == '+') { + IsLightmap = true; - MipCountType mipcount; + // Set bilinear filtering for lightmaps (they are very stretched and + // low detail so we don't care for anisotropic or trilinear filtering...) + Filter.Set_Min_Filter(TextureFilterClass::FILTER_TYPE_FAST); + Filter.Set_Mag_Filter(TextureFilterClass::FILTER_TYPE_FAST); + if (mip_level_count != MIP_LEVELS_1) Filter.Set_Mip_Mapping(TextureFilterClass::FILTER_TYPE_FAST); + break; + } + } + Set_Texture_Name(name); + Set_Full_Path(full_path); + WWASSERT(name[0] != '\0'); + if (!WW3D::Is_Texturing_Enabled()) + { + Initialized = true; + Poke_Texture(NULL); + } - bool no_lod = ((texinfo.Attributes & W3DTEXTURE_NO_LOD) == W3DTEXTURE_NO_LOD); + // Find original size from the thumbnail (but don't create thumbnail texture yet!) + ThumbnailClass* thumb = ThumbnailManagerClass::Peek_Thumbnail_Instance_From_Any_Manager(Get_Full_Path()); + if (thumb) + { + Width = thumb->Get_Original_Texture_Width(); + Height = thumb->Get_Original_Texture_Height(); + if (MipLevelCount != MIP_LEVELS_1) { + MipLevelCount = (MipCountType)thumb->Get_Original_Texture_Mip_Level_Count(); + } + } - if (no_lod) - { - mipcount = MIP_LEVELS_1; - } - else - { - switch (texinfo.Attributes & W3DTEXTURE_MIP_LEVELS_MASK) { + LastAccessed = WW3D::Get_Sync_Time(); - case W3DTEXTURE_MIP_LEVELS_ALL: - mipcount = MIP_LEVELS_ALL; - break; + // If the thumbnails are not enabled, init the texture at this point to avoid stalling when the + // mesh is rendered. + if (!WW3D::Get_Thumbnail_Enabled()) + { + if (TextureLoader::Is_DX8_Thread()) + { + Init(); + } + } +} - case W3DTEXTURE_MIP_LEVELS_2: - mipcount = MIP_LEVELS_2; - break; +// ---------------------------------------------------------------------------- +TextureClass::TextureClass +( + SurfaceClass* surface, + MipCountType mip_level_count +) + : TextureBaseClass(0, 0, mip_level_count), + Filter(mip_level_count), + TextureFormat(surface->Get_Surface_Format()) +{ + IsProcedural = true; + Initialized = true; + IsReducible = false; - case W3DTEXTURE_MIP_LEVELS_3: - mipcount = MIP_LEVELS_3; - break; + SurfaceClass::SurfaceDescription sd; + surface->Get_Description(sd); + Width = sd.Width; + Height = sd.Height; + switch (sd.Format) + { + case WW3D_FORMAT_DXT1: + case WW3D_FORMAT_DXT2: + case WW3D_FORMAT_DXT3: + case WW3D_FORMAT_DXT4: + case WW3D_FORMAT_DXT5: + IsCompressionAllowed = true; + break; + default: break; + } - case W3DTEXTURE_MIP_LEVELS_4: - mipcount = MIP_LEVELS_4; - break; + Poke_Texture + ( + DX8Wrapper::_Create_DX8_Texture + ( + surface->Peek_D3D_Surface(), + mip_level_count + ) + ); + LastAccessed = WW3D::Get_Sync_Time(); +} - default: - WWASSERT (false); - mipcount = MIP_LEVELS_ALL; - break; - } - } - newtex = WW3DAssetManager::Get_Instance()->Get_Texture (name, mipcount); +// ---------------------------------------------------------------------------- +TextureClass::TextureClass(IDirect3DBaseTexture8* d3d_texture) + : TextureBaseClass + ( + 0, + 0, + ((MipCountType)d3d_texture->GetLevelCount()) + ), + Filter((MipCountType)d3d_texture->GetLevelCount()) +{ + Initialized = true; + IsProcedural = true; + IsReducible = false; - if (no_lod) - { - newtex->Get_Filter().Set_Mip_Mapping(TextureFilterClass::FILTER_TYPE_NONE); - } - bool u_clamp = ((texinfo.Attributes & W3DTEXTURE_CLAMP_U) != 0); - newtex->Get_Filter().Set_U_Addr_Mode(u_clamp ? TextureFilterClass::TEXTURE_ADDRESS_CLAMP : TextureFilterClass::TEXTURE_ADDRESS_REPEAT); - bool v_clamp = ((texinfo.Attributes & W3DTEXTURE_CLAMP_V) != 0); - newtex->Get_Filter().Set_V_Addr_Mode(v_clamp ? TextureFilterClass::TEXTURE_ADDRESS_CLAMP : TextureFilterClass::TEXTURE_ADDRESS_REPEAT); + Set_D3D_Base_Texture(d3d_texture); + IDirect3DSurface8* surface; + DX8_ErrorCode(Peek_D3D_Texture()->GetSurfaceLevel(0, &surface)); + D3DSURFACE_DESC d3d_desc; + ::ZeroMemory(&d3d_desc, sizeof(D3DSURFACE_DESC)); + DX8_ErrorCode(surface->GetDesc(&d3d_desc)); + Width = d3d_desc.Width; + Height = d3d_desc.Height; + TextureFormat = D3DFormat_To_WW3DFormat(d3d_desc.Format); + switch (TextureFormat) + { + case WW3D_FORMAT_DXT1: + case WW3D_FORMAT_DXT2: + case WW3D_FORMAT_DXT3: + case WW3D_FORMAT_DXT4: + case WW3D_FORMAT_DXT5: + IsCompressionAllowed = true; + break; + default: break; + } - switch (texinfo.Attributes & W3DTEXTURE_TYPE_MASK) - { + LastAccessed = WW3D::Get_Sync_Time(); +} - case W3DTEXTURE_TYPE_COLORMAP: - // Do nothing. - break; +//********************************************************************************************** +//! Initialise the texture +/*! +*/ +void TextureClass::Init() +{ + // If the texture has already been initialised we should exit now + if (Initialized) return; - case W3DTEXTURE_TYPE_BUMPMAP: - { - TextureClass *releasetex = newtex; + WWPROFILE("TextureClass::Init"); - // Format is assumed to be a grayscale heightmap. Convert it to a bump map. - newtex = WW3DAssetManager::Get_Instance()->Get_Bumpmap_Based_On_Texture (newtex); - WW3DAssetManager::Get_Instance()->Release_Texture (releasetex); - break; - } + // If the texture has recently been inactivated, increase the inactivation time (this texture obviously + // should not have been inactivated yet). + if (InactivationTime && LastInactivationSyncTime) + { + if ((WW3D::Get_Sync_Time() - LastInactivationSyncTime) < InactivationTime) + { + ExtendedInactivationTime = 3 * InactivationTime; + } + LastInactivationSyncTime = 0; + } - default: - WWASSERT (false); - break; - } - } else { - newtex = WW3DAssetManager::Get_Instance()->Get_Texture(name); + if (!Peek_D3D_Base_Texture()) + { + if (!WW3D::Get_Thumbnail_Enabled() || MipLevelCount == MIP_LEVELS_1) + { + // if (MipLevelCount==MIP_LEVELS_1) { + TextureLoader::Request_Foreground_Loading(this); + } + else + { + WW3DFormat format = TextureFormat; + Load_Locked_Surface(); + TextureFormat = format; } + } - WWASSERT(newtex); + if (!Initialized) + { + TextureLoader::Request_Background_Loading(this); } - // Return a pointer to the new texture - return newtex; + LastAccessed = WW3D::Get_Sync_Time(); } -// Utility function used by Save_Texture -void setup_texture_attributes(TextureClass * tex, W3dTextureInfoStruct * texinfo) +//********************************************************************************************** +//! Apply new surface to texture +/*! +*/ +void TextureClass::Apply_New_Surface +( + IDirect3DBaseTexture8* d3d_texture, + bool initialized, + bool disable_auto_invalidation +) { - texinfo->Attributes = 0; + IDirect3DBaseTexture8* d3d_tex = Peek_D3D_Base_Texture(); + + if (d3d_tex) d3d_tex->Release(); + + Poke_Texture(d3d_texture);//TextureLoadTask->Peek_D3D_Texture(); + d3d_texture->AddRef(); + + if (initialized) Initialized = true; + if (disable_auto_invalidation) InactivationTime = 0; + + WWASSERT(d3d_texture); + IDirect3DSurface8* surface; + DX8_ErrorCode(Peek_D3D_Texture()->GetSurfaceLevel(0, &surface)); + D3DSURFACE_DESC d3d_desc; + ::ZeroMemory(&d3d_desc, sizeof(D3DSURFACE_DESC)); + DX8_ErrorCode(surface->GetDesc(&d3d_desc)); + if (initialized) + { + TextureFormat = D3DFormat_To_WW3DFormat(d3d_desc.Format); + Width = d3d_desc.Width; + Height = d3d_desc.Height; + } + surface->Release(); + +} + + +//********************************************************************************************** +//! Apply texture states +/*! +*/ +void TextureClass::Apply(unsigned int stage) +{ + // Initialization needs to be done when texture is used if it hasn't been done before. + // XBOX always initializes textures at creation time. + if (!Initialized) + { + Init(); + + /* was in battlefield// Non-thumbnailed textures are always initialized when used + if (MipLevelCount==MIP_LEVELS_1) + { + } + // Thumbnailed textures have delayed initialization and a background loading system + else + { + // Limit the number of texture initializations per frame to reduce stuttering + if (TexturesAppliedPerFrameGetSurfaceLevel(level, &d3d_surface)); + SurfaceClass* surface = new SurfaceClass(d3d_surface); + d3d_surface->Release(); + + return surface; +} + +//********************************************************************************************** +//! Get surface description for a mip level +/*! +*/ +void TextureClass::Get_Level_Description(SurfaceClass::SurfaceDescription& desc, unsigned int level) +{ + SurfaceClass* surf = Get_Surface_Level(level); + if (surf != NULL) { + surf->Get_Description(desc); + } + REF_PTR_RELEASE(surf); +} + +//********************************************************************************************** +//! Get D3D surface from mip level +/*! +*/ +IDirect3DSurface8* TextureClass::Get_D3D_Surface_Level(unsigned int level) +{ + if (!Peek_D3D_Texture()) + { + WWASSERT_PRINT(0, "Get_D3D_Surface_Level: D3DTexture is NULL!"); + return 0; + } + + IDirect3DSurface8* d3d_surface = NULL; + DX8_ErrorCode(Peek_D3D_Texture()->GetSurfaceLevel(level, &d3d_surface)); + return d3d_surface; +} + +//********************************************************************************************** +//! Get texture memory usage +/*! +*/ +unsigned TextureClass::Get_Texture_Memory_Usage() const +{ + int size = 0; + if (!Peek_D3D_Texture()) return 0; + for (unsigned i = 0; i < Peek_D3D_Texture()->GetLevelCount(); ++i) + { + D3DSURFACE_DESC desc; + DX8_ErrorCode(Peek_D3D_Texture()->GetLevelDesc(i, &desc)); + size += desc.Size; + } + return size; +} + + +// Utility functions +TextureClass* Load_Texture(ChunkLoadClass& cload) +{ + // Assume failure + TextureClass* newtex = NULL; + + char name[256]; + if (cload.Open_Chunk() && (cload.Cur_Chunk_ID() == W3D_CHUNK_TEXTURE)) + { + + W3dTextureInfoStruct texinfo; + bool hastexinfo = false; + + /* + ** Read in the texture filename, and a possible texture info structure. + */ + while (cload.Open_Chunk()) { + switch (cload.Cur_Chunk_ID()) { + case W3D_CHUNK_TEXTURE_NAME: + cload.Read(&name, cload.Cur_Chunk_Length()); + break; + + case W3D_CHUNK_TEXTURE_INFO: + cload.Read(&texinfo, sizeof(W3dTextureInfoStruct)); + hastexinfo = true; + break; + }; + cload.Close_Chunk(); + } + cload.Close_Chunk(); + + /* + ** Get the texture from the asset manager + */ + if (hastexinfo) + { + + MipCountType mipcount; + + bool no_lod = ((texinfo.Attributes & W3DTEXTURE_NO_LOD) == W3DTEXTURE_NO_LOD); + + if (no_lod) + { + mipcount = MIP_LEVELS_1; + } + else + { + switch (texinfo.Attributes & W3DTEXTURE_MIP_LEVELS_MASK) { + + case W3DTEXTURE_MIP_LEVELS_ALL: + mipcount = MIP_LEVELS_ALL; + break; + + case W3DTEXTURE_MIP_LEVELS_2: + mipcount = MIP_LEVELS_2; + break; + + case W3DTEXTURE_MIP_LEVELS_3: + mipcount = MIP_LEVELS_3; + break; + + case W3DTEXTURE_MIP_LEVELS_4: + mipcount = MIP_LEVELS_4; + break; + + default: + WWASSERT(false); + mipcount = MIP_LEVELS_ALL; + break; + } + } + + WW3DFormat format = WW3D_FORMAT_UNKNOWN; + + switch (texinfo.Attributes & W3DTEXTURE_TYPE_MASK) + { + + case W3DTEXTURE_TYPE_COLORMAP: + // Do nothing. + break; + + case W3DTEXTURE_TYPE_BUMPMAP: + { + if (DX8Wrapper::Is_Initted() && DX8Wrapper::Get_Current_Caps()->Support_Bump_Envmap()) + { + // No mipmaps to bumpmap for now + mipcount = MIP_LEVELS_1; + + if (DX8Wrapper::Get_Current_Caps()->Support_Texture_Format(WW3D_FORMAT_U8V8)) format = WW3D_FORMAT_U8V8; + else if (DX8Wrapper::Get_Current_Caps()->Support_Texture_Format(WW3D_FORMAT_X8L8V8U8)) format = WW3D_FORMAT_X8L8V8U8; + else if (DX8Wrapper::Get_Current_Caps()->Support_Texture_Format(WW3D_FORMAT_L6V5U5)) format = WW3D_FORMAT_L6V5U5; + } + break; + } + + default: + WWASSERT(false); + break; + } + + newtex = WW3DAssetManager::Get_Instance()->Get_Texture(name, mipcount, format); + + if (no_lod) + { + newtex->Get_Filter().Set_Mip_Mapping(TextureFilterClass::FILTER_TYPE_NONE); + } + bool u_clamp = ((texinfo.Attributes & W3DTEXTURE_CLAMP_U) != 0); + newtex->Get_Filter().Set_U_Addr_Mode(u_clamp ? TextureFilterClass::TEXTURE_ADDRESS_CLAMP : TextureFilterClass::TEXTURE_ADDRESS_REPEAT); + bool v_clamp = ((texinfo.Attributes & W3DTEXTURE_CLAMP_V) != 0); + newtex->Get_Filter().Set_V_Addr_Mode(v_clamp ? TextureFilterClass::TEXTURE_ADDRESS_CLAMP : TextureFilterClass::TEXTURE_ADDRESS_REPEAT); + + } + else + { + newtex = WW3DAssetManager::Get_Instance()->Get_Texture(name); + } + + WWASSERT(newtex); + } + + // Return a pointer to the new texture + return newtex; +} + +// Utility function used by Save_Texture +void setup_texture_attributes(TextureClass* tex, W3dTextureInfoStruct* texinfo) +{ + texinfo->Attributes = 0; if (tex->Get_Filter().Get_Mip_Mapping() == TextureFilterClass::FILTER_TYPE_NONE) texinfo->Attributes |= W3DTEXTURE_NO_LOD; if (tex->Get_Filter().Get_U_Addr_Mode() == TextureFilterClass::TEXTURE_ADDRESS_CLAMP) texinfo->Attributes |= W3DTEXTURE_CLAMP_U; @@ -855,18 +1182,18 @@ void setup_texture_attributes(TextureClass * tex, W3dTextureInfoStruct * texinfo } -void Save_Texture(TextureClass * texture,ChunkSaveClass & csave) +void Save_Texture(TextureClass* texture, ChunkSaveClass& csave) { - const char * filename; + const char* filename; W3dTextureInfoStruct texinfo; - memset(&texinfo,0,sizeof(texinfo)); + memset(&texinfo, 0, sizeof(texinfo)); filename = texture->Get_Full_Path(); setup_texture_attributes(texture, &texinfo); csave.Begin_Chunk(W3D_CHUNK_TEXTURE_NAME); - csave.Write(filename,strlen(filename)+1); + csave.Write(filename, strlen(filename) + 1); csave.End_Chunk(); if ((texinfo.Attributes != 0) || (texinfo.AnimType != 0) || (texinfo.FrameCount != 0)) { @@ -876,18 +1203,711 @@ void Save_Texture(TextureClass * texture,ChunkSaveClass & csave) } } -// ---------------------------------------------------------------------------- -BumpmapTextureClass::BumpmapTextureClass(TextureClass* texture) - : -// TextureClass(texture->Get_Width(),texture->Get_Height(),texture->Get_Textur4e_Format(),MIP_LEVELS_1) - TextureClass(TextureLoader::Generate_Bumpmap(texture)) +/*! + * KJM depth stencil texture constructor + */ +ZTextureClass::ZTextureClass +( + unsigned width, + unsigned height, + WW3DZFormat zformat, + MipCountType mip_level_count, + PoolType pool +) + : TextureBaseClass(width, height, mip_level_count, pool), + DepthStencilTextureFormat(zformat) +{ + D3DPOOL d3dpool = (D3DPOOL)0; + switch (pool) + { + case POOL_DEFAULT: d3dpool = D3DPOOL_DEFAULT; break; + case POOL_MANAGED: d3dpool = D3DPOOL_MANAGED; break; + case POOL_SYSTEMMEM: d3dpool = D3DPOOL_SYSTEMMEM; break; + default: WWASSERT(0); + } + + Poke_Texture + ( + DX8Wrapper::_Create_DX8_ZTexture + ( + width, + height, + zformat, + mip_level_count, + d3dpool + ) + ); + + if (pool == POOL_DEFAULT) + { + Set_Dirty(); + DX8ZTextureTrackerClass* track = new DX8ZTextureTrackerClass + ( + width, + height, + zformat, + mip_level_count, + this + ); + DX8TextureManagerClass::Add(track); + } + Initialized = true; + IsProcedural = true; + IsReducible = false; + + LastAccessed = WW3D::Get_Sync_Time(); +} + + +//********************************************************************************************** +//! Apply depth stencil texture +/*! KM +*/ +void ZTextureClass::Apply(unsigned int stage) +{ + DX8Wrapper::Set_DX8_Texture(stage, Peek_D3D_Base_Texture()); +} + +//********************************************************************************************** +//! Apply new surface to texture +/*! KM +*/ +void ZTextureClass::Apply_New_Surface +( + IDirect3DBaseTexture8* d3d_texture, + bool initialized, + bool disable_auto_invalidation +) +{ + IDirect3DBaseTexture8* d3d_tex = Peek_D3D_Base_Texture(); + + if (d3d_tex) d3d_tex->Release(); + + Poke_Texture(d3d_texture);//TextureLoadTask->Peek_D3D_Texture(); + d3d_texture->AddRef(); + + if (initialized) Initialized = true; + if (disable_auto_invalidation) InactivationTime = 0; + + WWASSERT(Peek_D3D_Texture()); + IDirect3DSurface8* surface; + DX8_ErrorCode(Peek_D3D_Texture()->GetSurfaceLevel(0, &surface)); + D3DSURFACE_DESC d3d_desc; + ::ZeroMemory(&d3d_desc, sizeof(D3DSURFACE_DESC)); + DX8_ErrorCode(surface->GetDesc(&d3d_desc)); + if (initialized) + { + DepthStencilTextureFormat = D3DFormat_To_WW3DZFormat(d3d_desc.Format); + Width = d3d_desc.Width; + Height = d3d_desc.Height; + } + surface->Release(); +} + +//********************************************************************************************** +//! Get D3D surface from mip level +/*! +*/ +IDirect3DSurface8* ZTextureClass::Get_D3D_Surface_Level(unsigned int level) { -// D3DTexture=TextureLoader::Generate_Bumpmap(texture); -// TextureLoader:::Generage_Bumpmap + if (!Peek_D3D_Texture()) + { + WWASSERT_PRINT(0, "Get_D3D_Surface_Level: D3DTexture is NULL!"); + return 0; + } + + IDirect3DSurface8* d3d_surface = NULL; + DX8_ErrorCode(Peek_D3D_Texture()->GetSurfaceLevel(level, &d3d_surface)); + return d3d_surface; } -BumpmapTextureClass::~BumpmapTextureClass() +//********************************************************************************************** +//! Get texture memory usage +/*! +*/ +unsigned ZTextureClass::Get_Texture_Memory_Usage() const { + int size = 0; + if (!Peek_D3D_Texture()) return 0; + for (unsigned i = 0; i < Peek_D3D_Texture()->GetLevelCount(); ++i) + { + D3DSURFACE_DESC desc; + DX8_ErrorCode(Peek_D3D_Texture()->GetLevelDesc(i, &desc)); + size += desc.Size; + } + return size; } + + +/************************************************************************* +** CubeTextureClass +*************************************************************************/ +CubeTextureClass::CubeTextureClass +( + unsigned width, + unsigned height, + WW3DFormat format, + MipCountType mip_level_count, + PoolType pool, + bool rendertarget, + bool allow_reduction +) + : TextureClass(width, height, format, mip_level_count, pool, rendertarget) +{ + Initialized = true; + IsProcedural = true; + IsReducible = false; + + switch (format) + { + case WW3D_FORMAT_DXT1: + case WW3D_FORMAT_DXT2: + case WW3D_FORMAT_DXT3: + case WW3D_FORMAT_DXT4: + case WW3D_FORMAT_DXT5: + IsCompressionAllowed = true; + break; + default: break; + } + + D3DPOOL d3dpool = (D3DPOOL)0; + switch (pool) + { + case POOL_DEFAULT: d3dpool = D3DPOOL_DEFAULT; break; + case POOL_MANAGED: d3dpool = D3DPOOL_MANAGED; break; + case POOL_SYSTEMMEM: d3dpool = D3DPOOL_SYSTEMMEM; break; + default: WWASSERT(0); + } + + Poke_Texture + ( + DX8Wrapper::_Create_DX8_Cube_Texture + ( + width, + height, + format, + mip_level_count, + d3dpool, + rendertarget + ) + ); + + if (pool == POOL_DEFAULT) + { + Set_Dirty(); + DX8TextureTrackerClass* track = new DX8TextureTrackerClass + ( + width, + height, + format, + mip_level_count, + this, + rendertarget + ); + DX8TextureManagerClass::Add(track); + } + LastAccessed = WW3D::Get_Sync_Time(); +} + + + +// ---------------------------------------------------------------------------- +CubeTextureClass::CubeTextureClass +( + const char* name, + const char* full_path, + MipCountType mip_level_count, + WW3DFormat texture_format, + bool allow_compression, + bool allow_reduction +) + : TextureClass(0, 0, mip_level_count, POOL_MANAGED, false, texture_format) +{ + IsCompressionAllowed = allow_compression; + InactivationTime = DEFAULT_INACTIVATION_TIME; // Default inactivation time 30 seconds + + switch (TextureFormat) + { + case WW3D_FORMAT_DXT1: + case WW3D_FORMAT_DXT2: + case WW3D_FORMAT_DXT3: + case WW3D_FORMAT_DXT4: + case WW3D_FORMAT_DXT5: + IsCompressionAllowed = true; + break; + case WW3D_FORMAT_U8V8: // Bumpmap + case WW3D_FORMAT_L6V5U5: // Bumpmap + case WW3D_FORMAT_X8L8V8U8: // Bumpmap + // If requesting bumpmap format that isn't available we'll just return the surface in whatever color + // format the texture file is in. (This is illegal case, the format support should always be queried + // before creating a bump texture!) + if (!DX8Wrapper::Is_Initted() || !DX8Wrapper::Get_Current_Caps()->Support_Texture_Format(TextureFormat)) + { + TextureFormat = WW3D_FORMAT_UNKNOWN; + } + // If bump format is valid, make sure compression is not allowed so that we don't even attempt to load + // from a compressed file (quality isn't good enough for bump map). Also disable mipmapping. + else + { + IsCompressionAllowed = false; + MipLevelCount = MIP_LEVELS_1; + Filter.Set_Mip_Mapping(TextureFilterClass::FILTER_TYPE_NONE); + } + break; + default: break; + } + + WWASSERT_PRINT(name && name[0], "TextureClass CTor: NULL or empty texture name"); + int len = strlen(name); + for (int i = 0; i < len; ++i) + { + if (name[i] == '+') + { + IsLightmap = true; + + // Set bilinear filtering for lightmaps (they are very stretched and + // low detail so we don't care for anisotropic or trilinear filtering...) + Filter.Set_Min_Filter(TextureFilterClass::FILTER_TYPE_FAST); + Filter.Set_Mag_Filter(TextureFilterClass::FILTER_TYPE_FAST); + if (mip_level_count != MIP_LEVELS_1) Filter.Set_Mip_Mapping(TextureFilterClass::FILTER_TYPE_FAST); + break; + } + } + Set_Texture_Name(name); + Set_Full_Path(full_path); + WWASSERT(name[0] != '\0'); + if (!WW3D::Is_Texturing_Enabled()) + { + Initialized = true; + Poke_Texture(NULL); + } + + // Find original size from the thumbnail (but don't create thumbnail texture yet!) + ThumbnailClass* thumb = ThumbnailManagerClass::Peek_Thumbnail_Instance_From_Any_Manager(Get_Full_Path()); + if (thumb) + { + Width = thumb->Get_Original_Texture_Width(); + Height = thumb->Get_Original_Texture_Height(); + if (MipLevelCount != MIP_LEVELS_1) { + MipLevelCount = (MipCountType)thumb->Get_Original_Texture_Mip_Level_Count(); + } + } + + LastAccessed = WW3D::Get_Sync_Time(); + + // If the thumbnails are not enabled, init the texture at this point to avoid stalling when the + // mesh is rendered. + if (!WW3D::Get_Thumbnail_Enabled()) + { + if (TextureLoader::Is_DX8_Thread()) + { + Init(); + } + } +} + +// don't know if these are needed +#if 0 +// ---------------------------------------------------------------------------- +CubeTextureClass::CubeTextureClass +( + SurfaceClass* surface, + MipCountType mip_level_count +) + : TextureClass(0, 0, mip_level_count, POOL_MANAGED, false, surface->Get_Surface_Format()) +{ + IsProcedural = true; + Initialized = true; + IsReducible = false; + + SurfaceClass::SurfaceDescription sd; + surface->Get_Description(sd); + Width = sd.Width; + Height = sd.Height; + switch (sd.Format) + { + case WW3D_FORMAT_DXT1: + case WW3D_FORMAT_DXT2: + case WW3D_FORMAT_DXT3: + case WW3D_FORMAT_DXT4: + case WW3D_FORMAT_DXT5: + IsCompressionAllowed = true; + break; + default: break; + } + + Poke_Texture + ( + DX8Wrapper::_Create_DX8_Cube_Texture + ( + surface->Peek_D3D_Surface(), + mip_level_count + ) + ); + LastAccessed = WW3D::Get_Sync_Time(); +} + +// ---------------------------------------------------------------------------- +CubeTextureClass::CubeTextureClass(IDirect3DBaseTexture8* d3d_texture) + : TextureBaseClass + ( + 0, + 0, + ((MipCountType)d3d_texture->GetLevelCount()) + ), + Filter((MipCountType)d3d_texture->GetLevelCount()) +{ + Initialized = true; + IsProcedural = true; + IsReducible = false; + + Peek_Texture()->AddRef(); + IDirect3DSurface8* surface; + DX8_ErrorCode(Peek_D3D_Texture()->GetSurfaceLevel(0, &surface)); + D3DSURFACE_DESC d3d_desc; + ::ZeroMemory(&d3d_desc, sizeof(D3DSURFACE_DESC)); + DX8_ErrorCode(surface->GetDesc(&d3d_desc)); + Width = d3d_desc.Width; + Height = d3d_desc.Height; + TextureFormat = D3DFormat_To_WW3DFormat(d3d_desc.Format); + switch (TextureFormat) + { + case WW3D_FORMAT_DXT1: + case WW3D_FORMAT_DXT2: + case WW3D_FORMAT_DXT3: + case WW3D_FORMAT_DXT4: + case WW3D_FORMAT_DXT5: + IsCompressionAllowed = true; + break; + default: break; + } + + LastAccessed = WW3D::Get_Sync_Time(); +} +#endif + +//********************************************************************************************** +//! Apply new surface to texture +/*! +*/ +void CubeTextureClass::Apply_New_Surface +( + IDirect3DBaseTexture8* d3d_texture, + bool initialized, + bool disable_auto_invalidation +) +{ + IDirect3DBaseTexture8* d3d_tex = Peek_D3D_Base_Texture(); + + if (d3d_tex) d3d_tex->Release(); + + Poke_Texture(d3d_texture);//TextureLoadTask->Peek_D3D_Texture(); + d3d_texture->AddRef(); + + if (initialized) Initialized = true; + if (disable_auto_invalidation) InactivationTime = 0; + + WWASSERT(d3d_texture); + D3DSURFACE_DESC d3d_desc; + ::ZeroMemory(&d3d_desc, sizeof(D3DSURFACE_DESC)); + DX8_ErrorCode(Peek_D3D_CubeTexture()->GetLevelDesc(0, &d3d_desc)); + + if (initialized) + { + TextureFormat = D3DFormat_To_WW3DFormat(d3d_desc.Format); + Width = d3d_desc.Width; + Height = d3d_desc.Height; + } +} + + +/************************************************************************* +** VolumeTextureClass +*************************************************************************/ +VolumeTextureClass::VolumeTextureClass +( + unsigned width, + unsigned height, + unsigned depth, + WW3DFormat format, + MipCountType mip_level_count, + PoolType pool, + bool rendertarget, + bool allow_reduction +) + : TextureClass(width, height, format, mip_level_count, pool, rendertarget), + Depth(depth) +{ + Initialized = true; + IsProcedural = true; + IsReducible = false; + + switch (format) + { + case WW3D_FORMAT_DXT1: + case WW3D_FORMAT_DXT2: + case WW3D_FORMAT_DXT3: + case WW3D_FORMAT_DXT4: + case WW3D_FORMAT_DXT5: + IsCompressionAllowed = true; + break; + default: break; + } + + D3DPOOL d3dpool = (D3DPOOL)0; + switch (pool) + { + case POOL_DEFAULT: d3dpool = D3DPOOL_DEFAULT; break; + case POOL_MANAGED: d3dpool = D3DPOOL_MANAGED; break; + case POOL_SYSTEMMEM: d3dpool = D3DPOOL_SYSTEMMEM; break; + default: WWASSERT(0); + } + + Poke_Texture + ( + DX8Wrapper::_Create_DX8_Volume_Texture + ( + width, + height, + depth, + format, + mip_level_count, + d3dpool + ) + ); + + if (pool == POOL_DEFAULT) + { + Set_Dirty(); + DX8TextureTrackerClass* track = new DX8TextureTrackerClass + ( + width, + height, + format, + mip_level_count, + this, + rendertarget + ); + DX8TextureManagerClass::Add(track); + } + LastAccessed = WW3D::Get_Sync_Time(); +} + + + +// ---------------------------------------------------------------------------- +VolumeTextureClass::VolumeTextureClass +( + const char* name, + const char* full_path, + MipCountType mip_level_count, + WW3DFormat texture_format, + bool allow_compression, + bool allow_reduction +) + : TextureClass(0, 0, mip_level_count, POOL_MANAGED, false, texture_format), + Depth(0) +{ + IsCompressionAllowed = allow_compression; + InactivationTime = DEFAULT_INACTIVATION_TIME; // Default inactivation time 30 seconds + + switch (TextureFormat) + { + case WW3D_FORMAT_DXT1: + case WW3D_FORMAT_DXT2: + case WW3D_FORMAT_DXT3: + case WW3D_FORMAT_DXT4: + case WW3D_FORMAT_DXT5: + IsCompressionAllowed = true; + break; + case WW3D_FORMAT_U8V8: // Bumpmap + case WW3D_FORMAT_L6V5U5: // Bumpmap + case WW3D_FORMAT_X8L8V8U8: // Bumpmap + // If requesting bumpmap format that isn't available we'll just return the surface in whatever color + // format the texture file is in. (This is illegal case, the format support should always be queried + // before creating a bump texture!) + if (!DX8Wrapper::Is_Initted() || !DX8Wrapper::Get_Current_Caps()->Support_Texture_Format(TextureFormat)) + { + TextureFormat = WW3D_FORMAT_UNKNOWN; + } + // If bump format is valid, make sure compression is not allowed so that we don't even attempt to load + // from a compressed file (quality isn't good enough for bump map). Also disable mipmapping. + else + { + IsCompressionAllowed = false; + MipLevelCount = MIP_LEVELS_1; + Filter.Set_Mip_Mapping(TextureFilterClass::FILTER_TYPE_NONE); + } + break; + default: break; + } + + WWASSERT_PRINT(name && name[0], "TextureClass CTor: NULL or empty texture name"); + int len = strlen(name); + for (int i = 0; i < len; ++i) + { + if (name[i] == '+') + { + IsLightmap = true; + + // Set bilinear filtering for lightmaps (they are very stretched and + // low detail so we don't care for anisotropic or trilinear filtering...) + Filter.Set_Min_Filter(TextureFilterClass::FILTER_TYPE_FAST); + Filter.Set_Mag_Filter(TextureFilterClass::FILTER_TYPE_FAST); + if (mip_level_count != MIP_LEVELS_1) Filter.Set_Mip_Mapping(TextureFilterClass::FILTER_TYPE_FAST); + break; + } + } + Set_Texture_Name(name); + Set_Full_Path(full_path); + WWASSERT(name[0] != '\0'); + if (!WW3D::Is_Texturing_Enabled()) + { + Initialized = true; + Poke_Texture(NULL); + } + + // Find original size from the thumbnail (but don't create thumbnail texture yet!) + ThumbnailClass* thumb = ThumbnailManagerClass::Peek_Thumbnail_Instance_From_Any_Manager(Get_Full_Path()); + if (thumb) + { + Width = thumb->Get_Original_Texture_Width(); + Height = thumb->Get_Original_Texture_Height(); + if (MipLevelCount != MIP_LEVELS_1) { + MipLevelCount = (MipCountType)thumb->Get_Original_Texture_Mip_Level_Count(); + } + } + + LastAccessed = WW3D::Get_Sync_Time(); + + // If the thumbnails are not enabled, init the texture at this point to avoid stalling when the + // mesh is rendered. + if (!WW3D::Get_Thumbnail_Enabled()) + { + if (TextureLoader::Is_DX8_Thread()) + { + Init(); + } + } +} + +// don't know if these are needed +#if 0 +// ---------------------------------------------------------------------------- +CubeTextureClass::CubeTextureClass +( + SurfaceClass* surface, + MipCountType mip_level_count +) + : TextureClass(0, 0, mip_level_count, POOL_MANAGED, false, surface->Get_Surface_Format()) +{ + IsProcedural = true; + Initialized = true; + IsReducible = false; + + SurfaceClass::SurfaceDescription sd; + surface->Get_Description(sd); + Width = sd.Width; + Height = sd.Height; + switch (sd.Format) + { + case WW3D_FORMAT_DXT1: + case WW3D_FORMAT_DXT2: + case WW3D_FORMAT_DXT3: + case WW3D_FORMAT_DXT4: + case WW3D_FORMAT_DXT5: + IsCompressionAllowed = true; + break; + default: break; + } + + Poke_Texture + ( + DX8Wrapper::_Create_DX8_Cube_Texture + ( + surface->Peek_D3D_Surface(), + mip_level_count + ) + ); + LastAccessed = WW3D::Get_Sync_Time(); +} + +// ---------------------------------------------------------------------------- +CubeTextureClass::CubeTextureClass(IDirect3DBaseTexture8* d3d_texture) + : TextureBaseClass + ( + 0, + 0, + ((MipCountType)d3d_texture->GetLevelCount()) + ), + Filter((MipCountType)d3d_texture->GetLevelCount()) +{ + Initialized = true; + IsProcedural = true; + IsReducible = false; + + Peek_Texture()->AddRef(); + IDirect3DSurface8* surface; + DX8_ErrorCode(Peek_D3D_Texture()->GetSurfaceLevel(0, &surface)); + D3DSURFACE_DESC d3d_desc; + ::ZeroMemory(&d3d_desc, sizeof(D3DSURFACE_DESC)); + DX8_ErrorCode(surface->GetDesc(&d3d_desc)); + Width = d3d_desc.Width; + Height = d3d_desc.Height; + TextureFormat = D3DFormat_To_WW3DFormat(d3d_desc.Format); + switch (TextureFormat) + { + case WW3D_FORMAT_DXT1: + case WW3D_FORMAT_DXT2: + case WW3D_FORMAT_DXT3: + case WW3D_FORMAT_DXT4: + case WW3D_FORMAT_DXT5: + IsCompressionAllowed = true; + break; + default: break; + } + + LastAccessed = WW3D::Get_Sync_Time(); +} +#endif + + + + +//********************************************************************************************** +//! Apply new surface to texture +/*! +*/ +void VolumeTextureClass::Apply_New_Surface +( + IDirect3DBaseTexture8* d3d_texture, + bool initialized, + bool disable_auto_invalidation +) +{ + IDirect3DBaseTexture8* d3d_tex = Peek_D3D_Base_Texture(); + + if (d3d_tex) d3d_tex->Release(); + + Poke_Texture(d3d_texture);//TextureLoadTask->Peek_D3D_Texture(); + d3d_texture->AddRef(); + + if (initialized) Initialized = true; + if (disable_auto_invalidation) InactivationTime = 0; + + WWASSERT(d3d_texture); + D3DVOLUME_DESC d3d_desc; + ::ZeroMemory(&d3d_desc, sizeof(D3DVOLUME_DESC)); + + DX8_ErrorCode(Peek_D3D_VolumeTexture()->GetLevelDesc(0, &d3d_desc)); + + if (initialized) + { + TextureFormat = D3DFormat_To_WW3DFormat(d3d_desc.Format); + Width = d3d_desc.Width; + Height = d3d_desc.Height; + Depth = d3d_desc.Depth; + } +} diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texture.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/texture.h index 7c6a4b3637..d1cf4f0e94 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texture.h +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/texture.h @@ -1,5 +1,5 @@ /* -** Command & Conquer Generals(tm) +** Command & Conquer Generals Zero Hour(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify @@ -24,12 +24,17 @@ * * * $Archive:: /Commando/Code/ww3d2/texture.h $* * * - * $Author:: Jani_p $* + * $Org Author:: Jani_p $* * * - * $Modtime:: 8/17/01 9:41a $* + * Author : Kenny Mitchell * * * - * $Revision:: 35 $* + * $Modtime:: 08/05/02 1:27p $* * * + * $Revision:: 46 $* + * * + * 05/16/02 KM Base texture class to abstract major texture types, e.g. 3d, z, cube, etc. + * 06/27/02 KM Texture class abstraction * + * 08/05/02 KM Texture class redesign (revisited) *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -48,221 +53,432 @@ #include "surfaceclass.h" #include "ww3dformat.h" #include "wwstring.h" +#include "vector3.h" #include "texturefilter.h" struct IDirect3DBaseTexture8; struct IDirect3DTexture8; +struct IDirect3DCubeTexture8; +struct IDirect3DVolumeTexture8; class DX8Wrapper; class TextureLoader; class LoaderThreadClass; -class DX8TextureManagerClass; class TextureLoadTaskClass; +class CubeTextureClass; +class VolumeTextureClass; + +class TextureBaseClass : public RefCountClass +{ + friend class TextureLoader; + friend class LoaderThreadClass; + friend class DX8TextureTrackerClass; //(gth) so it can call Poke_Texture, + friend class DX8ZTextureTrackerClass; + +public: + + enum PoolType + { + POOL_DEFAULT = 0, + POOL_MANAGED, + POOL_SYSTEMMEM + }; + + enum TexAssetType + { + TEX_REGULAR, + TEX_CUBEMAP, + TEX_VOLUME + }; + + // base constructor for derived classes + TextureBaseClass + ( + unsigned width, + unsigned height, + MipCountType mip_level_count = MIP_LEVELS_ALL, + PoolType pool = POOL_MANAGED, + bool rendertarget = false, + bool reducible = true + ); + + virtual ~TextureBaseClass(); + + virtual TexAssetType Get_Asset_Type() const = 0; + + // Names + void Set_Texture_Name(const char* name); + void Set_Full_Path(const char* path) { FullPath = path; } + const StringClass& Get_Texture_Name(void) const { return Name; } + const StringClass& Get_Full_Path(void) const { if (FullPath.Is_Empty()) return Name; return FullPath; } + + unsigned Get_ID() const { return texture_id; } // Each textrure has a unique id + + // The number of Mip levels in the texture + unsigned int Get_Mip_Level_Count(void) const + { + return MipLevelCount; + } + + // Note! Width and Height may be zero and may change if texture uses mipmaps + int Get_Width() const + { + return Width; + } + int Get_Height() const + { + return Height; + } + + // Time, after which the texture is invalidated if not used. Set to zero to indicate infinite. + // Time is in milliseconds. + void Set_Inactivation_Time(unsigned time) { InactivationTime = time; } + int Get_Inactivation_Time() const { return InactivationTime; } + + // Texture priority affects texture management and caching. + unsigned int Get_Priority(void); + unsigned int Set_Priority(unsigned int priority); // Returns previous priority + + // Debug utility functions for returning the texture memory usage + virtual unsigned Get_Texture_Memory_Usage() const = 0; + + bool Is_Initialized() const { return Initialized; } + bool Is_Lightmap() const { return IsLightmap; } + bool Is_Procedural() const { return IsProcedural; } + bool Is_Reducible() const { return IsReducible; } //can texture be reduced in resolution for LOD purposes? + + static int _Get_Total_Locked_Surface_Size(); + static int _Get_Total_Texture_Size(); + static int _Get_Total_Lightmap_Texture_Size(); + static int _Get_Total_Procedural_Texture_Size(); + static int _Get_Total_Locked_Surface_Count(); + static int _Get_Total_Texture_Count(); + static int _Get_Total_Lightmap_Texture_Count(); + static int _Get_Total_Procedural_Texture_Count(); + + virtual void Init() = 0; + + // This utility function processes the texture reduction (used during rendering) + void Invalidate(); + + // texture accessors (dx8) + IDirect3DBaseTexture8* Peek_D3D_Base_Texture() const; + void Set_D3D_Base_Texture(IDirect3DBaseTexture8* tex); + + PoolType Get_Pool() const { return Pool; } + + bool Is_Missing_Texture(); + + // Support for self managed textures + bool Is_Dirty() { WWASSERT(Pool == POOL_DEFAULT); return Dirty; }; + void Set_Dirty() { WWASSERT(Pool == POOL_DEFAULT); Dirty = true; } + void Clean() { Dirty = false; }; + + void Set_HSV_Shift(const Vector3& hsv_shift); + const Vector3& Get_HSV_Shift() { return HSVShift; } + + bool Is_Compression_Allowed() const { return IsCompressionAllowed; } + + unsigned Get_Reduction() const; + + // Background texture loader will call this when texture has been loaded + virtual void Apply_New_Surface(IDirect3DBaseTexture8* tex, bool initialized, bool disable_auto_invalidation = false) = 0; // If the parameter is true, the texture will be flagged as initialised + + MipCountType MipLevelCount; + + // Inactivate textures that haven't been used in a while. Pass zero to use textures' + // own inactive times (default). In urgent need to free up texture memory, try + // calling with relatively small (just few seconds) time override to free up everything + // but the currently used textures. + static void Invalidate_Old_Unused_Textures(unsigned inactive_time_override); + + // Apply this texture's settings into D3D + virtual void Apply(unsigned int stage) = 0; + + // Apply a Null texture's settings into D3D + static void Apply_Null(unsigned int stage); + + virtual TextureClass* As_TextureClass() { return NULL; } + virtual CubeTextureClass* As_CubeTextureClass() { return NULL; } + virtual VolumeTextureClass* As_VolumeTextureClass() { return NULL; } + + IDirect3DTexture8* Peek_D3D_Texture() const { return (IDirect3DTexture8*)Peek_D3D_Base_Texture(); } + IDirect3DVolumeTexture8* Peek_D3D_VolumeTexture() const { return (IDirect3DVolumeTexture8*)Peek_D3D_Base_Texture(); } + IDirect3DCubeTexture8* Peek_D3D_CubeTexture() const { return (IDirect3DCubeTexture8*)Peek_D3D_Base_Texture(); } + +protected: + + void Load_Locked_Surface(); + void Poke_Texture(IDirect3DBaseTexture8* tex) { D3DTexture = tex; } + + bool Initialized; + + // For debug purposes the texture sets this true if it is a lightmap texture + bool IsLightmap; + bool IsCompressionAllowed; + bool IsProcedural; + bool IsReducible; + + + unsigned InactivationTime; // In milliseconds + unsigned ExtendedInactivationTime; // This is set by the engine, if needed + unsigned LastInactivationSyncTime; + mutable unsigned LastAccessed; + + // If this is non-zero, the texture will have a hue shift done at the next init (this + // value should only be changed by Set_HSV_Shift() function, which also invalidates the + // texture). + Vector3 HSVShift; + + int Width; + int Height; + +private: + + // Direct3D texture object + IDirect3DBaseTexture8* D3DTexture; + + // Name + StringClass Name; + StringClass FullPath; + + // Unique id + unsigned texture_id; + + // Support for self-managed textures + + PoolType Pool; + bool Dirty; + + friend class TextureLoadTaskClass; + friend class CubeTextureLoadTaskClass; + friend class VolumeTextureLoadTaskClass; + TextureLoadTaskClass* TextureLoadTask; + TextureLoadTaskClass* ThumbnailLoadTask; + +}; + /************************************************************************* ** TextureClass ** -** This is our texture class. For legacy reasons it contains some +** This is our regular texture class. For legacy reasons it contains some ** information beyond the D3D texture itself, such as texture addressing ** modes. ** *************************************************************************/ -class TextureClass : public W3DMPO, public RefCountClass +class TextureClass : public TextureBaseClass { W3DMPO_GLUE(TextureClass) + // friend DX8Wrapper; - friend class DX8TextureTrackerClass; //(gth) so it can call Poke_Texture, - - friend DX8Wrapper; - friend TextureLoader; - friend LoaderThreadClass; - friend DX8TextureManagerClass; - - public: - - enum PoolType { - POOL_DEFAULT=0, - POOL_MANAGED, - POOL_SYSTEMMEM - }; - - enum TexAssetType - { - TEX_REGULAR, - }; - - // Create texture with desired height, width and format. - TextureClass( - unsigned width, - unsigned height, - WW3DFormat format, - MipCountType mip_level_count=MIP_LEVELS_ALL, - PoolType pool=POOL_MANAGED, - bool rendertarget=false); - - // Create texture from a file. If format is specified the texture is converted to that format. - // Note that the format must be supported by the current device and that a texture can't exist - // in the system with the same name in multiple formats. - TextureClass( - const char *name, - const char *full_path=NULL, - MipCountType mip_level_count=MIP_LEVELS_ALL, - WW3DFormat texture_format=WW3D_FORMAT_UNKNOWN, - bool allow_compression=true); - - // Create texture from a surface. - TextureClass( - SurfaceClass *surface, - MipCountType mip_level_count=MIP_LEVELS_ALL); - - TextureClass(IDirect3DTexture8* d3d_texture); - - virtual TexAssetType Get_Asset_Type() const { return TEX_REGULAR; } - - virtual ~TextureClass(void); - - // Names - void Set_Texture_Name(const char * name); - void Set_Full_Path(const char * path) { FullPath = path; } - const StringClass& Get_Texture_Name(void) const { return Name; } - const StringClass& Get_Full_Path(void) const { if (FullPath.Is_Empty ()) return Name; return FullPath; } - - unsigned Get_ID() const { return texture_id; } // Each textrure has a unique id - - // The number of Mip levels in the texture - unsigned int Get_Mip_Level_Count(void); - - // Note! Width and Height may be zero and may change if texture uses mipmaps - int Get_Width() const - { - return Width; - } - int Get_Height() const - { - return Height; - } - - // Get surface description of a Mip level (defaults to the highest-resolution one) - void Get_Level_Description(SurfaceClass::SurfaceDescription &surface_desc, unsigned int level = 0); - - TextureFilterClass& Get_Filter() { return Filter; } - - // Get the surface of one of the mipmap levels (defaults to highest-resolution one) - SurfaceClass *Get_Surface_Level(unsigned int level = 0); - - // Texture priority affects texture management and caching. - unsigned int Get_Priority(void); - unsigned int Set_Priority(unsigned int priority); // Returns previous priority - - // Debug utility functions for returning the texture memory usage - unsigned Get_Texture_Memory_Usage() const; - bool Is_Initialized() const { return Initialized; } - bool Is_Lightmap() const { return IsLightmap; } - bool Is_Procedural() const { return IsProcedural; } - - static int _Get_Total_Locked_Surface_Size(); - static int _Get_Total_Texture_Size(); - static int _Get_Total_Lightmap_Texture_Size(); - static int _Get_Total_Procedural_Texture_Size(); - static int _Get_Total_Locked_Surface_Count(); - static int _Get_Total_Texture_Count(); - static int _Get_Total_Lightmap_Texture_Count(); - static int _Get_Total_Procedural_Texture_Count(); - - static void _Set_Default_Min_Filter(TextureFilterClass::FilterType filter); - static void _Set_Default_Mag_Filter(TextureFilterClass::FilterType filter); - static void _Set_Default_Mip_Filter(TextureFilterClass::FilterType filter); - - // This utility function processes the texture reduction (used during rendering) - void Invalidate(); - - IDirect3DTexture8 *Peek_D3D_Texture() const { return (IDirect3DTexture8 *)Peek_D3D_Base_Texture(); } - - // texture accessors (dx8) - IDirect3DBaseTexture8 *Peek_D3D_Base_Texture() const; - void Set_D3D_Base_Texture(IDirect3DBaseTexture8* tex); - - PoolType Get_Pool() const { return Pool; } - - bool Is_Missing_Texture(); - - // Support for self managed textures - bool Is_Dirty() { WWASSERT(Pool==POOL_DEFAULT); return Dirty; }; - void Set_Dirty() { WWASSERT(Pool==POOL_DEFAULT); Dirty=true; } - void Clean() { Dirty=false; }; - - unsigned Get_Reduction() const; - WW3DFormat Get_Texture_Format() const { return TextureFormat; } - bool Is_Compression_Allowed() const { return IsCompressionAllowed; } - - protected: - void Poke_Texture(IDirect3DBaseTexture8* tex) { D3DTexture = tex; } - - // Apply this texture's settings into D3D - virtual void Apply(unsigned int stage); - void Load_Locked_Surface(); - - void Init(); +public: - // Apply a Null texture's settings into D3D - static void Apply_Null(unsigned int stage); + // Create texture with desired height, width and format. + TextureClass + ( + unsigned width, + unsigned height, + WW3DFormat format, + MipCountType mip_level_count = MIP_LEVELS_ALL, + PoolType pool = POOL_MANAGED, + bool rendertarget = false, + bool allow_reduction = true + ); + + // Create texture from a file. If format is specified the texture is converted to that format. + // Note that the format must be supported by the current device and that a texture can't exist + // in the system with the same name in multiple formats. + TextureClass + ( + const char* name, + const char* full_path = NULL, + MipCountType mip_level_count = MIP_LEVELS_ALL, + WW3DFormat texture_format = WW3D_FORMAT_UNKNOWN, + bool allow_compression = true, + bool allow_reduction = true + ); + + // Create texture from a surface. + TextureClass + ( + SurfaceClass* surface, + MipCountType mip_level_count = MIP_LEVELS_ALL + ); + + TextureClass(IDirect3DBaseTexture8* d3d_texture); + + // defualt constructors for derived classes (cube & vol) + TextureClass + ( + unsigned width, + unsigned height, + MipCountType mip_level_count = MIP_LEVELS_ALL, + PoolType pool = POOL_MANAGED, + bool rendertarget = false, + WW3DFormat format = WW3D_FORMAT_UNKNOWN, + bool allow_reduction = true + ) + : TextureBaseClass(width, height, mip_level_count, pool, rendertarget, allow_reduction), TextureFormat(format), Filter(mip_level_count) { } + + virtual TexAssetType Get_Asset_Type() const { return TEX_REGULAR; } + + virtual void Init(); + + // Background texture loader will call this when texture has been loaded + virtual void Apply_New_Surface(IDirect3DBaseTexture8* tex, bool initialized, bool disable_auto_invalidation = false); // If the parameter is true, the texture will be flagged as initialised + + // Get the surface of one of the mipmap levels (defaults to highest-resolution one) + SurfaceClass* Get_Surface_Level(unsigned int level = 0); + IDirect3DSurface8* Get_D3D_Surface_Level(unsigned int level = 0); + void Get_Level_Description(SurfaceClass::SurfaceDescription& desc, unsigned int level = 0); + + TextureFilterClass& Get_Filter() { return Filter; } + + WW3DFormat Get_Texture_Format() const { return TextureFormat; } + + virtual void Apply(unsigned int stage); + + virtual unsigned Get_Texture_Memory_Usage() const; + + virtual TextureClass* As_TextureClass() { return this; } + +protected: + + WW3DFormat TextureFormat; + + // legacy + TextureFilterClass Filter; +}; - // State not contained in the Direct3D texture object: - TextureFilterClass Filter; +class ZTextureClass : public TextureBaseClass +{ +public: + // Create a z texture with desired height, width and format + ZTextureClass + ( + unsigned width, + unsigned height, + WW3DZFormat zformat, + MipCountType mip_level_count = MIP_LEVELS_ALL, + PoolType pool = POOL_MANAGED + ); - // Direct3D texture object - IDirect3DBaseTexture8 *D3DTexture; - bool Initialized; + WW3DZFormat Get_Texture_Format() const { return DepthStencilTextureFormat; } - // Name - StringClass Name; - StringClass FullPath; + virtual TexAssetType Get_Asset_Type() const { return TEX_REGULAR; } - // Unique id - unsigned texture_id; + virtual void Init() {} - // NOTE: Since "texture wrapping" (NOT TEXTURE WRAP MODE - THIS IS - // SOMETHING ELSE) is a global state that affects all texture stages, - // and this class only affects its own stage, we will not worry about - // it for now. Later (probably when we implement world-oriented - // environment maps) we will consider where to put it. + // Background texture loader will call this when texture has been loaded + virtual void Apply_New_Surface(IDirect3DBaseTexture8* tex, bool initialized, bool disable_auto_invalidation = false); // If the parameter is true, the texture will be flagged as initialised - // For debug purposes the texture sets this true if it is a lightmap texture - bool IsLightmap; - bool IsProcedural; - bool IsCompressionAllowed; + virtual void Apply(unsigned int stage); - mutable unsigned LastAccessed; - WW3DFormat TextureFormat; + IDirect3DSurface8* Get_D3D_Surface_Level(unsigned int level = 0); + virtual unsigned Get_Texture_Memory_Usage() const; - int Width; - int Height; +private: - // Support for self-managed textures + WW3DZFormat DepthStencilTextureFormat; +}; - PoolType Pool; - bool Dirty; +class CubeTextureClass : public TextureClass +{ public: - MipCountType MipLevelCount; - TextureLoadTaskClass* TextureLoadTask; - // Background texture loader will call this when texture has been loaded - void Apply_New_Surface(bool initialized); // If the parameter is true, the texture will be flagged as initialised + // Create texture with desired height, width and format. + CubeTextureClass + ( + unsigned width, + unsigned height, + WW3DFormat format, + MipCountType mip_level_count = MIP_LEVELS_ALL, + PoolType pool = POOL_MANAGED, + bool rendertarget = false, + bool allow_reduction = true + ); + + // Create texture from a file. If format is specified the texture is converted to that format. + // Note that the format must be supported by the current device and that a texture can't exist + // in the system with the same name in multiple formats. + CubeTextureClass + ( + const char* name, + const char* full_path = NULL, + MipCountType mip_level_count = MIP_LEVELS_ALL, + WW3DFormat texture_format = WW3D_FORMAT_UNKNOWN, + bool allow_compression = true, + bool allow_reduction = true + ); + + // Create texture from a surface. + CubeTextureClass + ( + SurfaceClass* surface, + MipCountType mip_level_count = MIP_LEVELS_ALL + ); + + CubeTextureClass(IDirect3DBaseTexture8* d3d_texture); + + virtual void Apply_New_Surface(IDirect3DBaseTexture8* tex, bool initialized, bool disable_auto_invalidation = false); // If the parameter is true, the texture will be flagged as initialised + + virtual TexAssetType Get_Asset_Type() const { return TEX_CUBEMAP; } + + virtual CubeTextureClass* As_CubeTextureClass() { return this; } }; -class BumpmapTextureClass : public TextureClass +class VolumeTextureClass : public TextureClass { public: - // Generate bumpmap texture procedurally from the source texture - BumpmapTextureClass(TextureClass* texture); - virtual ~BumpmapTextureClass(); + // Create texture with desired height, width and format. + VolumeTextureClass + ( + unsigned width, + unsigned height, + unsigned depth, + WW3DFormat format, + MipCountType mip_level_count = MIP_LEVELS_ALL, + PoolType pool = POOL_MANAGED, + bool rendertarget = false, + bool allow_reduction = true + ); + + // Create texture from a file. If format is specified the texture is converted to that format. + // Note that the format must be supported by the current device and that a texture can't exist + // in the system with the same name in multiple formats. + VolumeTextureClass + ( + const char* name, + const char* full_path = NULL, + MipCountType mip_level_count = MIP_LEVELS_ALL, + WW3DFormat texture_format = WW3D_FORMAT_UNKNOWN, + bool allow_compression = true, + bool allow_reduction = true + ); + + // Create texture from a surface. + VolumeTextureClass + ( + SurfaceClass* surface, + MipCountType mip_level_count = MIP_LEVELS_ALL + ); + + VolumeTextureClass(IDirect3DBaseTexture8* d3d_texture); + + virtual void Apply_New_Surface(IDirect3DBaseTexture8* tex, bool initialized, bool disable_auto_invalidation = false); // If the parameter is true, the texture will be flagged as initialised + + virtual TexAssetType Get_Asset_Type() const { return TEX_VOLUME; } + + virtual VolumeTextureClass* As_VolumeTextureClass() { return this; } + +protected: + + int Depth; }; // Utility functions for loading and saving texture descriptions from/to W3D files -TextureClass *Load_Texture(ChunkLoadClass & cload); -void Save_Texture(TextureClass * texture, ChunkSaveClass & csave); - -// TheSuperHackers @todo TextureBaseClass abstraction -typedef TextureClass TextureBaseClass; +TextureClass* Load_Texture(ChunkLoadClass& cload); +void Save_Texture(TextureClass* texture, ChunkSaveClass& csave); #endif //TEXTURE_H diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturefilter.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturefilter.cpp index d3b11bbe35..c8c7c0700f 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturefilter.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturefilter.cpp @@ -101,7 +101,11 @@ void TextureFilterClass::Apply(unsigned int stage) //! Init filters (legacy) /*! */ -void TextureFilterClass::_Init_Filters(void) +void TextureFilterClass::_Init_Filters() +{ + _Init_Filters((TextureFilterClass::TextureFilterMode)WW3D::Get_Texture_Filter()); +} +void TextureFilterClass::_Init_Filters(TextureFilterMode texture_filter) { const D3DCAPS8& dx8caps=DX8Wrapper::Get_Current_Caps()->Get_DX8_Caps(); diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturefilter.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturefilter.h index a4e07d84f7..8177a202f2 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturefilter.h +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturefilter.h @@ -115,7 +115,8 @@ class TextureFilterClass void Set_V_Addr_Mode(TxtAddrMode mode) { VAddressMode=mode; } // This needs to be called after device has been created - static void _Init_Filters(void); + static void _Init_Filters(TextureFilterMode texture_filter); + static void _Init_Filters(); static void _Set_Default_Min_Filter(FilterType filter); static void _Set_Default_Mag_Filter(FilterType filter); diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/textureloader.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/textureloader.cpp index 341d8e4c45..5d4e4ca457 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/textureloader.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/textureloader.cpp @@ -1,5 +1,5 @@ /* -** Command & Conquer Generals(tm) +** Command & Conquer Generals Zero Hour(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify @@ -16,6 +16,28 @@ ** 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 : DX8 Texture Manager * + * * + * $Archive:: /Commando/Code/ww3d2/textureloader.h $* + * * + * Original Author:: vss_sync * + * * + * Author : Kenny Mitchell * + * * + * $Modtime:: 08/05/02 10:03a $* + * * + * $Revision:: 3 $* + * * + * 06/27/02 KM Texture class abstraction * + * 08/05/02 KM Texture class redesign (revisited) + *---------------------------------------------------------------------------------------------* + * Functions: * + * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + #include "textureloader.h" #include "mutex.h" #include "thread.h" @@ -38,264 +60,462 @@ #include "texturethumbnail.h" #include "ddsfile.h" #include "bitmaphandler.h" +#include "wwprofile.h" + + + //#pragma optimize("", off) + //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") + +bool TextureLoader::TextureLoadSuspended; +int TextureLoader::TextureInactiveOverrideTime = 0; -static TextureLoadTaskClass* LoadListHead; -static TextureLoadTaskClass* DeferredListHead; -static TextureLoadTaskClass* FinishedListHead; -static TextureLoadTaskClass* ThumbnailListHead; -static TextureLoadTaskClass* DeleteTaskListHead; +#define USE_MANAGED_TEXTURES -TextureLoadTaskClass* TextureLoadTaskClass::FreeTaskListHead; +//////////////////////////////////////////////////////////////////////////////// +// +// TextureLoadTaskListClass implementation +// +//////////////////////////////////////////////////////////////////////////////// -static bool Is_Format_Compressed(WW3DFormat texture_format,bool allow_compression) +TextureLoadTaskListClass::TextureLoadTaskListClass(void) + : Root() { - // Verify that the user isn't requesting compressed texture without hardware support + Root.Next = Root.Prev = &Root; +} - bool compressed=false; - if (texture_format!=WW3D_FORMAT_UNKNOWN) { - if (!DX8Wrapper::Get_Current_Caps()->Support_DXTC() || !allow_compression) { - WWASSERT(texture_format!=WW3D_FORMAT_DXT1); - WWASSERT(texture_format!=WW3D_FORMAT_DXT2); - WWASSERT(texture_format!=WW3D_FORMAT_DXT3); - WWASSERT(texture_format!=WW3D_FORMAT_DXT4); - WWASSERT(texture_format!=WW3D_FORMAT_DXT5); - } - if (texture_format==WW3D_FORMAT_DXT1 || - texture_format==WW3D_FORMAT_DXT2 || - texture_format==WW3D_FORMAT_DXT3 || - texture_format==WW3D_FORMAT_DXT4 || - texture_format==WW3D_FORMAT_DXT5) { - compressed=true; - } +void TextureLoadTaskListClass::Push_Front(TextureLoadTaskClass* task) +{ + // task should non-null and not on any list + WWASSERT(task != NULL && task->Next == NULL && task->Prev == NULL); + + // update inserted task to point to list + task->Next = Root.Next; + task->Prev = &Root; + task->List = this; + + // update list to point to inserted task + Root.Next->Prev = task; + Root.Next = task; +} + +void TextureLoadTaskListClass::Push_Back(TextureLoadTaskClass* task) +{ + // task should be non-null and not on any list + WWASSERT(task != NULL && task->Next == NULL && task->Prev == NULL); + + // update inserted task to point to list + task->Next = &Root; + task->Prev = Root.Prev; + task->List = this; + + // update list to point to inserted task + Root.Prev->Next = task; + Root.Prev = task; +} + +TextureLoadTaskClass* TextureLoadTaskListClass::Pop_Front(void) +{ + // exit early if list is empty + if (Is_Empty()) { + return 0; } - // If hardware supports DXTC compression, load a compressed texture. Proceed only if the texture format hasn't been - // defined as non-compressed. - compressed|=( - texture_format==WW3D_FORMAT_UNKNOWN && - DX8Wrapper::Get_Current_Caps()->Support_DXTC() && - allow_compression); + // otherwise, grab first task and remove it. + TextureLoadTaskClass* task = (TextureLoadTaskClass*)Root.Next; + Remove(task); + return task; - return compressed; } -// ---------------------------------------------------------------------------- +TextureLoadTaskClass* TextureLoadTaskListClass::Pop_Back(void) +{ + // exit early if list is empty + if (Is_Empty()) { + return 0; + } -static CriticalSectionClass mutex; -static class LoaderThreadClass : public ThreadClass + // otherwise, grab last task and remove it. + TextureLoadTaskClass* task = (TextureLoadTaskClass*)Root.Prev; + Remove(task); + return task; +} + +void TextureLoadTaskListClass::Remove(TextureLoadTaskClass* task) +{ + // exit early if task is not on this list. + if (task->List != this) { + return; + } + + // update list to skip task + task->Prev->Next = task->Next; + task->Next->Prev = task->Prev; + + // update task to no longer point at list + task->Prev = 0; + task->Next = 0; + task->List = 0; +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// SynchronizedTextureLoadTaskListClass implementation +// +//////////////////////////////////////////////////////////////////////////////// + +SynchronizedTextureLoadTaskListClass::SynchronizedTextureLoadTaskListClass(void) + : TextureLoadTaskListClass(), + CriticalSection() +{ +} + +void SynchronizedTextureLoadTaskListClass::Push_Front(TextureLoadTaskClass* task) +{ + FastCriticalSectionClass::LockClass lock(CriticalSection); + TextureLoadTaskListClass::Push_Front(task); +} + +void SynchronizedTextureLoadTaskListClass::Push_Back(TextureLoadTaskClass* task) { - TextureLoadTaskClass* Get_Task_From_Load_List(); + FastCriticalSectionClass::LockClass lock(CriticalSection); + TextureLoadTaskListClass::Push_Back(task); +} + +TextureLoadTaskClass* SynchronizedTextureLoadTaskListClass::Pop_Front(void) +{ + // this duplicates code inside base class, but saves us an unnecessary lock. + if (Is_Empty()) { + return 0; + } + + FastCriticalSectionClass::LockClass lock(CriticalSection); + return TextureLoadTaskListClass::Pop_Front(); + +} + +TextureLoadTaskClass* SynchronizedTextureLoadTaskListClass::Pop_Back(void) +{ + // this duplicates code inside base class, but saves us an unnecessary lock. + if (Is_Empty()) { + return 0; + } + + FastCriticalSectionClass::LockClass lock(CriticalSection); + return TextureLoadTaskListClass::Pop_Back(); +} + +void SynchronizedTextureLoadTaskListClass::Remove(TextureLoadTaskClass* task) +{ + FastCriticalSectionClass::LockClass lock(CriticalSection); + TextureLoadTaskListClass::Remove(task); +} + - static void Add_Task_To_Finished_List(TextureLoadTaskClass* task); +// Locks +// To prevent deadlock, threads should acquire locks in the order in which +// they are defined below. No ordering is necessary for the task list locks, +// since one thread can never hold two at once. + +static FastCriticalSectionClass _ForegroundCriticalSection; +static FastCriticalSectionClass _BackgroundCriticalSection; + +// Lists + +static SynchronizedTextureLoadTaskListClass _ForegroundQueue; +static SynchronizedTextureLoadTaskListClass _BackgroundQueue; + +static TextureLoadTaskListClass _TexLoadFreeList; +static TextureLoadTaskListClass _CubeTexLoadFreeList; +static TextureLoadTaskListClass _VolTexLoadFreeList; + + +// The background texture loading thread. +static class LoaderThreadClass : public ThreadClass +{ public: - LoaderThreadClass() : ThreadClass() {} +#ifdef Exception_Handler + LoaderThreadClass(const char* thread_name = "Texture loader thread") : ThreadClass(thread_name, &Exception_Handler) {} +#else + LoaderThreadClass(const char* thread_name = "Texture loader thread") : ThreadClass(thread_name) {} +#endif void Thread_Function(); +} _TextureLoadThread; + + +// TODO: Legacy - remove this call! +IDirect3DTexture8* Load_Compressed_Texture( + const StringClass& filename, + unsigned reduction_factor, + MipCountType mip_level_count, + WW3DFormat dest_format) +{ + // If DDS file isn't available, use TGA file to convert to DDS. + + DDSFileClass dds_file(filename, reduction_factor); + if (!dds_file.Is_Available()) return NULL; + if (!dds_file.Load()) return NULL; - static void Add_Task_To_Load_List(TextureLoadTaskClass* task); + unsigned width = dds_file.Get_Width(0); + unsigned height = dds_file.Get_Height(0); + unsigned mips = dds_file.Get_Mip_Level_Count(); -} thread; + // If format isn't defined get the nearest valid texture format to the compressed file format + // Note that the nearest valid format could be anything, even uncompressed. + if (dest_format == WW3D_FORMAT_UNKNOWN) dest_format = Get_Valid_Texture_Format(dds_file.Get_Format(), true); + + IDirect3DTexture8* d3d_texture = DX8Wrapper::_Create_DX8_Texture + ( + width, + height, + dest_format, + (MipCountType)mips + ); + + for (unsigned level = 0; level < mips; ++level) { + IDirect3DSurface8* d3d_surface = NULL; + WWASSERT(d3d_texture); + DX8_ErrorCode(d3d_texture->GetSurfaceLevel(level/*-reduction_factor*/, &d3d_surface)); + dds_file.Copy_Level_To_Surface(level, d3d_surface); + d3d_surface->Release(); + } + return d3d_texture; +} + +static bool Is_Format_Compressed(WW3DFormat texture_format, bool allow_compression) +{ + // Verify that the user isn't requesting compressed texture without hardware support + + bool compressed = false; + if (texture_format != WW3D_FORMAT_UNKNOWN) { + if (!DX8Wrapper::Get_Current_Caps()->Support_DXTC() || !allow_compression) { + WWASSERT(texture_format != WW3D_FORMAT_DXT1); + WWASSERT(texture_format != WW3D_FORMAT_DXT2); + WWASSERT(texture_format != WW3D_FORMAT_DXT3); + WWASSERT(texture_format != WW3D_FORMAT_DXT4); + WWASSERT(texture_format != WW3D_FORMAT_DXT5); + } + if (texture_format == WW3D_FORMAT_DXT1 || + texture_format == WW3D_FORMAT_DXT2 || + texture_format == WW3D_FORMAT_DXT3 || + texture_format == WW3D_FORMAT_DXT4 || + texture_format == WW3D_FORMAT_DXT5) { + compressed = true; + } + } + + // If hardware supports DXTC compression, load a compressed texture. Proceed only if the texture format hasn't been + // defined as non-compressed. + compressed |= ( + texture_format == WW3D_FORMAT_UNKNOWN && + DX8Wrapper::Get_Current_Caps()->Support_DXTC() && + allow_compression); + + return compressed; +} -// ---------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +// +// TextureLoader implementation +// +//////////////////////////////////////////////////////////////////////////////// void TextureLoader::Init() { - WWASSERT(!thread.Is_Running()); + WWASSERT(!_TextureLoadThread.Is_Running()); - ThumbnailClass::Init(); + ThumbnailManagerClass::Init(); - thread.Execute(); - thread.Set_Priority(-3); + _TextureLoadThread.Execute(); + _TextureLoadThread.Set_Priority(-4); + TextureInactiveOverrideTime = 0; } -// ---------------------------------------------------------------------------- void TextureLoader::Deinit() { - CriticalSectionClass::LockClass m(mutex); - thread.Stop(); + FastCriticalSectionClass::LockClass lock(_BackgroundCriticalSection); + _TextureLoadThread.Stop(); - ThumbnailClass::Deinit(); + ThumbnailManagerClass::Deinit(); + TextureLoadTaskClass::Delete_Free_Pool(); +} + + +bool TextureLoader::Is_DX8_Thread(void) +{ + return (ThreadClass::_Get_Current_Thread_ID() == DX8Wrapper::_Get_Main_Thread_ID()); } + // ---------------------------------------------------------------------------- // // Modify given texture size to nearest valid size on current hardware. // // ---------------------------------------------------------------------------- -void TextureLoader::Validate_Texture_Size(unsigned& width, unsigned& height) +void TextureLoader::Validate_Texture_Size +( + unsigned& width, + unsigned& height, + unsigned& depth +) { - const D3DCAPS8& dx8caps=DX8Wrapper::Get_Current_Caps()->Get_DX8_Caps(); + const D3DCAPS8& dx8caps = DX8Wrapper::Get_Current_Caps()->Get_DX8_Caps(); unsigned poweroftwowidth = 1; - while (poweroftwowidth < width) { + while (poweroftwowidth < width) + { poweroftwowidth <<= 1; } unsigned poweroftwoheight = 1; - while (poweroftwoheight < height) { + while (poweroftwoheight < height) + { poweroftwoheight <<= 1; } -// unsigned size = MAX (width, height); -// unsigned poweroftwosize = 1; -// while (poweroftwosize < size) { -// poweroftwosize <<= 1; -// } + unsigned poweroftwodepth = 1; + while (poweroftwodepth < depth) + { + poweroftwodepth <<= 1; + } - if (poweroftwowidth>dx8caps.MaxTextureWidth) { - poweroftwowidth=dx8caps.MaxTextureWidth; + if (poweroftwowidth > dx8caps.MaxTextureWidth) + { + poweroftwowidth = dx8caps.MaxTextureWidth; + } + if (poweroftwoheight > dx8caps.MaxTextureHeight) + { + poweroftwoheight = dx8caps.MaxTextureHeight; } - if (poweroftwoheight>dx8caps.MaxTextureHeight) { - poweroftwoheight=dx8caps.MaxTextureHeight; + if (poweroftwodepth > dx8caps.MaxVolumeExtent) + { + poweroftwodepth = dx8caps.MaxVolumeExtent; } - if (poweroftwowidth>poweroftwoheight) { - while (poweroftwowidth/poweroftwoheight>8) { - poweroftwoheight*=2; + if (poweroftwowidth > poweroftwoheight) + { + while (poweroftwowidth / poweroftwoheight > 8) + { + poweroftwoheight *= 2; } } - else { - while (poweroftwoheight/poweroftwowidth>8) { - poweroftwowidth*=2; + else + { + while (poweroftwoheight / poweroftwowidth > 8) + { + poweroftwowidth *= 2; } } -// width = height = poweroftwosize; - width=poweroftwowidth; - height=poweroftwoheight; + width = poweroftwowidth; + height = poweroftwoheight; + depth = poweroftwodepth; } +IDirect3DTexture8* TextureLoader::Load_Thumbnail(const StringClass& filename, const Vector3& hsv_shift)//,WW3DFormat texture_format) +{ + WWASSERT(Is_DX8_Thread()); + ThumbnailClass* thumb = NULL; + thumb = ThumbnailManagerClass::Peek_Thumbnail_Instance_From_Any_Manager(filename); -IDirect3DTexture8* TextureLoader::Load_Thumbnail(const StringClass& filename,WW3DFormat texture_format) -{ - ThumbnailClass* thumb=ThumbnailClass::Peek_Instance(filename); + // If no thumb is found return a missing texture if (!thumb) { - thumb=W3DNEW ThumbnailClass(filename); - // If load failed, return missing texture - if (!thumb->Peek_Bitmap()) { - delete thumb; - return MissingTexture::_Get_Missing_Texture(); - } + return MissingTexture::_Get_Missing_Texture(); } - unsigned src_pitch=thumb->Get_Width()*4; // Thumbs are always 32 bits + WWASSERT(thumb->Get_Format() == WW3D_FORMAT_A4R4G4B4); + unsigned src_pitch = thumb->Get_Width() * 2; // Thumbs are always 16 bits WW3DFormat dest_format; - if (texture_format==WW3D_FORMAT_UNKNOWN) { - dest_format=Get_Valid_Texture_Format(WW3D_FORMAT_A8R8G8B8,false); // no compressed formats please + WW3DFormat texture_format = WW3D_FORMAT_UNKNOWN; + if (texture_format == WW3D_FORMAT_UNKNOWN) { + dest_format = Get_Valid_Texture_Format(WW3D_FORMAT_A4R4G4B4, false); // no compressed formats please } else { - dest_format=Get_Valid_Texture_Format(texture_format,false); // no compressed formats please - WWASSERT(dest_format==texture_format); + dest_format = Get_Valid_Texture_Format(texture_format, false); // no compressed formats please + WWASSERT(dest_format == texture_format); } - IDirect3DTexture8* d3d_texture = DX8Wrapper::_Create_DX8_Texture( + IDirect3DTexture8* sysmem_texture = DX8Wrapper::_Create_DX8_Texture( thumb->Get_Width(), thumb->Get_Height(), dest_format, - MIP_LEVELS_ALL); + MIP_LEVELS_ALL, +#ifdef USE_MANAGED_TEXTURES + D3DPOOL_MANAGED); +#else + D3DPOOL_SYSTEMMEM); +#endif - unsigned level=0; - D3DLOCKED_RECT locked_rects[12]={0}; - WWASSERT(d3d_texture->GetLevelCount()<=12); + unsigned level = 0; + D3DLOCKED_RECT locked_rects[12] = { 0 }; + WWASSERT(sysmem_texture->GetLevelCount() <= 12); // Lock all surfaces - for (level=0;levelGetLevelCount();++level) { + for (level = 0; level < sysmem_texture->GetLevelCount(); ++level) { DX8_ErrorCode( - d3d_texture->LockRect( + sysmem_texture->LockRect( level, &locked_rects[level], NULL, 0)); } - unsigned char* src_surface=thumb->Peek_Bitmap(); - WW3DFormat src_format=WW3D_FORMAT_A8R8G8B8; - unsigned width=thumb->Get_Width(); - unsigned height=thumb->Get_Height(); + unsigned char* src_surface = thumb->Peek_Bitmap(); + WW3DFormat src_format = thumb->Get_Format(); + unsigned width = thumb->Get_Width(); + unsigned height = thumb->Get_Height(); - for (level=0;levelGetLevelCount()-1;++level) { + Vector3 hsv = hsv_shift; + for (level = 0; level < sysmem_texture->GetLevelCount() - 1; ++level) { BitmapHandlerClass::Copy_Image_Generate_Mipmap( width, height, - (unsigned char*)locked_rects[level].pBits, + (unsigned char*)locked_rects[level].pBits, locked_rects[level].Pitch, dest_format, src_surface, src_pitch, src_format, - (unsigned char*)locked_rects[level+1].pBits, // mipmap - locked_rects[level+1].Pitch);// mipmap - - src_format=dest_format; - src_surface=(unsigned char*)locked_rects[level].pBits; - src_pitch=locked_rects[level].Pitch; - width>>=1; - height>>=1; + (unsigned char*)locked_rects[level + 1].pBits, // mipmap + locked_rects[level + 1].Pitch, + hsv); + hsv = Vector3(0.0f, 0.0f, 0.0f); // Only do the shift for the first level, as the mipmaps are based on it. + + src_format = dest_format; + src_surface = (unsigned char*)locked_rects[level].pBits; + src_pitch = locked_rects[level].Pitch; + width >>= 1; + height >>= 1; } // Unlock all surfaces - for (level=0;levelGetLevelCount();++level) { - DX8_ErrorCode(d3d_texture->UnlockRect(level)); - } - - return d3d_texture; -} - -static bool Is_Power_Of_Two(unsigned i) -{ - if (!i) return false; - unsigned n=i; - unsigned shift=0; - while (n) { - shift++; - n>>=1; + for (level = 0; level < sysmem_texture->GetLevelCount(); ++level) { + DX8_ErrorCode(sysmem_texture->UnlockRect(level)); } - return ((i>>(shift-1))<<(shift-1))==i; -} - -// ---------------------------------------------------------------------------- - -// TODO: Legacy - remove this call! -IDirect3DTexture8* Load_Compressed_Texture( - const StringClass& filename, - unsigned reduction_factor, - MipCountType mip_level_count, - WW3DFormat dest_format) -{ - // If DDS file isn't available, use TGA file to convert to DDS. - - DDSFileClass dds_file(filename,reduction_factor); - if (!dds_file.Is_Available()) return NULL; - if (!dds_file.Load()) return NULL; - - unsigned width=dds_file.Get_Width(0); - unsigned height=dds_file.Get_Height(0); - unsigned mips=dds_file.Get_Mip_Level_Count(); - - // If format isn't defined get the nearest valid texture format to the compressed file format - // Note that the nearest valid format could be anything, even uncompressed. - if (dest_format==WW3D_FORMAT_UNKNOWN) dest_format=Get_Valid_Texture_Format(dds_file.Get_Format(),true); - +#ifdef USE_MANAGED_TEXTURES + return sysmem_texture; +#else IDirect3DTexture8* d3d_texture = DX8Wrapper::_Create_DX8_Texture( - width, - height, + thumb->Get_Width(), + thumb->Get_Height(), dest_format, - (MipCountType)mips); + TextureBaseClass::MIP_LEVELS_ALL, + D3DPOOL_DEFAULT); + DX8CALL(UpdateTexture(sysmem_texture, d3d_texture)); + sysmem_texture->Release(); - for (unsigned level=0;levelGetSurfaceLevel(level/*-reduction_factor*/,&d3d_surface)); - dds_file.Copy_Level_To_Surface(level,d3d_surface); - d3d_surface->Release(); - } + WWDEBUG_SAY(("Created non-managed texture (%s)", filename)); return d3d_texture; +#endif } + // ---------------------------------------------------------------------------- // // Load image to a surface. The function tries to create texture that matches @@ -308,13 +528,15 @@ IDirect3DSurface8* TextureLoader::Load_Surface_Immediate( WW3DFormat texture_format, bool allow_compression) { - bool compressed=Is_Format_Compressed(texture_format,allow_compression); + WWASSERT(Is_DX8_Thread()); + + bool compressed = Is_Format_Compressed(texture_format, allow_compression); if (compressed) { - IDirect3DTexture8* comp_tex=Load_Compressed_Texture(filename,0,MIP_LEVELS_1,WW3D_FORMAT_UNKNOWN); + IDirect3DTexture8* comp_tex = Load_Compressed_Texture(filename, 0, MIP_LEVELS_1, WW3D_FORMAT_UNKNOWN); if (comp_tex) { - IDirect3DSurface8* d3d_surface=NULL; - DX8_ErrorCode(comp_tex->GetSurfaceLevel(0,&d3d_surface)); + IDirect3DSurface8* d3d_surface = NULL; + DX8_ErrorCode(comp_tex->GetSurfaceLevel(0, &d3d_surface)); comp_tex->Release(); return d3d_surface; } @@ -322,63 +544,63 @@ IDirect3DSurface8* TextureLoader::Load_Surface_Immediate( // Make sure the file can be opened. If not, return missing texture. Targa targa; - if (TARGA_ERROR_HANDLER(targa.Open(filename, TGA_READMODE),filename)) return MissingTexture::_Create_Missing_Surface(); + if (TARGA_ERROR_HANDLER(targa.Open(filename, TGA_READMODE), filename)) return MissingTexture::_Create_Missing_Surface(); // DX8 uses image upside down compared to TGA targa.Header.ImageDescriptor ^= TGAIDF_YORIGIN; - WW3DFormat src_format,dest_format; - unsigned src_bpp=0; - Get_WW3D_Format(dest_format,src_format,src_bpp,targa); + WW3DFormat src_format, dest_format; + unsigned src_bpp = 0; + Get_WW3D_Format(dest_format, src_format, src_bpp, targa); - if (texture_format!=WW3D_FORMAT_UNKNOWN) { - dest_format=texture_format; + if (texture_format != WW3D_FORMAT_UNKNOWN) { + dest_format = texture_format; } // Destination size will be the next power of two square from the larger width and height... unsigned width, height; - width=targa.Header.Width; - height=targa.Header.Height; - unsigned src_width=targa.Header.Width; - unsigned src_height=targa.Header.Height; + width = targa.Header.Width; + height = targa.Header.Height; + unsigned src_width = targa.Header.Width; + unsigned src_height = targa.Header.Height; // NOTE: We load the palette but we do not yet support paletted textures! - char palette[256*4]; + char palette[256 * 4]; targa.SetPalette(palette); - if (TARGA_ERROR_HANDLER(targa.Load(filename, TGAF_IMAGE, false),filename)) return MissingTexture::_Create_Missing_Surface(); + if (TARGA_ERROR_HANDLER(targa.Load(filename, TGAF_IMAGE, false), filename)) return MissingTexture::_Create_Missing_Surface(); - unsigned char* src_surface=(unsigned char*)targa.GetImage(); + unsigned char* src_surface = (unsigned char*)targa.GetImage(); // No paletted destination format allowed - unsigned char* converted_surface=NULL; - if (src_format==WW3D_FORMAT_A1R5G5B5 || src_format==WW3D_FORMAT_R5G6B5 || src_format==WW3D_FORMAT_A4R4G4B4 || - src_format==WW3D_FORMAT_P8 || src_format==WW3D_FORMAT_L8 || src_width!=width || src_height!=height) { - converted_surface=W3DNEWARRAY unsigned char[width*height*4]; - dest_format=Get_Valid_Texture_Format(WW3D_FORMAT_A8R8G8B8,false); + unsigned char* converted_surface = NULL; + if (src_format == WW3D_FORMAT_A1R5G5B5 || src_format == WW3D_FORMAT_R5G6B5 || src_format == WW3D_FORMAT_A4R4G4B4 || + src_format == WW3D_FORMAT_P8 || src_format == WW3D_FORMAT_L8 || src_width != width || src_height != height) { + converted_surface = W3DNEWARRAY unsigned char[width * height * 4]; + dest_format = Get_Valid_Texture_Format(WW3D_FORMAT_A8R8G8B8, false); BitmapHandlerClass::Copy_Image( - converted_surface, + converted_surface, width, height, - width*4, + width * 4, WW3D_FORMAT_A8R8G8B8,//dest_format, src_surface, src_width, src_height, - src_width*src_bpp, + src_width * src_bpp, src_format, (unsigned char*)targa.GetPalette(), - targa.Header.CMapDepth>>3, + targa.Header.CMapDepth >> 3, false); - src_surface=converted_surface; - src_format=WW3D_FORMAT_A8R8G8B8;//dest_format; - src_width=width; - src_height=height; - src_bpp=Get_Bytes_Per_Pixel(src_format); + src_surface = converted_surface; + src_format = WW3D_FORMAT_A8R8G8B8;//dest_format; + src_width = width; + src_height = height; + src_bpp = Get_Bytes_Per_Pixel(src_format); } - unsigned src_pitch=src_width*src_bpp; + unsigned src_pitch = src_width * src_bpp; - IDirect3DSurface8* d3d_surface = DX8Wrapper::_Create_DX8_Surface(width,height,dest_format); + IDirect3DSurface8* d3d_surface = DX8Wrapper::_Create_DX8_Surface(width, height, dest_format); WWASSERT(d3d_surface); D3DLOCKED_RECT locked_rect; DX8_ErrorCode( @@ -388,7 +610,7 @@ IDirect3DSurface8* TextureLoader::Load_Surface_Immediate( 0)); BitmapHandlerClass::Copy_Image( - (unsigned char*)locked_rect.pBits, + (unsigned char*)locked_rect.pBits, width, height, locked_rect.Pitch, @@ -399,7 +621,7 @@ IDirect3DSurface8* TextureLoader::Load_Surface_Immediate( src_pitch, src_format, (unsigned char*)targa.GetPalette(), - targa.Header.CMapDepth>>3, + targa.Header.CMapDepth >> 3, false); // No mipmap DX8_ErrorCode(d3d_surface->UnlockRect()); @@ -410,967 +632,2206 @@ IDirect3DSurface8* TextureLoader::Load_Surface_Immediate( } -// ---------------------------------------------------------------------------- -// -// Load mipmap levels to a pre-generated and locked texture object based on -// information in load task object. Try loading from a DDS file first and if -// that fails try a TGA. -// -// ---------------------------------------------------------------------------- - -void TextureLoader::Load_Mipmap_Levels(TextureLoadTaskClass* task) +void TextureLoader::Request_Thumbnail(TextureBaseClass* tc) { - WWASSERT(task->Peek_D3D_Texture()); - WWMEMLOG(MEM_TEXTURE); + // Grab the foreground lock. This prevents the foreground thread + // from retiring any tasks related to this texture. It also + // serializes calls to Request_Thumbnail from multiple threads. + FastCriticalSectionClass::LockClass lock(_ForegroundCriticalSection); - if (task->Peek_Texture()->Is_Compression_Allowed()) { - DDSFileClass dds_file(task->Peek_Texture()->Get_Full_Path(),task->Get_Reduction()); - if (dds_file.Is_Available() && dds_file.Load()) { - unsigned width=task->Get_Width(); - unsigned height=task->Get_Height(); - for (unsigned level=0;levelGet_Mip_Level_Count();++level) { - WWASSERT(width && height); - dds_file.Copy_Level_To_Surface( - level, - task->Get_Format(), - width, - height, - task->Get_Locked_Surface_Ptr(level), - task->Get_Locked_Surface_Pitch(level)); - width>>=1; - height>>=1; - } - return; - } + // Has a Direct3D texture already been loaded? + if (tc->Peek_D3D_Base_Texture()) { + return; } - if (Load_Uncompressed_Mipmap_Levels_From_TGA(task)) return; -} - -// ---------------------------------------------------------------------------- -// -// Use load task to load texture surface from a targa file. Calculate mipmaps -// if needed. -// -// ---------------------------------------------------------------------------- -bool TextureLoader::Load_Uncompressed_Mipmap_Levels_From_TGA(TextureLoadTaskClass* task) -{ - if (!task->Get_Mip_Level_Count()) return false; - TextureBaseClass* texture=task->Peek_Texture(); + TextureLoadTaskClass* task = tc->ThumbnailLoadTask; - Targa targa; - if (TARGA_ERROR_HANDLER(targa.Open(texture->Get_Full_Path(), TGA_READMODE),texture->Get_Full_Path())) { - task->Set_Fail(true); - return false; - } - // DX8 uses image upside down compared to TGA - targa.Header.ImageDescriptor ^= TGAIDF_YORIGIN; + if (Is_DX8_Thread()) { + // load the thumbnail immediately + TextureLoader::Load_Thumbnail(tc); - WW3DFormat src_format,dest_format; - unsigned src_bpp=0; - Get_WW3D_Format(dest_format,src_format,src_bpp,targa); -// WWASSERT(task->Get_Format()==dest_format); - dest_format=task->Get_Format(); // Texture can be requested in different format than the most obvious from the TGA + // clear any pending thumbnail load + if (task) { + _ForegroundQueue.Remove(task); + task->Destroy(); + } - char palette[256*4]; - targa.SetPalette(palette); + } + else { + TextureLoadTaskClass* load_task = tc->TextureLoadTask; - unsigned src_width=targa.Header.Width; - unsigned src_height=targa.Header.Height; - unsigned width=task->Get_Width(); - unsigned height=task->Get_Height(); + // if texture is not already loading a thumbnail and there is no + // background load near completion. (a background load waiting + // to be applied will be ready at the same time as a queued thumbnail. + // Why do the extra work?) + if (!task && (!load_task || load_task->Get_State() < TextureLoadTaskClass::STATE_LOAD_MIPMAP)) { - // NOTE: We load the palette but we do not yet support paletted textures! - if (TARGA_ERROR_HANDLER(targa.Load(texture->Get_Full_Path(), TGAF_IMAGE, false),texture->Get_Full_Path())) { - task->Set_Fail(true); - return false; + // create a thumbnail load task and add to foreground queue. + task = TextureLoadTaskClass::Create(tc, TextureLoadTaskClass::TASK_THUMBNAIL, TextureLoadTaskClass::PRIORITY_LOW); + _ForegroundQueue.Push_Back(task); + } } - unsigned char* src_surface=(unsigned char*)targa.GetImage(); +} - // No paletted format allowed when generating mipmaps - unsigned char* converted_surface=NULL; - if (src_format==WW3D_FORMAT_A1R5G5B5 || src_format==WW3D_FORMAT_R5G6B5 || src_format==WW3D_FORMAT_A4R4G4B4 || - src_format==WW3D_FORMAT_P8 || src_format==WW3D_FORMAT_L8 || src_width!=width || src_height!=height) { - converted_surface=W3DNEWARRAY unsigned char[width*height*4]; - dest_format=Get_Valid_Texture_Format(WW3D_FORMAT_A8R8G8B8,false); - BitmapHandlerClass::Copy_Image( - converted_surface, - width, - height, - width*4, - WW3D_FORMAT_A8R8G8B8, //dest_format, - src_surface, - src_width, - src_height, - src_width*src_bpp, - src_format, - (unsigned char*)targa.GetPalette(), - targa.Header.CMapDepth>>3, - false); - src_surface=converted_surface; - src_format=WW3D_FORMAT_A8R8G8B8; //dest_format; - src_width=width; - src_height=height; - src_bpp=Get_Bytes_Per_Pixel(src_format); - } - unsigned src_pitch=src_width*src_bpp; +void TextureLoader::Request_Background_Loading(TextureBaseClass* tc) +{ + WWPROFILE(("TextureLoader::Request_Background_Loading()")); + // Grab the foreground lock. This prevents the foreground thread + // from retiring any tasks related to this texture. It also + // serializes calls to Request_Background_Loading from other + // threads. + FastCriticalSectionClass::LockClass foreground_lock(_ForegroundCriticalSection); + + // Has the texture already been loaded? + if (tc->Is_Initialized()) { + return; + } - for (unsigned level=0;levelGet_Mip_Level_Count();++level) { - WWASSERT(task->Get_Locked_Surface_Ptr(level)); - BitmapHandlerClass::Copy_Image( - task->Get_Locked_Surface_Ptr(level), - width, - height, - task->Get_Locked_Surface_Pitch(level), - task->Get_Format(), - src_surface, - src_width, - src_height, - src_pitch, - src_format, - NULL, - 0, - true); + TextureLoadTaskClass* task = tc->TextureLoadTask; - width>>=1; - height>>=1; - src_width>>=1; - src_height>>=1; - if (!width || !height || !src_width || !src_height) break; + // if texture already has a load task, we don't need to create another one. + if (task) { + return; } - if (converted_surface) delete[] converted_surface; + task = TextureLoadTaskClass::Create(tc, TextureLoadTaskClass::TASK_LOAD, TextureLoadTaskClass::PRIORITY_LOW); - return true; + if (Is_DX8_Thread()) { + Begin_Load_And_Queue(task); + } + else { + _ForegroundQueue.Push_Back(task); + } } -// ---------------------------------------------------------------------------- -// -// Return a task from the load list head. The loading thread uses this function -// to retrieve tasks from the load list. -// -// ---------------------------------------------------------------------------- -TextureLoadTaskClass* LoaderThreadClass::Get_Task_From_Load_List() +void TextureLoader::Request_Foreground_Loading(TextureBaseClass* tc) { - CriticalSectionClass::LockClass m(mutex); - - TextureLoadTaskClass* task=LoadListHead; - if (task) { - LoadListHead=task->Peek_Succ(); - task->Set_Succ(NULL); + WWPROFILE(("TextureLoader::Request_Foreground_Loading()")); + // Grab the foreground lock. This prevents the foreground thread + // from retiring the load tasks for this texture. It also + // serializes calls to Request_Foreground_Loading from other + // threads. + FastCriticalSectionClass::LockClass foreground_lock(_ForegroundCriticalSection); + + // Has the texture already been loaded? + if (tc->Is_Initialized()) { + return; } - return task; -} -// ---------------------------------------------------------------------------- -// -// This function adds a load task to the head of the loading thread task list. -// The latest added task will be the next processed (There are good reasons -// for such ordering). The loading thread will process tasks from this list -// as soons as it can and then move the tasks to finished list. -// -// ---------------------------------------------------------------------------- + TextureLoadTaskClass* task = tc->TextureLoadTask; + TextureLoadTaskClass* task_thumb = tc->ThumbnailLoadTask; -void LoaderThreadClass::Add_Task_To_Load_List(TextureLoadTaskClass* task) -{ - CriticalSectionClass::LockClass m(mutex); + if (Is_DX8_Thread()) { - WWASSERT(task->Peek_Succ()==NULL); + // since we're in the DX8 thread, we can load the entire + // texture right now. - task->Set_Succ(LoadListHead); - LoadListHead=task; -} + // if we have a thumbnail task waiting, kill it. + if (task_thumb) { + _ForegroundQueue.Remove(task_thumb); + task_thumb->Destroy(); + } -// ---------------------------------------------------------------------------- -// -// After the loading thread is done with the texture, it is moved to the list -// of finished tasks so that the main thread can then finish up by unlocking -// the surfaces and applying the changes to the texture class object. -// -// ---------------------------------------------------------------------------- + if (task) { + // we need to remove the task from any queue, since we're going + // to finish it up right now. + + // halt background thread. After we're holding this lock, + // we know the background thread cannot begin loading + // mipmap levels for this texture. + FastCriticalSectionClass::LockClass background_lock(_BackgroundCriticalSection); + _ForegroundQueue.Remove(task); + _BackgroundQueue.Remove(task); + } + else { + // Since the task manages all the state associated with loading + // a texture, we temporarily create one. + task = TextureLoadTaskClass::Create(tc, TextureLoadTaskClass::TASK_LOAD, TextureLoadTaskClass::PRIORITY_HIGH); + } -void LoaderThreadClass::Add_Task_To_Finished_List(TextureLoadTaskClass* task) -{ - CriticalSectionClass::LockClass m(mutex); + // finish loading the task and destroy it. + task->Finish_Load(); + task->Destroy(); - WWASSERT(task->Peek_Succ()==NULL); + } + else { + // we are not in the DX8 thread. We need to add a high-priority loading + // task to the foreground queue. + + // Grab the background lock. After we're holding this lock, we + // know the background thread cannot begin loading mipmap levels + // for this texture. + FastCriticalSectionClass::LockClass background_lock(_BackgroundCriticalSection); + + // if we have a thumbnail task, we should cancel it. Since we are not + // the foreground thread, we are not allowed to call Destroy(). Instead, + // leave it queued in the completed state so it will be destroyed by Update(). + if (task_thumb) { + task_thumb->Set_State(TextureLoadTaskClass::STATE_COMPLETE); + } - task->Set_Succ(FinishedListHead); - FinishedListHead=task; -} + if (task) { + // if a load task is waiting on the background queue, we need to + // move it to the foreground queue. + if (task->Get_List() == &_BackgroundQueue) { -// ---------------------------------------------------------------------------- -// -// If we need to find out if the load task list is empty this is the function -// to use. We can't use Get_Task_From_Load_List() as if the list isn't empty -// it also removes the head node from the list. -// -// ---------------------------------------------------------------------------- + // remove task from list + _BackgroundQueue.Remove(task); -bool Is_Load_List_Empty() -{ - return !LoadListHead; -} -// ---------------------------------------------------------------------------- -// -// Texture loading thread loads textures that appear in loading_task_list. -// If the list is empty the thread sleeps. -// -// ---------------------------------------------------------------------------- + // add to foreground queue. + _ForegroundQueue.Push_Back(task); + } + + // upgrade the task priority + task->Set_Priority(TextureLoadTaskClass::PRIORITY_HIGH); -void LoaderThreadClass::Thread_Function() -{ - while (running) { - TextureLoadTaskClass* task=Get_Task_From_Load_List(); - if (task) { - TextureLoader::Load_Mipmap_Levels(task); - Add_Task_To_Finished_List(task); } + else { + // allocate high priority load task + task = TextureLoadTaskClass::Create(tc, TextureLoadTaskClass::TASK_LOAD, TextureLoadTaskClass::PRIORITY_HIGH); - Switch_Thread(); + // add to back of foreground queue. + _ForegroundQueue.Push_Back(task); + } } } -// ---------------------------------------------------------------------------- -// -// Update refreshes all completed texture loading tasks -// -// ---------------------------------------------------------------------------- -TextureLoadTaskClass* Get_Finished_Task() +void TextureLoader::Flush_Pending_Load_Tasks(void) { - CriticalSectionClass::LockClass m(mutex); + // This function can only be called from the main thread. + // (Only the main thread can make the DX8 calls necessary + // to complete texture loading. If we wanted to flush + // the pending tasks from another thread, we'd probably + // want to set a bool that is checked by Update(). + WWASSERT(Is_DX8_Thread()); - TextureLoadTaskClass* task=FinishedListHead; - if (task) { - FinishedListHead=task->Peek_Succ(); - task->Set_Succ(NULL); - } - return task; -} + for (;;) { + bool done = false; -TextureLoadTaskClass* Get_Thumbnail_Task() -{ - CriticalSectionClass::LockClass m(mutex); + { + // we have no pending load tasks when both queues are empty + // and the background thread is not processing a texture. + + // Grab the background lock. Once we're holding it, we + // know that the background thread is not processing any + // textures. + + // NOTE: It's important that we do only hold on to the background + // lock while we check for completion. Otherwise, we will either + // violate the lock order when we call Update() (which grabs + // the foreground lock) or never give the background thread + // a chance to empty its queue. + FastCriticalSectionClass::LockClass background_lock(_BackgroundCriticalSection); + done = _BackgroundQueue.Is_Empty() && _ForegroundQueue.Is_Empty(); + } - TextureLoadTaskClass* task=ThumbnailListHead; - if (task) { - ThumbnailListHead=task->Peek_Succ(); - task->Set_Succ(NULL); + // exit loop if no entries in list + if (done) { + break; + } + + Update(); + ThreadClass::Switch_Thread(); } - return task; } -void Add_Thumbnail_Task(TextureLoadTaskClass* task) -{ - CriticalSectionClass::LockClass m(mutex); - - WWASSERT(task->Peek_Succ()==NULL); - task->Set_Succ(ThumbnailListHead); - ThumbnailListHead=task; +// Nework update macro for texture loader. +#pragma warning(disable:4201) // warning C4201: nonstandard extension used : nameless struct/union +#include +#define UPDATE_NETWORK \ + if (network_callback) { \ + unsigned long time2 = timeGetTime(); \ + if (time2 - time > 20) { \ + network_callback(); \ + time = time2; \ + } \ + } \ -} - -// ---------------------------------------------------------------------------- -// -// The main thread's update function deletes tasks from the load task list -// once a frame. -// -// ---------------------------------------------------------------------------- -TextureLoadTaskClass* Get_Task_From_Delete_List() +void TextureLoader::Update(void (*network_callback)(void)) { - WWASSERT(ThreadClass::_Get_Current_Thread_ID()==DX8Wrapper::_Get_Main_Thread_ID()); + WWASSERT_PRINT(Is_DX8_Thread(), "TextureLoader::Update must be called from the main thread!"); - TextureLoadTaskClass* task=DeleteTaskListHead; - if (task) { - DeleteTaskListHead=task->Peek_Succ(); - task->Set_Succ(NULL); + if (TextureLoadSuspended) { + return; } - return task; -} -// ---------------------------------------------------------------------------- -// -// When task wants to delete itself it adds itself to a delete list. This list -// can only be accessed from the main thread. -// -// ---------------------------------------------------------------------------- + // grab foreground lock to prevent any other thread from + // modifying texture tasks. + FastCriticalSectionClass::LockClass lock(_ForegroundCriticalSection); -void Add_Task_To_Delete_List(TextureLoadTaskClass* task) -{ - WWASSERT(ThreadClass::_Get_Current_Thread_ID()==DX8Wrapper::_Get_Main_Thread_ID()); + unsigned long time = timeGetTime(); + + // while we have tasks on the foreground queue + while (TextureLoadTaskClass* task = _ForegroundQueue.Pop_Front()) { + UPDATE_NETWORK; + // dispatch to proper task handler + switch (task->Get_Type()) { + case TextureLoadTaskClass::TASK_THUMBNAIL: + Process_Foreground_Thumbnail(task); + break; - WWASSERT(task->Peek_Succ()==NULL); + case TextureLoadTaskClass::TASK_LOAD: + Process_Foreground_Load(task); + break; + } + } - task->Set_Succ(DeleteTaskListHead); - DeleteTaskListHead=task; + TextureBaseClass::Invalidate_Old_Unused_Textures(TextureInactiveOverrideTime); } -TextureLoadTaskClass* Get_Deferred_Task() +void TextureLoader::Suspend_Texture_Load() { - CriticalSectionClass::LockClass m(mutex); - - TextureLoadTaskClass* task=DeferredListHead; - if (task) { - DeferredListHead=task->Peek_Succ(); - task->Set_Succ(NULL); - } - return task; + WWASSERT_PRINT(Is_DX8_Thread(), "TextureLoader::Suspend_Texture_Load must be called from the main thread!"); + TextureLoadSuspended = true; } -void Add_Deferred_Task(TextureLoadTaskClass* task) +void TextureLoader::Continue_Texture_Load() { - CriticalSectionClass::LockClass m(mutex); - - WWASSERT(task->Peek_Succ()==NULL); - task->Set_Succ(DeferredListHead); - DeferredListHead=task; + WWASSERT_PRINT(Is_DX8_Thread(), "TextureLoader::Continue_Texture_Load must be called from the main thread!"); + TextureLoadSuspended = false; } -void TextureLoader::Flush_Pending_Load_Tasks() +void TextureLoader::Process_Foreground_Thumbnail(TextureLoadTaskClass* task) { - while (!Is_Load_List_Empty()) { - Update(); - ThreadClass::Switch_Thread(); + switch (task->Get_State()) { + case TextureLoadTaskClass::STATE_NONE: + Load_Thumbnail(task->Peek_Texture()); + FALLTHROUGH; // NOTE: fall-through is intentional + + case TextureLoadTaskClass::STATE_COMPLETE: + task->Destroy(); + break; } } -void TextureLoader::Update() -{ - WWASSERT_PRINT(DX8Wrapper::_Get_Main_Thread_ID()==ThreadClass::_Get_Current_Thread_ID(),"TextureLoader::Update must be called from the main thread!"); - while (TextureLoadTaskClass* task=Get_Deferred_Task()) { - task->Begin_Texture_Load(); // This will add the task to load list +void TextureLoader::Process_Foreground_Load(TextureLoadTaskClass* task) +{ + // Is high-priority task? + if (task->Get_Priority() == TextureLoadTaskClass::PRIORITY_HIGH) { + task->Finish_Load(); + task->Destroy(); + return; } - while (TextureLoadTaskClass* task=Get_Finished_Task()) { - task->End_Load(); - task->Apply(true); - TextureLoadTaskClass::Release_Instance(task); - } + // otherwise, must be a low-priority task. - while (TextureLoadTaskClass* task=Get_Thumbnail_Task()) { - task->Begin_Thumbnail_Load(); - } + switch (task->Get_State()) { + case TextureLoadTaskClass::STATE_NONE: + Begin_Load_And_Queue(task); + break; - while (TextureLoadTaskClass* task=Get_Task_From_Delete_List()) { -// delete task; - TextureLoadTaskClass::Release_Instance(task); + case TextureLoadTaskClass::STATE_LOAD_MIPMAP: + task->End_Load(); + task->Destroy(); + break; } } -// ---------------------------------------------------------------------------- - -static DWORD VectortoRGBA( D3DXVECTOR3* v, FLOAT fHeight ) -{ - DWORD r = (DWORD)( 127.0f * v->x + 128.0f ); - DWORD g = (DWORD)( 127.0f * v->y + 128.0f ); - DWORD b = (DWORD)( 127.0f * v->z + 128.0f ); - DWORD a = (DWORD)( 255.0f * fHeight ); - - return( (a<<24L) + (r<<16L) + (g<<8L) + (b<<0L) ); -} -IDirect3DTexture8* TextureLoader::Generate_Bumpmap(TextureBaseClass* texture) +void TextureLoader::Begin_Load_And_Queue(TextureLoadTaskClass* task) { - WW3DFormat bump_format=WW3D_FORMAT_U8V8; - if (!DX8Wrapper::Get_Current_Caps()->Support_Texture_Format(bump_format)) { - return MissingTexture::_Get_Missing_Texture(); + // should only be called from the DX8 thread. + WWASSERT(Is_DX8_Thread()); + + if (task->Begin_Load()) { + // add to front of background queue. This means the + // background load thread will service tasks in LIFO + // (last in, first out) order. + + // NOTE: this was how the old code did it, with a + // comment that mentioned good reasons for doing so, + // without actually listing the reasons. I suspect + // it has something to do with visually important textures, + // like those in the foreground, starting their load last. + _BackgroundQueue.Push_Front(task); } + else { + // unable to load. + task->Apply_Missing_Texture(); + task->Destroy(); + } +} - D3DSURFACE_DESC desc; - IDirect3DTexture8* src_d3d_tex=texture->Peek_D3D_Texture(); - WWASSERT(src_d3d_tex); - DX8_ErrorCode(src_d3d_tex->GetLevelDesc(0,&desc)); - unsigned width=desc.Width; - unsigned height=desc.Height; - - IDirect3DTexture8* d3d_texture = DX8Wrapper::_Create_DX8_Texture( - width, - height, - bump_format, - MIP_LEVELS_1); - - D3DLOCKED_RECT src_locked_rect; - DX8_ErrorCode( - texture->Peek_D3D_Texture()->LockRect( - 0, - &src_locked_rect, - NULL, - D3DLOCK_READONLY)); - D3DLOCKED_RECT dest_locked_rect; - DX8_ErrorCode( - d3d_texture->LockRect( - 0, - &dest_locked_rect, - NULL, - 0)); +void TextureLoader::Load_Thumbnail(TextureBaseClass* tc) +{ + // All D3D operations must run from main thread + WWASSERT(Is_DX8_Thread()); - WW3DFormat format=D3DFormat_To_WW3DFormat(desc.Format); - unsigned bpp=Get_Bytes_Per_Pixel(format); + // load thumbnail texture + IDirect3DTexture8* d3d_texture = Load_Thumbnail(tc->Get_Full_Path(), tc->Get_HSV_Shift()); - for( unsigned y=0; yGet_Asset_Type() == TextureBaseClass::TEX_REGULAR) { - unsigned char* dest_ptr = (unsigned char*)dest_locked_rect.pBits; - dest_ptr+=y*dest_locked_rect.Pitch; - unsigned char* src_ptr_mid = (unsigned char*)src_locked_rect.pBits; - src_ptr_mid+=y*src_locked_rect.Pitch; - unsigned char* src_ptr_next_line = ( src_ptr_mid + src_locked_rect.Pitch ); - unsigned char* src_ptr_prev_line = ( src_ptr_mid - src_locked_rect.Pitch ); - - if( y == desc.Height-1 ) // Don't go past the last line - src_ptr_next_line = src_ptr_mid; - if( y == 0 ) // Don't go before first line - src_ptr_prev_line = src_ptr_mid; - - for( unsigned x=0; x1 ) ? 63 : 127; + tc->Apply_New_Surface(d3d_texture, false); + } - switch( bump_format ) - { - case WW3D_FORMAT_U8V8: - *dest_ptr++ = (unsigned char)iDu; - *dest_ptr++ = (unsigned char)iDv; - break; + // release our reference to thumbnail texture + d3d_texture->Release(); + d3d_texture = 0; +} - case WW3D_FORMAT_L6V5U5: - *(unsigned short*)dest_ptr = (unsigned short)( ( (iDu>>3) & 0x1f ) << 0 ); - *(unsigned short*)dest_ptr |= (unsigned short)( ( (iDv>>3) & 0x1f ) << 5 ); - *(unsigned short*)dest_ptr |= (unsigned short)( ( ( uL>>2) & 0x3f ) << 10 ); - dest_ptr += 2; - break; - case WW3D_FORMAT_X8L8V8U8: - *dest_ptr++ = (unsigned char)iDu; - *dest_ptr++ = (unsigned char)iDv; - *dest_ptr++ = (unsigned char)uL; - *dest_ptr++ = (unsigned char)0L; - break; +void LoaderThreadClass::Thread_Function(void) +{ + while (running) { + // if there are no tasks on the background queue, no need to grab background lock. + if (!_BackgroundQueue.Is_Empty()) { + // Grab background load so other threads know we could be + // loading a texture. + FastCriticalSectionClass::LockClass lock(_BackgroundCriticalSection); + + // try to remove a task from the background queue. This could fail + // if another thread modified the queue between our test above and + // grabbing the lock. + TextureLoadTaskClass* task = _BackgroundQueue.Pop_Front(); + if (task) { + // verify task is in proper state for background processing. + WWASSERT(task->Get_Type() == TextureLoadTaskClass::TASK_LOAD); + WWASSERT(task->Get_State() == TextureLoadTaskClass::STATE_LOAD_BEGUN); + + // load mip map levels and return to foreground queue for final step. + task->Load(); + _ForegroundQueue.Push_Back(task); } - - // Move one pixel to the left (src is 32-bpp) - src_ptr_mid+=bpp; - src_ptr_prev_line+=bpp; - src_ptr_next_line+=bpp; } - } - DX8_ErrorCode(d3d_texture->UnlockRect(0)); - DX8_ErrorCode(texture->Peek_D3D_Texture()->UnlockRect(0)); - return d3d_texture; + Switch_Thread(); + } } -// ---------------------------------------------------------------------------- -// -// Public texture request functions. These functions can be used to request -// texture loading. -// -// ---------------------------------------------------------------------------- -void TextureLoader::Add_Load_Task(TextureBaseClass* tc) +//////////////////////////////////////////////////////////////////////////////// +// +// TextureLoaderTaskClass implementation +// +//////////////////////////////////////////////////////////////////////////////// + +TextureLoadTaskClass::TextureLoadTaskClass() + : Texture(0), + D3DTexture(0), + Format(WW3D_FORMAT_UNKNOWN), + Width(0), + Height(0), + MipLevelCount(0), + Reduction(0), + Type(TASK_NONE), + Priority(PRIORITY_LOW), + State(STATE_NONE), + HSVShift(0.0f, 0.0f, 0.0f) { - // If the texture is already being loaded we just exit here. - if (tc->TextureLoadTask) return; + // because texture load tasks are pooled, the constructor and destructor + // don't need to do much. The work of attaching a task to a texture is + // is done by Init() and Deinit(). - TextureLoadTaskClass* task=TextureLoadTaskClass::Get_Instance(tc,false); - task->Begin_Texture_Load(); + for (int i = 0; i < MIP_LEVELS_MAX; ++i) { + LockedSurfacePtr[i] = NULL; + LockedSurfacePitch[i] = 0; + } } -// ---------------------------------------------------------------------------- -void TextureLoader::Request_High_Priority_Loading( - TextureBaseClass* tc, - MipCountType mip_level_count) +TextureLoadTaskClass::~TextureLoadTaskClass(void) { - TextureLoadTaskClass* task=TextureLoadTaskClass::Get_Instance(tc,true); - task->Begin_Texture_Load(); + Deinit(); } -// ---------------------------------------------------------------------------- -void TextureLoader::Request_Thumbnail(TextureBaseClass* tc) +TextureLoadTaskClass* TextureLoadTaskClass::Create(TextureBaseClass* tc, TaskType type, PriorityType priority) { - // If the texture is already being loaded we just exit here. - if (tc->TextureLoadTask) return; + // recycle or create a new texture load task with the given type + // and priority, then associate the texture with the task. - TextureLoadTaskClass* task=TextureLoadTaskClass::Get_Instance(tc,false); - task->Begin_Thumbnail_Load(); + // pull a load task from front of free list + TextureLoadTaskClass* task = NULL; + switch (tc->Get_Asset_Type()) + { + case TextureBaseClass::TEX_REGULAR: task = _TexLoadFreeList.Pop_Front(); break; + case TextureBaseClass::TEX_CUBEMAP: task = _CubeTexLoadFreeList.Pop_Front(); break; + case TextureBaseClass::TEX_VOLUME: task = _VolTexLoadFreeList.Pop_Front(); break; + default: WWASSERT(0); + }; + + // if no tasks on free list, allocate a new task + if (!task) + { + switch (tc->Get_Asset_Type()) + { + case TextureBaseClass::TEX_REGULAR: task = new TextureLoadTaskClass; break; + case TextureBaseClass::TEX_CUBEMAP: task = new CubeTextureLoadTaskClass; break; + case TextureBaseClass::TEX_VOLUME: task = new VolumeTextureLoadTaskClass; break; + default: WWASSERT(0); + } + } + task->Init(tc, type, priority); + return task; } -// ---------------------------------------------------------------------------- -// -// Texture loader task handler -// -// ---------------------------------------------------------------------------- -TextureLoadTaskClass::TextureLoadTaskClass() - : - Texture(0), - Succ(0), - D3DTexture(0), - Width(0), - Height(0), - Format(WW3D_FORMAT_UNKNOWN), - IsLoading(false), - HasFailed(false), - MipLevelCount(0), - HighPriorityRequested(false), - Reduction(0) +void TextureLoadTaskClass::Destroy(void) { + // detach the task from its texture, and return to free pool. + Deinit(); + _TexLoadFreeList.Push_Front(this); } -// ---------------------------------------------------------------------------- -// -// Destruct texture load task. The load task deinitialization will fail from -// any other than the main thread so the task must be either deleted from the -// main thread or deinitialized in the main thread prior to deleting it in -// another thread. -// -// ---------------------------------------------------------------------------- -TextureLoadTaskClass::~TextureLoadTaskClass() +void TextureLoadTaskClass::Delete_Free_Pool(void) { - Deinit(); + // (gth) We should probably just MEMPool these task objects... + while (TextureLoadTaskClass* task = _TexLoadFreeList.Pop_Front()) { + delete task; + } + while (TextureLoadTaskClass* task = _CubeTexLoadFreeList.Pop_Front()) { + delete task; + } + while (TextureLoadTaskClass* task = _VolTexLoadFreeList.Pop_Front()) { + delete task; + } } -void TextureLoadTaskClass::Init(TextureBaseClass* tc,bool high_priority) + +void TextureLoadTaskClass::Init(TextureBaseClass* tc, TaskType type, PriorityType priority) { + WWASSERT(tc); + + // NOTE: we must be in the main thread to avoid corrupting the texture's refcount. + WWASSERT(TextureLoader::Is_DX8_Thread()); + REF_PTR_SET(Texture, tc); + // Make sure texture has a filename. - REF_PTR_SET(Texture,tc); - //WWASSERT(Texture->Get_Full_Path() != NULL); + WWASSERT(Texture->Get_Full_Path() != ""); - Reduction=Texture->Get_Reduction(); - HighPriorityRequested=high_priority; - IsLoading=false; - HasFailed=false; - MipLevelCount=tc->MipLevelCount; - D3DTexture=0; - Width=0; - Height=0; - Format=Texture->Get_Texture_Format(); + Type = type; + Priority = priority; + State = STATE_NONE; - Texture->TextureLoadTask=this; - for (int i=0;iAs_TextureClass(); + + if (tex) + { + Format = tex->Get_Texture_Format(); // don't assume format yet KM } - if (Texture) { - WWASSERT(Texture->TextureLoadTask==this); - Texture->TextureLoadTask=NULL; + else + { + Format = WW3D_FORMAT_UNKNOWN; } - REF_PTR_RELEASE(Texture); - WWASSERT(!D3DTexture); + Width = 0; + Height = 0; + MipLevelCount = Texture->MipLevelCount; + Reduction = Texture->Get_Reduction(); + HSVShift = Texture->Get_HSV_Shift(); + + + for (int i = 0; i < MIP_LEVELS_MAX; ++i) + { + LockedSurfacePtr[i] = NULL; + LockedSurfacePitch[i] = 0; + } + + switch (Type) + { + case TASK_THUMBNAIL: + WWASSERT(Texture->ThumbnailLoadTask == NULL); + Texture->ThumbnailLoadTask = this; + break; + + case TASK_LOAD: + WWASSERT(Texture->TextureLoadTask == NULL); + Texture->TextureLoadTask = this; + break; + } } -// ---------------------------------------------------------------------------- -// -// -// -// ---------------------------------------------------------------------------- -void TextureLoadTaskClass::Begin_Texture_Load() -{ - // If we're in main thread, init for loading and add to the load list - if (ThreadClass::_Get_Current_Thread_ID()==DX8Wrapper::_Get_Main_Thread_ID()) { - - bool loaded=false; - if (Texture->Is_Compression_Allowed()) { - DDSFileClass dds_file(Texture->Get_Full_Path(),Get_Reduction()); - if (dds_file.Is_Available()) { - // Destination size will be the next power of two square from the larger width and height... - unsigned width, height; - width=dds_file.Get_Width(0); - height=dds_file.Get_Height(0); - TextureLoader::Validate_Texture_Size(width,height); - - // If the size doesn't match, try and see if texture reduction would help... (mainly for - // cases where loaded texture is larger than hardware limit) - if (width!=dds_file.Get_Width(0) || height!=dds_file.Get_Height(0)) { - for (unsigned i=1;iIs_Compression_Allowed()); - - unsigned mip_level_count=Get_Mip_Level_Count(); - // If texture wants all mip levels, take as many as the file contains (not necessarily all) - // Otherwise take as many mip levels as the texture wants, not to exceed the count in file... - if (!mip_level_count) mip_level_count=dds_file.Get_Mip_Level_Count(); - else if (mip_level_count>dds_file.Get_Mip_Level_Count()) mip_level_count=dds_file.Get_Mip_Level_Count(); - - // Once more, verify that the mip level count is correct (in case it was changed here it might not - // match the size...well actually it doesn't have to match but it can't be bigger than the size) - unsigned max_mip_level_count=1; - unsigned w=4; - unsigned h=4; - while (wmax_mip_level_count) mip_level_count=max_mip_level_count; - - D3DTexture=DX8Wrapper::_Create_DX8_Texture(Width,Height,Format,(MipCountType)mip_level_count); - MipLevelCount=mip_level_count; - //Texture->MipLevelCount); - loaded=true; - } - } +void TextureLoadTaskClass::Deinit() +{ + // task should not be on any list when it is being detached from texture. + WWASSERT(Next == NULL); + WWASSERT(Prev == NULL); - if (!loaded) { - Targa targa; - if (TARGA_ERROR_HANDLER(targa.Open(Texture->Get_Full_Path(), TGA_READMODE),Texture->Get_Full_Path())) { - D3DTexture=MissingTexture::_Get_Missing_Texture(); - HasFailed=true; - IsLoading=false; - End_Load(); - Apply(true); - Add_Task_To_Delete_List(this); - return; - } + WWASSERT(D3DTexture == NULL); + for (int i = 0; i < MIP_LEVELS_MAX; ++i) { + WWASSERT(LockedSurfacePtr[i] == NULL); + } - unsigned bpp; - WW3DFormat src_format,dest_format; - Get_WW3D_Format(dest_format,src_format,bpp,targa); - if (src_format!=WW3D_FORMAT_A8R8G8B8 && - src_format!=WW3D_FORMAT_R8G8B8 && - src_format!=WW3D_FORMAT_X8R8G8B8) { - WWDEBUG_SAY(("Invalid TGA format used in %s - only 24 and 32 bit formats should be used!",Texture->Get_Full_Path().str())); - } + if (Texture) { + switch (Type) { + case TASK_THUMBNAIL: + WWASSERT(Texture->ThumbnailLoadTask == this); + Texture->ThumbnailLoadTask = NULL; + break; - // Destination size will be the next power of two square from the larger width and height... - unsigned width=targa.Header.Width, height=targa.Header.Height; - int ReductionFactor=Get_Reduction(); - int MipLevels=0; - - //Figure out how many mip levels this texture will occupy - for (int i=width, j=height; i > 0 && j > 0; i>>=1, j>>=1) - MipLevels++; - - //Adjust the reduction factor to keep textures above some minimum dimensions - if (MipLevels <= WW3D::Get_Texture_Min_Dimension()) - ReductionFactor=0; - else - { int mipToDrop=MipLevels-WW3D::Get_Texture_Min_Dimension(); - if (ReductionFactor >= mipToDrop) - ReductionFactor=mipToDrop; - } + case TASK_LOAD: + WWASSERT(Texture->TextureLoadTask == this); + Texture->TextureLoadTask = NULL; + break; + } - width=targa.Header.Width>>ReductionFactor; - height=targa.Header.Height>>ReductionFactor; - unsigned ow=width; - unsigned oh=height; - TextureLoader::Validate_Texture_Size(width,height); - if (width!=ow || height!=oh) { - WWDEBUG_SAY(("Invalid texture size, scaling required. Texture: %s, size: %d x %d -> %d x %d",Texture->Get_Full_Path().str(),ow,oh,width,height)); - } + // NOTE: we must be in main thread to avoid corrupting Texture's refcount. + WWASSERT(TextureLoader::Is_DX8_Thread()); + REF_PTR_RELEASE(Texture); + } +} - IsLoading=true; - Width=width; - Height=height; - if (Format==WW3D_FORMAT_UNKNOWN) { - Format=Get_Valid_Texture_Format(dest_format,false); - } - else { - Format=Get_Valid_Texture_Format(Format,false); - } +bool TextureLoadTaskClass::Begin_Load(void) +{ + WWASSERT(TextureLoader::Is_DX8_Thread()); - D3DTexture=DX8Wrapper::_Create_DX8_Texture(Width,Height,Format,Texture->MipLevelCount); - } + bool loaded = false; - MipLevelCount=D3DTexture->GetLevelCount(); - for (unsigned i=0;iLockRect( - i, - &locked_rect, - NULL, - 0)); - LockedSurfacePtr[i]=(unsigned char*)locked_rect.pBits; - LockedSurfacePitch[i]=locked_rect.Pitch; - } + // if allowed, begin a compressed load + if (Texture->Is_Compression_Allowed()) { + loaded = Begin_Compressed_Load(); + } - if (HighPriorityRequested) { - TextureLoader::Load_Mipmap_Levels(this); - End_Load(); - Apply(true); - Add_Task_To_Delete_List(this); - } - else { - LoaderThreadClass::Add_Task_To_Load_List(this); - } + // otherwise, begin an uncompressed load + if (!loaded) { + loaded = Begin_Uncompressed_Load(); } - // Otherwise add to deferred list which will be handled by main thread - else { - Add_Deferred_Task(this); + + // if not loaded, abort. + if (!loaded) { + return false; } -} -/* file_auto_ptr my_tga_file(_TheFileFactory,Texture->Get_Full_Path()); - if (my_tga_file->Is_Available()) { - my_tga_file->Open(); - unsigned size=my_tga_file->Size(); - char* tga_memory=W3DNEWARRAY char[size]; - my_tga_file->Read(tga_memory,size); - my_tga_file->Close(); + // lock surfaces in preparation for copy + Lock_Surfaces(); - StringClass pth("data\\"); - pth+=Texture->Get_Texture_Name(); - RawFileClass tmp_tga_file(pth); - tmp_tga_file.Create(); - tmp_tga_file.Write(tga_memory,size); - tmp_tga_file.Close(); - delete[] tga_memory; + State = STATE_LOAD_BEGUN; + + return true; +} - } -*/ // ---------------------------------------------------------------------------- // -// +// Load mipmap levels to a pre-generated and locked texture object based on +// information in load task object. Try loading from a DDS file first and if +// that fails try a TGA. // // ---------------------------------------------------------------------------- +bool TextureLoadTaskClass::Load(void) +{ + WWMEMLOG(MEM_TEXTURE); + WWASSERT(Peek_D3D_Texture()); -void TextureLoadTaskClass::Begin_Thumbnail_Load() -{ -// CriticalSectionClass::LockClass m(mutex); - - unsigned thread_id=ThreadClass::_Get_Current_Thread_ID(); - if (thread_id==DX8Wrapper::_Get_Main_Thread_ID()) { - WW3DFormat format=Texture->Get_Texture_Format(); - // No compressed thumbnails - switch (format) { - case WW3D_FORMAT_DXT1: - case WW3D_FORMAT_DXT2: - case WW3D_FORMAT_DXT3: - case WW3D_FORMAT_DXT4: - case WW3D_FORMAT_DXT5: - format=WW3D_FORMAT_A8R8G8B8; break; - default: - break; - } - D3DTexture=TextureLoader::Load_Thumbnail(Texture->Get_Full_Path(),format); + bool loaded = false; - // Thumbnail loads are always high priority, so apply immediatelly - End_Load(); - Apply(false); - Add_Task_To_Delete_List(this); - return; + // if allowed, try to load compressed mipmaps + if (Texture->Is_Compression_Allowed()) { + loaded = Load_Compressed_Mipmap(); } - else { - Add_Thumbnail_Task(this); + + // otherwise, load uncompressed mipmaps + if (!loaded) { + loaded = Load_Uncompressed_Mipmap(); } + + State = STATE_LOAD_MIPMAP; + + return loaded; } -// ---------------------------------------------------------------------------- -// -// Deinit can be called multiple times. If any surfaces are locked this call -// can only be called from the main thread. -// -// ---------------------------------------------------------------------------- -void TextureLoadTaskClass::End_Load() +void TextureLoadTaskClass::End_Load(void) { - for (unsigned i=0;iUnlockRect(i)); - } - LockedSurfacePtr[i]=NULL; - } - IsLoading=false; + WWASSERT(TextureLoader::Is_DX8_Thread()); + + Unlock_Surfaces(); + Apply(true); + State = STATE_LOAD_COMPLETE; } -// ---------------------------------------------------------------------------- -// -// Link the node to another task node. This can only be done if the node isn't -// linked to something else already. If the node is linked to some other node, -// the only acceptable parameter to this function is NULL, which will unlink -// the connection. -// -// ---------------------------------------------------------------------------- -void TextureLoadTaskClass::Set_Succ(TextureLoadTaskClass* succ) +void TextureLoadTaskClass::Finish_Load(void) { - WWASSERT((succ && !Succ) || (!succ)); // Can't set successor pointer if it has been set already - Succ=succ; -} + switch (State) { + // NOTE: fall-through below is intentional. -// ---------------------------------------------------------------------------- -// -// -// -// ---------------------------------------------------------------------------- + case STATE_NONE: + if (!Begin_Load()) { + Apply_Missing_Texture(); + break; + } + FALLTHROUGH; + + case STATE_LOAD_BEGUN: + Load(); + FALLTHROUGH; + + case STATE_LOAD_MIPMAP: + End_Load(); + FALLTHROUGH; + + default: + break; + } +} -void TextureLoadTaskClass::Set_D3D_Texture(IDirect3DTexture8* texture) + +void TextureLoadTaskClass::Apply_Missing_Texture(void) { - WWASSERT(D3DTexture==0); - D3DTexture=texture; + WWASSERT(TextureLoader::Is_DX8_Thread()); + WWASSERT(!D3DTexture); + + D3DTexture = MissingTexture::_Get_Missing_Texture(); + Apply(true); } -// ---------------------------------------------------------------------------- -// -// Apply the D3D texture surface to the client texture. The parameter 'initialize' -// determines whether the client texture will be set to initialized state or -// not. Generally thumbnail tasks will not set texture to initialised state but -// all other loads do. -// -// ---------------------------------------------------------------------------- void TextureLoadTaskClass::Apply(bool initialize) { WWASSERT(D3DTexture); + // Verify that none of the mip levels are locked - for (unsigned i=0;iApply_New_Surface(initialize); + Texture->Apply_New_Surface(D3DTexture, initialize); D3DTexture->Release(); - D3DTexture=NULL; + D3DTexture = NULL; +} + +static bool Get_Texture_Information +( + const char* filename, + unsigned& reduction, + unsigned& w, + unsigned& h, + unsigned& d, + WW3DFormat& format, + unsigned& mip_count, + bool compressed +) +{ + ThumbnailClass* thumb = ThumbnailManagerClass::Peek_Thumbnail_Instance_From_Any_Manager(filename); + + if (!thumb) + { + if (compressed) + { + DDSFileClass dds_file(filename, 0); + if (!dds_file.Is_Available()) return false; + + // Destination size will be the next power of two square from the larger width and height... + w = dds_file.Get_Width(0); + h = dds_file.Get_Height(0); + d = dds_file.Get_Depth(0); + format = dds_file.Get_Format(); + mip_count = dds_file.Get_Mip_Level_Count(); + //Figure out correct reduction + int reqReduction = WW3D::Get_Texture_Reduction(); //requested reduction + + if (reqReduction >= mip_count) + reqReduction = mip_count - 1; //leave only the lowest level + + //Clamp reduction + int curReduction = 0; + int curWidth = w; + int curHeight = h; + int minDim = WW3D::Get_Texture_Min_Dimension(); + + while (curReduction < reqReduction && curWidth > minDim && curHeight > minDim) + { + curWidth >>= 1; //keep dividing + curHeight >>= 1; + curReduction++; + } + reduction = curReduction; + return true; + } + + Targa targa; + if (TARGA_ERROR_HANDLER(targa.Open(filename, TGA_READMODE), filename)) + { + return false; + } + + unsigned int bpp; + WW3DFormat dest_format; + Get_WW3D_Format(dest_format, format, bpp, targa); + + mip_count = 0; + + //Figure out how many mip levels this texture will occupy + for (int i = targa.Header.Width, j = targa.Header.Height; i > 0 && j > 0; i >>= 1, j >>= 1) + mip_count++; + + //Figure out correct reduction + int reqReduction = WW3D::Get_Texture_Reduction(); //requested reduction + + if (reqReduction >= mip_count) + reqReduction = mip_count - 1; //leave only the lowest level + + //Clamp reduction + int curReduction = 0; + int curWidth = targa.Header.Width; + int curHeight = targa.Header.Height; + int minDim = WW3D::Get_Texture_Min_Dimension(); + + while (curReduction < reqReduction && curWidth > minDim && curHeight > minDim) + { + curWidth >>= 1; //keep dividing + curHeight >>= 1; + curReduction++; + } + reduction = curReduction; + + // Destination size will be the next power of two square from the larger width and height... + w = targa.Header.Width; + h = targa.Header.Height; + d = 1; + return true; + } + + if (compressed && + thumb->Get_Original_Texture_Format() != WW3D_FORMAT_DXT1 && + thumb->Get_Original_Texture_Format() != WW3D_FORMAT_DXT2 && + thumb->Get_Original_Texture_Format() != WW3D_FORMAT_DXT3 && + thumb->Get_Original_Texture_Format() != WW3D_FORMAT_DXT4 && + thumb->Get_Original_Texture_Format() != WW3D_FORMAT_DXT5) { + return false; + } + + w = thumb->Get_Original_Texture_Width() >> reduction; + h = thumb->Get_Original_Texture_Height() >> reduction; + //d=thumb->Get_Original_Texture_Depth() >> reduction; // need to a volume texture support to thumbnails...maybe + mip_count = thumb->Get_Original_Texture_Mip_Level_Count(); + format = thumb->Get_Original_Texture_Format(); + return true; } -// ---------------------------------------------------------------------------- -// -// Return locked surface pointer at a specific level. The call will -// assert if level is greater or equal to the number of mip levels or if the -// requested level has not been locked. -// -// ---------------------------------------------------------------------------- -unsigned char* TextureLoadTaskClass::Get_Locked_Surface_Ptr(unsigned level) +bool TextureLoadTaskClass::Begin_Compressed_Load(void) { - WWASSERT(levelGet_Full_Path(), + reduction, + orig_w, + orig_h, + orig_d, + orig_format, + orig_mip_count, + true + ) + ) + { + return false; + } + + // Destination size will be the next power of two square from the larger width and height... + unsigned int width = orig_w; + unsigned int height = orig_h; + TextureLoader::Validate_Texture_Size(width, height, orig_d); + + // If the size doesn't match, try and see if texture reduction would help... (mainly for + // cases where loaded texture is larger than hardware limit) + if (width != orig_w || height != orig_h) + { + for (unsigned int i = 1; i < orig_mip_count; ++i) + { + unsigned w = orig_w >> i; + if (w < 4) w = 4; + unsigned h = orig_h >> i; + if (h < 4) h = 4; + unsigned tmp_w = w; + unsigned tmp_h = h; + + TextureLoader::Validate_Texture_Size(w, h, orig_d); + + if (w == tmp_w && h == tmp_h) + { + Reduction += i; + width = w; + height = h; + break; + } + } + } + + Width = width; + Height = height; + Format = Get_Valid_Texture_Format(orig_format, Texture->Is_Compression_Allowed()); + Reduction = reduction; + + + if (!Texture->Is_Reducible() || Texture->MipLevelCount == MIP_LEVELS_1) + Reduction = 0; //app doesn't want this texture to ever be reduced. + else + //Make sure we don't reduce below the level requested by the app + if (Texture->MipLevelCount != MIP_LEVELS_ALL && (Texture->MipLevelCount - Reduction) < 1) + Reduction = Texture->MipLevelCount - 1; + + //Another sanity check + if (Reduction >= orig_mip_count) + Reduction = 0; //should not be possible to get here, but check just in case. + + unsigned int mip_level_count = Get_Mip_Level_Count(); + int reducedWidth = Width; + int reducedHeight = Height; + + // If texture wants all mip levels, take as many as the file contains (not necessarily all) + // Otherwise take as many mip levels as the texture wants, not to exceed the count in file... + if (!mip_level_count) + { + reducedWidth >>= Reduction; + reducedHeight >>= Reduction; + mip_level_count = orig_mip_count - Reduction;//dds_file.Get_Mip_Level_Count(); + if (mip_level_count < 1) + mip_level_count = 1; //sanity check to make sure something gets loaded. + } + else + { + if (mip_level_count > orig_mip_count) + { //dds_file.Get_Mip_Level_Count()) { + mip_level_count = orig_mip_count;//dds_file.Get_Mip_Level_Count(); + } + + if (Reduction) + { + reducedWidth >>= Reduction; + reducedHeight >>= Reduction; + mip_level_count -= Reduction; //reduced requested number by those removed. + } + } + + // Once more, verify that the mip level count is correct (in case it was changed here it might not + // match the size...well actually it doesn't have to match but it can't be bigger than the size) + unsigned int max_mip_level_count = 1; + unsigned int w = 4; + unsigned int h = 4; + + while (w < Width && h < Height) + { + w += w; + h += h; + max_mip_level_count++; + } + + if (mip_level_count > max_mip_level_count) + { + mip_level_count = max_mip_level_count; + } + + D3DTexture = DX8Wrapper::_Create_DX8_Texture + ( + reducedWidth, + reducedHeight, + Format, + (MipCountType)mip_level_count, +#ifdef USE_MANAGED_TEXTURES + D3DPOOL_MANAGED +#else + D3DPOOL_SYSTEMMEM +#endif + ); + + MipLevelCount = mip_level_count; + + return true; } -// ---------------------------------------------------------------------------- -// -// Return locked surface pitch (in bytes) at a specific level. The call will -// assert if level is greater or equal to the number of mip levels or if the -// requested level has not been locked. -// -// ---------------------------------------------------------------------------- +bool TextureLoadTaskClass::Begin_Uncompressed_Load(void) +{ + unsigned width, height, depth, orig_mip_count, reduction; + WW3DFormat orig_format; + if (!Get_Texture_Information + ( + Texture->Get_Full_Path(), + reduction, + width, + height, + depth, + orig_format, + orig_mip_count, + false + ) + ) + { + return false; + } + + WW3DFormat src_format = orig_format; + WW3DFormat dest_format = src_format; + dest_format = Get_Valid_Texture_Format(dest_format, false); // No compressed destination format if reading from targa... + + if (src_format != WW3D_FORMAT_A8R8G8B8 + && src_format != WW3D_FORMAT_R8G8B8 + && src_format != WW3D_FORMAT_X8R8G8B8) + { + WWDEBUG_SAY(("Invalid TGA format used in %s - only 24 and 32 bit formats should be used!", Texture->Get_Full_Path().str())); + } + + // Destination size will be the next power of two square from the larger width and height... + unsigned ow = width; + unsigned oh = height; + TextureLoader::Validate_Texture_Size(width, height, depth); + if (width != ow || height != oh) + { + WWDEBUG_SAY(("Invalid texture size, scaling required. Texture: %s, size: %d x %d -> %d x %d", Texture->Get_Full_Path().str(), ow, oh, width, height)); + } + + Width = width; + Height = height; + Reduction = reduction; + + if (!Texture->Is_Reducible() || Texture->MipLevelCount == MIP_LEVELS_1) + Reduction = 0; //app doesn't want this texture to ever be reduced. + else + //Make sure we don't reduce below the level requested by the app + if (Texture->MipLevelCount != MIP_LEVELS_ALL && (Texture->MipLevelCount - Reduction) < 1) + Reduction = Texture->MipLevelCount - 1; + + //Another sanity check + if (Reduction >= orig_mip_count) + Reduction = 0; //should not be possible to get here, but check just in case. + + if (Format == WW3D_FORMAT_UNKNOWN) + { + Format = dest_format; + // Format = Get_Valid_Texture_Format(dest_format, false); validated above + } + else + { + Format = Get_Valid_Texture_Format(Format, false); + } + + int reducedWidth = Width; + int reducedHeight = Height; + int reducedMipCount = Texture->MipLevelCount; + + if (Reduction) + { //we don't care about specific levels so reduce them if needed. + reducedWidth >>= Reduction; + reducedHeight >>= Reduction; + if (reducedMipCount != MIP_LEVELS_ALL) + reducedMipCount -= Reduction; + } + + D3DTexture = DX8Wrapper::_Create_DX8_Texture + ( + reducedWidth, + reducedHeight, + Format, + (MipCountType)reducedMipCount, +#ifdef USE_MANAGED_TEXTURES + D3DPOOL_MANAGED +#else + D3DPOOL_SYSTEMMEM +#endif + ); + + return true; +} -unsigned TextureLoadTaskClass::Get_Locked_Surface_Pitch(unsigned level) const +/* +bool TextureLoadTaskClass::Begin_Compressed_Load(void) { - WWASSERT(levelGet_Full_Path(), Get_Reduction()); + if (!dds_file.Is_Available()) { + return false; + } + + // Destination size will be the next power of two square from the larger width and height... + unsigned int width = dds_file.Get_Width(0); + unsigned int height = dds_file.Get_Height(0); + TextureLoader::Validate_Texture_Size(width, height); + + // If the size doesn't match, try and see if texture reduction would help... (mainly for + // cases where loaded texture is larger than hardware limit) + if (width != dds_file.Get_Width(0) || height != dds_file.Get_Height(0)) { + for (unsigned int i = 1; i < dds_file.Get_Mip_Level_Count(); ++i) { + unsigned int w = dds_file.Get_Width(i); + unsigned int h = dds_file.Get_Height(i); + TextureLoader::Validate_Texture_Size(w,h); + + if (w == dds_file.Get_Width(i) && h == dds_file.Get_Height(i)) { + Reduction += i; + width = w; + height = h; + break; + } + } + } + + Width = width; + Height = height; + Format = Get_Valid_Texture_Format(dds_file.Get_Format(), Texture->Is_Compression_Allowed()); + + unsigned int mip_level_count = Get_Mip_Level_Count(); + + // If texture wants all mip levels, take as many as the file contains (not necessarily all) + // Otherwise take as many mip levels as the texture wants, not to exceed the count in file... + if (!mip_level_count) { + mip_level_count = dds_file.Get_Mip_Level_Count(); + } else if (mip_level_count > dds_file.Get_Mip_Level_Count()) { + mip_level_count = dds_file.Get_Mip_Level_Count(); + } + + // Once more, verify that the mip level count is correct (in case it was changed here it might not + // match the size...well actually it doesn't have to match but it can't be bigger than the size) + unsigned int max_mip_level_count = 1; + unsigned int w = 4; + unsigned int h = 4; + + while (w < Width && h < Height) { + w += w; + h += h; + max_mip_level_count++; + } + + if (mip_level_count > max_mip_level_count) { + mip_level_count = max_mip_level_count; + } + + D3DTexture = DX8Wrapper::_Create_DX8_Texture( + Width, + Height, + Format, + (TextureBaseClass::MipCountType)mip_level_count, +#ifdef USE_MANAGED_TEXTURES + D3DPOOL_MANAGED); +#else + D3DPOOL_SYSTEMMEM); +#endif + MipLevelCount = mip_level_count; + return true; } -// ---------------------------------------------------------------------------- -// -// Load tasks are stored in a pool when they are not used. If the pool is empty -// a new task is created. -// -// ---------------------------------------------------------------------------- -TextureLoadTaskClass* TextureLoadTaskClass::Get_Instance(TextureBaseClass* tc, bool high_priority) +bool TextureLoadTaskClass::Begin_Uncompressed_Load(void) { - CriticalSectionClass::LockClass m(mutex); + Targa targa; + if (TARGA_ERROR_HANDLER(targa.Open(Texture->Get_Full_Path(), TGA_READMODE), Texture->Get_Full_Path())) { + return false; + } - TextureLoadTaskClass* task=FreeTaskListHead; - if (task) { - FreeTaskListHead=task->Peek_Succ(); - task->Set_Succ(NULL); + unsigned int bpp; + WW3DFormat src_format, dest_format; + Get_WW3D_Format(dest_format,src_format,bpp,targa); + + if ( src_format != WW3D_FORMAT_A8R8G8B8 + && src_format != WW3D_FORMAT_R8G8B8 + && src_format != WW3D_FORMAT_X8R8G8B8) { + WWDEBUG_SAY(("Invalid TGA format used in %s - only 24 and 32 bit formats should be used!", Texture->Get_Full_Path())); } - else { - task=W3DNEW TextureLoadTaskClass(); + + // Destination size will be the next power of two square from the larger width and height... + unsigned width=targa.Header.Width, height=targa.Header.Height; + int ReductionFactor=Get_Reduction(); + int MipLevels=0; + + //Figure out how many mip levels this texture will occupy + for (int i=width, j=height; i > 0 && j > 0; i>>=1, j>>=1) + MipLevels++; + + //Adjust the reduction factor to keep textures above some minimum dimensions + if (MipLevels <= WW3D::Get_Texture_Min_Mip_Levels()) + ReductionFactor=0; + else + { int mipToDrop=MipLevels-WW3D::Get_Texture_Min_Mip_Levels(); + if (ReductionFactor >= mipToDrop) + ReductionFactor=mipToDrop; } - task->Init(tc,high_priority); - return task; + + width=targa.Header.Width>>ReductionFactor; + height=targa.Header.Height>>ReductionFactor; + unsigned ow = width; + unsigned oh = height; + TextureLoader::Validate_Texture_Size(width, height); + if (width != ow || height != oh) { + WWDEBUG_SAY(("Invalid texture size, scaling required. Texture: %s, size: %d x %d -> %d x %d", Texture->Get_Full_Path(), ow, oh, width, height)); + } + + Width = width; + Height = height; + + // changed because format was being read from previous loading task?! KJM + Format=dest_format; + //if (Format == WW3D_FORMAT_UNKNOWN) { + // Format = Get_Valid_Texture_Format(dest_format, false); + //} else { + // Format = Get_Valid_Texture_Format(Format, false); + //} + + D3DTexture = DX8Wrapper::_Create_DX8_Texture + ( + Width, + Height, + Format, + Texture->MipLevelCount, +#ifdef USE_MANAGED_TEXTURES + D3DPOOL_MANAGED); +#else + D3DPOOL_SYSTEMMEM); +#endif + return true; +} +*/ + +void TextureLoadTaskClass::Lock_Surfaces(void) +{ + MipLevelCount = D3DTexture->GetLevelCount(); + + for (unsigned int i = 0; i < MipLevelCount; ++i) + { + D3DLOCKED_RECT locked_rect; + DX8_ErrorCode + ( + Peek_D3D_Texture()->LockRect + ( + i, + &locked_rect, + NULL, + 0 + ) + ); + LockedSurfacePtr[i] = (unsigned char*)locked_rect.pBits; + LockedSurfacePitch[i] = locked_rect.Pitch; + } +} + + +void TextureLoadTaskClass::Unlock_Surfaces(void) +{ + for (unsigned int i = 0; i < MipLevelCount; ++i) + { + if (LockedSurfacePtr[i]) + { + WWASSERT(ThreadClass::_Get_Current_Thread_ID() == DX8Wrapper::_Get_Main_Thread_ID()); + DX8_ErrorCode(Peek_D3D_Texture()->UnlockRect(i)); + } + LockedSurfacePtr[i] = NULL; + } + +#ifndef USE_MANAGED_TEXTURES + IDirect3DTexture8* tex = DX8Wrapper::_Create_DX8_Texture(Width, Height, Format, Texture->MipLevelCount, D3DPOOL_DEFAULT); + DX8CALL(UpdateTexture(Peek_D3D_Texture(), tex)); + Peek_D3D_Texture()->Release(); + D3DTexture = tex; + WWDEBUG_SAY(("Created non-managed texture (%s)", Texture->Get_Full_Path())); +#endif + } -// ---------------------------------------------------------------------------- -// -// When task is no longer needed it is returned to the pool. -// -// ---------------------------------------------------------------------------- -void TextureLoadTaskClass::Release_Instance(TextureLoadTaskClass* task) +bool TextureLoadTaskClass::Load_Compressed_Mipmap(void) { - if (!task) return; + DDSFileClass dds_file(Texture->Get_Full_Path(), Get_Reduction()); + + // if we can't load from file, indicate rror. + if (!dds_file.Is_Available() || !dds_file.Load()) + { + return false; + } - CriticalSectionClass::LockClass m(mutex); + // regular 2d texture + unsigned int width = Get_Width(); + unsigned int height = Get_Height(); + + if (Reduction) + { + for (unsigned int level = 0; level < Reduction; ++level) { + width >>= 1; + height >>= 1; + } + } - task->Deinit(); + for (unsigned int level = 0; level < Get_Mip_Level_Count(); ++level) + { + WWASSERT(width && height); + dds_file.Copy_Level_To_Surface + ( + level, + Get_Format(), + width, + height, + Get_Locked_Surface_Ptr(level), + Get_Locked_Surface_Pitch(level), + HSVShift + ); - // Task must not be in any list when it is being freed - WWASSERT(task->Peek_Succ()==NULL); + width >>= 1; + height >>= 1; + } - task->Set_Succ(FreeTaskListHead); - FreeTaskListHead=task; + return true; } + +bool TextureLoadTaskClass::Load_Uncompressed_Mipmap(void) +{ + if (!Get_Mip_Level_Count()) + { + return false; + } + + Targa targa; + if (TARGA_ERROR_HANDLER(targa.Open(Texture->Get_Full_Path(), TGA_READMODE), Texture->Get_Full_Path())) { + return false; + } + + // DX8 uses image upside down compared to TGA + targa.Header.ImageDescriptor ^= TGAIDF_YORIGIN; + + WW3DFormat src_format; + WW3DFormat dest_format; + unsigned int src_bpp = 0; + Get_WW3D_Format(dest_format, src_format, src_bpp, targa); + if (src_format == WW3D_FORMAT_UNKNOWN) return false; + + dest_format = Get_Format(); // Texture can be requested in different format than the most obvious from the TGA + + char palette[256 * 4]; + targa.SetPalette(palette); + + unsigned int src_width = targa.Header.Width; + unsigned int src_height = targa.Header.Height; + unsigned int width = Get_Width(); + unsigned int height = Get_Height(); + + // NOTE: We load the palette but we do not yet support paletted textures! + if (TARGA_ERROR_HANDLER(targa.Load(Texture->Get_Full_Path(), TGAF_IMAGE, false), Texture->Get_Full_Path())) { + return false; + } + + unsigned char* src_surface = (unsigned char*)targa.GetImage(); + unsigned char* converted_surface = NULL; + + // No paletted format allowed when generating mipmaps + Vector3 hsv_shift = HSVShift; + if (src_format == WW3D_FORMAT_A1R5G5B5 + || src_format == WW3D_FORMAT_R5G6B5 + || src_format == WW3D_FORMAT_A4R4G4B4 + || src_format == WW3D_FORMAT_P8 + || src_format == WW3D_FORMAT_L8 + || src_width != width + || src_height != height) { + + converted_surface = new unsigned char[width * height * 4]; + dest_format = Get_Valid_Texture_Format(WW3D_FORMAT_A8R8G8B8, false); + + BitmapHandlerClass::Copy_Image( + converted_surface, + width, + height, + width * 4, + WW3D_FORMAT_A8R8G8B8, //dest_format, + src_surface, + src_width, + src_height, + src_width * src_bpp, + src_format, + (unsigned char*)targa.GetPalette(), + targa.Header.CMapDepth >> 3, + false, + hsv_shift); + hsv_shift = Vector3(0.0f, 0.0f, 0.0f); + + src_surface = converted_surface; + src_format = WW3D_FORMAT_A8R8G8B8; //dest_format; + src_width = width; + src_height = height; + src_bpp = Get_Bytes_Per_Pixel(src_format); + } + + unsigned src_pitch = src_width * src_bpp; + + if (Reduction) + { //texture needs to be reduced so allocate storage for full-sized version. + unsigned char* destination_surface = new unsigned char[width * height * 4]; + //generate upper mip-levels that will be dropped in final texture + for (unsigned int level = 0; level < Reduction; ++level) { + BitmapHandlerClass::Copy_Image( + (unsigned char*)destination_surface, + width, + height, + src_pitch, + Get_Format(), + src_surface, + src_width, + src_height, + src_pitch, + src_format, + NULL, + 0, + true, + hsv_shift); + + width >>= 1; + height >>= 1; + src_width >>= 1; + src_height >>= 1; + } + delete[] destination_surface; + } + + for (unsigned int level = 0; level < Get_Mip_Level_Count(); ++level) { + WWASSERT(Get_Locked_Surface_Ptr(level)); + BitmapHandlerClass::Copy_Image( + Get_Locked_Surface_Ptr(level), + width, + height, + Get_Locked_Surface_Pitch(level), + Get_Format(), + src_surface, + src_width, + src_height, + src_pitch, + src_format, + NULL, + 0, + true, + hsv_shift); + hsv_shift = Vector3(0.0f, 0.0f, 0.0f); + + width >>= 1; + height >>= 1; + src_width >>= 1; + src_height >>= 1; + + if (!width || !height || !src_width || !src_height) { + break; + } + } + + if (converted_surface) { + delete[] converted_surface; + } + + return true; +} + + +unsigned char* TextureLoadTaskClass::Get_Locked_Surface_Ptr(unsigned int level) +{ + WWASSERT(level < MipLevelCount); + WWASSERT(LockedSurfacePtr[level]); + return LockedSurfacePtr[level]; +} + +// ---------------------------------------------------------------------------- +// +// Return locked surface pitch (in bytes) at a specific level. The call will +// assert if level is greater or equal to the number of mip levels or if the +// requested level has not been locked. +// +// ---------------------------------------------------------------------------- + +unsigned int TextureLoadTaskClass::Get_Locked_Surface_Pitch(unsigned int level) const +{ + WWASSERT(level < MipLevelCount); + WWASSERT(LockedSurfacePtr[level]); + return LockedSurfacePitch[level]; +} + + + + + +// CubeTextureLoadTaskClass +CubeTextureLoadTaskClass::CubeTextureLoadTaskClass() + : TextureLoadTaskClass() +{ + // because texture load tasks are pooled, the constructor and destructor + // don't need to do much. The work of attaching a task to a texture is + // is done by Init() and Deinit(). + + for (int f = 0; f < 6; f++) + { + for (int i = 0; i < MIP_LEVELS_MAX; ++i) + { + LockedCubeSurfacePtr[f][i] = NULL; + LockedCubeSurfacePitch[f][i] = 0; + } + } +} + +void CubeTextureLoadTaskClass::Destroy(void) +{ + // detach the task from its texture, and return to free pool. + Deinit(); + _CubeTexLoadFreeList.Push_Front(this); +} + + +void CubeTextureLoadTaskClass::Init(TextureBaseClass* tc, TaskType type, PriorityType priority) +{ + WWASSERT(tc); + + // NOTE: we must be in the main thread to avoid corrupting the texture's refcount. + WWASSERT(TextureLoader::Is_DX8_Thread()); + REF_PTR_SET(Texture, tc); + + // Make sure texture has a filename. + WWASSERT(Texture->Get_Full_Path() != ""); + + Type = type; + Priority = priority; + State = STATE_NONE; + + D3DTexture = 0; + + CubeTextureClass* tex = Texture->As_CubeTextureClass(); + + if (tex) + { + Format = tex->Get_Texture_Format(); // don't assume format yet KM + } + else + { + Format = WW3D_FORMAT_UNKNOWN; + } + + Width = 0; + Height = 0; + MipLevelCount = Texture->MipLevelCount; + Reduction = Texture->Get_Reduction(); + HSVShift = Texture->Get_HSV_Shift(); + + + for (int f = 0; f < 6; f++) + { + for (int i = 0; i < MIP_LEVELS_MAX; ++i) + { + LockedCubeSurfacePtr[f][i] = NULL; + LockedCubeSurfacePitch[f][i] = 0; + } + } + + switch (Type) + { + case TASK_THUMBNAIL: + WWASSERT(Texture->ThumbnailLoadTask == NULL); + Texture->ThumbnailLoadTask = this; + break; + + case TASK_LOAD: + WWASSERT(Texture->TextureLoadTask == NULL); + Texture->TextureLoadTask = this; + break; + } +} + + +void CubeTextureLoadTaskClass::Deinit() +{ + // task should not be on any list when it is being detached from texture. + WWASSERT(Next == NULL); + WWASSERT(Prev == NULL); + + WWASSERT(D3DTexture == NULL); + + for (int f = 0; f < 6; f++) + { + for (int i = 0; i < MIP_LEVELS_MAX; ++i) + { + WWASSERT(LockedCubeSurfacePtr[f][i] == NULL); + } + } + + if (Texture) + { + switch (Type) + { + case TASK_THUMBNAIL: + WWASSERT(Texture->ThumbnailLoadTask == this); + Texture->ThumbnailLoadTask = NULL; + break; + + case TASK_LOAD: + WWASSERT(Texture->TextureLoadTask == this); + Texture->TextureLoadTask = NULL; + break; + } + + // NOTE: we must be in main thread to avoid corrupting Texture's refcount. + WWASSERT(TextureLoader::Is_DX8_Thread()); + REF_PTR_RELEASE(Texture); + } +} + +void CubeTextureLoadTaskClass::Lock_Surfaces(void) +{ + for (unsigned int f = 0; f < 6; f++) + { + for (unsigned int i = 0; i < MipLevelCount; i++) + { + D3DLOCKED_RECT locked_rect; + DX8_ErrorCode + ( + Peek_D3D_Cube_Texture()->LockRect + ( + (D3DCUBEMAP_FACES)f, + i, + &locked_rect, + NULL, + 0 + ) + ); + LockedCubeSurfacePtr[f][i] = (unsigned char*)locked_rect.pBits; + LockedCubeSurfacePitch[f][i] = locked_rect.Pitch; + } + } +} + +void CubeTextureLoadTaskClass::Unlock_Surfaces(void) +{ + for (unsigned int f = 0; f < 6; f++) + { + for (unsigned int i = 0; i < MipLevelCount; ++i) + { + if (LockedCubeSurfacePtr[f][i]) + { + WWASSERT(ThreadClass::_Get_Current_Thread_ID() == DX8Wrapper::_Get_Main_Thread_ID()); + DX8_ErrorCode + ( + Peek_D3D_Cube_Texture()->UnlockRect((D3DCUBEMAP_FACES)f, i) + ); + } + LockedCubeSurfacePtr[f][i] = NULL; + } + } + +#ifndef USE_MANAGED_TEXTURES + IDirect3DCubeTexture8* tex = DX8Wrapper::_Create_DX8_Cube_Texture + ( + Width, + Height, + Format, + Texture->MipLevelCount, + D3DPOOL_DEFAULT + ); + DX8CALL(UpdateTexture(Peek_D3D_Volume_Texture(), tex)); + Peek_D3D_Volume_Texture()->Release(); + D3DTexture = tex; + WWDEBUG_SAY(("Created non-managed texture (%s)", Texture->Get_Full_Path())); +#endif + +} + + + +bool CubeTextureLoadTaskClass::Begin_Compressed_Load() +{ + unsigned orig_w, orig_h, orig_d, orig_mip_count, reduction; + WW3DFormat orig_format; + if (!Get_Texture_Information + ( + Texture->Get_Full_Path(), + reduction, + orig_w, + orig_h, + orig_d, + orig_format, + orig_mip_count, + true + ) + ) + { + return false; + } + + // Destination size will be the next power of two square from the larger width and height... + unsigned int width = orig_w; + unsigned int height = orig_h; + TextureLoader::Validate_Texture_Size(width, height, orig_d); + + // If the size doesn't match, try and see if texture reduction would help... (mainly for + // cases where loaded texture is larger than hardware limit) + if (width != orig_w || height != orig_h) + { + for (unsigned int i = 1; i < orig_mip_count; ++i) + { + unsigned w = orig_w >> i; + if (w < 4) w = 4; + unsigned h = orig_h >> i; + if (h < 4) h = 4; + unsigned tmp_w = w; + unsigned tmp_h = h; + + TextureLoader::Validate_Texture_Size(w, h, orig_d); + + if (w == tmp_w && h == tmp_h) + { + Reduction += i; + width = w; + height = h; + break; + } + } + } + + Width = width; + Height = height; + Format = Get_Valid_Texture_Format(orig_format, Texture->Is_Compression_Allowed()); + + unsigned int mip_level_count = Get_Mip_Level_Count(); + + // If texture wants all mip levels, take as many as the file contains (not necessarily all) + // Otherwise take as many mip levels as the texture wants, not to exceed the count in file... + if (!mip_level_count) + { + mip_level_count = orig_mip_count;//dds_file.Get_Mip_Level_Count(); + } + else if (mip_level_count > orig_mip_count) + {//dds_file.Get_Mip_Level_Count()) { + mip_level_count = orig_mip_count;//dds_file.Get_Mip_Level_Count(); + } + + // Once more, verify that the mip level count is correct (in case it was changed here it might not + // match the size...well actually it doesn't have to match but it can't be bigger than the size) + unsigned int max_mip_level_count = 1; + unsigned int w = 4; + unsigned int h = 4; + + while (w < Width && h < Height) + { + w += w; + h += h; + max_mip_level_count++; + } + + if (mip_level_count > max_mip_level_count) + { + mip_level_count = max_mip_level_count; + } + + D3DTexture = DX8Wrapper::_Create_DX8_Cube_Texture + ( + Width, + Height, + Format, + (MipCountType)mip_level_count, +#ifdef USE_MANAGED_TEXTURES + D3DPOOL_MANAGED +#else + D3DPOOL_SYSTEMMEM +#endif + ); + + MipLevelCount = mip_level_count; + return true; +} + +bool CubeTextureLoadTaskClass::Begin_Uncompressed_Load(void) +{ + unsigned width, height, depth, orig_mip_count, reduction; + WW3DFormat orig_format; + if (!Get_Texture_Information + ( + Texture->Get_Full_Path(), + reduction, + width, + height, + depth, + orig_format, + orig_mip_count, + false + ) + ) + { + return false; + } + + WW3DFormat src_format = orig_format; + WW3DFormat dest_format = src_format; + dest_format = Get_Valid_Texture_Format(dest_format, false); // No compressed destination format if reading from targa... + + if (src_format != WW3D_FORMAT_A8R8G8B8 + && src_format != WW3D_FORMAT_R8G8B8 + && src_format != WW3D_FORMAT_X8R8G8B8) + { + WWDEBUG_SAY(("Invalid TGA format used in %s - only 24 and 32 bit formats should be used!", Texture->Get_Full_Path().str())); + } + + // Destination size will be the next power of two square from the larger width and height... + unsigned ow = width; + unsigned oh = height; + TextureLoader::Validate_Texture_Size(width, height, depth); + if (width != ow || height != oh) + { + WWDEBUG_SAY(("Invalid texture size, scaling required. Texture: %s, size: %d x %d -> %d x %d", Texture->Get_Full_Path().str(), ow, oh, width, height)); + } + + Width = width; + Height = height; + + if (Format == WW3D_FORMAT_UNKNOWN) + { + Format = dest_format; + } + else + { + Format = Get_Valid_Texture_Format(Format, false); + } + + D3DTexture = DX8Wrapper::_Create_DX8_Cube_Texture + ( + Width, + Height, + Format, + Texture->MipLevelCount, +#ifdef USE_MANAGED_TEXTURES + D3DPOOL_MANAGED +#else + D3DPOOL_SYSTEMMEM +#endif + ); + + return true; +} + +bool CubeTextureLoadTaskClass::Load_Compressed_Mipmap(void) +{ + DDSFileClass dds_file(Texture->Get_Full_Path(), Get_Reduction()); + + // if we can't load from file, indicate rror. + if (!dds_file.Is_Available() || !dds_file.Load()) + { + return false; + } + + // load cube map faces + for (unsigned int face = 0; face < 6; face++) + { + unsigned int width = Get_Width(); + unsigned int height = Get_Height(); + + for (unsigned int level = 0; level < Get_Mip_Level_Count(); level++) + { + WWASSERT(width && height); + + // get cube map surface + dds_file.Copy_CubeMap_Level_To_Surface + ( + face, + level, + Get_Format(), + width, + height, + Get_Locked_CubeMap_Surface_Pointer(face, level), + Get_Locked_CubeMap_Surface_Pitch(face, level), + HSVShift + ); + + width >>= 1; + height >>= 1; + } + } + + return true; +} + +unsigned char* CubeTextureLoadTaskClass::Get_Locked_CubeMap_Surface_Pointer(unsigned int face, unsigned int level) +{ + WWASSERT(face < 6 && level < MipLevelCount); + WWASSERT(LockedCubeSurfacePtr[face][level]); + return LockedCubeSurfacePtr[face][level]; +} + +unsigned int CubeTextureLoadTaskClass::Get_Locked_CubeMap_Surface_Pitch(unsigned int face, unsigned int level) const +{ + WWASSERT(face < 6 && level < MipLevelCount); + WWASSERT(LockedCubeSurfacePitch[face][level]); + return LockedCubeSurfacePitch[face][level]; +} + + + + + + + +// VolumeTextureLoadTaskClass +VolumeTextureLoadTaskClass::VolumeTextureLoadTaskClass() + : TextureLoadTaskClass() +{ + // because texture load tasks are pooled, the constructor and destructor + // don't need to do much. The work of attaching a task to a texture is + // is done by Init() and Deinit(). + + for (int i = 0; i < MIP_LEVELS_MAX; ++i) + { + LockedSurfacePtr[i] = NULL; + LockedSurfacePitch[i] = 0; + LockedSurfaceSlicePitch[i] = 0; + } +} + +void VolumeTextureLoadTaskClass::Destroy(void) +{ + // detach the task from its texture, and return to free pool. + Deinit(); + _VolTexLoadFreeList.Push_Front(this); +} + +void VolumeTextureLoadTaskClass::Init(TextureBaseClass* tc, TaskType type, PriorityType priority) +{ + WWASSERT(tc); + + // NOTE: we must be in the main thread to avoid corrupting the texture's refcount. + WWASSERT(TextureLoader::Is_DX8_Thread()); + REF_PTR_SET(Texture, tc); + + // Make sure texture has a filename. + WWASSERT(Texture->Get_Full_Path() != ""); + + Type = type; + Priority = priority; + State = STATE_NONE; + + D3DTexture = 0; + + VolumeTextureClass* tex = Texture->As_VolumeTextureClass(); + + if (tex) + { + Format = tex->Get_Texture_Format(); // don't assume format yet KM + } + else + { + Format = WW3D_FORMAT_UNKNOWN; + } + + Width = 0; + Height = 0; + Depth = 0; + MipLevelCount = Texture->MipLevelCount; + Reduction = Texture->Get_Reduction(); + HSVShift = Texture->Get_HSV_Shift(); + + + for (int i = 0; i < MIP_LEVELS_MAX; ++i) + { + LockedSurfacePtr[i] = NULL; + LockedSurfacePitch[i] = 0; + LockedSurfaceSlicePitch[i] = 0; + } + + switch (Type) + { + case TASK_THUMBNAIL: + WWASSERT(Texture->ThumbnailLoadTask == NULL); + Texture->ThumbnailLoadTask = this; + break; + + case TASK_LOAD: + WWASSERT(Texture->TextureLoadTask == NULL); + Texture->TextureLoadTask = this; + break; + } +} + +void VolumeTextureLoadTaskClass::Lock_Surfaces() +{ + for (unsigned int i = 0; i < MipLevelCount; i++) + { + D3DLOCKED_BOX locked_box; + DX8_ErrorCode + ( + Peek_D3D_Volume_Texture()->LockBox + ( + i, + &locked_box, + NULL, + 0 + ) + ); + LockedSurfacePtr[i] = (unsigned char*)locked_box.pBits; + LockedSurfacePitch[i] = locked_box.RowPitch; + LockedSurfaceSlicePitch[i] = locked_box.SlicePitch; + } +} + + +void VolumeTextureLoadTaskClass::Unlock_Surfaces() +{ + for (unsigned int i = 0; i < MipLevelCount; ++i) + { + if (LockedSurfacePtr[i]) + { + WWASSERT(ThreadClass::_Get_Current_Thread_ID() == DX8Wrapper::_Get_Main_Thread_ID()); + DX8_ErrorCode + ( + Peek_D3D_Volume_Texture()->UnlockBox(i) + ); + } + LockedSurfacePtr[i] = NULL; + } + +#ifndef USE_MANAGED_TEXTURES + IDirect3DTexture8* tex = DX8Wrapper::_Create_DX8_Volume_Texture(Width, Height, Depth, Format, Texture->MipLevelCount, D3DPOOL_DEFAULT); + DX8CALL(UpdateTexture(Peek_D3D_Volume_Texture(), tex)); + Peek_D3D_Volume_Texture()->Release(); + D3DTexture = tex; + WWDEBUG_SAY(("Created non-managed texture (%s)", Texture->Get_Full_Path())); +#endif + +} + + + +bool VolumeTextureLoadTaskClass::Begin_Compressed_Load() +{ + unsigned orig_w, orig_h, orig_d, orig_mip_count, reduction; + WW3DFormat orig_format; + if (!Get_Texture_Information + ( + Texture->Get_Full_Path(), + reduction, + orig_w, + orig_h, + orig_d, + orig_format, + orig_mip_count, + true + ) + ) + { + return false; + } + + // Destination size will be the next power of two square from the larger width and height... + unsigned int width = orig_w; + unsigned int height = orig_h; + unsigned int depth = orig_d; + TextureLoader::Validate_Texture_Size(width, height, depth); + + // If the size doesn't match, try and see if texture reduction would help... (mainly for + // cases where loaded texture is larger than hardware limit) + if (width != orig_w || height != orig_h || depth != orig_d) + { + for (unsigned int i = 1; i < orig_mip_count; ++i) + { + unsigned w = orig_w >> i; + if (w < 4) w = 4; + unsigned h = orig_h >> i; + if (h < 4) h = 4; + unsigned d = orig_d >> i; + if (d < 1) d = 1; + unsigned tmp_w = w; + unsigned tmp_h = h; + unsigned tmp_d = d; + + TextureLoader::Validate_Texture_Size(w, h, d); + + if (w == tmp_w && h == tmp_h && d == tmp_d) + { + Reduction += i; + width = w; + height = h; + depth = d; + break; + } + } + } + + Width = width; + Height = height; + Depth = depth; + Format = Get_Valid_Texture_Format(orig_format, Texture->Is_Compression_Allowed()); + + unsigned int mip_level_count = Get_Mip_Level_Count(); + + // If texture wants all mip levels, take as many as the file contains (not necessarily all) + // Otherwise take as many mip levels as the texture wants, not to exceed the count in file... + if (!mip_level_count) + { + mip_level_count = orig_mip_count;//dds_file.Get_Mip_Level_Count(); + } + else if (mip_level_count > orig_mip_count) + {//dds_file.Get_Mip_Level_Count()) { + mip_level_count = orig_mip_count;//dds_file.Get_Mip_Level_Count(); + } + + // Once more, verify that the mip level count is correct (in case it was changed here it might not + // match the size...well actually it doesn't have to match but it can't be bigger than the size) + unsigned int max_mip_level_count = 1; + unsigned int w = 4; + unsigned int h = 4; + + while (w < Width && h < Height) + { + w += w; + h += h; + max_mip_level_count++; + } + if (mip_level_count > max_mip_level_count) + { + mip_level_count = max_mip_level_count; + } + + D3DTexture = DX8Wrapper::_Create_DX8_Volume_Texture + ( + Width, + Height, + Depth, + Format, + (MipCountType)mip_level_count, +#ifdef USE_MANAGED_TEXTURES + D3DPOOL_MANAGED +#else + D3DPOOL_SYSTEMMEM +#endif + ); + + MipLevelCount = mip_level_count; + return true; +} + +bool VolumeTextureLoadTaskClass::Begin_Uncompressed_Load(void) +{ + unsigned width, height, depth, orig_mip_count, reduction; + WW3DFormat orig_format; + if (!Get_Texture_Information + ( + Texture->Get_Full_Path(), + reduction, + width, + height, + depth, + orig_format, + orig_mip_count, + false + ) + ) + { + return false; + } + + WW3DFormat src_format = orig_format; + WW3DFormat dest_format = src_format; + dest_format = Get_Valid_Texture_Format(dest_format, false); // No compressed destination format if reading from targa... + + if (src_format != WW3D_FORMAT_A8R8G8B8 + && src_format != WW3D_FORMAT_R8G8B8 + && src_format != WW3D_FORMAT_X8R8G8B8) + { + WWDEBUG_SAY(("Invalid TGA format used in %s - only 24 and 32 bit formats should be used!", Texture->Get_Full_Path().str())); + } + + // Destination size will be the next power of two square from the larger width and height... + unsigned ow = width; + unsigned oh = height; + unsigned od = depth; + TextureLoader::Validate_Texture_Size(width, height, depth); + if (width != ow || height != oh || depth != od) + { + WWDEBUG_SAY(("Invalid texture size, scaling required. Texture: %s, size: %d x %d -> %d x %d", Texture->Get_Full_Path().str(), ow, oh, width, height)); + } + + Width = width; + Height = height; + Depth = depth; + + if (Format == WW3D_FORMAT_UNKNOWN) + { + Format = dest_format; + } + else + { + Format = Get_Valid_Texture_Format(Format, false); + } + + D3DTexture = DX8Wrapper::_Create_DX8_Volume_Texture + ( + Width, + Height, + Depth, + Format, + Texture->MipLevelCount, +#ifdef USE_MANAGED_TEXTURES + D3DPOOL_MANAGED +#else + D3DPOOL_SYSTEMMEM +#endif + ); + + return true; +} + +bool VolumeTextureLoadTaskClass::Load_Compressed_Mipmap(void) +{ + DDSFileClass dds_file(Texture->Get_Full_Path(), Get_Reduction()); + + // if we can't load from file, indicate rror. + if (!dds_file.Is_Available() || !dds_file.Load()) + { + return false; + } + + // load volume + unsigned int depth = dds_file.Get_Depth(0); + unsigned int width = Get_Width(); + unsigned int height = Get_Height(); + + WWASSERT(width && height && depth); + + for (unsigned int level = 0; level < Get_Mip_Level_Count(); level++) + { + if (width < 1) width = 1; + if (height < 1) height = 1; + if (depth < 1) depth = 1; + + // get volume + dds_file.Copy_Volume_Level_To_Surface + ( + level, + depth, + Get_Format(), + width, + height, + Get_Locked_Volume_Pointer(level), + Get_Locked_Volume_Row_Pitch(level), + Get_Locked_Volume_Slice_Pitch(level), + HSVShift + ); + + width >>= 1; + height >>= 1; + depth >>= 1; + } + + return true; +} + +unsigned char* VolumeTextureLoadTaskClass::Get_Locked_Volume_Pointer(unsigned int level) +{ + WWASSERT(level < MipLevelCount); + WWASSERT(LockedSurfacePtr[level]); + return LockedSurfacePtr[level]; +} + +unsigned int VolumeTextureLoadTaskClass::Get_Locked_Volume_Row_Pitch(unsigned int level) +{ + WWASSERT(level < MipLevelCount); + WWASSERT(LockedSurfacePtr[level]); + return LockedSurfacePitch[level]; +} + +unsigned int VolumeTextureLoadTaskClass::Get_Locked_Volume_Slice_Pitch(unsigned int level) +{ + WWASSERT(level < MipLevelCount); + WWASSERT(LockedSurfacePtr[level]); + return LockedSurfaceSlicePitch[level]; +} diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/textureloader.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/textureloader.h index 7fd9091edb..434fb917af 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/textureloader.h +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/textureloader.h @@ -1,5 +1,5 @@ /* -** Command & Conquer Generals(tm) +** Command & Conquer Generals Zero Hour(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify @@ -16,6 +16,28 @@ ** 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 : DX8 Texture Manager * + * * + * $Archive:: /Commando/Code/ww3d2/textureloader.h $* + * * + * Original Author:: vss_sync * + * * + * Author : Kenny Mitchell * + * * + * $Modtime:: 06/27/02 1:27p $* + * * + * $Revision:: 2 $* + * * + * 06/27/02 KM Texture class abstraction * + *---------------------------------------------------------------------------------------------* + * Functions: * + * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + #ifndef TEXTURELOADER_H #define TEXTURELOADER_H @@ -32,111 +54,281 @@ class TextureLoadTaskClass; class TextureLoader { - static void Init_Load_Task(TextureBaseClass* tc); - - static bool Load_Uncompressed_Mipmap_Levels_From_TGA(TextureLoadTaskClass* texture); - public: - static void Init(); - static void Deinit(); + static void Init(void); + static void Deinit(void); // Modify given texture size to nearest valid size on current hardware. - static void Validate_Texture_Size(unsigned& width, unsigned& height); + static void Validate_Texture_Size(unsigned& width, unsigned& height, unsigned& depth); - // Adds a loading task to the system. The task if processed in a separate - // thread as soon as possible. The task will appear in finished tasks list - // when it's been completed. The texture will be refreshed on the next - // update call after appearing to the finished tasks list. - static void Add_Load_Task(TextureBaseClass* tc); static IDirect3DTexture8* Load_Thumbnail( - const StringClass& filename, - WW3DFormat texture_format); // Pass WW3D_FORMAT_UNKNOWN if you don't care - static void Load_Mipmap_Levels(TextureLoadTaskClass* texture); + const StringClass& filename, const Vector3& hsv_shift); + // WW3DFormat texture_format); // Pass WW3D_FORMAT_UNKNOWN if you don't care static IDirect3DSurface8* Load_Surface_Immediate( const StringClass& filename, WW3DFormat surface_format, // Pass WW3D_FORMAT_UNKNOWN if you don't care bool allow_compression); + static void Request_Thumbnail(TextureBaseClass* tc); + + // Adds a loading task to the system. The task if processed in a separate + // thread as soon as possible. The task will appear in finished tasks list + // when it's been completed. The texture will be refreshed on the next + // update call after appearing to the finished tasks list. + static void Request_Background_Loading(TextureBaseClass* tc); + // Textures can only be created and locked by the main thread so this function sends a request to the texture // handling system to load the texture immediatelly next time it enters the main thread. If this function // is called from the main thread the texture is loaded immediatelly. - static void Request_High_Priority_Loading( - TextureBaseClass* texture, - MipCountType mip_level_count); - static void Request_Thumbnail(TextureBaseClass* tc); + static void Request_Foreground_Loading(TextureBaseClass* tc); + + static void Flush_Pending_Load_Tasks(void); + static void Update(void(*network_callback)(void) = NULL); - static void Update(); - static void Flush_Pending_Load_Tasks(); + // returns true if current thread of execution is allowed to make DX8 calls. + static bool Is_DX8_Thread(void); - static IDirect3DTexture8* Generate_Bumpmap(TextureBaseClass* texture); + static void Suspend_Texture_Load(); + static void Continue_Texture_Load(); + static void Set_Texture_Inactive_Override_Time(int time_ms) { TextureInactiveOverrideTime = time_ms; } + +private: + static void Process_Foreground_Load(TextureLoadTaskClass* task); + static void Process_Foreground_Thumbnail(TextureLoadTaskClass* task); + + static void Begin_Load_And_Queue(TextureLoadTaskClass* task); + static void Load_Thumbnail(TextureBaseClass* tc); + + static bool TextureLoadSuspended; + + // The time in ms before a texture is thrown out. + // The default is zero. The scripted movies set this to reduce texture stalls in movies. + static int TextureInactiveOverrideTime; }; -// ---------------------------------------------------------------------------- -// -// Texture loader task handler -// -// ---------------------------------------------------------------------------- +class TextureLoadTaskListNodeClass +{ + friend class TextureLoadTaskListClass; -class TextureLoadTaskClass : public W3DMPO +public: + TextureLoadTaskListNodeClass(void) : Next(0), Prev(0) { } + + TextureLoadTaskListClass* Get_List(void) { return List; } + + TextureLoadTaskListNodeClass* Next; + TextureLoadTaskListNodeClass* Prev; + TextureLoadTaskListClass* List; +}; + + +class TextureLoadTaskListClass +{ + // This class implements an unsynchronized, double-linked list of TextureLoadTaskClass + // objects, using an embedded list node. + +public: + TextureLoadTaskListClass(void); + + // Returns true if list is empty, false otherwise. + bool Is_Empty(void) const { return (Root.Next == &Root); } + + // Add a task to beginning of list + void Push_Front(TextureLoadTaskClass* task); + + // Add a task to end of list + void Push_Back(TextureLoadTaskClass* task); + + // Remove and return a task from beginning of list, or NULL if list is empty. + TextureLoadTaskClass* Pop_Front(void); + + // Remove and return a task from end of list, or NULL if list is empty + TextureLoadTaskClass* Pop_Back(void); + + // Remove specified task from list, if present + void Remove(TextureLoadTaskClass* task); + +private: + // This list is implemented using a sentinel node. + TextureLoadTaskListNodeClass Root; +}; + + +class SynchronizedTextureLoadTaskListClass : public TextureLoadTaskListClass { - W3DMPO_GLUE(TextureLoadTaskClass) + // This class added thread-safety to the basic TextureLoadTaskListClass. - static TextureLoadTaskClass* FreeTaskListHead; +public: + SynchronizedTextureLoadTaskListClass(void); + + // See comments above for description of member functions. + void Push_Front(TextureLoadTaskClass* task); + void Push_Back(TextureLoadTaskClass* task); + TextureLoadTaskClass* Pop_Front(void); + TextureLoadTaskClass* Pop_Back(void); + void Remove(TextureLoadTaskClass* task); + +private: + FastCriticalSectionClass CriticalSection; +}; + +/* +** (gth) The allocation system we're using for TextureLoadTaskClass has gotten a little +** complicated since Kenny added the new task types for Cube and Volume textures. The +** ::Destroy member is used to return a task to the pool now and must be over-ridden in +** each derived class to put the task back into the correct free list. +*/ + + +class TextureLoadTaskClass : public TextureLoadTaskListNodeClass +{ +public: + enum TaskType { + TASK_NONE, + TASK_THUMBNAIL, + TASK_LOAD, + }; + + enum PriorityType { + PRIORITY_LOW, + PRIORITY_HIGH, + }; + + enum StateType { + STATE_NONE, + + STATE_LOAD_BEGUN, + STATE_LOAD_MIPMAP, + STATE_LOAD_COMPLETE, + + STATE_COMPLETE, + }; + + + TextureLoadTaskClass(void); + ~TextureLoadTaskClass(void); + + static TextureLoadTaskClass* Create(TextureBaseClass* tc, TaskType type, PriorityType priority); + static void Delete_Free_Pool(void); + + virtual void Destroy(void); + virtual void Init(TextureBaseClass* tc, TaskType type, PriorityType priority); + virtual void Deinit(void); + + TaskType Get_Type(void) const { return Type; } + PriorityType Get_Priority(void) const { return Priority; } + StateType Get_State(void) const { return State; } + + WW3DFormat Get_Format(void) const { return Format; } + unsigned int Get_Width(void) const { return Width; } + unsigned int Get_Height(void) const { return Height; } + unsigned int Get_Mip_Level_Count(void) const { return MipLevelCount; } + unsigned int Get_Reduction(void) const { return Reduction; } + + unsigned char* Get_Locked_Surface_Ptr(unsigned int level); + unsigned int Get_Locked_Surface_Pitch(unsigned int level) const; + + TextureBaseClass* Peek_Texture(void) { return Texture; } + IDirect3DTexture8* Peek_D3D_Texture(void) { return (IDirect3DTexture8*)D3DTexture; } + + void Set_Type(TaskType t) { Type = t; } + void Set_Priority(PriorityType p) { Priority = p; } + void Set_State(StateType s) { State = s; } + + bool Begin_Load(void); + bool Load(void); + void End_Load(void); + void Finish_Load(void); + void Apply_Missing_Texture(void); + +protected: + virtual bool Begin_Compressed_Load(void); + virtual bool Begin_Uncompressed_Load(void); + + virtual bool Load_Compressed_Mipmap(void); + virtual bool Load_Uncompressed_Mipmap(void); + + virtual void Lock_Surfaces(void); + virtual void Unlock_Surfaces(void); + + void Apply(bool initialize); TextureBaseClass* Texture; - IDirect3DTexture8 *D3DTexture; - unsigned Width; - unsigned Height; - WW3DFormat Format; + IDirect3DBaseTexture8* D3DTexture; + WW3DFormat Format; + + unsigned int Width; + unsigned int Height; + unsigned int MipLevelCount; + unsigned int Reduction; + Vector3 HSVShift; + unsigned char* LockedSurfacePtr[MIP_LEVELS_MAX]; - unsigned LockedSurfacePitch[MIP_LEVELS_MAX]; - unsigned MipLevelCount; - unsigned Reduction; - TextureLoadTaskClass* Succ; - bool IsLoading; - bool HasFailed; - bool HighPriorityRequested; - - ~TextureLoadTaskClass(); - TextureLoadTaskClass(); -public: - static TextureLoadTaskClass* Get_Instance(TextureBaseClass* tc, bool high_priority); - static void Release_Instance(TextureLoadTaskClass* task); - static void shutdown(void) {TextureLoadTaskClass *pT; while (FreeTaskListHead) {pT = FreeTaskListHead; FreeTaskListHead = pT->Peek_Succ(); pT->Set_Succ(NULL); delete pT;} }; + unsigned int LockedSurfacePitch[MIP_LEVELS_MAX]; - void Init(TextureBaseClass* tc,bool high_priority); - void Deinit(); + TaskType Type; + PriorityType Priority; + StateType State; +}; - unsigned Get_Mip_Level_Count() const { return MipLevelCount; } - unsigned Get_Width() const { return Width; } - unsigned Get_Height() const { return Height; } - WW3DFormat Get_Format() const { return Format; } - unsigned Get_Reduction() const { return Reduction; } +class CubeTextureLoadTaskClass : public TextureLoadTaskClass +{ +public: + CubeTextureLoadTaskClass(); - unsigned char* Get_Locked_Surface_Ptr(unsigned level); - unsigned Get_Locked_Surface_Pitch(unsigned level) const; + virtual void Destroy(void); + virtual void Init(TextureBaseClass* tc, TaskType type, PriorityType priority); + virtual void Deinit(void); - bool Has_Failed() const { return HasFailed; } - void Set_Fail(bool b) { HasFailed=b; } +protected: + virtual bool Begin_Compressed_Load(void); + virtual bool Begin_Uncompressed_Load(void); - // Init the task or put it to a deferred init list if called from outside the main thread - void Begin_Texture_Load(); - void Begin_Thumbnail_Load(); - void End_Load(); // Deinit must be called before Applying() + virtual bool Load_Compressed_Mipmap(void); + // virtual bool Load_Uncompressed_Mipmap(void); - void Apply(bool initialize); + virtual void Lock_Surfaces(void); + virtual void Unlock_Surfaces(void); - TextureLoadTaskClass* Peek_Succ() { return Succ; } - void Set_Succ(TextureLoadTaskClass* succ); +private: + unsigned char* Get_Locked_CubeMap_Surface_Pointer(unsigned int face, unsigned int level); + unsigned int Get_Locked_CubeMap_Surface_Pitch(unsigned int face, unsigned int level) const; - TextureBaseClass* Peek_Texture() { return Texture; } - IDirect3DTexture8* Peek_D3D_Texture() { return D3DTexture; } + IDirect3DCubeTexture8* Peek_D3D_Cube_Texture(void) { return (IDirect3DCubeTexture8*)D3DTexture; } - void Set_D3D_Texture(IDirect3DTexture8* texture); + unsigned char* LockedCubeSurfacePtr[6][MIP_LEVELS_MAX]; + unsigned int LockedCubeSurfacePitch[6][MIP_LEVELS_MAX]; }; -#endif +class VolumeTextureLoadTaskClass : public TextureLoadTaskClass +{ +public: + VolumeTextureLoadTaskClass(); + + virtual void Destroy(void); + virtual void Init(TextureBaseClass* tc, TaskType type, PriorityType priority); + +protected: + virtual bool Begin_Compressed_Load(void); + virtual bool Begin_Uncompressed_Load(void); + + virtual bool Load_Compressed_Mipmap(void); + // virtual bool Load_Uncompressed_Mipmap(void); + + virtual void Lock_Surfaces(void); + virtual void Unlock_Surfaces(void); +private: + unsigned char* Get_Locked_Volume_Pointer(unsigned int level); + unsigned int Get_Locked_Volume_Row_Pitch(unsigned int level); + unsigned int Get_Locked_Volume_Slice_Pitch(unsigned int level); + IDirect3DVolumeTexture8* Peek_D3D_Volume_Texture(void) { return (IDirect3DVolumeTexture8*)D3DTexture; } + + unsigned int LockedSurfaceSlicePitch[MIP_LEVELS_MAX]; + + unsigned int Depth; +}; + +#endif diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturethumbnail.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturethumbnail.cpp index 4a9ebd2f2a..02e282f6e7 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturethumbnail.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturethumbnail.cpp @@ -26,20 +26,54 @@ #include "bitmaphandler.h" #include "ffactory.h" +#include "RAWFILE.H" +#include "wwprofile.h" +#include + +static DLListClass ThumbnailManagerList; +static ThumbnailManagerClass* GlobalThumbnailManager; +bool ThumbnailManagerClass::CreateThumbnailIfNotFound = false; + static HashTemplateClass thumbnail_hash; static bool _ThumbHashModified; static unsigned char* _ThumbnailMemory; static const char *THUMBNAIL_FILENAME = "thumbnails.dat"; -ThumbnailClass::ThumbnailClass(const char* name, unsigned char* bitmap, unsigned w, unsigned h, bool allocated) +static void Create_Hash_Name(StringClass& name, const StringClass& thumb_name) +{ + name = thumb_name; + int len = name.Get_Length(); + WWASSERT(!stricmp(&name[len - 4], ".tga") || !stricmp(&name[len - 4], ".dds")); + name[len - 4] = '\0'; + _strlwr(name.Peek_Buffer()); +} + +ThumbnailClass::ThumbnailClass( + ThumbnailManagerClass* manager, + const char* name, + unsigned char* bitmap, + unsigned w, + unsigned h, + unsigned original_w, + unsigned original_h, + unsigned original_mip_level_count, + WW3DFormat original_format, + bool allocated, + unsigned long date_time) : - Name(name), - Bitmap(bitmap), + Manager(manager), + Name(name), + Bitmap(bitmap), Allocated(allocated), Width(w), - Height(h) + Height(h), + OriginalTextureWidth(original_w), + OriginalTextureHeight(original_h), + OriginalTextureMipLevelCount(original_mip_level_count), + OriginalTextureFormat(original_format), + DateTime(date_time) { - thumbnail_hash.Insert(Name,this); + Manager->Insert_To_Hash(this); } // ---------------------------------------------------------------------------- @@ -51,80 +85,154 @@ ThumbnailClass::ThumbnailClass(const char* name, unsigned char* bitmap, unsigned // // ---------------------------------------------------------------------------- -ThumbnailClass::ThumbnailClass(const StringClass& filename) +ThumbnailClass::ThumbnailClass(ThumbnailManagerClass* manager, const StringClass& filename) : - Bitmap(0), - Name(filename), + Manager(manager), + Bitmap(0), + Name(filename), Allocated(false), Width(0), - Height(0) + Height(0), + OriginalTextureWidth(0), + OriginalTextureHeight(0), + OriginalTextureMipLevelCount(0), + OriginalTextureFormat(WW3D_FORMAT_UNKNOWN), + DateTime(0) { - unsigned reduction_factor=3; + WWPROFILE(("ThumbnailClass::ThumbnailClass")); + unsigned reduction_factor = 3; // First, try loading image from a DDS file - DDSFileClass dds_file(filename,reduction_factor); + DDSFileClass dds_file(filename, reduction_factor); if (dds_file.Is_Available() && dds_file.Load()) { - Width=dds_file.Get_Width(0); - Height=dds_file.Get_Height(0); - Bitmap=W3DNEWARRAY unsigned char[Width*Height*4]; - Allocated=true; + DateTime = dds_file.Get_Date_Time(); + + int len = Name.Get_Length(); + WWASSERT(len > 4); + Name[len - 3] = 'd'; + Name[len - 2] = 'd'; + Name[len - 1] = 's'; + + unsigned level = 0; + while (dds_file.Get_Width(level) > 32 || dds_file.Get_Height(level) > 32) { + if (level >= dds_file.Get_Mip_Level_Count()) break; + level++; + } + + OriginalTextureWidth = dds_file.Get_Full_Width(); + OriginalTextureHeight = dds_file.Get_Full_Height(); + OriginalTextureFormat = dds_file.Get_Format(); + OriginalTextureMipLevelCount = dds_file.Get_Mip_Level_Count(); + Width = dds_file.Get_Width(0); + Height = dds_file.Get_Height(0); + Bitmap = W3DNEWARRAY unsigned char[Width * Height * 2]; + Allocated = true; dds_file.Copy_Level_To_Surface( 0, // Level - WW3D_FORMAT_A8R8G8B8, - Width, - Height, - Bitmap, - Width*4); + WW3D_FORMAT_A4R4G4B4, + Width, + Height, + Bitmap, + Width * 2, + Vector3(0.0f, 0.0f, 0.0f));// We don't want to HSV-shift here } // If DDS file can't be used try loading from TGA else { // Make sure the file can be opened. If not, return missing texture. Targa targa; - if (TARGA_ERROR_HANDLER(targa.Open(filename,TGA_READMODE),filename)) return; + if (TARGA_ERROR_HANDLER(targa.Open(filename, TGA_READMODE), filename)) return; // DX8 uses image upside down compared to TGA targa.Header.ImageDescriptor ^= TGAIDF_YORIGIN; - WW3DFormat src_format,dest_format; - unsigned src_bpp=0; - Get_WW3D_Format(dest_format,src_format,src_bpp,targa); + WW3DFormat src_format, dest_format; + unsigned src_bpp = 0; + Get_WW3D_Format(src_format, src_bpp, targa); + if (src_format == WW3D_FORMAT_UNKNOWN) { + WWDEBUG_SAY(("Unknown texture format for %s", filename.str())); + return; + } // Destination size will be the next power of two square from the larger width and height... - Width=targa.Header.Width>>reduction_factor; - Height=targa.Header.Height>>reduction_factor; - TextureLoader::Validate_Texture_Size(Width,Height); - unsigned src_width=targa.Header.Width; - unsigned src_height=targa.Header.Height; + OriginalTextureWidth = targa.Header.Width; + OriginalTextureHeight = targa.Header.Height; + OriginalTextureFormat = src_format; + Width = targa.Header.Width >> reduction_factor; + Height = targa.Header.Height >> reduction_factor; + OriginalTextureMipLevelCount = 1; + unsigned iw = 1; + unsigned ih = 1; + while (iw < OriginalTextureWidth && ih < OriginalTextureHeight) { + iw += iw; + ih += ih; + OriginalTextureMipLevelCount++; + } + + while (Width > 32 || Height > 32) { + reduction_factor++; + Width >>= 2; + Height >>= 2; + } + + unsigned poweroftwowidth = 1; + while (poweroftwowidth < Width) { + poweroftwowidth <<= 1; + } + + unsigned poweroftwoheight = 1; + while (poweroftwoheight < Height) { + poweroftwoheight <<= 1; + } + + Width = poweroftwowidth; + Height = poweroftwoheight; + + unsigned src_width = targa.Header.Width; + unsigned src_height = targa.Header.Height; // NOTE: We load the palette but we do not yet support paletted textures! - char palette[256*4]; + char palette[256 * 4]; targa.SetPalette(palette); - if (TARGA_ERROR_HANDLER(targa.Load(filename, TGAF_IMAGE, false),filename)) return; + if (TARGA_ERROR_HANDLER(targa.Load(filename, TGAF_IMAGE, false), filename)) return; + + // Get time stamp from the tga file + { + file_auto_ptr my_tga_file(_TheFileFactory, filename); + WWASSERT(my_tga_file->Is_Available()); + my_tga_file->Open(); + DateTime = my_tga_file->Get_Date_Time(); + my_tga_file->Close(); + } - unsigned char* src_surface=(unsigned char*)targa.GetImage(); + unsigned char* src_surface = (unsigned char*)targa.GetImage(); - Bitmap=W3DNEWARRAY unsigned char[Width*Height*4]; - Allocated=true; + int len = Name.Get_Length(); + WWASSERT(len > 4); + Name[len - 3] = 't'; + Name[len - 2] = 'g'; + Name[len - 1] = 'a'; - dest_format=WW3D_FORMAT_A8R8G8B8; + Bitmap = W3DNEWARRAY unsigned char[Width * Height * 2]; + Allocated = true; + + dest_format = WW3D_FORMAT_A8R8G8B8; BitmapHandlerClass::Copy_Image( - Bitmap, + Bitmap, Width, Height, - Width*4, - WW3D_FORMAT_A8R8G8B8, + Width * 2, + WW3D_FORMAT_A4R4G4B4, src_surface, src_width, src_height, - src_width*src_bpp, + src_width * src_bpp, src_format, (unsigned char*)targa.GetPalette(), - targa.Header.CMapDepth>>3, + targa.Header.CMapDepth >> 3, false); } - _ThumbHashModified=true; - thumbnail_hash.Insert(Name,this); + Manager->Insert_To_Hash(this); } ThumbnailClass::~ThumbnailClass() @@ -287,4 +395,158 @@ void ThumbnailClass::Deinit() delete [] _ThumbnailMemory; _ThumbnailMemory=NULL; -} \ No newline at end of file +} + +// ---------------------------------------------------------------------------- +ThumbnailManagerClass::ThumbnailManagerClass(const char* thumbnail_filename) + : + ThumbnailMemory(NULL), + ThumbnailFileName(thumbnail_filename), + PerTextureTimeStampUsed(false), + Changed(false), + DateTime(0) +{ +} + +// ---------------------------------------------------------------------------- +ThumbnailManagerClass::~ThumbnailManagerClass() +{ + HashTemplateIterator ite(ThumbnailHash); + ite.First(); + while (!ite.Is_Done()) { + ThumbnailClass* thumb = ite.Peek_Value(); + delete thumb; + ite.First(); + } + + if (ThumbnailMemory) delete[] ThumbnailMemory; + ThumbnailMemory = NULL; +} + +// ---------------------------------------------------------------------------- +ThumbnailManagerClass* ThumbnailManagerClass::Peek_Thumbnail_Manager(const char* thumbnail_filename) +{ + ThumbnailManagerClass* man = ThumbnailManagerList.Head(); + while (man) { + if (man->ThumbnailFileName == thumbnail_filename) return man; + man = man->Succ(); + } + if (GlobalThumbnailManager && + GlobalThumbnailManager->ThumbnailFileName == thumbnail_filename) return GlobalThumbnailManager; + return NULL; +} + +// ---------------------------------------------------------------------------- +void ThumbnailManagerClass::Add_Thumbnail_Manager(const char* thumbnail_filename) +{ + // First loop over all thumbnail managers to see if we already have this one created. This isn't + // supposed to be called often at all and there are usually just couple managers alive, + // so we'll do pure string compares here... + + // Must NOT add global manager with this function + WWASSERT(stricmp(thumbnail_filename, GLOBAL_THUMBNAIL_MANAGER_FILENAME)); + + ThumbnailManagerClass* man = Peek_Thumbnail_Manager(thumbnail_filename); + if (man) return; + + // Not found, create and add to the list. + man = new ThumbnailManagerClass(thumbnail_filename); + ThumbnailManagerList.Add_Tail(man); +} +// ---------------------------------------------------------------------------- +void ThumbnailManagerClass::Remove_Thumbnail_Manager(const char* thumbnail_filename) +{ + ThumbnailManagerClass* man = ThumbnailManagerList.Head(); + while (man) { + if (man->ThumbnailFileName == thumbnail_filename) { + delete man; + return; + } + man = man->Succ(); + } + if (GlobalThumbnailManager && + GlobalThumbnailManager->ThumbnailFileName == thumbnail_filename) { + delete GlobalThumbnailManager; + GlobalThumbnailManager = NULL; + } +} +// ---------------------------------------------------------------------------- +ThumbnailClass* ThumbnailManagerClass::Peek_Thumbnail_Instance(const StringClass& name) +{ + + return Get_From_Hash(name); +} + +ThumbnailClass* ThumbnailManagerClass::Peek_Thumbnail_Instance_From_Any_Manager(const StringClass& filename) +{ + WWPROFILE(("Peek_Thumbnail_Instance_From_Any_Manager")); + ThumbnailManagerClass* thumb_man = ThumbnailManagerList.Head(); + while (thumb_man) { + ThumbnailClass* thumb = thumb_man->Peek_Thumbnail_Instance(filename); + if (thumb) return thumb; + thumb_man = thumb_man->Succ(); + } + + if (GlobalThumbnailManager) { + ThumbnailClass* thumb = GlobalThumbnailManager->Peek_Thumbnail_Instance(filename); + if (thumb) return thumb; + } + + // If thumbnail is not found, see if we can find a texture. It is possible that the texture is outside of + // a mix file and didn't get included in any thumbnail database based on a mixfile. If so, we'll add it to + // our global thumbnail database. + if (Is_Thumbnail_Created_If_Not_Found()) { + if (GlobalThumbnailManager) { + ThumbnailClass* thumb = new ThumbnailClass(GlobalThumbnailManager, filename); + if (!thumb->Peek_Bitmap()) { + delete thumb; + thumb = NULL; + } + return thumb; + } + } + + return NULL; +} + + +void ThumbnailManagerClass::Insert_To_Hash(ThumbnailClass* thumb) +{ + Changed = true; + StringClass hash_name(0, true); + Create_Hash_Name(hash_name, thumb->Get_Name()); + ThumbnailHash.Insert(hash_name, thumb); +} + +ThumbnailClass* ThumbnailManagerClass::Get_From_Hash(const StringClass& name) +{ + StringClass hash_name(0, true); + Create_Hash_Name(hash_name, name); + return ThumbnailHash.Get(hash_name); +} + +void ThumbnailManagerClass::Remove_From_Hash(ThumbnailClass* thumb) +{ + Changed = true; + StringClass hash_name(0, true); + Create_Hash_Name(hash_name, thumb->Get_Name()); + ThumbnailHash.Remove(hash_name); +} + +void ThumbnailManagerClass::Init() +{ + WWASSERT(GlobalThumbnailManager == NULL); + GlobalThumbnailManager = new ThumbnailManagerClass(GLOBAL_THUMBNAIL_MANAGER_FILENAME); + GlobalThumbnailManager->Enable_Per_Texture_Time_Stamp(true); +} + +void ThumbnailManagerClass::Deinit() +{ + while (ThumbnailManagerClass* man = ThumbnailManagerList.Head()) { + delete man; + } + if (GlobalThumbnailManager) { + delete GlobalThumbnailManager; + GlobalThumbnailManager = NULL; + } +} diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturethumbnail.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturethumbnail.h index 905517e5e4..983d1d1236 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturethumbnail.h +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturethumbnail.h @@ -26,6 +26,14 @@ #include "always.h" #include "wwstring.h" +#include "hashtemplate.h" +#include "dllist.h" +#include "ww3dformat.h" + +#define GLOBAL_THUMBNAIL_MANAGER_FILENAME "global.th6" + +class ThumbnailManagerClass; + // ---------------------------------------------------------------------------- class ThumbnailClass @@ -34,15 +42,39 @@ class ThumbnailClass unsigned char* Bitmap; unsigned Width; unsigned Height; + unsigned OriginalTextureWidth; + unsigned OriginalTextureHeight; + unsigned OriginalTextureMipLevelCount; + WW3DFormat OriginalTextureFormat; + unsigned long DateTime; bool Allocated; // if true, destructor will free the memory + ThumbnailManagerClass* Manager; public: - ThumbnailClass(const char* name, unsigned char* bitmap, unsigned w, unsigned h, bool allocated); - ThumbnailClass(const StringClass& filename); + ThumbnailClass( + ThumbnailManagerClass* manager, + const char* name, + unsigned char* bitmap, + unsigned w, + unsigned h, + unsigned original_w, + unsigned original_h, + unsigned original_mip_level_count, + WW3DFormat original_format, + bool allocated, + unsigned long date_time); + ThumbnailClass( + ThumbnailManagerClass* manager, + const StringClass& filename); ~ThumbnailClass(); unsigned char* Peek_Bitmap() { return Bitmap; } + WW3DFormat Get_Format() { return WW3D_FORMAT_A4R4G4B4; } unsigned Get_Width() const { return Width; } unsigned Get_Height() const { return Height; } + unsigned Get_Original_Texture_Width() const { return OriginalTextureWidth; } + unsigned Get_Original_Texture_Height() const { return OriginalTextureHeight; } + unsigned Get_Original_Texture_Mip_Level_Count() const { return OriginalTextureMipLevelCount; } + WW3DFormat Get_Original_Texture_Format() const { return OriginalTextureFormat; } const StringClass& Get_Name() const { return Name; } static ThumbnailClass* Peek_Instance(const StringClass& name); @@ -52,4 +84,49 @@ class ThumbnailClass // ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- + +class ThumbnailManagerClass : public DLNodeClass +{ + W3DMPO_GLUE(ThumbnailManagerClass); + + friend ThumbnailClass; + + static bool CreateThumbnailIfNotFound; + bool PerTextureTimeStampUsed; + StringClass ThumbnailFileName; + HashTemplateClass ThumbnailHash; + unsigned char* ThumbnailMemory; + bool Changed; + unsigned long DateTime; + + ThumbnailManagerClass(const char* thumbnail_filename); + ~ThumbnailManagerClass(); + + void Remove_From_Hash(ThumbnailClass* thumb); + void Insert_To_Hash(ThumbnailClass* thumb); + ThumbnailClass* Get_From_Hash(const StringClass& name); + +public: + ThumbnailClass* Peek_Thumbnail_Instance(const StringClass& name); + + static void Add_Thumbnail_Manager(const char* thumbnail_filename); + static void Remove_Thumbnail_Manager(const char* thumbnail_filename); + static ThumbnailManagerClass* Peek_Thumbnail_Manager(const char* thumbnail_filename); + + static ThumbnailClass* Peek_Thumbnail_Instance_From_Any_Manager(const StringClass& name); + + static bool Is_Thumbnail_Created_If_Not_Found() { return CreateThumbnailIfNotFound; } + static void Create_Thumbnail_If_Not_Found(bool create) { CreateThumbnailIfNotFound = create; } + + bool Is_Per_Texture_Time_Stamp_Used() const { return PerTextureTimeStampUsed; } + void Enable_Per_Texture_Time_Stamp(bool enable) { PerTextureTimeStampUsed = enable; } + + static void Init(); + static void Deinit(); +}; + +// ---------------------------------------------------------------------------- + + #endif diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/ww3d.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/ww3d.cpp index b01f96be44..f030af2a0a 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/ww3d.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/ww3d.cpp @@ -778,7 +778,7 @@ void WW3D::Set_Texture_Filter(int texture_filter) if (texture_filter<0) texture_filter=0; if (texture_filter>TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC) texture_filter=TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC; TextureFilter=texture_filter; - TextureFilterClass::_Init_Filters(); + TextureFilterClass::_Init_Filters((TextureFilterClass::TextureFilterMode)TextureFilter); } diff --git a/Generals/Code/Tools/WorldBuilder/src/ObjectPreview.cpp b/Generals/Code/Tools/WorldBuilder/src/ObjectPreview.cpp index e0b138657e..12117f460f 100644 --- a/Generals/Code/Tools/WorldBuilder/src/ObjectPreview.cpp +++ b/Generals/Code/Tools/WorldBuilder/src/ObjectPreview.cpp @@ -218,7 +218,7 @@ static UnsignedByte * generatePreview( const ThingTemplate *tt ) } // Set the render target - DX8Wrapper::Set_Render_Target(objectTexture); + DX8Wrapper::Set_Render_Target_With_Z(objectTexture); // create the camera Bool orthoCamera = false; diff --git a/Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp b/Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp index 8c853cea4b..3729546dbe 100644 --- a/Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp +++ b/Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp @@ -629,7 +629,6 @@ int CWorldBuilderApp::ExitInstance() delete TheFileSystem; TheFileSystem = NULL; - TextureLoadTaskClass::shutdown(); delete TheW3DFileSystem; TheW3DFileSystem = NULL; diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt index b1a9848837..7d54e30ca3 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt @@ -62,8 +62,8 @@ set(WW3D2_SRC dx8vertexbuffer.h #dx8webbrowser.cpp #dx8webbrowser.h - dx8wrapper.cpp - dx8wrapper.h + #dx8wrapper.cpp + #dx8wrapper.h #dynamesh.cpp #dynamesh.h #font3d.cpp