diff --git a/Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt b/Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt index d8a1a275779..cb9067a383a 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt +++ b/Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt @@ -178,7 +178,7 @@ set(WW3D2_SRC #shader.h shattersystem.cpp shattersystem.h - #shdlib.h + shdlib.h snappts.cpp snapPts.h #sortingrenderer.cpp diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/shdlib.h b/Core/Libraries/Source/WWVegas/WW3D2/shdlib.h similarity index 100% rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/shdlib.h rename to Core/Libraries/Source/WWVegas/WW3D2/shdlib.h diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp index d25a2920651..5154f4d4951 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp @@ -47,13 +47,8 @@ static StringClass CapsWorkString; - -enum { - VENDOR_ID_NVIDIA=0x10de, - VENROD_ID_ATI=0x1002, - VENDOR_ID_VMWARE=0x15AD, -}; - +#define DXLOG(n) CapsWorkString.Format n ; CapsLog+=CapsWorkString; +#define COMPACTLOG(n) CapsWorkString.Format n ; CompactLog+=CapsWorkString; static const char* const VendorNames[]={ "Unknown", @@ -485,6 +480,26 @@ 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() @@ -501,13 +516,13 @@ void DX8Caps::Shutdown() void DX8Caps::Init_Caps(IDirect3DDevice8* D3DDevice) { D3DDevice->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING,TRUE); - DX8CALL(GetDeviceCaps(&swVPCaps)); + DX8CALL(GetDeviceCaps(&Caps)); - if ((swVPCaps.DevCaps&D3DDEVCAPS_HWTRANSFORMANDLIGHT)==D3DDEVCAPS_HWTRANSFORMANDLIGHT) { + if ((Caps.DevCaps&D3DDEVCAPS_HWTRANSFORMANDLIGHT)==D3DDEVCAPS_HWTRANSFORMANDLIGHT) { SupportTnL=true; D3DDevice->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING,FALSE); - DX8CALL(GetDeviceCaps(&hwVPCaps)); + DX8CALL(GetDeviceCaps(&Caps)); } else { SupportTnL=false; } @@ -522,33 +537,133 @@ void DX8Caps::Compute_Caps(WW3DFormat display_format, const D3DADAPTER_IDENTIFIE { // Init_Caps(D3DDevice); - const D3DCAPS8& caps=Get_DX8_Caps(); + CanDoMultiPass=true; + IsFogAllowed=true; - if ((caps.DevCaps&D3DDEVCAPS_NPATCHES)==D3DDEVCAPS_NPATCHES) { - SupportNPatches=true; - } else { - SupportNPatches=false; - } + CapsLog=""; + CompactLog=""; + DXLOG(("Video Card: %s\r\n",adapter_id.Description)); + DXLOG(("Driver: %s\r\n",adapter_id.Driver)); - if ((caps.TextureOpCaps&D3DTEXOPCAPS_DOTPRODUCT3)==D3DTEXOPCAPS_DOTPRODUCT3) - { - SupportDot3=true; - } else { - SupportDot3=false; - } + DriverDLL=adapter_id.Driver; + int Product = HIWORD(adapter_id.DriverVersion.HighPart); + int Version = LOWORD(adapter_id.DriverVersion.HighPart); + int SubVersion = HIWORD(adapter_id.DriverVersion.LowPart); + DriverBuildVersion = LOWORD(adapter_id.DriverVersion.LowPart); - supportGamma=((swVPCaps.Caps2&D3DCAPS2_FULLSCREENGAMMA)==D3DCAPS2_FULLSCREENGAMMA); - SupportPointSprites = (caps.MaxPointSize > 1.0f); + DXLOG(("Product=%d, Version=%d, SubVersion=%d, Build=%d\r\n",Product, Version, SubVersion, DriverBuildVersion)); - MaxTexturesPerPass=MAX_TEXTURE_STAGES; + VendorId=Define_Vendor(adapter_id.VendorId); + // Make a guess - if driver doesn't intruduce itself and the name starts with 3, what could it possibly be? + if (VendorId==VENDOR_UNKNOWN) { + if (DriverDLL[0]=='3') VendorId=VENDOR_3DFX; + } + COMPACTLOG(("%s\t",VendorNames[VendorId])); + DXLOG(("Video Card Chip Vendor: %s\r\n",VendorNames[VendorId])); + DXLOG(("Type of chip: ")); + switch (VendorId) { + default: + case VENDOR_UNKNOWN: + DeviceId=0; + DXLOG(("Unknown")); + COMPACTLOG(("Unknown")); + break; + case VENDOR_NVIDIA: + DeviceId=(unsigned)Get_NVidia_Device(adapter_id.DeviceId); + DXLOG((DeviceNamesNVidia[DeviceId])); + COMPACTLOG((DeviceNamesNVidia[DeviceId])); + break; + case VENDOR_ATI: + DeviceId=(unsigned)Get_ATI_Device(adapter_id.DeviceId); + DXLOG((DeviceNamesATI[DeviceId])); + COMPACTLOG((DeviceNamesATI[DeviceId])); + break; + case VENDOR_INTEL: + DeviceId=(unsigned)Get_Intel_Device(adapter_id.DeviceId); + DXLOG((DeviceNamesIntel[DeviceId])); + COMPACTLOG((DeviceNamesIntel[DeviceId])); + break; + case VENDOR_S3: + DeviceId=(unsigned)Get_S3_Device(adapter_id.DeviceId); + DXLOG((DeviceNamesS3[DeviceId])); + COMPACTLOG((DeviceNamesS3[DeviceId])); + break; + case VENDOR_POWERVR: + DeviceId=(unsigned)Get_PowerVR_Device(adapter_id.DeviceId); + DXLOG((DeviceNamesPowerVR[DeviceId])); + COMPACTLOG((DeviceNamesPowerVR[DeviceId])); + break; + case VENDOR_MATROX: + DeviceId=(unsigned)Get_Matrox_Device(adapter_id.DeviceId); + DXLOG((DeviceNamesMatrox[DeviceId])); + COMPACTLOG((DeviceNamesMatrox[DeviceId])); + break; + case VENDOR_3DFX: + DeviceId=(unsigned)Get_3Dfx_Device(adapter_id.DeviceId); + DXLOG((DeviceNames3Dfx[DeviceId])); + COMPACTLOG((DeviceNames3Dfx[DeviceId])); + break; + case VENDOR_3DLABS: + DeviceId=(unsigned)Get_3DLabs_Device(adapter_id.DeviceId); + DXLOG((DeviceNames3DLabs[DeviceId])); + COMPACTLOG((DeviceNames3DLabs[DeviceId])); + break; + } + + COMPACTLOG(("\t%d\t",DriverBuildVersion)); + + DXLOG(("\r\n")); + + DXLOG(("Vendor id: 0x%x\r\n",adapter_id.VendorId)); + DXLOG(("Device id: 0x%x\r\n",adapter_id.DeviceId)); + DXLOG(("SubSys id: 0x%x\r\n",adapter_id.SubSysId)); + DXLOG(("Revision: %d\r\n",adapter_id.Revision)); + + DXLOG(("GUID = {0x%x, 0x%x, 0x%x}, {0x%2.2x, 0x%2.2x, 0x%2.2x, 0x%2.2x, 0x%2.2x, 0x%2.2x, 0x%2.2x, 0x%2.2x}\r\n", + adapter_id.DeviceIdentifier.Data1, + adapter_id.DeviceIdentifier.Data2, + adapter_id.DeviceIdentifier.Data3, + adapter_id.DeviceIdentifier.Data4[0], + adapter_id.DeviceIdentifier.Data4[1], + adapter_id.DeviceIdentifier.Data4[2], + adapter_id.DeviceIdentifier.Data4[3], + adapter_id.DeviceIdentifier.Data4[4], + adapter_id.DeviceIdentifier.Data4[5], + adapter_id.DeviceIdentifier.Data4[6], + adapter_id.DeviceIdentifier.Data4[7])); + + + SupportPointSprites = (Caps.MaxPointSize > 1.0f); + SupportNPatches = ((Caps.DevCaps&D3DDEVCAPS_NPATCHES)==D3DDEVCAPS_NPATCHES); + SupportZBias = ((Caps.RasterCaps&D3DPRASTERCAPS_ZBIAS)==D3DPRASTERCAPS_ZBIAS); + supportGamma=((Caps.Caps2&D3DCAPS2_FULLSCREENGAMMA)==D3DCAPS2_FULLSCREENGAMMA); + SupportModAlphaAddClr = (Caps.TextureOpCaps & D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR) == D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR; + SupportDot3=(Caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3) == D3DTEXOPCAPS_DOTPRODUCT3; + SupportCubemaps=(Caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) == D3DPTEXTURECAPS_CUBEMAP; + SupportAnisotropicFiltering= + (Caps.TextureFilterCaps&D3DPTFILTERCAPS_MAGFANISOTROPIC) && (Caps.TextureFilterCaps&D3DPTFILTERCAPS_MINFANISOTROPIC); + + DXLOG(("Hardware T&L support: %s\r\n",SupportTnL ? "Yes" : "No")); + DXLOG(("NPatch support: %s\r\n",SupportNPatches ? "Yes" : "No")); + DXLOG(("ZBias support: %s\r\n",SupportZBias ? "Yes" : "No")); + DXLOG(("Gamma support: %s\r\n",supportGamma ? "Yes" : "No")); + DXLOG(("ModAlphaAddClr support: %s\r\n",SupportModAlphaAddClr ? "Yes" : "No")); + DXLOG(("Dot3 support: %s\r\n",SupportDot3 ? "Yes" : "No")); + DXLOG(("Anisotropic filtering support: %s\r\n",SupportAnisotropicFiltering ? "Yes" : "No")); + + Check_Texture_Format_Support(display_format,Caps); + Check_Render_To_Texture_Support(display_format,Caps); + Check_Depth_Stencil_Support(display_format,Caps); + Check_Texture_Compression_Support(Caps); + Check_Bumpmap_Support(Caps); + Check_Shader_Support(Caps); + Check_Driver_Version_Status(); + Check_Maximum_Texture_Support(Caps); + + MaxTexturesPerPass=Caps.MaxSimultaneousTextures; + + DXLOG(("Max textures per pass: %d\r\n",MaxTexturesPerPass)); - Check_Texture_Format_Support(display_format,caps); - Check_Render_To_Texture_Support(display_format,caps); - Check_Depth_Stencil_Support(display_format,caps); - Check_Texture_Compression_Support(caps); - Check_Bumpmap_Support(caps); - Check_Shader_Support(caps); - Check_Maximum_Texture_Support(caps); Vendor_Specific_Hacks(adapter_id); CapsWorkString=""; } @@ -563,6 +678,8 @@ void DX8Caps::Check_Bumpmap_Support(const D3DCAPS8& caps) { SupportBumpEnvmap=!!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP); SupportBumpEnvmapLuminance=!!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE); + DXLOG(("Bumpmap support: %s\r\n",SupportBumpEnvmap ? "Yes" : "No")); + DXLOG(("Bumpmap luminance support: %s\r\n",SupportBumpEnvmapLuminance ? "Yes" : "No")); } // ---------------------------------------------------------------------------- @@ -578,6 +695,7 @@ void DX8Caps::Check_Texture_Compression_Support(const D3DCAPS8& caps) SupportTextureFormat[WW3D_FORMAT_DXT3]| SupportTextureFormat[WW3D_FORMAT_DXT4]| SupportTextureFormat[WW3D_FORMAT_DXT5]; + DXLOG(("Texture compression support: %s\r\n",SupportDXTC ? "Yes" : "No")); } void DX8Caps::Check_Texture_Format_Support(WW3DFormat display_format,const D3DCAPS8& caps) @@ -603,6 +721,11 @@ void DX8Caps::Check_Texture_Format_Support(WW3DFormat display_format,const D3DCA 0, D3DRTYPE_TEXTURE, WW3DFormat_To_D3DFormat(format))); + if (SupportTextureFormat[i]) { + StringClass name(0,true); + Get_WW3D_Format_Name(format,name); + DXLOG(("Supports texture format: %s\r\n",name.str())); + } } } } @@ -630,6 +753,11 @@ void DX8Caps::Check_Render_To_Texture_Support(WW3DFormat display_format,const D3 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, WW3DFormat_To_D3DFormat(format))); + if (SupportRenderToTextureFormat[i]) { + StringClass name(0,true); + Get_WW3D_Format_Name(format,name); + DXLOG(("Supports render-to-texture format: %s\r\n",name.str())); + } } } } @@ -672,6 +800,13 @@ void DX8Caps::Check_Depth_Stencil_Support(WW3DFormat display_format, const D3DCA WW3DZFormat_To_D3DFormat(format) ) ); + + if (SupportDepthStencilFormat[i]) + { + StringClass name(0,true); + Get_WW3D_ZFormat_Name(format,name); + DXLOG(("Supports depth stencil format: %s\r\n",name.str())); + } } } } @@ -685,6 +820,183 @@ void DX8Caps::Check_Shader_Support(const D3DCAPS8& caps) { VertexShaderVersion=caps.VertexShaderVersion; PixelShaderVersion=caps.PixelShaderVersion; + DXLOG(("Vertex shader version: %d.%d, pixel shader version: %d.%d\r\n", + (VertexShaderVersion>>8)&0xff,VertexShaderVersion&0xff, + (PixelShaderVersion>>8)&0xff,PixelShaderVersion&0xff)); +} + +void DX8Caps::Check_Driver_Version_Status() +{ + DriverVersionStatus=DRIVER_STATUS_UNKNOWN; + + switch (VendorId) { + // All 3Dfx drivers are bad + case VENDOR_3DFX: + DriverVersionStatus=DRIVER_STATUS_BAD; + break; + case VENDOR_NVIDIA: + if (stricmp(DriverDLL,"nv4.dll") == 0) { + switch (DriverBuildVersion) { + case 327: // 5.00.2165.327 + DriverVersionStatus=DRIVER_STATUS_BAD; + } + } + + if (stricmp(DriverDLL,"nv4_disp.dll") == 0 || stricmp(DriverDLL,"nvdd32.dll") == 0) { + switch (DriverBuildVersion) { + // 23.11 Is known to be very unstable + case 2311: + DriverVersionStatus=DRIVER_STATUS_BAD; + break; + // 21.83 Has occasional lock-up at start or exit + // Darren Korman (DKORMAN2389-2K GeForce3) + case 2183: + case 2240: + DriverVersionStatus=DRIVER_STATUS_OK; + break; + // 21.81 Has occasional lock-up at start or exit + case 2181: + DriverVersionStatus=DRIVER_STATUS_OK; + break; + case 1440: // Denzil had problems in opening 16 bit modes, fixed by updating driver + DriverVersionStatus=DRIVER_STATUS_BAD; + break; + case 1410: + DriverVersionStatus=DRIVER_STATUS_BAD; + break; + case 1260: // Byon - BYONG + DriverVersionStatus=DRIVER_STATUS_BAD; + break; + case 1241: // Steve Tall gets occasional blue screening with this driver version (blue screen happens in the driver dll) + DriverVersionStatus=DRIVER_STATUS_BAD; + break; + case 1240: // Robert Powers + DriverVersionStatus=DRIVER_STATUS_BAD; + break; + case 1101: + DriverVersionStatus=DRIVER_STATUS_BAD;//DriverVersionStatus=DRIVER_STATUS_UNKNOWN; + break; + case 650: // Rich Donelly - RENEGADE-JENNA2 + DriverVersionStatus=DRIVER_STATUS_BAD;//DriverVersionStatus=DRIVER_STATUS_UNKNOWN; + break; + case 649: + DriverVersionStatus=DRIVER_STATUS_BAD;//DriverVersionStatus=DRIVER_STATUS_UNKNOWN; + break; + case 635: + DriverVersionStatus=DRIVER_STATUS_BAD; + break; + case 634: // Sean Decker - SDECKER2339-2K + DriverVersionStatus=DRIVER_STATUS_BAD;//DriverVersionStatus=DRIVER_STATUS_UNKNOWN; + break; + case 625: // TESTIBM240 + DriverVersionStatus=DRIVER_STATUS_BAD;//DriverVersionStatus=DRIVER_STATUS_UNKNOWN; + break; + case 618: + DriverVersionStatus=DRIVER_STATUS_BAD; + break; + default: + if (DriverBuildVersion<2000) { // All under 20.xx versions are too old! + DriverVersionStatus=DRIVER_STATUS_BAD; + } + else { + DriverVersionStatus=DRIVER_STATUS_UNKNOWN; + } + } + } + // Elsa OEM drivers? + if (stricmp(DriverDLL,"egdad.dll") == 0) { + // We know of version 5.9.0.312 (asked MShelling if he the drivers seem ok) + switch (DriverBuildVersion) { + default: + DriverVersionStatus=DRIVER_STATUS_UNKNOWN; + case 312: + DriverVersionStatus=DRIVER_STATUS_OK; + } + } + + // Elsa GLoria + if (stricmp(DriverDLL,"egliid.dll") == 0) { + switch (DriverBuildVersion) { + default: + DriverVersionStatus=DRIVER_STATUS_UNKNOWN; + case 172: + DriverVersionStatus=DRIVER_STATUS_OK; + } + + } + + // ASUS OEM drivers? + if (stricmp(DriverDLL,"v66_disp.dll") == 0) { + // TOMSS1: 5.0.2195.379 + } + break; + case VENDOR_ATI: + if (stricmp(DriverDLL,"ati2dvag.dll") == 0) { + switch (DriverBuildVersion) { + case 3287: + DriverVersionStatus=DRIVER_STATUS_UNKNOWN; + break; + case 3281: + DriverVersionStatus=DRIVER_STATUS_OK; // Not really ok, but we have to accept something... + break; + case 3063: + DriverVersionStatus=DRIVER_STATUS_BAD; + break; + case 3273: + DriverVersionStatus=DRIVER_STATUS_BAD; + break; + case 3276: + DriverVersionStatus=DRIVER_STATUS_BAD; + break; + } + } + if (stricmp(DriverDLL,"atid32ae.dll") == 0) { + switch (DriverBuildVersion) { + case 1010: + DriverVersionStatus=DRIVER_STATUS_OK; + } + } + if (stricmp(DriverDLL,"ati3drai.dll") == 0) { + switch (DriverBuildVersion) { + case 1119: + DriverVersionStatus=DRIVER_STATUS_UNKNOWN; + } + } + break; + case VENDOR_POWERVR: + if (stricmp(DriverDLL,"pmx2hal.dll") == 0) { + switch (DriverBuildVersion) { + case 3111: // Michael Ruppert - TESTIBM104 + default: DriverVersionStatus=DRIVER_STATUS_UNKNOWN; + } + } + break; + } + + switch (DriverVersionStatus) { + default: + case DRIVER_STATUS_UNKNOWN: + DXLOG(("Driver version status: Unknown\r\n")); + break; + case DRIVER_STATUS_OK: + DXLOG(("Driver version status: OK (No known problems)\r\n")); + break; + case DRIVER_STATUS_GOOD: + DXLOG(("Driver version status: Good\r\n")); + break; + case DRIVER_STATUS_BAD: + DXLOG(("Driver version status: Bad (Driver update recommended)\r\n")); + break; + } +} + +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; } // ---------------------------------------------------------------------------- @@ -696,7 +1008,15 @@ void DX8Caps::Check_Shader_Support(const D3DCAPS8& caps) void DX8Caps::Vendor_Specific_Hacks(const D3DADAPTER_IDENTIFIER8& adapter_id) { - if (adapter_id.VendorId==VENDOR_ID_NVIDIA) { + if (VendorId==VENDOR_NVIDIA) + { + if (SupportNPatches) { + DXLOG(("NVidia Driver reported N-Patch support, disabling.\r\n")); + } + if (SupportTextureFormat[WW3D_FORMAT_DXT1]) { + DXLOG(("Disabling DXT1 support on NVidia hardware.\r\n")); + } + SupportNPatches = false; // Driver incorrectly report N-Patch support SupportTextureFormat[WW3D_FORMAT_DXT1] = false; // DXT1 is broken on NVidia hardware SupportDXTC= @@ -705,15 +1025,147 @@ void DX8Caps::Vendor_Specific_Hacks(const D3DADAPTER_IDENTIFIER8& adapter_id) SupportTextureFormat[WW3D_FORMAT_DXT3]| SupportTextureFormat[WW3D_FORMAT_DXT4]| SupportTextureFormat[WW3D_FORMAT_DXT5]; + + + if (DeviceId == DEVICE_NVIDIA_GEFORCE2_MX || + DeviceId == DEVICE_NVIDIA_GEFORCE2_MX_400 ) + { + DXLOG(("Maximum screen resolution limited to 1024 x 768 on NVidia GeForce2 mx/mx400 cards\r\n")); + MaxDisplayWidth=1024; + MaxDisplayHeight=768; + } + + + + } + + if (VendorId==VENDOR_MATROX) { + // G400 and G550 claim support for ModAlphaAddClr but argument limitations make it unusable. + if (DeviceId==DEVICE_MATROX_G400 || + DeviceId==DEVICE_MATROX_G550) { + DXLOG(("ModAlphaAddClr disabled Matrox G400 and G550 cards (cannot put texture in 2nd arg)\r\n")); + SupportModAlphaAddClr = false; + } + } + + if (VendorId==VENDOR_ATI) { + // Rage Pro doesn't handle multitexturing well enough... + // It also doesn't really handle render-to-texture... + if (DeviceId==DEVICE_ATI_RAGE_PRO || DeviceId==DEVICE_ATI_RAGE_PRO_MOBILITY) { + DXLOG(("Disabling multitexturing on ATI Rage Pro\r\n")); + MaxTexturesPerPass=1; + CanDoMultiPass=false; + + DXLOG(("Disabling render-to-texture on Rage Pro\r\n")); + for (unsigned i=0;iRelease_Engine_Ref(); - REF_PTR_RELEASE(render_state.vertex_buffer); + for (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); @@ -467,6 +474,7 @@ void DX8Wrapper::Do_Onetime_Device_Dependent_Shutdowns() PointGroupClass::_Shutdown(); VertexMaterialClass::Shutdown(); BoxRenderObjClass::Shutdown(); + SHD_SHUTDOWN; TheDX8MeshRenderer.Shutdown(); MissingTexture::_Deinit(); @@ -515,11 +523,14 @@ bool DX8Wrapper::Create_Device() return false; } - Vertex_Processing_Behavior=D3DCREATE_SOFTWARE_VERTEXPROCESSING; - if (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 + /*if (caps.DevCaps&D3DDEVCAPS_PUREDEVICE) { - Vertex_Processing_Behavior=D3DCREATE_MIXED_VERTEXPROCESSING; - } + Vertex_Processing_Behavior|=D3DCREATE_PUREDEVICE; + }*/ #ifdef CREATE_DX8_MULTI_THREADED Vertex_Processing_Behavior|=D3DCREATE_MULTITHREADED; @@ -551,7 +562,36 @@ bool DX8Wrapper::Create_Device() if (FAILED(hr)) { - return false; + // 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)) + { + _PresentParameters.AutoDepthStencilFormat=D3DFMT_D16; + hr = D3DInterface->CreateDevice + ( + CurRenderDevice, + WW3D_DEVTYPE, + _Hwnd, + Vertex_Processing_Behavior, + &_PresentParameters, + &D3DDevice + ); + + if (FAILED(hr)) + { + return false; + } + } + else + { + return false; + } } dbgHelpGuard.deactivate(); @@ -570,8 +610,11 @@ bool DX8Wrapper::Reset_Device(bool reload_assets) if ((IsInitted) && (D3DDevice != nullptr)) { // Release all non-MANAGED stuff WW3D::_Invalidate_Textures(); - - Set_Vertex_Buffer (nullptr); + + for (unsigned i=0;iReleaseResources(); @@ -579,6 +622,10 @@ bool DX8Wrapper::Reset_Device(bool reload_assets) DynamicVBAccessClass::_Deinit(); DynamicIBAccessClass::_Deinit(); DX8TextureManagerClass::Release_Textures(); + SHD_SHUTDOWN_SHADERS; + + // 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); @@ -601,6 +648,7 @@ bool DX8Wrapper::Reset_Device(bool reload_assets) } Invalidate_Cached_Render_States(); Set_Default_Global_Render_States(); + SHD_INIT_SHADERS; WWDEBUG_SAY(("Device reset completed")); return true; } @@ -624,8 +672,11 @@ void DX8Wrapper::Release_Device() /* ** Release the current vertex and index buffers */ - if (render_state.vertex_buffer) render_state.vertex_buffer->Release_Engine_Ref(); - REF_PTR_RELEASE(render_state.vertex_buffer); + for (unsigned 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); @@ -656,13 +707,6 @@ void DX8Wrapper::Enumerate_Devices() 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) @@ -680,6 +724,11 @@ 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); + + DX8Caps dx8caps(D3DInterface,desc.Caps,WW3D_FORMAT_UNKNOWN,desc.AdapterIdentifier); + /* ** Enumerate the resolutions */ @@ -702,6 +751,11 @@ void DX8Wrapper::Enumerate_Devices() 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 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? @@ -712,27 +766,39 @@ void DX8Wrapper::Enumerate_Devices() } } - /* - ** Add the render device to our table - */ - _RenderDeviceDescriptionTable.Add(desc); + // IML: If the device has one or more valid resolutions add it to the device list. + // NOTE: Testing has shown that there are drivers with zero resolutions. + if (desc.Enumerate_Resolutions().Count() > 0) { + + /* + ** Set up the device name + */ + 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" + + /* + ** Add the render device to our table + */ + _RenderDeviceDescriptionTable.Add(desc); + } } } } bool DX8Wrapper::Set_Any_Render_Device() { - // Try windowed first + // Try fullscreen first int dev_number = 0; for (; 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,0,false)) { return true; } } - // Then fullscreen + // Then windowed for (dev_number = 0; 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,1,false)) { return true; } } @@ -916,7 +982,8 @@ bool DX8Wrapper::Set_Render_Device(int dev, int width, int height, int bits, int _PresentParameters.BackBufferHeight = ResolutionHeight; _PresentParameters.BackBufferCount = IsWindowed ? 1 : 2; - _PresentParameters.SwapEffect = IsWindowed ? D3DSWAPEFFECT_DISCARD : D3DSWAPEFFECT_FLIP; // Shouldn't this be D3DSWAPEFFECT_FLIP? + //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? _PresentParameters.hDeviceWindow = _Hwnd; _PresentParameters.Windowed = IsWindowed; @@ -1284,7 +1351,58 @@ bool DX8Wrapper::Registry_Load_Render_Device( const char * sub_key, bool resize_ } if ( Set_Render_Device( name, width,height,depth,windowed, resize_window ) != true) { - return Set_Any_Render_Device(); + 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; + // we'll test resolutions down, so if start is 640, increase to begin with... + if (width==640) { + width=1024; + height=768; + } + for(;;) { + if (width>2048) { + width=2048; + height=1536; + } + else if (width>1920) { + width=1920; + height=1440; + } + else if (width>1600) { + width=1600; + height=1200; + } + else if (width>1280) { + width=1280; + height=1024; + } + else if (width>1024) { + width=1024; + height=768; + } + else if (width>800) { + width=800; + height=600; + } + 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) { + return true; + } + if (depth==16) depth=32; + else depth=16; + } + } } return true; @@ -1655,13 +1773,40 @@ void DX8Wrapper::Flip_To_Primary() } +//********************************************************************************************** +//! 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) { 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 || + // KJM fixed this to get format from back buffer (incase render to texture is used) + /*bool has_stencil = ( _PresentParameters.AutoDepthStencilFormat == D3DFMT_D15S1 || _PresentParameters.AutoDepthStencilFormat == D3DFMT_D24S8 || - _PresentParameters.AutoDepthStencilFormat == D3DFMT_D24X4S4); + _PresentParameters.AutoDepthStencilFormat == D3DFMT_D24X4S4);*/ + bool has_stencil=false; + IDirect3DSurface8* depthbuffer; + + _Get_D3D_Device8()->GetDepthStencilSurface(&depthbuffer); + DX8_RECORD_DX8_CALLS(); + + if (depthbuffer) + { + D3DSURFACE_DESC desc; + depthbuffer->GetDesc(&desc); + has_stencil= + ( + desc.Format==D3DFMT_D15S1 || + desc.Format==D3DFMT_D24S8 || + desc.Format==D3DFMT_D24X4S4 + ); + + // release ref + depthbuffer->Release(); + } DWORD flags = 0; if (clear_color) flags |= D3DCLEAR_TARGET; @@ -1687,20 +1832,20 @@ void DX8Wrapper::Set_Viewport(CONST D3DVIEWPORT8* pViewport) // // ---------------------------------------------------------------------------- -void DX8Wrapper::Set_Vertex_Buffer(const VertexBufferClass* vb) +void DX8Wrapper::Set_Vertex_Buffer(const VertexBufferClass* vb, unsigned stream) { render_state.vba_offset=0; render_state.vba_count=0; - if (render_state.vertex_buffer) { - render_state.vertex_buffer->Release_Engine_Ref(); + if (render_state.vertex_buffers[stream]) { + render_state.vertex_buffers[stream]->Release_Engine_Ref(); } - REF_PTR_SET(render_state.vertex_buffer,const_cast(vb)); + REF_PTR_SET(render_state.vertex_buffers[stream],const_cast(vb)); if (vb) { vb->Add_Engine_Ref(); - render_state.vertex_buffer_type=vb->Type(); + render_state.vertex_buffer_types[stream]=vb->Type(); } else { - render_state.index_buffer_type=BUFFER_TYPE_INVALID; + render_state.vertex_buffer_types[stream]=BUFFER_TYPE_INVALID; } render_state_changed|=VERTEX_BUFFER_CHANGED; } @@ -1739,14 +1884,18 @@ void DX8Wrapper::Set_Index_Buffer(const IndexBufferClass* ib,unsigned short inde void DX8Wrapper::Set_Vertex_Buffer(const DynamicVBAccessClass& vba_) { - if (render_state.vertex_buffer) render_state.vertex_buffer->Release_Engine_Ref(); + // 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_type=vba.Get_Type(); + 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_buffer,vba.VertexBuffer); - render_state.vertex_buffer->Add_Engine_Ref(); + 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. } @@ -1784,14 +1933,14 @@ void DX8Wrapper::Draw_Sorting_IB_VB( 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.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::WriteLockClass lock(&dyn_vb_access); - VertexFormatXYZNDUV2* src = static_cast(render_state.vertex_buffer)->VertexBuffer; + VertexFormatXYZNDUV2* src = static_cast(render_state.vertex_buffers[0])->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); @@ -1807,7 +1956,11 @@ void DX8Wrapper::Draw_Sorting_IB_VB( 0, static_cast(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())); + // 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) { + DX8CALL(SetVertexShader(fvf)); + } DX8_RECORD_VERTEX_BUFFER_CHANGE(); unsigned index_count=0; @@ -1929,10 +2082,10 @@ void DX8Wrapper::Draw( if (vertex_count<3) { min_vertex_index=0; - switch (render_state.vertex_buffer_type) { + switch (render_state.vertex_buffer_types[0]) { 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; + 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: @@ -1941,7 +2094,7 @@ void DX8Wrapper::Draw( } } - switch (render_state.vertex_buffer_type) { + switch (render_state.vertex_buffer_types[0]) { case BUFFER_TYPE_DX8: case BUFFER_TYPE_DYNAMIC_DX8: switch (render_state.index_buffer_type) { @@ -2067,7 +2220,7 @@ void DX8Wrapper::Apply_Render_State_Changes() { if (render_state_changed&mask) { - SNAPSHOT_SAY(("DX8 - apply texture %d",i)); + 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]) { @@ -2135,26 +2288,34 @@ void DX8Wrapper::Apply_Render_State_Changes() } 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())); + for (i=0;iType()) { + case BUFFER_TYPE_DX8: + case BUFFER_TYPE_DYNAMIC_DX8: + DX8CALL(SetStreamSource( + i, + static_cast(render_state.vertex_buffers[i])->Get_DX8_Vertex_Buffer(), + render_state.vertex_buffers[i]->FVF_Info().Get_FVF_Size())); + 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) { + Set_Vertex_Shader(fvf); + } + } + break; + case BUFFER_TYPE_SORTING: + case BUFFER_TYPE_DYNAMIC_SORTING: + break; + default: + WWASSERT(0); + } + } else { + DX8CALL(SetStreamSource(i,nullptr,0)); 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,nullptr,0)); - DX8_RECORD_VERTEX_BUFFER_CHANGE(); } } if (render_state_changed&INDEX_BUFFER_CHANGED) { @@ -2226,9 +2387,35 @@ IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture return nullptr; } + // If ran out of texture ram, try invalidating some textures and mesh cache. if (ret==D3DERR_OUTOFVIDEOMEMORY) { - Non_Fatal_Log_DX8_ErrorCode(ret,__FILE__,__LINE__); - return nullptr; + 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); + + // Invalidate the mesh cache + WW3D::_Invalidate_Mesh_Cache(); + + ret=D3DXCreateTexture( + DX8Wrapper::_Get_D3D_Device8(), + width, + height, + mip_level_count, + D3DUSAGE_RENDERTARGET, + WW3DFormat_To_D3DFormat(format), + pool, + &texture); + + if (SUCCEEDED(ret)) { + WWDEBUG_SAY(("...Render target creation successful.")); + } + else { + WWDEBUG_SAY(("...Render target creation failed.")); + } + if (ret==D3DERR_OUTOFVIDEOMEMORY) { + Non_Fatal_Log_DX8_ErrorCode(ret,__FILE__,__LINE__); + return nullptr; + } } DX8_ErrorCode(ret); @@ -2237,9 +2424,10 @@ IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture return texture; } - // Don't allow any errors in non-render target - // texture creation. - DX8_ErrorCode(D3DXCreateTexture( + // 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( DX8Wrapper::_Get_D3D_Device8(), width, height, @@ -2247,12 +2435,37 @@ IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture 0, WW3DFormat_To_D3DFormat(format), pool, - &texture)); + &texture); -// unsigned reduction=WW3D::Get_Texture_Reduction(); -// unsigned level_count=texture->GetLevelCount(); -// if (reduction>=level_count) reduction=level_count-1; -// texture->SetLOD(reduction); + // If ran out of texture ram, try invalidating some textures and mesh cache. + 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); + + // Invalidate the mesh cache + WW3D::_Invalidate_Mesh_Cache(); + + ret=D3DXCreateTexture( + DX8Wrapper::_Get_D3D_Device8(), + width, + height, + mip_level_count, + 0, + WW3DFormat_To_D3DFormat(format), + pool, + &texture); + if (SUCCEEDED(ret)) { + WWDEBUG_SAY(("...Texture creation successful.")); + } + else { + 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)); + } + + } + DX8_ErrorCode(ret); return texture; } @@ -2818,13 +3031,16 @@ void DX8Wrapper::Set_Light(unsigned index,const LightClass &light) Set_Light(index,&dlight); } -// ---------------------------------------------------------------------------- -// -// Set the light environment. This is a lighting model which used up to four -// directional lights to produce the lighting. -// +//********************************************************************************************** +//! Set the light environment. This is a lighting model which used up to four +//! directional lights to produce the lighting. +/*! 5/27/02 KJM Added shader light environment support +*/ void DX8Wrapper::Set_Light_Environment(LightEnvironmentClass* light_env) { + // Shader light environment support * + Light_Environment=light_env; + if (light_env) { int light_count = light_env->Get_Light_Count(); @@ -2848,6 +3064,12 @@ void DX8Wrapper::Set_Light_Environment(LightEnvironmentClass* light_env) (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) { + 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); @@ -2859,7 +3081,14 @@ void DX8Wrapper::Set_Light_Environment(LightEnvironmentClass* light_env) 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. +#if 0 light.Attenuation0=0.01f; +#else + light.Attenuation0=1.0f; +#endif if (fabs(a-b)<1e-5) // if the attenuation range is too small assume uniform with cutoff light.Attenuation1=0.0f; diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h index dbdbd5b9c88..6869609ee00 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h @@ -22,16 +22,19 @@ * * * Project Name : ww3d * * * - * $Archive:: /VSS_Sync/ww3d2/dx8wrapper.h $* + * $Archive:: /Commando/Code/ww3d2/dx8wrapper.h $* * * * Original Author:: Jani Penttinen * * * - * $Author:: Vss_sync $* + * Author : Kenny Mitchell * * * - * $Modtime:: 8/29/01 7:29p $* + * $Modtime:: 08/05/02 2:40p $* * * - * $Revision:: 76 $* + * $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 *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -199,12 +202,12 @@ struct RenderStateStruct bool LightEnable[4]; D3DMATRIX world; D3DMATRIX view; - unsigned vertex_buffer_type; + unsigned vertex_buffer_types[MAX_VERTEX_STREAMS]; unsigned index_buffer_type; unsigned short vba_offset; unsigned short vba_count; unsigned short iba_offset; - VertexBufferClass* vertex_buffer; + VertexBufferClass* vertex_buffers[MAX_VERTEX_STREAMS]; IndexBufferClass* index_buffer; unsigned short index_base_offset; @@ -297,7 +300,7 @@ class DX8Wrapper static void Set_Viewport(CONST D3DVIEWPORT8* pViewport); - static void Set_Vertex_Buffer(const VertexBufferClass* vb); + 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); @@ -313,6 +316,8 @@ class DX8Wrapper // Set_ and Get_Transform() functions take the matrix in Westwood convention format. + 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 Get_Transform(D3DTRANSFORMSTATETYPE transform, Matrix4x4& m); @@ -705,7 +710,7 @@ class DX8Wrapper // 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... +#if 0 //(gth) some code is bypassing this accessor 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 @@ -983,7 +988,7 @@ WWINLINE unsigned int DX8Wrapper::Convert_Color(const Vector3& color,float alpha 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. + // such that 32 bit integer has AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB. __asm { sub esp,20 // space for a, r, g and b float plus fpu rounding mode @@ -1160,9 +1165,18 @@ WWINLINE void DX8Wrapper::Set_Texture(unsigned stage,TextureBaseClass* texture) WWINLINE void DX8Wrapper::Set_Material(const VertexMaterialClass* material) { - if (material==render_state.material) return; +/* 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) @@ -1178,6 +1192,24 @@ WWINLINE void DX8Wrapper::Set_Shader(const ShaderClass& shader) 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=To_D3DMATRIX(matrix); + + if (!Get_Current_Caps()->Support_ZBias() && ZNear!=ZFar) { + D3DMATRIX tmp=ProjectionMatrix; + float tmp_zbias=ZBias; + tmp_zbias*=(1.0f/16.0f); + tmp_zbias*=1.0f / (ZFar - ZNear); + tmp.m[2][2]-=tmp_zbias*tmp.m[3][2]; + DX8CALL(SetTransform(D3DTS_PROJECTION,&tmp)); + } + else { + DX8CALL(SetTransform(D3DTS_PROJECTION,&ProjectionMatrix)); + } +} WWINLINE void DX8Wrapper::Set_Transform(D3DTRANSFORMSTATETYPE transform,const Matrix4x4& m) { @@ -1260,12 +1292,18 @@ WWINLINE void DX8Wrapper::Get_Transform(D3DTRANSFORMSTATETYPE transform, Matrix4 WWINLINE void DX8Wrapper::Set_Render_State(const RenderStateStruct& state) { + int i; + if (render_state.index_buffer) { render_state.index_buffer->Release_Engine_Ref(); } - if (render_state.vertex_buffer) { - render_state.vertex_buffer->Release_Engine_Ref(); + for (i=0;iRelease_Engine_Ref(); + } } render_state=state; @@ -1275,52 +1313,82 @@ WWINLINE void DX8Wrapper::Set_Render_State(const RenderStateStruct& state) render_state.index_buffer->Add_Engine_Ref(); } - if (render_state.vertex_buffer) { - render_state.vertex_buffer->Add_Engine_Ref(); + for (i=0;iAdd_Engine_Ref(); + } } } WWINLINE void DX8Wrapper::Release_Render_State() { + int i; + if (render_state.index_buffer) { render_state.index_buffer->Release_Engine_Ref(); } - if (render_state.vertex_buffer) { - render_state.vertex_buffer->Release_Engine_Ref(); + for (i=0;iRelease_Engine_Ref(); + } } - REF_PTR_RELEASE(render_state.vertex_buffer); + for (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/ww3d2/sortingrenderer.cpp $* + * * + * Original Author:: Greg Hjelstrom * + * * + * Author : Kenny Mitchell * + * * + * $Modtime:: 06/27/02 1:27p $* + * * + * $Revision:: 2 $* + * * + * 06/26/02 KM Matrix name change to avoid MAX conflicts * + * 06/27/02 KM Changes to max texture stage caps * + *---------------------------------------------------------------------------------------------* + * Functions: * + * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + #include "sortingrenderer.h" #include "dx8vertexbuffer.h" #include "dx8indexbuffer.h" @@ -25,10 +47,13 @@ #include "d3d8.h" #include "d3dx8math.h" #include "statistics.h" +#include +#include + bool SortingRendererClass::_EnableTriangleDraw=true; -unsigned DEFAULT_SORTING_POLY_COUNT = 16384; // (count * 3) must be less than 65536 -unsigned DEFAULT_SORTING_VERTEX_COUNT = 32768; // count must be less than 65536 +static unsigned DEFAULT_SORTING_POLY_COUNT = 16384; // (count * 3) must be less than 65536 +static unsigned DEFAULT_SORTING_VERTEX_COUNT = 32768; // count must be less than 65536 void SortingRendererClass::SetMinVertexBufferSize( unsigned val ) { @@ -329,6 +354,9 @@ void SortingRendererClass::Insert_Triangles( return; } + SNAPSHOT_SAY(("SortingRenderer::Insert(start_i: %d, polygons : %d, min_vi: %d, vertex_count: %d)", + start_index,polygon_count,min_vertex_index,vertex_count)); + DX8_RECORD_SORTING_RENDER(polygon_count,vertex_count); @@ -338,7 +366,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 +375,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()); @@ -393,7 +421,7 @@ void SortingRendererClass::Insert_Triangles( WWASSERT(idx2vertex_count); WWASSERT(idx3vertex_count); } -#endif +#endif // WWDEBUG } // ---------------------------------------------------------------------------- @@ -421,7 +449,9 @@ void SortingRendererClass::Insert_Triangles( void Release_Refs(SortingNodeStruct* state) { int i; - REF_PTR_RELEASE(state->sorting_state.vertex_buffer); + for (i=0;isorting_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) @@ -460,17 +490,8 @@ static void Apply_Render_State(RenderStateStruct& render_state) { DX8Wrapper::Set_Shader(render_state.shader); -/* if (render_state.material) render_state.material->Apply(); -*/ DX8Wrapper::Set_Material(render_state.material); -/* if (render_state.Textures[2]) render_state.Textures[2]->Apply(); - if (render_state.Textures[3]) render_state.Textures[3]->Apply(); - if (render_state.Textures[4]) render_state.Textures[4]->Apply(); - if (render_state.Textures[5]) render_state.Textures[5]->Apply(); - if (render_state.Textures[6]) render_state.Textures[6]->Apply(); - if (render_state.Textures[7]) render_state.Textures[7]->Apply(); -*/ for (int i=0;iGet_Max_Textures_Per_Pass();++i) { DX8Wrapper::Set_Texture(i,render_state.Textures[i]); @@ -520,7 +541,6 @@ void SortingRendererClass::Flush_Sorting_Pool() SNAPSHOT_SAY(("SortingSystem - Flush")); - unsigned node_id; // Fill dynamic index buffer with sorting index buffer vertices unsigned * node_id_array=Get_Node_Id_Array(overlapping_polygon_count); float* polygon_z_array=Get_Polygon_Z_Array(overlapping_polygon_count); @@ -539,12 +559,12 @@ void SortingRendererClass::Flush_Sorting_Pool() unsigned polygon_array_offset=0; unsigned vertex_array_offset=0; - for (node_id=0;node_idvertex_count); VertexFormatXYZNDUV2* src_verts=nullptr; - 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); @@ -633,7 +653,7 @@ void SortingRendererClass::Flush_Sorting_Pool() DynamicIBAccessClass::WriteLockClass lock(&dyn_ib_access); ShortVectorIStruct* sorted_polygon_index_array=(ShortVectorIStruct*)lock.Get_Index_Array(); - for (a=0;aRemove(); 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)) { + (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 { @@ -803,7 +824,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 +832,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()); @@ -845,23 +866,4 @@ void SortingRendererClass::Insert_VolumeParticle( node=node->Succ(); } if (!node) sorted_list.Add_Tail(state); - -//#ifdef WWDEBUG -// unsigned short* indices=nullptr; -// SortingIndexBufferClass* index_buffer=static_cast(state->sorting_state.index_buffer); -// WWASSERT(index_buffer); -// indices=index_buffer->index_buffer; -// WWASSERT(indices); -// indices+=state->start_index; -// indices+=state->sorting_state.iba_offset; -// -// for (int i=0;ipolygon_count;++i) { -// unsigned short idx1=indices[i*3]-state->min_vertex_index; -// unsigned short idx2=indices[i*3+1]-state->min_vertex_index; -// unsigned short idx3=indices[i*3+2]-state->min_vertex_index; -// WWASSERT(idx1vertex_count); -// WWASSERT(idx2vertex_count); -// WWASSERT(idx3vertex_count); -// } -//#endif } diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt index 59617b6b451..2e3548b7f12 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt @@ -178,7 +178,7 @@ set(WW3D2_SRC shader.h #shattersystem.cpp #shattersystem.h - shdlib.h +# shdlib.h #snappts.cpp #snapPts.h sortingrenderer.cpp diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp index 2661e719f9c..7a921f68d65 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp @@ -1009,7 +1009,7 @@ bool DX8Caps::Is_Valid_Display_Format(int width, int height, WW3DFormat format) void DX8Caps::Vendor_Specific_Hacks(const D3DADAPTER_IDENTIFIER8& adapter_id) { if (VendorId==VENDOR_NVIDIA) - { + { if (SupportNPatches) { DXLOG(("NVidia Driver reported N-Patch support, disabling.\r\n")); } diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp index 956540ddae3..5f4bb7ef362 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp @@ -788,7 +788,7 @@ void DX8Wrapper::Enumerate_Devices() bool DX8Wrapper::Set_Any_Render_Device() { - // Then fullscreen + // Try fullscreen first int dev_number = 0; for (; dev_number < _RenderDeviceNameTable.Count(); dev_number++) { if (Set_Render_Device(dev_number,-1,-1,-1,0,false)) { @@ -796,7 +796,7 @@ bool DX8Wrapper::Set_Any_Render_Device() } } - // Try windowed first + // Then windowed for (dev_number = 0; dev_number < _RenderDeviceNameTable.Count(); dev_number++) { if (Set_Render_Device(dev_number,-1,-1,-1,1,false)) { return true; @@ -1350,10 +1350,6 @@ bool DX8Wrapper::Registry_Load_Render_Device( const char * sub_key, bool resize_ TextureBitDepth=16; } - -// _RenderDeviceDescriptionTable. - - if ( Set_Render_Device( name, width,height,depth,windowed, resize_window ) != true) { if (depth==16) depth=32; else depth=16; @@ -2276,7 +2272,7 @@ void DX8Wrapper::Apply_Render_State_Changes() } else { Set_DX8_Light(index,nullptr); - SNAPSHOT_SAY((" clearing light to NULL")); + SNAPSHOT_SAY((" clearing light to null")); } } } @@ -3043,8 +3039,6 @@ void DX8Wrapper::Set_Light(unsigned index,const LightClass &light) void DX8Wrapper::Set_Light_Environment(LightEnvironmentClass* light_env) { // Shader light environment support * -// if (Light_Environment && light_env && (*Light_Environment)==(*light_env)) return; - Light_Environment=light_env; if (light_env) @@ -3841,7 +3835,7 @@ void DX8Wrapper::Apply_Default_State() VertexMaterialClass::Apply_Null(); for (unsigned index=0;index<4;++index) { - SNAPSHOT_SAY(("Clearing light %d to NULL",index)); + SNAPSHOT_SAY(("Clearing light %d to null",index)); Set_DX8_Light(index,nullptr); } diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h index 937aa6ea6a1..d77e152d227 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h @@ -200,7 +200,6 @@ struct RenderStateStruct TextureBaseClass * Textures[MAX_TEXTURE_STAGES]; D3DLIGHT8 Lights[4]; bool LightEnable[4]; - //unsigned lightsHash; D3DMATRIX world; D3DMATRIX view; unsigned vertex_buffer_types[MAX_VERTEX_STREAMS]; @@ -1359,7 +1358,6 @@ WWINLINE RenderStateStruct::RenderStateStruct() unsigned i; for (i=0;i 0) + assert(toFirstFolderIndex > 0) + + fromFirstFolderName = fromFile[:fromFirstFolderIndex] + toFirstFolderName = toFile[:toFirstFolderIndex] + fromFileInCmake = fromFile[fromFirstFolderIndex+1:] + toFileInCmake = toFile[toFirstFolderIndex+1:] + + fromCmakeFile = os.path.join(fromGamePath, fromFirstFolderName, "CMakeLists.txt") + toCmakeFile = os.path.join(toGamePath, toFirstFolderName, "CMakeLists.txt") + + modify_cmakelists(fromCmakeFile, fromFileInCmake, CmakeModifyType.ADD_COMMENT) + modify_cmakelists(toCmakeFile, toFileInCmake, CmakeModifyType.REMOVE_COMMENT) + + move_file(fromGame, fromFile, toGame, toFile) + + def main(): #unify_file(Game.ZEROHOUR, "GameEngine/Include/Common/crc.h", Game.CORE, "GameEngine/Include/Common/crc.h") @@ -412,6 +437,8 @@ def main(): #unify_file(Game.ZEROHOUR, "GameEngine/Source/GameLogic/AI/AIPathfind.cpp", Game.CORE, "GameEngine/Source/GameLogic/AI/AIPathfind.cpp") #unify_file(Game.ZEROHOUR, "GameEngine/Include/GameLogic/AIPathfind.h", Game.CORE, "GameEngine/Include/GameLogic/AIPathfind.h") + unify_move_file_lib(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/shdlib.h", Game.CORE, "Libraries/Source/WWVegas/WW3D2/shdlib.h") + return