From ef6bf1f96d352a9378b2ee5020fcd3c77b8109df Mon Sep 17 00:00:00 2001 From: jarmonik Date: Tue, 25 Jul 2023 11:50:52 +0300 Subject: [PATCH 01/42] Project to implement ray-traced VC texture support. Issue #378 --- OVP/D3D9Client/D3D9Effect.cpp | 6 +- OVP/D3D9Client/D3D9Effect.h | 5 +- OVP/D3D9Client/D3D9Surface.cpp | 1 + OVP/D3D9Client/D3D9Surface.h | 3 +- OVP/D3D9Client/DebugControls.cpp | 13 ++ OVP/D3D9Client/IProcess.cpp | 17 ++ OVP/D3D9Client/IProcess.h | 3 +- OVP/D3D9Client/Mesh.cpp | 88 ++++++++- OVP/D3D9Client/Mesh.h | 12 ++ OVP/D3D9Client/Scene.cpp | 3 + OVP/D3D9Client/VVessel.cpp | 38 ++++ OVP/D3D9Client/shaders/BakedVC.fx | 221 ++++++++++++++++++++++ OVP/D3D9Client/shaders/PreBakeLights.hlsl | 29 +++ 13 files changed, 432 insertions(+), 7 deletions(-) create mode 100644 OVP/D3D9Client/shaders/BakedVC.fx create mode 100644 OVP/D3D9Client/shaders/PreBakeLights.hlsl diff --git a/OVP/D3D9Client/D3D9Effect.cpp b/OVP/D3D9Client/D3D9Effect.cpp index 873754ed1..0b1a66a97 100644 --- a/OVP/D3D9Client/D3D9Effect.cpp +++ b/OVP/D3D9Client/D3D9Effect.cpp @@ -75,7 +75,6 @@ D3DXHANDLE D3D9Effect::eTex3 = 0; // Tertiary texture D3DXHANDLE D3D9Effect::eSpecMap = 0; D3DXHANDLE D3D9Effect::eEmisMap = 0; D3DXHANDLE D3D9Effect::eEnvMapA = 0; -D3DXHANDLE D3D9Effect::eEnvMapB = 0; D3DXHANDLE D3D9Effect::eReflMap = 0; D3DXHANDLE D3D9Effect::eRghnMap = 0; D3DXHANDLE D3D9Effect::eMetlMap = 0; @@ -84,6 +83,8 @@ D3DXHANDLE D3D9Effect::eShadowMap = 0; D3DXHANDLE D3D9Effect::eTranslMap = 0; D3DXHANDLE D3D9Effect::eTransmMap = 0; D3DXHANDLE D3D9Effect::eIrradMap = 0; +D3DXHANDLE D3D9Effect::eAmbientMap = 0; +D3DXHANDLE D3D9Effect::eCombinedMap = 0; D3DXHANDLE D3D9Effect::eSpecularMode = 0; D3DXHANDLE D3D9Effect::eHazeMode = 0; @@ -469,7 +470,6 @@ void D3D9Effect::D3D9TechInit(D3D9Client *_gc, LPDIRECT3DDEVICE9 _pDev, const ch eSpecMap = FX->GetParameterByName(0,"gSpecMap"); eEmisMap = FX->GetParameterByName(0,"gEmisMap"); eEnvMapA = FX->GetParameterByName(0,"gEnvMapA"); - eEnvMapB = FX->GetParameterByName(0,"gEnvMapB"); eReflMap = FX->GetParameterByName(0,"gReflMap"); eRghnMap = FX->GetParameterByName(0,"gRghnMap"); eMetlMap = FX->GetParameterByName(0,"gMetlMap"); @@ -478,6 +478,8 @@ void D3D9Effect::D3D9TechInit(D3D9Client *_gc, LPDIRECT3DDEVICE9 _pDev, const ch eTranslMap = FX->GetParameterByName(0, "gTranslMap"); eTransmMap = FX->GetParameterByName(0, "gTransmMap"); eIrradMap = FX->GetParameterByName(0,"gIrradianceMap"); + eAmbientMap = FX->GetParameterByName(0, "gAmbientMap"); + eCombinedMap = FX->GetParameterByName(0, "gCombinedMap"); // Atmosphere ----------------------------------------------------------- eGlobalAmb = FX->GetParameterByName(0,"gGlobalAmb"); diff --git a/OVP/D3D9Client/D3D9Effect.h b/OVP/D3D9Client/D3D9Effect.h index a9e2f8a31..9c9499947 100644 --- a/OVP/D3D9Client/D3D9Effect.h +++ b/OVP/D3D9Client/D3D9Effect.h @@ -27,6 +27,8 @@ struct TexFlow { BOOL Norm; // Enable normal map BOOL Metl; // Enable metalness map BOOL Heat; // Enable heat map + BOOL Baked; // Enable pre-baked maps +}; }; @@ -172,7 +174,6 @@ class D3D9Effect { static D3DXHANDLE eSpecMap; static D3DXHANDLE eEmisMap; static D3DXHANDLE eEnvMapA; - static D3DXHANDLE eEnvMapB; static D3DXHANDLE eReflMap; static D3DXHANDLE eMetlMap; static D3DXHANDLE eHeatMap; @@ -181,6 +182,8 @@ class D3D9Effect { static D3DXHANDLE eTransmMap; static D3DXHANDLE eShadowMap; static D3DXHANDLE eIrradMap; + static D3DXHANDLE eAmbientMap; + static D3DXHANDLE eCombinedMap; // Legacy Atmosphere ----------------------------------------------- static D3DXHANDLE eGlobalAmb; diff --git a/OVP/D3D9Client/D3D9Surface.cpp b/OVP/D3D9Client/D3D9Surface.cpp index af99a5968..f061fc5d4 100644 --- a/OVP/D3D9Client/D3D9Surface.cpp +++ b/OVP/D3D9Client/D3D9Surface.cpp @@ -136,6 +136,7 @@ SURFHANDLE NatLoadSurface(const char* file, DWORD flags, bool bPath) pNat->AddMap(MAP_REFLECTION, NatLoadSpecialTexture(file, "refl")); pNat->AddMap(MAP_TRANSLUCENCE, NatLoadSpecialTexture(file, "transl")); pNat->AddMap(MAP_TRANSMITTANCE, NatLoadSpecialTexture(file, "transm")); + pNat->AddMap(MAP_AMBIENT, NatLoadSpecialTexture(file, "bkao")); } else oapiWriteLogV("FAILED: NatLoadSurface(%d)", path); } diff --git a/OVP/D3D9Client/D3D9Surface.h b/OVP/D3D9Client/D3D9Surface.h index 580f21a46..ba4af0b59 100644 --- a/OVP/D3D9Client/D3D9Surface.h +++ b/OVP/D3D9Client/D3D9Surface.h @@ -24,7 +24,8 @@ #define MAP_ROUGHNESS 6 #define MAP_METALNESS 7 #define MAP_HEAT 8 -#define MAP_MAX_COUNT 9 +#define MAP_AMBIENT 9 +#defineMAP_MAX_COUNT 10 #define OAPISURFACE_MAPS 0x80000000 // Additional Texture Maps #define OAPISURFACE_BACKBUFFER 0x40000000 // It's a backbuffer diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index 100728a9d..429d3929a 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -355,6 +355,12 @@ void InitMatList(WORD shader) for (auto x : Dropdown) SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_ADDSTRING, 0, (LPARAM)x.name.c_str()); } + if (shader == SHADER_BAKED_VC) { + std::list list = { 0, 3, 5, 7, 8, 9 }; + for (auto x : list) Dropdown.push_back(PrmList[x]); + for (auto x : Dropdown) SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_ADDSTRING, 0, (LPARAM)x.name.c_str()); + } + SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_SETCURSEL, idx, 0); switch (shader) { @@ -363,6 +369,7 @@ void InitMatList(WORD shader) Params[6].var[2] = DefVar(10.0f, 4096.0f, SQRT, "Specular lobe size"); break; case SHADER_METALNESS: + case SHADER_BAKED_VC: Params[6].var[1] = DefVar(0, 1, LIN, "Fresnel effect attennuation 1.0 = disabled, 0.0 = max intensity"); Params[6].var[2].bUsed = false; break; @@ -403,6 +410,7 @@ void OpenDlgClbk(void *context) SendDlgItemMessageA(hDlg, IDC_DBG_DEFSHADER, CB_RESETCONTENT, 0, 0); SendDlgItemMessageA(hDlg, IDC_DBG_DEFSHADER, CB_ADDSTRING, 0, (LPARAM)"PBR (Old)"); SendDlgItemMessageA(hDlg, IDC_DBG_DEFSHADER, CB_ADDSTRING, 0, (LPARAM)"Metalness PBR"); + SendDlgItemMessageA(hDlg, IDC_DBG_DEFSHADER, CB_ADDSTRING, 0, (LPARAM)"Baked VC"); SendDlgItemMessageA(hDlg, IDC_DBG_DEFSHADER, CB_SETCURSEL, 0, 0); SendDlgItemMessageA(hDlg, IDC_DBG_SCENEDBG, CB_RESETCONTENT, 0, 0); @@ -647,6 +655,10 @@ void UpdateShader() hMesh->SetDefaultShader(SHADER_METALNESS); pMgr->RegisterShaderChange(hMesh, SHADER_METALNESS); break; + case 2: + hMesh->SetDefaultShader(SHADER_BAKED_VC); + pMgr->RegisterShaderChange(hMesh, SHADER_BAKED_VC); + break; } InitMatList(hMesh->GetDefaultShader()); @@ -1106,6 +1118,7 @@ void UpdateMaterialDisplay(bool bSetup) WORD Shader = hMesh->GetDefaultShader(); if (Shader == SHADER_NULL) SendDlgItemMessageA(hDlg, IDC_DBG_DEFSHADER, CB_SETCURSEL, 0, 0); if (Shader == SHADER_METALNESS) SendDlgItemMessageA(hDlg, IDC_DBG_DEFSHADER, CB_SETCURSEL, 1, 0); + if (Shader == SHADER_BAKED_VC) SendDlgItemMessageA(hDlg, IDC_DBG_DEFSHADER, CB_SETCURSEL, 2, 0); DWORD matidx = hMesh->GetMeshGroupMaterialIdx(sGroup); diff --git a/OVP/D3D9Client/IProcess.cpp b/OVP/D3D9Client/IProcess.cpp index 4936bd405..1b41eb833 100644 --- a/OVP/D3D9Client/IProcess.cpp +++ b/OVP/D3D9Client/IProcess.cpp @@ -629,6 +629,23 @@ void ImageProcessing::SetTextureNative(const char *var, LPDIRECT3DBASETEXTURE9 h } +// ================================================================================================ +// +void ImageProcessing::SetTextureNative(int idx, LPDIRECT3DBASETEXTURE9 hTex, DWORD flags) +{ + if (idx < 0 || idx>15) return; + + if (!hTex) { + pTextures[idx].hTex = NULL; + pTextures[idx].flags = 0; + return; + } + + pTextures[idx].hTex = hTex; + pTextures[idx].flags = flags; +} + + // ================================================================================================ // void ImageProcessing::SetOutput(int id, SURFHANDLE hTex) diff --git a/OVP/D3D9Client/IProcess.h b/OVP/D3D9Client/IProcess.h index 195968849..3133c1c93 100644 --- a/OVP/D3D9Client/IProcess.h +++ b/OVP/D3D9Client/IProcess.h @@ -115,6 +115,7 @@ class ImageProcessing { void SetDepthStencil(LPDIRECT3DSURFACE9 hSrf = NULL); void SetOutputNative(int id, LPDIRECT3DSURFACE9 hSrf); void SetTextureNative(const char *var, LPDIRECT3DBASETEXTURE9 hTex, DWORD flags); + void SetTextureNative(int idx, LPDIRECT3DBASETEXTURE9 hTex, DWORD flags); private: @@ -128,7 +129,7 @@ class ImageProcessing { struct { LPDIRECT3DBASETEXTURE9 hTex; DWORD flags; - } pTextures[8]; + } pTextures[10]; gcIPInterface::ipicull mesh_cull; diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index ac5d5f312..82e985bb1 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -460,6 +460,76 @@ void D3D9Mesh::ReLoadMeshFromHandle(MESHHANDLE hMesh) } +// =========================================================================================== +// +void D3D9Mesh::LoadBakedLights() +{ + char id[8]; + for (int i = 0; i < nTex; i++) + { + if (!Tex[i]) continue; + if (!Tex[i]->GetMap(MAP_AMBIENT)) continue; + + const char* name = Tex[i]->GetName(); + + for (int j = 0; j < 10; j++) + { + sprintf_s(id, "_bkl%d", j); + BakedLights[i].pMap[j] = NatLoadSpecialTexture(name, id); + } + + HR(D3DXCreateTexture(pDev, Tex[i]->GetWidth(), Tex[i]->GetHeight(), 0, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &BakedLights[i].pCombined)); + } + for (int i = 0; i < 10;i++) BakedLightsControl[i] = FVECTOR3(1, 1, 1); +} + + +// =========================================================================================== +// +void D3D9Mesh::SetBakedLightLevel(int idx, FVECTOR3 level) +{ + if (idx >= 0 && idx <= 9) BakedLightsControl[idx] = level; +} + + +// =========================================================================================== +// +void D3D9Mesh::BakeLights(ImageProcessing* pBaker) +{ + if (!pBaker->IsOK()) return; + + DWORD flags = IPF_POINT; + FVECTOR3 control[10]; + + for (auto x : BakedLights) + { + int slot = 0; + for (int i = 0; i < 10; i++) + { + auto y = x.second.pMap[i]; + if (y && length(BakedLightsControl[i]) > 0.01f) + { + pBaker->SetTextureNative(slot, y, flags); + control[slot] = BakedLightsControl[i]; + slot++; + } + } + + pBaker->SetFloat("fControl", control, slot * sizeof(FVECTOR3)); + pBaker->SetInt("iCount", slot); + + LPDIRECT3DSURFACE9 pSrf = NULL; + + if (x.second.pCombined->GetSurfaceLevel(0, &pSrf) == S_OK) + { + pBaker->SetOutputNative(0, pSrf); + pBaker->Execute(true); + SAFE_RELEASE(pSrf); + } + } +} + + // =========================================================================================== // void D3D9Mesh::LoadMeshFromHandle(MESHHANDLE hMesh, D3DXVECTOR3 *reorig, float *scale) @@ -501,6 +571,7 @@ void D3D9Mesh::LoadMeshFromHandle(MESHHANDLE hMesh, D3DXVECTOR3 *reorig, float * UpdateBoundingBox(); CheckMeshStatus(); + LoadBakedLights(); } // =========================================================================================== @@ -1729,7 +1800,9 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, int iTech, LPDIRECT3DCUBETEXTURE9 * if (pSpec) FX->SetTexture(eSpecMap, pSpec); if (pRefl) FX->SetTexture(eReflMap, pRefl); - if (CurrentShader == SHADER_ADV || CurrentShader == SHADER_METALNESS) + if (CurrentShader == SHADER_ADV + || CurrentShader == SHADER_METALNESS + || CurrentShader == SHADER_BAKED_VC) { pTransl = Tex[ti]->GetMap(MAP_TRANSLUCENCE); pTransm = Tex[ti]->GetMap(MAP_TRANSMITTANCE); @@ -1749,6 +1822,17 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, int iTech, LPDIRECT3DCUBETEXTURE9 * FC.Metl = false; } + if (CurrentShader == SHADER_BAKED_VC) + { + LPDIRECT3DTEXTURE9 pAmbi = Tex[ti]->GetMap(MAP_AMBIENT); + LPDIRECT3DTEXTURE9 pComb = BakedLights[ti].pCombined; + + if (pAmbi) FX->SetTexture(eAmbientMap, pAmbi); + if (pComb) FX->SetTexture(eCombinedMap, pComb); + + FC.Baked = (pAmbi != NULL) && (pComb != NULL); + } + FC.Emis = (pEmis != NULL); FC.Norm = (pNorm != NULL); FC.Rghn = (pRghn != NULL); @@ -1868,7 +1952,7 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, int iTech, LPDIRECT3DCUBETEXTURE9 * static const char *YesNo[2] = { "No", "Yes" }; static const char *LPW[2] = { "Legacy", "PBR" }; static const char *RGH[2] = { "Disabled", "Enabled" }; - static const char *Shaders[7] = { "PBR", "PBR-ADV", "FAST", "XR2", "METALNESS", "SPECULAR", "???"}; + static const char *Shaders[7] = { "PBR", "PBR-ADV", "FAST", "XR2", "METALNESS", "BAKED_VC", "???"}; DebugControls::Append("MeshIdx = %d, GrpIdx = %d\n", uCurrentMesh, g); DebugControls::Append("MtrlIdx = %d, TexIdx = %d\n", Grp[g].MtrlIdx, Grp[g].TexIdx); diff --git a/OVP/D3D9Client/Mesh.h b/OVP/D3D9Client/Mesh.h index 7c9429104..e1e80f361 100644 --- a/OVP/D3D9Client/Mesh.h +++ b/OVP/D3D9Client/Mesh.h @@ -20,9 +20,11 @@ #include "D3D9Client.h" #include "D3D9Effect.h" #include "AABBUtil.h" +#include "IProcess.h" #include #include #include +#include const DWORD SPEC_DEFAULT = (DWORD)(-1); // "default" material/texture flag const DWORD SPEC_INHERIT = (DWORD)(-2); // "inherit" material/texture flag @@ -45,6 +47,7 @@ const DWORD SPEC_INHERIT = (DWORD)(-2); // "inherit" material/texture flag #define SHADER_LEGACY 2 // Shader most compatible with DX7 Inline #define SHADER_XR2HUD 3 // XR2 HUD shader #define SHADER_METALNESS 4 +#define SHADER_BAKED_VC 5 #define SHADER_SHADOWMAP 10 #define SHADER_SHADOWMAP_OIT 11 #define SHADER_NORMAL_DEPTH 12 @@ -69,6 +72,10 @@ struct _LightList { float illuminace; }; +struct _BakedLights { + LPDIRECT3DTEXTURE9 pMap[16]; + LPDIRECT3DTEXTURE9 pCombined; +}; class MeshShader : public ShaderClass { @@ -203,6 +210,9 @@ class D3D9Mesh : private D3D9Effect void Release(); + void LoadBakedLights(); + void BakeLights(ImageProcessing *pBaker); + void SetBakedLightLevel(int idx, FVECTOR3 level); void LoadMeshFromHandle(MESHHANDLE hMesh, D3DXVECTOR3 *reorig = NULL, float *scale = NULL); void ReLoadMeshFromHandle(MESHHANDLE hMesh); void ReloadTextures(); @@ -352,6 +362,8 @@ class D3D9Mesh : private D3D9Effect DWORD Flags; D3D9MatExt *Mtrl; // list of mesh materials SurfNative **Tex; // list of mesh textures + std::map BakedLights; + FVECTOR3 BakedLightsControl[10]; D3D9Tune *pTune; D3DXMATRIX mTransform; D3DXMATRIX mTransformInv; diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index 86c54e6a9..8b97bde17 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -314,6 +314,8 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) } } + pBakeLights = new ImageProcessing(pDevice, "Modules/D3D9Client/PreBakeLights.hlsl", "PSMain"); + LogAlw("================ Scene Created ==============="); } @@ -341,6 +343,7 @@ Scene::~Scene () SAFE_DELETE(pLocalCompute); SAFE_DELETE(pRenderGlares); SAFE_DELETE(pCreateGlare); + SAFE_DELETE(pBakeLights); SAFE_RELEASE(pOffscreenTarget); SAFE_RELEASE(pEnvDS); diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index c460b2293..8b77dcabd 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -640,6 +640,44 @@ void vVessel::GetMinMaxLightDist(float *mind, float *maxd) *maxd = max(*maxd, x + shd->rad); } +// ============================================================================================ +// +bool vVessel::GetVCPos(D3DXVECTOR3* out, float* rad) +{ + for (int i = 0; i < nmesh; i++) + { + if (!meshlist[i].mesh) continue; + + if (meshlist[i].vismode == MESHVIS_VC) + { + D3DXVECTOR3 pos = meshlist[i].mesh->GetBoundingSpherePos(); + + if (meshlist[i].trans) + { + D3DXMATRIX mWT; + D3DXMatrixMultiply(&mWT, (const D3DXMATRIX*)meshlist[i].trans, &mWorld); + D3DXVec3TransformCoord(&pos, &pos, &mWT); + } + else D3DXVec3TransformCoord(&pos, &pos, &mWorld); + if (out) *out = pos; + if (rad) *rad = meshlist[i].mesh->GetBoundingSphereRadius(); + return true; + } + } + return false; +} + + +// ============================================================================================ +// +void vVessel::NoVC() +{ + static bool bDisp = true; + if (bDisp) { + bDisp = false; + oapiWriteLogV("ERROR:D3D9: Cannot identify Virtual Cockpit mesh [%s]", vessel->GetClassNameA()); + } +} // ============================================================================================ // diff --git a/OVP/D3D9Client/shaders/BakedVC.fx b/OVP/D3D9Client/shaders/BakedVC.fx new file mode 100644 index 000000000..24b9b8987 --- /dev/null +++ b/OVP/D3D9Client/shaders/BakedVC.fx @@ -0,0 +1,221 @@ +// ============================================================== +// Part of the ORBITER VISUALISATION PROJECT (OVP) +// licensed under LGPL v2 +// ============================================================== + +#define eps 0.001f + + + + +// ============================================================================ +// A Shader for a typical "Metalness" PBR workflow. +// ============================================================================ + +float4 BakedVC_PS(float4 sc : VPOS, PBRData frg) : COLOR +{ + float3 nrmT; + float3 nrmW; + float3 cEmis; + //float4 cSpecularMap; + float4 cDiff; + //float fHeat; + float fSmth, fMetal; + + // ====================================================================== + // Start fetching texture data + // ====================================================================== + + if (gTextured) cDiff = tex2D(WrapS, frg.tex0.xy); + else cDiff = 1; + + // Fetch a normal map + // + if (gCfg.Norm) nrmT = tex2D(Nrm0S, frg.tex0.xy).rgb; + + // Fetch Smoothness map (i.e. *_rghn.dds) + // + if (gCfg.Rghn) fSmth = tex2D(RghnS, frg.tex0.xy).g; + else fSmth = 1.0f; + + // Fetch Roughness map + // + if (gCfg.Metl) fMetal = tex2D(MetlS, frg.tex0.xy).g; + else fMetal = gMtrl.metalness; + + // Sample emission map. (Note: Emissive materials and textures need to go different stages, material is added to light) + // + if (gCfg.Emis) cEmis = tex2D(EmisS, frg.tex0.xy).rgb; + else cEmis = 0; + + // Sample specular map + // + //if (gCfg.Spec) cSpecularMap = tex2D(SpecS, frg.tex0.xy).rgba; + + // Fetch Heat map + // + //if (gCfg.Heat) fHeat = saturate((tex2D(HeatS, frg.tex0.xy).g) - 1.0f + (gMtrl.specialfx.x * gMtrl.specialfx.x * gMtrl.specialfx.x)); + //else fHeat = (gMtrl.specialfx.x * gMtrl.specialfx.x * gMtrl.specialfx.x); + + // ---------------------------------------------------------------------- + // Now do other calculations while textures are being fetched + // ---------------------------------------------------------------------- + + float3 camW = normalize(frg.camW); + float3 cSun = gSun.Color * lerp(float3(1.1, 1.1, 0.9), float3(1,1,1), saturate(gRadius[3]*2e-5)); + + + // ====================================================================== + // Construct a proper world space normal + // ====================================================================== + + float3 tanW = frg.tanW.xyz; + float3 bitW = cross(tanW, frg.nrmW) * frg.tanW.w; + + if (gCfg.Norm) { + nrmT.rg = nrmT.rg * 2.0f - 1.0f; + nrmW = frg.nrmW*nrmT.z + tanW*nrmT.x + bitW*nrmT.y; + } + else nrmW = frg.nrmW; + + nrmW = normalize(nrmW); + + + + // ====================================================================== + // Typical compatibility requirements + // ====================================================================== + + if (gNoColor) cDiff.rgb = 1; + cDiff = saturate(cDiff * float4(gMtrl.diffuse.rgb, gMtrlAlpha)); + + + // ====================================================================== + // Some Precomputations + // ====================================================================== + + float3 sunW = -gSun.Dir; + float3 cEnv = 0; + + float3 rflW = reflect(-camW, nrmW); + float3 hlvW = normalize(camW + sunW); + + // Dot Products + float uLN = dot(sunW, nrmW); + float uLC = dot(sunW, camW); + float dLN = saturate(uLN); + float dLH = saturate(dot(sunW, hlvW)); + float dCN = saturate(dot(camW, nrmW)); + float dHN = saturate(dot(hlvW, nrmW)); + + // Apply a proper curve to a texture data, modulate with material value and clamp + fSmth = pow(abs(fSmth), gMtrl.roughness.y) * gMtrl.roughness.x; + + // Apply fresnel and Fresnell cut-off to fSmth + fSmth = fSmth + ((1.0f - fSmth) * pow(abs(1.0f - dCN), 4.0f)) * pow(abs(fSmth), 0.5f); + + float fRgh = saturate(1.0f - fSmth); + float fRgh3 = fRgh*fRgh*fRgh; + +/* +#if defined(_ENVMAP) + + if (gEnvMapEnable) { + + // ====================================================================== + // Sample Env Map + SampleEnvMap(cEnv, dCN, fRgh, fMetal, rflW, nrmW); + } + + // ====================================================================== + // Sample Irradiance Map + float3 cAmbient = Paraboloidal_LVLH(IrradS, nrmW).rgb; + cAmbient *= cAmbient; + + //cAmbient = saturate(cAmbient * (1.0f + 15.0f * gNightTime)); + // Apply base ambient light + cAmbient = max(cAmbient, gSun.Ambient); +#else + +#endif + + cAmbient *= (1.0f - fMetal); // No ambient for metals +*/ + + + // ====================================================================== + // Add vessel self-shadows + // ====================================================================== +#if SHDMAP > 0 + cSun *= smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc)); +#endif + + + // ====================================================================== + // Main shader core MetalnessPS + // ====================================================================== + float fD = GGX_NDF(dHN, lerp(0.01f, 1.0f, fRgh3)); + float fG = SchlickBeckmanGSF(dLN, dCN, fRgh); + float fR = DiffuseRetroReflectance(dLN, dCN, dLH, fRgh, fMetal); + + + // Base material color for reflections. Use cDiff for metals and very rough plastics, white for the rest. + // cDiff for rough plastics is to avoid washed-out(white) look of black and rough parts. + float3 cSpec = lerp(cDiff.rgb, float3(1, 1, 1), (1.0f - fMetal) * (1.0f - fRgh3)); + + // Fresnel power 2.5 for glossy, 5.0 for rough + float fFrs = pow(1.0f - dCN, fRgh*2.5 + 2.5f); + + // Fresnel cut-off below X of fSmth + fFrs *= saturate(0.3f - fRgh*fRgh) * 3.3f; + + // Assume that plastics absorve 50-90% of specular light + float fP = lerp(0.1f + (1.0f - fRgh)*0.4f, 1.0f, fMetal); + + // Fresnel color shift + float3 cF = cSpec + (1.0f - cSpec) * fFrs; + + // Specular Color + float3 cS = (fD * cF * fG * fP) * 0.25f; // (4.0f*dLN*dCN) removed to avoid division by zero, compensation in GSF + + + // How plastics reflect the environment + float R = 0.1f * fSmth; + float frP = R + (1.0f - R) * fFrs; + + float3 cE = (cEnv * cF * lerp(frP, 1.0f, fMetal)); + + // Attennuate diffuse color for Metals & Fresnel + float fA = (1.0f - fFrs) * (1.0f - fMetal); + + // Add a faint diffuse hue for rough metals. Rough metal doesn't look good if it's totally black + fA += fRgh * fMetal * 0.05f; + + float3 zD = cDiff.rgb * fA * LightFXSq(Sq(cSun * fR * dLN) + Sq(gMtrl.emissive.rgb)); + + // Combine specular terms + float3 zS = cS * (cSun * dLN); + + cDiff.rgb = zD + zS + cE; + + // Override material alpha to make reflections visible + cDiff.a = saturate(cDiff.a + cmax(zS + cE)); + + // Add emission texture to output, modulate with material + cDiff.rgb = max(cDiff.rgb, cEmis * gMtrl.emission2.rgb); + + +#if defined(_DEBUG) + cDiff = cDiff * (1.0f - gColor*0.5f) + gColor; +#endif + + + // Is post-processing shader enabled on not ? + // +#if defined(_LIGHTGLOW) + return cDiff; +#else + float3 h2 = cDiff.rgb*cDiff.rgb; + return float4(cDiff.rgb * pow(max(0, 1.0f + h2*h2), -0.25), cDiff.a); +#endif +} diff --git a/OVP/D3D9Client/shaders/PreBakeLights.hlsl b/OVP/D3D9Client/shaders/PreBakeLights.hlsl new file mode 100644 index 000000000..632499edc --- /dev/null +++ b/OVP/D3D9Client/shaders/PreBakeLights.hlsl @@ -0,0 +1,29 @@ +// ============================================================== +// Part of the ORBITER VISUALISATION PROJECT (OVP) +// licensed under MIT +// ============================================================== + +uniform extern float3 fControl[10]; +uniform extern int iCount; + +sampler tMap[10] : register(s0); + +float cmax(float3 a) +{ + return max(a.x, max(a.y, a.z)); +} + +float3 LightFX(float3 c) +{ + float q = cmax(c); + return c * 1.2f * rsqrt(2 + q * q); +} + + +float4 PSMain(float x : TEXCOORD0, float y : TEXCOORD1) : COLOR +{ + float3 color = 0; + [unroll] for (int i = 0; i < iCount; i++) color += tex2D(tMap[i], float2(x, y)).rgb * fControl[i]; + //[unroll] for (int i = 0; i < 10; i++) if (i < iCount) color += tex2D(tMap[i], float2(x, y)).rgb * fControl[i]; + return float4(LightFX(color), 1.0f); +} From 62ab5bffe7459ada2e6c2d9dadca20aa887260c8 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Tue, 25 Jul 2023 13:25:28 +0300 Subject: [PATCH 02/42] Fixed build errors. Added new shaders in a shader folder. --- OVP/D3D9Client/CMakeLists.txt | 2 ++ OVP/D3D9Client/D3D9Effect.h | 1 - OVP/D3D9Client/D3D9Surface.h | 2 +- OVP/D3D9Client/Scene.cpp | 1 + OVP/D3D9Client/Scene.h | 2 +- OVP/D3D9Client/VVessel.cpp | 1 + OVP/D3D9Client/VVessel.h | 2 ++ 7 files changed, 8 insertions(+), 3 deletions(-) diff --git a/OVP/D3D9Client/CMakeLists.txt b/OVP/D3D9Client/CMakeLists.txt index 8e89c0e60..74385322a 100644 --- a/OVP/D3D9Client/CMakeLists.txt +++ b/OVP/D3D9Client/CMakeLists.txt @@ -141,6 +141,7 @@ set(ShaderFiles ${ShaderDir}/NewPlanet.hlsl ${ShaderDir}/Scatter.hlsl ${ShaderDir}/Glare.hlsl + ${ShaderDir}/PreBakeLights.hlsl ${ShaderDir}/Mesh.fx ${ShaderDir}/Metalness.fx ${ShaderDir}/Particle.fx @@ -149,6 +150,7 @@ set(ShaderFiles ${ShaderDir}/SceneTech.fx ${ShaderDir}/Sketchpad.fx ${ShaderDir}/Vessel.fx + ${ShaderDir}/BakedVC.fx ) source_group(APIHeaders FILES ${APIHeaders}) diff --git a/OVP/D3D9Client/D3D9Effect.h b/OVP/D3D9Client/D3D9Effect.h index a0a51c108..3a05f3283 100644 --- a/OVP/D3D9Client/D3D9Effect.h +++ b/OVP/D3D9Client/D3D9Effect.h @@ -29,7 +29,6 @@ struct TexFlow { BOOL Heat; // Enable heat map BOOL Baked; // Enable pre-baked maps }; -}; diff --git a/OVP/D3D9Client/D3D9Surface.h b/OVP/D3D9Client/D3D9Surface.h index ba4af0b59..a92063b9a 100644 --- a/OVP/D3D9Client/D3D9Surface.h +++ b/OVP/D3D9Client/D3D9Surface.h @@ -25,7 +25,7 @@ #define MAP_METALNESS 7 #define MAP_HEAT 8 #define MAP_AMBIENT 9 -#defineMAP_MAX_COUNT 10 +#define MAP_MAX_COUNT 10 #define OAPISURFACE_MAPS 0x80000000 // Additional Texture Maps #define OAPISURFACE_BACKBUFFER 0x40000000 // It's a backbuffer diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index 2e7d7ac91..073fb2727 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -102,6 +102,7 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) pVisDepth = NULL; pLocalResults = NULL; pLocalResultsSL = NULL; + pBakeLights = NULL; fDisplayScale = float(viewH) / 1080.0f; diff --git a/OVP/D3D9Client/Scene.h b/OVP/D3D9Client/Scene.h index 4635a487a..c79d498c8 100644 --- a/OVP/D3D9Client/Scene.h +++ b/OVP/D3D9Client/Scene.h @@ -489,7 +489,7 @@ class Scene { SurfNative *pLblSrf; - class ImageProcessing *pLightBlur, *pBlur, *pGDIOverlay, *pIrradiance, *pVisDepth, *pCreateGlare; + class ImageProcessing *pLightBlur, *pBlur, *pGDIOverlay, *pIrradiance, *pVisDepth, *pCreateGlare, *pBakeLights; class ShaderClass *pLocalCompute, *pRenderGlares; class vVessel *vFocus; diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index f8577fa59..67b2e1e0e 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -640,6 +640,7 @@ void vVessel::GetMinMaxLightDist(float *mind, float *maxd) *maxd = max(*maxd, x + shd->rad); } + // ============================================================================================ // bool vVessel::GetVCPos(D3DXVECTOR3* out, float* rad) diff --git a/OVP/D3D9Client/VVessel.h b/OVP/D3D9Client/VVessel.h index 2ad3b2e24..53ed453a9 100644 --- a/OVP/D3D9Client/VVessel.h +++ b/OVP/D3D9Client/VVessel.h @@ -71,6 +71,8 @@ class vVessel: public vObject { void GetMinMaxLightDist(float *mind, float *maxd); int GetMatrixTransform(gcCore::MatrixId matrix_id, DWORD mesh, DWORD group, FMATRIX4 *pMat); int SetMatrixTransform(gcCore::MatrixId matrix_id, DWORD mesh, DWORD group, const FMATRIX4 *pMat); + bool GetVCPos(D3DXVECTOR3* out, float* rad); + void NoVC(); void UpdateBoundingBox(); bool IsInsideShadows(); bool IntersectShadowVolume(); From a193053e2a2196646d38fb1e0152fa458aac8b48 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Tue, 25 Jul 2023 16:51:08 +0300 Subject: [PATCH 03/42] Enabled basic shadows for virtual cockpit. Cascaded maps still needs doing. --- OVP/D3D9Client/Mesh.cpp | 8 +++++++- OVP/D3D9Client/Mesh.h | 2 +- OVP/D3D9Client/Scene.cpp | 18 +++++++++++++++++- OVP/D3D9Client/VVessel.cpp | 7 +++++-- OVP/D3D9Client/shaders/BakedVC.fx | 1 - OVP/D3D9Client/shaders/Common.hlsl | 11 ++++------- OVP/D3D9Client/shaders/PreBakeLights.hlsl | 1 - .../DeltaGlider/Meshes/deltaglider_ns.msh | 1 + .../DeltaGlider/Meshes/deltaglider_vc.msh | 2 +- 9 files changed, 36 insertions(+), 15 deletions(-) diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index 7c5fba600..afd5c9ba0 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -2791,7 +2791,7 @@ void D3D9Mesh::RenderBaseTile(const LPD3DXMATRIX pW) // ================================================================================================ // -void D3D9Mesh::RenderShadowMap(const LPD3DXMATRIX pW, const LPD3DXMATRIX pVP, int opt) +void D3D9Mesh::RenderShadowMap(const LPD3DXMATRIX pW, const LPD3DXMATRIX pVP, int opt, bool bNoCull) { if (!IsOK()) return; @@ -2865,7 +2865,13 @@ void D3D9Mesh::RenderShadowMap(const LPD3DXMATRIX pW, const LPD3DXMATRIX pVP, in if (pShader->hPSB) pShader->SetPSConstants(pShader->hPSB, &MeshShader::ps_bools, sizeof(MeshShader::ps_bools)); pShader->UpdateTextures(); + DWORD oc; + if (bNoCull) { + pDev->GetRenderState(D3DRS_CULLMODE, &oc); + pDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + } pDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, Grp[g].VertOff, 0, Grp[g].nVert, Grp[g].IdexOff, Grp[g].nFace); + if (bNoCull) pDev->SetRenderState(D3DRS_CULLMODE, oc); } } diff --git a/OVP/D3D9Client/Mesh.h b/OVP/D3D9Client/Mesh.h index 1aa16ed31..3da0101e9 100644 --- a/OVP/D3D9Client/Mesh.h +++ b/OVP/D3D9Client/Mesh.h @@ -301,7 +301,7 @@ class D3D9Mesh : private D3D9Effect void RenderBoundingBox(const LPD3DXMATRIX pW); void Render(const LPD3DXMATRIX pW, int iTech=RENDER_VESSEL, LPDIRECT3DCUBETEXTURE9 *pEnv=NULL, int nEnv=0); void RenderFast(const LPD3DXMATRIX pW, int iTech); - void RenderShadowMap(const LPD3DXMATRIX pW, const LPD3DXMATRIX pVP, int flags); + void RenderShadowMap(const LPD3DXMATRIX pW, const LPD3DXMATRIX pVP, int flags, bool bNoCull = false); void RenderStencilShadows(float alpha, const LPD3DXMATRIX pP, const LPD3DXMATRIX pW, bool bShadowMap = false, const D3DXVECTOR4 *elev = NULL); void RenderShadowsEx(float alpha, const LPD3DXMATRIX pP, const LPD3DXMATRIX pW, const D3DXVECTOR4 *light, const D3DXVECTOR4 *param); void RenderRings(const LPD3DXMATRIX pW, LPDIRECT3DTEXTURE9 pTex); diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index 073fb2727..2a0dd6ddd 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -1970,6 +1970,21 @@ void Scene::RenderMainScene() if (znear>1.0) znear=1.0; OBJHANDLE hFocus = oapiGetFocusObject(); SetCameraFrustumLimits(znear, oapiGetSize(hFocus)*2.0); + + if (Config->ShadowMapMode >= 1) + { + SmapRenderList.clear(); + + float rad = 1.5f; + D3DXVECTOR3 ld = sunLight.Dir; + D3DXVECTOR3 pos = Camera.z * rad; + + RenderShadowMap(pos, ld, rad, true, false); + + pShdMap = smap.pShadowMap; + } + + // Render VC vFocus->Render(pDevice, true); } @@ -2524,7 +2539,8 @@ int Scene::RenderShadowMap(D3DXVECTOR3 &pos, D3DXVECTOR3 &ld, float rad, bool bI BeginPass(RENDERPASS_SHADOWMAP); while(SmapRenderList.size()>0) { - SmapRenderList.front()->Render(pDevice, bInternal); + SmapRenderList.front()->Render(pDevice, false); + if (bInternal) SmapRenderList.front()->Render(pDevice, true); SmapRenderList.pop_front(); } diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index 67b2e1e0e..484a4c2ce 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -718,7 +718,7 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass) if (scn->GetRenderPass() == RENDERPASS_ENVCAM) bCockpit = bVC = false; // Always render exterior view for envmaps - if (scn->GetRenderPass() == RENDERPASS_SHADOWMAP) bCockpit = bVC = false; + // if (scn->GetRenderPass() == RENDERPASS_SHADOWMAP) bCockpit = bVC = false; // Always render exterior view for envmaps // if (scn->GetRenderPass() == RENDERPASS_NORMAL_DEPTH) bCockpit = bVC = false; @@ -824,7 +824,10 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass) // Render vessel meshes -------------------------------------------------------------------------- // - if (scn->GetRenderPass() == RENDERPASS_SHADOWMAP) meshlist[i].mesh->RenderShadowMap(pWT, pLVP, 0); + if (scn->GetRenderPass() == RENDERPASS_SHADOWMAP) + { + meshlist[i].mesh->RenderShadowMap(pWT, pLVP, 0, internalpass); + } else if (scn->GetRenderPass() == RENDERPASS_NORMAL_DEPTH) { meshlist[i].mesh->RenderShadowMap(pWT, pVP, 1); diff --git a/OVP/D3D9Client/shaders/BakedVC.fx b/OVP/D3D9Client/shaders/BakedVC.fx index 24b9b8987..9e2fccb7c 100644 --- a/OVP/D3D9Client/shaders/BakedVC.fx +++ b/OVP/D3D9Client/shaders/BakedVC.fx @@ -3,7 +3,6 @@ // licensed under LGPL v2 // ============================================================== -#define eps 0.001f diff --git a/OVP/D3D9Client/shaders/Common.hlsl b/OVP/D3D9Client/shaders/Common.hlsl index 85a5a2132..184f82f67 100644 --- a/OVP/D3D9Client/shaders/Common.hlsl +++ b/OVP/D3D9Client/shaders/Common.hlsl @@ -1,8 +1,5 @@ #define KERNEL_RADIUS 2.0f -#define SHADOW_THRESHOLD 0.1f // 0.3 to 7.0 - - // ============================================================================ // @@ -385,9 +382,9 @@ float ComputeShadow(float4 shdH, float dLN, float4 sc) float kr = gSHD[0] * KERNEL_RADIUS; float dx = rsqrt(1.0 - dLN*dLN); - float ofs = kr / (dLN * dx); - float omx = min(0.05 + ofs, 0.5); - + float ofs = 0.33f * kr / (dLN * dx); + float omx = min(gSHD[0] * 2.0f + max(0, ofs), 0.25); + float pd = shdH.z + omx * gSHD[3]; if (pd < 0) pd = 0; @@ -396,4 +393,4 @@ float ComputeShadow(float4 shdH, float dLN, float4 sc) fShadow = SampleShadowsEx(sp, pd, sc); return 1 - fShadow; -} \ No newline at end of file +} diff --git a/OVP/D3D9Client/shaders/PreBakeLights.hlsl b/OVP/D3D9Client/shaders/PreBakeLights.hlsl index 632499edc..e02cf327b 100644 --- a/OVP/D3D9Client/shaders/PreBakeLights.hlsl +++ b/OVP/D3D9Client/shaders/PreBakeLights.hlsl @@ -24,6 +24,5 @@ float4 PSMain(float x : TEXCOORD0, float y : TEXCOORD1) : COLOR { float3 color = 0; [unroll] for (int i = 0; i < iCount; i++) color += tex2D(tMap[i], float2(x, y)).rgb * fControl[i]; - //[unroll] for (int i = 0; i < 10; i++) if (i < iCount) color += tex2D(tMap[i], float2(x, y)).rgb * fControl[i]; return float4(LightFX(color), 1.0f); } diff --git a/Src/Vessel/DeltaGlider/Meshes/deltaglider_ns.msh b/Src/Vessel/DeltaGlider/Meshes/deltaglider_ns.msh index 92c56686b..2a1ce9b6b 100644 --- a/Src/Vessel/DeltaGlider/Meshes/deltaglider_ns.msh +++ b/Src/Vessel/DeltaGlider/Meshes/deltaglider_ns.msh @@ -26391,6 +26391,7 @@ GEOM 20 28 ; HUD_glass 116 16 18 0 MATERIAL 25 TEXTURE 0 +FLAG 11 GEOM 78 62 ; cockpitglass 110 -0.431152 1.201853 7.235322 -0.780780 0.469222 0.412569 -0.550900 1.232871 6.973425 -0.806691 0.484650 0.338177 diff --git a/Src/Vessel/DeltaGlider/Meshes/deltaglider_vc.msh b/Src/Vessel/DeltaGlider/Meshes/deltaglider_vc.msh index f7fed26e6..74b8a5ee8 100644 --- a/Src/Vessel/DeltaGlider/Meshes/deltaglider_vc.msh +++ b/Src/Vessel/DeltaGlider/Meshes/deltaglider_vc.msh @@ -19927,7 +19927,7 @@ GEOM 6 4 4 2 3 MATERIAL 24 TEXTURE 0 -FLAG 1 +FLAG 11 GEOM 120 108 ; cockpitglass 128 1.217259 1.510586 4.404531 -0.591781 -0.777958 -0.211134 1.242981 1.457264 4.528909 -0.591780 -0.777958 -0.211135 From e86a2114c0271ee503462ad8bfd9221ce003a289 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Tue, 25 Jul 2023 17:45:25 +0300 Subject: [PATCH 04/42] Fixed issue #322 --- OVP/D3D9Client/Scene.cpp | 8 ++++---- OVP/D3D9Client/VVessel.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index 2a0dd6ddd..61e43ecca 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -2511,13 +2511,13 @@ int Scene::RenderShadowMap(D3DXVECTOR3 &pos, D3DXVECTOR3 &ld, float rad, bool bI } } - smap.depth = (mxd - mnd) + 10.0f; + smap.depth = (mxd + rad); - D3DXMatrixOrthoOffCenterRH(&smap.mProj, -rad, rad, rad, -rad, 50.0f, 50.0f + smap.depth); + D3DXMatrixOrthoOffCenterRH(&smap.mProj, -rad, rad, rad, -rad, -rad, smap.depth); - smap.dist = mnd - 55.0f; + smap.dist = mxd; - D3DXVECTOR3 lp = pos + ld * smap.dist; + D3DXVECTOR3 lp = pos - ld * smap.dist; D3DXMatrixLookAtRH(&smap.mView, &lp, &pos, ptr(D3DXVECTOR3(0, 1, 0))); D3DXMatrixMultiply(&smap.mViewProj, &smap.mView, &smap.mProj); diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index 484a4c2ce..a20bb7a30 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -636,8 +636,8 @@ void vVessel::GetMinMaxLightDist(float *mind, float *maxd) D3DXVec3TransformCoord(&bc, ptr(D3DXVECTOR3f4(BBox.bs)), &mWorld); bc -= shd->pos; float x = D3DXVec3Dot(&bc, &(shd->ld)); - *mind = min(*mind, x - shd->rad); - *maxd = max(*maxd, x + shd->rad); + *mind = min(*mind, x - BBox.bs.w); + *maxd = max(*maxd, x + BBox.bs.w); } From fb61851d7449d0398be11145d36210f0f4f690f7 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Wed, 26 Jul 2023 17:06:40 +0300 Subject: [PATCH 05/42] - Added oapiMeshProperty() and oapiLoadAdditionalTextureMaps() functions - Passed the data to a client level - Addressed issue #379 (implemented but not tested) - Cleared up filename and pathname confusion in D3D9Surface.cpp - Cleared up visualization of shadow map (Debug) --- OVP/D3D9Client/D3D9Client.cpp | 52 +++++++++ OVP/D3D9Client/D3D9Client.h | 3 + OVP/D3D9Client/D3D9Surface.cpp | 177 +++++++++++++++++++------------ OVP/D3D9Client/D3D9Surface.h | 8 +- OVP/D3D9Client/Mesh.cpp | 19 ++-- OVP/D3D9Client/Mesh.h | 6 +- OVP/D3D9Client/Scene.cpp | 8 +- OVP/D3D9Client/VVessel.cpp | 2 +- Orbitersdk/include/GraphicsAPI.h | 8 +- Orbitersdk/include/OrbiterAPI.h | 22 +++- Src/Orbiter/OrbiterAPI.cpp | 13 +++ 11 files changed, 235 insertions(+), 83 deletions(-) diff --git a/OVP/D3D9Client/D3D9Client.cpp b/OVP/D3D9Client/D3D9Client.cpp index ddb836442..d215a1a3a 100644 --- a/OVP/D3D9Client/D3D9Client.cpp +++ b/OVP/D3D9Client/D3D9Client.cpp @@ -1469,6 +1469,29 @@ bool D3D9Client::clbkSetMeshProperty(DEVMESHHANDLE hMesh, DWORD prop, DWORD valu return false; } +// ============================================================== + +bool D3D9Client::clbkSetMeshProperty(DEVMESHHANDLE hMesh, MeshProp prp, const oapi::FVECTOR4& value) +{ + D3D9Mesh* mesh = (D3D9Mesh*)hMesh; + switch (prp) { + case MeshProp::BAKED_0: mesh->SetBakedLightLevel(0, value.xyz); return true; + case MeshProp::BAKED_1: mesh->SetBakedLightLevel(1, value.xyz); return true; + case MeshProp::BAKED_2: mesh->SetBakedLightLevel(2, value.xyz); return true; + case MeshProp::BAKED_3: mesh->SetBakedLightLevel(3, value.xyz); return true; + case MeshProp::BAKED_4: mesh->SetBakedLightLevel(4, value.xyz); return true; + case MeshProp::BAKED_5: mesh->SetBakedLightLevel(5, value.xyz); return true; + case MeshProp::BAKED_6: mesh->SetBakedLightLevel(6, value.xyz); return true; + case MeshProp::BAKED_7: mesh->SetBakedLightLevel(7, value.xyz); return true; + case MeshProp::BAKED_8: mesh->SetBakedLightLevel(8, value.xyz); return true; + case MeshProp::BAKED_9: mesh->SetBakedLightLevel(9, value.xyz); return true; + default: + oapiWriteLogV("oapiSetMeshProperty() FAILED: unknown property %u", DWORD(prp)); + break; + } + return false; +} + // ============================================================== // Returns a dev-mesh for a visual @@ -2061,6 +2084,35 @@ SURFHANDLE D3D9Client::clbkLoadTexture(const char *fname, DWORD flags) // ============================================================== +SURFHANDLE D3D9Client::clbkLoadMaps(const char* diff, const char* maps, bool bPath, SURFHANDLE hOld, bool bAll) +{ + char mpath[MAX_PATH]; + + if (diff != NULL && hOld != NULL) { + oapiWriteLog((char*)"oapiLoadAdditionalTextureMaps() FAILED. Used either 'diff' or 'hOld'. The other one must be NULL"); + return NULL; + } + if (maps) { + if (bPath) strcpy_s(mpath, MAX_PATH, maps); + else if (!g_client->TexturePath(maps, mpath)) return NULL; + } + if (diff) { + SURFHANDLE hSrf = NatLoadSurface(diff, OAPISURFACE_TEXTURE | OAPISURFACE_SHARED | OAPISURFACE_DIFFUSE_ONLY, bPath); + if (hSrf && maps) { + if (bAll) NatLoadMaps(SURFACE(hSrf), mpath); + else NatLoadMap(SURFACE(hSrf), mpath); + } + return hSrf; + } + else if (maps) { + if (bAll) NatLoadMaps(SURFACE(hOld), mpath); + else NatLoadMap(SURFACE(hOld), mpath); + } + return hOld; +} + +// ============================================================== + SURFHANDLE D3D9Client::clbkLoadSurface (const char *fname, DWORD attrib, bool bPath) { _TRACE; diff --git a/OVP/D3D9Client/D3D9Client.h b/OVP/D3D9Client/D3D9Client.h index 22701215e..81178eadd 100644 --- a/OVP/D3D9Client/D3D9Client.h +++ b/OVP/D3D9Client/D3D9Client.h @@ -266,6 +266,8 @@ class D3D9Client : public GraphicsClient * \sa oapiCreateSurface(DWORD,DWORD,DWORD) */ SURFHANDLE clbkLoadSurface (const char *fname, DWORD attrib, bool bPath = false); + SURFHANDLE clbkLoadMaps(const char* diff, const char* maps, bool bPath, SURFHANDLE hOld = NULL, bool bAll = true); + /** @@ -361,6 +363,7 @@ class D3D9Client : public GraphicsClient * \default None, returns \e false. */ bool clbkSetMeshProperty (DEVMESHHANDLE hMesh, DWORD property, DWORD value); + bool clbkSetMeshProperty(DEVMESHHANDLE hMesh, MeshProp prp, const oapi::FVECTOR4& value); /** * \brief React to vessel creation diff --git a/OVP/D3D9Client/D3D9Surface.cpp b/OVP/D3D9Client/D3D9Surface.cpp index 0114e9223..aae6aa3a5 100644 --- a/OVP/D3D9Client/D3D9Surface.cpp +++ b/OVP/D3D9Client/D3D9Surface.cpp @@ -1,7 +1,7 @@ // =========================================================================================== // D3D9Surface.cpp // Part of the ORBITER VISUALISATION PROJECT (OVP) -// Dual licensed under GPL v3 and LGPL v3 +// Licensed under LGPL v2 // Copyright (C) 2011 - 2016 Jarmo Nikkanen // =========================================================================================== @@ -20,6 +20,8 @@ using namespace oapi; extern D3D9Client* g_client; +// =============================================================================================== +// void NatCheckFlags(DWORD &flags) { // Append dependend flags @@ -53,34 +55,78 @@ void NatCheckFlags(DWORD &flags) } } -LPDIRECT3DTEXTURE9 NatLoadSpecialTexture(const char* fname, const char* ext) -{ - char path[MAX_PATH]; - char name[MAX_PATH]; - - NatCreateName(name, ARRAYSIZE(name), fname, ext); +// =============================================================================================== +// Load a simple plain texture +// +LPDIRECT3DTEXTURE9 NatLoadTexture(const char* path) +{ LPDIRECT3DTEXTURE9 pTex = NULL; - - if (g_client->TexturePath(name, path)) { - D3DXIMAGE_INFO info; - if (D3DXGetImageInfoFromFileA(path, &info) == S_OK) { + D3DXIMAGE_INFO info; - DWORD Mips = D3DFMT_FROM_FILE; + if (D3DXGetImageInfoFromFileA(path, &info) == S_OK) { - if (Config->TextureMips == 2) Mips = 0; // Autogen all - if (Config->TextureMips == 1 && info.MipLevels == 1) Mips = 0; // Autogen missing + DWORD Mips = D3DFMT_FROM_FILE; - if (S_OK == D3DXCreateTextureFromFileExA(g_client->GetDevice(), path, info.Width, info.Height, Mips, 0, D3DFMT_FROM_FILE, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &pTex)) - { - return pTex; - } + if (Config->TextureMips == 2) Mips = 0; // Autogen all + if (Config->TextureMips == 1 && info.MipLevels == 1) Mips = 0; // Autogen missing + + if (S_OK == D3DXCreateTextureFromFileExA(g_client->GetDevice(), path, info.Width, info.Height, Mips, 0, D3DFMT_FROM_FILE, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &pTex)) + { + return pTex; } } + return NULL; } +// =============================================================================================== +// Load a simple plain texture with map type extension +// +LPDIRECT3DTEXTURE9 NatLoadSpecialTexture(const char* path, const char* ext) +{ + char name[MAX_PATH]; + NatCreateName(name, ARRAYSIZE(name), path, ext); + return NatLoadTexture(name); +} + + +// ====================================================================================== +// Main loading routine for all maps +// +void NatLoadMaps(SurfNative *pNat, const char* path) +{ + pNat->AddMap(MAP_HEAT, NatLoadSpecialTexture(path, "heat")); + pNat->AddMap(MAP_NORMAL, NatLoadSpecialTexture(path, "norm")); + pNat->AddMap(MAP_SPECULAR, NatLoadSpecialTexture(path, "spec")); + pNat->AddMap(MAP_EMISSION, NatLoadSpecialTexture(path, "emis")); + pNat->AddMap(MAP_ROUGHNESS, NatLoadSpecialTexture(path, "rghn")); + pNat->AddMap(MAP_METALNESS, NatLoadSpecialTexture(path, "metal")); + pNat->AddMap(MAP_REFLECTION, NatLoadSpecialTexture(path, "refl")); + pNat->AddMap(MAP_TRANSLUCENCE, NatLoadSpecialTexture(path, "transl")); + pNat->AddMap(MAP_TRANSMITTANCE, NatLoadSpecialTexture(path, "transm")); + pNat->AddMap(MAP_AMBIENT, NatLoadSpecialTexture(path, "bkao")); +} + + +// ====================================================================================== +// Main loading routine for a single map +// +void NatLoadMap(SurfNative* pNat, const char* path) +{ + if (NatIsTypeOf(path, "heat")) { pNat->AddMap(MAP_HEAT, NatLoadTexture(path)); return; } + if (NatIsTypeOf(path, "norm")) { pNat->AddMap(MAP_NORMAL, NatLoadTexture(path)); return; } + if (NatIsTypeOf(path, "spec")) { pNat->AddMap(MAP_SPECULAR, NatLoadTexture(path)); return; } + if (NatIsTypeOf(path, "emis")) { pNat->AddMap(MAP_EMISSION, NatLoadTexture(path)); return; } + if (NatIsTypeOf(path, "rghn")) { pNat->AddMap(MAP_ROUGHNESS, NatLoadTexture(path)); return; } + if (NatIsTypeOf(path, "metal")) { pNat->AddMap(MAP_METALNESS, NatLoadTexture(path)); return; } + if (NatIsTypeOf(path, "refl")) { pNat->AddMap(MAP_REFLECTION, NatLoadTexture(path)); return; } + if (NatIsTypeOf(path, "transl")) { pNat->AddMap(MAP_TRANSLUCENCE, NatLoadTexture(path)); return; } + if (NatIsTypeOf(path, "transm")) { pNat->AddMap(MAP_TRANSMITTANCE, NatLoadTexture(path)); return; } + if (NatIsTypeOf(path, "bkao")) { pNat->AddMap(MAP_AMBIENT, NatLoadTexture(path)); return; } +} + // ====================================================================================== // Main loading routine @@ -95,12 +141,8 @@ SURFHANDLE NatLoadSurface(const char* file, DWORD flags, bool bPath) char path[MAX_PATH]; if (bPath) strcpy_s(path, MAX_PATH, file); - else { - if (!g_client->TexturePath(file, path)) { - return NULL; - } - } - + else if (!g_client->TexturePath(file, path)) return NULL; + DWORD pass = OAPISURFACE_TEXTURE | OAPISURFACE_SHARED; // Load regular texture with additional maps if exists @@ -112,9 +154,9 @@ SURFHANDLE NatLoadSurface(const char* file, DWORD flags, bool bPath) if (D3DXGetImageInfoFromFileA(path, &info) == S_OK) { - if (info.ImageFileFormat == D3DXIFF_JPG) info.Format = D3DFMT_X8R8G8B8; - if (info.ImageFileFormat == D3DXIFF_PNG) info.Format = D3DFMT_X8R8G8B8; - if (info.ImageFileFormat == D3DXIFF_BMP) info.Format = D3DFMT_X8R8G8B8; + if (info.ImageFileFormat == D3DXIFF_JPG) info.Format = D3DFMT_X8R8G8B8, flags |= OAPISURFACE_DIFFUSE_ONLY; + if (info.ImageFileFormat == D3DXIFF_PNG) info.Format = D3DFMT_X8R8G8B8, flags |= OAPISURFACE_DIFFUSE_ONLY; + if (info.ImageFileFormat == D3DXIFF_BMP) info.Format = D3DFMT_X8R8G8B8, flags |= OAPISURFACE_DIFFUSE_ONLY; DWORD Mips = D3DFMT_FROM_FILE; if (Config->TextureMips == 2) Mips = 0; // Autogen all @@ -124,19 +166,13 @@ SURFHANDLE NatLoadSurface(const char* file, DWORD flags, bool bPath) { pNat = new SurfNative(pTex, flags); pNat->SetName(file); - + pNat->SetPath(path); LogBlu("TextureLoaded [%s] PLAIN Mips=%u Format=%u (%u,%u) Flags=0x%X, %s", file, pTex->GetLevelCount(), info.Format, info.Width, info.Height, flags, _PTR(pNat)); - pNat->AddMap(MAP_HEAT, NatLoadSpecialTexture(file, "heat")); - pNat->AddMap(MAP_NORMAL, NatLoadSpecialTexture(file, "norm")); - pNat->AddMap(MAP_SPECULAR, NatLoadSpecialTexture(file, "spec")); - pNat->AddMap(MAP_EMISSION, NatLoadSpecialTexture(file, "emis")); - pNat->AddMap(MAP_ROUGHNESS, NatLoadSpecialTexture(file, "rghn")); - pNat->AddMap(MAP_METALNESS, NatLoadSpecialTexture(file, "metal")); - pNat->AddMap(MAP_REFLECTION, NatLoadSpecialTexture(file, "refl")); - pNat->AddMap(MAP_TRANSLUCENCE, NatLoadSpecialTexture(file, "transl")); - pNat->AddMap(MAP_TRANSMITTANCE, NatLoadSpecialTexture(file, "transm")); - pNat->AddMap(MAP_AMBIENT, NatLoadSpecialTexture(file, "bkao")); + if ((flags & OAPISURFACE_DIFFUSE_ONLY) == 0) + { + NatLoadMaps(pNat, path); + } } else oapiWriteLogV("FAILED: NatLoadSurface(%d)", path); } @@ -198,6 +234,7 @@ SURFHANDLE NatLoadSurface(const char* file, DWORD flags, bool bPath) { SurfNative* pSrf = new SurfNative(pTex, flags); pSrf->SetName(file); + pSrf->SetPath(path); LogBlu("TextureLoaded [%s] Mips=%u, Usage=%u, Format=%u (%u,%u) Flags=0x%X, %s", file, pTex->GetLevelCount(), Usage, Format, info.Width, info.Height, flags, _PTR(pSrf)); return SURFHANDLE(pSrf); } @@ -213,6 +250,7 @@ SURFHANDLE NatLoadSurface(const char* file, DWORD flags, bool bPath) { SurfNative* pSrf = new SurfNative(pSurf, flags); pSrf->SetName(file); + pSrf->SetPath(path); LogBlu("SurfaceLoaded [%s] RENDERTARGET Format=%u (%u,%u) Flags=0x%X %s", file, Format, info.Width, info.Height, flags, _PTR(pSrf)); return SURFHANDLE(pSrf); } @@ -227,22 +265,22 @@ SURFHANDLE NatLoadSurface(const char* file, DWORD flags, bool bPath) // =============================================================================================== // -bool NatSaveSurface(const char* file, LPDIRECT3DRESOURCE9 pResource) +bool NatSaveSurface(const char* path, LPDIRECT3DRESOURCE9 pResource) { LPDIRECT3DDEVICE9 pDev = g_client->GetDevice(); D3DXIMAGE_FILEFORMAT fmt = D3DXIMAGE_FILEFORMAT(0); - if (contains(file, ".dds")) fmt = D3DXIFF_DDS; - if (contains(file, ".bmp")) fmt = D3DXIFF_BMP; - if (contains(file, ".jpg")) fmt = D3DXIFF_JPG; - if (contains(file, ".png")) fmt = D3DXIFF_PNG; + if (contains(path, ".dds")) fmt = D3DXIFF_DDS; + if (contains(path, ".bmp")) fmt = D3DXIFF_BMP; + if (contains(path, ".jpg")) fmt = D3DXIFF_JPG; + if (contains(path, ".png")) fmt = D3DXIFF_PNG; if (pResource->GetType() == D3DRTYPE_SURFACE) { LPDIRECT3DSURFACE9 pSurf = static_cast(pResource); - if (D3DXSaveSurfaceToFileA(file, fmt, pSurf, NULL, NULL) == S_OK) return true; + if (D3DXSaveSurfaceToFileA(path, fmt, pSurf, NULL, NULL) == S_OK) return true; oapiWriteLog((char*)"NatSaveSurface(SURF):"); NatDumpResource(pResource); return false; @@ -256,7 +294,7 @@ bool NatSaveSurface(const char* file, LPDIRECT3DRESOURCE9 pResource) pTex->GetLevelDesc(0, &desc); if (desc.Pool == D3DPOOL_SYSTEMMEM || desc.Usage & D3DUSAGE_DYNAMIC) { - if (D3DXSaveTextureToFileA(file, fmt, pTex, NULL) == S_OK) return true; + if (D3DXSaveTextureToFileA(path, fmt, pTex, NULL) == S_OK) return true; oapiWriteLog((char*)"NatSaveSurface(TEX):"); NatDumpResource(pResource); return false; @@ -274,14 +312,14 @@ bool NatSaveSurface(const char* file, LPDIRECT3DRESOURCE9 pResource) pSrc->Release(); pTgt->Release(); } - if (D3DXSaveTextureToFile(file, fmt, pSys, NULL) == S_OK) { + if (D3DXSaveTextureToFile(path, fmt, pSys, NULL) == S_OK) { pSys->Release(); return true; } pSys->Release(); } - if (D3DXSaveTextureToFileA(file, fmt, pTex, NULL) == S_OK) return true; + if (D3DXSaveTextureToFileA(path, fmt, pTex, NULL) == S_OK) return true; } oapiWriteLog((char*)"NatSaveSurface():"); @@ -501,6 +539,7 @@ SurfNative::SurfNative(LPDIRECT3DRESOURCE9 pRes, DWORD flags, LPDIRECT3DSURFACE9 memset(&DC, 0, sizeof(DC)); strcpy_s(name, sizeof(name), "null"); + strcpy_s(path, sizeof(path), "null"); type = pResource->GetType(); @@ -539,7 +578,8 @@ SurfNative::SurfNative(SurfNative* pOrigin) for (int i = 0; i < MAP_MAX_COUNT; i++) pMap[i] = pOrigin->pMap[i]; - strcpy_s(name, 128, pOrigin->name); + strcpy_s(name, sizeof(name), pOrigin->name); + strcpy_s(path, sizeof(path), pOrigin->path); } @@ -690,12 +730,22 @@ bool SurfNative::IsPowerOfTwo() const // void SurfNative::SetName(const char* n) { - strcpy_s(name, 128, n); + strcpy_s(name, sizeof(name), n); int i = -1; while (name[++i] != 0) if (name[i] == '/') name[i] = '\\'; } +// ----------------------------------------------------------------------------------------------- +// +void SurfNative::SetPath(const char* n) +{ + strcpy_s(path, sizeof(path), n); + int i = -1; + while (path[++i] != 0) if (path[i] == '/') path[i] = '\\'; +} + + // ----------------------------------------------------------------------------------------------- // LPDIRECT3DTEXTURE9 SurfNative::GetGDICache(DWORD Flags) @@ -925,13 +975,6 @@ bool SurfNative::Decompress() if (desc.Format == D3DFMT_DXT5) Format = D3DFMT_A8R8G8B8; if (desc.Format == D3DFMT_DXT3) Format = D3DFMT_A8R8G8B8; - char path[MAX_PATH]; - - if (!g_client->TexturePath(name, path)) { - oapiWriteLogV("SurfNative::Reload() File Not Found [%s]", path); - return false; - } - if (S_OK == D3DXCreateTextureFromFileExA(pDevice, path, desc.Width, desc.Height, Mipmaps, D3DUSAGE_RENDERTARGET, Format, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &pDecomp)) { @@ -963,7 +1006,6 @@ bool SurfNative::Decompress() // bool SurfNative::DeClone() { - char path[MAX_PATH]; if (!IsClone()) return false; else @@ -983,11 +1025,6 @@ bool SurfNative::DeClone() if (desc.Format == D3DFMT_DXT5) Format = D3DFMT_A8R8G8B8; if (desc.Format == D3DFMT_DXT3) Format = D3DFMT_A8R8G8B8; - if (!g_client->TexturePath(name, path)) { - oapiWriteLogV("SurfNative::DeClone() File Not Found [%s]", path); - return false; - } - if (S_OK == D3DXCreateTextureFromFileExA(pDevice, path, desc.Width, desc.Height, Mipmaps, D3DUSAGE_RENDERTARGET, Format, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &pTex)) { @@ -1016,13 +1053,6 @@ void SurfNative::Reload() SAFE_RELEASE(pResource); for (int i = 0; i < ARRAYSIZE(pMap); i++) SAFE_RELEASE(pMap[i]); - char path[MAX_PATH]; - - if (!g_client->TexturePath(name, path)) { - oapiWriteLogV("SurfNative::Reload() File Not Found [%s]", path); - return; - } - if (Flags == OAPISURFACE_TEXTURE) { D3DXIMAGE_INFO info; @@ -1156,6 +1186,15 @@ bool NatCreateName(char* out, int mlen, const char* fname, const char* id) return (p != NULL); } +// ----------------------------------------------------------------------------------------------- +// +bool NatIsTypeOf(const char* fname, const char* id) +{ + char buf[32]; + sprintf_s(buf, 32, "_%s.dds", id); + const char* p = strstr(fname, id); + return (p != NULL); +} // ----------------------------------------------------------------------------------------------- // diff --git a/OVP/D3D9Client/D3D9Surface.h b/OVP/D3D9Client/D3D9Surface.h index a92063b9a..e96cba5e1 100644 --- a/OVP/D3D9Client/D3D9Surface.h +++ b/OVP/D3D9Client/D3D9Surface.h @@ -1,6 +1,6 @@ // ============================================================== // Part of the ORBITER VISUALISATION PROJECT (OVP) -// Dual licensed under GPL v3 and LGPL v3 +// Licensed under LGPL v2 // Copyright (C) 2012 - 2016 Jarmo Nikkanen // ============================================================== @@ -49,6 +49,9 @@ const char* NatPool(D3DPOOL Pool); const char* NatOAPIFlags(DWORD AF); const char* NatOAPIFormat(DWORD PF); void NatDumpResource(LPDIRECT3DRESOURCE9 pResource); +void NatLoadMaps(SurfNative* pNat, const char* file); +void NatLoadMap(SurfNative* pNat, const char* file); +bool NatIsTypeOf(const char*, const char*); #define ERR_DC_NOT_AVAILABLE 0x1 @@ -95,7 +98,9 @@ class SurfNative DWORD* GetClientFlags(); const char* GetName() const { return name; } + const char* GetPath() const { return path; } void SetName(const char*); + void SetPath(const char*); HDC GetDC(); void ReleaseDC(HDC); @@ -135,6 +140,7 @@ class SurfNative // ------------------------------------------------------------------------------- char name[128]; // Surface name + char path[MAX_PATH]; // Surface name with path SURFHANDLE hOrigin; D3DSURFACE_DESC desc; // Surface size and format description D3DRESOURCETYPE type; // Resource type diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index afd5c9ba0..d0c4acded 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -201,6 +201,7 @@ void D3D9Mesh::Null(const char *meshName /* = NULL */) bIsReflective = false; bCanRenderFast = false; bMtrlModidied = false; + bMustRebake = true; Locals = new LightStruct[Config->MaxLights()]; @@ -464,30 +465,34 @@ void D3D9Mesh::ReLoadMeshFromHandle(MESHHANDLE hMesh) // void D3D9Mesh::LoadBakedLights() { + bMustRebake = true; char id[8]; + for (int i = 0; i < nTex; i++) { if (!Tex[i]) continue; if (!Tex[i]->GetMap(MAP_AMBIENT)) continue; - const char* name = Tex[i]->GetName(); - + BakedLights[i].bEnabled = false; + for (int j = 0; j < 10; j++) { - sprintf_s(id, "_bkl%d", j); - BakedLights[i].pMap[j] = NatLoadSpecialTexture(name, id); + sprintf_s(id, "_bkl%d", j); + BakedLights[i].pMap[j] = NatLoadSpecialTexture(Tex[i]->GetPath(), id); + if (BakedLights[i].pMap[j] != NULL) BakedLights[i].bEnabled = true; } HR(D3DXCreateTexture(pDev, Tex[i]->GetWidth(), Tex[i]->GetHeight(), 0, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &BakedLights[i].pCombined)); } - for (int i = 0; i < 10;i++) BakedLightsControl[i] = FVECTOR3(1, 1, 1); + for (int i = 0; i < 10;i++) BakedLightsControl[i] = FVECTOR3(0, 0, 0); } // =========================================================================================== // -void D3D9Mesh::SetBakedLightLevel(int idx, FVECTOR3 level) +void D3D9Mesh::SetBakedLightLevel(int idx, const FVECTOR3 &level) { + bMustRebake = true; if (idx >= 0 && idx <= 9) BakedLightsControl[idx] = level; } @@ -527,6 +532,8 @@ void D3D9Mesh::BakeLights(ImageProcessing* pBaker) SAFE_RELEASE(pSrf); } } + + bMustRebake = false; // Done } diff --git a/OVP/D3D9Client/Mesh.h b/OVP/D3D9Client/Mesh.h index 3da0101e9..12d3a0c86 100644 --- a/OVP/D3D9Client/Mesh.h +++ b/OVP/D3D9Client/Mesh.h @@ -73,8 +73,9 @@ struct _LightList { }; struct _BakedLights { - LPDIRECT3DTEXTURE9 pMap[16]; + LPDIRECT3DTEXTURE9 pMap[10]; LPDIRECT3DTEXTURE9 pCombined; + bool bEnabled; }; class MeshShader : public ShaderClass @@ -212,7 +213,7 @@ class D3D9Mesh : private D3D9Effect void LoadBakedLights(); void BakeLights(ImageProcessing *pBaker); - void SetBakedLightLevel(int idx, FVECTOR3 level); + void SetBakedLightLevel(int idx, const FVECTOR3 &level); void LoadMeshFromHandle(MESHHANDLE hMesh, D3DXVECTOR3 *reorig = NULL, float *scale = NULL); void ReLoadMeshFromHandle(MESHHANDLE hMesh); void ReloadTextures(); @@ -378,6 +379,7 @@ class D3D9Mesh : private D3D9Effect bool bBSRecomputeAll; bool bModulateMatAlpha; // mix material and texture alpha channels bool bGlobalTF; // Mesh has a valid mTransform matrix + bool bMustRebake; // Must run BakeTextures before rendering char name[128]; diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index 61e43ecca..8891348c3 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -1977,7 +1977,7 @@ void Scene::RenderMainScene() float rad = 1.5f; D3DXVECTOR3 ld = sunLight.Dir; - D3DXVECTOR3 pos = Camera.z * rad; + D3DXVECTOR3 pos = Camera.z * rad * 0.75f; RenderShadowMap(pos, ld, rad, true, false); @@ -2157,8 +2157,12 @@ void Scene::RenderMainScene() break; case 8: if (pShdMap) { + D3DSURFACE_DESC desc; + pShdMap->GetLevelDesc(0, &desc); + RECT scr = { 0, 0, long(viewH), long(viewH) }; pSketch = GetPooledSketchpad(SKETCHPAD_2D_OVERLAY); - pSketch->CopyRectNative(pShdMap, NULL, 0, 0); + if (desc.Height>viewH) pSketch->StretchRectNative(pShdMap, NULL, &scr); + else pSketch->CopyRectNative(pShdMap, NULL, 0, 0); pSketch->EndDrawing(); } break; diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index a20bb7a30..100ed3476 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -826,7 +826,7 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass) // if (scn->GetRenderPass() == RENDERPASS_SHADOWMAP) { - meshlist[i].mesh->RenderShadowMap(pWT, pLVP, 0, internalpass); + meshlist[i].mesh->RenderShadowMap(pWT, pLVP, 0, bVC); } else if (scn->GetRenderPass() == RENDERPASS_NORMAL_DEPTH) { diff --git a/Orbitersdk/include/GraphicsAPI.h b/Orbitersdk/include/GraphicsAPI.h index cbe6bcad3..8efa604c0 100644 --- a/Orbitersdk/include/GraphicsAPI.h +++ b/Orbitersdk/include/GraphicsAPI.h @@ -519,6 +519,11 @@ class OAPIFUNC GraphicsClient: public Module { virtual SURFHANDLE clbkLoadSurface (const char *fname, DWORD attrib, bool bPath = false) { return NULL; } + /** + */ + virtual SURFHANDLE clbkLoadMaps(const char* diff, const char* maps, bool bPath, SURFHANDLE hOld = NULL, bool bAll = true) + { return NULL; } + /** * \brief Save the contents of a surface to a formatted image file or to the clipboard * \param surf surface handle (0 for primary render surface) @@ -593,7 +598,8 @@ class OAPIFUNC GraphicsClient: public Module { * if value<>0 modulate (mix) material alpha values with texture alpha maps. * \default None, returns \e false. */ - virtual bool clbkSetMeshProperty (DEVMESHHANDLE hMesh, DWORD property, DWORD value) { return false; } + virtual bool clbkSetMeshProperty(DEVMESHHANDLE hMesh, DWORD property, DWORD value) { return false; } + virtual bool clbkSetMeshProperty(DEVMESHHANDLE hMesh, MeshProp prp, const oapi::FVECTOR4 &value) { return false; } // ================================================================== /// \name Visual object interface diff --git a/Orbitersdk/include/OrbiterAPI.h b/Orbitersdk/include/OrbiterAPI.h index 8f372c420..96fd55f50 100644 --- a/Orbitersdk/include/OrbiterAPI.h +++ b/Orbitersdk/include/OrbiterAPI.h @@ -349,6 +349,7 @@ typedef struct { #define OAPISURFACE_RENDER3D 0x0400 ///< Create a surface that can act as a target for rendering a 3D scene #define OAPISURFACE_ANTIALIAS 0x0800 ///< Create a surface with anti-aliasing the level will depend on launchpad settings. #define OAPISURFACE_SHARED 0x1000 ///< Create a shared resource +#define OAPISURFACE_DIFFUSE_ONLY 0x2000 ///< Load only a regular diffuse texture and ignore additional maps if exists //@} /** @@ -449,7 +450,7 @@ typedef struct { } MATERIAL; -enum MatProp { +enum class MatProp { Diffuse, ///< Material Diffuse color or Albedo depending on shader used. [.rgba] Ambient, ///< Ambient color or Ambien occlusion [.rgb] Specular, ///< Specular color [.rgb] power in [.a] @@ -462,6 +463,12 @@ enum MatProp { SpecialFX ///< Heat map effect control variable in [.r] (i.e. average part temperature) }; +enum class MeshProp { + BAKED_0, BAKED_1, BAKED_2, BAKED_3, BAKED_4, ///< baked light level 0-4 + BAKED_5, BAKED_6, BAKED_7, BAKED_8, BAKED_9, ///< baked light level 5-9 + AMBIENT ///< ambient light level +}; + /** * \brief Kepler orbital elements * @@ -4816,6 +4823,7 @@ OAPIFUNC bool oapiSetMeshProperty (MESHHANDLE hMesh, DWORD property, DWORD value * \sa oapiSetMeshProperty(MESHHANDLE,DWORD,DWORD) */ OAPIFUNC bool oapiSetMeshProperty (DEVMESHHANDLE hMesh, DWORD property, DWORD value); +OAPIFUNC bool oapiSetMeshProperty (DEVMESHHANDLE hMesh, MeshProp prop, const oapi::FVECTOR4 &value); // Particle functions /** @@ -5482,6 +5490,18 @@ OAPIFUNC SURFHANDLE oapiCreateSurfaceEx (int width, int height, DWORD attrib); */ OAPIFUNC SURFHANDLE oapiLoadSurfaceEx(const char* fname, DWORD attrib, bool bPath = false); + /** + * \brief Load a diffuse/albedo texture and additional texture maps from a separate sources + * \param diff difuse/albedo texture file name. If NULL, hOld must be specified + * \param maps base name for texture maps, if NULL only diffuse is loaded. + * \param bPath if 'true' then 'fname' must contain absolute path to a file. If 'false' a normal Orbiter texture search path is used. + * \param hOld handle to an existing diffuse texture to receive additional maps, or NULL. + * \param bAll if true, auto load all existing additional maps. If false, load and add a simgle map. + * \return Surface handle for the loaded texture, or NULL in a case of an error. + * \note A surface must always have a base diffuse texture. + */ +OAPIFUNC SURFHANDLE oapiLoadAdditionalTextureMaps(const char* diff, const char* maps = NULL, bool bPath = false, SURFHANDLE hOld = NULL, bool bAll = true); + /** * \brief Create a surface from a bitmap. Bitmap surfaces are typically used for blitting * operations during instrument panel redraws. diff --git a/Src/Orbiter/OrbiterAPI.cpp b/Src/Orbiter/OrbiterAPI.cpp index 80e7afe05..ef574cfb2 100644 --- a/Src/Orbiter/OrbiterAPI.cpp +++ b/Src/Orbiter/OrbiterAPI.cpp @@ -1419,6 +1419,12 @@ DLLEXPORT DWORD oapiMeshTextureCount (MESHHANDLE hMesh) return ((Mesh*)hMesh)->nTexture(); } +DLLEXPORT void oapiMeshProperty(DEVMESHHANDLE hMesh, MeshProp prp, const oapi::FVECTOR4 &value) +{ + oapi::GraphicsClient* gc = g_pOrbiter->GetGraphicsClient(); + if (gc) gc->clbkSetMeshProperty(hMesh, prp, value); +} + DLLEXPORT SURFHANDLE oapiGetTextureHandle (MESHHANDLE hMesh, DWORD texidx) { Mesh *mesh = (Mesh*)hMesh; @@ -1439,6 +1445,13 @@ DLLEXPORT SURFHANDLE oapiLoadSurfaceEx(const char* fname, DWORD attrib, bool bPa else return NULL; } +DLLEXPORT SURFHANDLE oapiLoadAdditionalTextureMaps(const char* diff, const char* maps, bool bPath, SURFHANDLE hOld, bool bAll) +{ + oapi::GraphicsClient* gc = g_pOrbiter->GetGraphicsClient(); + if (gc) return gc->clbkLoadMaps(diff, maps, bPath, hOld, bAll); + else return NULL; +} + DLLEXPORT void oapiReleaseTexture (SURFHANDLE hTex) { oapi::GraphicsClient *gc = g_pOrbiter->GetGraphicsClient(); From 47eec6dc6361223aae99579136ee25a712ada7f6 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Wed, 26 Jul 2023 17:37:41 +0300 Subject: [PATCH 06/42] Fixed oapiLoadAdditionalMaps() for D3D7 --- Orbitersdk/include/GraphicsAPI.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Orbitersdk/include/GraphicsAPI.h b/Orbitersdk/include/GraphicsAPI.h index 8efa604c0..b7512b1e9 100644 --- a/Orbitersdk/include/GraphicsAPI.h +++ b/Orbitersdk/include/GraphicsAPI.h @@ -522,7 +522,9 @@ class OAPIFUNC GraphicsClient: public Module { /** */ virtual SURFHANDLE clbkLoadMaps(const char* diff, const char* maps, bool bPath, SURFHANDLE hOld = NULL, bool bAll = true) - { return NULL; } + { + return clbkLoadTexture(diff); + } /** * \brief Save the contents of a surface to a formatted image file or to the clipboard From 8d7804459e4be57316984f8c13ee764f58b985ac Mon Sep 17 00:00:00 2001 From: jarmonik Date: Wed, 26 Jul 2023 22:49:41 +0300 Subject: [PATCH 07/42] Work in progress --- OVP/D3D9Client/MaterialMgr.cpp | 3 ++- OVP/D3D9Client/Mesh.cpp | 9 +++++-- OVP/D3D9Client/shaders/BakedVC.fx | 30 +++++++++-------------- OVP/D3D9Client/shaders/D3D9Client.fx | 28 +++++++++++++++++++++ OVP/D3D9Client/shaders/Metalness.fx | 1 + OVP/D3D9Client/shaders/PreBakeLights.hlsl | 3 ++- OVP/D3D9Client/shaders/Vessel.fx | 15 ++++++++++++ Orbitersdk/include/DrawAPI.h | 10 ++++++++ 8 files changed, 76 insertions(+), 23 deletions(-) diff --git a/OVP/D3D9Client/MaterialMgr.cpp b/OVP/D3D9Client/MaterialMgr.cpp index d04e93f50..0a3ebac94 100644 --- a/OVP/D3D9Client/MaterialMgr.cpp +++ b/OVP/D3D9Client/MaterialMgr.cpp @@ -23,8 +23,9 @@ MatMgr::MatMgr(class vObject *v, class D3D9Client *_gc) ResetCamera(0); - Shaders.push_back(SHADER("PBR-Old",SHADER_NULL)); + Shaders.push_back(SHADER("PBR-Old", SHADER_NULL)); Shaders.push_back(SHADER("Metalness", SHADER_METALNESS)); + Shaders.push_back(SHADER("BakedVC", SHADER_BAKED_VC)); } diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index d0c4acded..41e57f87a 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -492,8 +492,12 @@ void D3D9Mesh::LoadBakedLights() // void D3D9Mesh::SetBakedLightLevel(int idx, const FVECTOR3 &level) { - bMustRebake = true; - if (idx >= 0 && idx <= 9) BakedLightsControl[idx] = level; + if (idx >= 0 && idx <= 9) { + if (BakedLightsControl[idx] != level) { + BakedLightsControl[idx] = level; + bMustRebake = true; + } + } } @@ -502,6 +506,7 @@ void D3D9Mesh::SetBakedLightLevel(int idx, const FVECTOR3 &level) void D3D9Mesh::BakeLights(ImageProcessing* pBaker) { if (!pBaker->IsOK()) return; + if (!bMustRebake) return; DWORD flags = IPF_POINT; FVECTOR3 control[10]; diff --git a/OVP/D3D9Client/shaders/BakedVC.fx b/OVP/D3D9Client/shaders/BakedVC.fx index 9e2fccb7c..7410789b6 100644 --- a/OVP/D3D9Client/shaders/BakedVC.fx +++ b/OVP/D3D9Client/shaders/BakedVC.fx @@ -16,22 +16,20 @@ float4 BakedVC_PS(float4 sc : VPOS, PBRData frg) : COLOR float3 nrmT; float3 nrmW; float3 cEmis; - //float4 cSpecularMap; float4 cDiff; - //float fHeat; float fSmth, fMetal; // ====================================================================== // Start fetching texture data // ====================================================================== - if (gTextured) cDiff = tex2D(WrapS, frg.tex0.xy); - else cDiff = 1; - // Fetch a normal map // if (gCfg.Norm) nrmT = tex2D(Nrm0S, frg.tex0.xy).rgb; + if (gTextured) cDiff = tex2D(WrapS, frg.tex0.xy); + else cDiff = 1; + // Fetch Smoothness map (i.e. *_rghn.dds) // if (gCfg.Rghn) fSmth = tex2D(RghnS, frg.tex0.xy).g; @@ -47,21 +45,21 @@ float4 BakedVC_PS(float4 sc : VPOS, PBRData frg) : COLOR if (gCfg.Emis) cEmis = tex2D(EmisS, frg.tex0.xy).rgb; else cEmis = 0; - // Sample specular map - // - //if (gCfg.Spec) cSpecularMap = tex2D(SpecS, frg.tex0.xy).rgba; + float3 cBL = 0; + float3 cBAO = 0; + + if (gCfg.Baked) { + cBL = tex2D(BakedLightS, frg.tex0.xy).rgb; + cBAO = tex2D(BakedAOS, frg.tex0.xy).rgb; + } - // Fetch Heat map - // - //if (gCfg.Heat) fHeat = saturate((tex2D(HeatS, frg.tex0.xy).g) - 1.0f + (gMtrl.specialfx.x * gMtrl.specialfx.x * gMtrl.specialfx.x)); - //else fHeat = (gMtrl.specialfx.x * gMtrl.specialfx.x * gMtrl.specialfx.x); // ---------------------------------------------------------------------- // Now do other calculations while textures are being fetched // ---------------------------------------------------------------------- float3 camW = normalize(frg.camW); - float3 cSun = gSun.Color * lerp(float3(1.1, 1.1, 0.9), float3(1,1,1), saturate(gRadius[3]*2e-5)); + float3 cSun = gSun.Color; // ====================================================================== @@ -118,26 +116,20 @@ float4 BakedVC_PS(float4 sc : VPOS, PBRData frg) : COLOR /* #if defined(_ENVMAP) - if (gEnvMapEnable) { - // ====================================================================== // Sample Env Map SampleEnvMap(cEnv, dCN, fRgh, fMetal, rflW, nrmW); } - // ====================================================================== // Sample Irradiance Map float3 cAmbient = Paraboloidal_LVLH(IrradS, nrmW).rgb; cAmbient *= cAmbient; - //cAmbient = saturate(cAmbient * (1.0f + 15.0f * gNightTime)); // Apply base ambient light cAmbient = max(cAmbient, gSun.Ambient); #else - #endif - cAmbient *= (1.0f - fMetal); // No ambient for metals */ diff --git a/OVP/D3D9Client/shaders/D3D9Client.fx b/OVP/D3D9Client/shaders/D3D9Client.fx index 471df002a..b94456ab7 100644 --- a/OVP/D3D9Client/shaders/D3D9Client.fx +++ b/OVP/D3D9Client/shaders/D3D9Client.fx @@ -69,6 +69,7 @@ struct Flow bool Norm; // Enable normal map bool Metl; // Enable metalness map bool Heat; // Enable heat map + bool Baked; // Enable pre-baked maps }; @@ -166,6 +167,8 @@ uniform extern texture gTranslMap; // Translucence Map uniform extern texture gTransmMap; // Transmittance Map uniform extern texture gShadowMap; // Shadow Map uniform extern texture gIrradianceMap; // Irradiance Map +uniform extern texture gAmbientMap; // Baked Ambient occlusion map +uniform extern texture gCombinedMap; // Combined baked light map // Legacy Atmosphere -------------------------------------------------------- @@ -320,6 +323,31 @@ sampler EmisS = sampler_state // Primary Mesh texture sampler AddressV = WRAP; }; +sampler BakedLightS = sampler_state // Primary Mesh texture sampler +{ + Texture = ; + MinFilter = ANISOTROPIC; + MagFilter = LINEAR; + MipFilter = LINEAR; + MaxAnisotropy = ANISOTROPY_MACRO; + MipMapLODBias = 0; + AddressU = WRAP; + AddressV = WRAP; +}; + +sampler BakedAOS = sampler_state // Primary Mesh texture sampler +{ + Texture = ; + MinFilter = ANISOTROPIC; + MagFilter = LINEAR; + MipFilter = LINEAR; + MaxAnisotropy = ANISOTROPY_MACRO; + MipMapLODBias = 0; + AddressU = WRAP; + AddressV = WRAP; +}; + + sampler ReflS = sampler_state // Primary Mesh texture sampler { Texture = ; diff --git a/OVP/D3D9Client/shaders/Metalness.fx b/OVP/D3D9Client/shaders/Metalness.fx index 618ba0b61..12665eb34 100644 --- a/OVP/D3D9Client/shaders/Metalness.fx +++ b/OVP/D3D9Client/shaders/Metalness.fx @@ -126,6 +126,7 @@ void Transmittance(in out float4 cDiff, float uLN, float uLC, float2 uv, float3 cDiff.rgb += cTransm.rgb * (sunSpotFromBehind * cSun); } +#include "BakedVC.fx" // ============================================================================ // A Shader for a typical "Metalness" PBR workflow. diff --git a/OVP/D3D9Client/shaders/PreBakeLights.hlsl b/OVP/D3D9Client/shaders/PreBakeLights.hlsl index e02cf327b..2f56a1608 100644 --- a/OVP/D3D9Client/shaders/PreBakeLights.hlsl +++ b/OVP/D3D9Client/shaders/PreBakeLights.hlsl @@ -19,7 +19,8 @@ float3 LightFX(float3 c) return c * 1.2f * rsqrt(2 + q * q); } - +// Combine multiple baked lightmaps into a single map +// float4 PSMain(float x : TEXCOORD0, float y : TEXCOORD1) : COLOR { float3 color = 0; diff --git a/OVP/D3D9Client/shaders/Vessel.fx b/OVP/D3D9Client/shaders/Vessel.fx index ea4691f5b..ff73fbd36 100644 --- a/OVP/D3D9Client/shaders/Vessel.fx +++ b/OVP/D3D9Client/shaders/Vessel.fx @@ -25,6 +25,7 @@ inline float cmax(float3 color) // Must be included here #include "Metalness.fx" + // ============================================================================ // Vertex shader for physics based rendering // @@ -315,6 +316,7 @@ technique VesselTech DestBlend = InvSrcAlpha; ZWriteEnable = true; } + pass P4 { vertexShader = compile vs_3_0 MetalnessVS(); @@ -327,4 +329,17 @@ technique VesselTech DestBlend = InvSrcAlpha; ZWriteEnable = true; } + + pass P5 + { + vertexShader = compile vs_3_0 MetalnessVS(); + pixelShader = compile ps_3_0 BakedVC_PS(); + + AlphaBlendEnable = true; + BlendOp = Add; + ZEnable = true; + SrcBlend = SrcAlpha; + DestBlend = InvSrcAlpha; + ZWriteEnable = true; + } } diff --git a/Orbitersdk/include/DrawAPI.h b/Orbitersdk/include/DrawAPI.h index 1f7a303dd..c60cc7218 100644 --- a/Orbitersdk/include/DrawAPI.h +++ b/Orbitersdk/include/DrawAPI.h @@ -335,6 +335,16 @@ namespace oapi { return FVECTOR3(-x, -y, -z); } + inline bool operator== (const FVECTOR3& f) const + { + return x == f.x && y == f.y && z == f.z; + } + + inline bool operator!= (const FVECTOR3& f) const + { + return x != f.x || y != f.y || z != f.z; + } + #ifdef D3D9CLIENT_EXPORTS inline operator D3DXVECTOR3() const { From ce9fd0a3a023a0521fdf91803089943e43662d40 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Thu, 27 Jul 2023 17:26:42 +0300 Subject: [PATCH 08/42] -Added a baked lights test control slider to debug controls Dialog -Activated pre-bake process --- OVP/D3D9Client/D3D9Client.rc | 19 +++++++----- OVP/D3D9Client/DebugControls.cpp | 50 ++++++++++++++++++++++++++++++- OVP/D3D9Client/Mesh.cpp | 25 +++++++++++++--- OVP/D3D9Client/Mesh.h | 6 ++-- OVP/D3D9Client/Scene.cpp | 1 + OVP/D3D9Client/VVessel.cpp | 16 ++++++++++ OVP/D3D9Client/VVessel.h | 1 + OVP/D3D9Client/resource.h | 2 ++ OVP/D3D9Client/shaders/BakedVC.fx | 5 ++-- 9 files changed, 106 insertions(+), 19 deletions(-) diff --git a/OVP/D3D9Client/D3D9Client.rc b/OVP/D3D9Client/D3D9Client.rc index 11d3a4943..03304b096 100644 --- a/OVP/D3D9Client/D3D9Client.rc +++ b/OVP/D3D9Client/D3D9Client.rc @@ -34,14 +34,14 @@ FONT 8, "Ms Shell Dlg" LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK -IDD_D3D9MESHDEBUG DIALOG 0, 0, 374, 428 +IDD_D3D9MESHDEBUG DIALOG 0, 0, 374, 465 STYLE DS_3DLOOK | DS_CENTER | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_THICKFRAME | WS_SYSMENU EXSTYLE WS_EX_WINDOWEDGE CAPTION "D3D9 Debug Controls" FONT 8, "Ms Shell Dlg" { GROUPBOX "Mesh Options", IDC_DBG_MESHGRP, 5, 166, 176, 60, 0, WS_EX_LEFT - PUSHBUTTON "Close", IDCANCEL, 127, 393, 51, 14, 0, WS_EX_LEFT + PUSHBUTTON "Close", IDCANCEL, 124, 429, 51, 14, 0, WS_EX_LEFT PUSHBUTTON "Open", IDC_DBG_OPEN, 202, 169, 30, 14, 0, WS_EX_LEFT PUSHBUTTON "Execute", IDC_DBG_EXECUTE, 305, 282, 56, 14, 0, WS_EX_LEFT LTEXT "Selected Visual: Cape Canaveral", IDC_DBG_VISUAL, 7, 5, 104, 8, SS_LEFT, WS_EX_LEFT @@ -108,13 +108,13 @@ FONT 8, "Ms Shell Dlg" LTEXT "Fa:", IDC_STATIC, 267, 264, 11, 8, SS_LEFT, WS_EX_LEFT LTEXT "Noise:", IDC_STATIC, 205, 264, 21, 8, SS_LEFT, WS_EX_LEFT CONTROL "", IDC_DBG_MATADJ, TRACKBAR_CLASS, WS_TABSTOP | TBS_BOTH | TBS_NOTICKS, 20, 282, 156, 14, WS_EX_LEFT - PUSHBUTTON "Save materials", IDC_DBG_MATSAVE, 8, 393, 51, 14, 0, WS_EX_LEFT + PUSHBUTTON "Save materials", IDC_DBG_MATSAVE, 5, 429, 51, 14, 0, WS_EX_LEFT PUSHBUTTON "Create kernel", IDC_DBG_KERNEL, 310, 25, 47, 14, 0, WS_EX_LEFT - PUSHBUTTON "Data window", IDC_DBG_DATAWND, 8, 410, 50, 14, 0, WS_EX_LEFT + PUSHBUTTON "Data window", IDC_DBG_DATAWND, 5, 446, 50, 14, 0, WS_EX_LEFT PUSHBUTTON "Save envmap", IDC_DBG_ENVSAVE, 205, 128, 60, 12, 0, WS_EX_LEFT - PUSHBUTTON ">>>", IDC_DBG_MORE, 127, 410, 50, 14, 0, WS_EX_LEFT - PUSHBUTTON "Reload Shader", IDC_DBG_RELOADSHD, 63, 410, 60, 14, 0, WS_EX_LEFT - PUSHBUTTON "Reload Textures", IDC_DBG_RELOADTEX, 63, 394, 60, 14, 0, WS_EX_LEFT + PUSHBUTTON ">>>", IDC_DBG_MORE, 124, 446, 50, 14, 0, WS_EX_LEFT + PUSHBUTTON "Reload Shader", IDC_DBG_RELOADSHD, 60, 446, 60, 14, 0, WS_EX_LEFT + PUSHBUTTON "Reload Textures", IDC_DBG_RELOADTEX, 60, 430, 60, 14, 0, WS_EX_LEFT LTEXT "Texture: None", IDC_DBG_TEXTURE, 10, 352, 168, 10, SS_LEFT, WS_EX_LEFT AUTOCHECKBOX "Pick", IDC_DBG_PICK, 120, 147, 30, 8, 0, WS_EX_LEFT LTEXT "Mesh: None", IDC_DBG_MESHNAME, 10, 363, 168, 10, SS_LEFT, WS_EX_LEFT @@ -125,7 +125,10 @@ FONT 8, "Ms Shell Dlg" AUTOCHECKBOX "Use and Save the property", IDC_DBG_DEFINED, 20, 335, 101, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Extend material range", IDC_DBG_EXTEND, 20, 321, 84, 8, 0, WS_EX_LEFT AUTOCHECKBOX "FPS Limiter", IDC_DBG_FPSLIM, 205, 25, 51, 8, 0, WS_EX_LEFT - PUSHBUTTON "Export textures", IDC_DBG_EXPTEX, 315, 410, 52, 14, 0, WS_EX_LEFT + PUSHBUTTON "Export textures", IDC_DBG_EXPTEX, 315, 445, 52, 14, 0, WS_EX_LEFT + COMBOBOX IDC_DBG_BKLID, 10, 406, 50, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT + GROUPBOX "Baked Lights", 0, 5, 394, 175, 30, 0, WS_EX_LEFT + CONTROL "", IDC_DBG_BKLADJ, TRACKBAR_CLASS, WS_TABSTOP | TBS_BOTH | TBS_NOTICKS, 64, 404, 115, 15, WS_EX_LEFT } diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index 42a4da3f7..04a069a3b 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -34,6 +34,7 @@ extern D3D9Client *g_client; namespace DebugControls { +int bkl_id = -1; DWORD dwGFX, dwCmd, nMesh, nGroup, sMesh, sGroup, debugFlags, dspMode, camMode, SelColor, sEmitter; double camSpeed; float cpr, cpg, cpb, cpa; @@ -452,14 +453,35 @@ void OpenDlgClbk(void *context) SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"ScreenDepth"); SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"Normals"); SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"LightVisbil."); + SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"BakedLightMap"); SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_SETCURSEL, 0, 0); + SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_RESETCONTENT, 0, 0); + SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"Baked_0"); + SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"Baked_1"); + SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"Baked_2"); + SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"Baked_3"); + SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"Baked_4"); + SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"Baked_5"); + SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"Baked_6"); + SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"Baked_7"); + SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"Baked_8"); + SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"Baked_9"); + SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"Ambient"); + SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_SETCURSEL, 0, 0); + SetWindowText(GetDlgItem(hDlg, IDC_DBG_VARA), "1.3"); SetWindowText(GetDlgItem(hDlg, IDC_DBG_VARB), "0.01"); SetWindowText(GetDlgItem(hDlg, IDC_DBG_VARC), "0.00"); - // Speed slider + // BakedLights slider + SendDlgItemMessage(hDlg, IDC_DBG_BKLADJ, TBM_SETRANGEMAX, 1, 255); + SendDlgItemMessage(hDlg, IDC_DBG_BKLADJ, TBM_SETRANGEMIN, 1, 0); + SendDlgItemMessage(hDlg, IDC_DBG_BKLADJ, TBM_SETTICFREQ, 1, 0); + SendDlgItemMessage(hDlg, IDC_DBG_BKLADJ, TBM_SETPOS, 1, 0); + + // Resolution bias slider SendDlgItemMessage(hDlg, IDC_DBG_RESBIAS, TBM_SETRANGEMAX, 1, 10); SendDlgItemMessage(hDlg, IDC_DBG_RESBIAS, TBM_SETRANGEMIN, 1, -10); SendDlgItemMessage(hDlg, IDC_DBG_RESBIAS, TBM_SETTICFREQ, 1, 0); @@ -1294,6 +1316,21 @@ void SetupMeshGroups() InitMatList(mesh->GetDefaultShader()); } + +// ============================================================================================= +// +void UpdateBakedLights(float lvl) +{ + D3D9Mesh* mesh = (class D3D9Mesh*)vObj->GetMesh(sMesh); + if (mesh) { + if (bkl_id < 10 && bkl_id >= 0) { + mesh->SetBakedLightLevel(bkl_id, FVECTOR3(lvl, lvl, lvl)); + } + if (bkl_id == 10) mesh->SetAmbientColor(FVECTOR3(lvl, lvl, lvl)); + } +} + + // ============================================================================================= // double GetVisualSize() @@ -1817,6 +1854,11 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) UpdateColorSlider(pos); UpdateMaterialDisplay(); } + + if (HWND(lParam) == GetDlgItem(hWnd, IDC_DBG_BKLADJ)) { + if (pos == 0) pos = WORD(SendDlgItemMessage(hDlg, IDC_DBG_BKLADJ, TBM_GETPOS, 0, 0)); + float val = float(pos) / 255.0f; + } } return false; } @@ -1944,6 +1986,12 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } break; + case IDC_DBG_BKLID: + if (HIWORD(wParam) == CBN_SELCHANGE) { + bkl_id = int(SendDlgItemMessage(hDlg, IDC_DBG_BKLID, CB_GETCURSEL, 0, 0)); + } + break; + case IDC_DBG_DISPLAY: if (HIWORD(wParam)==CBN_SELCHANGE) dspMode = DWORD(SendDlgItemMessage(hWnd, IDC_DBG_DISPLAY, CB_GETCURSEL, 0, 0)); break; diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index 41e57f87a..28e7106d3 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -471,8 +471,6 @@ void D3D9Mesh::LoadBakedLights() for (int i = 0; i < nTex; i++) { if (!Tex[i]) continue; - if (!Tex[i]->GetMap(MAP_AMBIENT)) continue; - BakedLights[i].bEnabled = false; for (int j = 0; j < 10; j++) @@ -506,6 +504,7 @@ void D3D9Mesh::SetBakedLightLevel(int idx, const FVECTOR3 &level) void D3D9Mesh::BakeLights(ImageProcessing* pBaker) { if (!pBaker->IsOK()) return; + if (DefShader != SHADER_BAKED_VC) return; if (!bMustRebake) return; DWORD flags = IPF_POINT; @@ -583,7 +582,6 @@ void D3D9Mesh::LoadMeshFromHandle(MESHHANDLE hMesh, D3DXVECTOR3 *reorig, float * UpdateBoundingBox(); CheckMeshStatus(); - LoadBakedLights(); } // =========================================================================================== @@ -1382,7 +1380,7 @@ void D3D9Mesh::SetTexTune(const D3D9Tune *pT, DWORD idx) // =========================================================================================== // -void D3D9Mesh::SetAmbientColor(D3DCOLOR c) +void D3D9Mesh::SetAmbientColor(const FVECTOR3& c) { _TRACE; if (!IsOK()) return; @@ -1499,6 +1497,25 @@ void D3D9Mesh::CheckMeshStatus() bIsReflective = true; for (DWORD g = 0; g < nGrp; g++) Grp[g].Shader = SHADER_METALNESS; } + + if (DefShader == SHADER_BAKED_VC) { + bIsReflective = true; + for (DWORD g = 0; g < nGrp; g++) Grp[g].Shader = SHADER_BAKED_VC; + } +} + + +// =========================================================================================== +// +void D3D9Mesh::SetDefaultShader(WORD shader) +{ + DefShader = shader; + bMtrlModidied = true; + CheckMeshStatus(); + + if (shader == SHADER_BAKED_VC) { + LoadBakedLights(); + } } diff --git a/OVP/D3D9Client/Mesh.h b/OVP/D3D9Client/Mesh.h index 12d3a0c86..2cebba2ee 100644 --- a/OVP/D3D9Client/Mesh.h +++ b/OVP/D3D9Client/Mesh.h @@ -222,7 +222,7 @@ class D3D9Mesh : private D3D9Effect void SetName(UINT idx); const char * GetName() const { return name; } - void SetDefaultShader(WORD shader) { DefShader = shader; bMtrlModidied = true; } + void SetDefaultShader(WORD shader); WORD GetDefaultShader() const { return DefShader; } void SetClass(DWORD cl) { vClass = cl; } @@ -323,7 +323,7 @@ class D3D9Mesh : private D3D9Effect void UpdateBoundingBox(); void BoundingBox(const NMVERTEX *vtx, DWORD n, D9BBox *box); - void SetAmbientColor(D3DCOLOR c); + void SetAmbientColor(const FVECTOR3& c); void SetupFog(const LPD3DXMATRIX pW); void ResetRenderStatus(); @@ -370,7 +370,7 @@ class D3D9Mesh : private D3D9Effect D3DXMATRIX mTransformInv; D3DXMATRIX *pGrpTF; D3D9Sun sunLight; - D3DCOLOR cAmbient; + FVECTOR3 cAmbient; LightStruct null_light; _LightList LightList[MAX_SCENE_LIGHTS]; diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index 8891348c3..7fa5b6c7b 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -1390,6 +1390,7 @@ void Scene::RenderMainScene() vVessel* vV = (vVessel*)pv->vobj; RenderList.push_back(vV); vV->bStencilShadow = true; + vV->BakeLights(pBakeLights); } } diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index 100ed3476..a4376f4a5 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -18,6 +18,7 @@ #include "DebugControls.h" #include "D3D9Util.h" #include "MaterialMgr.h" +#include "IProcess.h" using namespace oapi; @@ -669,6 +670,21 @@ bool vVessel::GetVCPos(D3DXVECTOR3* out, float* rad) } +// ============================================================================================ +// +void vVessel::BakeLights(ImageProcessing *pBaker) +{ + for (int i = 0; i < nmesh; i++) + { + if (!meshlist[i].mesh) continue; + if (meshlist[i].vismode & MESHVIS_VC) + { + meshlist[i].mesh->BakeLights(pBaker); + } + } +} + + // ============================================================================================ // void vVessel::NoVC() diff --git a/OVP/D3D9Client/VVessel.h b/OVP/D3D9Client/VVessel.h index 53ed453a9..41b0845f9 100644 --- a/OVP/D3D9Client/VVessel.h +++ b/OVP/D3D9Client/VVessel.h @@ -72,6 +72,7 @@ class vVessel: public vObject { int GetMatrixTransform(gcCore::MatrixId matrix_id, DWORD mesh, DWORD group, FMATRIX4 *pMat); int SetMatrixTransform(gcCore::MatrixId matrix_id, DWORD mesh, DWORD group, const FMATRIX4 *pMat); bool GetVCPos(D3DXVECTOR3* out, float* rad); + void BakeLights(ImageProcessing* pBaker); void NoVC(); void UpdateBoundingBox(); bool IsInsideShadows(); diff --git a/OVP/D3D9Client/resource.h b/OVP/D3D9Client/resource.h index 349e5cad2..981195cac 100644 --- a/OVP/D3D9Client/resource.h +++ b/OVP/D3D9Client/resource.h @@ -219,3 +219,5 @@ #define IDC_EAQUALITY 3035 #define IDC_ATM_TRLIGHTSHAD 3036 #define IDC_ATD_TRLIGHTSHAD 3037 +#define IDC_DBG_BKLID 3038 +#define IDC_DBG_BKLADJ 3039 diff --git a/OVP/D3D9Client/shaders/BakedVC.fx b/OVP/D3D9Client/shaders/BakedVC.fx index 7410789b6..f1760421c 100644 --- a/OVP/D3D9Client/shaders/BakedVC.fx +++ b/OVP/D3D9Client/shaders/BakedVC.fx @@ -83,9 +83,8 @@ float4 BakedVC_PS(float4 sc : VPOS, PBRData frg) : COLOR // Typical compatibility requirements // ====================================================================== + cDiff.a = saturate(cDiff.a * gMtrlAlpha); if (gNoColor) cDiff.rgb = 1; - cDiff = saturate(cDiff * float4(gMtrl.diffuse.rgb, gMtrlAlpha)); - // ====================================================================== // Some Precomputations @@ -182,7 +181,7 @@ float4 BakedVC_PS(float4 sc : VPOS, PBRData frg) : COLOR // Add a faint diffuse hue for rough metals. Rough metal doesn't look good if it's totally black fA += fRgh * fMetal * 0.05f; - float3 zD = cDiff.rgb * fA * LightFXSq(Sq(cSun * fR * dLN) + Sq(gMtrl.emissive.rgb)); + float3 zD = cDiff.rgb * fA * LightFXSq(gMtrl.diffuse.rgb * (Sq(cSun * fR * dLN)) + Sq(gMtrl.emissive.rgb)); // Combine specular terms float3 zS = cS * (cSun * dLN); From 925a4ed75302a1bd983805fb66f7f052f36283ca Mon Sep 17 00:00:00 2001 From: jarmonik Date: Fri, 28 Jul 2023 11:58:05 +0300 Subject: [PATCH 09/42] - Pre-Bake is now in a working condition. Baked maps are fed to the shader and are operational. - Fixed bugs from IProcess.cpp - Baked light sources can be adjusted from debug controls. --- OVP/D3D9Client/D3D9Surface.cpp | 1 + OVP/D3D9Client/D3D9Util.h | 6 +-- OVP/D3D9Client/DebugControls.cpp | 12 ++++++ OVP/D3D9Client/DebugControls.h | 2 + OVP/D3D9Client/IProcess.cpp | 19 +++++---- OVP/D3D9Client/Mesh.cpp | 70 ++++++++++++++++++++++--------- OVP/D3D9Client/Mesh.h | 2 +- OVP/D3D9Client/Scene.cpp | 12 +++++- OVP/D3D9Client/shaders/BakedVC.fx | 2 +- 9 files changed, 92 insertions(+), 34 deletions(-) diff --git a/OVP/D3D9Client/D3D9Surface.cpp b/OVP/D3D9Client/D3D9Surface.cpp index aae6aa3a5..349d4ed70 100644 --- a/OVP/D3D9Client/D3D9Surface.cpp +++ b/OVP/D3D9Client/D3D9Surface.cpp @@ -73,6 +73,7 @@ LPDIRECT3DTEXTURE9 NatLoadTexture(const char* path) if (S_OK == D3DXCreateTextureFromFileExA(g_client->GetDevice(), path, info.Width, info.Height, Mips, 0, D3DFMT_FROM_FILE, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &pTex)) { + LogBlu("TextureLoaded [%s] Mips=%u Format=%u (%u,%u)", RemovePath(path), pTex->GetLevelCount(), info.Format, info.Width, info.Height); return pTex; } } diff --git a/OVP/D3D9Client/D3D9Util.h b/OVP/D3D9Client/D3D9Util.h index 156b941f3..ffc311684 100644 --- a/OVP/D3D9Client/D3D9Util.h +++ b/OVP/D3D9Client/D3D9Util.h @@ -74,10 +74,8 @@ const char *_PTR(const void *p); // Required only with c++20 without /permissive flag -// template -// T* ptr(T&& x) { return &x; } - -#define ptr & // use for faster code +template +T* ptr(T&& x) { return &x; } // ------------------------------------------------------------------------------------ // Vertex Declaration equal to NTVERTEX diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index 04a069a3b..881a6590c 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -1330,6 +1330,17 @@ void UpdateBakedLights(float lvl) } } +// ============================================================================================= +// +LPDIRECT3DTEXTURE9 GetCombinedMap() +{ + D3D9Mesh* mesh = (class D3D9Mesh*)vObj->GetMesh(sMesh); + if (mesh) { + DWORD texidx = mesh->GetMeshGroupTextureIdx(sGroup); + return mesh->GetCombinedMap(texidx); + } + return NULL; +} // ============================================================================================= // @@ -1858,6 +1869,7 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if (HWND(lParam) == GetDlgItem(hWnd, IDC_DBG_BKLADJ)) { if (pos == 0) pos = WORD(SendDlgItemMessage(hDlg, IDC_DBG_BKLADJ, TBM_GETPOS, 0, 0)); float val = float(pos) / 255.0f; + UpdateBakedLights(val); } } return false; diff --git a/OVP/D3D9Client/DebugControls.h b/OVP/D3D9Client/DebugControls.h index b05e4a676..9b4cb928a 100644 --- a/OVP/D3D9Client/DebugControls.h +++ b/OVP/D3D9Client/DebugControls.h @@ -125,6 +125,8 @@ namespace DebugControls { void Append(const char *format, ...); void Refresh(); + LPDIRECT3DTEXTURE9 GetCombinedMap(); + INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK ViewProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); }; diff --git a/OVP/D3D9Client/IProcess.cpp b/OVP/D3D9Client/IProcess.cpp index 41a6b238a..e81691c79 100644 --- a/OVP/D3D9Client/IProcess.cpp +++ b/OVP/D3D9Client/IProcess.cpp @@ -260,6 +260,7 @@ bool ImageProcessing::Execute(DWORD blendop, bool bInScene, gcIPInterface::ipite HR(pDevice->SetRenderState(D3DRS_ALPHATESTENABLE, false)); HR(pDevice->SetRenderState(D3DRS_STENCILENABLE, false)); HR(pDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0xF)); + HR(pDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, false)); if (blendop == 1) { HR(pDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD)); @@ -269,14 +270,14 @@ bool ImageProcessing::Execute(DWORD blendop, bool bInScene, gcIPInterface::ipite // Define vertices -------------------------------------------------------- // - SMVERTEX Vertex[4] = { + static const SMVERTEX Vertex[4] = { {0, 0, 0, 0, 0}, {0, 1, 0, 0, 1}, {1, 1, 0, 1, 1}, {1, 0, 0, 1, 0} }; - static WORD cIndex[6] = {0, 2, 1, 0, 3, 2}; + static const WORD cIndex[6] = {0, 2, 1, 0, 3, 2}; // Set render targets ----------------------------------------------------- // @@ -292,16 +293,18 @@ bool ImageProcessing::Execute(DWORD blendop, bool bInScene, gcIPInterface::ipite // Set Depth-Stencil surface ---------------------------------------------- // + + pDevice->GetDepthStencilSurface(&pDepthBak); + if (pDepth) { HR(pDevice->SetRenderState(D3DRS_ZENABLE, true)); HR(pDevice->SetRenderState(D3DRS_ZWRITEENABLE, true)); - - pDevice->GetDepthStencilSurface(&pDepthBak); - pDevice->SetDepthStencilSurface(pDepth); + HR(pDevice->SetDepthStencilSurface(pDepth)); } else { HR(pDevice->SetRenderState(D3DRS_ZENABLE, false)); HR(pDevice->SetRenderState(D3DRS_ZWRITEENABLE, false)); + HR(pDevice->SetDepthStencilSurface(NULL)); } // Set textures and samplers ----------------------------------------------- @@ -382,9 +385,9 @@ bool ImageProcessing::Execute(DWORD blendop, bool bInScene, gcIPInterface::ipite // Disconnect render targets ---------------------------------------------- // - if (pDepth) { - pDevice->SetDepthStencilSurface(pDepthBak); - } + pDevice->SetDepthStencilSurface(pDepthBak); + SAFE_RELEASE(pDepthBak); + // Disconnect render targets ---------------------------------------------- // diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index 28e7106d3..6014e1da4 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -465,24 +465,31 @@ void D3D9Mesh::ReLoadMeshFromHandle(MESHHANDLE hMesh) // void D3D9Mesh::LoadBakedLights() { + if (BakedLights.size()) return; // Already Loaded, skip the rest + bMustRebake = true; char id[8]; for (int i = 0; i < nTex; i++) { - if (!Tex[i]) continue; - BakedLights[i].bEnabled = false; - + if (!Tex[i]) continue; // No base texture, pick next for (int j = 0; j < 10; j++) { - sprintf_s(id, "_bkl%d", j); - BakedLights[i].pMap[j] = NatLoadSpecialTexture(Tex[i]->GetPath(), id); - if (BakedLights[i].pMap[j] != NULL) BakedLights[i].bEnabled = true; + sprintf_s(id, "bkl%d", j); + LPDIRECT3DTEXTURE9 pTex = NatLoadSpecialTexture(Tex[i]->GetPath(), id); + if (pTex) BakedLights[i].pMap[j] = pTex; } + } - HR(D3DXCreateTexture(pDev, Tex[i]->GetWidth(), Tex[i]->GetHeight(), 0, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &BakedLights[i].pCombined)); + // Construct render surface for all combined maps + for (auto& a : BakedLights) { + int i = a.first; + if (Tex[i]) { + HR(D3DXCreateTexture(pDev, Tex[i]->GetWidth(), Tex[i]->GetHeight(), 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &a.second.pCombined)); + } } - for (int i = 0; i < 10;i++) BakedLightsControl[i] = FVECTOR3(0, 0, 0); + + for (int i = 0; i < 10; i++) BakedLightsControl[i] = FVECTOR3(0.5, 0.5, 0.5); } @@ -503,20 +510,23 @@ void D3D9Mesh::SetBakedLightLevel(int idx, const FVECTOR3 &level) // void D3D9Mesh::BakeLights(ImageProcessing* pBaker) { - if (!pBaker->IsOK()) return; - if (DefShader != SHADER_BAKED_VC) return; - if (!bMustRebake) return; + if (!pBaker->IsOK()) return; // Baker not initialized + if (DefShader != SHADER_BAKED_VC) return; // Not supported by shader + if (!bMustRebake) return; // Allready Done + if (BakedLights.size() == 0) return; // Nothing to bake - DWORD flags = IPF_POINT; + DWORD flags = IPF_POINT | IPF_CLAMP; FVECTOR3 control[10]; + pBaker->Activate("PSMain"); + for (auto x : BakedLights) { int slot = 0; for (int i = 0; i < 10; i++) { auto y = x.second.pMap[i]; - if (y && length(BakedLightsControl[i]) > 0.01f) + if (y) { pBaker->SetTextureNative(slot, y, flags); control[slot] = BakedLightsControl[i]; @@ -529,11 +539,14 @@ void D3D9Mesh::BakeLights(ImageProcessing* pBaker) LPDIRECT3DSURFACE9 pSrf = NULL; - if (x.second.pCombined->GetSurfaceLevel(0, &pSrf) == S_OK) + if (x.second.pCombined) { - pBaker->SetOutputNative(0, pSrf); - pBaker->Execute(true); - SAFE_RELEASE(pSrf); + if (x.second.pCombined->GetSurfaceLevel(0, &pSrf) == S_OK) + { + pBaker->SetOutputNative(0, pSrf); + pBaker->Execute(true); + SAFE_RELEASE(pSrf); + } } } @@ -541,6 +554,17 @@ void D3D9Mesh::BakeLights(ImageProcessing* pBaker) } +// =========================================================================================== +// +LPDIRECT3DTEXTURE9 D3D9Mesh::GetCombinedMap(int tex_idx) +{ + if (tex_idx < 0 ) for (auto a : BakedLights) if (a.second.pCombined) return a.second.pCombined; + auto it = BakedLights.find(tex_idx); + if (it != BakedLights.end()) return it->second.pCombined; + return NULL; +} + + // =========================================================================================== // void D3D9Mesh::LoadMeshFromHandle(MESHHANDLE hMesh, D3DXVECTOR3 *reorig, float *scale) @@ -1853,13 +1877,15 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, int iTech, LPDIRECT3DCUBETEXTURE9 * if (CurrentShader == SHADER_BAKED_VC) { + auto bm = BakedLights.find(ti); + LPDIRECT3DTEXTURE9 pAmbi = Tex[ti]->GetMap(MAP_AMBIENT); - LPDIRECT3DTEXTURE9 pComb = BakedLights[ti].pCombined; + LPDIRECT3DTEXTURE9 pComb = (bm == BakedLights.end() ? NULL : bm->second.pCombined); if (pAmbi) FX->SetTexture(eAmbientMap, pAmbi); if (pComb) FX->SetTexture(eCombinedMap, pComb); - FC.Baked = (pAmbi != NULL) && (pComb != NULL); + FC.Baked = (pAmbi != NULL) || (pComb != NULL); } FC.Emis = (pEmis != NULL); @@ -2019,6 +2045,12 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, int iTech, LPDIRECT3DCUBETEXTURE9 * DebugControls::Append("]\n"); } + if (CurrentShader == SHADER_BAKED_VC) { + DebugControls::Append("BakedLights = [ "); + for (auto& a : BakedLights) DebugControls::Append(" %d", a.first); + DebugControls::Append("]\n"); + } + DebugControls::Append("Local Lights = %d\n", nMeshLights); DebugControls::Refresh(); diff --git a/OVP/D3D9Client/Mesh.h b/OVP/D3D9Client/Mesh.h index 2cebba2ee..e7553f888 100644 --- a/OVP/D3D9Client/Mesh.h +++ b/OVP/D3D9Client/Mesh.h @@ -75,7 +75,6 @@ struct _LightList { struct _BakedLights { LPDIRECT3DTEXTURE9 pMap[10]; LPDIRECT3DTEXTURE9 pCombined; - bool bEnabled; }; class MeshShader : public ShaderClass @@ -327,6 +326,7 @@ class D3D9Mesh : private D3D9Effect void SetupFog(const LPD3DXMATRIX pW); void ResetRenderStatus(); + LPDIRECT3DTEXTURE9 GetCombinedMap(int tex_idx = -1); /** * \brief Enable/disable material alpha value for transparency calculation. diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index 7fa5b6c7b..a203aa8eb 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -1976,7 +1976,7 @@ void Scene::RenderMainScene() { SmapRenderList.clear(); - float rad = 1.5f; + float rad = 2.0f; D3DXVECTOR3 ld = sunLight.Dir; D3DXVECTOR3 pos = Camera.z * rad * 0.75f; @@ -2214,6 +2214,16 @@ void Scene::RenderMainScene() pSketch->EndDrawing(); } break; + case 14: + { + LPDIRECT3DTEXTURE9 pTex = DebugControls::GetCombinedMap(); + if (pTex) { + pSketch = GetPooledSketchpad(SKETCHPAD_2D_OVERLAY); + pSketch->StretchRectNative(pTex, NULL, ptr(_RECT(0, 0, viewH, viewH))); + pSketch->EndDrawing(); + } + break; + } default: break; } diff --git a/OVP/D3D9Client/shaders/BakedVC.fx b/OVP/D3D9Client/shaders/BakedVC.fx index f1760421c..f4269775a 100644 --- a/OVP/D3D9Client/shaders/BakedVC.fx +++ b/OVP/D3D9Client/shaders/BakedVC.fx @@ -181,7 +181,7 @@ float4 BakedVC_PS(float4 sc : VPOS, PBRData frg) : COLOR // Add a faint diffuse hue for rough metals. Rough metal doesn't look good if it's totally black fA += fRgh * fMetal * 0.05f; - float3 zD = cDiff.rgb * fA * LightFXSq(gMtrl.diffuse.rgb * (Sq(cSun * fR * dLN)) + Sq(gMtrl.emissive.rgb)); + float3 zD = cDiff.rgb * fA * cBL * LightFXSq(gMtrl.diffuse.rgb * (Sq(cSun * fR * dLN)) + Sq(gMtrl.emissive.rgb) + Sq(cBL)); // Combine specular terms float3 zS = cS * (cSun * dLN); From c07d722cc19e704452aba9db46c957e625f64a7c Mon Sep 17 00:00:00 2001 From: jarmonik Date: Fri, 28 Jul 2023 16:14:37 +0300 Subject: [PATCH 10/42] Removed texture "tuning" stuff to simplify the code. --- OVP/D3D9Client/D3D9Effect.cpp | 4 - OVP/D3D9Client/D3D9Effect.h | 2 - OVP/D3D9Client/D3D9Util.cpp | 11 -- OVP/D3D9Client/D3D9Util.h | 13 --- OVP/D3D9Client/DebugControls.cpp | 166 +-------------------------- OVP/D3D9Client/Mesh.cpp | 44 ------- OVP/D3D9Client/Mesh.h | 3 - OVP/D3D9Client/shaders/D3D9Client.fx | 17 --- OVP/D3D9Client/shaders/PBR.fx | 23 ---- OVP/D3D9Client/shaders/Vessel.fx | 9 +- 10 files changed, 4 insertions(+), 288 deletions(-) diff --git a/OVP/D3D9Client/D3D9Effect.cpp b/OVP/D3D9Client/D3D9Effect.cpp index b68611516..4c29c5845 100644 --- a/OVP/D3D9Client/D3D9Effect.cpp +++ b/OVP/D3D9Client/D3D9Effect.cpp @@ -64,7 +64,6 @@ D3DXHANDLE D3D9Effect::eGT = 0; // Mesh group transformation matrix D3DXHANDLE D3D9Effect::eMat = 0; // Material D3DXHANDLE D3D9Effect::eWater = 0; // Water D3DXHANDLE D3D9Effect::eMtrl = 0; -D3DXHANDLE D3D9Effect::eTune = 0; D3DXHANDLE D3D9Effect::eSun = 0; D3DXHANDLE D3D9Effect::eNight = 0; D3DXHANDLE D3D9Effect::eLights = 0; // Additional light sources @@ -116,7 +115,6 @@ D3DXHANDLE D3D9Effect::eEnvMapEnable = 0; // BOOL D3DXHANDLE D3D9Effect::eInSpace = 0; // BOOL D3DXHANDLE D3D9Effect::eNoColor = 0; // BOOL D3DXHANDLE D3D9Effect::eLightsEnabled = 0; // BOOL -D3DXHANDLE D3D9Effect::eTuneEnabled = 0; // BOOL D3DXHANDLE D3D9Effect::eBaseBuilding = 0; // BOOL D3DXHANDLE D3D9Effect::eOITEnable = 0; // BOOL // -------------------------------------------------------------- @@ -429,7 +427,6 @@ void D3D9Effect::D3D9TechInit(D3D9Client *_gc, LPDIRECT3DDEVICE9 _pDev, const ch eInSpace = FX->GetParameterByName(0,"gInSpace"); eNoColor = FX->GetParameterByName(0,"gNoColor"); eLightsEnabled = FX->GetParameterByName(0,"gLightsEnabled"); - eTuneEnabled = FX->GetParameterByName(0,"gTuneEnabled"); eBaseBuilding = FX->GetParameterByName(0,"gBaseBuilding"); eOITEnable = FX->GetParameterByName(0,"gOITEnable"); @@ -462,7 +459,6 @@ void D3D9Effect::D3D9TechInit(D3D9Client *_gc, LPDIRECT3DDEVICE9 _pDev, const ch eMat = FX->GetParameterByName(0,"gMat"); eWater = FX->GetParameterByName(0,"gWater"); eMtrl = FX->GetParameterByName(0,"gMtrl"); - eTune = FX->GetParameterByName(0,"gTune"); // ---------------------------------------------------------------------- eTex0 = FX->GetParameterByName(0,"gTex0"); eTex1 = FX->GetParameterByName(0,"gTex1"); diff --git a/OVP/D3D9Client/D3D9Effect.h b/OVP/D3D9Client/D3D9Effect.h index 3a05f3283..1c5c48ac8 100644 --- a/OVP/D3D9Client/D3D9Effect.h +++ b/OVP/D3D9Client/D3D9Effect.h @@ -117,7 +117,6 @@ class D3D9Effect { // Lighting related parameters ------------------------------------ static D3DXHANDLE eMtrl; - static D3DXHANDLE eTune; static D3DXHANDLE eMat; ///< Material static D3DXHANDLE eWater; ///< Water static D3DXHANDLE eSun; ///< Sun @@ -135,7 +134,6 @@ class D3D9Effect { static D3DXHANDLE eNoColor; ///< BOOL static D3DXHANDLE eLightsEnabled;///< BOOL static D3DXHANDLE eBaseBuilding; ///< BOOL - static D3DXHANDLE eTuneEnabled; ///< BOOL static D3DXHANDLE eFresnel; ///< BOOL static D3DXHANDLE eSwitch; ///< BOOL static D3DXHANDLE eRghnSw; ///< BOOL diff --git a/OVP/D3D9Client/D3D9Util.cpp b/OVP/D3D9Client/D3D9Util.cpp index cc1177e70..b68fc35bc 100644 --- a/OVP/D3D9Client/D3D9Util.cpp +++ b/OVP/D3D9Client/D3D9Util.cpp @@ -202,17 +202,6 @@ void CreateDefaultMat(D3D9MatExt *pOut) pOut->ModFlags = 0; } -void D3D9TuneInit(D3D9Tune *pTune) -{ - pTune->Albedo = D3DXCOLOR(1, 1, 1, 1); - pTune->Emis = D3DXCOLOR(1, 1, 1, 1); - pTune->Spec = D3DXCOLOR(1, 1, 1, 1); - pTune->Refl = D3DXCOLOR(1, 1, 1, 1); - pTune->Transl = D3DXCOLOR(1, 1, 1, 1); - pTune->Transm = D3DXCOLOR(1, 1, 1, 1); - pTune->Norm = D3DXCOLOR(1, 1, 1, 1); - pTune->Rghn = D3DXCOLOR(1, 1, 1, 1); -} void SurfaceLighting(D3D9Sun *light, OBJHANDLE hP, OBJHANDLE hO, float ao) { diff --git a/OVP/D3D9Client/D3D9Util.h b/OVP/D3D9Client/D3D9Util.h index ffc311684..7ccdd87aa 100644 --- a/OVP/D3D9Client/D3D9Util.h +++ b/OVP/D3D9Client/D3D9Util.h @@ -320,18 +320,6 @@ typedef struct { DWORD ModFlags; ///< Modification flags } D3D9MatExt; - -typedef struct { - D3DCOLORVALUE Albedo; // Tune Albedo - D3DCOLORVALUE Emis; // Tune Emission Maps - D3DCOLORVALUE Spec; // Tune Specular Maps - D3DCOLORVALUE Refl; // Tune Reflection Maps - D3DCOLORVALUE Transl; // Tune translucent effect - D3DCOLORVALUE Transm; // Tune transmissive effect - D3DCOLORVALUE Norm; // Tune normal map - D3DCOLORVALUE Rghn; // Tune roughness map -} D3D9Tune; - #pragma pack(pop) typedef struct { @@ -580,7 +568,6 @@ void UpdateMatExt(const D3DMATERIAL9 *pIn, D3D9MatExt *pOut); void CreateDefaultMat(D3D9MatExt *pOut); void GetMatExt(const D3D9MatExt *pIn, D3DMATERIAL9 *pOut); bool CopyBuffer(LPDIRECT3DRESOURCE9 _pDst, LPDIRECT3DRESOURCE9 _pSrc); -void D3D9TuneInit(D3D9Tune *); int LoadPlanetTextures(const char* fname, LPDIRECT3DTEXTURE9* ppdds, DWORD flags, int amount); LPDIRECT3DPIXELSHADER9 CompilePixelShader(LPDIRECT3DDEVICE9 pDev, const char *file, const char *function, const char* name, const char *options, LPD3DXCONSTANTTABLE *pConst); diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index 881a6590c..356898001 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -34,7 +34,7 @@ extern D3D9Client *g_client; namespace DebugControls { -int bkl_id = -1; +int bkl_id = 0; DWORD dwGFX, dwCmd, nMesh, nGroup, sMesh, sGroup, debugFlags, dspMode, camMode, SelColor, sEmitter; double camSpeed; float cpr, cpg, cpb, cpa; @@ -85,7 +85,7 @@ struct _Params { }; -_Params Params[20] = { 0 }; +_Params Params[10] = { 0 }; @@ -220,14 +220,6 @@ void Create() PrmList.push_back(MatParams("Emission2", 7)); PrmList.push_back(MatParams("Metalness", 8)); PrmList.push_back(MatParams("SpecialFX", 9)); - PrmList.push_back(MatParams("- - - - - -", 10)); - PrmList.push_back(MatParams("Tune Albedo", 11)); - PrmList.push_back(MatParams("Tune _Emis", 12)); - PrmList.push_back(MatParams("Tune _Refl", 13)); - PrmList.push_back(MatParams("Tune _Rghn", 14)); - PrmList.push_back(MatParams("Tune _Transl", 15)); - PrmList.push_back(MatParams("Tune _Transm", 16)); - PrmList.push_back(MatParams("Tune _Spec", 17)); } // ============================================================================================= @@ -347,7 +339,7 @@ void InitMatList(WORD shader) Dropdown.clear(); if (shader == SHADER_NULL) { - std::list list = { 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17 }; + std::list list = { 0, 1, 2, 3, 4, 5, 6, 7, 9 }; for (auto x : list) Dropdown.push_back(PrmList[x]); for (auto x : Dropdown) SendDlgItemMessageA(hDlg, IDC_DBG_MATPRP, CB_ADDSTRING, 0, (LPARAM)x.name.c_str()); } @@ -575,75 +567,8 @@ void OpenDlgClbk(void *context) // SpecialFX Params[9].var[0] = DefVar(0, 1, LIN, "Part Temperature"); - - - // Unused index 10 - - // Tuning ------------------------------------------------------------------------------------- - // Albedo - int i = 11; - Params[i].var[0] = DefVar(0.2f, 5.0f, SQRT, "Red"); - Params[i].var[1] = DefVar(0.2f, 5.0f, SQRT, "Green"); - Params[i].var[2] = DefVar(0.2f, 5.0f, SQRT, "Blue"); - Params[i].var[3] = DefVar(0.2f, 5.0f, SQRT, "Gamma", true); - - Params[1 + i] = Params[i]; // Emis - Params[1 + i].var[3] = DefVar(0.2f, 5.0f, SQRT, "Gamma", true); - - Params[2 + i] = Params[i]; // Refl - Params[2 + i].var[3] = DefVar(0.2f, 5.0f, SQRT, "Gamma", true); - - Params[3 + i] = Params[i]; // Regn - Params[3 + i].var[3] = DefVar(0.2f, 5.0f, SQRT, "Gamma", true); - - Params[4 + i] = Params[i]; // Transl - Params[4 + i].var[3] = DefVar(0.2f, 5.0f, SQRT, "???"); - - Params[5 + i] = Params[i]; // Transm - Params[5 + i].var[3] = DefVar(0.2f, 5.0f, SQRT, "???"); - - Params[6 + i] = Params[i]; // Spec - Params[6 + i].var[3] = DefVar(0.1f, 9.9f, SQRT, "Power", false); -} - - -// ============================================================================================= -// -void SetTuningValue(int idx, D3DCOLORVALUE *pClr, DWORD clr, float value) -{ - bool bExtend = (SendDlgItemMessageA(hDlg, IDC_DBG_EXTEND, BM_GETCHECK, 0, 0) == BST_CHECKED); - - float mi = Params[idx].var[clr].min; - float mx = (bExtend ? Params[idx].var[clr].extmax : Params[idx].var[clr].max); - - switch (clr) { - case 0: pClr->r = CLAMP(value, mi, mx); break; - case 1: pClr->g = CLAMP(value, mi, mx); break; - case 2: pClr->b = CLAMP(value, mi, mx); break; - case 3: - { - if (Params[idx].var[clr].bGamma) pClr->a = 1.0f / CLAMP(value, mi, mx); - else pClr->a = CLAMP(value, mi, mx); - } break; - } } -// ============================================================================================= -// -float GetTuningValue(int idx, D3DCOLORVALUE *pClr, DWORD clr) -{ - switch (clr) { - case 0: return pClr->r; - case 1: return pClr->g; - case 2: return pClr->b; - case 3: - { - if (Params[idx].var[clr].bGamma) return 1.0f / pClr->a; - else return pClr->a; - } - } - return 1.0f; -} // ============================================================================================= // @@ -704,12 +629,8 @@ void UpdateMeshMaterial(float value, DWORD MatPrp, DWORD clr) DWORD texidx = hMesh->GetMeshGroupTextureIdx(sGroup); D3D9MatExt Mat; - D3D9Tune Tune; - if (!hMesh->GetMaterial(&Mat, matidx)) return; - bool bTune = hMesh->GetTexTune(&Tune, texidx); - switch(MatPrp) { case 0: // Diffuse @@ -781,51 +702,8 @@ void UpdateMeshMaterial(float value, DWORD MatPrp, DWORD clr) Mat.SpecialFX[clr] = _Clamp(value, MatPrp, clr); break; } - - case 11: // Tune Albedo - { - SetTuningValue(MatPrp, &Tune.Albedo, clr, value); - break; - } - - case 12: // Tune Emis - { - SetTuningValue(MatPrp, &Tune.Emis, clr, value); - break; - } - - case 13: // Tune Refl - { - SetTuningValue(MatPrp, &Tune.Refl, clr, value); - break; - } - - case 14: // Tune _Rghn - { - SetTuningValue(MatPrp, &Tune.Rghn, clr, value); - break; - } - - case 15: // Tune _Transl - { - SetTuningValue(MatPrp, &Tune.Transl, clr, value); - break; - } - - case 16: // Tune _Transm - { - SetTuningValue(MatPrp, &Tune.Transm, clr, value); - break; - } - - case 17: // Tune _Spec - { - SetTuningValue(MatPrp, &Tune.Spec, clr, value); - break; - } } - if (bTune) hMesh->SetTexTune(&Tune, texidx); hMesh->SetMaterial(&Mat, matidx); vVessel *vVes = (vVessel *)vObj; @@ -919,9 +797,6 @@ float GetMaterialValue(DWORD MatPrp, DWORD clr) if (!pMat) return 0.0f; - D3D9Tune Tune; - bool bTune = hMesh->GetTexTune(&Tune, texidx); - switch(MatPrp) { case 0: // Diffuse @@ -1023,41 +898,6 @@ float GetMaterialValue(DWORD MatPrp, DWORD clr) } break; } - - case 11: // Tune Albedo - { - return GetTuningValue(MatPrp, &Tune.Albedo, clr); - } - - case 12: // Tune Emis - { - return GetTuningValue(MatPrp, &Tune.Emis, clr); - } - - case 13: // Tune Refl - { - return GetTuningValue(MatPrp, &Tune.Refl, clr); - } - - case 14: // Tune _Rghn - { - return GetTuningValue(MatPrp, &Tune.Rghn, clr); - } - - case 15: // Tune _Transl - { - return GetTuningValue(MatPrp, &Tune.Transl, clr); - } - - case 16: // Tune _Transm - { - return GetTuningValue(MatPrp, &Tune.Transm, clr); - } - - case 17: // Tune _Spec - { - return GetTuningValue(MatPrp, &Tune.Spec, clr); - } } return 0.0f; diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index 6014e1da4..cc954e5f3 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -182,7 +182,6 @@ void D3D9Mesh::Null(const char *meshName /* = NULL */) Grp = NULL; nTex = 0; Tex = NULL; - pTune = NULL; nMtrl = 0; pBuf = NULL; Mtrl = NULL; @@ -391,7 +390,6 @@ void D3D9Mesh::Release() SAFE_DELETEA(Tex); SAFE_DELETEA(Mtrl); SAFE_DELETEA(pGrpTF); - SAFE_DELETEA(pTune); if (pBuf) if (pBuf->IsLocalTo(this)) delete pBuf; } @@ -1377,31 +1375,6 @@ int D3D9Mesh::GetMaterialEx(DWORD idx, MatProp mid, FVECTOR4* value) return 5; } -// =========================================================================================== -// -bool D3D9Mesh::GetTexTune(D3D9Tune *pT, DWORD idx) const -{ - if (idxSetTechnique(eVesselTech); FX->SetBool(eFresnel, false); FX->SetBool(eEnvMapEnable, false); - FX->SetBool(eTuneEnabled, false); FX->SetBool(eLightsEnabled, false); FX->SetBool(eOITEnable, false); FX->SetVector(eColor, ptr(D3DXVECTOR4(0, 0, 0, 0))); ConfigureAtmo(); - if (DebugControls::IsActive()) if (pTune) FX->SetBool(eTuneEnabled, true); - TexFlow FC; reset(FC); @@ -1827,11 +1797,6 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, int iTech, LPDIRECT3DCUBETEXTURE9 * if (tni && Tex[tni]) FX->SetTexture(eEmisMap, Tex[tni]->GetTexture()); } else { - - if (DebugControls::IsActive()) if (pTune) { - FX->SetValue(eTune, &pTune[ti], sizeof(D3D9Tune)); - } - LPDIRECT3DTEXTURE9 pTransl = NULL; LPDIRECT3DTEXTURE9 pTransm = NULL; LPDIRECT3DTEXTURE9 pMetl = NULL; @@ -2141,7 +2106,6 @@ void D3D9Mesh::RenderSimplified(const LPD3DXMATRIX pW, LPDIRECT3DCUBETEXTURE9 *p FX->SetTechnique(eVesselTech); FX->SetBool(eFresnel, false); FX->SetBool(eEnvMapEnable, false); - FX->SetBool(eTuneEnabled, false); FX->SetBool(eLightsEnabled, false); FX->SetVector(eColor, ptr(D3DXVECTOR4(0, 0, 0, 0))); FX->SetMatrix(eW, pW); @@ -2436,14 +2400,10 @@ void D3D9Mesh::RenderFast(const LPD3DXMATRIX pW, int iTech) FX->SetTechnique(eVesselTech); - FX->SetBool(eTuneEnabled, false); FX->SetBool(eLightsEnabled, false); FX->SetVector(eColor, ptr(D3DXVECTOR4(0, 0, 0, 0))); ConfigureAtmo(); - - if (DebugControls::IsActive()) if (pTune) FX->SetBool(eTuneEnabled, true); - TexFlow FC; reset(FC); const D3D9Light *pLights = gc->GetScene()->GetLights(); @@ -2548,10 +2508,6 @@ void D3D9Mesh::RenderFast(const LPD3DXMATRIX pW, int iTech) if (Tex[ti] != old_tex) { - D3D9Stats.Mesh.TexChanges++; - - if (DebugControls::IsActive()) if (pTune) FX->SetValue(eTune, &pTune[ti], sizeof(D3D9Tune)); - old_tex = Tex[ti]; FX->SetTexture(eTex0, Tex[ti]->GetTexture()); diff --git a/OVP/D3D9Client/Mesh.h b/OVP/D3D9Client/Mesh.h index e7553f888..3ebb2284a 100644 --- a/OVP/D3D9Client/Mesh.h +++ b/OVP/D3D9Client/Mesh.h @@ -261,8 +261,6 @@ class D3D9Mesh : private D3D9Effect void SetMaterial(const D3DMATERIAL9 *pMat, DWORD idx, bool bUpdateStatus = true); int SetMaterialEx(DWORD idx, MatProp mid, const FVECTOR4* in); int GetMaterialEx(DWORD idx, MatProp mid, FVECTOR4* out); - bool GetTexTune(D3D9Tune *pT, DWORD idx) const; - void SetTexTune(const D3D9Tune *pT, DWORD idx); DWORD GetGroupCount() const { return nGrp; } DWORD GetMaterialCount() const { return nMtrl; } @@ -365,7 +363,6 @@ class D3D9Mesh : private D3D9Effect SurfNative **Tex; // list of mesh textures std::map BakedLights; FVECTOR3 BakedLightsControl[10]; - D3D9Tune *pTune; D3DXMATRIX mTransform; D3DXMATRIX mTransformInv; D3DXMATRIX *pGrpTF; diff --git a/OVP/D3D9Client/shaders/D3D9Client.fx b/OVP/D3D9Client/shaders/D3D9Client.fx index b94456ab7..0c5af7b93 100644 --- a/OVP/D3D9Client/shaders/D3D9Client.fx +++ b/OVP/D3D9Client/shaders/D3D9Client.fx @@ -73,21 +73,6 @@ struct Flow }; -// Must match with counterpart D3D9Tune in D3D9Util.h - -struct Tune -{ - float4 Albe; // Tune Diffese Maps - float4 Emis; // Tune Emission Maps - float4 Spec; // Tune Specular Maps - float4 Refl; // Tune Reflection Maps - float4 Transl; // Tune translucent effect - float4 Transm; // Tune transmissive effect - float4 Norm; // Tune normal map - float4 Rghn; // Tune roughness map -}; - - #define Range 0 #define Falloff 1 #define Theta 2 @@ -119,10 +104,8 @@ uniform extern Sun gSun; // Sun light direction uniform extern Mat gMat; // Material input structure TODO: Remove all reference to this. Use gMtrl uniform extern Mat gWater; // Water material input structure uniform extern Mtrl gMtrl; // Material input structure -uniform extern Tune gTune; // Texture tuning parameters uniform extern Light gLights[MAX_LIGHTS]; uniform extern bool gLightsEnabled; -uniform extern bool gTuneEnabled; uniform extern bool gModAlpha; // Configuration input uniform extern bool gFullyLit; // Always fully lit bypass lighting calculations uniform extern bool gTextured; // Enable Diffuse Texturing diff --git a/OVP/D3D9Client/shaders/PBR.fx b/OVP/D3D9Client/shaders/PBR.fx index e09b23c87..b4816e962 100644 --- a/OVP/D3D9Client/shaders/PBR.fx +++ b/OVP/D3D9Client/shaders/PBR.fx @@ -111,29 +111,6 @@ float4 PBR_PS(float4 sc : VPOS, PBRData frg) : COLOR float3 cSun = saturate(gSun.Color); - // ---------------------------------------------------------------------- - // Texture tuning controls for add-on developpers - // ---------------------------------------------------------------------- - -#if defined(_DEBUG) - if (gTuneEnabled) { - - nrmT *= gTune.Norm.rgb; - - cDiff.rgb = pow(abs(cDiff.rgb), gTune.Albe.a) * gTune.Albe.rgb; - cRefl.rgb = pow(abs(cRefl.rgb), gTune.Refl.a) * gTune.Refl.rgb; - cEmis.rgb = pow(abs(cEmis.rgb), gTune.Emis.a) * gTune.Emis.rgb; - fRghn = pow(abs(fRghn), gTune.Rghn.a) * gTune.Rghn.g; - cSpec.rgba = cSpec.rgba * gTune.Spec.rgba; - - cDiff = saturate(cDiff); - cRefl = saturate(cRefl); - fRghn = saturate(fRghn); - cSpec = min(cSpec, sMask); - } -#endif - - // Use alpha zero to mask off specular reflections cSpec.rgb *= saturate(cSpec.a); diff --git a/OVP/D3D9Client/shaders/Vessel.fx b/OVP/D3D9Client/shaders/Vessel.fx index ff73fbd36..9cd383491 100644 --- a/OVP/D3D9Client/shaders/Vessel.fx +++ b/OVP/D3D9Client/shaders/Vessel.fx @@ -159,14 +159,7 @@ float4 AdvancedPS(float4 sc : VPOS, PBRData frg) : COLOR if (gCfg.Transl) { cTransl = tex2D(TranslS, frg.tex0.xy).rgb; - } - - // Texture Tuning ------------------------------------------------------- - // - if (gTuneEnabled) { - cTransm *= gTune.Transm.rgba; - cTransl *= gTune.Transl.rgb; - } + } float sunLightFromBehind = saturate(dot(gSun.Dir, nrmW)); float sunSpotFromBehind = pow(saturate(dot(gSun.Dir, CamD)), cTransm.a); From c72b5e32227f9960877fae05565ccbacdbe80f80 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Sat, 29 Jul 2023 23:58:15 +0300 Subject: [PATCH 11/42] Shadow cascade creation implemented. --- OVP/D3D9Client/Scene.cpp | 223 ++++++++++++++++++++++++--- OVP/D3D9Client/Scene.h | 33 ++-- OVP/D3D9Client/Surfmgr2.cpp | 4 +- OVP/D3D9Client/VPlanet.cpp | 4 +- OVP/D3D9Client/VVessel.cpp | 17 +- OVP/D3D9Client/shaders/BakedVC.fx | 2 +- OVP/D3D9Client/shaders/Common.hlsl | 70 +++------ OVP/D3D9Client/shaders/D3D9Client.fx | 3 +- OVP/D3D9Client/shaders/Metalness.fx | 2 +- OVP/D3D9Client/shaders/PBR.fx | 4 +- OVP/D3D9Client/shaders/Vessel.fx | 2 +- Orbitersdk/include/DrawAPI.h | 23 +++ 12 files changed, 288 insertions(+), 99 deletions(-) diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index a203aa8eb..346ac0ad4 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -61,6 +61,16 @@ float Rand() return float(rand()) / 32768.0f; } +void DebugMatrix(FMATRIX4* pM, const char* name) +{ + D3D9DebugLog("[%3.3f, %3.3f, %3.3f, %3.3f]", pM->m41, pM->m42, pM->m43, pM->m44); + D3D9DebugLog("[%3.3f, %3.3f, %3.3f, %3.3f]", pM->m31, pM->m32, pM->m33, pM->m34); + D3D9DebugLog("[%3.3f, %3.3f, %3.3f, %3.3f]", pM->m21, pM->m22, pM->m23, pM->m24); + D3D9DebugLog("[%3.3f, %3.3f, %3.3f, %3.3f]", pM->m11, pM->m12, pM->m13, pM->m14); + D3D9DebugLog("%s", name); +} + + // =========================================================================================== // Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) @@ -112,6 +122,9 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) memset(&ptShmRT, 0, sizeof(ptShmRT)); memset(&psShmRT, 0, sizeof(psShmRT)); + memset(&ptVCShmRT, 0, sizeof(ptShmRT)); + memset(&psVCShmRT, 0, sizeof(psShmRT)); + pDevice = _gc->GetDevice(); @@ -217,6 +230,7 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) } + // Exterior shadows if (Config->ShadowMapMode) { UINT size = ShmMapSize; for (int i = 0; i < SHM_LOD_COUNT; i++) { @@ -226,9 +240,17 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) size >>= 1; } - smap.pShadowMap = ptShmRT[0]; + smap.pShadowMap[0] = ptShmRT[0]; } + // VC Shadows + if (Config->ShadowMapMode) { + UINT size = ShmMapSize; + for (int i = 0; i < SHM_CASCADE_COUNT; i++) { + HR(pDevice->CreateTexture(size, size, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R32F, D3DPOOL_DEFAULT, &ptVCShmRT[i], NULL)); + HR(ptVCShmRT[i]->GetSurfaceLevel(0, &psVCShmRT[i])); + } + } // Create auxiliary color buffer for on screen GDI @@ -363,6 +385,8 @@ Scene::~Scene () for (int i = 0; i < ARRAYSIZE(psShmDS); i++) SAFE_RELEASE(psShmDS[i]); for (int i = 0; i < ARRAYSIZE(ptShmRT); i++) SAFE_RELEASE(ptShmRT[i]); for (int i = 0; i < ARRAYSIZE(psShmRT); i++) SAFE_RELEASE(psShmRT[i]); + for (int i = 0; i < ARRAYSIZE(ptVCShmRT); i++) SAFE_RELEASE(ptVCShmRT[i]); + for (int i = 0; i < ARRAYSIZE(psVCShmRT); i++) SAFE_RELEASE(psVCShmRT[i]); for (int i = 0; i < ARRAYSIZE(pBlrTemp); i++) SAFE_RELEASE(pBlrTemp[i]); if (Lights) { @@ -1573,7 +1597,7 @@ void Scene::RenderMainScene() shadow_lod = RenderShadowMap(pos, ld, rad, false, true); - pShdMap = smap.pShadowMap; + pShdMap = smap.pShadowMap[0]; } @@ -1859,7 +1883,7 @@ void Scene::RenderMainScene() // Render the remaining vessels those are not yet renderred // - smap.pShadowMap = NULL; + smap.pShadowMap[SHM_CASCADE_COUNT] = { }; while (RenderList.empty()==false) { RenderList.front()->Render(pDevice); @@ -1976,13 +2000,13 @@ void Scene::RenderMainScene() { SmapRenderList.clear(); - float rad = 2.0f; + float rad = 6.0f; D3DXVECTOR3 ld = sunLight.Dir; - D3DXVECTOR3 pos = Camera.z * rad * 0.75f; + D3DXVECTOR3 pos = Camera.z * rad; - RenderShadowMap(pos, ld, rad, true, false); + RenderVCShadowMap(pos, ld, rad, false); - pShdMap = smap.pShadowMap; + pShdMap = smap.pShadowMap[0]; } // Render VC @@ -2157,15 +2181,7 @@ void Scene::RenderMainScene() VisualizeCubeMap(pIrradTemp, 0); break; case 8: - if (pShdMap) { - D3DSURFACE_DESC desc; - pShdMap->GetLevelDesc(0, &desc); - RECT scr = { 0, 0, long(viewH), long(viewH) }; - pSketch = GetPooledSketchpad(SKETCHPAD_2D_OVERLAY); - if (desc.Height>viewH) pSketch->StretchRectNative(pShdMap, NULL, &scr); - else pSketch->CopyRectNative(pShdMap, NULL, 0, 0); - pSketch->EndDrawing(); - } + VisualizeShadowMap(); break; case 9: if (vFocus->GetIrradianceMap()) { @@ -2475,11 +2491,13 @@ D3DXCOLOR Scene::GetSunDiffColor() // int Scene::RenderShadowMap(D3DXVECTOR3 &pos, D3DXVECTOR3 &ld, float rad, bool bInternal, bool bListExists) { - rad *= 1.02f; - + smap.pos = pos; smap.ld = ld; smap.rad = rad; + smap.cascades = 1; + smap.Center[0] = { 0, 0 }; + smap.Subrect[0] = { 0, 0, 1, 1 }; float mnd = 1e16f; float mxd = -1e16f; @@ -2528,14 +2546,18 @@ int Scene::RenderShadowMap(D3DXVECTOR3 &pos, D3DXVECTOR3 &ld, float rad, bool bI smap.depth = (mxd + rad); - D3DXMatrixOrthoOffCenterRH(&smap.mProj, -rad, rad, rad, -rad, -rad, smap.depth); + D3DXMATRIX mProj, mView; + + D3DXMatrixOrthoOffCenterRH(&mProj, -rad, rad, rad, -rad, -rad, smap.depth); smap.dist = mxd; D3DXVECTOR3 lp = pos - ld * smap.dist; - D3DXMatrixLookAtRH(&smap.mView, &lp, &pos, ptr(D3DXVECTOR3(0, 1, 0))); - D3DXMatrixMultiply(&smap.mViewProj, &smap.mView, &smap.mProj); + D3DXMatrixLookAtRH(&mView, &lp, &pos, ptr(D3DXVECTOR3(0, 1, 0))); + D3DXMatrixMultiply(smap.mLVP.toDX(), &mView, &mProj); + + smap.mVP[0] = smap.mLVP; float lod = log2f(float(Config->ShadowMapSize) / (rsmax*1.5f)); @@ -2563,12 +2585,132 @@ int Scene::RenderShadowMap(D3DXVECTOR3 &pos, D3DXVECTOR3 &ld, float rad, bool bI gc->PopRenderTargets(); - smap.pShadowMap = ptShmRT[smap.lod]; + for (int i = 1; i < SHM_CASCADE_COUNT; i++) smap.pShadowMap[i] = NULL; + smap.pShadowMap[0] = ptShmRT[smap.lod]; return smap.lod; } + +// =========================================================================================== +// +int Scene::RenderVCShadowMap(D3DXVECTOR3& pos, D3DXVECTOR3& ld, float rad, bool bListExists) +{ + + smap.pos = pos; + smap.ld = ld; + smap.rad = rad; + + float mnd = 1e16f; + float mxd = -1e16f; + float rsmax = 0.0f; + float tanap = float(GetTanAp()); + float viewh = float(ViewH()); + + + if (!bListExists) { + + // If the list doesn't exists then create it... + SmapRenderList.clear(); + + // browse through vessels to find shadowers -------------------------- + // + for (VOBJREC* pv = vobjFirst; pv; pv = pv->next) { + if (pv->type != OBJTP_VESSEL) continue; + vVessel* vV = (vVessel*)pv->vobj; + if (!vV->IsActive()) continue; + if (vV->IntersectShadowVolume()) { + SmapRenderList.push_back(vV); + vV->GetMinMaxLightDist(&mnd, &mxd); + } + } + + // Compute shadow lod + rsmax = viewh * rad / (tanap * D3DXVec3Length(&pos)); + } + + + if (SmapRenderList.size() == 0) return -1; // The list is empty, Nothing to render + + + if (bListExists) { + + for (auto vV : SmapRenderList) + { + // Get shadow min-max distances + vV->GetMinMaxLightDist(&mnd, &mxd); + + // Compute shadow lod + D3DXVECTOR3 bspos = vV->GetBoundingSpherePosDX(); + float rs = viewh * rad / (tanap * D3DXVec3Length(&bspos)); + if (rs > rsmax) rsmax = rs; + } + } + + smap.depth = (mxd + rad); + smap.dist = mxd; + smap.lod = 0; + smap.size = Config->ShadowMapSize; + smap.cascades = SHM_CASCADE_COUNT; + + float fnear = -rad; + float ffar = smap.depth; + D3DXMATRIX mProj, mView; + FMATRIX4 mV; + + for (int i = 0; i < SHM_CASCADE_COUNT; i++) + { + D3DXVECTOR3 ep = pos - ld * smap.dist; + + D3DXMatrixOrthoOffCenterRH(&mProj, -rad, rad, rad, -rad, fnear, ffar); + D3DXMatrixLookAtRH(&mView, &ep, &pos, ptr(D3DXVECTOR3(0, 1, 0))); + D3DXMatrixMultiply(smap.mLVP.toDX(), &mView, &mProj); + + smap.mVP[i] = smap.mLVP; + + D3DXVECTOR3 xy; + D3DXVec3TransformCoord(&xy, &pos, smap.mVP[0].toDX()); + float r = 0.5f * rad / smap.rad; + + xy.y = -xy.y; + xy = (xy + 1.0f) * 0.5f; + + smap.Center[i] = { xy.x, xy.y }; + smap.Subrect[i] = { xy.x - r, xy.y - r, xy.x + r, xy.y + r }; + + D3D9DebugLog("Cascade %i pos=[%f, %f]", i, xy.x, xy.y); + D3D9DebugLog("Cascade %i rect=[%f, %f, %f, %f]", i, xy.x-r, xy.y-r, xy.x+r, xy.y+r); + + gc->PushRenderTarget(psVCShmRT[i], psShmDS[0], RENDERPASS_SHADOWMAP); + + // Clear the viewport + HR(pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 1.0f, 0L)); + + // render the vessel objects -------------------------------- + // + BeginPass(RENDERPASS_SHADOWMAP); + + for (auto &a : SmapRenderList) + { + a->Render(pDevice, false); + if (a == vFocus) a->Render(pDevice, true); + } + + rad *= SHM_CASCADE_RATIO; + pos *= SHM_CASCADE_RATIO; + + PopPass(); + + gc->PopRenderTargets(); + + smap.pShadowMap[i] = ptVCShmRT[i]; + } + + return 0; +} + + // =========================================================================================== // void Scene::RenderSecondaryScene(std::set &RndList, std::set &LightsList, DWORD flags) @@ -2959,6 +3101,39 @@ void Scene::VisualizeCubeMap(LPDIRECT3DCUBETEXTURE9 pCube, int mip) } +// =========================================================================================== +// +void Scene::VisualizeShadowMap() +{ + if (smap.pShadowMap[0] == NULL) return; + + D3DSURFACE_DESC desc; + smap.pShadowMap[0]->GetLevelDesc(0, &desc); + + float w, h; + if (desc.Height > viewH) w = h = float(viewH); + else w = h = float(desc.Height); + + D3D9Pad *pSketch = GetPooledSketchpad(SKETCHPAD_2D_OVERLAY); + + for (int i=0;iStretchRectNative(smap.pShadowMap[i], NULL, &tgt); + pSketch->QuickBrush(0); + pSketch->QuickPen(0xFFFFFFFF); + pSketch->Rectangle(l, t, r, b); + } + pSketch->EndDrawing(); +} + + // =========================================================================================== // @@ -2995,10 +3170,10 @@ void Scene::RenderMesh(DEVMESHHANDLE hMesh, const oapi::FMATRIX4 *pWorld) float s = float(shd->size); float sr = 2.0f * shd->rad / s; - HR(D3D9Effect::FX->SetMatrix(D3D9Effect::eLVP, &shd->mViewProj)); + HR(D3D9Effect::FX->SetMatrix(D3D9Effect::eLVP, shd->mLVP.toCDX())); if (shd->pShadowMap) { - HR(D3D9Effect::FX->SetTexture(D3D9Effect::eShadowMap, shd->pShadowMap)); + HR(D3D9Effect::FX->SetTexture(D3D9Effect::eShadowMap, shd->pShadowMap[0])); HR(D3D9Effect::FX->SetVector(D3D9Effect::eSHD, ptr(D3DXVECTOR4(sr, 1.0f / s, float(oapiRand()), 1.0f / shd->depth)))); HR(D3D9Effect::FX->SetBool(D3D9Effect::eShadowToggle, true)); } diff --git a/OVP/D3D9Client/Scene.h b/OVP/D3D9Client/Scene.h index c79d498c8..d9ca2d9c2 100644 --- a/OVP/D3D9Client/Scene.h +++ b/OVP/D3D9Client/Scene.h @@ -40,6 +40,8 @@ class D3D9Pad; #define GBUF_COUNT 5 // Buffer count #define SHM_LOD_COUNT 5 +#define SHM_CASCADE_COUNT 3 +#define SHM_CASCADE_RATIO 0.3333333333f #define TEX_NOISE 0 #define TEX_CLUT 1 @@ -156,15 +158,21 @@ class Scene { }; struct SHADOWMAPPARAM { - LPDIRECT3DTEXTURE9 pShadowMap; - D3DXMATRIX mProj, mView, mViewProj; - D3DXVECTOR3 pos; - D3DXVECTOR3 ld; - float rad; - float dist; - float depth; - int lod; - int size; + LPDIRECT3DTEXTURE9 pShadowMap[SHM_CASCADE_COUNT]; + // Index 0 is also used for exterior map where the map size varies by LOD, distant object may use 128x128 map + // Interior VC cascades are all same size + FMATRIX4 mVP[SHM_CASCADE_COUNT]; + FVECTOR4 Subrect[SHM_CASCADE_COUNT]; + FVECTOR2 Center[SHM_CASCADE_COUNT]; + FMATRIX4 mLVP; + D3DXVECTOR3 pos; // Shadow map origin + D3DXVECTOR3 ld; // Light direction + float rad; // radius of the area covered by map [meters] + float dist; // far plane distance from shadow origin + float depth; // near to far plane distance. i.r. depth of the field + int lod; // level of detail, 0 = highest + int size; // Map size in pixels + int cascades; // Number of active cascades } smap; static void D3D9TechInit(LPDIRECT3DDEVICE9 pDev, const char *folder); @@ -244,7 +252,8 @@ class Scene { * \brief Render a secondary scene. (Env Maps, Shadow Maps, MFD Camera Views) */ void RenderSecondaryScene(std::set &RndList, std::set &AdditionalLightsList, DWORD flags = 0xFF); - int RenderShadowMap(D3DXVECTOR3 &pos, D3DXVECTOR3 &ld, float rad, bool bInternal = false, bool bListExists = false); + int RenderShadowMap(D3DXVECTOR3& pos, D3DXVECTOR3& ld, float rad, bool bInternal = false, bool bListExists = false); + int RenderVCShadowMap(D3DXVECTOR3& pos, D3DXVECTOR3& ld, float rad, bool bListExists = false); bool IntegrateIrradiance(vVessel *vV, LPDIRECT3DCUBETEXTURE9 pSrc, LPDIRECT3DTEXTURE9 pOut); bool RenderBlurredMap(LPDIRECT3DDEVICE9 pDev, LPDIRECT3DCUBETEXTURE9 pSrc); @@ -412,6 +421,7 @@ class Scene { DWORD GetActiveParticleEffectCount(); float ComputeNearClipPlane(); void VisualizeCubeMap(LPDIRECT3DCUBETEXTURE9 pCube, int mip); + void VisualizeShadowMap(); VOBJREC * FindVisual (OBJHANDLE hObj) const; void RenderVesselMarker(vVessel *vV, D3D9Pad *pSketch); @@ -519,6 +529,9 @@ class Scene { LPDIRECT3DSURFACE9 psShmRT[SHM_LOD_COUNT]; LPDIRECT3DTEXTURE9 ptShmRT[SHM_LOD_COUNT]; + LPDIRECT3DSURFACE9 psVCShmRT[SHM_CASCADE_COUNT]; + LPDIRECT3DTEXTURE9 ptVCShmRT[SHM_CASCADE_COUNT]; + LocalLightsCompute LLCBuf[MAX_SCENE_LIGHTS + 1]; // Rendering Technique related parameters ============================================ diff --git a/OVP/D3D9Client/Surfmgr2.cpp b/OVP/D3D9Client/Surfmgr2.cpp index 5056100ac..18bf86604 100644 --- a/OVP/D3D9Client/Surfmgr2.cpp +++ b/OVP/D3D9Client/Surfmgr2.cpp @@ -1003,14 +1003,14 @@ void SurfTile::Render () if (sqrt(D3DXVec3Dot(&bc, &bc) - x * x) < (shd->rad + mesh->bsRad)) { float s = float(shd->size); float sr = 2.0f * shd->rad / s; - sp->mLVP = shd->mViewProj; + sp->mLVP = shd->mLVP; sp->vSHD = FVECTOR4(sr, 1.0f / s, 0.0f, 1.0f / shd->depth); fc->bShadows = true; } } } - pShader->SetTexture(pShader->tShadowMap, shd->pShadowMap); + pShader->SetTexture(pShader->tShadowMap, shd->pShadowMap[0]); } // --------------------------------------------------------------------- diff --git a/OVP/D3D9Client/VPlanet.cpp b/OVP/D3D9Client/VPlanet.cpp index 330ee7516..e2cc59ac7 100644 --- a/OVP/D3D9Client/VPlanet.cpp +++ b/OVP/D3D9Client/VPlanet.cpp @@ -928,8 +928,8 @@ bool vPlanet::Render(LPDIRECT3DDEVICE9 dev) float s = float(shd->size); float is = 1.0f / s; float qw = 1.0f / float(Config->ShadowMapSize); - HR(D3D9Effect::FX->SetMatrix(D3D9Effect::eLVP, &shd->mViewProj)); - HR(D3D9Effect::FX->SetTexture(D3D9Effect::eShadowMap, shd->pShadowMap)); + HR(D3D9Effect::FX->SetMatrix(D3D9Effect::eLVP, shd->mLVP.toCDX())); + HR(D3D9Effect::FX->SetTexture(D3D9Effect::eShadowMap, shd->pShadowMap[0])); HR(D3D9Effect::FX->SetVector(D3D9Effect::eSHD, ptr(D3DXVECTOR4(s, is, qw, 0)))); HR(D3D9Effect::FX->SetBool(D3D9Effect::eShadowToggle, true)); } diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index a4376f4a5..322cc0908 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -753,12 +753,21 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass) float sr = 2.0f * shd->rad / s; HR(D3D9Effect::FX->SetBool(D3D9Effect::eEnvMapEnable, false)); - HR(D3D9Effect::FX->SetMatrix(D3D9Effect::eLVP, &shd->mViewProj)); + HR(D3D9Effect::FX->SetMatrix(D3D9Effect::eLVP, shd->mLVP.toCDX())); // Cascade 0 for all if (shd->pShadowMap && (scn->GetRenderPass() == RENDERPASS_MAINSCENE)) { - HR(D3D9Effect::FX->SetTexture(D3D9Effect::eShadowMap, shd->pShadowMap)); - HR(D3D9Effect::FX->SetVector(D3D9Effect::eSHD, ptr(D3DXVECTOR4(sr, 1.0f / s, float(oapiRand()), 1.0f / shd->depth)))); + + D3DXVECTOR4 sh[2]; + sh[0] = D3DXVECTOR4(sr, 1.0f / s, float(oapiRand()), 1.0f / shd->depth); + sh[1] = D3DXVECTOR4(sr, 1.0f / s, float(oapiRand()), 1.0f / shd->depth); + + HR(D3D9Effect::FX->SetTexture(D3D9Effect::eShadowMap, shd->pShadowMap[0])); + HR(D3D9Effect::FX->SetValue(D3D9Effect::eSHD, &sh, sizeof(sh))); HR(D3D9Effect::FX->SetBool(D3D9Effect::eShadowToggle, true)); + + if (bVC) { + //HR(D3D9Effect::FX->SetTexture(D3D9Effect::eShadowMap2, shd->pShadowMap[1])); + } } else { HR(D3D9Effect::FX->SetBool(D3D9Effect::eShadowToggle, false)); @@ -836,7 +845,7 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass) } const LPD3DXMATRIX pVP = scn->GetProjectionViewMatrix(); - const LPD3DXMATRIX pLVP = (const LPD3DXMATRIX)&shd->mViewProj; + const LPD3DXMATRIX pLVP = (const LPD3DXMATRIX)&shd->mLVP; // Render vessel meshes -------------------------------------------------------------------------- // diff --git a/OVP/D3D9Client/shaders/BakedVC.fx b/OVP/D3D9Client/shaders/BakedVC.fx index f4269775a..a90995800 100644 --- a/OVP/D3D9Client/shaders/BakedVC.fx +++ b/OVP/D3D9Client/shaders/BakedVC.fx @@ -137,7 +137,7 @@ float4 BakedVC_PS(float4 sc : VPOS, PBRData frg) : COLOR // Add vessel self-shadows // ====================================================================== #if SHDMAP > 0 - cSun *= smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc)); + cSun *= smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc, gSHD[0])); #endif diff --git a/OVP/D3D9Client/shaders/Common.hlsl b/OVP/D3D9Client/shaders/Common.hlsl index 184f82f67..da40ab19c 100644 --- a/OVP/D3D9Client/shaders/Common.hlsl +++ b/OVP/D3D9Client/shaders/Common.hlsl @@ -251,48 +251,15 @@ void LocalLightsEx(out float3 cDiffLocal, out float3 cSpecLocal, in float3 nrmW, - - // ========================================================================================================== // Object Self Shadows // ========================================================================================================== -/* -float ProjectShadows(float2 sp) -{ - if (!gShadowsEnabled) return 0.0f; - - if (sp.x < 0 || sp.y < 0) return 0.0f; - if (sp.x > 1 || sp.y > 1) return 0.0f; - - float2 dx = float2(gSHD[1], 0) * 1.5f; - float2 dy = float2(0, gSHD[1]) * 1.5f; - float va = 0; - float pd = 1e-4; - - sp -= dy; - if ((tex2D(ShadowS, sp - dx).r) > pd) va++; - if ((tex2D(ShadowS, sp).r) > pd) va++; - if ((tex2D(ShadowS, sp + dx).r) > pd) va++; - sp += dy; - if ((tex2D(ShadowS, sp - dx).r) > pd) va++; - if ((tex2D(ShadowS, sp).r) > pd) va++; - if ((tex2D(ShadowS, sp + dx).r) > pd) va++; - sp += dy; - if ((tex2D(ShadowS, sp - dx).r) > pd) va++; - if ((tex2D(ShadowS, sp).r) > pd) va++; - if ((tex2D(ShadowS, sp + dx).r) > pd) va++; - - return va / 9.0f; -}*/ - -// --------------------------------------------------------------------------------------------------- -// -float SampleShadows(float2 sp, float pd) +float SampleShadows(float2 sp, float pd, float4 SHD) { - float2 dx = float2(gSHD[1], 0) * 1.5f; - float2 dy = float2(0, gSHD[1]) * 1.5f; + float2 dx = float2(SHD[1], 0) * 1.5f; + float2 dy = float2(0, SHD[1]) * 1.5f; float va = 0; sp -= dy; @@ -314,11 +281,11 @@ float SampleShadows(float2 sp, float pd) // --------------------------------------------------------------------------------------------------- // -float SampleShadows2(float2 sp, float pd) +float SampleShadows2(float2 sp, float pd, float4 SHD) { float val = 0; - float m = KERNEL_RADIUS * gSHD[1]; + float m = KERNEL_RADIUS * SHD[1]; [unroll] for (int i = 0; i < KERNEL_SIZE; i++) { if ((tex2D(ShadowS, sp + kernel[i].xy * m).r) > pd) val += kernel[i].z; @@ -330,11 +297,11 @@ float SampleShadows2(float2 sp, float pd) // --------------------------------------------------------------------------------------------------- // -float SampleShadows3(float2 sp, float pd, float4 frame) +float SampleShadows3(float2 sp, float pd, float4 frame, float4 SHD) { float val = 0; - frame *= KERNEL_RADIUS * gSHD[1]; + frame *= KERNEL_RADIUS * SHD[1]; [unroll] for (int i = 0; i < KERNEL_SIZE; i++) { float2 ofs = frame.xy*kernel[i].x + frame.zw*kernel[i].y; @@ -347,25 +314,26 @@ float SampleShadows3(float2 sp, float pd, float4 frame) // --------------------------------------------------------------------------------------------------- // -float SampleShadowsEx(float2 sp, float pd, float4 sc) +float SampleShadowsEx(float2 sp, float pd, float4 sc, float4 SHD) { #if SHDMAP == 1 - return SampleShadows(sp, pd); + return SampleShadows(sp, pd, SHD); #elif SHDMAP == 2 || SHDMAP == 4 - return SampleShadows2(sp, pd); + return SampleShadows2(sp, pd, SHD); #else float si, co; - sc += (gSHD[2] * 2.0f); + sc += (SHD[2] * 2.0f); sincos(sc.y + sc.x*149.0f, si, co); - return SampleShadows3(sp, pd, float4(si, co, co, -si)); + return SampleShadows3(sp, pd, float4(si, co, co, -si), SHD); #endif } + // --------------------------------------------------------------------------------------------------- // -float ComputeShadow(float4 shdH, float dLN, float4 sc) +float ComputeShadow(float4 shdH, float dLN, float4 sc, float4 SHD) { if (!gShadowsEnabled) return 1.0f; @@ -373,24 +341,24 @@ float ComputeShadow(float4 shdH, float dLN, float4 sc) shdH.z = 1 - shdH.z; float2 sp = shdH.xy * float2(0.5f, -0.5f) + float2(0.5f, 0.5f); - sp += gSHD[1] * 0.5f; + sp += SHD[1] * 0.5f; if (sp.x < 0 || sp.y < 0) return 1.0f; // If a sample is outside border -> fully lit if (sp.x > 1 || sp.y > 1) return 1.0f; float fShadow; - float kr = gSHD[0] * KERNEL_RADIUS; + float kr = SHD[0] * KERNEL_RADIUS; float dx = rsqrt(1.0 - dLN*dLN); float ofs = 0.33f * kr / (dLN * dx); - float omx = min(gSHD[0] * 2.0f + max(0, ofs), 0.25); + float omx = min(SHD[0] * 2.0f + max(0, ofs), 0.25); - float pd = shdH.z + omx * gSHD[3]; + float pd = shdH.z + omx * SHD[3]; if (pd < 0) pd = 0; if (pd > 1) pd = 1; - fShadow = SampleShadowsEx(sp, pd, sc); + fShadow = SampleShadowsEx(sp, pd, sc, SHD); return 1 - fShadow; } diff --git a/OVP/D3D9Client/shaders/D3D9Client.fx b/OVP/D3D9Client/shaders/D3D9Client.fx index 0c5af7b93..f8d6e491a 100644 --- a/OVP/D3D9Client/shaders/D3D9Client.fx +++ b/OVP/D3D9Client/shaders/D3D9Client.fx @@ -96,7 +96,7 @@ uniform extern float4 gFogColor; // Distance fog color in "Legacy" im uniform extern float4 gAtmColor; // Earth glow color uniform extern float4 gTexOff; // Texture offsets used by surface manager uniform extern float4 gRadius; // PlanetRad, AtmOuterLimit, CameraRad, CameraAlt -uniform extern float4 gSHD; // ShadowMap data +uniform extern float4 gSHD[2]; // ShadowMap data uniform extern float3 gCameraPos; // Planet relative camera position, Unit vector uniform extern float3 gNorth; uniform extern float3 gEast; @@ -149,6 +149,7 @@ uniform extern texture gHeatMap; // Heat Map uniform extern texture gTranslMap; // Translucence Map uniform extern texture gTransmMap; // Transmittance Map uniform extern texture gShadowMap; // Shadow Map +uniform extern texture gShadowMap2; // Shadow Map2 uniform extern texture gIrradianceMap; // Irradiance Map uniform extern texture gAmbientMap; // Baked Ambient occlusion map uniform extern texture gCombinedMap; // Combined baked light map diff --git a/OVP/D3D9Client/shaders/Metalness.fx b/OVP/D3D9Client/shaders/Metalness.fx index 12665eb34..6d0646d2f 100644 --- a/OVP/D3D9Client/shaders/Metalness.fx +++ b/OVP/D3D9Client/shaders/Metalness.fx @@ -285,7 +285,7 @@ float4 MetalnessPS(float4 sc : VPOS, PBRData frg) : COLOR // Add vessel self-shadows // ====================================================================== #if SHDMAP > 0 - cSun *= smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc)); + cSun *= smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc, gSHD[0])); #endif diff --git a/OVP/D3D9Client/shaders/PBR.fx b/OVP/D3D9Client/shaders/PBR.fx index b4816e962..c2fc8fd74 100644 --- a/OVP/D3D9Client/shaders/PBR.fx +++ b/OVP/D3D9Client/shaders/PBR.fx @@ -172,7 +172,7 @@ float4 PBR_PS(float4 sc : VPOS, PBRData frg) : COLOR // ---------------------------------------------------------------------- #if SHDMAP > 0 - cSun *= smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc)); + cSun *= smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc, gSHD[0])); #endif @@ -431,7 +431,7 @@ float4 FAST_PS(float4 sc : VPOS, FASTData frg) : COLOR // ---------------------------------------------------------------------- #if SHDMAP > 0 - float fShadow = smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc)); + float fShadow = smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc, gSHD[0])); dLN *= fShadow; #endif diff --git a/OVP/D3D9Client/shaders/Vessel.fx b/OVP/D3D9Client/shaders/Vessel.fx index 9cd383491..30342ba47 100644 --- a/OVP/D3D9Client/shaders/Vessel.fx +++ b/OVP/D3D9Client/shaders/Vessel.fx @@ -124,7 +124,7 @@ float4 AdvancedPS(float4 sc : VPOS, PBRData frg) : COLOR // ---------------------------------------------------------------------- #if SHDMAP > 0 - cSun.rgb *= ComputeShadow(frg.shdH, dLN, sc); + cSun.rgb *= ComputeShadow(frg.shdH, dLN, sc, gSHD[0]); #endif diff --git a/Orbitersdk/include/DrawAPI.h b/Orbitersdk/include/DrawAPI.h index c60cc7218..dd0def505 100644 --- a/Orbitersdk/include/DrawAPI.h +++ b/Orbitersdk/include/DrawAPI.h @@ -175,6 +175,18 @@ namespace oapi { return FVECTOR2(x - f.x, y - f.y); } + inline FVECTOR2& operator*= (float f) + { + x *= f; y *= f; + return *this; + } + + inline FVECTOR2& operator/= (float f) + { + x /= f; y /= f; + return *this; + } + float x, y; } FVECTOR2; @@ -648,6 +660,17 @@ namespace oapi { { return (LPD3DXMATRIX)this; } + + inline LPD3DXMATRIX toDX() + { + return (LPD3DXMATRIX)this; + } + + inline const D3DXMATRIX* toCDX() const + { + return (const D3DXMATRIX*)this; + } + #endif void Zero() From f361bf49bbfc74b3bb034d1812ed0c8db850ce76 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Sun, 30 Jul 2023 22:13:31 +0300 Subject: [PATCH 12/42] - Fixed a VC shadow bug, exported VC ambient level to shaders. --- OVP/D3D9Client/D3D9Effect.cpp | 2 ++ OVP/D3D9Client/D3D9Effect.h | 1 + OVP/D3D9Client/Mesh.cpp | 3 +- OVP/D3D9Client/Scene.cpp | 43 +++++++++++++++++++--------- OVP/D3D9Client/Scene.h | 4 +-- OVP/D3D9Client/shaders/BakedVC.fx | 3 +- OVP/D3D9Client/shaders/D3D9Client.fx | 1 + 7 files changed, 39 insertions(+), 18 deletions(-) diff --git a/OVP/D3D9Client/D3D9Effect.cpp b/OVP/D3D9Client/D3D9Effect.cpp index 4c29c5845..075d64817 100644 --- a/OVP/D3D9Client/D3D9Effect.cpp +++ b/OVP/D3D9Client/D3D9Effect.cpp @@ -122,6 +122,7 @@ D3DXHANDLE D3D9Effect::eExposure = 0; D3DXHANDLE D3D9Effect::eCameraPos = 0; D3DXHANDLE D3D9Effect::eNorth = 0; D3DXHANDLE D3D9Effect::eEast = 0; +D3DXHANDLE D3D9Effect::eVCAmbient = 0; D3DXHANDLE D3D9Effect::eDistScale = 0; D3DXHANDLE D3D9Effect::eRadius = 0; D3DXHANDLE D3D9Effect::eAttennuate = 0; @@ -441,6 +442,7 @@ void D3D9Effect::D3D9TechInit(D3D9Client *_gc, LPDIRECT3DDEVICE9 _pDev, const ch eCameraPos = FX->GetParameterByName(0,"gCameraPos"); eNorth = FX->GetParameterByName(0,"gNorth"); eEast = FX->GetParameterByName(0,"gEast"); + eVCAmbient = FX->GetParameterByName(0,"gVCAmbient"); ePointScale = FX->GetParameterByName(0,"gPointScale"); eMix = FX->GetParameterByName(0,"gMix"); eTime = FX->GetParameterByName(0,"gTime"); diff --git a/OVP/D3D9Client/D3D9Effect.h b/OVP/D3D9Client/D3D9Effect.h index 1c5c48ac8..60bcbe140 100644 --- a/OVP/D3D9Client/D3D9Effect.h +++ b/OVP/D3D9Client/D3D9Effect.h @@ -151,6 +151,7 @@ class D3D9Effect { static D3DXHANDLE eCameraPos; static D3DXHANDLE eNorth; static D3DXHANDLE eEast; + static D3DXHANDLE eVCAmbient; static D3DXHANDLE eDistScale; static D3DXHANDLE eGlowConst; static D3DXHANDLE eRadius; diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index cc954e5f3..929436efc 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -186,7 +186,7 @@ void D3D9Mesh::Null(const char *meshName /* = NULL */) pBuf = NULL; Mtrl = NULL; pGrpTF = NULL; - cAmbient = 0; + cAmbient = { 0.0f, 0.0f, 0.0f }; MaxFace = 0; MaxVert = 0; vClass = 0; @@ -1640,6 +1640,7 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, int iTech, LPDIRECT3DCUBETEXTURE9 * FX->SetBool(eLightsEnabled, false); FX->SetBool(eOITEnable, false); FX->SetVector(eColor, ptr(D3DXVECTOR4(0, 0, 0, 0))); + FX->SetValue(eVCAmbient, &cAmbient, sizeof(FVECTOR3)); ConfigureAtmo(); diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index 346ac0ad4..aa223bab3 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -2000,9 +2000,17 @@ void Scene::RenderMainScene() { SmapRenderList.clear(); - float rad = 6.0f; +#if SHM_CASCADE_COUNT == 1 + float rad = 1.5f; +#endif +#if SHM_CASCADE_COUNT == 2 + float rad = 4.5f; +#endif +#if SHM_CASCADE_COUNT == 3 + float rad = 9.0f; +#endif D3DXVECTOR3 ld = sunLight.Dir; - D3DXVECTOR3 pos = Camera.z * rad; + D3DXVECTOR3 pos = Camera.z * rad * 0.75f; RenderVCShadowMap(pos, ld, rad, false); @@ -2576,8 +2584,7 @@ int Scene::RenderShadowMap(D3DXVECTOR3 &pos, D3DXVECTOR3 &ld, float rad, bool bI BeginPass(RENDERPASS_SHADOWMAP); while(SmapRenderList.size()>0) { - SmapRenderList.front()->Render(pDevice, false); - if (bInternal) SmapRenderList.front()->Render(pDevice, true); + SmapRenderList.front()->Render(pDevice, bInternal); SmapRenderList.pop_front(); } @@ -2648,26 +2655,27 @@ int Scene::RenderVCShadowMap(D3DXVECTOR3& pos, D3DXVECTOR3& ld, float rad, bool } } - smap.depth = (mxd + rad); smap.dist = mxd; smap.lod = 0; smap.size = Config->ShadowMapSize; smap.cascades = SHM_CASCADE_COUNT; + smap.depth = (mxd + vFocus->GetSize()); - float fnear = -rad; - float ffar = smap.depth; D3DXMATRIX mProj, mView; - FMATRIX4 mV; - + for (int i = 0; i < SHM_CASCADE_COUNT; i++) { - D3DXVECTOR3 ep = pos - ld * smap.dist; + // Compute mLVP needed to render this cascade. - D3DXMatrixOrthoOffCenterRH(&mProj, -rad, rad, rad, -rad, fnear, ffar); - D3DXMatrixLookAtRH(&mView, &ep, &pos, ptr(D3DXVECTOR3(0, 1, 0))); + // Project pos to a shadow plane + D3DXVECTOR3 sp = pos - ld * D3DXVec3Dot(&pos, &ld); + D3DXVECTOR3 ep = sp - ld * smap.dist; + D3DXMatrixOrthoOffCenterRH(&mProj, -rad, rad, rad, -rad, 0, smap.depth); + D3DXMatrixLookAtRH(&mView, &ep, &sp, ptr(D3DXVECTOR3(0, 1, 0))); D3DXMatrixMultiply(smap.mLVP.toDX(), &mView, &mProj); - smap.mVP[i] = smap.mLVP; + // Backup projection for a cascade for later use + smap.mVP[i] = smap.mLVP; D3DXVECTOR3 xy; D3DXVec3TransformCoord(&xy, &pos, smap.mVP[0].toDX()); @@ -2676,12 +2684,15 @@ int Scene::RenderVCShadowMap(D3DXVECTOR3& pos, D3DXVECTOR3& ld, float rad, bool xy.y = -xy.y; xy = (xy + 1.0f) * 0.5f; + // Cascade's center and subrect within the main level (i.e '0') + // All cascades share the same near and far plane and exists inside the previous cascade. smap.Center[i] = { xy.x, xy.y }; smap.Subrect[i] = { xy.x - r, xy.y - r, xy.x + r, xy.y + r }; +#ifdef CASCADE_DEBUG D3D9DebugLog("Cascade %i pos=[%f, %f]", i, xy.x, xy.y); D3D9DebugLog("Cascade %i rect=[%f, %f, %f, %f]", i, xy.x-r, xy.y-r, xy.x+r, xy.y+r); - +#endif gc->PushRenderTarget(psVCShmRT[i], psShmDS[0], RENDERPASS_SHADOWMAP); // Clear the viewport @@ -2691,6 +2702,8 @@ int Scene::RenderVCShadowMap(D3DXVECTOR3& pos, D3DXVECTOR3& ld, float rad, bool // BeginPass(RENDERPASS_SHADOWMAP); + + // NOTE: smap.mLVP must containg the projection needed for rendering of the map for (auto &a : SmapRenderList) { a->Render(pDevice, false); @@ -3125,7 +3138,9 @@ void Scene::VisualizeShadowMap() RECT tgt = { l,t,r,b }; + pSketch->SetRenderParam(Sketchpad::RenderParam::PRM_GAMMA, ptr(FVECTOR4(0.25f, 0.25f, 0.25f, 1.0f))); pSketch->StretchRectNative(smap.pShadowMap[i], NULL, &tgt); + pSketch->SetRenderParam(Sketchpad::RenderParam::PRM_GAMMA, NULL); pSketch->QuickBrush(0); pSketch->QuickPen(0xFFFFFFFF); pSketch->Rectangle(l, t, r, b); diff --git a/OVP/D3D9Client/Scene.h b/OVP/D3D9Client/Scene.h index d9ca2d9c2..ae10269b1 100644 --- a/OVP/D3D9Client/Scene.h +++ b/OVP/D3D9Client/Scene.h @@ -40,7 +40,7 @@ class D3D9Pad; #define GBUF_COUNT 5 // Buffer count #define SHM_LOD_COUNT 5 -#define SHM_CASCADE_COUNT 3 +#define SHM_CASCADE_COUNT 1 #define SHM_CASCADE_RATIO 0.3333333333f #define TEX_NOISE 0 @@ -168,7 +168,7 @@ class Scene { D3DXVECTOR3 pos; // Shadow map origin D3DXVECTOR3 ld; // Light direction float rad; // radius of the area covered by map [meters] - float dist; // far plane distance from shadow origin + float dist; // Shadow camera distance from shadow origin float depth; // near to far plane distance. i.r. depth of the field int lod; // level of detail, 0 = highest int size; // Map size in pixels diff --git a/OVP/D3D9Client/shaders/BakedVC.fx b/OVP/D3D9Client/shaders/BakedVC.fx index a90995800..4dc706d01 100644 --- a/OVP/D3D9Client/shaders/BakedVC.fx +++ b/OVP/D3D9Client/shaders/BakedVC.fx @@ -181,7 +181,8 @@ float4 BakedVC_PS(float4 sc : VPOS, PBRData frg) : COLOR // Add a faint diffuse hue for rough metals. Rough metal doesn't look good if it's totally black fA += fRgh * fMetal * 0.05f; - float3 zD = cDiff.rgb * fA * cBL * LightFXSq(gMtrl.diffuse.rgb * (Sq(cSun * fR * dLN)) + Sq(gMtrl.emissive.rgb) + Sq(cBL)); + // gVCAmbient is an application and debug controls controllable variable + float3 zD = cDiff.rgb * fA * LightFXSq(gMtrl.diffuse.rgb * (Sq(cSun * fR * dLN)) + Sq(gMtrl.emissive.rgb) + Sq(cBL) + Sq(gVCAmbient)); // Combine specular terms float3 zS = cS * (cSun * dLN); diff --git a/OVP/D3D9Client/shaders/D3D9Client.fx b/OVP/D3D9Client/shaders/D3D9Client.fx index f8d6e491a..885618e72 100644 --- a/OVP/D3D9Client/shaders/D3D9Client.fx +++ b/OVP/D3D9Client/shaders/D3D9Client.fx @@ -100,6 +100,7 @@ uniform extern float4 gSHD[2]; // ShadowMap data uniform extern float3 gCameraPos; // Planet relative camera position, Unit vector uniform extern float3 gNorth; uniform extern float3 gEast; +uniform extern float3 gVCAmbient; // Ambient level inside virtual cockpit uniform extern Sun gSun; // Sun light direction uniform extern Mat gMat; // Material input structure TODO: Remove all reference to this. Use gMtrl uniform extern Mat gWater; // Water material input structure From 2feb632a766b816a6d26ad009b13f21bd7cb6fe5 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Tue, 1 Aug 2023 00:00:33 +0300 Subject: [PATCH 13/42] Cleaned up shadow maps Fed shadow cascades to shaders Added a debug visualization of cascade coverage --- OVP/D3D9Client/D3D9Client.h | 21 +++++++ OVP/D3D9Client/D3D9Config.cpp | 3 + OVP/D3D9Client/D3D9Config.h | 3 +- OVP/D3D9Client/D3D9Effect.cpp | 6 +- OVP/D3D9Client/D3D9Effect.h | 3 +- OVP/D3D9Client/Mesh.cpp | 53 ++++++++++++++++- OVP/D3D9Client/Mesh.h | 4 ++ OVP/D3D9Client/Scene.cpp | 44 +++++++------- OVP/D3D9Client/Scene.h | 23 +------- OVP/D3D9Client/Surfmgr2.cpp | 2 +- OVP/D3D9Client/VPlanet.cpp | 5 +- OVP/D3D9Client/VVessel.cpp | 25 ++++---- OVP/D3D9Client/shaders/BakedVC.fx | 2 +- OVP/D3D9Client/shaders/Common.hlsl | 87 ++++++++++++++++++---------- OVP/D3D9Client/shaders/D3D9Client.fx | 16 +---- OVP/D3D9Client/shaders/Metalness.fx | 10 +++- OVP/D3D9Client/shaders/PBR.fx | 6 +- OVP/D3D9Client/shaders/Vessel.fx | 2 +- 18 files changed, 198 insertions(+), 117 deletions(-) diff --git a/OVP/D3D9Client/D3D9Client.h b/OVP/D3D9Client/D3D9Client.h index 81178eadd..46ad4b183 100644 --- a/OVP/D3D9Client/D3D9Client.h +++ b/OVP/D3D9Client/D3D9Client.h @@ -33,6 +33,10 @@ #include #include "WindowMgr.h" +#define SHM_CASCADE_COUNT 3 +#define SHM_LOD_COUNT 5 + + #define PP_DEFAULT 0x1 #define PP_LENSFLARE 0x2 @@ -125,6 +129,23 @@ struct RenderTgtData { }; +struct SHADOWMAPPARAM { + LPDIRECT3DTEXTURE9 pShadowMap[SHM_CASCADE_COUNT]; + // Index 0 is also used for exterior map where the map size varies by LOD, distant object may use 128x128 map + // Interior VC cascades are all same size + FMATRIX4 mVP[SHM_CASCADE_COUNT]; + FVECTOR4 Subrect[SHM_CASCADE_COUNT]; + FVECTOR2 Center[SHM_CASCADE_COUNT]; + FMATRIX4 mLVP; + D3DXVECTOR3 pos; // Shadow map origin i.e. Cascade '0' origin + D3DXVECTOR3 ld; // Light direction + float rad; // radius of the area covered by map [meters] + float dist; // Shadow camera distance from shadow origin + float depth; // near to far plane distance. i.r. depth of the field + int lod; // level of detail, 0 = highest + int size; // Map size in pixels + int cascades; // Number of active cascades +}; diff --git a/OVP/D3D9Client/D3D9Config.cpp b/OVP/D3D9Client/D3D9Config.cpp index bbdb1f92f..fb551e336 100644 --- a/OVP/D3D9Client/D3D9Config.cpp +++ b/OVP/D3D9Client/D3D9Config.cpp @@ -96,6 +96,7 @@ void D3D9Config::Reset () bIrradiance = 1; bAtmoQuality = 1; NoPlanetAA = 0; + VCCascadeCount = 1; GFXIntensity = 0.5; GFXDistance = 0.8; @@ -192,6 +193,7 @@ bool D3D9Config::ReadParams () if (oapiReadItem_int (hFile, (char*)"DebugBreak", i)) DebugBreak = max(0, min(1, i)); if (oapiReadItem_int (hFile, (char*)"ShaderCacheUse", i)) ShaderCacheUse = max(0, min(1, i)); if (oapiReadItem_int (hFile, (char*)"NoPlanetAA", i)) NoPlanetAA = max(0, min(1, i)); + if (oapiReadItem_int (hFile, (char*)"VCCascadeCount", i)) VCCascadeCount = max(1, min(3, i)); if (oapiReadItem_float (hFile, (char*)"OrbitalShadowMult", d)) OrbitalShadowMult = max(0.5, min(10.0, d)); if (oapiReadItem_float (hFile, (char*)"GFXIntensity", d)) GFXIntensity = max(0.0, min(1.0, d)); @@ -281,6 +283,7 @@ void D3D9Config::WriteParams () oapiWriteItem_int (hFile, (char*)"DebugBreak", DebugBreak); oapiWriteItem_int (hFile, (char*)"ShaderCacheUse", ShaderCacheUse); oapiWriteItem_int (hFile, (char*)"NoPlanetAA", NoPlanetAA); + oapiWriteItem_int (hFile, (char*)"VCCascadeCount", VCCascadeCount); oapiWriteItem_float (hFile, (char*)"OrbitalShadowMult", OrbitalShadowMult); oapiWriteItem_float (hFile, (char*)"GFXIntensity", GFXIntensity); diff --git a/OVP/D3D9Client/D3D9Config.h b/OVP/D3D9Client/D3D9Config.h index de2cbcedc..edfab8616 100644 --- a/OVP/D3D9Client/D3D9Config.h +++ b/OVP/D3D9Client/D3D9Config.h @@ -96,7 +96,8 @@ class D3D9Config { int bLocalGlares; int bIrradiance; int bAtmoQuality; - int NoPlanetAA; ///< Disable planet surface anti-aliasing to prevent white pixels at horizon + int NoPlanetAA; ///< Disable planet surface anti-aliasing to prevent white pixels at horizon + int VCCascadeCount; char *DebugFont; ///< Font face for debug lines (default="Fixed") char *SolCfg; ///< Solar system to use (default="Sol") double GFXIntensity; ///< Post Processing | Light glow intensity (0.0...1.0, default=0.5) diff --git a/OVP/D3D9Client/D3D9Effect.cpp b/OVP/D3D9Client/D3D9Effect.cpp index 075d64817..4d7654d91 100644 --- a/OVP/D3D9Client/D3D9Effect.cpp +++ b/OVP/D3D9Client/D3D9Effect.cpp @@ -78,7 +78,6 @@ D3DXHANDLE D3D9Effect::eReflMap = 0; D3DXHANDLE D3D9Effect::eRghnMap = 0; D3DXHANDLE D3D9Effect::eMetlMap = 0; D3DXHANDLE D3D9Effect::eHeatMap = 0; -D3DXHANDLE D3D9Effect::eShadowMap = 0; D3DXHANDLE D3D9Effect::eTranslMap = 0; D3DXHANDLE D3D9Effect::eTransmMap = 0; D3DXHANDLE D3D9Effect::eIrradMap = 0; @@ -95,6 +94,7 @@ D3DXHANDLE D3D9Effect::eMix = 0; // FLOAT Auxiliary factor/multiplier D3DXHANDLE D3D9Effect::eFogDensity = 0; // D3DXHANDLE D3D9Effect::ePointScale = 0; D3DXHANDLE D3D9Effect::eSHD = 0; +D3DXHANDLE D3D9Effect::eSHDSubRect = 0; D3DXHANDLE D3D9Effect::eAtmColor = 0; D3DXHANDLE D3D9Effect::eProxySize = 0; @@ -116,6 +116,7 @@ D3DXHANDLE D3D9Effect::eInSpace = 0; // BOOL D3DXHANDLE D3D9Effect::eNoColor = 0; // BOOL D3DXHANDLE D3D9Effect::eLightsEnabled = 0; // BOOL D3DXHANDLE D3D9Effect::eBaseBuilding = 0; // BOOL +D3DXHANDLE D3D9Effect::eCockpit = 0; D3DXHANDLE D3D9Effect::eOITEnable = 0; // BOOL // -------------------------------------------------------------- D3DXHANDLE D3D9Effect::eExposure = 0; @@ -429,6 +430,7 @@ void D3D9Effect::D3D9TechInit(D3D9Client *_gc, LPDIRECT3DDEVICE9 _pDev, const ch eNoColor = FX->GetParameterByName(0,"gNoColor"); eLightsEnabled = FX->GetParameterByName(0,"gLightsEnabled"); eBaseBuilding = FX->GetParameterByName(0,"gBaseBuilding"); + eCockpit = FX->GetParameterByName(0,"gCockpit"); eOITEnable = FX->GetParameterByName(0,"gOITEnable"); // General parameters -------------------------------------------------- @@ -449,6 +451,7 @@ void D3D9Effect::D3D9TechInit(D3D9Client *_gc, LPDIRECT3DDEVICE9 _pDev, const ch eMtrlAlpha = FX->GetParameterByName(0,"gMtrlAlpha"); eGlowConst = FX->GetParameterByName(0,"gGlowConst"); eSHD = FX->GetParameterByName(0,"gSHD"); + eSHDSubRect = FX->GetParameterByName(0,"gSHDSubRect"); eKernel = FX->GetParameterByName(0,"kernel"); eAtmoParams = FX->GetParameterByName(0,"gAtmo"); // ---------------------------------------------------------------------- @@ -472,7 +475,6 @@ void D3D9Effect::D3D9TechInit(D3D9Client *_gc, LPDIRECT3DDEVICE9 _pDev, const ch eRghnMap = FX->GetParameterByName(0,"gRghnMap"); eMetlMap = FX->GetParameterByName(0,"gMetlMap"); eHeatMap = FX->GetParameterByName(0,"gHeatMap"); - eShadowMap = FX->GetParameterByName(0,"gShadowMap"); eTranslMap = FX->GetParameterByName(0, "gTranslMap"); eTransmMap = FX->GetParameterByName(0, "gTransmMap"); eIrradMap = FX->GetParameterByName(0,"gIrradianceMap"); diff --git a/OVP/D3D9Client/D3D9Effect.h b/OVP/D3D9Client/D3D9Effect.h index 60bcbe140..3219f7dcf 100644 --- a/OVP/D3D9Client/D3D9Effect.h +++ b/OVP/D3D9Client/D3D9Effect.h @@ -134,6 +134,7 @@ class D3D9Effect { static D3DXHANDLE eNoColor; ///< BOOL static D3DXHANDLE eLightsEnabled;///< BOOL static D3DXHANDLE eBaseBuilding; ///< BOOL + static D3DXHANDLE eCockpit; ///< BOOL static D3DXHANDLE eFresnel; ///< BOOL static D3DXHANDLE eSwitch; ///< BOOL static D3DXHANDLE eRghnSw; ///< BOOL @@ -163,6 +164,7 @@ class D3D9Effect { static D3DXHANDLE eAttennuate; static D3DXHANDLE eInScatter; static D3DXHANDLE eSHD; + static D3DXHANDLE eSHDSubRect; static D3DXHANDLE eNight; // Textures -------------------------------------------------------- @@ -178,7 +180,6 @@ class D3D9Effect { static D3DXHANDLE eRghnMap; static D3DXHANDLE eTranslMap; static D3DXHANDLE eTransmMap; - static D3DXHANDLE eShadowMap; static D3DXHANDLE eIrradMap; static D3DXHANDLE eAmbientMap; static D3DXHANDLE eCombinedMap; diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index 929436efc..8d6c45710 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -24,8 +24,10 @@ using namespace oapi; - +LPDIRECT3DTEXTURE9 D3D9Mesh::pShadowMap[SHM_CASCADE_COUNT] = {}; +FVECTOR4 D3D9Mesh::ShdSubRect[SHM_CASCADE_COUNT] = {}; MeshShader* D3D9Mesh::s_pShader[16] = {}; + MeshShader::VSConst MeshShader::vs_const = {}; MeshShader::PSConst MeshShader::ps_const = {}; MeshShader::PSBools MeshShader::ps_bools = {}; @@ -204,6 +206,11 @@ void D3D9Mesh::Null(const char *meshName /* = NULL */) Locals = new LightStruct[Config->MaxLights()]; + for (int i = 0; i < SHM_CASCADE_COUNT; i++) { + pShadowMap[i] = NULL; + ShdSubRect[i] = { 0,0,1,1 }; + } + memset(Locals, 0, sizeof(LightStruct) * Config->MaxLights()); memset(LightList, 0, sizeof(LightList)); strcpy_s(this->name, ARRAYSIZE(this->name), meshName ? meshName : "???"); @@ -1527,6 +1534,45 @@ void D3D9Mesh::ConfigureAtmo() } +// =========================================================================================== +// Setup shadow map samplers and textures +// +void D3D9Mesh::ConfigureShadows() +{ + for (int i = 0; i < SHM_CASCADE_COUNT; i++) + { + int idx = 13 + i; // Sampler index + HR(pDev->SetSamplerState(idx, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP)); + HR(pDev->SetSamplerState(idx, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP)); + HR(pDev->SetSamplerState(idx, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP)); + HR(pDev->SetSamplerState(idx, D3DSAMP_MAGFILTER, D3DTEXF_POINT)); + HR(pDev->SetSamplerState(idx, D3DSAMP_MINFILTER, D3DTEXF_POINT)); + HR(pDev->SetSamplerState(idx, D3DSAMP_MIPFILTER, D3DTEXF_NONE)); + HR(pDev->SetTexture(idx, pShadowMap[i])); + } + HR(FX->SetValue(D3D9Effect::eSHDSubRect, ShdSubRect, sizeof(ShdSubRect))); +} + + +// =========================================================================================== +// static: +void D3D9Mesh::SetShadows(const SHADOWMAPPARAM *sprm) +{ + if (sprm) { + for (int i = 0; i < SHM_CASCADE_COUNT; i++) { + pShadowMap[i] = sprm->pShadowMap[i]; + ShdSubRect[i] = sprm->Subrect[i]; + } + } + else { + for (int i = 0; i < SHM_CASCADE_COUNT; i++) { + pShadowMap[i] = NULL; + ShdSubRect[i] = { 0,0,1,1 }; + } + } +} + + // ================================================================================================ // This is a rendering routine for a Exterior Mesh, non-spherical moons/asteroids // @@ -1576,12 +1622,14 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, int iTech, LPDIRECT3DCUBETEXTURE9 * bool bGroupCull = true; bool bUpdateFlow = true; bool bShadowProjection = false; + bool bVirtualCockpit = false; switch (iTech) { case RENDER_VC: EnablePlanetGlow(false); + bVirtualCockpit = true; break; case RENDER_BASE: EnablePlanetGlow(false); @@ -1605,6 +1653,7 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, int iTech, LPDIRECT3DCUBETEXTURE9 * } HR(D3D9Effect::FX->SetBool(D3D9Effect::eBaseBuilding, bShadowProjection)); + HR(D3D9Effect::FX->SetBool(D3D9Effect::eCockpit, bVirtualCockpit)); D3DXVECTOR4 Field; D3DXMATRIX mWorldView, q; @@ -1632,6 +1681,8 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, int iTech, LPDIRECT3DCUBETEXTURE9 * pDev->SetStreamSource(0, pBuf->pVB, 0, sizeof(NMVERTEX)); pDev->SetIndices(pBuf->pIB); + ConfigureShadows(); + if (flags&DBG_FLAGS_DUALSIDED) pDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); FX->SetTechnique(eVesselTech); diff --git a/OVP/D3D9Client/Mesh.h b/OVP/D3D9Client/Mesh.h index 3ebb2284a..cf038095e 100644 --- a/OVP/D3D9Client/Mesh.h +++ b/OVP/D3D9Client/Mesh.h @@ -338,6 +338,7 @@ class D3D9Mesh : private D3D9Effect static void GlobalInit(LPDIRECT3DDEVICE9 pDev); static void GlobalExit(); + static void SetShadows(const SHADOWMAPPARAM* sprm); private: @@ -349,6 +350,7 @@ class D3D9Mesh : private D3D9Effect void Null(const char *meshName = NULL); void UpdateFlags(); void ConfigureAtmo(); + void ConfigureShadows(); WORD DefShader; DWORD MaxVert; @@ -380,6 +382,8 @@ class D3D9Mesh : private D3D9Effect char name[128]; + static LPDIRECT3DTEXTURE9 pShadowMap[SHM_CASCADE_COUNT]; + static FVECTOR4 ShdSubRect[SHM_CASCADE_COUNT]; static MeshShader* s_pShader[16]; }; diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index aa223bab3..107c95eb1 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -1999,20 +1999,16 @@ void Scene::RenderMainScene() if (Config->ShadowMapMode >= 1) { SmapRenderList.clear(); + float dist = 1.5f; + fCascadeRatio = 1.00f; -#if SHM_CASCADE_COUNT == 1 - float rad = 1.5f; -#endif -#if SHM_CASCADE_COUNT == 2 - float rad = 4.5f; -#endif -#if SHM_CASCADE_COUNT == 3 - float rad = 9.0f; -#endif + if (Config->VCCascadeCount == 2) dist = 4.00f, fCascadeRatio = 0.33f; + if (Config->VCCascadeCount == 3) dist = 6.25f, fCascadeRatio = 0.40f; + D3DXVECTOR3 ld = sunLight.Dir; - D3DXVECTOR3 pos = Camera.z * rad * 0.75f; + D3DXVECTOR3 pos = Camera.z * dist * 0.75f; - RenderVCShadowMap(pos, ld, rad, false); + RenderVCShadowMap(pos, ld, dist, false); pShdMap = smap.pShadowMap[0]; } @@ -2658,12 +2654,12 @@ int Scene::RenderVCShadowMap(D3DXVECTOR3& pos, D3DXVECTOR3& ld, float rad, bool smap.dist = mxd; smap.lod = 0; smap.size = Config->ShadowMapSize; - smap.cascades = SHM_CASCADE_COUNT; + smap.cascades = Config->VCCascadeCount; smap.depth = (mxd + vFocus->GetSize()); D3DXMATRIX mProj, mView; - for (int i = 0; i < SHM_CASCADE_COUNT; i++) + for (int i = 0; i < smap.cascades; i++) { // Compute mLVP needed to render this cascade. @@ -2672,10 +2668,7 @@ int Scene::RenderVCShadowMap(D3DXVECTOR3& pos, D3DXVECTOR3& ld, float rad, bool D3DXVECTOR3 ep = sp - ld * smap.dist; D3DXMatrixOrthoOffCenterRH(&mProj, -rad, rad, rad, -rad, 0, smap.depth); D3DXMatrixLookAtRH(&mView, &ep, &sp, ptr(D3DXVECTOR3(0, 1, 0))); - D3DXMatrixMultiply(smap.mLVP.toDX(), &mView, &mProj); - - // Backup projection for a cascade for later use - smap.mVP[i] = smap.mLVP; + D3DXMatrixMultiply(smap.mVP[i].toDX(), &mView, &mProj); D3DXVECTOR3 xy; D3DXVec3TransformCoord(&xy, &pos, smap.mVP[0].toDX()); @@ -2702,16 +2695,17 @@ int Scene::RenderVCShadowMap(D3DXVECTOR3& pos, D3DXVECTOR3& ld, float rad, bool // BeginPass(RENDERPASS_SHADOWMAP); - // NOTE: smap.mLVP must containg the projection needed for rendering of the map + smap.mLVP = smap.mVP[i]; + for (auto &a : SmapRenderList) { a->Render(pDevice, false); if (a == vFocus) a->Render(pDevice, true); } - rad *= SHM_CASCADE_RATIO; - pos *= SHM_CASCADE_RATIO; + rad *= fCascadeRatio; + pos *= fCascadeRatio; PopPass(); @@ -2720,6 +2714,9 @@ int Scene::RenderVCShadowMap(D3DXVECTOR3& pos, D3DXVECTOR3& ld, float rad, bool smap.pShadowMap[i] = ptVCShmRT[i]; } + // smap.mLVP must point to cascade '0' by default + smap.mLVP = smap.mVP[0]; + return 0; } @@ -3142,7 +3139,7 @@ void Scene::VisualizeShadowMap() pSketch->StretchRectNative(smap.pShadowMap[i], NULL, &tgt); pSketch->SetRenderParam(Sketchpad::RenderParam::PRM_GAMMA, NULL); pSketch->QuickBrush(0); - pSketch->QuickPen(0xFFFFFFFF); + pSketch->QuickPen(0xFFFF00FF); pSketch->Rectangle(l, t, r, b); } pSketch->EndDrawing(); @@ -3180,7 +3177,7 @@ void Scene::RenderMesh(DEVMESHHANDLE hMesh, const oapi::FMATRIX4 *pWorld) { D3D9Mesh *pMesh = (D3D9Mesh *)hMesh; - const Scene::SHADOWMAPPARAM *shd = GetSMapData(); + const SHADOWMAPPARAM *shd = GetSMapData(); float s = float(shd->size); float sr = 2.0f * shd->rad / s; @@ -3188,11 +3185,12 @@ void Scene::RenderMesh(DEVMESHHANDLE hMesh, const oapi::FMATRIX4 *pWorld) HR(D3D9Effect::FX->SetMatrix(D3D9Effect::eLVP, shd->mLVP.toCDX())); if (shd->pShadowMap) { - HR(D3D9Effect::FX->SetTexture(D3D9Effect::eShadowMap, shd->pShadowMap[0])); + pMesh->SetShadows(shd); HR(D3D9Effect::FX->SetVector(D3D9Effect::eSHD, ptr(D3DXVECTOR4(sr, 1.0f / s, float(oapiRand()), 1.0f / shd->depth)))); HR(D3D9Effect::FX->SetBool(D3D9Effect::eShadowToggle, true)); } else { + pMesh->SetShadows(NULL); HR(D3D9Effect::FX->SetBool(D3D9Effect::eShadowToggle, false)); } diff --git a/OVP/D3D9Client/Scene.h b/OVP/D3D9Client/Scene.h index ae10269b1..09906f457 100644 --- a/OVP/D3D9Client/Scene.h +++ b/OVP/D3D9Client/Scene.h @@ -39,10 +39,6 @@ class D3D9Pad; #define GBUF_GDI 4 #define GBUF_COUNT 5 // Buffer count -#define SHM_LOD_COUNT 5 -#define SHM_CASCADE_COUNT 1 -#define SHM_CASCADE_RATIO 0.3333333333f - #define TEX_NOISE 0 #define TEX_CLUT 1 #define TEX_COUNT 2 @@ -157,23 +153,7 @@ class Scene { D3DXCOLOR color; }; - struct SHADOWMAPPARAM { - LPDIRECT3DTEXTURE9 pShadowMap[SHM_CASCADE_COUNT]; - // Index 0 is also used for exterior map where the map size varies by LOD, distant object may use 128x128 map - // Interior VC cascades are all same size - FMATRIX4 mVP[SHM_CASCADE_COUNT]; - FVECTOR4 Subrect[SHM_CASCADE_COUNT]; - FVECTOR2 Center[SHM_CASCADE_COUNT]; - FMATRIX4 mLVP; - D3DXVECTOR3 pos; // Shadow map origin - D3DXVECTOR3 ld; // Light direction - float rad; // radius of the area covered by map [meters] - float dist; // Shadow camera distance from shadow origin - float depth; // near to far plane distance. i.r. depth of the field - int lod; // level of detail, 0 = highest - int size; // Map size in pixels - int cascades; // Number of active cascades - } smap; + struct SHADOWMAPPARAM smap; static void D3D9TechInit(LPDIRECT3DDEVICE9 pDev, const char *folder); @@ -483,6 +463,7 @@ class Scene { VECTOR3 sky_color; double bglvl; + float fCascadeRatio; float fDisplayScale; float lmaxdst2; DWORD nLights; diff --git a/OVP/D3D9Client/Surfmgr2.cpp b/OVP/D3D9Client/Surfmgr2.cpp index 18bf86604..203ae8811 100644 --- a/OVP/D3D9Client/Surfmgr2.cpp +++ b/OVP/D3D9Client/Surfmgr2.cpp @@ -988,7 +988,7 @@ void SurfTile::Render () if (pShader->bShdMap) { - const Scene::SHADOWMAPPARAM* shd = scene->GetSMapData(); + const SHADOWMAPPARAM* shd = scene->GetSMapData(); D3DXVECTOR3 bc = bs_pos - shd->pos; diff --git a/OVP/D3D9Client/VPlanet.cpp b/OVP/D3D9Client/VPlanet.cpp index e2cc59ac7..4c25e5cdf 100644 --- a/OVP/D3D9Client/VPlanet.cpp +++ b/OVP/D3D9Client/VPlanet.cpp @@ -891,7 +891,7 @@ bool vPlanet::Render(LPDIRECT3DDEVICE9 dev) _TRACE; if (!active) return false; - const Scene::SHADOWMAPPARAM *shd = scn->GetSMapData(); + const SHADOWMAPPARAM *shd = scn->GetSMapData(); if (DebugControls::IsActive()) { // DWORD flags = *(DWORD*)gc->GetConfigParam(CFGPRM_GETDEBUGFLAGS); @@ -929,9 +929,10 @@ bool vPlanet::Render(LPDIRECT3DDEVICE9 dev) float is = 1.0f / s; float qw = 1.0f / float(Config->ShadowMapSize); HR(D3D9Effect::FX->SetMatrix(D3D9Effect::eLVP, shd->mLVP.toCDX())); - HR(D3D9Effect::FX->SetTexture(D3D9Effect::eShadowMap, shd->pShadowMap[0])); HR(D3D9Effect::FX->SetVector(D3D9Effect::eSHD, ptr(D3DXVECTOR4(s, is, qw, 0)))); HR(D3D9Effect::FX->SetBool(D3D9Effect::eShadowToggle, true)); + + D3D9Mesh::SetShadows(shd); } } diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index 322cc0908..7d98b95fe 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -590,7 +590,7 @@ void vVessel::UpdateAnimations (int mshidx) bool vVessel::IsInsideShadows() { D3DXVECTOR3 bc; - const Scene::SHADOWMAPPARAM *shd = scn->GetSMapData(); + const SHADOWMAPPARAM *shd = scn->GetSMapData(); D3DXVec3TransformCoord(&bc, ptr(D3DXVECTOR3f4(BBox.bs)), &mWorld); bc = bc - shd->pos; float x = D3DXVec3Dot(&bc, &(shd->ld)); @@ -606,7 +606,7 @@ bool vVessel::IsInsideShadows() bool vVessel::IntersectShadowVolume() { D3DXVECTOR3 bc; - const Scene::SHADOWMAPPARAM *shd = scn->GetSMapData(); + const SHADOWMAPPARAM *shd = scn->GetSMapData(); D3DXVec3TransformCoord(&bc, ptr(D3DXVECTOR3f4(BBox.bs)), &mWorld); bc = bc - shd->pos; float x = D3DXVec3Dot(&bc, &(shd->ld)); @@ -620,7 +620,7 @@ bool vVessel::IntersectShadowVolume() bool vVessel::IntersectShadowTarget() { D3DXVECTOR3 bc; - const Scene::SHADOWMAPPARAM *shd = scn->GetSMapData(); + const SHADOWMAPPARAM *shd = scn->GetSMapData(); D3DXVec3TransformCoord(&bc, ptr(D3DXVECTOR3f4(BBox.bs)), &mWorld); bc = bc - shd->pos; if (D3DXVec3Length(&bc) < (shd->rad + BBox.bs.w)) return true; @@ -633,7 +633,7 @@ bool vVessel::IntersectShadowTarget() void vVessel::GetMinMaxLightDist(float *mind, float *maxd) { D3DXVECTOR3 bc; - const Scene::SHADOWMAPPARAM *shd = scn->GetSMapData(); + const SHADOWMAPPARAM *shd = scn->GetSMapData(); D3DXVec3TransformCoord(&bc, ptr(D3DXVECTOR3f4(BBox.bs)), &mWorld); bc -= shd->pos; float x = D3DXVec3Dot(&bc, &(shd->ld)); @@ -746,30 +746,25 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass) static bool gotHUDSpec(false); const VCMFDSPEC *mfdspec[MAXMFD] = { NULL }; - - const Scene::SHADOWMAPPARAM *shd = scn->GetSMapData(); + const SHADOWMAPPARAM *shd = scn->GetSMapData(); float s = float(shd->size); float sr = 2.0f * shd->rad / s; - + HR(D3D9Effect::FX->SetBool(D3D9Effect::eEnvMapEnable, false)); HR(D3D9Effect::FX->SetMatrix(D3D9Effect::eLVP, shd->mLVP.toCDX())); // Cascade 0 for all if (shd->pShadowMap && (scn->GetRenderPass() == RENDERPASS_MAINSCENE)) { - - D3DXVECTOR4 sh[2]; - sh[0] = D3DXVECTOR4(sr, 1.0f / s, float(oapiRand()), 1.0f / shd->depth); - sh[1] = D3DXVECTOR4(sr, 1.0f / s, float(oapiRand()), 1.0f / shd->depth); - - HR(D3D9Effect::FX->SetTexture(D3D9Effect::eShadowMap, shd->pShadowMap[0])); - HR(D3D9Effect::FX->SetValue(D3D9Effect::eSHD, &sh, sizeof(sh))); + D3DXVECTOR4 sh = D3DXVECTOR4(sr, 1.0f / s, float(oapiRand()), 1.0f / shd->depth); + HR(D3D9Effect::FX->SetVector(D3D9Effect::eSHD, &sh)); HR(D3D9Effect::FX->SetBool(D3D9Effect::eShadowToggle, true)); + D3D9Mesh::SetShadows(shd); if (bVC) { - //HR(D3D9Effect::FX->SetTexture(D3D9Effect::eShadowMap2, shd->pShadowMap[1])); } } else { + D3D9Mesh::SetShadows(NULL); HR(D3D9Effect::FX->SetBool(D3D9Effect::eShadowToggle, false)); } diff --git a/OVP/D3D9Client/shaders/BakedVC.fx b/OVP/D3D9Client/shaders/BakedVC.fx index 4dc706d01..6de08f94c 100644 --- a/OVP/D3D9Client/shaders/BakedVC.fx +++ b/OVP/D3D9Client/shaders/BakedVC.fx @@ -137,7 +137,7 @@ float4 BakedVC_PS(float4 sc : VPOS, PBRData frg) : COLOR // Add vessel self-shadows // ====================================================================== #if SHDMAP > 0 - cSun *= smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc, gSHD[0])); + cSun *= smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc)); #endif diff --git a/OVP/D3D9Client/shaders/Common.hlsl b/OVP/D3D9Client/shaders/Common.hlsl index da40ab19c..502652977 100644 --- a/OVP/D3D9Client/shaders/Common.hlsl +++ b/OVP/D3D9Client/shaders/Common.hlsl @@ -1,6 +1,8 @@ #define KERNEL_RADIUS 2.0f +sampler tShadowMap[3] : register(s13); + // ============================================================================ // float4 Paraboloidal_LVLH(sampler s, float3 i) @@ -23,6 +25,14 @@ float4 Sq(float4 x) return x*x; } +bool PointInRect(float2 pt, float4 rect) +{ + if (pt.x < rect[0]) return false; + if (pt.x > rect[2]) return false; + if (pt.y < rect[1]) return false; + if (pt.y > rect[3]) return false; + return true; +} // ========================================================================================================== // Local light sources @@ -255,25 +265,25 @@ void LocalLightsEx(out float3 cDiffLocal, out float3 cSpecLocal, in float3 nrmW, // Object Self Shadows // ========================================================================================================== -float SampleShadows(float2 sp, float pd, float4 SHD) +float SampleShadows(float2 sp, float pd, int sid) { - float2 dx = float2(SHD[1], 0) * 1.5f; - float2 dy = float2(0, SHD[1]) * 1.5f; + float2 dx = float2(gSHD[1], 0) * 1.5f; + float2 dy = float2(0, gSHD[1]) * 1.5f; float va = 0; sp -= dy; - if ((tex2D(ShadowS, sp - dx).r) > pd) va++; - if ((tex2D(ShadowS, sp).r) > pd) va++; - if ((tex2D(ShadowS, sp + dx).r) > pd) va++; + if ((tex2D(tShadowMap[sid], sp - dx).r) > pd) va++; + if ((tex2D(tShadowMap[sid], sp).r) > pd) va++; + if ((tex2D(tShadowMap[sid], sp + dx).r) > pd) va++; sp += dy; - if ((tex2D(ShadowS, sp - dx).r) > pd) va++; - if ((tex2D(ShadowS, sp).r) > pd) va++; - if ((tex2D(ShadowS, sp + dx).r) > pd) va++; + if ((tex2D(tShadowMap[sid], sp - dx).r) > pd) va++; + if ((tex2D(tShadowMap[sid], sp).r) > pd) va++; + if ((tex2D(tShadowMap[sid], sp + dx).r) > pd) va++; sp += dy; - if ((tex2D(ShadowS, sp - dx).r) > pd) va++; - if ((tex2D(ShadowS, sp).r) > pd) va++; - if ((tex2D(ShadowS, sp + dx).r) > pd) va++; + if ((tex2D(tShadowMap[sid], sp - dx).r) > pd) va++; + if ((tex2D(tShadowMap[sid], sp).r) > pd) va++; + if ((tex2D(tShadowMap[sid], sp + dx).r) > pd) va++; return va * 0.1111111f; } @@ -281,14 +291,14 @@ float SampleShadows(float2 sp, float pd, float4 SHD) // --------------------------------------------------------------------------------------------------- // -float SampleShadows2(float2 sp, float pd, float4 SHD) +float SampleShadows2(float2 sp, float pd, int sid) { float val = 0; - float m = KERNEL_RADIUS * SHD[1]; + float m = KERNEL_RADIUS * gSHD[1]; [unroll] for (int i = 0; i < KERNEL_SIZE; i++) { - if ((tex2D(ShadowS, sp + kernel[i].xy * m).r) > pd) val += kernel[i].z; + if ((tex2D(tShadowMap[sid], sp + kernel[i].xy * m).r) > pd) val += kernel[i].z; } return saturate(val * KERNEL_WEIGHT); @@ -297,15 +307,15 @@ float SampleShadows2(float2 sp, float pd, float4 SHD) // --------------------------------------------------------------------------------------------------- // -float SampleShadows3(float2 sp, float pd, float4 frame, float4 SHD) +float SampleShadows3(float2 sp, float pd, float4 frame, int sid) { float val = 0; - frame *= KERNEL_RADIUS * SHD[1]; + frame *= KERNEL_RADIUS * gSHD[1]; [unroll] for (int i = 0; i < KERNEL_SIZE; i++) { float2 ofs = frame.xy*kernel[i].x + frame.zw*kernel[i].y; - if (tex2D(ShadowS, sp + ofs).r > pd) val += kernel[i].z; + if (tex2D(tShadowMap[sid], sp + ofs).r > pd) val += kernel[i].z; } return saturate(val * KERNEL_WEIGHT); @@ -314,18 +324,18 @@ float SampleShadows3(float2 sp, float pd, float4 frame, float4 SHD) // --------------------------------------------------------------------------------------------------- // -float SampleShadowsEx(float2 sp, float pd, float4 sc, float4 SHD) +float SampleShadowsEx(float2 sp, float pd, float4 sc, int sid) { #if SHDMAP == 1 - return SampleShadows(sp, pd, SHD); + return SampleShadows(sp, pd, sid); #elif SHDMAP == 2 || SHDMAP == 4 - return SampleShadows2(sp, pd, SHD); + return SampleShadows2(sp, pd, sid); #else float si, co; - sc += (SHD[2] * 2.0f); + sc += (gSHD[2] * 2.0f); sincos(sc.y + sc.x*149.0f, si, co); - return SampleShadows3(sp, pd, float4(si, co, co, -si), SHD); + return SampleShadows3(sp, pd, float4(si, co, co, -si), sid); #endif } @@ -333,7 +343,7 @@ float SampleShadowsEx(float2 sp, float pd, float4 sc, float4 SHD) // --------------------------------------------------------------------------------------------------- // -float ComputeShadow(float4 shdH, float dLN, float4 sc, float4 SHD) +float ComputeShadow(float4 shdH, float dLN, float4 sc) { if (!gShadowsEnabled) return 1.0f; @@ -341,24 +351,43 @@ float ComputeShadow(float4 shdH, float dLN, float4 sc, float4 SHD) shdH.z = 1 - shdH.z; float2 sp = shdH.xy * float2(0.5f, -0.5f) + float2(0.5f, 0.5f); - sp += SHD[1] * 0.5f; + sp += gSHD[1] * 0.5f; if (sp.x < 0 || sp.y < 0) return 1.0f; // If a sample is outside border -> fully lit if (sp.x > 1 || sp.y > 1) return 1.0f; float fShadow; - float kr = SHD[0] * KERNEL_RADIUS; + float kr = gSHD[0] * KERNEL_RADIUS; float dx = rsqrt(1.0 - dLN*dLN); float ofs = 0.33f * kr / (dLN * dx); - float omx = min(SHD[0] * 2.0f + max(0, ofs), 0.25); + float omx = min(gSHD[0] * 2.0f + max(0, ofs), 0.25); - float pd = shdH.z + omx * SHD[3]; + float pd = shdH.z + omx * gSHD[3]; if (pd < 0) pd = 0; if (pd > 1) pd = 1; - fShadow = SampleShadowsEx(sp, pd, sc, SHD); + fShadow = SampleShadowsEx(sp, pd, sc, 0); return 1 - fShadow; } + + +// --------------------------------------------------------------------------------------------------- +// +float3 VisualizeCascades(float4 shdH) +{ + if (!gShadowsEnabled) return float3(1, 1, 1); + + shdH.xyz /= shdH.w; + shdH.z = 1 - shdH.z; + float2 sp = shdH.xy * float2(0.5f, -0.5f) + float2(0.5f, 0.5f); + + sp += gSHD[1] * 0.5f; // Shift 0.5 pixels aside + + if (PointInRect(sp, gSHDSubRect[2])) return float3(0, 0, 1); + if (PointInRect(sp, gSHDSubRect[1])) return float3(0, 1, 0); + if (PointInRect(sp, gSHDSubRect[0])) return float3(1, 0, 0); + return float3(1, 1, 1); +} diff --git a/OVP/D3D9Client/shaders/D3D9Client.fx b/OVP/D3D9Client/shaders/D3D9Client.fx index 885618e72..3cb9bc998 100644 --- a/OVP/D3D9Client/shaders/D3D9Client.fx +++ b/OVP/D3D9Client/shaders/D3D9Client.fx @@ -96,7 +96,8 @@ uniform extern float4 gFogColor; // Distance fog color in "Legacy" im uniform extern float4 gAtmColor; // Earth glow color uniform extern float4 gTexOff; // Texture offsets used by surface manager uniform extern float4 gRadius; // PlanetRad, AtmOuterLimit, CameraRad, CameraAlt -uniform extern float4 gSHD[2]; // ShadowMap data +uniform extern float4 gSHD; // ShadowMap data +uniform extern float4 gSHDSubRect[3]; // Shadow cascade sub-rects uniform extern float3 gCameraPos; // Planet relative camera position, Unit vector uniform extern float3 gNorth; uniform extern float3 gEast; @@ -120,6 +121,7 @@ uniform extern bool gInSpace; // True if a mesh is located in space uniform extern bool gNoColor; // No color flag uniform extern bool gBaseBuilding; uniform extern bool gOITEnable; +uniform extern bool gCockpit; uniform extern int gSpecMode; uniform extern int gHazeMode; uniform extern float gProxySize; // Cosine of the angular size of the Proxy Gbody. (one half) @@ -149,8 +151,6 @@ uniform extern texture gMetlMap; // Metalness Map uniform extern texture gHeatMap; // Heat Map uniform extern texture gTranslMap; // Translucence Map uniform extern texture gTransmMap; // Transmittance Map -uniform extern texture gShadowMap; // Shadow Map -uniform extern texture gShadowMap2; // Shadow Map2 uniform extern texture gIrradianceMap; // Irradiance Map uniform extern texture gAmbientMap; // Baked Ambient occlusion map uniform extern texture gCombinedMap; // Combined baked light map @@ -250,16 +250,6 @@ sampler IrradS = sampler_state // Irradiance map sampler AddressV = CLAMP; }; -sampler ShadowS = sampler_state // Shadow map sampler -{ - Texture = ; - MinFilter = POINT; - MagFilter = POINT; - MipFilter = POINT; - AddressU = CLAMP; - AddressV = CLAMP; -}; - sampler WrapS = sampler_state // Primary Mesh texture sampler { Texture = ; diff --git a/OVP/D3D9Client/shaders/Metalness.fx b/OVP/D3D9Client/shaders/Metalness.fx index 6d0646d2f..978188007 100644 --- a/OVP/D3D9Client/shaders/Metalness.fx +++ b/OVP/D3D9Client/shaders/Metalness.fx @@ -4,6 +4,7 @@ // ============================================================== #define eps 0.001f +//#define _VISCASCADES // ============================================================================ // Vertex shader for physics based rendering @@ -137,7 +138,7 @@ float4 MetalnessPS(float4 sc : VPOS, PBRData frg) : COLOR float3 nrmT; float3 nrmW; float3 cEmis; - float4 cSpecularMap; // Added + float4 cSpecularMap; float4 cDiff; float fHeat; float fSmth, fMetal; @@ -151,6 +152,11 @@ float4 MetalnessPS(float4 sc : VPOS, PBRData frg) : COLOR if (gTextured) cDiff = tex2D(WrapS, frg.tex0.xy); else cDiff = 1; +#if defined(_VISCASCADES) + cDiff.rgb *= VisualizeCascades(frg.shdH); + return cDiff; +#endif + if (gOITEnable) if (cDiff.a < 0.5f) clip(-1); // Fetch a normal map @@ -285,7 +291,7 @@ float4 MetalnessPS(float4 sc : VPOS, PBRData frg) : COLOR // Add vessel self-shadows // ====================================================================== #if SHDMAP > 0 - cSun *= smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc, gSHD[0])); + cSun *= smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc)); #endif diff --git a/OVP/D3D9Client/shaders/PBR.fx b/OVP/D3D9Client/shaders/PBR.fx index c2fc8fd74..d4e46896b 100644 --- a/OVP/D3D9Client/shaders/PBR.fx +++ b/OVP/D3D9Client/shaders/PBR.fx @@ -172,7 +172,7 @@ float4 PBR_PS(float4 sc : VPOS, PBRData frg) : COLOR // ---------------------------------------------------------------------- #if SHDMAP > 0 - cSun *= smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc, gSHD[0])); + cSun *= smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc)); #endif @@ -422,8 +422,6 @@ float4 FAST_PS(float4 sc : VPOS, FASTData frg) : COLOR float3 cSun = saturate(gSun.Color); float dLN = saturate(-dot(gSun.Dir, nrmW)); - //cSpec.rgb *= 0.33333f; - if (gNoColor) cDiff.rgb = 1; // ---------------------------------------------------------------------- @@ -431,7 +429,7 @@ float4 FAST_PS(float4 sc : VPOS, FASTData frg) : COLOR // ---------------------------------------------------------------------- #if SHDMAP > 0 - float fShadow = smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc, gSHD[0])); + float fShadow = smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc)); dLN *= fShadow; #endif diff --git a/OVP/D3D9Client/shaders/Vessel.fx b/OVP/D3D9Client/shaders/Vessel.fx index 30342ba47..9cd383491 100644 --- a/OVP/D3D9Client/shaders/Vessel.fx +++ b/OVP/D3D9Client/shaders/Vessel.fx @@ -124,7 +124,7 @@ float4 AdvancedPS(float4 sc : VPOS, PBRData frg) : COLOR // ---------------------------------------------------------------------- #if SHDMAP > 0 - cSun.rgb *= ComputeShadow(frg.shdH, dLN, sc, gSHD[0]); + cSun.rgb *= ComputeShadow(frg.shdH, dLN, sc); #endif From 55b6cd94eda49b6033a29f8497dc40892ff598be Mon Sep 17 00:00:00 2001 From: jarmonik Date: Tue, 1 Aug 2023 16:59:02 +0300 Subject: [PATCH 14/42] - Implementation of cascaded VC shadows passed preliminary testing. Fine tuning required. --- OVP/D3D9Client/D3D9Client.h | 1 + OVP/D3D9Client/Mesh.cpp | 5 ++- OVP/D3D9Client/Scene.cpp | 15 ++++--- OVP/D3D9Client/shaders/BakedVC.fx | 7 +++- OVP/D3D9Client/shaders/Common.hlsl | 61 +++++++++++++++++++++++++---- OVP/D3D9Client/shaders/Metalness.fx | 11 ++++-- OVP/D3D9Client/shaders/PBR.fx | 5 ++- OVP/D3D9Client/shaders/Vessel.fx | 2 +- 8 files changed, 85 insertions(+), 22 deletions(-) diff --git a/OVP/D3D9Client/D3D9Client.h b/OVP/D3D9Client/D3D9Client.h index 46ad4b183..d02caa75f 100644 --- a/OVP/D3D9Client/D3D9Client.h +++ b/OVP/D3D9Client/D3D9Client.h @@ -135,6 +135,7 @@ struct SHADOWMAPPARAM { // Interior VC cascades are all same size FMATRIX4 mVP[SHM_CASCADE_COUNT]; FVECTOR4 Subrect[SHM_CASCADE_COUNT]; + FVECTOR4 SubrectTF[SHM_CASCADE_COUNT]; FVECTOR2 Center[SHM_CASCADE_COUNT]; FMATRIX4 mLVP; D3DXVECTOR3 pos; // Shadow map origin i.e. Cascade '0' origin diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index 8d6c45710..3cfa33a43 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -1561,7 +1561,7 @@ void D3D9Mesh::SetShadows(const SHADOWMAPPARAM *sprm) if (sprm) { for (int i = 0; i < SHM_CASCADE_COUNT; i++) { pShadowMap[i] = sprm->pShadowMap[i]; - ShdSubRect[i] = sprm->Subrect[i]; + ShdSubRect[i] = sprm->SubrectTF[i]; } } else { @@ -2393,9 +2393,11 @@ void D3D9Mesh::RenderFast(const LPD3DXMATRIX pW, int iTech) bool bGroupCull = true; bool bUpdateFlow = true; bool bShadowProjection = false; + bool bVirtualCockpit = false; switch (iTech) { case RENDER_VC: + bVirtualCockpit = true; EnablePlanetGlow(false); break; case RENDER_BASE: @@ -2420,6 +2422,7 @@ void D3D9Mesh::RenderFast(const LPD3DXMATRIX pW, int iTech) } HR(D3D9Effect::FX->SetBool(D3D9Effect::eBaseBuilding, bShadowProjection)); + HR(D3D9Effect::FX->SetBool(D3D9Effect::eCockpit, bVirtualCockpit)); D3DXVECTOR4 Field; D3DXMATRIX mWorldView, q; diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index 107c95eb1..fccd6efe5 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -2002,11 +2002,11 @@ void Scene::RenderMainScene() float dist = 1.5f; fCascadeRatio = 1.00f; - if (Config->VCCascadeCount == 2) dist = 4.00f, fCascadeRatio = 0.33f; - if (Config->VCCascadeCount == 3) dist = 6.25f, fCascadeRatio = 0.40f; + if (Config->VCCascadeCount == 2) dist = 5.00f, fCascadeRatio = 0.25f; + if (Config->VCCascadeCount == 3) dist = 6.00f, fCascadeRatio = 0.25f; D3DXVECTOR3 ld = sunLight.Dir; - D3DXVECTOR3 pos = Camera.z * dist * 0.75f; + D3DXVECTOR3 pos = Camera.z * dist; RenderVCShadowMap(pos, ld, dist, false); @@ -2502,6 +2502,7 @@ int Scene::RenderShadowMap(D3DXVECTOR3 &pos, D3DXVECTOR3 &ld, float rad, bool bI smap.cascades = 1; smap.Center[0] = { 0, 0 }; smap.Subrect[0] = { 0, 0, 1, 1 }; + smap.SubrectTF[0] = { 0, 0, 1, 1 }; float mnd = 1e16f; float mxd = -1e16f; @@ -2672,15 +2673,17 @@ int Scene::RenderVCShadowMap(D3DXVECTOR3& pos, D3DXVECTOR3& ld, float rad, bool D3DXVECTOR3 xy; D3DXVec3TransformCoord(&xy, &pos, smap.mVP[0].toDX()); - float r = 0.5f * rad / smap.rad; + float s = 0.5f * rad / smap.rad; xy.y = -xy.y; xy = (xy + 1.0f) * 0.5f; - // Cascade's center and subrect within the main level (i.e '0') + // Cascade's center, subrect and subrect-transform within the main level (i.e '0') // All cascades share the same near and far plane and exists inside the previous cascade. smap.Center[i] = { xy.x, xy.y }; - smap.Subrect[i] = { xy.x - r, xy.y - r, xy.x + r, xy.y + r }; + float l = xy.x - s; float t = xy.y - s; float r = xy.x + s; float b = xy.y + s; + smap.Subrect[i] = FVECTOR4(l, t, r, b); + smap.SubrectTF[i] = FVECTOR4(-l, -t, 1.0f / (r - l), 1.0f / (b - t)); #ifdef CASCADE_DEBUG D3D9DebugLog("Cascade %i pos=[%f, %f]", i, xy.x, xy.y); diff --git a/OVP/D3D9Client/shaders/BakedVC.fx b/OVP/D3D9Client/shaders/BakedVC.fx index 6de08f94c..aeec3b17a 100644 --- a/OVP/D3D9Client/shaders/BakedVC.fx +++ b/OVP/D3D9Client/shaders/BakedVC.fx @@ -137,7 +137,12 @@ float4 BakedVC_PS(float4 sc : VPOS, PBRData frg) : COLOR // Add vessel self-shadows // ====================================================================== #if SHDMAP > 0 - cSun *= smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc)); + if (gCockpit) { + cSun *= smoothstep(0, 0.72, ComputeShadowVC(frg.shdH, dLN, sc)); + } + else { + cSun *= smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc)); + } #endif diff --git a/OVP/D3D9Client/shaders/Common.hlsl b/OVP/D3D9Client/shaders/Common.hlsl index 502652977..cc8bbc29c 100644 --- a/OVP/D3D9Client/shaders/Common.hlsl +++ b/OVP/D3D9Client/shaders/Common.hlsl @@ -25,12 +25,12 @@ float4 Sq(float4 x) return x*x; } -bool PointInRect(float2 pt, float4 rect) +bool PointInRect(float2 pt) { - if (pt.x < rect[0]) return false; - if (pt.x > rect[2]) return false; - if (pt.y < rect[1]) return false; - if (pt.y > rect[3]) return false; + if (pt.x < 0) return false; + if (pt.x > 1) return false; + if (pt.y < 0) return false; + if (pt.y > 1) return false; return true; } @@ -374,6 +374,47 @@ float ComputeShadow(float4 shdH, float dLN, float4 sc) } +// --------------------------------------------------------------------------------------------------- +// +float ComputeShadowVC(float4 shdH, float dLN, float4 sc) +{ + if (!gShadowsEnabled) return 1.0f; + + shdH.xyz /= shdH.w; + shdH.z = 1 - shdH.z; + float2 sp = shdH.xy * float2(0.5f, -0.5f) + float2(0.5f, 0.5f); + float2 c[3]; + int sid = 0; + + sp += gSHD[1] * 0.5f; + + c[0] = (sp + gSHDSubRect[0].xy) * gSHDSubRect[0].zw; + c[1] = (sp + gSHDSubRect[1].xy) * gSHDSubRect[1].zw; + c[2] = (sp + gSHDSubRect[2].xy) * gSHDSubRect[2].zw; + + if (!PointInRect(c[0])) return 1.0f; // Sample outside of cascade '0' + if (PointInRect(c[2])) sid = 2; + if (PointInRect(c[1])) sid = 1; + + float kr = gSHD[0] * KERNEL_RADIUS; + float dx = rsqrt(1.0 - dLN * dLN); + float ofs = 0.33f * kr / (dLN * dx); + float omx = min(gSHD[0] * 0.1f + max(0, ofs), 0.25); + + float pd = shdH.z + omx * gSHD[3]; + + if (pd < 0) pd = 0; + if (pd > 1) pd = 1; + + float fShadow[3]; + fShadow[0] = SampleShadowsEx(c[0], pd, sc, 0); + fShadow[1] = SampleShadowsEx(c[1], pd, sc, 1); + fShadow[2] = SampleShadowsEx(c[2], pd, sc, 2); + + return 1 - fShadow[sid]; +} + + // --------------------------------------------------------------------------------------------------- // float3 VisualizeCascades(float4 shdH) @@ -386,8 +427,12 @@ float3 VisualizeCascades(float4 shdH) sp += gSHD[1] * 0.5f; // Shift 0.5 pixels aside - if (PointInRect(sp, gSHDSubRect[2])) return float3(0, 0, 1); - if (PointInRect(sp, gSHDSubRect[1])) return float3(0, 1, 0); - if (PointInRect(sp, gSHDSubRect[0])) return float3(1, 0, 0); + float2 c0 = (sp + gSHDSubRect[0].xy) * gSHDSubRect[0].zw; + float2 c1 = (sp + gSHDSubRect[1].xy) * gSHDSubRect[1].zw; + float2 c2 = (sp + gSHDSubRect[2].xy) * gSHDSubRect[2].zw; + + if (PointInRect(c2)) return float3(0, 0, 1); + if (PointInRect(c1)) return float3(0, 1, 0); + if (PointInRect(c0)) return float3(1, 0, 0); return float3(1, 1, 1); } diff --git a/OVP/D3D9Client/shaders/Metalness.fx b/OVP/D3D9Client/shaders/Metalness.fx index 978188007..268352f25 100644 --- a/OVP/D3D9Client/shaders/Metalness.fx +++ b/OVP/D3D9Client/shaders/Metalness.fx @@ -216,8 +216,8 @@ float4 MetalnessPS(float4 sc : VPOS, PBRData frg) : COLOR // Typical compatibility requirements // ====================================================================== + cDiff.a = saturate(cDiff.a * gMtrlAlpha); if (gNoColor) cDiff.rgb = 1; - cDiff = saturate(cDiff * float4(gMtrl.diffuse.rgb, gMtrlAlpha)); // ====================================================================== @@ -291,7 +291,12 @@ float4 MetalnessPS(float4 sc : VPOS, PBRData frg) : COLOR // Add vessel self-shadows // ====================================================================== #if SHDMAP > 0 - cSun *= smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc)); + if (gCockpit) { + cSun *= smoothstep(0, 0.72, ComputeShadowVC(frg.shdH, dLN, sc)); + } + else { + cSun *= smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc)); + } #endif @@ -352,7 +357,7 @@ float4 MetalnessPS(float4 sc : VPOS, PBRData frg) : COLOR // Add a faint diffuse hue for rough metals. Rough metal doesn't look good if it's totally black fA += fRgh * fMetal * 0.05f; - float3 zD = cDiff.rgb * fA * LightFXSq(Sq(cSun * fR * dLN) + cDiffLocal + Sq(cAmbient) + Sq(gMtrl.emissive.rgb)); + float3 zD = cDiff.rgb * fA * LightFXSq(gMtrl.diffuse.rgb * (Sq(cSun * fR * dLN) + cDiffLocal + Sq(cAmbient)) + Sq(gMtrl.emissive.rgb)); // Combine specular terms // float3 zS = cS * (cSun * dLN) + cSpec * LightFX(cSpecLocal) * 0.5f; diff --git a/OVP/D3D9Client/shaders/PBR.fx b/OVP/D3D9Client/shaders/PBR.fx index d4e46896b..89127c892 100644 --- a/OVP/D3D9Client/shaders/PBR.fx +++ b/OVP/D3D9Client/shaders/PBR.fx @@ -172,7 +172,7 @@ float4 PBR_PS(float4 sc : VPOS, PBRData frg) : COLOR // ---------------------------------------------------------------------- #if SHDMAP > 0 - cSun *= smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc)); + if (!gCockpit) cSun *= smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc)); #endif @@ -429,7 +429,8 @@ float4 FAST_PS(float4 sc : VPOS, FASTData frg) : COLOR // ---------------------------------------------------------------------- #if SHDMAP > 0 - float fShadow = smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc)); + float fShadow = 1.0f; + if (!gCockpit) fShadow = smoothstep(0, 0.72, ComputeShadow(frg.shdH, dLN, sc)); dLN *= fShadow; #endif diff --git a/OVP/D3D9Client/shaders/Vessel.fx b/OVP/D3D9Client/shaders/Vessel.fx index 9cd383491..7edcb2e26 100644 --- a/OVP/D3D9Client/shaders/Vessel.fx +++ b/OVP/D3D9Client/shaders/Vessel.fx @@ -124,7 +124,7 @@ float4 AdvancedPS(float4 sc : VPOS, PBRData frg) : COLOR // ---------------------------------------------------------------------- #if SHDMAP > 0 - cSun.rgb *= ComputeShadow(frg.shdH, dLN, sc); + if (!gCockpit) cSun.rgb *= ComputeShadow(frg.shdH, dLN, sc); #endif From 40c83420ddfa82782a72ab152f83583ba69491eb Mon Sep 17 00:00:00 2001 From: jarmonik Date: Wed, 2 Aug 2023 15:56:04 +0300 Subject: [PATCH 15/42] Shadow cascade configuration improved --- OVP/D3D9Client/Scene.cpp | 50 +++++++++++++++++++++++++++++----------- OVP/D3D9Client/Scene.h | 10 +++++++- 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index fccd6efe5..eec62560a 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -1999,16 +1999,33 @@ void Scene::RenderMainScene() if (Config->ShadowMapMode >= 1) { SmapRenderList.clear(); - float dist = 1.5f; - fCascadeRatio = 1.00f; + cascfg[0].dist = 1.5f; + cascfg[0].size = 1.5f; + float sa = sin(GetCameraApertureCorner()); + + if (Config->VCCascadeCount == 2) { + cascfg[0].size = 5.0f; + cascfg[0].dist = 5.0f; + cascfg[1].size = 1.5f; + cascfg[1].dist = cascfg[1].size * (1.0f + sa) / (2.0f * sa); + } - if (Config->VCCascadeCount == 2) dist = 5.00f, fCascadeRatio = 0.25f; - if (Config->VCCascadeCount == 3) dist = 6.00f, fCascadeRatio = 0.25f; - - D3DXVECTOR3 ld = sunLight.Dir; - D3DXVECTOR3 pos = Camera.z * dist; - - RenderVCShadowMap(pos, ld, dist, false); + if (Config->VCCascadeCount == 3) { + cascfg[0].size = 7.0f; + cascfg[0].dist = 7.0f; + cascfg[1].size = 2.0f; + cascfg[1].dist = 2.0f; + cascfg[2].size = 0.6f; + cascfg[2].dist = cascfg[2].size * (1.0f + sa) / (2.0f * sa); + } + + cascfg[1].dist = min(cascfg[0].dist, cascfg[1].dist); + cascfg[2].dist = min(cascfg[1].dist, cascfg[2].dist); + + //D3D9DebugLog("Aperture = %f, dist=%f", GetCameraApertureCorner() * 2.0 * 180.0 / PI, cascfg[2].dist- cascfg[2].size); + + D3DXVECTOR3 ld = sunLight.Dir; + RenderVCShadowMap(Camera.z, ld, false); pShdMap = smap.pShadowMap[0]; } @@ -2599,9 +2616,11 @@ int Scene::RenderShadowMap(D3DXVECTOR3 &pos, D3DXVECTOR3 &ld, float rad, bool bI // =========================================================================================== // -int Scene::RenderVCShadowMap(D3DXVECTOR3& pos, D3DXVECTOR3& ld, float rad, bool bListExists) +int Scene::RenderVCShadowMap(D3DXVECTOR3& cdir, D3DXVECTOR3& ld, bool bListExists) { + D3DXVECTOR3 pos = cdir * cascfg[0].dist; + float rad = cascfg[0].size; smap.pos = pos; smap.ld = ld; smap.rad = rad; @@ -2664,6 +2683,9 @@ int Scene::RenderVCShadowMap(D3DXVECTOR3& pos, D3DXVECTOR3& ld, float rad, bool { // Compute mLVP needed to render this cascade. + pos = cdir * cascfg[i].dist; + rad = cascfg[i].size; + // Project pos to a shadow plane D3DXVECTOR3 sp = pos - ld * D3DXVec3Dot(&pos, &ld); D3DXVECTOR3 ep = sp - ld * smap.dist; @@ -2707,9 +2729,6 @@ int Scene::RenderVCShadowMap(D3DXVECTOR3& pos, D3DXVECTOR3& ld, float rad, bool if (a == vFocus) a->Render(pDevice, true); } - rad *= fCascadeRatio; - pos *= fCascadeRatio; - PopPass(); gc->PopRenderTargets(); @@ -2717,7 +2736,7 @@ int Scene::RenderVCShadowMap(D3DXVECTOR3& pos, D3DXVECTOR3& ld, float rad, bool smap.pShadowMap[i] = ptVCShmRT[i]; } - // smap.mLVP must point to cascade '0' by default + // smap.mLVP must point to cascade '0' by default. That's where subrects lie smap.mLVP = smap.mVP[0]; return 0; @@ -3514,6 +3533,9 @@ void Scene::SetCameraAperture(float ap, float as) Camera.aspect = as; float tanap = tan(ap); + float opa = 1.0f / as; + float cor = sqrt(tanap * tanap + tanap * tanap * as * as); + Camera.corner = atan(cor); ZeroMemory(&Camera.mProj, sizeof(D3DXMATRIX)); diff --git a/OVP/D3D9Client/Scene.h b/OVP/D3D9Client/Scene.h index 09906f457..bcc043dc4 100644 --- a/OVP/D3D9Client/Scene.h +++ b/OVP/D3D9Client/Scene.h @@ -112,6 +112,7 @@ class Scene { // Camera frustum parameters ======================================================== // struct CAMERA { + float corner; // corner to center aperture [rad] float aperture; // aperture [rad] float aspect; // aspect ratio float nearplane; // frustum nearplane distance @@ -233,7 +234,7 @@ class Scene { */ void RenderSecondaryScene(std::set &RndList, std::set &AdditionalLightsList, DWORD flags = 0xFF); int RenderShadowMap(D3DXVECTOR3& pos, D3DXVECTOR3& ld, float rad, bool bInternal = false, bool bListExists = false); - int RenderVCShadowMap(D3DXVECTOR3& pos, D3DXVECTOR3& ld, float rad, bool bListExists = false); + int RenderVCShadowMap(D3DXVECTOR3& cdir, D3DXVECTOR3& ld, bool bListExists = false); bool IntegrateIrradiance(vVessel *vV, LPDIRECT3DCUBETEXTURE9 pSrc, LPDIRECT3DTEXTURE9 pOut); bool RenderBlurredMap(LPDIRECT3DDEVICE9 pDev, LPDIRECT3DCUBETEXTURE9 pSrc); @@ -339,6 +340,7 @@ class Scene { float GetCameraFarPlane() const { return Camera.farplane; } float GetCameraNearPlane() const { return Camera.nearplane; } float GetCameraAperture() const { return (float)Camera.aperture; } + float GetCameraApertureCorner() const { return (float)Camera.corner; } VECTOR3 GetCameraGPos() const { return Camera.pos; } VECTOR3 GetCameraGDir() const { return Camera.dir; } OBJHANDLE GetCameraProxyBody() const { return Camera.hObj_proxy; } @@ -427,6 +429,12 @@ class Scene { // Scene variables ================================================================ // + + struct _cascfg { + float size; + float dist; + } cascfg[SHM_CASCADE_COUNT]; + oapi::D3D9Client* gc; LPDIRECT3DDEVICE9 pDevice; // render device DWORD viewW, viewH; // render viewport size From ea5d97fe1cb0459af7205df737a5559fea11f07d Mon Sep 17 00:00:00 2001 From: jarmonik Date: Tue, 15 Aug 2023 08:09:52 +0300 Subject: [PATCH 16/42] Fixed some bugs. Hard coded VC shadows to use 9 samples. Fixed cascade level selection. --- OVP/D3D9Client/D3D9Client.h | 1 + OVP/D3D9Client/D3D9Config.cpp | 2 +- OVP/D3D9Client/D3D9Effect.cpp | 8 +++- OVP/D3D9Client/D3D9Effect.h | 1 + OVP/D3D9Client/Mesh.cpp | 14 +++--- OVP/D3D9Client/Scene.cpp | 25 +++++----- OVP/D3D9Client/VVessel.cpp | 2 + OVP/D3D9Client/shaders/Common.hlsl | 69 +++++++++++++++++----------- OVP/D3D9Client/shaders/D3D9Client.fx | 1 + 9 files changed, 74 insertions(+), 49 deletions(-) diff --git a/OVP/D3D9Client/D3D9Client.h b/OVP/D3D9Client/D3D9Client.h index d02caa75f..3961a065d 100644 --- a/OVP/D3D9Client/D3D9Client.h +++ b/OVP/D3D9Client/D3D9Client.h @@ -137,6 +137,7 @@ struct SHADOWMAPPARAM { FVECTOR4 Subrect[SHM_CASCADE_COUNT]; FVECTOR4 SubrectTF[SHM_CASCADE_COUNT]; FVECTOR2 Center[SHM_CASCADE_COUNT]; + float SubPx[SHM_CASCADE_COUNT]; FMATRIX4 mLVP; D3DXVECTOR3 pos; // Shadow map origin i.e. Cascade '0' origin D3DXVECTOR3 ld; // Light direction diff --git a/OVP/D3D9Client/D3D9Config.cpp b/OVP/D3D9Client/D3D9Config.cpp index fb551e336..684d400aa 100644 --- a/OVP/D3D9Client/D3D9Config.cpp +++ b/OVP/D3D9Client/D3D9Config.cpp @@ -96,7 +96,7 @@ void D3D9Config::Reset () bIrradiance = 1; bAtmoQuality = 1; NoPlanetAA = 0; - VCCascadeCount = 1; + VCCascadeCount = 2; GFXIntensity = 0.5; GFXDistance = 0.8; diff --git a/OVP/D3D9Client/D3D9Effect.cpp b/OVP/D3D9Client/D3D9Effect.cpp index 4d7654d91..b39a78ef6 100644 --- a/OVP/D3D9Client/D3D9Effect.cpp +++ b/OVP/D3D9Client/D3D9Effect.cpp @@ -94,6 +94,7 @@ D3DXHANDLE D3D9Effect::eMix = 0; // FLOAT Auxiliary factor/multiplier D3DXHANDLE D3D9Effect::eFogDensity = 0; // D3DXHANDLE D3D9Effect::ePointScale = 0; D3DXHANDLE D3D9Effect::eSHD = 0; +D3DXHANDLE D3D9Effect::eSHDPx = 0; D3DXHANDLE D3D9Effect::eSHDSubRect = 0; D3DXHANDLE D3D9Effect::eAtmColor = 0; @@ -339,8 +340,12 @@ void D3D9Effect::D3D9TechInit(D3D9Client *_gc, LPDIRECT3DDEVICE9 _pDev, const ch if (Config->ShadowFilter >= 3) sprintf_s((char*)macro[5].Definition, 32, "%f", 0.0285f); else sprintf_s((char*)macro[5].Definition, 32, "%f", 1.0f / 27.0f); // 0.04634f); // ------------------------------------------------------------------------------ + macro[6].Name = "CASCOUNT"; + macro[6].Definition = new char[32]; + sprintf_s((char*)macro[6].Definition, 32, "%d", Config->VCCascadeCount); + // ------------------------------------------------------------------------------ - int m = 6; + int m = 7; if (Config->EnableGlass) macro[m++].Name = "_GLASS"; if (Config->EnableMeshDbg) macro[m++].Name = "_DEBUG"; if (Config->EnvMapMode) macro[m++].Name = "_ENVMAP"; @@ -451,6 +456,7 @@ void D3D9Effect::D3D9TechInit(D3D9Client *_gc, LPDIRECT3DDEVICE9 _pDev, const ch eMtrlAlpha = FX->GetParameterByName(0,"gMtrlAlpha"); eGlowConst = FX->GetParameterByName(0,"gGlowConst"); eSHD = FX->GetParameterByName(0,"gSHD"); + eSHDPx = FX->GetParameterByName(0,"gSHDPx"); eSHDSubRect = FX->GetParameterByName(0,"gSHDSubRect"); eKernel = FX->GetParameterByName(0,"kernel"); eAtmoParams = FX->GetParameterByName(0,"gAtmo"); diff --git a/OVP/D3D9Client/D3D9Effect.h b/OVP/D3D9Client/D3D9Effect.h index 3219f7dcf..7d5a0d692 100644 --- a/OVP/D3D9Client/D3D9Effect.h +++ b/OVP/D3D9Client/D3D9Effect.h @@ -164,6 +164,7 @@ class D3D9Effect { static D3DXHANDLE eAttennuate; static D3DXHANDLE eInScatter; static D3DXHANDLE eSHD; + static D3DXHANDLE eSHDPx; static D3DXHANDLE eSHDSubRect; static D3DXHANDLE eNight; diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index 3cfa33a43..82d644a69 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -1545,8 +1545,8 @@ void D3D9Mesh::ConfigureShadows() HR(pDev->SetSamplerState(idx, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP)); HR(pDev->SetSamplerState(idx, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP)); HR(pDev->SetSamplerState(idx, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP)); - HR(pDev->SetSamplerState(idx, D3DSAMP_MAGFILTER, D3DTEXF_POINT)); - HR(pDev->SetSamplerState(idx, D3DSAMP_MINFILTER, D3DTEXF_POINT)); + HR(pDev->SetSamplerState(idx, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR)); + HR(pDev->SetSamplerState(idx, D3DSAMP_MINFILTER, D3DTEXF_LINEAR)); HR(pDev->SetSamplerState(idx, D3DSAMP_MIPFILTER, D3DTEXF_NONE)); HR(pDev->SetTexture(idx, pShadowMap[i])); } @@ -1567,7 +1567,7 @@ void D3D9Mesh::SetShadows(const SHADOWMAPPARAM *sprm) else { for (int i = 0; i < SHM_CASCADE_COUNT; i++) { pShadowMap[i] = NULL; - ShdSubRect[i] = { 0,0,1,1 }; + ShdSubRect[i] = { 0,0,0,0 }; } } } @@ -1818,11 +1818,9 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, int iTech, LPDIRECT3DCUBETEXTURE9 * // --------------------------------------------------------------------------------------------------------- // - if (Tex[ti] != old_tex) { - if (Tex[ti] == NULL) { - reset(FC); - bUpdateFlow = true; - } + if ((Tex[ti] == NULL) || (Tex[ti] != old_tex)) { + reset(FC); + bUpdateFlow = true; } if (Tex[ti]==NULL) bTextured = false, old_tex = NULL; diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index eec62560a..a2db38d55 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -1999,24 +1999,24 @@ void Scene::RenderMainScene() if (Config->ShadowMapMode >= 1) { SmapRenderList.clear(); - cascfg[0].dist = 1.5f; - cascfg[0].size = 1.5f; + cascfg[0].dist = 2.5f; + cascfg[0].size = 2.5f; float sa = sin(GetCameraApertureCorner()); if (Config->VCCascadeCount == 2) { - cascfg[0].size = 5.0f; - cascfg[0].dist = 5.0f; - cascfg[1].size = 1.5f; - cascfg[1].dist = cascfg[1].size * (1.0f + sa) / (2.0f * sa); + cascfg[0].size = 4.0f; + cascfg[0].dist = 4.0f; + cascfg[1].size = 1.0f; + cascfg[1].dist = 1.0f; } if (Config->VCCascadeCount == 3) { - cascfg[0].size = 7.0f; - cascfg[0].dist = 7.0f; - cascfg[1].size = 2.0f; - cascfg[1].dist = 2.0f; - cascfg[2].size = 0.6f; - cascfg[2].dist = cascfg[2].size * (1.0f + sa) / (2.0f * sa); + cascfg[0].size = 9.0f; + cascfg[0].dist = 9.0f; + cascfg[1].size = 3.0f; + cascfg[1].dist = 3.0f; + cascfg[2].size = 1.0f; + cascfg[2].dist = 0.5f * cascfg[2].size * (1.0f + sa) / (2.0f * sa); } cascfg[1].dist = min(cascfg[0].dist, cascfg[1].dist); @@ -2706,6 +2706,7 @@ int Scene::RenderVCShadowMap(D3DXVECTOR3& cdir, D3DXVECTOR3& ld, bool bListExist float l = xy.x - s; float t = xy.y - s; float r = xy.x + s; float b = xy.y + s; smap.Subrect[i] = FVECTOR4(l, t, r, b); smap.SubrectTF[i] = FVECTOR4(-l, -t, 1.0f / (r - l), 1.0f / (b - t)); + smap.SubPx[i] = rad / float(smap.size); #ifdef CASCADE_DEBUG D3D9DebugLog("Cascade %i pos=[%f, %f]", i, xy.x, xy.y); diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index 7d98b95fe..bd027fd96 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -756,7 +756,9 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass) if (shd->pShadowMap && (scn->GetRenderPass() == RENDERPASS_MAINSCENE)) { D3DXVECTOR4 sh = D3DXVECTOR4(sr, 1.0f / s, float(oapiRand()), 1.0f / shd->depth); + D3DXVECTOR4 px = D3DXVECTOR4(shd->SubPx[0], shd->SubPx[1], shd->SubPx[2], 0.0f); HR(D3D9Effect::FX->SetVector(D3D9Effect::eSHD, &sh)); + HR(D3D9Effect::FX->SetVector(D3D9Effect::eSHDPx, &px)); HR(D3D9Effect::FX->SetBool(D3D9Effect::eShadowToggle, true)); D3D9Mesh::SetShadows(shd); diff --git a/OVP/D3D9Client/shaders/Common.hlsl b/OVP/D3D9Client/shaders/Common.hlsl index cc8bbc29c..ec2c81cbf 100644 --- a/OVP/D3D9Client/shaders/Common.hlsl +++ b/OVP/D3D9Client/shaders/Common.hlsl @@ -268,22 +268,23 @@ void LocalLightsEx(out float3 cDiffLocal, out float3 cSpecLocal, in float3 nrmW, float SampleShadows(float2 sp, float pd, int sid) { - float2 dx = float2(gSHD[1], 0) * 1.5f; - float2 dy = float2(0, gSHD[1]) * 1.5f; + float2 dxa = float2(gSHD[1], 0) * 0.75f; + float2 dya = float2(0, gSHD[1]) * 0.75f; + float2 dxb = dxa * 0.707f; + float2 dyb = dya * 0.707f; float va = 0; - sp -= dy; - if ((tex2D(tShadowMap[sid], sp - dx).r) > pd) va++; - if ((tex2D(tShadowMap[sid], sp).r) > pd) va++; - if ((tex2D(tShadowMap[sid], sp + dx).r) > pd) va++; - sp += dy; - if ((tex2D(tShadowMap[sid], sp - dx).r) > pd) va++; - if ((tex2D(tShadowMap[sid], sp).r) > pd) va++; - if ((tex2D(tShadowMap[sid], sp + dx).r) > pd) va++; - sp += dy; - if ((tex2D(tShadowMap[sid], sp - dx).r) > pd) va++; + if ((tex2D(tShadowMap[sid], sp - dxb - dyb).r) > pd) va++; + if ((tex2D(tShadowMap[sid], sp - dya).r) > pd) va++; + if ((tex2D(tShadowMap[sid], sp + dxb - dyb).r) > pd) va++; + + if ((tex2D(tShadowMap[sid], sp - dxa).r) > pd) va++; if ((tex2D(tShadowMap[sid], sp).r) > pd) va++; - if ((tex2D(tShadowMap[sid], sp + dx).r) > pd) va++; + if ((tex2D(tShadowMap[sid], sp + dxa).r) > pd) va++; + + if ((tex2D(tShadowMap[sid], sp - dxb + dyb).r) > pd) va++; + if ((tex2D(tShadowMap[sid], sp + dya).r) > pd) va++; + if ((tex2D(tShadowMap[sid], sp + dxb + dyb).r) > pd) va++; return va * 0.1111111f; } @@ -386,30 +387,37 @@ float ComputeShadowVC(float4 shdH, float dLN, float4 sc) float2 c[3]; int sid = 0; - sp += gSHD[1] * 0.5f; - +#if CASCOUNT >= 1 c[0] = (sp + gSHDSubRect[0].xy) * gSHDSubRect[0].zw; + if (!PointInRect(c[0])) return 1.0f; // Sample outside of cascade '0' +#endif +#if CASCOUNT >= 2 c[1] = (sp + gSHDSubRect[1].xy) * gSHDSubRect[1].zw; + if (PointInRect(c[1])) sid = 1; +#endif +#if CASCOUNT >= 3 c[2] = (sp + gSHDSubRect[2].xy) * gSHDSubRect[2].zw; - - if (!PointInRect(c[0])) return 1.0f; // Sample outside of cascade '0' if (PointInRect(c[2])) sid = 2; - if (PointInRect(c[1])) sid = 1; - - float kr = gSHD[0] * KERNEL_RADIUS; - float dx = rsqrt(1.0 - dLN * dLN); - float ofs = 0.33f * kr / (dLN * dx); - float omx = min(gSHD[0] * 0.1f + max(0, ofs), 0.25); +#endif - float pd = shdH.z + omx * gSHD[3]; + float kr = gSHDPx[sid]; + float omx = max(0.0015f, kr * sqrt(rcp(dLN * dLN) - 1.0f)); + float pd = shdH.z + min(omx, 0.02f) * gSHD[3]; if (pd < 0) pd = 0; if (pd > 1) pd = 1; float fShadow[3]; - fShadow[0] = SampleShadowsEx(c[0], pd, sc, 0); - fShadow[1] = SampleShadowsEx(c[1], pd, sc, 1); - fShadow[2] = SampleShadowsEx(c[2], pd, sc, 2); + +#if CASCOUNT >= 1 + fShadow[0] = SampleShadows(c[0], pd, 0); +#endif +#if CASCOUNT >= 2 + fShadow[1] = SampleShadows(c[1], pd, 1); +#endif +#if CASCOUNT >= 3 + fShadow[2] = SampleShadows(c[2], pd, 2); +#endif return 1 - fShadow[sid]; } @@ -431,8 +439,15 @@ float3 VisualizeCascades(float4 shdH) float2 c1 = (sp + gSHDSubRect[1].xy) * gSHDSubRect[1].zw; float2 c2 = (sp + gSHDSubRect[2].xy) * gSHDSubRect[2].zw; +#if CASCOUNT >= 3 if (PointInRect(c2)) return float3(0, 0, 1); +#endif +#if CASCOUNT >= 2 if (PointInRect(c1)) return float3(0, 1, 0); +#endif +#if CASCOUNT >= 1 if (PointInRect(c0)) return float3(1, 0, 0); +#endif + return float3(1, 1, 1); } diff --git a/OVP/D3D9Client/shaders/D3D9Client.fx b/OVP/D3D9Client/shaders/D3D9Client.fx index 3cb9bc998..b388bfad2 100644 --- a/OVP/D3D9Client/shaders/D3D9Client.fx +++ b/OVP/D3D9Client/shaders/D3D9Client.fx @@ -97,6 +97,7 @@ uniform extern float4 gAtmColor; // Earth glow color uniform extern float4 gTexOff; // Texture offsets used by surface manager uniform extern float4 gRadius; // PlanetRad, AtmOuterLimit, CameraRad, CameraAlt uniform extern float4 gSHD; // ShadowMap data +uniform extern float4 gSHDPx; // Shadow resolution [Pixels / meter] for each cascade uniform extern float4 gSHDSubRect[3]; // Shadow cascade sub-rects uniform extern float3 gCameraPos; // Planet relative camera position, Unit vector uniform extern float3 gNorth; From 21631fdb9ba77b2d16aa7d1838e8c59b489eecc9 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Tue, 15 Aug 2023 13:18:24 +0300 Subject: [PATCH 17/42] Added VC shadow config options in a setup dialog --- OVP/D3D9Client/D3D9Client.rc | 6 ++++-- OVP/D3D9Client/Scene.cpp | 6 +++--- OVP/D3D9Client/VideoTab.cpp | 7 +++++++ OVP/D3D9Client/resource.h | 1 + 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/OVP/D3D9Client/D3D9Client.rc b/OVP/D3D9Client/D3D9Client.rc index 03304b096..a607d5d4f 100644 --- a/OVP/D3D9Client/D3D9Client.rc +++ b/OVP/D3D9Client/D3D9Client.rc @@ -260,7 +260,7 @@ FONT 8, "MS Sans Serif", 0, 0, 0 COMBOBOX IDC_LIGHTCONFIG, 201, 255, 150, 15, WS_TABSTOP | CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT COMBOBOX IDC_SELFSHADOWS, 196, 310, 90, 15, WS_TABSTOP | CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT COMBOBOX IDC_SHADOWFILTER, 291, 310, 65, 15, WS_TABSTOP | CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT - COMBOBOX IDC_TERRAIN, 196, 335, 90, 15, WS_TABSTOP | CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT + COMBOBOX IDC_TERRAIN, 290, 335, 65, 15, WS_TABSTOP | CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT AUTOCHECKBOX "Enable Development Tools", IDC_MESH_DEBUGGER, 200, 85, 101, 8, 0, WS_EX_LEFT CONTROL "", IDC_CONVERGENCE, TRACKBAR_CLASS, WS_TABSTOP | TBS_AUTOTICKS | TBS_TOP, 425, 20, 85, 20, WS_EX_LEFT CONTROL "", IDC_SEPARATION, TRACKBAR_CLASS, WS_TABSTOP | TBS_AUTOTICKS | TBS_TOP, 425, 40, 85, 20, WS_EX_LEFT @@ -285,7 +285,7 @@ FONT 8, "MS Sans Serif", 0, 0, 0 LTEXT "Anisotropic filtering", IDC_STATIC, 15, 127, 60, 8, SS_LEFT, WS_EX_LEFT LTEXT "Planet glow", IDC_STATIC, 16, 144, 38, 8, SS_LEFT, WS_EX_LEFT LTEXT "Vessel mapping", IDC_STATIC, 196, 300, 50, 8, SS_LEFT, WS_EX_LEFT - LTEXT "Terrain mapping", IDC_STATIC, 196, 325, 52, 8, SS_LEFT, WS_EX_LEFT + LTEXT "Terrain mapping", IDC_STATIC, 290, 325, 52, 8, SS_LEFT, WS_EX_LEFT LTEXT "Filter options", IDC_STATIC, 291, 300, 40, 8, SS_LEFT, WS_EX_LEFT LTEXT "Texture Mipmaps", IDC_STATIC, 16, 162, 55, 8, SS_LEFT, WS_EX_LEFT LTEXT "Post Processing", IDC_STATIC, 17, 179, 52, 8, SS_LEFT, WS_EX_LEFT @@ -317,6 +317,8 @@ FONT 8, "MS Sans Serif", 0, 0, 0 LTEXT "Earth visual config", IDC_STATIC, 17, 215, 59, 9, SS_LEFT, WS_EX_LEFT AUTOCHECKBOX "Enable shader cache for faster startup", IDC_ESCACHE, 370, 250, 136, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Enable increased atmosphere quality", IDC_EAQUALITY, 20, 344, 131, 8, 0, WS_EX_LEFT + LTEXT "Virtual cockpit shadows", IDC_STATIC, 195, 326, 76, 9, SS_LEFT, WS_EX_LEFT + COMBOBOX IDC_CASCOUNT, 195, 335, 90, 15, WS_TABSTOP | CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT } diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index a2db38d55..0cc081bc5 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -2011,12 +2011,12 @@ void Scene::RenderMainScene() } if (Config->VCCascadeCount == 3) { - cascfg[0].size = 9.0f; - cascfg[0].dist = 9.0f; + cascfg[0].size = 12.0f; + cascfg[0].dist = 12.0f; cascfg[1].size = 3.0f; cascfg[1].dist = 3.0f; cascfg[2].size = 1.0f; - cascfg[2].dist = 0.5f * cascfg[2].size * (1.0f + sa) / (2.0f * sa); + cascfg[2].dist = 1.0f; //cascfg[2].size * (1.0f + sa) / (2.0f * sa); } cascfg[1].dist = min(cascfg[0].dist, cascfg[1].dist); diff --git a/OVP/D3D9Client/VideoTab.cpp b/OVP/D3D9Client/VideoTab.cpp index e8cbe4119..60af6b1a0 100644 --- a/OVP/D3D9Client/VideoTab.cpp +++ b/OVP/D3D9Client/VideoTab.cpp @@ -710,6 +710,11 @@ void VideoTab::InitSetupDialog(HWND hWnd) //SendDlgItemMessageA(hWnd, IDC_SHADOWFILTER, CB_ADDSTRING, 0, (LPARAM)"40 samples"); //SendDlgItemMessageA(hWnd, IDC_SHADOWFILTER, CB_ADDSTRING, 0, (LPARAM)"40s dither"); + SendDlgItemMessage(hWnd, IDC_CASCOUNT, CB_RESETCONTENT, 0, 0); + SendDlgItemMessageA(hWnd, IDC_CASCOUNT, CB_ADDSTRING, 0, (LPARAM)"5m 1-cas low quality"); + SendDlgItemMessageA(hWnd, IDC_CASCOUNT, CB_ADDSTRING, 0, (LPARAM)"8m 2-cas hight quality"); + SendDlgItemMessageA(hWnd, IDC_CASCOUNT, CB_ADDSTRING, 0, (LPARAM)"24m 3-cas hight quality"); + SendDlgItemMessage(hWnd, IDC_TERRAIN, CB_RESETCONTENT, 0, 0); SendDlgItemMessageA(hWnd, IDC_TERRAIN, CB_ADDSTRING, 0, (LPARAM)"None"); SendDlgItemMessageA(hWnd, IDC_TERRAIN, CB_ADDSTRING, 0, (LPARAM)"Stencil"); @@ -799,6 +804,7 @@ void VideoTab::InitSetupDialog(HWND hWnd) SendDlgItemMessage(hWnd, IDC_SHADOWFILTER, CB_SETCURSEL, Config->ShadowFilter, 0); SendDlgItemMessage(hWnd, IDC_TERRAIN, CB_SETCURSEL, Config->TerrainShadowing, 0); SendDlgItemMessage(hWnd, IDC_GUIMODE, CB_SETCURSEL, Config->gcGUIMode, 0); + SendDlgItemMessage(hWnd, IDC_CASCOUNT, CB_SETCURSEL, Config->VCCascadeCount - 1, 0); SendDlgItemMessage(hWnd, IDC_DEMAND, BM_SETCHECK, Config->PlanetPreloadMode==0, 0); SendDlgItemMessage(hWnd, IDC_SRFPRELOAD, BM_SETCHECK, Config->PlanetPreloadMode==1, 0); @@ -874,6 +880,7 @@ void VideoTab::SaveSetupState(HWND hWnd) Config->ShadowFilter = (int)SendDlgItemMessage(hWnd, IDC_SHADOWFILTER, CB_GETCURSEL, 0, 0); Config->TerrainShadowing = (int)SendDlgItemMessage(hWnd, IDC_TERRAIN, CB_GETCURSEL, 0, 0); Config->gcGUIMode = (int)SendDlgItemMessage(hWnd, IDC_GUIMODE, CB_GETCURSEL, 0, 0); + Config->VCCascadeCount = (int)SendDlgItemMessage(hWnd, IDC_CASCOUNT, CB_GETCURSEL, 0, 0) + 1; if (Config->gcGUIMode == 1) Config->gcGUIMode = 0; diff --git a/OVP/D3D9Client/resource.h b/OVP/D3D9Client/resource.h index 981195cac..ca5458441 100644 --- a/OVP/D3D9Client/resource.h +++ b/OVP/D3D9Client/resource.h @@ -221,3 +221,4 @@ #define IDC_ATD_TRLIGHTSHAD 3037 #define IDC_DBG_BKLID 3038 #define IDC_DBG_BKLADJ 3039 +#define IDC_CASCOUNT 3040 From 9bc4332f56be19a58656289adcc2005aed509994 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Fri, 18 Aug 2023 08:48:15 +0300 Subject: [PATCH 18/42] Increased baked lights count to 16 --- OVP/D3D9Client/DebugControls.cpp | 19 +++++++------------ OVP/D3D9Client/IProcess.h | 2 +- OVP/D3D9Client/Mesh.cpp | 20 +++++++++++--------- OVP/D3D9Client/Mesh.h | 4 ++-- OVP/D3D9Client/shaders/D3D9Client.fx | 2 +- OVP/D3D9Client/shaders/PreBakeLights.hlsl | 4 ++-- 6 files changed, 24 insertions(+), 27 deletions(-) diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index 356898001..120afaac5 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -377,6 +377,7 @@ void InitMatList(WORD shader) // void OpenDlgClbk(void *context) { + char buf[64]; DWORD idx = 0; HWND l_hDlg = oapiOpenDialog(g_hInst, IDD_D3D9MESHDEBUG, WndProc); @@ -449,16 +450,10 @@ void OpenDlgClbk(void *context) SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_SETCURSEL, 0, 0); SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_RESETCONTENT, 0, 0); - SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"Baked_0"); - SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"Baked_1"); - SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"Baked_2"); - SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"Baked_3"); - SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"Baked_4"); - SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"Baked_5"); - SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"Baked_6"); - SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"Baked_7"); - SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"Baked_8"); - SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"Baked_9"); + for (int i = 0; i < 16; i++) { + sprintf_s(buf, 64, "Baked_%d", i); + SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)buf); + } SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"Ambient"); SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_SETCURSEL, 0, 0); @@ -1163,10 +1158,10 @@ void UpdateBakedLights(float lvl) { D3D9Mesh* mesh = (class D3D9Mesh*)vObj->GetMesh(sMesh); if (mesh) { - if (bkl_id < 10 && bkl_id >= 0) { + if (bkl_id < 16 && bkl_id >= 0) { mesh->SetBakedLightLevel(bkl_id, FVECTOR3(lvl, lvl, lvl)); } - if (bkl_id == 10) mesh->SetAmbientColor(FVECTOR3(lvl, lvl, lvl)); + if (bkl_id == 16) mesh->SetAmbientColor(FVECTOR3(lvl, lvl, lvl)); } } diff --git a/OVP/D3D9Client/IProcess.h b/OVP/D3D9Client/IProcess.h index 3133c1c93..8c78dce21 100644 --- a/OVP/D3D9Client/IProcess.h +++ b/OVP/D3D9Client/IProcess.h @@ -129,7 +129,7 @@ class ImageProcessing { struct { LPDIRECT3DBASETEXTURE9 hTex; DWORD flags; - } pTextures[10]; + } pTextures[16]; gcIPInterface::ipicull mesh_cull; diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index 82d644a69..b08335b9f 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -478,11 +478,15 @@ void D3D9Mesh::LoadBakedLights() for (int i = 0; i < nTex; i++) { if (!Tex[i]) continue; // No base texture, pick next - for (int j = 0; j < 10; j++) + + for (int j = 0; j < 16; j++) { sprintf_s(id, "bkl%d", j); LPDIRECT3DTEXTURE9 pTex = NatLoadSpecialTexture(Tex[i]->GetPath(), id); - if (pTex) BakedLights[i].pMap[j] = pTex; + if (pTex) { + if (BakedLights.find(i) == BakedLights.end()) for (int k = 0; k < 16; k++) BakedLights[i].pMap[k] = NULL; + BakedLights[i].pMap[j] = pTex; + } } } @@ -494,7 +498,7 @@ void D3D9Mesh::LoadBakedLights() } } - for (int i = 0; i < 10; i++) BakedLightsControl[i] = FVECTOR3(0.5, 0.5, 0.5); + for (int i = 0; i < 16; i++) BakedLightsControl[i] = FVECTOR3(0.5, 0.5, 0.5); } @@ -502,7 +506,7 @@ void D3D9Mesh::LoadBakedLights() // void D3D9Mesh::SetBakedLightLevel(int idx, const FVECTOR3 &level) { - if (idx >= 0 && idx <= 9) { + if (idx >= 0 && idx <= 15) { if (BakedLightsControl[idx] != level) { BakedLightsControl[idx] = level; bMustRebake = true; @@ -521,14 +525,14 @@ void D3D9Mesh::BakeLights(ImageProcessing* pBaker) if (BakedLights.size() == 0) return; // Nothing to bake DWORD flags = IPF_POINT | IPF_CLAMP; - FVECTOR3 control[10]; + FVECTOR3 control[16]; pBaker->Activate("PSMain"); for (auto x : BakedLights) { int slot = 0; - for (int i = 0; i < 10; i++) + for (int i = 0; i < 16; i++) { auto y = x.second.pMap[i]; if (y) @@ -1818,7 +1822,7 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, int iTech, LPDIRECT3DCUBETEXTURE9 * // --------------------------------------------------------------------------------------------------------- // - if ((Tex[ti] == NULL) || (Tex[ti] != old_tex)) { + if (Tex[ti] != old_tex) { reset(FC); bUpdateFlow = true; } @@ -1840,8 +1844,6 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, int iTech, LPDIRECT3DCUBETEXTURE9 * FX->SetTexture(eTex0, Tex[ti]->GetTexture()); - bUpdateFlow = true; // Fix this later - if (CurrentShader == SHADER_LEGACY) { if (tni && Grp[g].TexMixEx[0] < 0.5f) tni = 0; if (tni && Tex[tni]) FX->SetTexture(eEmisMap, Tex[tni]->GetTexture()); diff --git a/OVP/D3D9Client/Mesh.h b/OVP/D3D9Client/Mesh.h index cf038095e..bdca5d2c7 100644 --- a/OVP/D3D9Client/Mesh.h +++ b/OVP/D3D9Client/Mesh.h @@ -73,7 +73,7 @@ struct _LightList { }; struct _BakedLights { - LPDIRECT3DTEXTURE9 pMap[10]; + LPDIRECT3DTEXTURE9 pMap[16]; LPDIRECT3DTEXTURE9 pCombined; }; @@ -364,7 +364,7 @@ class D3D9Mesh : private D3D9Effect D3D9MatExt *Mtrl; // list of mesh materials SurfNative **Tex; // list of mesh textures std::map BakedLights; - FVECTOR3 BakedLightsControl[10]; + FVECTOR3 BakedLightsControl[16]; D3DXMATRIX mTransform; D3DXMATRIX mTransformInv; D3DXMATRIX *pGrpTF; diff --git a/OVP/D3D9Client/shaders/D3D9Client.fx b/OVP/D3D9Client/shaders/D3D9Client.fx index b388bfad2..880e8217e 100644 --- a/OVP/D3D9Client/shaders/D3D9Client.fx +++ b/OVP/D3D9Client/shaders/D3D9Client.fx @@ -63,7 +63,7 @@ struct Flow bool Emis; // Enable Emission Maps bool Spec; // Enable Specular Maps bool Refl; // Enable Reflection Maps - bool Transl; // Enble translucent effect + bool Transl; // Enable translucent effect bool Transm; // Enable transmissive effect bool Rghn; // Enable roughness map bool Norm; // Enable normal map diff --git a/OVP/D3D9Client/shaders/PreBakeLights.hlsl b/OVP/D3D9Client/shaders/PreBakeLights.hlsl index 2f56a1608..bd2a26db0 100644 --- a/OVP/D3D9Client/shaders/PreBakeLights.hlsl +++ b/OVP/D3D9Client/shaders/PreBakeLights.hlsl @@ -3,10 +3,10 @@ // licensed under MIT // ============================================================== -uniform extern float3 fControl[10]; +uniform extern float3 fControl[16]; uniform extern int iCount; -sampler tMap[10] : register(s0); +sampler tMap[16] : register(s0); float cmax(float3 a) { From 4e505d29c8dfc99350601e607fdc94084b667146 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Fri, 18 Aug 2023 14:33:06 +0300 Subject: [PATCH 19/42] Added a separate enable control for AO and baked light maps. --- OVP/D3D9Client/D3D9Effect.h | 1 + OVP/D3D9Client/Mesh.cpp | 3 ++- OVP/D3D9Client/shaders/BakedVC.fx | 7 +++---- OVP/D3D9Client/shaders/D3D9Client.fx | 1 + 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/OVP/D3D9Client/D3D9Effect.h b/OVP/D3D9Client/D3D9Effect.h index 7d5a0d692..a1086c278 100644 --- a/OVP/D3D9Client/D3D9Effect.h +++ b/OVP/D3D9Client/D3D9Effect.h @@ -28,6 +28,7 @@ struct TexFlow { BOOL Metl; // Enable metalness map BOOL Heat; // Enable heat map BOOL Baked; // Enable pre-baked maps + BOOL BakedAO; // Enable pre-baked AO map }; diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index b08335b9f..0a89f00ee 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -1902,7 +1902,8 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, int iTech, LPDIRECT3DCUBETEXTURE9 * if (pAmbi) FX->SetTexture(eAmbientMap, pAmbi); if (pComb) FX->SetTexture(eCombinedMap, pComb); - FC.Baked = (pAmbi != NULL) || (pComb != NULL); + FC.Baked = (pComb != NULL); + FC.BakedAO = (pAmbi != NULL); } FC.Emis = (pEmis != NULL); diff --git a/OVP/D3D9Client/shaders/BakedVC.fx b/OVP/D3D9Client/shaders/BakedVC.fx index aeec3b17a..7ae77e672 100644 --- a/OVP/D3D9Client/shaders/BakedVC.fx +++ b/OVP/D3D9Client/shaders/BakedVC.fx @@ -48,10 +48,9 @@ float4 BakedVC_PS(float4 sc : VPOS, PBRData frg) : COLOR float3 cBL = 0; float3 cBAO = 0; - if (gCfg.Baked) { - cBL = tex2D(BakedLightS, frg.tex0.xy).rgb; - cBAO = tex2D(BakedAOS, frg.tex0.xy).rgb; - } + if (gCfg.Baked) cBL = tex2D(BakedLightS, frg.tex0.xy).rgb; + if (gCfg.BakedAO) cBAO = tex2D(BakedAOS, frg.tex0.xy).rgb; + // ---------------------------------------------------------------------- diff --git a/OVP/D3D9Client/shaders/D3D9Client.fx b/OVP/D3D9Client/shaders/D3D9Client.fx index 880e8217e..bc01733bb 100644 --- a/OVP/D3D9Client/shaders/D3D9Client.fx +++ b/OVP/D3D9Client/shaders/D3D9Client.fx @@ -70,6 +70,7 @@ struct Flow bool Metl; // Enable metalness map bool Heat; // Enable heat map bool Baked; // Enable pre-baked maps + bool BakedAO; // Enable pre-baked AO map }; From 6397e1bcbd3c7f84132ae83da73cd905175043d4 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Fri, 18 Aug 2023 15:40:35 +0300 Subject: [PATCH 20/42] Fixed MeshProperty function to support 16 baked lights. --- OVP/D3D9Client/D3D9Client.cpp | 7 +++++++ Orbitersdk/include/OrbiterAPI.h | 6 ++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/OVP/D3D9Client/D3D9Client.cpp b/OVP/D3D9Client/D3D9Client.cpp index d215a1a3a..179db6f23 100644 --- a/OVP/D3D9Client/D3D9Client.cpp +++ b/OVP/D3D9Client/D3D9Client.cpp @@ -1485,6 +1485,13 @@ bool D3D9Client::clbkSetMeshProperty(DEVMESHHANDLE hMesh, MeshProp prp, const oa case MeshProp::BAKED_7: mesh->SetBakedLightLevel(7, value.xyz); return true; case MeshProp::BAKED_8: mesh->SetBakedLightLevel(8, value.xyz); return true; case MeshProp::BAKED_9: mesh->SetBakedLightLevel(9, value.xyz); return true; + case MeshProp::BAKED_10: mesh->SetBakedLightLevel(10, value.xyz); return true; + case MeshProp::BAKED_11: mesh->SetBakedLightLevel(11, value.xyz); return true; + case MeshProp::BAKED_12: mesh->SetBakedLightLevel(12, value.xyz); return true; + case MeshProp::BAKED_13: mesh->SetBakedLightLevel(13, value.xyz); return true; + case MeshProp::BAKED_14: mesh->SetBakedLightLevel(14, value.xyz); return true; + case MeshProp::BAKED_15: mesh->SetBakedLightLevel(15, value.xyz); return true; + case MeshProp::AMBIENT: mesh->SetAmbientColor(value.xyz); return true; default: oapiWriteLogV("oapiSetMeshProperty() FAILED: unknown property %u", DWORD(prp)); break; diff --git a/Orbitersdk/include/OrbiterAPI.h b/Orbitersdk/include/OrbiterAPI.h index 96fd55f50..b4c85497e 100644 --- a/Orbitersdk/include/OrbiterAPI.h +++ b/Orbitersdk/include/OrbiterAPI.h @@ -464,8 +464,10 @@ enum class MatProp { }; enum class MeshProp { - BAKED_0, BAKED_1, BAKED_2, BAKED_3, BAKED_4, ///< baked light level 0-4 - BAKED_5, BAKED_6, BAKED_7, BAKED_8, BAKED_9, ///< baked light level 5-9 + BAKED_0, BAKED_1, BAKED_2, BAKED_3, BAKED_4, ///< baked light level + BAKED_5, BAKED_6, BAKED_7, BAKED_8, BAKED_9, ///< baked light level + BAKED_10, BAKED_11, BAKED_12, BAKED_13, ///< baked light level + BAKED_14, BAKED_15, ///< baked light level AMBIENT ///< ambient light level }; From 8f77cee77db38eb0b210f77f46793427068855c3 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Mon, 13 Nov 2023 05:43:37 +0200 Subject: [PATCH 21/42] Implemented loading of baked sunlight ambient occlusion textures. Implemented pre-bake shader. --- OVP/D3D9Client/D3D9Surface.cpp | 47 ++++---- OVP/D3D9Client/D3D9Surface.h | 3 +- OVP/D3D9Client/Mesh.cpp | 127 +++++++++++++++++++++- OVP/D3D9Client/Mesh.h | 8 +- OVP/D3D9Client/Scene.cpp | 1 + OVP/D3D9Client/VVessel.cpp | 2 + OVP/D3D9Client/shaders/PreBakeLights.hlsl | 14 +++ 7 files changed, 171 insertions(+), 31 deletions(-) diff --git a/OVP/D3D9Client/D3D9Surface.cpp b/OVP/D3D9Client/D3D9Surface.cpp index 349d4ed70..73a0324e6 100644 --- a/OVP/D3D9Client/D3D9Surface.cpp +++ b/OVP/D3D9Client/D3D9Surface.cpp @@ -59,7 +59,7 @@ void NatCheckFlags(DWORD &flags) // =============================================================================================== // Load a simple plain texture // -LPDIRECT3DTEXTURE9 NatLoadTexture(const char* path) +LPDIRECT3DTEXTURE9 NatLoadTexture(const char* path, bool bNoMips) { LPDIRECT3DTEXTURE9 pTex = NULL; D3DXIMAGE_INFO info; @@ -70,6 +70,7 @@ LPDIRECT3DTEXTURE9 NatLoadTexture(const char* path) if (Config->TextureMips == 2) Mips = 0; // Autogen all if (Config->TextureMips == 1 && info.MipLevels == 1) Mips = 0; // Autogen missing + if (bNoMips) Mips = 1; if (S_OK == D3DXCreateTextureFromFileExA(g_client->GetDevice(), path, info.Width, info.Height, Mips, 0, D3DFMT_FROM_FILE, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &pTex)) { @@ -85,11 +86,11 @@ LPDIRECT3DTEXTURE9 NatLoadTexture(const char* path) // =============================================================================================== // Load a simple plain texture with map type extension // -LPDIRECT3DTEXTURE9 NatLoadSpecialTexture(const char* path, const char* ext) +LPDIRECT3DTEXTURE9 NatLoadSpecialTexture(const char* path, const char* ext, bool bNoMips) { char name[MAX_PATH]; NatCreateName(name, ARRAYSIZE(name), path, ext); - return NatLoadTexture(name); + return NatLoadTexture(name, bNoMips); } @@ -98,16 +99,16 @@ LPDIRECT3DTEXTURE9 NatLoadSpecialTexture(const char* path, const char* ext) // void NatLoadMaps(SurfNative *pNat, const char* path) { - pNat->AddMap(MAP_HEAT, NatLoadSpecialTexture(path, "heat")); - pNat->AddMap(MAP_NORMAL, NatLoadSpecialTexture(path, "norm")); - pNat->AddMap(MAP_SPECULAR, NatLoadSpecialTexture(path, "spec")); - pNat->AddMap(MAP_EMISSION, NatLoadSpecialTexture(path, "emis")); - pNat->AddMap(MAP_ROUGHNESS, NatLoadSpecialTexture(path, "rghn")); - pNat->AddMap(MAP_METALNESS, NatLoadSpecialTexture(path, "metal")); - pNat->AddMap(MAP_REFLECTION, NatLoadSpecialTexture(path, "refl")); - pNat->AddMap(MAP_TRANSLUCENCE, NatLoadSpecialTexture(path, "transl")); - pNat->AddMap(MAP_TRANSMITTANCE, NatLoadSpecialTexture(path, "transm")); - pNat->AddMap(MAP_AMBIENT, NatLoadSpecialTexture(path, "bkao")); + pNat->AddMap(MAP_HEAT, NatLoadSpecialTexture(path, "_heat")); + pNat->AddMap(MAP_NORMAL, NatLoadSpecialTexture(path, "_norm")); + pNat->AddMap(MAP_SPECULAR, NatLoadSpecialTexture(path, "_spec")); + pNat->AddMap(MAP_EMISSION, NatLoadSpecialTexture(path, "_emis")); + pNat->AddMap(MAP_ROUGHNESS, NatLoadSpecialTexture(path, "_rghn")); + pNat->AddMap(MAP_METALNESS, NatLoadSpecialTexture(path, "_metal")); + pNat->AddMap(MAP_REFLECTION, NatLoadSpecialTexture(path, "_refl")); + pNat->AddMap(MAP_TRANSLUCENCE, NatLoadSpecialTexture(path, "_transl")); + pNat->AddMap(MAP_TRANSMITTANCE, NatLoadSpecialTexture(path, "_transm")); + pNat->AddMap(MAP_AMBIENT, NatLoadSpecialTexture(path, "_bkao")); } @@ -1067,15 +1068,15 @@ void SurfNative::Reload() if (S_OK == D3DXCreateTextureFromFileExA(g_client->GetDevice(), path, info.Width, info.Height, Mips, 0, D3DFMT_FROM_FILE, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, (LPDIRECT3DTEXTURE9 *)&pResource)) { - AddMap(MAP_HEAT, NatLoadSpecialTexture(name, "heat")); - AddMap(MAP_NORMAL, NatLoadSpecialTexture(name, "norm")); - AddMap(MAP_SPECULAR, NatLoadSpecialTexture(name, "spec")); - AddMap(MAP_EMISSION, NatLoadSpecialTexture(name, "emis")); - AddMap(MAP_ROUGHNESS, NatLoadSpecialTexture(name, "rghn")); - AddMap(MAP_METALNESS, NatLoadSpecialTexture(name, "metal")); - AddMap(MAP_REFLECTION, NatLoadSpecialTexture(name, "refl")); - AddMap(MAP_TRANSLUCENCE, NatLoadSpecialTexture(name, "transl")); - AddMap(MAP_TRANSMITTANCE, NatLoadSpecialTexture(name, "transm")); + AddMap(MAP_HEAT, NatLoadSpecialTexture(name, "_heat")); + AddMap(MAP_NORMAL, NatLoadSpecialTexture(name, "_norm")); + AddMap(MAP_SPECULAR, NatLoadSpecialTexture(name, "_spec")); + AddMap(MAP_EMISSION, NatLoadSpecialTexture(name, "_emis")); + AddMap(MAP_ROUGHNESS, NatLoadSpecialTexture(name, "_rghn")); + AddMap(MAP_METALNESS, NatLoadSpecialTexture(name, "_metal")); + AddMap(MAP_REFLECTION, NatLoadSpecialTexture(name, "_refl")); + AddMap(MAP_TRANSLUCENCE, NatLoadSpecialTexture(name, "_transl")); + AddMap(MAP_TRANSMITTANCE, NatLoadSpecialTexture(name, "_transm")); } } } @@ -1182,7 +1183,7 @@ bool NatCreateName(char* out, int mlen, const char* fname, const char* id) char* p = strrchr(buffe, '.'); if (p != NULL) { *p = '\0'; - sprintf_s(out, mlen, "%s_%s.%s", buffe, id, ++p); + sprintf_s(out, mlen, "%s%s.%s", buffe, id, ++p); } return (p != NULL); } diff --git a/OVP/D3D9Client/D3D9Surface.h b/OVP/D3D9Client/D3D9Surface.h index e96cba5e1..4531ee3b1 100644 --- a/OVP/D3D9Client/D3D9Surface.h +++ b/OVP/D3D9Client/D3D9Surface.h @@ -34,7 +34,8 @@ #define OAPISURF_SKP_GDI_WARN 0x00000001 -LPDIRECT3DTEXTURE9 NatLoadSpecialTexture(const char* fname, const char* ext); +LPDIRECT3DTEXTURE9 NatLoadTexture(const char* path, bool bNoMips = false); +LPDIRECT3DTEXTURE9 NatLoadSpecialTexture(const char* fname, const char* ext, bool bNoMips = false); SURFHANDLE NatLoadSurface(const char* file, DWORD flags, bool bPath = false); bool NatSaveSurface(const char* file, LPDIRECT3DRESOURCE9 pResource); SURFHANDLE NatCreateSurface(int width, int height, DWORD flags); diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index 0a89f00ee..94be8c03a 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -204,6 +204,8 @@ void D3D9Mesh::Null(const char *meshName /* = NULL */) bMtrlModidied = false; bMustRebake = true; + bli = BakedLights.begin(); + Locals = new LightStruct[Config->MaxLights()]; for (int i = 0; i < SHM_CASCADE_COUNT; i++) { @@ -399,6 +401,13 @@ void D3D9Mesh::Release() SAFE_DELETEA(pGrpTF); if (pBuf) if (pBuf->IsLocalTo(this)) delete pBuf; + + for (auto x : BakedLights) { + for (auto y : x.second.pMap) SAFE_RELEASE(y); + for (auto y : x.second.pSunAO) SAFE_RELEASE(y); + SAFE_RELEASE(x.second.pCombined); + SAFE_RELEASE(x.second.pSunAOComb); + } } @@ -465,6 +474,40 @@ void D3D9Mesh::ReLoadMeshFromHandle(MESHHANDLE hMesh) pBuf->Map(pDev); } +// =========================================================================================== +// +const char* D3D9Mesh::GetDirName(int i, int v) +{ + static const char* names[] = { "up", "down", "left", "right", "fwd", "aft" }; + static const char* named[] = { "+y", "-y", "-x", "+x", "+z", "-z" }; + if (v == 0) return names[i]; + return named[i]; +} + +// =========================================================================================== +// +FVECTOR3 D3D9Mesh::GetDir(int i) +{ + switch (i) { + case 0: return FVECTOR3(0, 1, 0); // Up + case 1: return FVECTOR3(0, -1, 0); // Down + case 2: return FVECTOR3(-1, 0, 0); // Left + case 3: return FVECTOR3( 1, 0, 0); // Right + case 4: return FVECTOR3(0, 0, 1); // Fwd + case 5: return FVECTOR3(0, 0, -1); // Aft + } + return FVECTOR3(0, 0, 1); +} + +// =========================================================================================== +// +void D3D9Mesh::ClearBake(int i) +{ + for (int k = 0; k < 16; k++) BakedLights[i].pMap[k] = NULL; + for (int k = 0; k < 6; k++) BakedLights[i].pSunAO[k] = NULL; + BakedLights[i].pCombined = NULL; + BakedLights[i].pSunAOComb = NULL; +} // =========================================================================================== // @@ -473,7 +516,7 @@ void D3D9Mesh::LoadBakedLights() if (BakedLights.size()) return; // Already Loaded, skip the rest bMustRebake = true; - char id[8]; + char id[32]; for (int i = 0; i < nTex; i++) { @@ -481,24 +524,45 @@ void D3D9Mesh::LoadBakedLights() for (int j = 0; j < 16; j++) { - sprintf_s(id, "bkl%d", j); - LPDIRECT3DTEXTURE9 pTex = NatLoadSpecialTexture(Tex[i]->GetPath(), id); + sprintf_s(id, "_bkl%d", j); + LPDIRECT3DTEXTURE9 pTex = NatLoadSpecialTexture(Tex[i]->GetPath(), id, true); if (pTex) { - if (BakedLights.find(i) == BakedLights.end()) for (int k = 0; k < 16; k++) BakedLights[i].pMap[k] = NULL; + if (BakedLights.find(i) == BakedLights.end()) ClearBake(i); BakedLights[i].pMap[j] = pTex; } } + + for (int j = 0; j < 6; j++) + { + sprintf_s(id, " baked sunlight %s", GetDirName(j, 0)); + LPDIRECT3DTEXTURE9 pTex = NatLoadSpecialTexture(Tex[i]->GetPath(), id, true); + if (pTex) { + if (BakedLights.find(i) == BakedLights.end()) ClearBake(i); + BakedLights[i].pSunAO[j] = pTex; + } + else { + sprintf_s(id, "_bs%s", GetDirName(j, 1)); + LPDIRECT3DTEXTURE9 pTex = NatLoadSpecialTexture(Tex[i]->GetPath(), id, true); + if (pTex) { + if (BakedLights.find(i) == BakedLights.end()) ClearBake(i); + BakedLights[i].pSunAO[j] = pTex; + } + } + } } // Construct render surface for all combined maps for (auto& a : BakedLights) { int i = a.first; if (Tex[i]) { - HR(D3DXCreateTexture(pDev, Tex[i]->GetWidth(), Tex[i]->GetHeight(), 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &a.second.pCombined)); + HR(D3DXCreateTexture(pDev, Tex[i]->GetWidth(), Tex[i]->GetHeight(), 0, D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &a.second.pCombined)); + HR(D3DXCreateTexture(pDev, Tex[i]->GetWidth(), Tex[i]->GetHeight(), 0, D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &a.second.pSunAOComb)); } } - for (int i = 0; i < 16; i++) BakedLightsControl[i] = FVECTOR3(0.5, 0.5, 0.5); + for (int i = 0; i < 16; i++) BakedLightsControl[i] = FVECTOR3(1.0f, 1.0f, 1.0f); + + bli = BakedLights.begin(); } @@ -563,6 +627,57 @@ void D3D9Mesh::BakeLights(ImageProcessing* pBaker) } +// =========================================================================================== +// +void D3D9Mesh::BakeAO(ImageProcessing* pBaker, const FVECTOR3 &vSun) +{ + if (!pBaker->IsOK()) return; // Baker not initialized + if (DefShader != SHADER_BAKED_VC) return; // Not supported by shader + if (BakedLights.size() == 0) return; // Nothing to bake + + DWORD flags = IPF_POINT | IPF_CLAMP; + FVECTOR3 control[6]; + bool bSE[6]; + + pBaker->Activate("PSSunAO"); + + for (int i = 0; i < 6; i++) + { + auto y = bli->second.pSunAO[i]; + bSE[i] = (y != NULL); + if (y) + { + pBaker->SetTextureNative(i, y, flags); + control[i] = saturate(dot(GetDir(i), vSun)); + control[i] *= control[i]; + if (i == 4) D3D9DebugLog("Fwd %f", control[i].x); + if (i == 0) D3D9DebugLog("Up %f", control[i].x); + } + else { + control[i] = 0.0f; + } + } + + pBaker->SetFloat("fControl", control, sizeof(control)); + pBaker->SetBool("bEnabled", bSE, sizeof(bSE)); + + LPDIRECT3DSURFACE9 pSrf = NULL; + + if (bli->second.pSunAOComb) + { + if (bli->second.pSunAOComb->GetSurfaceLevel(0, &pSrf) == S_OK) + { + pBaker->SetOutputNative(0, pSrf); + pBaker->Execute(true); + SAFE_RELEASE(pSrf); + } + } + + bli++; + if (bli == BakedLights.end()) bli = BakedLights.begin(); +} + + // =========================================================================================== // LPDIRECT3DTEXTURE9 D3D9Mesh::GetCombinedMap(int tex_idx) diff --git a/OVP/D3D9Client/Mesh.h b/OVP/D3D9Client/Mesh.h index bdca5d2c7..3f57da9e7 100644 --- a/OVP/D3D9Client/Mesh.h +++ b/OVP/D3D9Client/Mesh.h @@ -74,7 +74,9 @@ struct _LightList { struct _BakedLights { LPDIRECT3DTEXTURE9 pMap[16]; + LPDIRECT3DTEXTURE9 pSunAO[6]; LPDIRECT3DTEXTURE9 pCombined; + LPDIRECT3DTEXTURE9 pSunAOComb; }; class MeshShader : public ShaderClass @@ -209,9 +211,10 @@ class D3D9Mesh : private D3D9Effect bool IsOK() const { return pBuf != NULL; } void Release(); - + void ClearBake(int i); void LoadBakedLights(); void BakeLights(ImageProcessing *pBaker); + void BakeAO(ImageProcessing* pBaker, const FVECTOR3 &vSun); void SetBakedLightLevel(int idx, const FVECTOR3 &level); void LoadMeshFromHandle(MESHHANDLE hMesh, D3DXVECTOR3 *reorig = NULL, float *scale = NULL); void ReLoadMeshFromHandle(MESHHANDLE hMesh); @@ -220,6 +223,8 @@ class D3D9Mesh : private D3D9Effect void SetName(const char *name); void SetName(UINT idx); const char * GetName() const { return name; } + const char * GetDirName(int i, int v); + FVECTOR3 GetDir(int i); void SetDefaultShader(WORD shader); WORD GetDefaultShader() const { return DefShader; } @@ -364,6 +369,7 @@ class D3D9Mesh : private D3D9Effect D3D9MatExt *Mtrl; // list of mesh materials SurfNative **Tex; // list of mesh textures std::map BakedLights; + std::map::const_iterator bli; FVECTOR3 BakedLightsControl[16]; D3DXMATRIX mTransform; D3DXMATRIX mTransformInv; diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index 0cc081bc5..5d9276ba8 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -338,6 +338,7 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) } pBakeLights = new ImageProcessing(pDevice, "Modules/D3D9Client/PreBakeLights.hlsl", "PSMain"); + pBakeLights->CompileShader("PSSunAO"); LogAlw("================ Scene Created ==============="); } diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index bd027fd96..1ef43e194 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -679,7 +679,9 @@ void vVessel::BakeLights(ImageProcessing *pBaker) if (!meshlist[i].mesh) continue; if (meshlist[i].vismode & MESHVIS_VC) { + auto vSun = tmul(FVECTOR4(sundir, 0), oapi::FMATRIX4(mWorld)); meshlist[i].mesh->BakeLights(pBaker); + meshlist[i].mesh->BakeAO(pBaker, vSun.xyz); } } } diff --git a/OVP/D3D9Client/shaders/PreBakeLights.hlsl b/OVP/D3D9Client/shaders/PreBakeLights.hlsl index bd2a26db0..e368392c6 100644 --- a/OVP/D3D9Client/shaders/PreBakeLights.hlsl +++ b/OVP/D3D9Client/shaders/PreBakeLights.hlsl @@ -5,6 +5,7 @@ uniform extern float3 fControl[16]; uniform extern int iCount; +uniform extern bool bEnabled[6]; sampler tMap[16] : register(s0); @@ -27,3 +28,16 @@ float4 PSMain(float x : TEXCOORD0, float y : TEXCOORD1) : COLOR [unroll] for (int i = 0; i < iCount; i++) color += tex2D(tMap[i], float2(x, y)).rgb * fControl[i]; return float4(LightFX(color), 1.0f); } + +// Combine multiple baked lightmaps into a single map +// +float4 PSSunAO(float x : TEXCOORD0, float y : TEXCOORD1) : COLOR +{ + float3 color = 0; + [unroll] for (int i = 0; i < 6; i++) { + if (bEnabled[i]) { + color += tex2D(tMap[i], float2(x, y)).rgb * fControl[i]; + } + } + return float4(LightFX(color), 1.0f); +} From 1945793772a5f721079594b2c82ddc1d7aa3a6ec Mon Sep 17 00:00:00 2001 From: jarmonik Date: Mon, 13 Nov 2023 06:35:36 +0200 Subject: [PATCH 22/42] Fixed light control slider's default position bug --- OVP/D3D9Client/DebugControls.cpp | 16 ++++++++++++++++ OVP/D3D9Client/Mesh.cpp | 17 +++++++++++++++++ OVP/D3D9Client/Mesh.h | 2 ++ 3 files changed, 35 insertions(+) diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index 120afaac5..b229e748e 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -59,6 +59,7 @@ char SaveFileName[255]; void UpdateMaterialDisplay(bool bSetup=false); void SetGFXSliders(); +void UpdateLightsSlider(); INT_PTR CALLBACK WndProcGFX(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void OpenGFXDlgClbk(void *context); @@ -1102,6 +1103,7 @@ void SelectMesh(D3D9Mesh *pMesh) } } SetupMeshGroups(); + UpdateLightsSlider(); } // ============================================================================================= @@ -1165,6 +1167,19 @@ void UpdateBakedLights(float lvl) } } +// ============================================================================================= +// +void UpdateLightsSlider() +{ + float val = 0.0f; + D3D9Mesh* mesh = (class D3D9Mesh*)vObj->GetMesh(sMesh); + if (mesh) { + if (bkl_id < 16 && bkl_id >= 0) val = mesh->GetBakedLightLevel(bkl_id).x; + if (bkl_id == 16) val = mesh->GetAmbientColor().x; + SendDlgItemMessage(hDlg, IDC_DBG_BKLADJ, TBM_SETPOS, 1, WORD(255.0f * val)); + } +} + // ============================================================================================= // LPDIRECT3DTEXTURE9 GetCombinedMap() @@ -1836,6 +1851,7 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case IDC_DBG_BKLID: if (HIWORD(wParam) == CBN_SELCHANGE) { bkl_id = int(SendDlgItemMessage(hDlg, IDC_DBG_BKLID, CB_GETCURSEL, 0, 0)); + UpdateLightsSlider(); } break; diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index 94be8c03a..57fb9470c 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -579,6 +579,15 @@ void D3D9Mesh::SetBakedLightLevel(int idx, const FVECTOR3 &level) } +// =========================================================================================== +// +FVECTOR3 D3D9Mesh::GetBakedLightLevel(int idx) +{ + if (idx >= 0 && idx <= 15) return BakedLightsControl[idx]; + return FVECTOR3(1, 1, 1); +} + + // =========================================================================================== // void D3D9Mesh::BakeLights(ImageProcessing* pBaker) @@ -1510,6 +1519,14 @@ void D3D9Mesh::SetAmbientColor(const FVECTOR3& c) cAmbient = c; } +// =========================================================================================== +// +const FVECTOR3& D3D9Mesh::GetAmbientColor() +{ + _TRACE; + return cAmbient; +} + // =========================================================================================== // void D3D9Mesh::SetupFog(const LPD3DXMATRIX pW) diff --git a/OVP/D3D9Client/Mesh.h b/OVP/D3D9Client/Mesh.h index 3f57da9e7..2754ea601 100644 --- a/OVP/D3D9Client/Mesh.h +++ b/OVP/D3D9Client/Mesh.h @@ -216,6 +216,7 @@ class D3D9Mesh : private D3D9Effect void BakeLights(ImageProcessing *pBaker); void BakeAO(ImageProcessing* pBaker, const FVECTOR3 &vSun); void SetBakedLightLevel(int idx, const FVECTOR3 &level); + FVECTOR3 GetBakedLightLevel(int idx); void LoadMeshFromHandle(MESHHANDLE hMesh, D3DXVECTOR3 *reorig = NULL, float *scale = NULL); void ReLoadMeshFromHandle(MESHHANDLE hMesh); void ReloadTextures(); @@ -326,6 +327,7 @@ class D3D9Mesh : private D3D9Effect void BoundingBox(const NMVERTEX *vtx, DWORD n, D9BBox *box); void SetAmbientColor(const FVECTOR3& c); + const FVECTOR3& GetAmbientColor(); void SetupFog(const LPD3DXMATRIX pW); void ResetRenderStatus(); From 9afe991cbc6cb2bff0c77fc25767dddfb81231f6 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Tue, 14 Nov 2023 21:59:59 +0200 Subject: [PATCH 23/42] Updated BakedVC shader to use baked sunlight map --- OVP/D3D9Client/D3D9Effect.cpp | 2 ++ OVP/D3D9Client/D3D9Effect.h | 1 + OVP/D3D9Client/Mesh.cpp | 2 ++ OVP/D3D9Client/shaders/BakedVC.fx | 8 ++++++-- OVP/D3D9Client/shaders/D3D9Client.fx | 13 +++++++++++++ 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/OVP/D3D9Client/D3D9Effect.cpp b/OVP/D3D9Client/D3D9Effect.cpp index b39a78ef6..62c299bf7 100644 --- a/OVP/D3D9Client/D3D9Effect.cpp +++ b/OVP/D3D9Client/D3D9Effect.cpp @@ -83,6 +83,7 @@ D3DXHANDLE D3D9Effect::eTransmMap = 0; D3DXHANDLE D3D9Effect::eIrradMap = 0; D3DXHANDLE D3D9Effect::eAmbientMap = 0; D3DXHANDLE D3D9Effect::eCombinedMap = 0; +D3DXHANDLE D3D9Effect::eCombSunMap = 0; D3DXHANDLE D3D9Effect::eSpecularMode = 0; D3DXHANDLE D3D9Effect::eHazeMode = 0; @@ -486,6 +487,7 @@ void D3D9Effect::D3D9TechInit(D3D9Client *_gc, LPDIRECT3DDEVICE9 _pDev, const ch eIrradMap = FX->GetParameterByName(0,"gIrradianceMap"); eAmbientMap = FX->GetParameterByName(0, "gAmbientMap"); eCombinedMap = FX->GetParameterByName(0, "gCombinedMap"); + eCombSunMap = FX->GetParameterByName(0, "gCombinedSunMap"); // Atmosphere ----------------------------------------------------------- eGlobalAmb = FX->GetParameterByName(0,"gGlobalAmb"); diff --git a/OVP/D3D9Client/D3D9Effect.h b/OVP/D3D9Client/D3D9Effect.h index a1086c278..e320ebcc5 100644 --- a/OVP/D3D9Client/D3D9Effect.h +++ b/OVP/D3D9Client/D3D9Effect.h @@ -185,6 +185,7 @@ class D3D9Effect { static D3DXHANDLE eIrradMap; static D3DXHANDLE eAmbientMap; static D3DXHANDLE eCombinedMap; + static D3DXHANDLE eCombSunMap; // Legacy Atmosphere ----------------------------------------------- static D3DXHANDLE eGlobalAmb; diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index 57fb9470c..d6f501cb8 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -2030,9 +2030,11 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, int iTech, LPDIRECT3DCUBETEXTURE9 * LPDIRECT3DTEXTURE9 pAmbi = Tex[ti]->GetMap(MAP_AMBIENT); LPDIRECT3DTEXTURE9 pComb = (bm == BakedLights.end() ? NULL : bm->second.pCombined); + LPDIRECT3DTEXTURE9 pSun = (bm == BakedLights.end() ? NULL : bm->second.pSunAOComb); if (pAmbi) FX->SetTexture(eAmbientMap, pAmbi); if (pComb) FX->SetTexture(eCombinedMap, pComb); + if (pSun) FX->SetTexture(eCombSunMap, pSun); FC.Baked = (pComb != NULL); FC.BakedAO = (pAmbi != NULL); diff --git a/OVP/D3D9Client/shaders/BakedVC.fx b/OVP/D3D9Client/shaders/BakedVC.fx index 7ae77e672..1bca1a88e 100644 --- a/OVP/D3D9Client/shaders/BakedVC.fx +++ b/OVP/D3D9Client/shaders/BakedVC.fx @@ -46,9 +46,13 @@ float4 BakedVC_PS(float4 sc : VPOS, PBRData frg) : COLOR else cEmis = 0; float3 cBL = 0; + float3 cBS = 0; float3 cBAO = 0; - if (gCfg.Baked) cBL = tex2D(BakedLightS, frg.tex0.xy).rgb; + if (gCfg.Baked) { + cBL = tex2D(BakedLightS, frg.tex0.xy).rgb; + cBS = tex2D(BakedSunS, frg.tex0.xy).rgb; + } if (gCfg.BakedAO) cBAO = tex2D(BakedAOS, frg.tex0.xy).rgb; @@ -186,7 +190,7 @@ float4 BakedVC_PS(float4 sc : VPOS, PBRData frg) : COLOR fA += fRgh * fMetal * 0.05f; // gVCAmbient is an application and debug controls controllable variable - float3 zD = cDiff.rgb * fA * LightFXSq(gMtrl.diffuse.rgb * (Sq(cSun * fR * dLN)) + Sq(gMtrl.emissive.rgb) + Sq(cBL) + Sq(gVCAmbient)); + float3 zD = cDiff.rgb * fA * LightFXSq(gMtrl.diffuse.rgb * (Sq(cSun * fR * dLN)) + Sq(gMtrl.emissive.rgb) + Sq(cBL) + Sq(cBS) + Sq(gVCAmbient)); // Combine specular terms float3 zS = cS * (cSun * dLN); diff --git a/OVP/D3D9Client/shaders/D3D9Client.fx b/OVP/D3D9Client/shaders/D3D9Client.fx index bc01733bb..d362685f4 100644 --- a/OVP/D3D9Client/shaders/D3D9Client.fx +++ b/OVP/D3D9Client/shaders/D3D9Client.fx @@ -156,6 +156,7 @@ uniform extern texture gTransmMap; // Transmittance Map uniform extern texture gIrradianceMap; // Irradiance Map uniform extern texture gAmbientMap; // Baked Ambient occlusion map uniform extern texture gCombinedMap; // Combined baked light map +uniform extern texture gCombinedSunMap; // Combined baked light map // Legacy Atmosphere -------------------------------------------------------- @@ -312,6 +313,18 @@ sampler BakedLightS = sampler_state // Primary Mesh texture sampler AddressV = WRAP; }; +sampler BakedSunS = sampler_state // Primary Mesh texture sampler +{ + Texture = ; + MinFilter = ANISOTROPIC; + MagFilter = LINEAR; + MipFilter = LINEAR; + MaxAnisotropy = ANISOTROPY_MACRO; + MipMapLODBias = 0; + AddressU = WRAP; + AddressV = WRAP; +}; + sampler BakedAOS = sampler_state // Primary Mesh texture sampler { Texture = ; From 0b59947da878c360d98298c9e9f54b8952ccd148 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Wed, 22 Nov 2023 18:36:20 +0200 Subject: [PATCH 24/42] Working on better mesh debugger. --- OVP/D3D9Client/D3D9Client.rc | 105 ++++++---- OVP/D3D9Client/DebugControls.cpp | 345 ++++++++++++++++++++++++++++++- OVP/D3D9Client/Mesh.cpp | 9 + OVP/D3D9Client/Mesh.h | 1 + OVP/D3D9Client/resource.h | 11 + 5 files changed, 419 insertions(+), 52 deletions(-) diff --git a/OVP/D3D9Client/D3D9Client.rc b/OVP/D3D9Client/D3D9Client.rc index a607d5d4f..8cec589db 100644 --- a/OVP/D3D9Client/D3D9Client.rc +++ b/OVP/D3D9Client/D3D9Client.rc @@ -34,16 +34,16 @@ FONT 8, "Ms Shell Dlg" LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK -IDD_D3D9MESHDEBUG DIALOG 0, 0, 374, 465 +IDD_D3D9MESHDEBUG DIALOG 0, 0, 373, 465 STYLE DS_3DLOOK | DS_CENTER | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_THICKFRAME | WS_SYSMENU EXSTYLE WS_EX_WINDOWEDGE CAPTION "D3D9 Debug Controls" FONT 8, "Ms Shell Dlg" { - GROUPBOX "Mesh Options", IDC_DBG_MESHGRP, 5, 166, 176, 60, 0, WS_EX_LEFT + GROUPBOX "Mesh Options", IDC_DBG_MESHGRP, 5, 165, 176, 35, 0, WS_EX_LEFT PUSHBUTTON "Close", IDCANCEL, 124, 429, 51, 14, 0, WS_EX_LEFT - PUSHBUTTON "Open", IDC_DBG_OPEN, 202, 169, 30, 14, 0, WS_EX_LEFT - PUSHBUTTON "Execute", IDC_DBG_EXECUTE, 305, 282, 56, 14, 0, WS_EX_LEFT + PUSHBUTTON "Open", IDC_DBG_OPEN, 387, 34, 30, 14, 0, WS_EX_LEFT + PUSHBUTTON "Execute", IDC_DBG_EXECUTE, 490, 147, 56, 14, 0, WS_EX_LEFT LTEXT "Selected Visual: Cape Canaveral", IDC_DBG_VISUAL, 7, 5, 104, 8, SS_LEFT, WS_EX_LEFT COMBOBOX IDC_DBG_DISPLAY, 48, 33, 120, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT LTEXT "Display", IDC_STATIC, 18, 36, 24, 8, SS_LEFT, WS_EX_LEFT @@ -53,82 +53,97 @@ FONT 8, "Ms Shell Dlg" LTEXT "Group Idx", IDC_STATIC, 18, 105, 32, 12, SS_LEFT, WS_EX_LEFT LTEXT "Mesh Idx", IDC_STATIC, 18, 90, 30, 8, SS_LEFT, WS_EX_LEFT EDITTEXT IDC_DBG_GROUP, 54, 105, 44, 12, WS_GROUP | ES_AUTOHSCROLL, WS_EX_LEFT - EDITTEXT IDC_DBG_FILE, 236, 170, 125, 12, WS_GROUP | ES_AUTOHSCROLL | ES_READONLY, WS_EX_LEFT + EDITTEXT IDC_DBG_FILE, 421, 35, 125, 12, WS_GROUP | ES_AUTOHSCROLL | ES_READONLY, WS_EX_LEFT AUTOCHECKBOX "Highlight selected group", IDC_DBG_HSG, 18, 123, 92, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Highlight selected mesh", IDC_DBG_HSM, 18, 135, 91, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Boxes", IDC_DBG_BOXES, 208, 317, 35, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Normalize", IDC_DBG_NORM, 215, 214, 47, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Mipmap fade", IDC_DBG_FADE, 215, 227, 57, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Reduce seams", IDC_DBG_SEAMS, 275, 214, 63, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Spheres", IDC_DBG_SPHERES, 208, 328, 42, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Surface Tiles", IDC_DBG_TILEBB, 208, 340, 57, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Selected group only", IDC_DBG_GRPO, 274, 317, 79, 8, 0, WS_EX_LEFT - GROUPBOX "Bounding geometry", IDC_STATIC, 195, 305, 175, 50, 0, WS_EX_LEFT - GROUPBOX "Visualize local light cones", IDC_STATIC, 195, 360, 175, 35, 0, WS_EX_LEFT + AUTOCHECKBOX "Boxes", IDC_DBG_BOXES, 208, 162, 35, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Normalize", IDC_DBG_NORM, 400, 79, 47, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Mipmap fade", IDC_DBG_FADE, 400, 92, 57, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Reduce seams", IDC_DBG_SEAMS, 460, 79, 63, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Spheres", IDC_DBG_SPHERES, 208, 173, 42, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Surface Tiles", IDC_DBG_TILEBB, 208, 185, 57, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Selected group only", IDC_DBG_GRPO, 274, 162, 79, 8, 0, WS_EX_LEFT + GROUPBOX "Bounding geometry", IDC_STATIC, 195, 150, 175, 50, 0, WS_EX_LEFT + GROUPBOX "Visualize local light cones", IDC_STATIC, 195, 205, 175, 35, 0, WS_EX_LEFT GROUPBOX "Mesh debugger", IDC_STATIC, 5, 20, 175, 142, 0, WS_EX_LEFT GROUPBOX "Misc.", IDC_STATIC, 195, 10, 173, 70, 0, WS_EX_LEFT GROUPBOX "Scene Debugger", IDC_STATIC, 195, 85, 173, 60, 0, WS_EX_LEFT - GROUPBOX "Texture Tools", IDC_STATIC, 195, 150, 173, 151, 0, WS_EX_LEFT - AUTOCHECKBOX "Selected mesh only", IDC_DBG_MSHO, 274, 329, 77, 8, 0, WS_EX_LEFT + GROUPBOX "Texture Tools", IDC_STATIC, 380, 15, 173, 151, 0, WS_EX_LEFT + AUTOCHECKBOX "Selected mesh only", IDC_DBG_MSHO, 274, 174, 77, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Dual sided", IDC_DBG_DUAL, 120, 123, 49, 8, 0, WS_EX_LEFT PUSHBUTTON "<", IDC_DBG_GRPUP, 102, 105, 9, 12, BS_CENTER, WS_EX_LEFT PUSHBUTTON ">", IDC_DBG_GRPDN, 114, 105, 9, 12, BS_CENTER, WS_EX_LEFT PUSHBUTTON "<", IDC_DBG_MSHUP, 102, 87, 9, 12, BS_CENTER, WS_EX_LEFT PUSHBUTTON ">", IDC_DBG_MSHDN, 114, 87, 9, 12, BS_CENTER, WS_EX_LEFT - AUTOCHECKBOX "Selected visual only", IDC_DBG_VISO, 274, 341, 79, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Selected visual only", IDC_DBG_VISO, 274, 186, 79, 8, 0, WS_EX_LEFT CONTROL "", IDC_DBG_SPEED, TRACKBAR_CLASS, WS_TABSTOP | TBS_BOTH | TBS_NOTICKS, 42, 69, 108, 13, WS_EX_LEFT CONTROL "", IDC_DBG_RESBIAS, TRACKBAR_CLASS, WS_TABSTOP | TBS_AUTOTICKS | TBS_BOTH, 205, 55, 155, 20, WS_EX_LEFT LTEXT "Speed", IDC_STATIC, 18, 69, 22, 8, SS_LEFT, WS_EX_LEFT LTEXT "Static", IDC_DBG_SPEEDDSP, 150, 69, 21, 10, SS_LEFT, WS_EX_LEFT AUTOCHECKBOX "Add ambient light", IDC_DBG_AMBIENT, 18, 147, 70, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Wireframe", IDC_DBG_WIRE, 120, 135, 48, 8, 0, WS_EX_LEFT - GROUPBOX "Material", IDC_DBG_MATGRP, 6, 230, 175, 160, 0, WS_EX_LEFT - COMBOBOX IDC_DBG_MATPRP, 78, 245, 96, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT + GROUPBOX "Material", IDC_DBG_MATGRP, 5, 205, 175, 175, 0, WS_EX_LEFT + COMBOBOX IDC_DBG_MATPRP, 77, 220, 96, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT COMBOBOX IDC_DBG_DEFSHADER, 77, 181, 96, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT - COMBOBOX IDC_DBG_CONES, 200, 375, 165, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT - LTEXT "Material property", IDC_STATIC, 19, 247, 53, 8, SS_LEFT, WS_EX_LEFT + COMBOBOX IDC_DBG_CONES, 200, 220, 165, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT + LTEXT "Material property", IDC_STATIC, 18, 222, 53, 8, SS_LEFT, WS_EX_LEFT LTEXT "Default Shader", IDC_STATIC, 15, 183, 48, 8, SS_LEFT, WS_EX_LEFT - EDITTEXT IDC_DBG_RED, 32, 265, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT - EDITTEXT IDC_DBG_GREEN, 68, 265, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT - EDITTEXT IDC_DBG_BLUE, 104, 265, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT - EDITTEXT IDC_DBG_ALPHA, 140, 265, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT - EDITTEXT IDC_DBG_VARA, 280, 262, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT - EDITTEXT IDC_DBG_VARC, 230, 262, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT - EDITTEXT IDC_DBG_VARB, 330, 262, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT + EDITTEXT IDC_DBG_RED, 31, 240, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT + EDITTEXT IDC_DBG_GREEN, 67, 240, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT + EDITTEXT IDC_DBG_BLUE, 103, 240, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT + EDITTEXT IDC_DBG_ALPHA, 139, 240, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT + EDITTEXT IDC_DBG_VARA, 465, 127, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT + EDITTEXT IDC_DBG_VARC, 415, 127, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT + EDITTEXT IDC_DBG_VARB, 515, 127, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT COMBOBOX IDC_DBG_ENVMAP, 275, 115, 86, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT COMBOBOX IDC_DBG_SCENEDBG, 255, 100, 106, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT - COMBOBOX IDC_DBG_ACTION, 265, 193, 95, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT - COMBOBOX IDC_DBG_TARGET, 235, 242, 126, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT + COMBOBOX IDC_DBG_ACTION, 450, 58, 95, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT + COMBOBOX IDC_DBG_TARGET, 420, 107, 126, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT LTEXT "Debug Mode", IDC_STATIC, 205, 102, 42, 8, SS_LEFT, WS_EX_LEFT LTEXT "Display special buffer", IDC_STATIC, 205, 117, 68, 9, SS_LEFT, WS_EX_LEFT LTEXT "Resolution Bias", IDC_STATIC, 205, 40, 50, 8, SS_LEFT, WS_EX_LEFT - LTEXT "Select Action", IDC_STATIC, 216, 195, 43, 8, SS_LEFT, WS_EX_LEFT - LTEXT "Target", IDC_STATIC, 207, 244, 25, 8, SS_LEFT, WS_EX_LEFT - LTEXT "Fb:", IDC_STATIC, 317, 264, 11, 8, SS_LEFT, WS_EX_LEFT - LTEXT "Fa:", IDC_STATIC, 267, 264, 11, 8, SS_LEFT, WS_EX_LEFT - LTEXT "Noise:", IDC_STATIC, 205, 264, 21, 8, SS_LEFT, WS_EX_LEFT - CONTROL "", IDC_DBG_MATADJ, TRACKBAR_CLASS, WS_TABSTOP | TBS_BOTH | TBS_NOTICKS, 20, 282, 156, 14, WS_EX_LEFT + LTEXT "Select Action", IDC_STATIC, 401, 60, 43, 8, SS_LEFT, WS_EX_LEFT + LTEXT "Target", IDC_STATIC, 392, 109, 25, 8, SS_LEFT, WS_EX_LEFT + LTEXT "Fb:", IDC_STATIC, 502, 129, 11, 8, SS_LEFT, WS_EX_LEFT + LTEXT "Fa:", IDC_STATIC, 452, 129, 11, 8, SS_LEFT, WS_EX_LEFT + LTEXT "Noise:", IDC_STATIC, 390, 129, 21, 8, SS_LEFT, WS_EX_LEFT + CONTROL "", IDC_DBG_MATADJ, TRACKBAR_CLASS, WS_TABSTOP | TBS_BOTH | TBS_NOTICKS, 19, 257, 156, 14, WS_EX_LEFT PUSHBUTTON "Save materials", IDC_DBG_MATSAVE, 5, 429, 51, 14, 0, WS_EX_LEFT - PUSHBUTTON "Create kernel", IDC_DBG_KERNEL, 310, 25, 47, 14, 0, WS_EX_LEFT + PUSHBUTTON "Create kernel", IDC_DBG_KERNEL, 315, 430, 47, 14, 0, WS_EX_LEFT PUSHBUTTON "Data window", IDC_DBG_DATAWND, 5, 446, 50, 14, 0, WS_EX_LEFT PUSHBUTTON "Save envmap", IDC_DBG_ENVSAVE, 205, 128, 60, 12, 0, WS_EX_LEFT PUSHBUTTON ">>>", IDC_DBG_MORE, 124, 446, 50, 14, 0, WS_EX_LEFT PUSHBUTTON "Reload Shader", IDC_DBG_RELOADSHD, 60, 446, 60, 14, 0, WS_EX_LEFT PUSHBUTTON "Reload Textures", IDC_DBG_RELOADTEX, 60, 430, 60, 14, 0, WS_EX_LEFT - LTEXT "Texture: None", IDC_DBG_TEXTURE, 10, 352, 168, 10, SS_LEFT, WS_EX_LEFT + LTEXT "Texture: None", IDC_DBG_TEXTURE, 9, 327, 168, 10, SS_LEFT, WS_EX_LEFT AUTOCHECKBOX "Pick", IDC_DBG_PICK, 120, 147, 30, 8, 0, WS_EX_LEFT - LTEXT "Mesh: None", IDC_DBG_MESHNAME, 10, 363, 168, 10, SS_LEFT, WS_EX_LEFT - LTEXT "Group Status:", IDC_DBG_GROUPSTAT, 10, 374, 170, 10, SS_LEFT, WS_EX_LEFT - PUSHBUTTON "Paste", IDC_DBG_PASTE, 134, 300, 37, 14, 0, WS_EX_LEFT - PUSHBUTTON "Copy", IDC_DBG_COPY, 91, 300, 39, 14, 0, WS_EX_LEFT - AUTOCHECKBOX "Link channels", IDC_DBG_LINK, 20, 307, 60, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Use and Save the property", IDC_DBG_DEFINED, 20, 335, 101, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Extend material range", IDC_DBG_EXTEND, 20, 321, 84, 8, 0, WS_EX_LEFT + LTEXT "Mesh: None", IDC_DBG_MESHNAME, 9, 339, 168, 10, SS_LEFT, WS_EX_LEFT + LTEXT "Group Status:", IDC_DBG_GROUPSTAT, 10, 350, 170, 10, SS_LEFT, WS_EX_LEFT + PUSHBUTTON "Paste", IDC_DBG_PASTE, 133, 275, 37, 14, 0, WS_EX_LEFT + PUSHBUTTON "Copy", IDC_DBG_COPY, 90, 275, 39, 14, 0, WS_EX_LEFT + AUTOCHECKBOX "Link channels", IDC_DBG_LINK, 19, 282, 60, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Use and Save the property", IDC_DBG_DEFINED, 19, 310, 101, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Extend material range", IDC_DBG_EXTEND, 19, 296, 84, 8, 0, WS_EX_LEFT AUTOCHECKBOX "FPS Limiter", IDC_DBG_FPSLIM, 205, 25, 51, 8, 0, WS_EX_LEFT PUSHBUTTON "Export textures", IDC_DBG_EXPTEX, 315, 445, 52, 14, 0, WS_EX_LEFT COMBOBOX IDC_DBG_BKLID, 10, 406, 50, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT GROUPBOX "Baked Lights", 0, 5, 394, 175, 30, 0, WS_EX_LEFT CONTROL "", IDC_DBG_BKLADJ, TRACKBAR_CLASS, WS_TABSTOP | TBS_BOTH | TBS_NOTICKS, 64, 404, 115, 15, WS_EX_LEFT + GROUPBOX "Mesh Group Information", IDC_STATIC, 195, 245, 175, 130, 0, WS_EX_LEFT + AUTOCHECKBOX "No Shadow", IDC_DBG_NOSHADOW, 200, 260, 53, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Do not render", IDC_DBG_NORENDER, 200, 270, 59, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Always Lit", IDC_DBG_NOLIGHT, 200, 280, 47, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Additive Blend", IDC_DBG_ADDITIVE, 200, 290, 61, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Texture Alpha Only (No Color)", IDC_DBG_NOCOLOR, 200, 300, 109, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Order Independent Transparency", IDC_DBG_OIT, 200, 310, 121, 8, 0, WS_EX_LEFT + EDITTEXT IDC_DBG_MATIDX, 225, 325, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT + EDITTEXT IDC_DBG_TEXIDX, 225, 340, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT + LTEXT "MatIdx", IDC_STATIC, 200, 326, 22, 9, SS_LEFT, WS_EX_LEFT + LTEXT "TexIdx", IDC_STATIC, 200, 342, 22, 9, SS_LEFT, WS_EX_LEFT + PUSHBUTTON "Save Mesh", IDC_DBG_MESHSAVE, 200, 430, 55, 14, 0, WS_EX_LEFT + PUSHBUTTON "Unrendered", IDC_DBG_NEXT, 127, 105, 48, 12, 0, WS_EX_LEFT + LTEXT "Label", IDC_STATIC, 201, 357, 18, 9, SS_LEFT, WS_EX_LEFT + EDITTEXT IDC_DBG_GRPLABEL, 225, 355, 140, 12, ES_AUTOHSCROLL, WS_EX_LEFT } diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index b229e748e..667a6e326 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -17,7 +17,9 @@ #include "Mesh.h" #include "MaterialMgr.h" #include "VectorHelpers.h" +#include "OapiExtension.h" #include +#include enum scale { LIN, SQRT, SQR }; @@ -45,6 +47,7 @@ HWND hGfxDlg = NULL; HWND hDlg = NULL; HWND hDataWnd = NULL; vObject *vObj = NULL; +D3D9Mesh* hSelMesh = NULL; std::string buffer(""); std::string buffer2(""); D3DXVECTOR3 PickLocation; @@ -53,9 +56,11 @@ std::map Emitters; HWND hTipRed, hTipGrn, hTipBlu, hTipAlp; -OPENFILENAMEA OpenTex, SaveTex; +OPENFILENAMEA OpenTex, SaveTex, SaveMesh; char OpenFileName[255]; char SaveFileName[255]; +char SaveMeshName[255]; +char SaveMeshTitle[255]; void UpdateMaterialDisplay(bool bSetup=false); void SetGFXSliders(); @@ -88,6 +93,200 @@ struct _Params { _Params Params[10] = { 0 }; +struct DbgMeshGrp { + vector Lines; + vector Vtx; + vector Idx; +}; + + +class DbgMesh +{ +public: + + DbgMesh(const char* file) + { + enum sec { header, group, geom, materials, textures }; + sec sec = header; + char buf[256]; + DWORD ng = 0, nm = 0, nt = 0, nv = 0, ni = 0, gi = 0; + std::ifstream is(file); + + if (is.is_open()) + { + while (is.getline(buf, 256)) + { + if (!_strnicmp(buf, "MATERIALS", 9)) sec = materials; + if (!_strnicmp(buf, "TEXTURES", 8)) sec = textures; + + if (sec == header) Header.push_back(buf); + if (sec == materials) Materials.push_back(buf); + if (sec == textures) Textures.push_back(buf); + + if (!_strnicmp(buf, "GROUPS", 6)) + { + if (sscanf(buf + 6, "%d", &ng) != 1) throw std::invalid_argument("End of file"); + Groups.resize(ng); + + for (gi = 0;gi> key >> std::hex >> x; + return x; + } + } + return 0; + } + + DWORD GetGroupMaterial(DWORD grp) + { + DWORD x; + for (auto a : Groups[grp].Lines) { + if (a.find("MATERIAL") != string::npos) { + std::istringstream iss(a); + iss >> key >> x; + return x; + } + } + if (grp > 0) return GetGroupMaterial(grp - 1); + return 0; + } + + DWORD GetGroupTexture(DWORD grp) + { + DWORD x; + for (auto a : Groups[grp].Lines) { + if (a.find("TEXTURE") != string::npos) { + std::istringstream iss(a); + iss >> key >> x; + return x; + } + } + if (grp > 0) return GetGroupTexture(grp - 1); + return 0; + } + + string GetGroupLabel(DWORD grp) + { + string x; + for (auto a : Groups[grp].Lines) { + if (a.find("LABEL") != string::npos) { + std::istringstream iss(a); + iss >> key >> x; + return x; + } + } + return string(""); + } + + void SetGroupFlags(DWORD grp, DWORD f) + { + std::stringstream s; + s << std::hex << f; + for (auto &a : Groups[grp].Lines) { + if (a.find("FLAG") != string::npos) { + a = s.str(); + return; + } + } + } + + void SetGroupMaterial(DWORD grp, DWORD x) + { + for (auto& a : Groups[grp].Lines) { + if (a.find("MATERIAL") != string::npos) { + a = string("MATERIAL ") + std::to_string(x); + return; + } + } + } + + void SetGroupTexture(DWORD grp, DWORD x) + { + for (auto& a : Groups[grp].Lines) { + if (a.find("TEXTURE") != string::npos) { + a = string("TEXTURE ") + std::to_string(x); + return; + } + } + } + + void SetGroupLabel(DWORD grp, string x) + { + for (auto& a : Groups[grp].Lines) { + if (a.find("LABEL") != string::npos) { + a = string("LABEL ") + x; + return; + } + } + } + + vector Header; + vector Materials; + vector Textures; + vector Groups; + string key; +}; + + +map dbgMsh; // =========================================================================== @@ -211,6 +410,20 @@ void Create() SaveTex.nMaxFileTitle = 0; SaveTex.Flags = OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR; + memset(&SaveMesh, 0, sizeof(OPENFILENAME)); + memset(SaveMeshName, 0, sizeof(SaveMeshName)); + memset(SaveMeshTitle, 0, sizeof(SaveMeshTitle)); + + SaveMesh.lStructSize = sizeof(OPENFILENAME); + SaveMesh.lpstrFile = SaveMeshName; + SaveMesh.lpstrInitialDir = "Meshes\0"; + SaveMesh.nMaxFile = sizeof(SaveMeshName); + SaveMesh.lpstrFilter = "*.msh\0"; + SaveMesh.nFilterIndex = 0; + SaveMesh.lpstrFileTitle = SaveMeshTitle; + SaveMesh.nMaxFileTitle = 0; + SaveMesh.Flags = OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR; + PrmList.push_back(MatParams("Diffuse", 0)); PrmList.push_back(MatParams("Ambient", 1)); PrmList.push_back(MatParams("Specular", 2)); @@ -268,6 +481,7 @@ void Release() if (dwGFX) oapiUnregisterCustomCmd(dwGFX); dwCmd = NULL; dwGFX = NULL; + for (auto x : dbgMsh) SAFE_DELETE(x.second); } // ============================================================================================= @@ -574,6 +788,10 @@ float _Clamp(float value, DWORD p, DWORD v) return CLAMP(value, Params[p].var[v].min, (bExtend ? Params[p].var[v].extmax : Params[p].var[v].max)); } + + + + // ============================================================================================= // void UpdateShader() @@ -609,6 +827,78 @@ void UpdateShader() InitMatList(hMesh->GetDefaultShader()); } + +// ============================================================================================= +// +void UpdateGroup(DWORD grp) +{ + D3D9Mesh* hMesh = (D3D9Mesh*)vObj->GetMesh(sMesh); + if (!hMesh) return; + + auto dm = dbgMsh[hMesh]; + if (grp >= hMesh->GetGroupCount()) return; + auto g = hMesh->GetGroup(grp); + + if (g) { + SendDlgItemMessage(hDlg, IDC_DBG_NOSHADOW, BM_SETCHECK, (g->UsrFlag & 0x1) != 0, 0); + SendDlgItemMessage(hDlg, IDC_DBG_NORENDER, BM_SETCHECK, (g->UsrFlag & 0x2) != 0, 0); + SendDlgItemMessage(hDlg, IDC_DBG_NOLIGHT, BM_SETCHECK, (g->UsrFlag & 0x4) != 0, 0); + SendDlgItemMessage(hDlg, IDC_DBG_ADDITIVE, BM_SETCHECK, (g->UsrFlag & 0x8) != 0, 0); + SendDlgItemMessage(hDlg, IDC_DBG_NOCOLOR, BM_SETCHECK, (g->UsrFlag & 0x10) != 0, 0); + SendDlgItemMessage(hDlg, IDC_DBG_OIT, BM_SETCHECK, (g->UsrFlag & 0x20) != 0, 0); + + char buf[64]; + sprintf_s(buf, 64, "%d", g->MtrlIdx); + SetWindowText(GetDlgItem(hDlg, IDC_DBG_MATIDX), buf); + sprintf_s(buf, 64, "%d", g->TexIdx); + SetWindowText(GetDlgItem(hDlg, IDC_DBG_TEXIDX), buf); + if (dm) { + sprintf_s(buf, 64, "%s", dm->GetGroupLabel(grp).c_str()); + SetWindowText(GetDlgItem(hDlg, IDC_DBG_GRPLABEL), buf); + } + } +} + + +// ============================================================================================= +// +void ValidateGroup(DWORD grp) +{ + D3D9Mesh* hMesh = (D3D9Mesh*)vObj->GetMesh(sMesh); + if (!hMesh) return; + + auto dm = dbgMsh[hMesh]; + if (grp >= hMesh->GetGroupCount()) return; + auto g = hMesh->GetGroup(grp); + DWORD f = 0; + + if (g && dm) + { + if (SendDlgItemMessage(hDlg, IDC_DBG_NOSHADOW, BM_GETCHECK, 0, 0) == BST_CHECKED) f |= 0x1; + if (SendDlgItemMessage(hDlg, IDC_DBG_NORENDER, BM_GETCHECK, 0, 0) == BST_CHECKED) f |= 0x2; + if (SendDlgItemMessage(hDlg, IDC_DBG_NOLIGHT, BM_GETCHECK, 0, 0) == BST_CHECKED) f |= 0x4; + if (SendDlgItemMessage(hDlg, IDC_DBG_ADDITIVE, BM_GETCHECK, 0, 0) == BST_CHECKED) f |= 0x8; + if (SendDlgItemMessage(hDlg, IDC_DBG_NOCOLOR, BM_GETCHECK, 0, 0) == BST_CHECKED) f |= 0x10; + if (SendDlgItemMessage(hDlg, IDC_DBG_OIT, BM_GETCHECK, 0, 0) == BST_CHECKED) f |= 0x20; + + g->UsrFlag = f; + dm->SetGroupFlags(grp, f); + + char buf[64]; + GetWindowText(GetDlgItem(hDlg, IDC_DBG_MATIDX), buf, 64); + g->MtrlIdx = atoi(buf); + dm->SetGroupMaterial(grp, g->MtrlIdx); + + GetWindowText(GetDlgItem(hDlg, IDC_DBG_TEXIDX), buf, 64); + g->TexIdx = atoi(buf); + dm->SetGroupTexture(grp, g->TexIdx); + + GetWindowText(GetDlgItem(hDlg, IDC_DBG_GRPLABEL), buf, 64); + dm->SetGroupLabel(grp, string(buf)); + } +} + + // ============================================================================================= // void UpdateMeshMaterial(float value, DWORD MatPrp, DWORD clr) @@ -1096,10 +1386,18 @@ void SelectGroup(DWORD idx) // void SelectMesh(D3D9Mesh *pMesh) { - for (DWORD i=0;iGetMesh(i)==pMesh) { - sMesh = i; - break; + char MeshFile[MAX_PATH]; + + if (pMesh != hSelMesh) + { + for (DWORD i = 0; i < nMesh; i++) { + if (vObj->GetMesh(i) == pMesh) { + sMesh = i; + hSelMesh = pMesh; + sprintf_s(MeshFile, MAX_PATH, "%s%s.msh", OapiExtension::GetMeshDir(), pMesh->GetName()); + dbgMsh[pMesh] = new DbgMesh(MeshFile); + break; + } } } SetupMeshGroups(); @@ -1138,6 +1436,7 @@ void SetupMeshGroups() if (nGroup!=0) { if (sGroup>0xFFFF) sGroup = nGroup-1; if (sGroup>=nGroup) sGroup = 0; + UpdateGroup(sGroup); } else { sGroup=0; @@ -1920,6 +2219,19 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) oapiSetPause(bPaused); break; + case IDC_DBG_MESHSAVE: + if (dbgMsh[hSelMesh]) { + bPaused = oapiGetPause(); + oapiSetPause(true); + strcpy(SaveMesh.lpstrFileTitle, hSelMesh->GetName()); + if (GetSaveFileName(&SaveMesh)) { + dbgMsh[hSelMesh]->Save(SaveMesh.lpstrFile); + return true; + } + oapiSetPause(bPaused); + } + break; + case IDC_DBG_ACTION: break; @@ -1966,6 +2278,25 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) UpdateFlags(); break; + case IDC_DBG_NOSHADOW: + case IDC_DBG_NORENDER: + case IDC_DBG_NOLIGHT: + case IDC_DBG_ADDITIVE: + case IDC_DBG_NOCOLOR: + case IDC_DBG_OIT: + if (HIWORD(wParam) == BN_CLICKED) { + ValidateGroup(sGroup); + } + break; + + case IDC_DBG_MATIDX: + case IDC_DBG_TEXIDX: + case IDC_DBG_GRPLABEL: + if (HIWORD(wParam) == EN_KILLFOCUS) { + ValidateGroup(sGroup); + } + break; + case IDC_DBG_VARA: case IDC_DBG_VARB: case IDC_DBG_VARC: @@ -1973,7 +2304,7 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) break; default: - LogErr("LOWORD(%hu), HIWORD(0x%hX)",LOWORD(wParam),HIWORD(wParam)); + //LogErr("LOWORD(%hu), HIWORD(0x%hX)",LOWORD(wParam),HIWORD(wParam)); break; } break; @@ -2249,7 +2580,7 @@ INT_PTR CALLBACK WndProcGFX(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) break; default: - LogErr("WndProcGFX() LOWORD(%hu), HIWORD(0x%hX)", LOWORD(wParam), HIWORD(wParam)); + //LogErr("WndProcGFX() LOWORD(%hu), HIWORD(0x%hX)", LOWORD(wParam), HIWORD(wParam)); break; } break; diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index d6f501cb8..172bc9675 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -1277,6 +1277,15 @@ const D3D9Mesh::GROUPREC *D3D9Mesh::GetGroup(DWORD idx) const return NULL; } +// =========================================================================================== +// +D3D9Mesh::GROUPREC* D3D9Mesh::GetGroup(DWORD idx) +{ + if (!IsOK()) return NULL; + if (idx < nGrp) return &Grp[idx]; + return NULL; +} + // =========================================================================================== // const D3D9MatExt * D3D9Mesh::GetMaterial(DWORD idx) const diff --git a/OVP/D3D9Client/Mesh.h b/OVP/D3D9Client/Mesh.h index 2754ea601..82306e632 100644 --- a/OVP/D3D9Client/Mesh.h +++ b/OVP/D3D9Client/Mesh.h @@ -245,6 +245,7 @@ class D3D9Mesh : private D3D9Effect * \return Pointer to group structure. */ const GROUPREC * GetGroup(DWORD idx) const; + GROUPREC* GetGroup(DWORD idx); void SetMFDScreenId(DWORD idx, WORD id); void SetDualSided(DWORD idx, bool bState) { Grp[idx].bDualSided = bState; } diff --git a/OVP/D3D9Client/resource.h b/OVP/D3D9Client/resource.h index ca5458441..969d43da1 100644 --- a/OVP/D3D9Client/resource.h +++ b/OVP/D3D9Client/resource.h @@ -222,3 +222,14 @@ #define IDC_DBG_BKLID 3038 #define IDC_DBG_BKLADJ 3039 #define IDC_CASCOUNT 3040 +#define IDC_DBG_NOSHADOW 3041 +#define IDC_DBG_NORENDER 3042 +#define IDC_DBG_NOLIGHT 3043 +#define IDC_DBG_ADDITIVE 3044 +#define IDC_DBG_NOCOLOR 3045 +#define IDC_DBG_OIT 3046 +#define IDC_DBG_MATIDX 3047 +#define IDC_DBG_TEXIDX 3048 +#define IDC_DBG_MESHSAVE 3049 +#define IDC_DBG_NEXT 3050 +#define IDC_DBG_GRPLABEL 3051 From b868bef0fd78a43d29248695ad9071ab9c6bac86 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Thu, 23 Nov 2023 14:35:14 +0200 Subject: [PATCH 25/42] Added additional debug options and bug fixes --- OVP/D3D9Client/D3D9Client.rc | 50 +++++++++++++++++--------------- OVP/D3D9Client/DebugControls.cpp | 39 +++++++++++++++++++++++++ OVP/D3D9Client/DebugControls.h | 2 ++ OVP/D3D9Client/Scene.cpp | 10 +++++++ OVP/D3D9Client/resource.h | 2 ++ 5 files changed, 79 insertions(+), 24 deletions(-) diff --git a/OVP/D3D9Client/D3D9Client.rc b/OVP/D3D9Client/D3D9Client.rc index 8cec589db..5a53064a8 100644 --- a/OVP/D3D9Client/D3D9Client.rc +++ b/OVP/D3D9Client/D3D9Client.rc @@ -40,7 +40,7 @@ EXSTYLE WS_EX_WINDOWEDGE CAPTION "D3D9 Debug Controls" FONT 8, "Ms Shell Dlg" { - GROUPBOX "Mesh Options", IDC_DBG_MESHGRP, 5, 165, 176, 35, 0, WS_EX_LEFT + GROUPBOX "Mesh Options", IDC_DBG_MESHGRP, 3, 189, 176, 35, 0, WS_EX_LEFT PUSHBUTTON "Close", IDCANCEL, 124, 429, 51, 14, 0, WS_EX_LEFT PUSHBUTTON "Open", IDC_DBG_OPEN, 387, 34, 30, 14, 0, WS_EX_LEFT PUSHBUTTON "Execute", IDC_DBG_EXECUTE, 490, 147, 56, 14, 0, WS_EX_LEFT @@ -55,7 +55,7 @@ FONT 8, "Ms Shell Dlg" EDITTEXT IDC_DBG_GROUP, 54, 105, 44, 12, WS_GROUP | ES_AUTOHSCROLL, WS_EX_LEFT EDITTEXT IDC_DBG_FILE, 421, 35, 125, 12, WS_GROUP | ES_AUTOHSCROLL | ES_READONLY, WS_EX_LEFT AUTOCHECKBOX "Highlight selected group", IDC_DBG_HSG, 18, 123, 92, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Highlight selected mesh", IDC_DBG_HSM, 18, 135, 91, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Highlight selected mesh", IDC_DBG_HSM, 18, 133, 91, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Boxes", IDC_DBG_BOXES, 208, 162, 35, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Normalize", IDC_DBG_NORM, 400, 79, 47, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Mipmap fade", IDC_DBG_FADE, 400, 92, 57, 8, 0, WS_EX_LEFT @@ -65,7 +65,7 @@ FONT 8, "Ms Shell Dlg" AUTOCHECKBOX "Selected group only", IDC_DBG_GRPO, 274, 162, 79, 8, 0, WS_EX_LEFT GROUPBOX "Bounding geometry", IDC_STATIC, 195, 150, 175, 50, 0, WS_EX_LEFT GROUPBOX "Visualize local light cones", IDC_STATIC, 195, 205, 175, 35, 0, WS_EX_LEFT - GROUPBOX "Mesh debugger", IDC_STATIC, 5, 20, 175, 142, 0, WS_EX_LEFT + GROUPBOX "Mesh debugger", IDC_STATIC, 5, 20, 175, 160, 0, WS_EX_LEFT GROUPBOX "Misc.", IDC_STATIC, 195, 10, 173, 70, 0, WS_EX_LEFT GROUPBOX "Scene Debugger", IDC_STATIC, 195, 85, 173, 60, 0, WS_EX_LEFT GROUPBOX "Texture Tools", IDC_STATIC, 380, 15, 173, 151, 0, WS_EX_LEFT @@ -80,18 +80,18 @@ FONT 8, "Ms Shell Dlg" CONTROL "", IDC_DBG_RESBIAS, TRACKBAR_CLASS, WS_TABSTOP | TBS_AUTOTICKS | TBS_BOTH, 205, 55, 155, 20, WS_EX_LEFT LTEXT "Speed", IDC_STATIC, 18, 69, 22, 8, SS_LEFT, WS_EX_LEFT LTEXT "Static", IDC_DBG_SPEEDDSP, 150, 69, 21, 10, SS_LEFT, WS_EX_LEFT - AUTOCHECKBOX "Add ambient light", IDC_DBG_AMBIENT, 18, 147, 70, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Wireframe", IDC_DBG_WIRE, 120, 135, 48, 8, 0, WS_EX_LEFT - GROUPBOX "Material", IDC_DBG_MATGRP, 5, 205, 175, 175, 0, WS_EX_LEFT - COMBOBOX IDC_DBG_MATPRP, 77, 220, 96, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT - COMBOBOX IDC_DBG_DEFSHADER, 77, 181, 96, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT + AUTOCHECKBOX "Add ambient light", IDC_DBG_AMBIENT, 18, 143, 70, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Wireframe", IDC_DBG_WIRE, 120, 133, 48, 8, 0, WS_EX_LEFT + GROUPBOX "Material", IDC_DBG_MATGRP, 3, 229, 175, 160, 0, WS_EX_LEFT + COMBOBOX IDC_DBG_MATPRP, 75, 244, 96, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT + COMBOBOX IDC_DBG_DEFSHADER, 75, 205, 96, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT COMBOBOX IDC_DBG_CONES, 200, 220, 165, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT - LTEXT "Material property", IDC_STATIC, 18, 222, 53, 8, SS_LEFT, WS_EX_LEFT - LTEXT "Default Shader", IDC_STATIC, 15, 183, 48, 8, SS_LEFT, WS_EX_LEFT - EDITTEXT IDC_DBG_RED, 31, 240, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT - EDITTEXT IDC_DBG_GREEN, 67, 240, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT - EDITTEXT IDC_DBG_BLUE, 103, 240, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT - EDITTEXT IDC_DBG_ALPHA, 139, 240, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT + LTEXT "Material property", IDC_STATIC, 16, 246, 53, 8, SS_LEFT, WS_EX_LEFT + LTEXT "Default Shader", IDC_STATIC, 13, 207, 48, 8, SS_LEFT, WS_EX_LEFT + EDITTEXT IDC_DBG_RED, 29, 264, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT + EDITTEXT IDC_DBG_GREEN, 65, 264, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT + EDITTEXT IDC_DBG_BLUE, 101, 264, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT + EDITTEXT IDC_DBG_ALPHA, 137, 264, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT EDITTEXT IDC_DBG_VARA, 465, 127, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT EDITTEXT IDC_DBG_VARC, 415, 127, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT EDITTEXT IDC_DBG_VARB, 515, 127, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT @@ -107,7 +107,7 @@ FONT 8, "Ms Shell Dlg" LTEXT "Fb:", IDC_STATIC, 502, 129, 11, 8, SS_LEFT, WS_EX_LEFT LTEXT "Fa:", IDC_STATIC, 452, 129, 11, 8, SS_LEFT, WS_EX_LEFT LTEXT "Noise:", IDC_STATIC, 390, 129, 21, 8, SS_LEFT, WS_EX_LEFT - CONTROL "", IDC_DBG_MATADJ, TRACKBAR_CLASS, WS_TABSTOP | TBS_BOTH | TBS_NOTICKS, 19, 257, 156, 14, WS_EX_LEFT + CONTROL "", IDC_DBG_MATADJ, TRACKBAR_CLASS, WS_TABSTOP | TBS_BOTH | TBS_NOTICKS, 17, 281, 156, 14, WS_EX_LEFT PUSHBUTTON "Save materials", IDC_DBG_MATSAVE, 5, 429, 51, 14, 0, WS_EX_LEFT PUSHBUTTON "Create kernel", IDC_DBG_KERNEL, 315, 430, 47, 14, 0, WS_EX_LEFT PUSHBUTTON "Data window", IDC_DBG_DATAWND, 5, 446, 50, 14, 0, WS_EX_LEFT @@ -115,15 +115,15 @@ FONT 8, "Ms Shell Dlg" PUSHBUTTON ">>>", IDC_DBG_MORE, 124, 446, 50, 14, 0, WS_EX_LEFT PUSHBUTTON "Reload Shader", IDC_DBG_RELOADSHD, 60, 446, 60, 14, 0, WS_EX_LEFT PUSHBUTTON "Reload Textures", IDC_DBG_RELOADTEX, 60, 430, 60, 14, 0, WS_EX_LEFT - LTEXT "Texture: None", IDC_DBG_TEXTURE, 9, 327, 168, 10, SS_LEFT, WS_EX_LEFT - AUTOCHECKBOX "Pick", IDC_DBG_PICK, 120, 147, 30, 8, 0, WS_EX_LEFT - LTEXT "Mesh: None", IDC_DBG_MESHNAME, 9, 339, 168, 10, SS_LEFT, WS_EX_LEFT - LTEXT "Group Status:", IDC_DBG_GROUPSTAT, 10, 350, 170, 10, SS_LEFT, WS_EX_LEFT - PUSHBUTTON "Paste", IDC_DBG_PASTE, 133, 275, 37, 14, 0, WS_EX_LEFT - PUSHBUTTON "Copy", IDC_DBG_COPY, 90, 275, 39, 14, 0, WS_EX_LEFT - AUTOCHECKBOX "Link channels", IDC_DBG_LINK, 19, 282, 60, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Use and Save the property", IDC_DBG_DEFINED, 19, 310, 101, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Extend material range", IDC_DBG_EXTEND, 19, 296, 84, 8, 0, WS_EX_LEFT + LTEXT "Texture: None", IDC_DBG_TEXTURE, 7, 351, 168, 10, SS_LEFT, WS_EX_LEFT + AUTOCHECKBOX "Pick", IDC_DBG_PICK, 120, 143, 30, 8, 0, WS_EX_LEFT + LTEXT "Mesh: None", IDC_DBG_MESHNAME, 7, 363, 168, 10, SS_LEFT, WS_EX_LEFT + LTEXT "Group Status:", IDC_DBG_GROUPSTAT, 8, 374, 170, 10, SS_LEFT, WS_EX_LEFT + PUSHBUTTON "Paste", IDC_DBG_PASTE, 131, 299, 37, 14, 0, WS_EX_LEFT + PUSHBUTTON "Copy", IDC_DBG_COPY, 88, 299, 39, 14, 0, WS_EX_LEFT + AUTOCHECKBOX "Link channels", IDC_DBG_LINK, 17, 306, 60, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Use and Save the property", IDC_DBG_DEFINED, 17, 334, 101, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Extend material range", IDC_DBG_EXTEND, 17, 320, 84, 8, 0, WS_EX_LEFT AUTOCHECKBOX "FPS Limiter", IDC_DBG_FPSLIM, 205, 25, 51, 8, 0, WS_EX_LEFT PUSHBUTTON "Export textures", IDC_DBG_EXPTEX, 315, 445, 52, 14, 0, WS_EX_LEFT COMBOBOX IDC_DBG_BKLID, 10, 406, 50, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT @@ -144,6 +144,8 @@ FONT 8, "Ms Shell Dlg" PUSHBUTTON "Unrendered", IDC_DBG_NEXT, 127, 105, 48, 12, 0, WS_EX_LEFT LTEXT "Label", IDC_STATIC, 201, 357, 18, 9, SS_LEFT, WS_EX_LEFT EDITTEXT IDC_DBG_GRPLABEL, 225, 355, 140, 12, ES_AUTOHSCROLL, WS_EX_LEFT + AUTOCHECKBOX "Exterior in VC", IDC_DBG_EXTVC, 120, 153, 58, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "10cm near clip distance", IDC_DBG_CLIPDIST, 18, 153, 91, 8, 0, WS_EX_LEFT } diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index 667a6e326..e717714c3 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -501,6 +501,8 @@ void UpdateFlags() SETFLAG(debugFlags, DBG_FLAGS_DUALSIDED, (SendDlgItemMessageA(hDlg, IDC_DBG_DUAL, BM_GETCHECK, 0, 0)==BST_CHECKED)); SETFLAG(debugFlags, DBG_FLAGS_PICK, (SendDlgItemMessageA(hDlg, IDC_DBG_PICK, BM_GETCHECK, 0, 0)==BST_CHECKED)); SETFLAG(debugFlags, DBG_FLAGS_FPSLIM, (SendDlgItemMessageA(hDlg, IDC_DBG_FPSLIM, BM_GETCHECK, 0, 0)==BST_CHECKED)); + SETFLAG(debugFlags, DBG_FLAGS_NEARCLIP, (SendDlgItemMessageA(hDlg, IDC_DBG_CLIPDIST, BM_GETCHECK, 0, 0) == BST_CHECKED)); + SETFLAG(debugFlags, DBG_FLAGS_RENDEREXT, (SendDlgItemMessageA(hDlg, IDC_DBG_EXTVC, BM_GETCHECK, 0, 0) == BST_CHECKED)); Config->EnableLimiter = (int)((debugFlags&DBG_FLAGS_FPSLIM)>0); } @@ -887,10 +889,13 @@ void ValidateGroup(DWORD grp) char buf[64]; GetWindowText(GetDlgItem(hDlg, IDC_DBG_MATIDX), buf, 64); g->MtrlIdx = atoi(buf); + if (g->MtrlIdx >= hMesh->GetMaterialCount()) g->MtrlIdx = hMesh->GetMaterialCount() - 1; dm->SetGroupMaterial(grp, g->MtrlIdx); GetWindowText(GetDlgItem(hDlg, IDC_DBG_TEXIDX), buf, 64); g->TexIdx = atoi(buf); + if (g->TexIdx >= hMesh->GetTextureCount()) g->TexIdx = hMesh->GetTextureCount() - 1; + dm->SetGroupTexture(grp, g->TexIdx); GetWindowText(GetDlgItem(hDlg, IDC_DBG_GRPLABEL), buf, 64); @@ -899,6 +904,32 @@ void ValidateGroup(DWORD grp) } +// ============================================================================================= +// +void NextDoNotRender() +{ + D3D9Mesh* hMesh = (D3D9Mesh*)vObj->GetMesh(sMesh); + if (!hMesh) return; + DWORD bak = sGroup; + sGroup++; + for (; sGroup < hMesh->GetGroupCount(); sGroup++) { + auto g = hMesh->GetGroup(sGroup); + if (g->UsrFlag & 0x2) { + SetupMeshGroups(); + return; + } + } + for (sGroup = 0; sGroup < hMesh->GetGroupCount(); sGroup++) { + auto g = hMesh->GetGroup(sGroup); + if (g->UsrFlag & 0x2) { + SetupMeshGroups(); + return; + } + } + sGroup = bak; +} + + // ============================================================================================= // void UpdateMeshMaterial(float value, DWORD MatPrp, DWORD clr) @@ -2038,6 +2069,12 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) break; } + case IDC_DBG_NEXT: + { + NextDoNotRender(); + break; + } + case IDC_DBG_MATSAVE: { OBJHANDLE hObj = vObj->GetObjectA(); @@ -2275,6 +2312,8 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case IDC_DBG_PICK: case IDC_DBG_FPSLIM: case IDC_DBG_TILEBB: + case IDC_DBG_CLIPDIST: + case IDC_DBG_EXTVC: UpdateFlags(); break; diff --git a/OVP/D3D9Client/DebugControls.h b/OVP/D3D9Client/DebugControls.h index 9b4cb928a..a8baed679 100644 --- a/OVP/D3D9Client/DebugControls.h +++ b/OVP/D3D9Client/DebugControls.h @@ -61,6 +61,8 @@ #define DBG_FLAGS_PICK 0x1000 ///< Enable mesh picking with mouse #define DBG_FLAGS_FPSLIM 0x2000 ///< FPS Limiter enabled #define DBG_FLAGS_TILEBOXES 0x4000 ///< Tile Boxes +#define DBG_FLAGS_NEARCLIP 0x8000 ///< Set Clip distance to 2cm +#define DBG_FLAGS_RENDEREXT 0x10000 ///< Render exterior meshes for VC view /// @} diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index 5d9276ba8..dbec50f31 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -1991,12 +1991,22 @@ void Scene::RenderMainScene() } pDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0L); // clear z-buffer + double znear = Config->VCNearPlane; + if (DebugControls::IsActive()) if (DebugControls::debugFlags & DBG_FLAGS_NEARCLIP) znear = 0.02; + if (znear<0.01) znear=0.01; if (znear>1.0) znear=1.0; + OBJHANDLE hFocus = oapiGetFocusObject(); SetCameraFrustumLimits(znear, oapiGetSize(hFocus)*2.0); + if (DebugControls::IsActive()) { + if (DebugControls::debugFlags & DBG_FLAGS_RENDEREXT) { + vFocus->Render(pDevice, false); + } + } + if (Config->ShadowMapMode >= 1) { SmapRenderList.clear(); diff --git a/OVP/D3D9Client/resource.h b/OVP/D3D9Client/resource.h index 969d43da1..c6bf9754d 100644 --- a/OVP/D3D9Client/resource.h +++ b/OVP/D3D9Client/resource.h @@ -233,3 +233,5 @@ #define IDC_DBG_MESHSAVE 3049 #define IDC_DBG_NEXT 3050 #define IDC_DBG_GRPLABEL 3051 +#define IDC_DBG_EXTVC 3052 +#define IDC_DBG_CLIPDIST 3053 From 0ad2cd4a28045954e2a102bf6801d34211c40bf2 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Fri, 24 Nov 2023 17:16:06 +0200 Subject: [PATCH 26/42] Fixed Pick related bugs and added Mesh visibility info in debug controls. --- OVP/D3D9Client/D3D9Client.rc | 45 ++++++++++++++++---------------- OVP/D3D9Client/DebugControls.cpp | 17 +++++++++--- OVP/D3D9Client/VObject.h | 1 + OVP/D3D9Client/VVessel.cpp | 29 +++++++++++++++++--- OVP/D3D9Client/VVessel.h | 1 + OVP/D3D9Client/resource.h | 2 +- 6 files changed, 65 insertions(+), 30 deletions(-) diff --git a/OVP/D3D9Client/D3D9Client.rc b/OVP/D3D9Client/D3D9Client.rc index 5a53064a8..1ed818e17 100644 --- a/OVP/D3D9Client/D3D9Client.rc +++ b/OVP/D3D9Client/D3D9Client.rc @@ -40,7 +40,7 @@ EXSTYLE WS_EX_WINDOWEDGE CAPTION "D3D9 Debug Controls" FONT 8, "Ms Shell Dlg" { - GROUPBOX "Mesh Options", IDC_DBG_MESHGRP, 3, 189, 176, 35, 0, WS_EX_LEFT + GROUPBOX "Mesh Options", IDC_STATIC, 5, 185, 176, 35, 0, WS_EX_LEFT PUSHBUTTON "Close", IDCANCEL, 124, 429, 51, 14, 0, WS_EX_LEFT PUSHBUTTON "Open", IDC_DBG_OPEN, 387, 34, 30, 14, 0, WS_EX_LEFT PUSHBUTTON "Execute", IDC_DBG_EXECUTE, 490, 147, 56, 14, 0, WS_EX_LEFT @@ -82,16 +82,16 @@ FONT 8, "Ms Shell Dlg" LTEXT "Static", IDC_DBG_SPEEDDSP, 150, 69, 21, 10, SS_LEFT, WS_EX_LEFT AUTOCHECKBOX "Add ambient light", IDC_DBG_AMBIENT, 18, 143, 70, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Wireframe", IDC_DBG_WIRE, 120, 133, 48, 8, 0, WS_EX_LEFT - GROUPBOX "Material", IDC_DBG_MATGRP, 3, 229, 175, 160, 0, WS_EX_LEFT - COMBOBOX IDC_DBG_MATPRP, 75, 244, 96, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT - COMBOBOX IDC_DBG_DEFSHADER, 75, 205, 96, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT + GROUPBOX "Material", IDC_DBG_MATGRP, 5, 225, 175, 170, 0, WS_EX_LEFT + COMBOBOX IDC_DBG_MATPRP, 77, 240, 96, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT + COMBOBOX IDC_DBG_DEFSHADER, 77, 201, 96, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT COMBOBOX IDC_DBG_CONES, 200, 220, 165, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT - LTEXT "Material property", IDC_STATIC, 16, 246, 53, 8, SS_LEFT, WS_EX_LEFT - LTEXT "Default Shader", IDC_STATIC, 13, 207, 48, 8, SS_LEFT, WS_EX_LEFT - EDITTEXT IDC_DBG_RED, 29, 264, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT - EDITTEXT IDC_DBG_GREEN, 65, 264, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT - EDITTEXT IDC_DBG_BLUE, 101, 264, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT - EDITTEXT IDC_DBG_ALPHA, 137, 264, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT + LTEXT "Material property", IDC_STATIC, 18, 242, 53, 8, SS_LEFT, WS_EX_LEFT + LTEXT "Default Shader", IDC_STATIC, 15, 203, 48, 8, SS_LEFT, WS_EX_LEFT + EDITTEXT IDC_DBG_RED, 31, 260, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT + EDITTEXT IDC_DBG_GREEN, 67, 260, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT + EDITTEXT IDC_DBG_BLUE, 103, 260, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT + EDITTEXT IDC_DBG_ALPHA, 139, 260, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT EDITTEXT IDC_DBG_VARA, 465, 127, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT EDITTEXT IDC_DBG_VARC, 415, 127, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT EDITTEXT IDC_DBG_VARB, 515, 127, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT @@ -107,7 +107,7 @@ FONT 8, "Ms Shell Dlg" LTEXT "Fb:", IDC_STATIC, 502, 129, 11, 8, SS_LEFT, WS_EX_LEFT LTEXT "Fa:", IDC_STATIC, 452, 129, 11, 8, SS_LEFT, WS_EX_LEFT LTEXT "Noise:", IDC_STATIC, 390, 129, 21, 8, SS_LEFT, WS_EX_LEFT - CONTROL "", IDC_DBG_MATADJ, TRACKBAR_CLASS, WS_TABSTOP | TBS_BOTH | TBS_NOTICKS, 17, 281, 156, 14, WS_EX_LEFT + CONTROL "", IDC_DBG_MATADJ, TRACKBAR_CLASS, WS_TABSTOP | TBS_BOTH | TBS_NOTICKS, 19, 277, 156, 14, WS_EX_LEFT PUSHBUTTON "Save materials", IDC_DBG_MATSAVE, 5, 429, 51, 14, 0, WS_EX_LEFT PUSHBUTTON "Create kernel", IDC_DBG_KERNEL, 315, 430, 47, 14, 0, WS_EX_LEFT PUSHBUTTON "Data window", IDC_DBG_DATAWND, 5, 446, 50, 14, 0, WS_EX_LEFT @@ -115,20 +115,20 @@ FONT 8, "Ms Shell Dlg" PUSHBUTTON ">>>", IDC_DBG_MORE, 124, 446, 50, 14, 0, WS_EX_LEFT PUSHBUTTON "Reload Shader", IDC_DBG_RELOADSHD, 60, 446, 60, 14, 0, WS_EX_LEFT PUSHBUTTON "Reload Textures", IDC_DBG_RELOADTEX, 60, 430, 60, 14, 0, WS_EX_LEFT - LTEXT "Texture: None", IDC_DBG_TEXTURE, 7, 351, 168, 10, SS_LEFT, WS_EX_LEFT + LTEXT "Texture: None", IDC_DBG_TEXTURE, 9, 347, 168, 10, SS_LEFT, WS_EX_LEFT AUTOCHECKBOX "Pick", IDC_DBG_PICK, 120, 143, 30, 8, 0, WS_EX_LEFT - LTEXT "Mesh: None", IDC_DBG_MESHNAME, 7, 363, 168, 10, SS_LEFT, WS_EX_LEFT - LTEXT "Group Status:", IDC_DBG_GROUPSTAT, 8, 374, 170, 10, SS_LEFT, WS_EX_LEFT - PUSHBUTTON "Paste", IDC_DBG_PASTE, 131, 299, 37, 14, 0, WS_EX_LEFT - PUSHBUTTON "Copy", IDC_DBG_COPY, 88, 299, 39, 14, 0, WS_EX_LEFT - AUTOCHECKBOX "Link channels", IDC_DBG_LINK, 17, 306, 60, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Use and Save the property", IDC_DBG_DEFINED, 17, 334, 101, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Extend material range", IDC_DBG_EXTEND, 17, 320, 84, 8, 0, WS_EX_LEFT + LTEXT "Mesh: None", IDC_DBG_MESHNAME, 9, 358, 168, 10, SS_LEFT, WS_EX_LEFT + LTEXT "Group Status:", IDC_DBG_GROUPSTAT, 10, 369, 170, 10, SS_LEFT, WS_EX_LEFT + PUSHBUTTON "Paste", IDC_DBG_PASTE, 133, 295, 37, 14, 0, WS_EX_LEFT + PUSHBUTTON "Copy", IDC_DBG_COPY, 90, 295, 39, 14, 0, WS_EX_LEFT + AUTOCHECKBOX "Link channels", IDC_DBG_LINK, 19, 302, 60, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Use and Save the property", IDC_DBG_DEFINED, 19, 330, 101, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Extend material range", IDC_DBG_EXTEND, 19, 316, 84, 8, 0, WS_EX_LEFT AUTOCHECKBOX "FPS Limiter", IDC_DBG_FPSLIM, 205, 25, 51, 8, 0, WS_EX_LEFT PUSHBUTTON "Export textures", IDC_DBG_EXPTEX, 315, 445, 52, 14, 0, WS_EX_LEFT - COMBOBOX IDC_DBG_BKLID, 10, 406, 50, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT - GROUPBOX "Baked Lights", 0, 5, 394, 175, 30, 0, WS_EX_LEFT - CONTROL "", IDC_DBG_BKLADJ, TRACKBAR_CLASS, WS_TABSTOP | TBS_BOTH | TBS_NOTICKS, 64, 404, 115, 15, WS_EX_LEFT + COMBOBOX IDC_DBG_BKLID, 11, 407, 50, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT + GROUPBOX "Baked Lights", 0, 6, 395, 175, 30, 0, WS_EX_LEFT + CONTROL "", IDC_DBG_BKLADJ, TRACKBAR_CLASS, WS_TABSTOP | TBS_BOTH | TBS_NOTICKS, 65, 405, 115, 15, WS_EX_LEFT GROUPBOX "Mesh Group Information", IDC_STATIC, 195, 245, 175, 130, 0, WS_EX_LEFT AUTOCHECKBOX "No Shadow", IDC_DBG_NOSHADOW, 200, 260, 53, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Do not render", IDC_DBG_NORENDER, 200, 270, 59, 8, 0, WS_EX_LEFT @@ -146,6 +146,7 @@ FONT 8, "Ms Shell Dlg" EDITTEXT IDC_DBG_GRPLABEL, 225, 355, 140, 12, ES_AUTOHSCROLL, WS_EX_LEFT AUTOCHECKBOX "Exterior in VC", IDC_DBG_EXTVC, 120, 153, 58, 8, 0, WS_EX_LEFT AUTOCHECKBOX "10cm near clip distance", IDC_DBG_CLIPDIST, 18, 153, 91, 8, 0, WS_EX_LEFT + LTEXT "MeshVisMode: ", IDC_DBG_VISMODE, 10, 380, 162, 9, SS_LEFT, WS_EX_LEFT } diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index e717714c3..681b353fd 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -1335,9 +1335,20 @@ void UpdateMaterialDisplay(bool bSetup) sprintf_s(lbl, 256, "Mesh: %s", RemovePath(hMesh->GetName())); SetWindowText(GetDlgItem(hDlg, IDC_DBG_MESHNAME), lbl); - - GetWindowText(GetDlgItem(hDlg, IDC_DBG_MESHGRP), lbl2, 64); - if (strcmp(lbl, lbl2)) SetWindowText(GetDlgItem(hDlg, IDC_DBG_MESHGRP), lbl); // Avoid causing flashing + + string str = ""; + DWORD vis = vObj->GetMeshVisMode(sMesh); + + if (vis == 0) str = "NEVER"; + if (vis == MESHVIS_ALWAYS) str = "ALWAYS"; + + if (vis & MESHVIS_COCKPIT) str.append("COCKPIT "); + if (vis & MESHVIS_VC) str.append("VC "); + if (vis & MESHVIS_EXTERNAL) str.append("EXTERNAL "); + if (vis & MESHVIS_EXTPASS) str.append("EXTPASS "); + + sprintf_s(lbl, 256, "MeshVisMode: %s", str.c_str()); + SetWindowText(GetDlgItem(hDlg, IDC_DBG_VISMODE), lbl); } // ============================================================================================= diff --git a/OVP/D3D9Client/VObject.h b/OVP/D3D9Client/VObject.h index c5a438439..316fcb23e 100644 --- a/OVP/D3D9Client/VObject.h +++ b/OVP/D3D9Client/VObject.h @@ -121,6 +121,7 @@ class vObject: public oapi::VisObject { * \note Currently only vessel visuals return anything here. */ virtual MESHHANDLE GetMesh (UINT idx) { return NULL; } + virtual DWORD GetMeshVisMode (UINT idx) { return MESHVIS_ALWAYS; } virtual void PreInitObject() { } diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index 1ef43e194..f8c39592f 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -215,6 +215,14 @@ MESHHANDLE vVessel::GetMesh (UINT idx) } +// ============================================================================================ +// +DWORD vVessel::GetMeshVisMode(UINT idx) +{ + return (idx < nmesh ? meshlist[idx].vismode : MESHVIS_ALWAYS); +} + + // ============================================================================================ // bool vVessel::HasExtPass() @@ -1921,17 +1929,30 @@ D3D9Pick vVessel::Pick(const D3DXVECTOR3 *vDir) // check if mesh should be rendered in this pass WORD vismode = meshlist[i].vismode; - if (vismode==0) continue; + if (DebugControls::IsActive() && (DebugControls::debugFlags & DBG_FLAGS_RENDEREXT)) + { + vismode |= MESHVIS_EXTPASS; + } + + if (vismode == 0) continue; + + bool bRender = false; if (bCockpit) { - if (!(vismode & MESHVIS_COCKPIT)) { - if ((!bVC) || (!(vismode & MESHVIS_VC))) continue; + // Internal View + if (vismode & MESHVIS_COCKPIT) bRender = true; + if (vismode & MESHVIS_EXTPASS) bRender = true; + if (bVC) { + if (vismode & MESHVIS_VC) bRender = true; } } else { - if (!(vismode & MESHVIS_EXTERNAL)) continue; + // External view + if (vismode & MESHVIS_EXTERNAL) bRender = true; } + if (!bRender) continue; + D3D9Pick pick = hMesh->Pick(&mWorld, meshlist[i].trans, vDir); if (pick.pMesh) if (pick.dist Date: Mon, 27 Nov 2023 00:56:01 +0200 Subject: [PATCH 27/42] Fixed Mesh Saving, Improved Picking options, Added VC shadow caster selection. --- OVP/D3D9Client/D3D9Client.cpp | 14 +- OVP/D3D9Client/D3D9Client.h | 5 + OVP/D3D9Client/D3D9Client.rc | 108 +++++----- OVP/D3D9Client/D3D9ControlPanel.cpp | 2 +- OVP/D3D9Client/DebugControls.cpp | 312 ++++++++++++++-------------- OVP/D3D9Client/DebugControls.h | 2 + OVP/D3D9Client/Mesh.cpp | 19 +- OVP/D3D9Client/Mesh.h | 8 +- OVP/D3D9Client/Scene.cpp | 20 +- OVP/D3D9Client/Scene.h | 3 +- OVP/D3D9Client/VObject.h | 2 +- OVP/D3D9Client/VVessel.cpp | 43 ++-- OVP/D3D9Client/VVessel.h | 4 +- OVP/D3D9Client/resource.h | 4 + Orbitersdk/include/OrbiterAPI.h | 11 +- Src/Orbiter/Mesh.cpp | 25 ++- Src/Orbiter/Mesh.h | 10 + Src/Orbiter/OrbiterAPI.cpp | 23 ++ 18 files changed, 362 insertions(+), 253 deletions(-) diff --git a/OVP/D3D9Client/D3D9Client.cpp b/OVP/D3D9Client/D3D9Client.cpp index 179db6f23..ed3866a4e 100644 --- a/OVP/D3D9Client/D3D9Client.cpp +++ b/OVP/D3D9Client/D3D9Client.cpp @@ -1509,7 +1509,7 @@ MESHHANDLE D3D9Client::clbkGetMesh(VISHANDLE vis, UINT idx) LogErr("NULL visual in clbkGetMesh(NULL,%u)",idx); return NULL; } - MESHHANDLE hMesh = ((vObject*)vis)->GetMesh(idx); + MESHHANDLE hMesh = (MESHHANDLE)((vObject*)vis)->GetMesh(idx); if (hMesh==NULL) LogWrn("clbkGetMesh() returns NULL"); return hMesh; } @@ -1717,13 +1717,21 @@ LRESULT D3D9Client::RenderWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l TRACKMOUSEEVENT te; te.cbSize = sizeof(TRACKMOUSEEVENT); te.dwFlags = TME_LEAVE; te.hwndTrack = hRenderWnd; TrackMouseEvent(&te); + PickProp prp = { NULL, 0.1f, false }; bool bShift = (GetAsyncKeyState(VK_SHIFT) & 0x8000) != 0; bool bCtrl = (GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0; bool bPckVsl = IsGenericProcEnabled(GENERICPROC_PICK_VESSEL); - if (DebugControls::IsActive() || bPckVsl || (bShift && bCtrl)) { - pick = GetScene()->PickScene(xpos, ypos); + if (DebugControls::IsActive() || bPckVsl || (bShift && bCtrl)) + { + if (DebugControls::IsActive()) { + if (DebugControls::debugFlags & DBG_FLAGS_PICKCURRENT) prp.pMesh = DebugControls::GetMesh(); + if (DebugControls::debugFlags & DBG_FLAGS_DUALSIDED) prp.bDualSided = true; + } + + pick = GetScene()->PickScene(xpos, ypos, &prp); + if (bPckVsl) { gcCore::PickData out; out.hVessel = pick.vObj->GetObjectA(); diff --git a/OVP/D3D9Client/D3D9Client.h b/OVP/D3D9Client/D3D9Client.h index 3961a065d..76b1506c4 100644 --- a/OVP/D3D9Client/D3D9Client.h +++ b/OVP/D3D9Client/D3D9Client.h @@ -128,6 +128,11 @@ struct RenderTgtData { int code; }; +struct PickProp { + D3D9Mesh* pMesh; // Mesh to pick, or NULL for full scene + float fnear; // Near clip distance, ignore entities closer than this + bool bDualSided; // Pick also back-facing triangles +}; struct SHADOWMAPPARAM { LPDIRECT3DTEXTURE9 pShadowMap[SHM_CASCADE_COUNT]; diff --git a/OVP/D3D9Client/D3D9Client.rc b/OVP/D3D9Client/D3D9Client.rc index 1ed818e17..710973851 100644 --- a/OVP/D3D9Client/D3D9Client.rc +++ b/OVP/D3D9Client/D3D9Client.rc @@ -40,54 +40,54 @@ EXSTYLE WS_EX_WINDOWEDGE CAPTION "D3D9 Debug Controls" FONT 8, "Ms Shell Dlg" { - GROUPBOX "Mesh Options", IDC_STATIC, 5, 185, 176, 35, 0, WS_EX_LEFT + GROUPBOX "Mesh Options", IDC_STATIC, 5, 165, 176, 60, 0, WS_EX_LEFT PUSHBUTTON "Close", IDCANCEL, 124, 429, 51, 14, 0, WS_EX_LEFT PUSHBUTTON "Open", IDC_DBG_OPEN, 387, 34, 30, 14, 0, WS_EX_LEFT PUSHBUTTON "Execute", IDC_DBG_EXECUTE, 490, 147, 56, 14, 0, WS_EX_LEFT - LTEXT "Selected Visual: Cape Canaveral", IDC_DBG_VISUAL, 7, 5, 104, 8, SS_LEFT, WS_EX_LEFT - COMBOBOX IDC_DBG_DISPLAY, 48, 33, 120, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT - LTEXT "Display", IDC_STATIC, 18, 36, 24, 8, SS_LEFT, WS_EX_LEFT - LTEXT "Camera", IDC_STATIC, 18, 51, 25, 11, SS_LEFT, WS_EX_LEFT - COMBOBOX IDC_DBG_CAMERA, 48, 51, 120, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT - EDITTEXT IDC_DBG_MESH, 54, 87, 44, 12, ES_AUTOHSCROLL, WS_EX_LEFT - LTEXT "Group Idx", IDC_STATIC, 18, 105, 32, 12, SS_LEFT, WS_EX_LEFT - LTEXT "Mesh Idx", IDC_STATIC, 18, 90, 30, 8, SS_LEFT, WS_EX_LEFT - EDITTEXT IDC_DBG_GROUP, 54, 105, 44, 12, WS_GROUP | ES_AUTOHSCROLL, WS_EX_LEFT + LTEXT "Selected Visual: Cape Canaveral", IDC_DBG_VISUAL, 7, 2, 104, 8, SS_LEFT, WS_EX_LEFT + COMBOBOX IDC_DBG_DISPLAY, 48, 27, 120, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT + LTEXT "Display", IDC_STATIC, 18, 30, 24, 8, SS_LEFT, WS_EX_LEFT + LTEXT "Camera", IDC_STATIC, 18, 43, 25, 11, SS_LEFT, WS_EX_LEFT + COMBOBOX IDC_DBG_CAMERA, 48, 42, 120, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT + EDITTEXT IDC_DBG_MESH, 54, 73, 44, 12, ES_AUTOHSCROLL, WS_EX_LEFT + LTEXT "Group Idx", IDC_STATIC, 18, 92, 32, 12, SS_LEFT, WS_EX_LEFT + LTEXT "Mesh Idx", IDC_STATIC, 18, 76, 30, 8, SS_LEFT, WS_EX_LEFT + EDITTEXT IDC_DBG_GROUP, 54, 89, 44, 12, WS_GROUP | ES_AUTOHSCROLL, WS_EX_LEFT EDITTEXT IDC_DBG_FILE, 421, 35, 125, 12, WS_GROUP | ES_AUTOHSCROLL | ES_READONLY, WS_EX_LEFT - AUTOCHECKBOX "Highlight selected group", IDC_DBG_HSG, 18, 123, 92, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Highlight selected mesh", IDC_DBG_HSM, 18, 133, 91, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Highlight selected group", IDC_DBG_HSG, 18, 107, 92, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Highlight selected mesh", IDC_DBG_HSM, 18, 117, 91, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Boxes", IDC_DBG_BOXES, 208, 162, 35, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Normalize", IDC_DBG_NORM, 400, 79, 47, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Mipmap fade", IDC_DBG_FADE, 400, 92, 57, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Reduce seams", IDC_DBG_SEAMS, 460, 79, 63, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Spheres", IDC_DBG_SPHERES, 208, 173, 42, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Surface Tiles", IDC_DBG_TILEBB, 208, 185, 57, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Spheres", IDC_DBG_SPHERES, 208, 171, 42, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Surface Tiles", IDC_DBG_TILEBB, 208, 180, 57, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Selected group only", IDC_DBG_GRPO, 274, 162, 79, 8, 0, WS_EX_LEFT - GROUPBOX "Bounding geometry", IDC_STATIC, 195, 150, 175, 50, 0, WS_EX_LEFT - GROUPBOX "Visualize local light cones", IDC_STATIC, 195, 205, 175, 35, 0, WS_EX_LEFT - GROUPBOX "Mesh debugger", IDC_STATIC, 5, 20, 175, 160, 0, WS_EX_LEFT + GROUPBOX "Bounding geometry", IDC_STATIC, 195, 150, 175, 45, 0, WS_EX_LEFT + GROUPBOX "Visualize local light cones", IDC_STATIC, 195, 200, 175, 35, 0, WS_EX_LEFT + GROUPBOX "Selection and Display Options", IDC_STATIC, 5, 15, 175, 145, 0, WS_EX_LEFT GROUPBOX "Misc.", IDC_STATIC, 195, 10, 173, 70, 0, WS_EX_LEFT GROUPBOX "Scene Debugger", IDC_STATIC, 195, 85, 173, 60, 0, WS_EX_LEFT GROUPBOX "Texture Tools", IDC_STATIC, 380, 15, 173, 151, 0, WS_EX_LEFT - AUTOCHECKBOX "Selected mesh only", IDC_DBG_MSHO, 274, 174, 77, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Dual sided", IDC_DBG_DUAL, 120, 123, 49, 8, 0, WS_EX_LEFT - PUSHBUTTON "<", IDC_DBG_GRPUP, 102, 105, 9, 12, BS_CENTER, WS_EX_LEFT - PUSHBUTTON ">", IDC_DBG_GRPDN, 114, 105, 9, 12, BS_CENTER, WS_EX_LEFT - PUSHBUTTON "<", IDC_DBG_MSHUP, 102, 87, 9, 12, BS_CENTER, WS_EX_LEFT - PUSHBUTTON ">", IDC_DBG_MSHDN, 114, 87, 9, 12, BS_CENTER, WS_EX_LEFT - AUTOCHECKBOX "Selected visual only", IDC_DBG_VISO, 274, 186, 79, 8, 0, WS_EX_LEFT - CONTROL "", IDC_DBG_SPEED, TRACKBAR_CLASS, WS_TABSTOP | TBS_BOTH | TBS_NOTICKS, 42, 69, 108, 13, WS_EX_LEFT + AUTOCHECKBOX "Selected mesh only", IDC_DBG_MSHO, 274, 171, 77, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Dual sided", IDC_DBG_DUAL, 120, 107, 49, 8, 0, WS_EX_LEFT + PUSHBUTTON "<", IDC_DBG_GRPUP, 102, 90, 9, 12, BS_CENTER, WS_EX_LEFT + PUSHBUTTON ">", IDC_DBG_GRPDN, 114, 90, 9, 12, BS_CENTER, WS_EX_LEFT + PUSHBUTTON "<", IDC_DBG_MSHUP, 102, 73, 9, 12, BS_CENTER, WS_EX_LEFT + PUSHBUTTON ">", IDC_DBG_MSHDN, 114, 73, 9, 12, BS_CENTER, WS_EX_LEFT + AUTOCHECKBOX "Selected visual only", IDC_DBG_VISO, 274, 180, 79, 8, 0, WS_EX_LEFT + CONTROL "", IDC_DBG_SPEED, TRACKBAR_CLASS, WS_TABSTOP | TBS_BOTH | TBS_NOTICKS, 42, 58, 108, 13, WS_EX_LEFT CONTROL "", IDC_DBG_RESBIAS, TRACKBAR_CLASS, WS_TABSTOP | TBS_AUTOTICKS | TBS_BOTH, 205, 55, 155, 20, WS_EX_LEFT - LTEXT "Speed", IDC_STATIC, 18, 69, 22, 8, SS_LEFT, WS_EX_LEFT - LTEXT "Static", IDC_DBG_SPEEDDSP, 150, 69, 21, 10, SS_LEFT, WS_EX_LEFT - AUTOCHECKBOX "Add ambient light", IDC_DBG_AMBIENT, 18, 143, 70, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Wireframe", IDC_DBG_WIRE, 120, 133, 48, 8, 0, WS_EX_LEFT - GROUPBOX "Material", IDC_DBG_MATGRP, 5, 225, 175, 170, 0, WS_EX_LEFT + LTEXT "Speed", IDC_STATIC, 18, 58, 22, 8, SS_LEFT, WS_EX_LEFT + LTEXT "Static", IDC_DBG_SPEEDDSP, 150, 58, 21, 10, SS_LEFT, WS_EX_LEFT + AUTOCHECKBOX "Add ambient light", IDC_DBG_AMBIENT, 18, 127, 70, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Wireframe", IDC_DBG_WIRE, 120, 117, 48, 8, 0, WS_EX_LEFT + GROUPBOX "Material", IDC_DBG_MATGRP, 5, 230, 175, 165, 0, WS_EX_LEFT COMBOBOX IDC_DBG_MATPRP, 77, 240, 96, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT - COMBOBOX IDC_DBG_DEFSHADER, 77, 201, 96, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT - COMBOBOX IDC_DBG_CONES, 200, 220, 165, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT + COMBOBOX IDC_DBG_DEFSHADER, 75, 177, 96, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT + COMBOBOX IDC_DBG_CONES, 200, 215, 165, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT LTEXT "Material property", IDC_STATIC, 18, 242, 53, 8, SS_LEFT, WS_EX_LEFT - LTEXT "Default Shader", IDC_STATIC, 15, 203, 48, 8, SS_LEFT, WS_EX_LEFT + LTEXT "Mesh Shader", IDC_STATIC, 15, 179, 43, 9, SS_LEFT, WS_EX_LEFT EDITTEXT IDC_DBG_RED, 31, 260, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT EDITTEXT IDC_DBG_GREEN, 67, 260, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT EDITTEXT IDC_DBG_BLUE, 103, 260, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT @@ -116,37 +116,41 @@ FONT 8, "Ms Shell Dlg" PUSHBUTTON "Reload Shader", IDC_DBG_RELOADSHD, 60, 446, 60, 14, 0, WS_EX_LEFT PUSHBUTTON "Reload Textures", IDC_DBG_RELOADTEX, 60, 430, 60, 14, 0, WS_EX_LEFT LTEXT "Texture: None", IDC_DBG_TEXTURE, 9, 347, 168, 10, SS_LEFT, WS_EX_LEFT - AUTOCHECKBOX "Pick", IDC_DBG_PICK, 120, 143, 30, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Pick", IDC_DBG_PICK, 120, 127, 30, 8, 0, WS_EX_LEFT LTEXT "Mesh: None", IDC_DBG_MESHNAME, 9, 358, 168, 10, SS_LEFT, WS_EX_LEFT LTEXT "Group Status:", IDC_DBG_GROUPSTAT, 10, 369, 170, 10, SS_LEFT, WS_EX_LEFT PUSHBUTTON "Paste", IDC_DBG_PASTE, 133, 295, 37, 14, 0, WS_EX_LEFT PUSHBUTTON "Copy", IDC_DBG_COPY, 90, 295, 39, 14, 0, WS_EX_LEFT AUTOCHECKBOX "Link channels", IDC_DBG_LINK, 19, 302, 60, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Use and Save the property", IDC_DBG_DEFINED, 19, 330, 101, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Extend material range", IDC_DBG_EXTEND, 19, 316, 84, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Use and Save the property", IDC_DBG_DEFINED, 19, 324, 101, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Extend material range", IDC_DBG_EXTEND, 19, 313, 84, 8, 0, WS_EX_LEFT AUTOCHECKBOX "FPS Limiter", IDC_DBG_FPSLIM, 205, 25, 51, 8, 0, WS_EX_LEFT PUSHBUTTON "Export textures", IDC_DBG_EXPTEX, 315, 445, 52, 14, 0, WS_EX_LEFT COMBOBOX IDC_DBG_BKLID, 11, 407, 50, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT GROUPBOX "Baked Lights", 0, 6, 395, 175, 30, 0, WS_EX_LEFT CONTROL "", IDC_DBG_BKLADJ, TRACKBAR_CLASS, WS_TABSTOP | TBS_BOTH | TBS_NOTICKS, 65, 405, 115, 15, WS_EX_LEFT - GROUPBOX "Mesh Group Information", IDC_STATIC, 195, 245, 175, 130, 0, WS_EX_LEFT - AUTOCHECKBOX "No Shadow", IDC_DBG_NOSHADOW, 200, 260, 53, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Do not render", IDC_DBG_NORENDER, 200, 270, 59, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Always Lit", IDC_DBG_NOLIGHT, 200, 280, 47, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Additive Blend", IDC_DBG_ADDITIVE, 200, 290, 61, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Texture Alpha Only (No Color)", IDC_DBG_NOCOLOR, 200, 300, 109, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Order Independent Transparency", IDC_DBG_OIT, 200, 310, 121, 8, 0, WS_EX_LEFT - EDITTEXT IDC_DBG_MATIDX, 225, 325, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT - EDITTEXT IDC_DBG_TEXIDX, 225, 340, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT - LTEXT "MatIdx", IDC_STATIC, 200, 326, 22, 9, SS_LEFT, WS_EX_LEFT - LTEXT "TexIdx", IDC_STATIC, 200, 342, 22, 9, SS_LEFT, WS_EX_LEFT + GROUPBOX "Mesh Group Information", IDC_STATIC, 195, 240, 175, 135, 0, WS_EX_LEFT + AUTOCHECKBOX "No Shadow", IDC_DBG_NOSHADOW, 200, 255, 53, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Do not render", IDC_DBG_NORENDER, 200, 265, 59, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Always Lit", IDC_DBG_NOLIGHT, 200, 275, 47, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Additive Blend", IDC_DBG_ADDITIVE, 200, 285, 61, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Texture Alpha Only (No Color)", IDC_DBG_NOCOLOR, 200, 295, 109, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Order Independent Transparency", IDC_DBG_OIT, 200, 305, 121, 8, 0, WS_EX_LEFT + EDITTEXT IDC_DBG_MATIDX, 225, 320, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT + EDITTEXT IDC_DBG_TEXIDX, 225, 335, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT + LTEXT "MatIdx", IDC_STATIC, 200, 321, 22, 9, SS_LEFT, WS_EX_LEFT + LTEXT "TexIdx", IDC_STATIC, 200, 337, 22, 9, SS_LEFT, WS_EX_LEFT PUSHBUTTON "Save Mesh", IDC_DBG_MESHSAVE, 200, 430, 55, 14, 0, WS_EX_LEFT - PUSHBUTTON "Unrendered", IDC_DBG_NEXT, 127, 105, 48, 12, 0, WS_EX_LEFT - LTEXT "Label", IDC_STATIC, 201, 357, 18, 9, SS_LEFT, WS_EX_LEFT - EDITTEXT IDC_DBG_GRPLABEL, 225, 355, 140, 12, ES_AUTOHSCROLL, WS_EX_LEFT - AUTOCHECKBOX "Exterior in VC", IDC_DBG_EXTVC, 120, 153, 58, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "10cm near clip distance", IDC_DBG_CLIPDIST, 18, 153, 91, 8, 0, WS_EX_LEFT + PUSHBUTTON "Unrendered", IDC_DBG_NEXT, 127, 90, 48, 12, 0, WS_EX_LEFT + LTEXT "Label", IDC_STATIC, 201, 352, 18, 9, SS_LEFT, WS_EX_LEFT + EDITTEXT IDC_DBG_GRPLABEL, 225, 350, 140, 12, ES_AUTOHSCROLL, WS_EX_LEFT + AUTOCHECKBOX "Exterior in VC", IDC_DBG_EXTVC, 120, 137, 58, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "2cm near clip distance", IDC_DBG_CLIPDIST, 18, 136, 87, 8, 0, WS_EX_LEFT LTEXT "MeshVisMode: ", IDC_DBG_VISMODE, 10, 380, 162, 9, SS_LEFT, WS_EX_LEFT + AUTOCHECKBOX "Pick only current mesh", IDC_DBG_PICKCURRENT, 18, 146, 87, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Dynamic", IDC_DBG_DYNAMIC, 285, 255, 43, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Is VC Mesh", IDC_DBG_ISVCMESH, 15, 193, 52, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Cast VC Shadow", IDC_DBG_VCSHADOW, 15, 203, 69, 8, 0, WS_EX_LEFT } diff --git a/OVP/D3D9Client/D3D9ControlPanel.cpp b/OVP/D3D9Client/D3D9ControlPanel.cpp index 0b172745b..3f17f2fa8 100644 --- a/OVP/D3D9Client/D3D9ControlPanel.cpp +++ b/OVP/D3D9Client/D3D9ControlPanel.cpp @@ -230,7 +230,7 @@ void D3D9Client::RenderControlPanel() if (vObj) { DWORD nMesh = vObj->GetMeshCount(); for (DWORD i = 0; i < nMesh; i++) { - D3D9Mesh *hMesh = static_cast(vObj->GetMesh(i)); + D3D9Mesh *hMesh = vObj->GetMesh(i); hMesh->ResetRenderStatus(); } } diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index 681b353fd..2e1558c9a 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -133,7 +133,8 @@ class DbgMesh while (true) { if (!is.getline(buf, 256)) throw std::invalid_argument("End of file"); - Groups[gi].Lines.push_back(buf); + if (buf[0] != ';') Groups[gi].Lines.push_back(buf); + if (!_strnicmp(buf, "GEOM", 4)) { if (sscanf(buf + 4, "%d %d", &nv, &ni) != 2) throw std::invalid_argument("End of file"); @@ -149,7 +150,7 @@ class DbgMesh } } } - } + } } is.close(); } @@ -169,8 +170,10 @@ class DbgMesh if (os.is_open()) { + int i = 0; for (auto a : Header) os << a << "\n"; for (auto a : Groups) { + os << ";--- GroupIndex " << i << " ---\n"; i++; for (auto b : a.Lines) os << b << "\n"; for (auto b : a.Vtx) os << b << "\n"; for (auto b : a.Idx) os << b << "\n"; @@ -182,58 +185,30 @@ class DbgMesh } } - DWORD GetGroupFlags(DWORD grp) - { - DWORD x; - for (auto a : Groups[grp].Lines) { - if (a.find("FLAG") != string::npos) { - std::istringstream iss(a); - iss >> key >> std::hex >> x; - return x; - } - } - return 0; - } - - DWORD GetGroupMaterial(DWORD grp) - { - DWORD x; - for (auto a : Groups[grp].Lines) { - if (a.find("MATERIAL") != string::npos) { - std::istringstream iss(a); - iss >> key >> x; - return x; - } - } - if (grp > 0) return GetGroupMaterial(grp - 1); - return 0; - } - - DWORD GetGroupTexture(DWORD grp) + string GetGroupLabel(DWORD grp) { - DWORD x; + string x; for (auto a : Groups[grp].Lines) { - if (a.find("TEXTURE") != string::npos) { + if (a.find("LABEL") != string::npos) { std::istringstream iss(a); iss >> key >> x; return x; } } - if (grp > 0) return GetGroupTexture(grp - 1); - return 0; + return string(""); } - string GetGroupLabel(DWORD grp) + void SetMeshFlags(DWORD f) { - string x; - for (auto a : Groups[grp].Lines) { - if (a.find("LABEL") != string::npos) { - std::istringstream iss(a); - iss >> key >> x; - return x; + std::stringstream s; + s << std::hex << f; + for (auto &a : Header) { + if (a.find("MESHFLAGS") != string::npos) { + a = string("MESHFLAGS ") + s.str(); + return; } } - return string(""); + Header.insert(Header.begin() + 1, string("MESHFLAGS ") + s.str()); } void SetGroupFlags(DWORD grp, DWORD f) @@ -242,20 +217,24 @@ class DbgMesh s << std::hex << f; for (auto &a : Groups[grp].Lines) { if (a.find("FLAG") != string::npos) { - a = s.str(); + a = string("FLAG ") + s.str(); return; } } + auto b = Groups[grp].Lines.begin(); + Groups[grp].Lines.insert(b, string("FLAG ") + s.str()); } void SetGroupMaterial(DWORD grp, DWORD x) { for (auto& a : Groups[grp].Lines) { if (a.find("MATERIAL") != string::npos) { - a = string("MATERIAL ") + std::to_string(x); + a = string("MATERIAL ") + std::to_string(x + 1); return; } } + auto b = Groups[grp].Lines.begin(); + Groups[grp].Lines.insert(b, string("MATERIAL ") + std::to_string(x)); } void SetGroupTexture(DWORD grp, DWORD x) @@ -266,6 +245,8 @@ class DbgMesh return; } } + auto b = Groups[grp].Lines.begin(); + Groups[grp].Lines.insert(b, string("TEXTURE ") + std::to_string(x)); } void SetGroupLabel(DWORD grp, string x) @@ -276,6 +257,8 @@ class DbgMesh return; } } + auto b = Groups[grp].Lines.begin(); + Groups[grp].Lines.insert(b, string("LABEL ") + x); } vector Header; @@ -287,6 +270,7 @@ class DbgMesh map dbgMsh; +DbgMesh* hDbgMsh = NULL; // =========================================================================== @@ -503,6 +487,7 @@ void UpdateFlags() SETFLAG(debugFlags, DBG_FLAGS_FPSLIM, (SendDlgItemMessageA(hDlg, IDC_DBG_FPSLIM, BM_GETCHECK, 0, 0)==BST_CHECKED)); SETFLAG(debugFlags, DBG_FLAGS_NEARCLIP, (SendDlgItemMessageA(hDlg, IDC_DBG_CLIPDIST, BM_GETCHECK, 0, 0) == BST_CHECKED)); SETFLAG(debugFlags, DBG_FLAGS_RENDEREXT, (SendDlgItemMessageA(hDlg, IDC_DBG_EXTVC, BM_GETCHECK, 0, 0) == BST_CHECKED)); + SETFLAG(debugFlags, DBG_FLAGS_PICKCURRENT, (SendDlgItemMessageA(hDlg, IDC_DBG_PICKCURRENT, BM_GETCHECK, 0, 0) == BST_CHECKED)); Config->EnableLimiter = (int)((debugFlags&DBG_FLAGS_FPSLIM)>0); } @@ -802,9 +787,7 @@ void UpdateShader() if (!oapiIsVessel(hObj)) return; - D3D9Mesh *hMesh = (D3D9Mesh *)vObj->GetMesh(sMesh); - - if (!hMesh) return; + if (!hSelMesh) return; DWORD Shader = DWORD(SendDlgItemMessageA(hDlg, IDC_DBG_DEFSHADER, CB_GETCURSEL, 0, 0)); @@ -813,20 +796,20 @@ void UpdateShader() switch (Shader) { case 0: - hMesh->SetDefaultShader(SHADER_NULL); - pMgr->RegisterShaderChange(hMesh, SHADER_NULL); + hSelMesh->SetDefaultShader(SHADER_NULL); + pMgr->RegisterShaderChange(hSelMesh, SHADER_NULL); break; case 1: - hMesh->SetDefaultShader(SHADER_METALNESS); - pMgr->RegisterShaderChange(hMesh, SHADER_METALNESS); + hSelMesh->SetDefaultShader(SHADER_METALNESS); + pMgr->RegisterShaderChange(hSelMesh, SHADER_METALNESS); break; case 2: - hMesh->SetDefaultShader(SHADER_BAKED_VC); - pMgr->RegisterShaderChange(hMesh, SHADER_BAKED_VC); + hSelMesh->SetDefaultShader(SHADER_BAKED_VC); + pMgr->RegisterShaderChange(hSelMesh, SHADER_BAKED_VC); break; } - InitMatList(hMesh->GetDefaultShader()); + InitMatList(hSelMesh->GetDefaultShader()); } @@ -834,12 +817,9 @@ void UpdateShader() // void UpdateGroup(DWORD grp) { - D3D9Mesh* hMesh = (D3D9Mesh*)vObj->GetMesh(sMesh); - if (!hMesh) return; - - auto dm = dbgMsh[hMesh]; - if (grp >= hMesh->GetGroupCount()) return; - auto g = hMesh->GetGroup(grp); + if (!hSelMesh) return; + if (grp >= hSelMesh->GetGroupCount()) return; + auto g = hSelMesh->GetGroup(grp); if (g) { SendDlgItemMessage(hDlg, IDC_DBG_NOSHADOW, BM_SETCHECK, (g->UsrFlag & 0x1) != 0, 0); @@ -848,16 +828,15 @@ void UpdateGroup(DWORD grp) SendDlgItemMessage(hDlg, IDC_DBG_ADDITIVE, BM_SETCHECK, (g->UsrFlag & 0x8) != 0, 0); SendDlgItemMessage(hDlg, IDC_DBG_NOCOLOR, BM_SETCHECK, (g->UsrFlag & 0x10) != 0, 0); SendDlgItemMessage(hDlg, IDC_DBG_OIT, BM_SETCHECK, (g->UsrFlag & 0x20) != 0, 0); + SendDlgItemMessage(hDlg, IDC_DBG_DYNAMIC, BM_SETCHECK, 0, 0); char buf[64]; sprintf_s(buf, 64, "%d", g->MtrlIdx); SetWindowText(GetDlgItem(hDlg, IDC_DBG_MATIDX), buf); sprintf_s(buf, 64, "%d", g->TexIdx); SetWindowText(GetDlgItem(hDlg, IDC_DBG_TEXIDX), buf); - if (dm) { - sprintf_s(buf, 64, "%s", dm->GetGroupLabel(grp).c_str()); - SetWindowText(GetDlgItem(hDlg, IDC_DBG_GRPLABEL), buf); - } + string s = hDbgMsh->GetGroupLabel(grp); + SetWindowText(GetDlgItem(hDlg, IDC_DBG_GRPLABEL), s.c_str()); } } @@ -866,15 +845,14 @@ void UpdateGroup(DWORD grp) // void ValidateGroup(DWORD grp) { - D3D9Mesh* hMesh = (D3D9Mesh*)vObj->GetMesh(sMesh); - if (!hMesh) return; + if (!hSelMesh) return; + if (!hDbgMsh) return; - auto dm = dbgMsh[hMesh]; - if (grp >= hMesh->GetGroupCount()) return; - auto g = hMesh->GetGroup(grp); + if (grp >= hSelMesh->GetGroupCount()) return; + auto g = hSelMesh->GetGroup(grp); DWORD f = 0; - if (g && dm) + if (g) { if (SendDlgItemMessage(hDlg, IDC_DBG_NOSHADOW, BM_GETCHECK, 0, 0) == BST_CHECKED) f |= 0x1; if (SendDlgItemMessage(hDlg, IDC_DBG_NORENDER, BM_GETCHECK, 0, 0) == BST_CHECKED) f |= 0x2; @@ -882,24 +860,24 @@ void ValidateGroup(DWORD grp) if (SendDlgItemMessage(hDlg, IDC_DBG_ADDITIVE, BM_GETCHECK, 0, 0) == BST_CHECKED) f |= 0x8; if (SendDlgItemMessage(hDlg, IDC_DBG_NOCOLOR, BM_GETCHECK, 0, 0) == BST_CHECKED) f |= 0x10; if (SendDlgItemMessage(hDlg, IDC_DBG_OIT, BM_GETCHECK, 0, 0) == BST_CHECKED) f |= 0x20; + if (SendDlgItemMessage(hDlg, IDC_DBG_DYNAMIC, BM_GETCHECK, 0, 0) == BST_CHECKED) f |= 0x0; // TODO: To be implemented g->UsrFlag = f; - dm->SetGroupFlags(grp, f); + hDbgMsh->SetGroupFlags(grp, f); char buf[64]; GetWindowText(GetDlgItem(hDlg, IDC_DBG_MATIDX), buf, 64); g->MtrlIdx = atoi(buf); - if (g->MtrlIdx >= hMesh->GetMaterialCount()) g->MtrlIdx = hMesh->GetMaterialCount() - 1; - dm->SetGroupMaterial(grp, g->MtrlIdx); + if (g->MtrlIdx >= hSelMesh->GetMaterialCount()) g->MtrlIdx = hSelMesh->GetMaterialCount() - 1; + hDbgMsh->SetGroupMaterial(grp, g->MtrlIdx); GetWindowText(GetDlgItem(hDlg, IDC_DBG_TEXIDX), buf, 64); g->TexIdx = atoi(buf); - if (g->TexIdx >= hMesh->GetTextureCount()) g->TexIdx = hMesh->GetTextureCount() - 1; - - dm->SetGroupTexture(grp, g->TexIdx); + if (g->TexIdx >= hSelMesh->GetTextureCount()) g->TexIdx = hSelMesh->GetTextureCount() - 1; + hDbgMsh->SetGroupTexture(grp, g->TexIdx); GetWindowText(GetDlgItem(hDlg, IDC_DBG_GRPLABEL), buf, 64); - dm->SetGroupLabel(grp, string(buf)); + hDbgMsh->SetGroupLabel(grp, string(buf)); } } @@ -908,19 +886,18 @@ void ValidateGroup(DWORD grp) // void NextDoNotRender() { - D3D9Mesh* hMesh = (D3D9Mesh*)vObj->GetMesh(sMesh); - if (!hMesh) return; + if (!hSelMesh) return; DWORD bak = sGroup; sGroup++; - for (; sGroup < hMesh->GetGroupCount(); sGroup++) { - auto g = hMesh->GetGroup(sGroup); + for (; sGroup < hSelMesh->GetGroupCount(); sGroup++) { + auto g = hSelMesh->GetGroup(sGroup); if (g->UsrFlag & 0x2) { SetupMeshGroups(); return; } } - for (sGroup = 0; sGroup < hMesh->GetGroupCount(); sGroup++) { - auto g = hMesh->GetGroup(sGroup); + for (sGroup = 0; sGroup < hSelMesh->GetGroupCount(); sGroup++) { + auto g = hSelMesh->GetGroup(sGroup); if (g->UsrFlag & 0x2) { SetupMeshGroups(); return; @@ -935,18 +912,14 @@ void NextDoNotRender() void UpdateMeshMaterial(float value, DWORD MatPrp, DWORD clr) { OBJHANDLE hObj = vObj->GetObjectA(); - if (!oapiIsVessel(hObj)) return; - - D3D9Mesh *hMesh = (D3D9Mesh *)vObj->GetMesh(sMesh); - - if (!hMesh) return; + if (!hSelMesh) return; - DWORD matidx = hMesh->GetMeshGroupMaterialIdx(sGroup); - DWORD texidx = hMesh->GetMeshGroupTextureIdx(sGroup); + DWORD matidx = hSelMesh->GetMeshGroupMaterialIdx(sGroup); + DWORD texidx = hSelMesh->GetMeshGroupTextureIdx(sGroup); D3D9MatExt Mat; - if (!hMesh->GetMaterial(&Mat, matidx)) return; + if (!hSelMesh->GetMaterial(&Mat, matidx)) return; switch(MatPrp) { @@ -1021,10 +994,9 @@ void UpdateMeshMaterial(float value, DWORD MatPrp, DWORD clr) } } - hMesh->SetMaterial(&Mat, matidx); + hSelMesh->SetMaterial(&Mat, matidx); vVessel *vVes = (vVessel *)vObj; - - vVes->GetMaterialManager()->RegisterMaterialChange(hMesh, matidx, &Mat); + vVes->GetMaterialManager()->RegisterMaterialChange(hSelMesh, matidx, &Mat); } @@ -1053,18 +1025,13 @@ DWORD GetModFlags(DWORD MatPrp) bool IsMaterialModified(DWORD MatPrp) { OBJHANDLE hObj = vObj->GetObjectA(); - if (!oapiIsVessel(hObj)) return false; + if (!hSelMesh) return false; - D3D9Mesh *hMesh = (D3D9Mesh *)vObj->GetMesh(sMesh); - - if (!hMesh) return false; - - DWORD matidx = hMesh->GetMeshGroupMaterialIdx(sGroup); - + DWORD matidx = hSelMesh->GetMeshGroupMaterialIdx(sGroup); D3D9MatExt Mat; - if (!hMesh->GetMaterial(&Mat, matidx)) return false; + if (!hSelMesh->GetMaterial(&Mat, matidx)) return false; return (Mat.ModFlags & GetModFlags(MatPrp)) != 0; } @@ -1077,21 +1044,17 @@ void SetMaterialModified(DWORD MatPrp, bool bState) OBJHANDLE hObj = vObj->GetObjectA(); if (!oapiIsVessel(hObj)) return; + if (!hSelMesh) return; - D3D9Mesh *hMesh = (D3D9Mesh *)vObj->GetMesh(sMesh); - - if (!hMesh) return; - - DWORD matidx = hMesh->GetMeshGroupMaterialIdx(sGroup); - + DWORD matidx = hSelMesh->GetMeshGroupMaterialIdx(sGroup); D3D9MatExt Mat; - if (!hMesh->GetMaterial(&Mat, matidx)) return; + if (!hSelMesh->GetMaterial(&Mat, matidx)) return; if (bState) Mat.ModFlags |= GetModFlags(MatPrp); else Mat.ModFlags &= (~GetModFlags(MatPrp)); - hMesh->SetMaterial(&Mat, matidx); + hSelMesh->SetMaterial(&Mat, matidx); } @@ -1102,16 +1065,12 @@ float GetMaterialValue(DWORD MatPrp, DWORD clr) OBJHANDLE hObj = vObj->GetObjectA(); if (!oapiIsVessel(hObj)) return 0.0f; + if (!hSelMesh) return 0.0f; - D3D9Mesh *hMesh = (D3D9Mesh *)vObj->GetMesh(sMesh); + DWORD matidx = hSelMesh->GetMeshGroupMaterialIdx(sGroup); + DWORD texidx = hSelMesh->GetMeshGroupTextureIdx(sGroup); - if (!hMesh) return 0.0f; - - DWORD matidx = hMesh->GetMeshGroupMaterialIdx(sGroup); - DWORD texidx = hMesh->GetMeshGroupTextureIdx(sGroup); - - const D3D9MatExt *pMat = hMesh->GetMaterial(matidx); - + const D3D9MatExt *pMat = hSelMesh->GetMaterial(matidx); if (!pMat) return 0.0f; switch(MatPrp) { @@ -1292,16 +1251,14 @@ void UpdateMaterialDisplay(bool bSetup) OBJHANDLE hObj = vObj->GetObjectA(); if (!oapiIsVessel(hObj)) return; - - D3D9Mesh *hMesh = (D3D9Mesh *)vObj->GetMesh(sMesh); - if (!hMesh) return; + if (!hSelMesh) return; - WORD Shader = hMesh->GetDefaultShader(); + WORD Shader = hSelMesh->GetDefaultShader(); if (Shader == SHADER_NULL) SendDlgItemMessageA(hDlg, IDC_DBG_DEFSHADER, CB_SETCURSEL, 0, 0); if (Shader == SHADER_METALNESS) SendDlgItemMessageA(hDlg, IDC_DBG_DEFSHADER, CB_SETCURSEL, 1, 0); if (Shader == SHADER_BAKED_VC) SendDlgItemMessageA(hDlg, IDC_DBG_DEFSHADER, CB_SETCURSEL, 2, 0); - DWORD matidx = hMesh->GetMeshGroupMaterialIdx(sGroup); + DWORD matidx = hSelMesh->GetMeshGroupMaterialIdx(sGroup); // Set material info const char *skin = NULL; @@ -1322,18 +1279,18 @@ void UpdateMaterialDisplay(bool bSetup) SetToolTip(IDC_DBG_BLUE, hTipBlu, Params[MatPrp].var[2].tip); SetToolTip(IDC_DBG_ALPHA, hTipAlp, Params[MatPrp].var[3].tip); - DWORD texidx = hMesh->GetMeshGroupTextureIdx(sGroup); + DWORD texidx = hSelMesh->GetMeshGroupTextureIdx(sGroup); if (texidx==0) SetWindowText(GetDlgItem(hDlg, IDC_DBG_TEXTURE), "Texture: None"); else { - SURFHANDLE hSrf = hMesh->GetTexture(texidx); + SURFHANDLE hSrf = hSelMesh->GetTexture(texidx); if (hSrf) { sprintf_s(lbl, 256, "Texture: %s [%u]", RemovePath(SURFACE(hSrf)->GetName()), texidx); SetWindowText(GetDlgItem(hDlg, IDC_DBG_TEXTURE), lbl); } } - sprintf_s(lbl, 256, "Mesh: %s", RemovePath(hMesh->GetName())); + sprintf_s(lbl, 256, "Mesh: %s", RemovePath(hSelMesh->GetName())); SetWindowText(GetDlgItem(hDlg, IDC_DBG_MESHNAME), lbl); string str = ""; @@ -1356,8 +1313,7 @@ void UpdateMaterialDisplay(bool bSetup) bool IsSelectedGroupRendered() { if (!vObj) return false; - D3D9Mesh *hMesh = (D3D9Mesh *)vObj->GetMesh(sMesh); - if (hMesh) return hMesh->IsGroupRendered(sGroup); + if (hSelMesh) return hSelMesh->IsGroupRendered(sGroup); return false; } @@ -1426,24 +1382,46 @@ void SelectGroup(DWORD idx) // ============================================================================================= // -void SelectMesh(D3D9Mesh *pMesh) +void ValidateMesh(D3D9Mesh* pMesh) { - char MeshFile[MAX_PATH]; - if (pMesh != hSelMesh) - { - for (DWORD i = 0; i < nMesh; i++) { - if (vObj->GetMesh(i) == pMesh) { - sMesh = i; - hSelMesh = pMesh; - sprintf_s(MeshFile, MAX_PATH, "%s%s.msh", OapiExtension::GetMeshDir(), pMesh->GetName()); - dbgMsh[pMesh] = new DbgMesh(MeshFile); - break; - } + { + if (dbgMsh.find(pMesh) == dbgMsh.end()) { + char MeshFile[MAX_PATH]; + sprintf_s(MeshFile, MAX_PATH, "%s%s.msh", OapiExtension::GetMeshDir(), pMesh->GetName()); + dbgMsh[pMesh] = new DbgMesh(MeshFile); } + hSelMesh = pMesh; + hDbgMsh = dbgMsh[pMesh]; } - SetupMeshGroups(); - UpdateLightsSlider(); +} + +// ============================================================================================= +// +void SelectMesh(D3D9Mesh *pMesh) +{ + sMesh = 0; + for (DWORD i = 0; i < nMesh; i++) { + if (vObj->GetMesh(i) == pMesh) { + sMesh = i; + ValidateMesh(pMesh); + SetupMeshGroups(); + return; + } + } +} + +// ============================================================================================= +// +void UpdateMeshFlags() +{ + if (!hSelMesh) return; + DWORD f = 0; + + if (SendDlgItemMessage(hDlg, IDC_DBG_ISVCMESH, BM_GETCHECK, 0, 0) == BST_CHECKED) f |= MESHFLAG_VC; + if (SendDlgItemMessage(hDlg, IDC_DBG_VCSHADOW, BM_GETCHECK, 0, 0) == BST_CHECKED) f |= MESHFLAG_SHADOW_VC; + hSelMesh->MeshFlags = f | 0x1; + hDbgMsh->SetMeshFlags(hSelMesh->MeshFlags); } // ============================================================================================= @@ -1470,10 +1448,10 @@ void SetupMeshGroups() sprintf_s(lbl,256,"%u/%u",sMesh,nMesh-1); SetWindowText(GetDlgItem(hDlg, IDC_DBG_MESH), lbl); - D3D9Mesh *mesh = (class D3D9Mesh *)vObj->GetMesh(sMesh); + ValidateMesh(vObj->GetMesh(sMesh)); - if (mesh) nGroup = mesh->GetGroupCount(); - else nGroup = 0; + if (hSelMesh) nGroup = hSelMesh->GetGroupCount(); + else nGroup = 0; if (nGroup!=0) { if (sGroup>0xFFFF) sGroup = nGroup-1; @@ -1489,9 +1467,15 @@ void SetupMeshGroups() sprintf_s(lbl,256,"%u/%u",sGroup,nGroup-1); SetWindowText(GetDlgItem(hDlg, IDC_DBG_GROUP), lbl); + if (hSelMesh) { + SendDlgItemMessage(hDlg, IDC_DBG_ISVCMESH, BM_SETCHECK, (hSelMesh->MeshFlags & MESHFLAG_VC) != 0, 0); + SendDlgItemMessage(hDlg, IDC_DBG_VCSHADOW, BM_SETCHECK, (hSelMesh->MeshFlags & MESHFLAG_SHADOW_VC) != 0, 0); + } + UpdateMaterialDisplay(); SetColorSlider(); - InitMatList(mesh->GetDefaultShader()); + UpdateLightsSlider(); + InitMatList(hSelMesh->GetDefaultShader()); } @@ -1499,12 +1483,11 @@ void SetupMeshGroups() // void UpdateBakedLights(float lvl) { - D3D9Mesh* mesh = (class D3D9Mesh*)vObj->GetMesh(sMesh); - if (mesh) { + if (hSelMesh) { if (bkl_id < 16 && bkl_id >= 0) { - mesh->SetBakedLightLevel(bkl_id, FVECTOR3(lvl, lvl, lvl)); + hSelMesh->SetBakedLightLevel(bkl_id, FVECTOR3(lvl, lvl, lvl)); } - if (bkl_id == 16) mesh->SetAmbientColor(FVECTOR3(lvl, lvl, lvl)); + if (bkl_id == 16) hSelMesh->SetAmbientColor(FVECTOR3(lvl, lvl, lvl)); } } @@ -1513,10 +1496,9 @@ void UpdateBakedLights(float lvl) void UpdateLightsSlider() { float val = 0.0f; - D3D9Mesh* mesh = (class D3D9Mesh*)vObj->GetMesh(sMesh); - if (mesh) { - if (bkl_id < 16 && bkl_id >= 0) val = mesh->GetBakedLightLevel(bkl_id).x; - if (bkl_id == 16) val = mesh->GetAmbientColor().x; + if (hSelMesh) { + if (bkl_id < 16 && bkl_id >= 0) val = hSelMesh->GetBakedLightLevel(bkl_id).x; + if (bkl_id == 16) val = hSelMesh->GetAmbientColor().x; SendDlgItemMessage(hDlg, IDC_DBG_BKLADJ, TBM_SETPOS, 1, WORD(255.0f * val)); } } @@ -1525,10 +1507,9 @@ void UpdateLightsSlider() // LPDIRECT3DTEXTURE9 GetCombinedMap() { - D3D9Mesh* mesh = (class D3D9Mesh*)vObj->GetMesh(sMesh); - if (mesh) { - DWORD texidx = mesh->GetMeshGroupTextureIdx(sGroup); - return mesh->GetCombinedMap(texidx); + if (hSelMesh) { + DWORD texidx = hSelMesh->GetMeshGroupTextureIdx(sGroup); + return hSelMesh->GetCombinedMap(texidx); } return NULL; } @@ -1551,6 +1532,13 @@ vObject * GetVisual() return vObj; } +// ============================================================================================= +// +D3D9Mesh* GetMesh() +{ + return hSelMesh; +} + // ============================================================================================= // void SetVisual(vObject *vo) @@ -2272,6 +2260,7 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) bPaused = oapiGetPause(); oapiSetPause(true); strcpy(SaveMesh.lpstrFileTitle, hSelMesh->GetName()); + SaveMesh.hwndOwner = hWnd; if (GetSaveFileName(&SaveMesh)) { dbgMsh[hSelMesh]->Save(SaveMesh.lpstrFile); return true; @@ -2310,6 +2299,11 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) SetColorSlider(); break; + case IDC_DBG_ISVCMESH: + case IDC_DBG_VCSHADOW: + UpdateMeshFlags(); + break; + case IDC_DBG_GRPO: case IDC_DBG_VISO: case IDC_DBG_MSHO: @@ -2325,6 +2319,7 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case IDC_DBG_TILEBB: case IDC_DBG_CLIPDIST: case IDC_DBG_EXTVC: + case IDC_DBG_PICKCURRENT: UpdateFlags(); break; @@ -2334,6 +2329,7 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case IDC_DBG_ADDITIVE: case IDC_DBG_NOCOLOR: case IDC_DBG_OIT: + case IDC_DBG_DYNAMIC: if (HIWORD(wParam) == BN_CLICKED) { ValidateGroup(sGroup); } diff --git a/OVP/D3D9Client/DebugControls.h b/OVP/D3D9Client/DebugControls.h index a8baed679..c56fb8003 100644 --- a/OVP/D3D9Client/DebugControls.h +++ b/OVP/D3D9Client/DebugControls.h @@ -63,6 +63,7 @@ #define DBG_FLAGS_TILEBOXES 0x4000 ///< Tile Boxes #define DBG_FLAGS_NEARCLIP 0x8000 ///< Set Clip distance to 2cm #define DBG_FLAGS_RENDEREXT 0x10000 ///< Render exterior meshes for VC view +#define DBG_FLAGS_PICKCURRENT 0x20000 ///< Only use Pick for current mesh /// @} @@ -109,6 +110,7 @@ namespace DebugControls { void RemoveVisual(vObject *vo); vObject * GetVisual(); void SetPickPos(D3DXVECTOR3 pos); + D3D9Mesh* GetMesh(); void SetupMeshGroups(); void UpdateVisual(); diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index 172bc9675..1e423a798 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -193,6 +193,9 @@ void D3D9Mesh::Null(const char *meshName /* = NULL */) MaxVert = 0; vClass = 0; DefShader = SHADER_NULL; + hOapiMesh = NULL; + MeshFlags = 0; + Flags = 0; bIsTemplate = false; bGlobalTF = false; @@ -328,6 +331,7 @@ D3D9Mesh::D3D9Mesh(const MESHGROUPEX *pGroup, const MATERIAL *pMat, SurfNative * D3D9Mesh::D3D9Mesh(MESHHANDLE hMesh, const D3D9Mesh &hTemp) { Null(oapiGetMeshFilename(hMesh)); + hOapiMesh = hMesh; // Confirm the source is global template assert(hTemp.bIsTemplate == true); @@ -344,6 +348,9 @@ D3D9Mesh::D3D9Mesh(MESHHANDLE hMesh, const D3D9Mesh &hTemp) BBox = hTemp.BBox; MaxVert = hTemp.MaxVert; MaxFace = hTemp.MaxFace; + MeshFlags = hTemp.MeshFlags; + Flags = hTemp.Flags; + // Clone group records from a tremplate Grp = new GROUPREC[nGrp]; memcpy(Grp, hTemp.Grp, sizeof(GROUPREC)*nGrp); @@ -417,6 +424,7 @@ void D3D9Mesh::Release() void D3D9Mesh::ReLoadMeshFromHandle(MESHHANDLE hMesh) { + hOapiMesh = hMesh; const char* meshn = oapiGetMeshFilename(hMesh); strcpy_s(name, 128, meshn ? meshn : "???"); @@ -464,6 +472,7 @@ void D3D9Mesh::ReLoadMeshFromHandle(MESHHANDLE hMesh) for (DWORD i = 0; ipMesh) if (p->pMesh != this) return result; + if (!pBuf->pGBSys || !pBuf->pIBSys) { LogErr("D3D9Mesh::Pick() Failed: No Geometry Available"); return result; @@ -3553,9 +3566,9 @@ D3D9Pick D3D9Mesh::Pick(const LPD3DXMATRIX pW, const LPD3DXMATRIX pT, const D3DX D3DXVec3Cross(&cp, ptr(_c - _b), ptr(_a - _b)); - if (D3DXVec3Dot(&cp, &dir)<0) { + if ((D3DXVec3Dot(&cp, &dir)<0) || p->bDualSided) { if (D3DXIntersectTri(&_c, &_b, &_a, &pos, &dir, &u, &v, &dst)) { - if (dst > 0.1f) { + if (dst > p->fnear) { if (dst < result.dist) { result.dist = dst; result.group = int(g); diff --git a/OVP/D3D9Client/Mesh.h b/OVP/D3D9Client/Mesh.h index 82306e632..48b09cd14 100644 --- a/OVP/D3D9Client/Mesh.h +++ b/OVP/D3D9Client/Mesh.h @@ -170,9 +170,11 @@ class D3D9Mesh : private D3D9Effect bool bIsReflective; // Mesh has a reflective material in one or more groups bool bMtrlModidied; bool bIsTemplate; - + + DWORD MeshFlags; D9BBox BBox; MeshBuffer *pBuf; + MESHHANDLE hOapiMesh; struct GROUPREC { // mesh group definition DWORD VertOff; // Main mesh Vertex Offset @@ -209,7 +211,7 @@ class D3D9Mesh : private D3D9Effect ~D3D9Mesh(); bool IsOK() const { return pBuf != NULL; } - + MESHHANDLE GetOapiHandle() { return hOapiMesh; } void Release(); void ClearBake(int i); void LoadBakedLights(); @@ -322,7 +324,7 @@ class D3D9Mesh : private D3D9Effect void SetSunLight(const D3D9Sun *pLight); - D3D9Pick Pick(const LPD3DXMATRIX pW, const LPD3DXMATRIX pT, const D3DXVECTOR3 *vDir); + D3D9Pick Pick(const LPD3DXMATRIX pW, const LPD3DXMATRIX pT, const D3DXVECTOR3 *vDir, const PickProp* p); void UpdateBoundingBox(); void BoundingBox(const NMVERTEX *vtx, DWORD n, D9BBox *box); diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index dbec50f31..c3d5750ef 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -2410,7 +2410,8 @@ Scene::SUNVISPARAMS Scene::GetSunScreenVisualState() short xpos = short((scrPos.x + 0.5f) * w); short ypos = short((1.0f - (scrPos.y + 0.5f)) * h); - D3D9Pick pick = PickScene(xpos, ypos); + PickProp prp = { NULL, 0.1f, false }; + D3D9Pick pick = PickScene(xpos, ypos, &prp); if (pick.pMesh != NULL) { @@ -2730,15 +2731,19 @@ int Scene::RenderVCShadowMap(D3DXVECTOR3& cdir, D3DXVECTOR3& ld, bool bListExist // render the vessel objects -------------------------------- // - BeginPass(RENDERPASS_SHADOWMAP); + BeginPass(RENDERPASS_VC_SHADOWMAP); // NOTE: smap.mLVP must containg the projection needed for rendering of the map smap.mLVP = smap.mVP[i]; for (auto &a : SmapRenderList) { - a->Render(pDevice, false); - if (a == vFocus) a->Render(pDevice, true); + if (a == vFocus) { + a->Render(pDevice, true); + } + else { + a->Render(pDevice, false); + } } PopPass(); @@ -3489,7 +3494,7 @@ TILEPICK Scene::PickSurface(short xpos, short ypos) // =========================================================================================== // -D3D9Pick Scene::PickScene(short xpos, short ypos) +D3D9Pick Scene::PickScene(short xpos, short ypos, const PickProp *p) { D3DXVECTOR3 vPick = GetPickingRay(xpos, ypos); @@ -3510,7 +3515,7 @@ D3D9Pick Scene::PickScene(short xpos, short ypos) double cd = vVes->CamDist(); if (cd<5e3 && cd>1e-3) { - D3D9Pick pick = vVes->Pick(&vPick); + D3D9Pick pick = vVes->Pick(&vPick, p); if (pick.pMesh) if (pick.distPick(pW, NULL, ptr(GetPickingRay(xpos, ypos))); + PickProp prp = { NULL, 0.1f, false }; + return pMesh->Pick(pW, NULL, ptr(GetPickingRay(xpos, ypos)), &prp); } // =========================================================================================== diff --git a/OVP/D3D9Client/Scene.h b/OVP/D3D9Client/Scene.h index bcc043dc4..22b09aa62 100644 --- a/OVP/D3D9Client/Scene.h +++ b/OVP/D3D9Client/Scene.h @@ -52,6 +52,7 @@ class D3D9Pad; #define RENDERPASS_SKETCHPAD 0x0006 #define RENDERPASS_MAINOVERLAY 0x0007 #define RENDERPASS_NORMAL_DEPTH 0x0008 +#define RENDERPASS_VC_SHADOWMAP 0x0009 #define RESTORE ((LPDIRECT3DSURFACE9)(-1)) #define CURRENT ((LPDIRECT3DSURFACE9)(-2)) @@ -290,7 +291,7 @@ class Scene { // Picking Functions ============================================================================================================ // D3DXVECTOR3 GetPickingRay(short x, short y); - D3D9Pick PickScene(short xpos, short ypos); + D3D9Pick PickScene(short xpos, short ypos, const PickProp* p); TILEPICK PickSurface(short xpos, short ypos); D3D9Pick PickMesh(DEVMESHHANDLE hMesh, const LPD3DXMATRIX pW, short xpos, short ypos); diff --git a/OVP/D3D9Client/VObject.h b/OVP/D3D9Client/VObject.h index 316fcb23e..840664ad6 100644 --- a/OVP/D3D9Client/VObject.h +++ b/OVP/D3D9Client/VObject.h @@ -120,7 +120,7 @@ class vObject: public oapi::VisObject { * \return Mesh handle * \note Currently only vessel visuals return anything here. */ - virtual MESHHANDLE GetMesh (UINT idx) { return NULL; } + virtual D3D9Mesh * GetMesh (UINT idx) { return NULL; } virtual DWORD GetMeshVisMode (UINT idx) { return MESHVIS_ALWAYS; } virtual void PreInitObject() { } diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index f8c39592f..ed8eb2a38 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -209,7 +209,7 @@ DWORD vVessel::GetMeshCount() // ============================================================================================ // -MESHHANDLE vVessel::GetMesh (UINT idx) +D3D9Mesh* vVessel::GetMesh (UINT idx) { return (idx < nmesh ? meshlist[idx].mesh : NULL); } @@ -658,7 +658,7 @@ bool vVessel::GetVCPos(D3DXVECTOR3* out, float* rad) { if (!meshlist[i].mesh) continue; - if (meshlist[i].vismode == MESHVIS_VC) + if (meshlist[i].mesh->MeshFlags & MESHFLAG_VC) { D3DXVECTOR3 pos = meshlist[i].mesh->GetBoundingSpherePos(); @@ -811,20 +811,22 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass) if (DebugControls::IsActive()) if (displ>1) vismode = MESHVIS_ALWAYS; - if (vismode==0) continue; - - if (internalpass==false) { - if (vismode==MESHVIS_VC) continue; // Added 3-jan-2011 to prevent VC interior double rendering during exterior and interior passes - if ((vismode&MESHVIS_EXTPASS)==0 && bCockpit) continue; - } - - if (bCockpit) { - if (internalpass && (vismode & MESHVIS_EXTPASS)) continue; - if (!(vismode & MESHVIS_COCKPIT)) { - if ((!bVC) || (!(vismode & MESHVIS_VC))) continue; + if (scn->GetRenderPass() != RENDERPASS_VC_SHADOWMAP) + { + if (vismode == 0) continue; + if (internalpass == false) { + if (vismode == MESHVIS_VC) continue; // Added 3-jan-2011 to prevent VC interior double rendering during exterior and interior passes + if ((vismode & MESHVIS_EXTPASS) == 0 && bCockpit) continue; + } + if (bCockpit) { + if (internalpass && (vismode & MESHVIS_EXTPASS)) continue; + if (!(vismode & MESHVIS_COCKPIT)) { + if ((!bVC) || (!(vismode & MESHVIS_VC))) continue; + } + } + else { + if (!(vismode & MESHVIS_EXTERNAL)) continue; } - } else { - if (!(vismode & MESHVIS_EXTERNAL)) continue; } D3DXMATRIX mWT; @@ -856,7 +858,12 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass) // Render vessel meshes -------------------------------------------------------------------------- // - if (scn->GetRenderPass() == RENDERPASS_SHADOWMAP) + if (scn->GetRenderPass() == RENDERPASS_VC_SHADOWMAP) + { + if (meshlist[i].mesh->MeshFlags & MESHFLAG_SHADOW_VC || meshlist[i].mesh->MeshFlags & MESHFLAG_VC) + meshlist[i].mesh->RenderShadowMap(pWT, pLVP, 0, bVC); + } + else if (scn->GetRenderPass() == RENDERPASS_SHADOWMAP) { meshlist[i].mesh->RenderShadowMap(pWT, pLVP, 0, bVC); } @@ -1900,7 +1907,7 @@ void vVessel::UpdateBoundingBox() // =========================================================================================== // -D3D9Pick vVessel::Pick(const D3DXVECTOR3 *vDir) +D3D9Pick vVessel::Pick(const D3DXVECTOR3 *vDir, const PickProp *p) { D3DXMATRIX mWT; LPD3DXMATRIX pWT = NULL; @@ -1953,7 +1960,7 @@ D3D9Pick vVessel::Pick(const D3DXVECTOR3 *vDir) if (!bRender) continue; - D3D9Pick pick = hMesh->Pick(&mWorld, meshlist[i].trans, vDir); + D3D9Pick pick = hMesh->Pick(&mWorld, meshlist[i].trans, vDir, p); if (pick.pMesh) if (pick.dist0 modulate (mix) material alpha values with texture alpha maps. * \sa oapiSetMeshProperty(DEVMESHHANDLE,DWORD,DWORD) */ OAPIFUNC bool oapiSetMeshProperty (MESHHANDLE hMesh, DWORD property, DWORD value); +OAPIFUNC bool oapiGetMeshProperty (MESHHANDLE hMesh, DWORD property, DWORD *value); /** * \brief Set custom properties for a device-specific mesh. @@ -4819,7 +4825,8 @@ OAPIFUNC bool oapiSetMeshProperty (MESHHANDLE hMesh, DWORD property, DWORD value * \return \e true if the property tag was recognised and the request could be executed, \e false otherwise. * \note Currently only a single mesh property is recognised, but this may be * extended in future versions: - * - \c MESHPROPERTY_MODULATEMATALPHA \n \n + * - \c MESHPROPERTY_MODULATEMATALPHA + * - \c MESHPROPERTY_FLAGS\n \n * if value==0 (default) disable material alpha information in textured mesh groups (only use texture alpha channel).\n * if value<>0 modulate (mix) material alpha values with texture alpha maps. * \sa oapiSetMeshProperty(MESHHANDLE,DWORD,DWORD) diff --git a/Src/Orbiter/Mesh.cpp b/Src/Orbiter/Mesh.cpp index 809aa75b2..785df51bb 100644 --- a/Src/Orbiter/Mesh.cpp +++ b/Src/Orbiter/Mesh.cpp @@ -64,6 +64,7 @@ Mesh::Mesh () { name = NULL; nGrp = nMtrl = nTex = 0; + Flags = 0; GrpVis = 0; GrpSetup = false; bModulateMatAlpha = false; @@ -73,6 +74,7 @@ Mesh::Mesh (NTVERTEX *vtx, DWORD nvtx, WORD *idx, DWORD nidx, DWORD matidx, DWOR { name = NULL; nGrp = nMtrl = nTex = 0; + Flags = 0; GrpVis = 0; GrpSetup = false; AddGroup (vtx, nvtx, idx, nidx, matidx, texidx); @@ -132,6 +134,7 @@ void Mesh::Set (const Mesh &mesh) } SetName(mesh.GetName()); bModulateMatAlpha = mesh.bModulateMatAlpha; + Flags = mesh.Flags; } Mesh::~Mesh () @@ -187,6 +190,16 @@ void Mesh::SetupGroup (DWORD grp) GrpRad[grp] = (FLOAT)sqrt (d2max); } +void Mesh::AddLabel(DWORD grp, const char* label) +{ + GrpLabels[grp] = std::string(label); +} + +std::string Mesh::GetLabel(DWORD grp) +{ + return GrpLabels.find(grp) != GrpLabels.end() ? GrpLabels[grp] : std::string(""); +} + int Mesh::AddGroup (NTVERTEX *vtx, DWORD nvtx, WORD *idx, DWORD nidx, DWORD mtrl_idx, DWORD tex_idx, WORD zbias, DWORD flag, bool deepcopy) { @@ -1037,6 +1050,10 @@ istream &operator>> (istream &is, Mesh &mesh) break; } else if (!_strnicmp (cbuf, "STATICMESH", 10)) { staticmesh = true; + } else if (!_strnicmp(cbuf, "MESHFLAGS", 9)) { + DWORD mf = 0; + if (sscanf(cbuf + 9, "%lx", &mf) != 1) return is; + mesh.Flags = mf | 0x1; // Flag entry is defined } } @@ -1056,7 +1073,9 @@ istream &operator>> (istream &is, Mesh &mesh) for (;;) { if (!is.getline (cbuf, 256)) { term = true; break; } - if (!_strnicmp (cbuf, "MATERIAL", 8)) { // read material index + if (cbuf[0] == ';') { + // Do nothing + } else if (!_strnicmp (cbuf, "MATERIAL", 8)) { // read material index sscanf (cbuf+8, "%d", &mtrl_idx); mtrl_idx--; } else if (!_strnicmp (cbuf, "TEXTURE", 7)) { // read texture index @@ -1076,7 +1095,9 @@ istream &operator>> (istream &is, Mesh &mesh) } else if (!_strnicmp (cbuf, "FLIP", 4)) { flipidx = true; } else if (!_strnicmp (cbuf, "LABEL", 5)) { - // ignore group labels here + char label[64]; + sscanf(cbuf + 5, "%63s", label); + mesh.AddLabel(g, label); } else if (!_strnicmp (cbuf, "STATIC", 6)) { flag |= 0x04; } else if (!_strnicmp (cbuf, "DYNAMIC", 7)) { diff --git a/Src/Orbiter/Mesh.h b/Src/Orbiter/Mesh.h index 45f6a92f8..f27420ff0 100644 --- a/Src/Orbiter/Mesh.h +++ b/Src/Orbiter/Mesh.h @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include "OrbiterAPI.h" typedef char Str256[256]; @@ -104,6 +106,12 @@ class Mesh { inline DWORD GetGroupUsrFlag (DWORD grp) const { return (grp < nGrp ? Grp[grp].UsrFlag : 0); } // return the user-defined flag for group grp + void AddLabel(DWORD grp, const char* label); + // Add label to a mesh group + + std::string GetLabel(DWORD grp); + // return group label + int AddGroup (NTVERTEX *vtx, DWORD nvtx, WORD *idx, DWORD nidx, DWORD mtrl_idx = SPEC_INHERIT, DWORD tex_idx = SPEC_INHERIT, WORD zbias = 0, DWORD flag = 0, bool deepcopy = false); @@ -203,6 +211,7 @@ class Mesh { static void GlobalEnableSpecular (bool enable); void EnableMatAlpha (bool enable); + bool EnableMatAlpha() { return bModulateMatAlpha; } friend std::istream &operator>> (std::istream &is, Mesh &mesh); // read mesh from file @@ -215,6 +224,7 @@ class Mesh { // Release textures acquired by the mesh private: + std::map GrpLabels; DWORD nGrp; // number of groups GroupSpec *Grp; // list of group specs diff --git a/Src/Orbiter/OrbiterAPI.cpp b/Src/Orbiter/OrbiterAPI.cpp index ef574cfb2..f71e64ad6 100644 --- a/Src/Orbiter/OrbiterAPI.cpp +++ b/Src/Orbiter/OrbiterAPI.cpp @@ -1496,6 +1496,12 @@ DLLEXPORT DWORD oapiGetMeshFlags (MESHHANDLE hMesh) return ((Mesh*)hMesh)->GetFlags(); } +DLLEXPORT void oapiMeshGroupLabel(MESHHANDLE hMesh, DWORD grp, char* label, DWORD bufsize) +{ + Mesh* pMesh = (Mesh*)hMesh; + strncpy(label, pMesh->GetLabel(grp).c_str(), bufsize); +} + DLLEXPORT MESHGROUP *oapiMeshGroup (MESHHANDLE hMesh, DWORD idx) { if (!hMesh) { @@ -1601,6 +1607,23 @@ DLLEXPORT bool oapiSetMeshProperty (MESHHANDLE hMesh, DWORD property, DWORD valu case MESHPROPERTY_MODULATEMATALPHA: mesh->EnableMatAlpha (value != 0); return true; + case MESHPROPERTY_FLAGS: + mesh->SetFlags(value); + return true; + } + return false; +} + +DLLEXPORT bool oapiGetMeshProperty(MESHHANDLE hMesh, DWORD property, DWORD *value) +{ + Mesh* mesh = (Mesh*)hMesh; + switch (property) { + case MESHPROPERTY_MODULATEMATALPHA: + *value = mesh->EnableMatAlpha() ? 1 : 0; + return true; + case MESHPROPERTY_FLAGS: + *value = mesh->GetFlags(); + return true; } return false; } From 324be7c2d4f4b5f3c43a1132d19a83ec8a452ef6 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Wed, 24 Jan 2024 01:41:42 +0200 Subject: [PATCH 28/42] - Verbose logging added. oapiWriteLogVerbose() - Env camera configuration cleanup and improvements. - Irradiance map quality and performance updates. - Planet glow included in BakedAmbient lighting. --- OVP/D3D9Client/D3D9Client.cpp | 43 +- OVP/D3D9Client/D3D9Client.h | 40 ++ OVP/D3D9Client/DebugControls.cpp | 12 +- OVP/D3D9Client/Log.cpp | 27 ++ OVP/D3D9Client/Log.h | 1 + OVP/D3D9Client/MaterialMgr.cpp | 102 +---- OVP/D3D9Client/MaterialMgr.h | 29 -- OVP/D3D9Client/Mesh.cpp | 50 ++- OVP/D3D9Client/Mesh.h | 15 +- OVP/D3D9Client/Scene.cpp | 433 ++++++++++--------- OVP/D3D9Client/Scene.h | 79 ++-- OVP/D3D9Client/VBase.cpp | 4 +- OVP/D3D9Client/VPlanet.cpp | 2 +- OVP/D3D9Client/VVessel.cpp | 442 +++++++++++--------- OVP/D3D9Client/VVessel.h | 31 +- OVP/D3D9Client/shaders/EnvMapBlur.hlsl | 8 +- OVP/D3D9Client/shaders/IrradianceInteg.hlsl | 44 +- OVP/D3D9Client/shaders/PreBakeLights.hlsl | 42 +- Orbitersdk/include/DrawAPI.h | 8 +- Orbitersdk/include/GraphicsAPI.h | 8 + Orbitersdk/include/OrbiterAPI.h | 14 + Orbitersdk/include/VesselAPI.h | 6 + Src/Orbiter/Orbiter.cpp | 12 +- Src/Orbiter/OrbiterAPI.cpp | 5 + Src/Orbiter/Vessel.cpp | 59 +++ Src/Orbiter/Vessel.h | 3 + Src/Vessel/DeltaGlider/DeltaGlider.cpp | 12 + 27 files changed, 895 insertions(+), 636 deletions(-) diff --git a/OVP/D3D9Client/D3D9Client.cpp b/OVP/D3D9Client/D3D9Client.cpp index ed3866a4e..00baa4063 100644 --- a/OVP/D3D9Client/D3D9Client.cpp +++ b/OVP/D3D9Client/D3D9Client.cpp @@ -140,6 +140,7 @@ DLLCLBK void InitModule(HINSTANCE hDLL) #endif D3D9InitLog("Modules/D3D9Client/D3D9ClientLog.html"); + LogVerbose("[D3D9] === InitModule ==="); if (!D3DXCheckVersion(D3D_SDK_VERSION, D3DX_SDK_VERSION)) { MissingRuntimeError(); @@ -188,7 +189,7 @@ DLLCLBK void InitModule(HINSTANCE hDLL) DLLCLBK void ExitModule(HINSTANCE hDLL) { - LogAlw("--------------ExitModule------------"); + LogVerbose("[D3D9] === ExitModule ==="); delete TileCatalog; delete Config; @@ -275,7 +276,7 @@ D3D9Client::D3D9Client (HINSTANCE hInstance) : D3D9Client::~D3D9Client() { - LogAlw("D3D9Client destructor called"); + LogVerbose("[D3D9] === destructor called ==="); SAFE_DELETE(vtab); } @@ -310,7 +311,7 @@ const void *D3D9Client::GetConfigParam (DWORD paramtype) const bool D3D9Client::clbkInitialise() { _TRACE; - LogAlw("================ clbkInitialise ==============="); + LogVerbose("[D3D9] === clbkInitialise ==="); LogAlw("Orbiter Version = %d",oapiGetOrbiterVersion()); // Perform default setup @@ -329,7 +330,7 @@ HWND D3D9Client::clbkCreateRenderWindow() { _TRACE; - LogAlw("================ clbkCreateRenderWindow ==============="); + LogVerbose("[D3D9] === clbkCreateRenderWindow ==="); Config->WriteParams(); @@ -421,7 +422,7 @@ HWND D3D9Client::clbkCreateRenderWindow() LogAlw("Render Target = %s", _PTR(pBackBuffer)); LogAlw("DepthStencil = %s", _PTR(pDepthStencil)); - meshmgr = new MeshManager(this); + meshmgr = new MeshManager(this); // Bring Sketchpad Online D3D9PadFont::D3D9TechInit(pDevice); @@ -531,9 +532,10 @@ HWND D3D9Client::clbkCreateRenderWindow() void D3D9Client::clbkPostCreation() { _TRACE; - LogAlw("================ clbkPostCreation ==============="); - if (scene) scene->Initialise(); + LogVerbose("[D3D9] === clbkPostCreation ==="); + + if (scene) scene->clbkInitialise(); // Create Window Manager ----------------------------------------- // @@ -544,8 +546,6 @@ void D3D9Client::clbkPostCreation() bRunning = true; - LogAlw("=============== Loading Completed and Visuals Created ================"); - #ifdef _DEBUG SketchPadTest(); #endif @@ -762,9 +762,8 @@ void D3D9Client::SketchPadTest() // void D3D9Client::clbkCloseSession(bool fastclose) { - - LogAlw("================ clbkCloseSession ==============="); - + LogVerbose("[D3D9] === clbkCloseSession ==="); + // Post shutdown signals for gcGUI applications // for (auto pApp : g_gcGUIAppList) pApp->clbkShutdown(); @@ -824,7 +823,8 @@ void D3D9Client::clbkDestroyRenderWindow (bool fastclose) { _TRACE; oapiWriteLog((char*)"D3D9: [Destroy Render Window Called]"); - LogAlw("============= clbkDestroyRenderWindow ==========="); + + LogVerbose("[D3D9] === clbkDestroyRenderWindow ==="); #ifdef _NVAPI_H if (bNVAPI) { @@ -1096,7 +1096,7 @@ void D3D9Client::clbkUpdate(bool running) { _TRACE; double tot_update = D3D9GetTime(); - if (bFailed==false && bRunning) scene->Update(); + if (bFailed==false && bRunning) scene->clbkUpdate(); D3D9SetTime(D3D9Stats.Timer.Update, tot_update); } @@ -1128,7 +1128,7 @@ void D3D9Client::clbkRenderScene() UINT mem = pDevice->GetAvailableTextureMem()>>20; if (mem<32) TileBuffer::HoldThread(true); - scene->RenderMainScene(); // Render the main scene + scene->clbkRenderMainScene(); // Render the main scene VESSEL *hVes = oapiGetFocusInterface(); @@ -1538,14 +1538,14 @@ int D3D9Client::clbkGetMeshGroup (DEVMESHHANDLE hMesh, DWORD grpidx, GROUPREQUES void D3D9Client::clbkNewVessel(OBJHANDLE hVessel) { _TRACE; - if (scene) scene->NewVessel(hVessel); + if (scene) scene->clbkNewVessel(hVessel); } // ============================================================== void D3D9Client::clbkDeleteVessel(OBJHANDLE hVessel) { - if (scene) scene->DeleteVessel(hVessel); + if (scene) scene->clbkDeleteVessel(hVessel); } @@ -1564,13 +1564,20 @@ void D3D9Client::clbkOptionChanged(DWORD cat, DWORD item) { switch (cat) { case OPTCAT_CELSPHERE: - if (scene) scene->OnOptionChanged(cat, item); + if (scene) scene->clbkOnOptionChanged(cat, item); return; } } // ============================================================== +void D3D9Client::clbkScenarioChanged(OBJHANDLE hVesselA, ScnChgEvent type) +{ + if (scene) scene->clbkScenarioChanged(hVesselA, type); +} + +// ============================================================== + bool D3D9Client::clbkUseLaunchpadVideoTab() const { _TRACE; diff --git a/OVP/D3D9Client/D3D9Client.h b/OVP/D3D9Client/D3D9Client.h index 76b1506c4..d8e28e436 100644 --- a/OVP/D3D9Client/D3D9Client.h +++ b/OVP/D3D9Client/D3D9Client.h @@ -74,6 +74,33 @@ extern D3D9Catalog *TileCatalog; extern set MeshCatalog; extern set SurfaceCatalog; +enum class EnvCamType { Undefined, Exterior, VC, Mesh }; + +struct ENVMAPS +{ + LPDIRECT3DBASETEXTURE9 pEnv = nullptr; ///< Reflection map (cube) + LPDIRECT3DTEXTURE9 pIrrad = nullptr; ///< Irradiance map (baraboloidal) +}; + +/** + * \brief Storage structure to keep reflection camera information. + */ +struct ENVCAMREC +{ + std::vector omitAttc; + std::vector omitDock; + ENVMAPS tex; + EnvCamType type = EnvCamType::Undefined; + FVECTOR3 lPos = { 0,0,0 }; ///< Camera local position + FVECTOR3 lDir = { 1,0,0 }; ///< Camera local direction (in 'PLANE' mode only) + float near_clip = 0.1f; ///< Near clip-plane distance + DWORD flags = 0; ///< Camera flags + int mesh_idx = -1; ///< Camera is attached to a mesh + int group_idx = -1; ///< Camera is attached to a group + int id = -1; ///< User Id, for binding + BYTE iSide = 0; ///< [Private] Current side being rendered + bool bRendered = false; ///< [Private] Rendering of camera view is completed +}; /** * \brief Statistical data storage @@ -154,6 +181,11 @@ struct SHADOWMAPPARAM { int cascades; // Number of active cascades }; +struct LVLH { + FVECTOR3 Up; + FVECTOR3 North; + FVECTOR3 East; +}; extern _D3D9Stats D3D9Stats; @@ -393,6 +425,14 @@ class D3D9Client : public GraphicsClient bool clbkSetMeshProperty (DEVMESHHANDLE hMesh, DWORD property, DWORD value); bool clbkSetMeshProperty(DEVMESHHANDLE hMesh, MeshProp prp, const oapi::FVECTOR4& value); + /** + * \brief React to vessel docking, attaching events + * \param hVesselA object handle of first vessel + * \param hVesselB object handle of second vessel + * \param type Event type + */ + void clbkScenarioChanged(OBJHANDLE hVessel, ScnChgEvent type); + /** * \brief React to vessel creation * \param hVessel object handle of new vessel diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index 2e1558c9a..f1b413016 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -640,8 +640,8 @@ void OpenDlgClbk(void *context) SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"Blur 2"); SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"Blur 3"); SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"Blur 4"); - SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"Irrad.Probe"); - SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"IrdPreItg"); + SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"--unused--"); + SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"--unused--"); SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"ShadowMap"); SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"Irradiance"); SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"GlowMask"); @@ -1839,9 +1839,11 @@ void SaveEnvMap() if (oapiIsVessel(hObj)) { vVessel *vVes = (vVessel *)vObj; - LPDIRECT3DCUBETEXTURE9 pTex = vVes->GetEnvMap(ENVMAP_MAIN); - if (D3DXSaveTextureToFileA("EnvMap.dds", D3DXIFF_DDS, pTex, NULL) != S_OK) { - LogErr("Failed to save envmap"); + auto pTex = vVes->GetEnvMap() ? vVes->GetEnvMap()->pEnv : nullptr; + if (pTex->GetType() == D3DRTYPE_CUBETEXTURE) { + if (D3DXSaveTextureToFileA("EnvMap.dds", D3DXIFF_DDS, (LPDIRECT3DCUBETEXTURE9)pTex, NULL) != S_OK) { + LogErr("Failed to save envmap"); + } } } } diff --git a/OVP/D3D9Client/Log.cpp b/OVP/D3D9Client/Log.cpp index ac8e1152b..8f2cfeff3 100644 --- a/OVP/D3D9Client/Log.cpp +++ b/OVP/D3D9Client/Log.cpp @@ -352,6 +352,33 @@ void LogOapi(const char *format, ...) } } +//------------------------------------------------------------------------------------------- +// +void LogVerbose(const char* format, ...) +{ + + if (d3d9client_log == NULL) return; + if (iLine > LOG_MAX_LINES) return; + if (uEnableLog > 0) { + EnterCriticalSection(&LogCrit); + DWORD th = GetCurrentThreadId(); + fprintf(d3d9client_log, "(%s)(0x%lX) ", my_ctime(), th); + + va_list args; + va_start(args, format); + _vsnprintf_s(ErrBuf, ERRBUF, ERRBUF, format, args); + va_end(args); + + oapiWriteLogVerbose(ErrBuf); + + escape_ErrBuf(); + fputs(ErrBuf, d3d9client_log); + fputs("
\n", d3d9client_log); + fflush(d3d9client_log); + LeaveCriticalSection(&LogCrit); + } +} + // --------------------------------------------------- // void LogErr(const char *format, ...) diff --git a/OVP/D3D9Client/Log.h b/OVP/D3D9Client/Log.h index ad115f36d..a12b0061b 100644 --- a/OVP/D3D9Client/Log.h +++ b/OVP/D3D9Client/Log.h @@ -56,6 +56,7 @@ void LogOk (const char *format, ...); void LogBreak(const char* format, ...); void LogBlu(const char *format, ...); void LogOapi(const char *format, ...); +void LogVerbose(const char* format, ...); void LogAlw(const char *format, ...); void LogDbg(const char *color, const char *format, ...); void LogClr(const char *color, const char *format, ...); diff --git a/OVP/D3D9Client/MaterialMgr.cpp b/OVP/D3D9Client/MaterialMgr.cpp index 0a3ebac94..e86282430 100644 --- a/OVP/D3D9Client/MaterialMgr.cpp +++ b/OVP/D3D9Client/MaterialMgr.cpp @@ -18,61 +18,19 @@ MatMgr::MatMgr(class vObject *v, class D3D9Client *_gc) { gc = _gc; vObj = v; - - pCamera = new ENVCAMREC[1]; - - ResetCamera(0); - + Shaders.push_back(SHADER("PBR-Old", SHADER_NULL)); Shaders.push_back(SHADER("Metalness", SHADER_METALNESS)); Shaders.push_back(SHADER("BakedVC", SHADER_BAKED_VC)); } - // =========================================================================================== // MatMgr::~MatMgr() { MeshConfig.clear(); - - if (pCamera) { - if (pCamera[0].pOmitAttc) delete[] pCamera[0].pOmitAttc; - if (pCamera[0].pOmitDock) delete[] pCamera[0].pOmitDock; - delete[] pCamera; - } } - -// =========================================================================================== -// -ENVCAMREC * MatMgr::GetCamera(DWORD idx) -{ - return &pCamera[0]; -} - - -// =========================================================================================== -// -DWORD MatMgr::CameraCount() -{ - return 1; -} - - -// =========================================================================================== -// -void MatMgr::ResetCamera(DWORD idx) -{ - pCamera[idx].near_clip = 0.25f; - pCamera[idx].lPos = D3DXVECTOR3(0,0,0); - pCamera[idx].nAttc = 0; - pCamera[idx].nDock = 0; - pCamera[idx].flags = ENVCAM_OMIT_ATTC; - pCamera[idx].pOmitAttc = NULL; - pCamera[idx].pOmitDock = NULL; -} - - // =========================================================================================== // void MatMgr::RegisterMaterialChange(D3D9Mesh *pMesh, DWORD midx, const D3D9MatExt *pM) @@ -421,85 +379,65 @@ bool MatMgr::LoadCameraConfig() if (file.IsInvalid()) return true; LogAlw("Reading a camera configuration file for a vessel %s (%s)", vessel->GetName(), vessel->GetClassNameA()); - - DWORD iattc = 0; - DWORD idock = 0; - DWORD camera = 0; - BYTE attclist[256]; - BYTE docklist[256]; + ENVCAMREC* pCamera = NULL; while(fgets2(cbuf, 256, file.pFile, 0x08)>=0) { float a, b, c; - DWORD id; // -------------------------------------------------------------------------------------------- if (!strncmp(cbuf, "END_CAMERA", 10)) { - - if (iattc) pCamera[camera].pOmitAttc = new BYTE[iattc]; - if (idock) pCamera[camera].pOmitDock = new BYTE[idock]; - - if (iattc) memcpy(pCamera[camera].pOmitAttc, attclist, iattc); - if (idock) memcpy(pCamera[camera].pOmitDock, docklist, idock); - - pCamera[camera].nAttc = WORD(iattc); - pCamera[camera].nDock = WORD(idock); - + pCamera = NULL; continue; } // -------------------------------------------------------------------------------------------- if (!strncmp(cbuf, "BEGIN_CAMERA", 12)) { - if (sscanf_s(cbuf, "BEGIN_CAMERA %u", &camera)!=1) LogErr("Invalid Line in (%s): %s", path, cbuf); - camera = 0; // For now just one camera - pCamera[camera].flags = 0; // Clear default flags + int idx = -1; + if (sscanf_s(cbuf, "BEGIN_CAMERA %d", &idx)!=1) LogErr("Invalid Line in (%s): %s", path, cbuf); + if (idx == 0) { + pCamera = ((vVessel*)vObj)->CreateEnvCam(EnvCamType::Exterior); + pCamera->id = -1; + pCamera->flags = 0; // Clear default flags + } + if (idx == 1) { + pCamera = ((vVessel*)vObj)->CreateEnvCam(EnvCamType::VC); + pCamera->id = -1; + pCamera->flags = 0; // Clear default flags + } continue; } // -------------------------------------------------------------------------------------------- if (!strncmp(cbuf, "LPOS", 4)) { if (sscanf_s(cbuf, "LPOS %g %g %g", &a, &b, &c)!=3) LogErr("Invalid Line in (%s): %s", path, cbuf); - pCamera[camera].lPos = D3DXVECTOR3(a,b,c); - continue; - } - - // -------------------------------------------------------------------------------------------- - if (!strncmp(cbuf, "OMITATTC", 8)) { - if (sscanf_s(cbuf, "OMITATTC %u", &id)!=1) LogErr("Invalid Line in (%s): %s", path, cbuf); - attclist[iattc++] = BYTE(id); - continue; - } - - // -------------------------------------------------------------------------------------------- - if (!strncmp(cbuf, "OMITDOCK", 8)) { - if (sscanf_s(cbuf, "OMITDOCK %u", &id)!=1) LogErr("Invalid Line in (%s): %s", path, cbuf); - docklist[idock++] = BYTE(id); + pCamera->lPos = FVECTOR3(a,b,c); continue; } // -------------------------------------------------------------------------------------------- if (!strncmp(cbuf, "CLIPDIST", 8)) { if (sscanf_s(cbuf, "CLIPDIST %g", &a)!=1) LogErr("Invalid Line in (%s): %s", path, cbuf); - pCamera[camera].near_clip = a; + pCamera->near_clip = a; continue; } // -------------------------------------------------------------------------------------------- if (!strncmp(cbuf, "OMIT_ALL_ATTC", 13)) { - pCamera[camera].flags |= ENVCAM_OMIT_ATTC; + pCamera->flags |= ENVCAM_OMIT_ATTC; continue; } // -------------------------------------------------------------------------------------------- if (!strncmp(cbuf, "DO_NOT_OMIT_FOCUS", 17)) { - pCamera[camera].flags |= ENVCAM_FOCUS; + pCamera->flags |= ENVCAM_FOCUS; continue; } // -------------------------------------------------------------------------------------------- if (!strncmp(cbuf, "OMIT_ALL_DOCKS", 14)) { - pCamera[camera].flags |= ENVCAM_OMIT_DOCKS; + pCamera->flags |= ENVCAM_OMIT_DOCKS; continue; } diff --git a/OVP/D3D9Client/MaterialMgr.h b/OVP/D3D9Client/MaterialMgr.h index 0c24536f6..ff43e8349 100644 --- a/OVP/D3D9Client/MaterialMgr.h +++ b/OVP/D3D9Client/MaterialMgr.h @@ -16,24 +16,6 @@ #include "D3D9Util.h" #include "vObject.h" -#define ENVCAM_OMIT_ATTC 0x0001 -#define ENVCAM_OMIT_DOCKS 0x0002 -#define ENVCAM_FOCUS 0x0004 - - -/** - * \brief Storage structure to keep environmental camera information. - */ -struct ENVCAMREC { - D3DXVECTOR3 lPos; ///< Camera local position - float near_clip; ///< Near clip-plane distance - DWORD flags; ///< Camera flags - WORD nAttc; ///< Number of attachments points in a list - WORD nDock; ///< Number of docking ports in a list - BYTE * pOmitAttc; ///< Omit attachments - BYTE * pOmitDock; ///< Omit vessels in docking ports -}; - /** * \brief Management of custom configurations for vessel materials */ @@ -47,8 +29,6 @@ class MatMgr { MatMgr(class vObject *vObj, class D3D9Client *_gc); ~MatMgr(); - //DWORD NewRecord(const char *name, DWORD midx); - //void ClearRecord(DWORD iRec); void RegisterMaterialChange(D3D9Mesh *pMesh, DWORD midx, const D3D9MatExt *pM); void RegisterShaderChange(D3D9Mesh *pMesh, WORD id); void ApplyConfiguration(D3D9Mesh *pMesh); @@ -56,18 +36,11 @@ class MatMgr { bool LoadConfiguration(bool bAppend=false); bool LoadCameraConfig(); bool HasMesh(const char *name); - void ResetCamera(DWORD idx); - - ENVCAMREC * GetCamera(DWORD idx); - DWORD CameraCount(); private: vObject *vObj; D3D9Client *gc; - //DWORD nRec; ///< Number of records - //DWORD mRec; ///< Allocated records - struct SHADER { SHADER(string x, WORD i) { name = x; id = i; } @@ -82,8 +55,6 @@ class MatMgr { std::map MeshConfig; std::list Shaders; - - ENVCAMREC *pCamera; }; #endif diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index 1e423a798..2c2ebdd5c 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -647,7 +647,7 @@ void D3D9Mesh::BakeLights(ImageProcessing* pBaker) // =========================================================================================== // -void D3D9Mesh::BakeAO(ImageProcessing* pBaker, const FVECTOR3 &vSun) +void D3D9Mesh::BakeAO(ImageProcessing* pBaker, const FVECTOR3 &vSun, const LVLH &lvlh, const LPDIRECT3DTEXTURE9 pIrrad) { if (!pBaker->IsOK()) return; // Baker not initialized if (DefShader != SHADER_BAKED_VC) return; // Not supported by shader @@ -655,28 +655,43 @@ void D3D9Mesh::BakeAO(ImageProcessing* pBaker, const FVECTOR3 &vSun) DWORD flags = IPF_POINT | IPF_CLAMP; FVECTOR3 control[6]; + FVECTOR3 ParTexCoord[6]; bool bSE[6]; + float fShine = 1.0f; + + // Compute texcoords for Irradiance lookup for prime directions + // + for (int i = 0; i < 6; i++) { + FVECTOR3 DirL = GetDir(i); + float z = dot(lvlh.Up, DirL); // lvlh is in a local vessel frame + FVECTOR2 p = FVECTOR2(dot(lvlh.East, DirL), dot(lvlh.North, DirL)) / (1.0f + abs(z)); + p *= FVECTOR2(0.2273f, 0.4545f); + ParTexCoord[i] = FVECTOR3(p.x, p.y, z); + } pBaker->Activate("PSSunAO"); + // Compute sunligh intensity factors for prime directions + // for (int i = 0; i < 6; i++) { - auto y = bli->second.pSunAO[i]; - bSE[i] = (y != NULL); - if (y) + auto tex = bli->second.pSunAO[i]; + bSE[i] = (tex != NULL); + if (tex) { - pBaker->SetTextureNative(i, y, flags); + pBaker->SetTextureNative(i, tex, flags); control[i] = saturate(dot(GetDir(i), vSun)); control[i] *= control[i]; - if (i == 4) D3D9DebugLog("Fwd %f", control[i].x); - if (i == 0) D3D9DebugLog("Up %f", control[i].x); } else { control[i] = 0.0f; } } + pBaker->SetTextureNative("tIrrad", pIrrad, IPF_LINEAR | IPF_CLAMP); pBaker->SetFloat("fControl", control, sizeof(control)); + pBaker->SetFloat("vParTexPos", ParTexCoord, sizeof(ParTexCoord)); + pBaker->SetFloat("fShine", &fShine, sizeof(fShine)); pBaker->SetBool("bEnabled", bSE, sizeof(bSE)); LPDIRECT3DSURFACE9 pSrf = NULL; @@ -1732,9 +1747,8 @@ void D3D9Mesh::SetShadows(const SHADOWMAPPARAM *sprm) // ================================================================================================ // This is a rendering routine for a Exterior Mesh, non-spherical moons/asteroids // -void D3D9Mesh::Render(const LPD3DXMATRIX pW, int iTech, LPDIRECT3DCUBETEXTURE9 *pEnv, int nEnv) +void D3D9Mesh::Render(const LPD3DXMATRIX pW, const ENVMAPS* em, int iTech) { - _TRACE; if (!IsOK()) return; @@ -1843,7 +1857,6 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, int iTech, LPDIRECT3DCUBETEXTURE9 * FX->SetTechnique(eVesselTech); FX->SetBool(eFresnel, false); - FX->SetBool(eEnvMapEnable, false); FX->SetBool(eLightsEnabled, false); FX->SetBool(eOITEnable, false); FX->SetVector(eColor, ptr(D3DXVECTOR4(0, 0, 0, 0))); @@ -1854,6 +1867,9 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, int iTech, LPDIRECT3DCUBETEXTURE9 * TexFlow FC; reset(FC); + + // Setup Local lights ------------------------------------------- + // const D3D9Light *pLights = gc->GetScene()->GetLights(); int nSceneLights = gc->GetScene()->GetLightCount(); @@ -1899,7 +1915,16 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, int iTech, LPDIRECT3DCUBETEXTURE9 * FX->SetValue(eLights, Locals, sizeof(LightStruct) * Config->MaxLights()); - if (nEnv >= 1 && pEnv[0]) FX->SetTexture(eEnvMapA, pEnv[0]); + // Setup Env Maps ------------------------------------------- + // + if (em && em->pEnv && em->pIrrad) { + FX->SetBool(eEnvMapEnable, true); + FX->SetTexture(eEnvMapA, em->pEnv); + FX->SetTexture(eIrradMap, em->pIrrad); + } + else { + FX->SetBool(eEnvMapEnable, false); + } UINT numPasses = 0; @@ -1908,6 +1933,7 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, int iTech, LPDIRECT3DCUBETEXTURE9 * WORD CurrentShader = SHADER_NULL; bool bRefl = true; + int iEnvCam = -1; for (DWORD g=0; g BakedLights; std::map::const_iterator bli; + std::vector env_cams; + FVECTOR3 BakedLightsControl[16]; D3DXMATRIX mTransform; D3DXMATRIX mTransformInv; diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index c3d5750ef..6adaca9e0 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -25,7 +25,7 @@ #include #include -#define IKernelSize 150 +#define IKernelSize 120 using namespace oapi; @@ -78,8 +78,6 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) _TRACE; gc = _gc; - vobjEnv = NULL; - vobjIrd = NULL; m_celSphere = NULL; Lights = NULL; hSun = NULL; @@ -87,6 +85,7 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) pLabelFont = NULL; pDebugFont = NULL; pBlur = NULL; + pBlur2D = NULL; pOffscreenTarget = NULL; pLocalCompute = NULL; pRenderGlares = NULL; @@ -103,16 +102,16 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) pSunGlare = NULL; pSunGlareAtm = NULL; pEnvDS = NULL; - pIrradDS = NULL; pIrradiance = NULL; pIrradTemp = NULL; - pIrradTemp2 = NULL; - pIrradTemp3 = NULL; pDepthNormalDS = NULL; pVisDepth = NULL; pLocalResults = NULL; pLocalResultsSL = NULL; pBakeLights = NULL; + ptRandom = NULL; + + vobjEnv = eCamRenderList.begin(); fDisplayScale = float(viewH) / 1080.0f; @@ -144,6 +143,7 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) memset(&smap, 0, sizeof(smap)); CLEARARRAY(pBlrTemp); + CLEARARRAY(pBlrTemp2D); CLEARARRAY(pTextures); CLEARARRAY(ptgBuffer); CLEARARRAY(psgBuffer); @@ -158,7 +158,7 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) float dx = 0; float dy = 0; for (int i = 0; i < IKernelSize; i++) { - double r = oapiRand(); + double r = sqrt(oapiRand()); double a = oapiRand() * PI2; IKernel[i].x = float(cos(a) * r); IKernel[i].y = float(sin(a) * r); @@ -171,7 +171,7 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) for (int i = 0; i < IKernelSize; i++) { float d = IKernel[i].x*IKernel[i].x + IKernel[i].y*IKernel[i].y; IKernel[i].z = sqrt(1.0f - saturate(d)); - IKernel[i].w = sqrt(IKernel[i].z); + IKernel[i].w = IKernel[i].z; } @@ -225,11 +225,6 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) HR(pDevice->CreateDepthStencilSurface(EnvMapSize, EnvMapSize, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, true, &pEnvDS, NULL)); } - if (Config->bIrradiance) { - HR(pDevice->CreateDepthStencilSurface(128, 128, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, true, &pIrradDS, NULL)); - } - - // Exterior shadows if (Config->ShadowMapMode) { UINT size = ShmMapSize; @@ -269,6 +264,14 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) HR(D3DXCreateTexture(pDevice, viewW, viewH, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &ptgBuffer[GBUF_DEPTH])); } + HR(D3DXCreateTexture(pDevice, 64, 64, 1, D3DUSAGE_DYNAMIC, D3DFMT_R32F, D3DPOOL_DEFAULT, &ptRandom)); + + D3DLOCKED_RECT rect; + if (ptRandom->LockRect(0, &rect, 0, 0) == S_OK) { + for (int i = 0; i < (64 * 64); i++) ((float*)rect.pBits)[i] = oapiRand(); + ptRandom->UnlockRect(0); + } + else LogErr("Failed to create random table"); // Initialize post processing effects -------------------------------------------------------------------------------------------------- // @@ -371,10 +374,7 @@ Scene::~Scene () SAFE_RELEASE(pOffscreenTarget); SAFE_RELEASE(pEnvDS); - SAFE_RELEASE(pIrradDS); SAFE_RELEASE(pIrradTemp); - SAFE_RELEASE(pIrradTemp2); - SAFE_RELEASE(pIrradTemp3); SAFE_RELEASE(pDepthNormalDS); SAFE_RELEASE(pLocalResults); SAFE_RELEASE(pLocalResultsSL); @@ -382,6 +382,7 @@ Scene::~Scene () SAFE_RELEASE(pLightGlare); SAFE_RELEASE(pSunGlare); SAFE_RELEASE(pSunGlareAtm); + SAFE_RELEASE(ptRandom); for (int i = 0; i < ARRAYSIZE(psShmDS); i++) SAFE_RELEASE(psShmDS[i]); for (int i = 0; i < ARRAYSIZE(ptShmRT); i++) SAFE_RELEASE(ptShmRT[i]); @@ -389,6 +390,7 @@ Scene::~Scene () for (int i = 0; i < ARRAYSIZE(ptVCShmRT); i++) SAFE_RELEASE(ptVCShmRT[i]); for (int i = 0; i < ARRAYSIZE(psVCShmRT); i++) SAFE_RELEASE(psVCShmRT[i]); for (int i = 0; i < ARRAYSIZE(pBlrTemp); i++) SAFE_RELEASE(pBlrTemp[i]); + for (int i = 0; i < ARRAYSIZE(pBlrTemp2D); i++) SAFE_RELEASE(pBlrTemp2D[i]); if (Lights) { delete []Lights; @@ -463,7 +465,7 @@ void Scene::CreateSunGlare() // =========================================================================================== // -void Scene::Initialise() +void Scene::clbkInitialise() { _TRACE; @@ -502,7 +504,7 @@ static D3D9Pad *_pad = NULL; // =========================================================================================== -void Scene::OnOptionChanged(int cat, int item) +void Scene::clbkOnOptionChanged(int cat, int item) { if (cat == OPTCAT_CELSPHERE) m_celSphere->OnOptionChanged(cat, item); @@ -659,12 +661,9 @@ void Scene::DelVisualRec (VOBJREC *pv) DebugControls::RemoveVisual(pv->vobj); - vobjEnv = NULL; - vobjIrd = NULL; - // delete the visual, its children and the entry itself gc->UnregisterVisObject(pv->vobj->GetObject()); - + if (pv->type == OBJTP_VESSEL) gc->clbkScenarioChanged(pv->vobj, ScnChgEvent::VisualDeleted); delete pv->vobj; delete pv; } @@ -688,8 +687,6 @@ void Scene::DeleteAllVisuals() pv = pvn; } vobjFirst = vobjLast = NULL; - vobjEnv = NULL; - vobjIrd = NULL; } // =========================================================================================== @@ -727,6 +724,8 @@ Scene::VOBJREC *Scene::AddVisualRec(OBJHANDLE hObj) // Initialize Meshes pv->vobj->PreInitObject(); + if (pv->type == OBJTP_VESSEL) gc->clbkScenarioChanged(pv->vobj, ScnChgEvent::VisualCreated); + return pv; } @@ -771,7 +770,7 @@ VECTOR3 Scene::SkyColour () // =========================================================================================== // -void Scene::Update () +void Scene::clbkUpdate () { _TRACE; @@ -1262,7 +1261,61 @@ void Scene::RecallDefaultState() // =========================================================================================== // -void Scene::RenderMainScene() +void Scene::clbkNewVessel(OBJHANDLE hVessel) +{ + CheckVisual(hVessel); +} + +// =========================================================================================== +// +void Scene::clbkDeleteVessel(OBJHANDLE hVessel) +{ + VOBJREC* pv = FindVisual(hVessel); + if (pv) DelVisualRec(pv); +} + +// =========================================================================================== +// +void Scene::clbkScenarioChanged(OBJHANDLE hVessel, ScnChgEvent e) +{ + LogVerbose("=== clbkScenarioChanged(%d) Event ===", e); + + // Acquire list of vessel visuals + // + Vessels.clear(); + + for (VOBJREC* pv = vobjFirst; pv; pv = pv->next) + if (pv->type == OBJTP_VESSEL) Vessels.insert((vVessel*)pv->vobj); + + // Update Attachment hierarchy + // + RootList.clear(); + for (auto v : Vessels) { + OBJHANDLE hRoot = v->GetInterface()->GetAttachmentRoot(); + v->vRoot = (vVessel*)GetVisObject(hRoot); + RootList.insert(v->vRoot); + } + + // Update eCam render list + // + eCamRenderList.clear(); + + // Render env-map for all root vessels in range + for (auto v : RootList) eCamRenderList.insert(v); + + // Render env-map for all vessels with user defined eCam setup, if enabled + if (Config->EnvMapFaces > 1) + for (auto v : Vessels) + if (v->HasOwnEnvCam(EnvCamType::Exterior)) eCamRenderList.insert(v); + + // Return vobjEnv iterator to start of the list + vobjEnv = eCamRenderList.begin(); +} + + +// =========================================================================================== +// +void Scene::clbkRenderMainScene() { _TRACE; @@ -1273,15 +1326,13 @@ void Scene::RenderMainScene() UpdateCamVis(); + set Active; + for (auto v : Vessels) if (v->IsActive()) Active.insert(v); + // Update Vessel Animations // - for (VOBJREC *pv = vobjFirst; pv; pv = pv->next) { - if (pv->type == OBJTP_VESSEL) { - vVessel *vv = (vVessel *)pv->vobj; - vv->UpdateAnimations(); - } - } + for (auto v : Active) v->UpdateAnimations(); if (vFocus == NULL) return; @@ -1305,9 +1356,7 @@ void Scene::RenderMainScene() if (Config->CustomCamMode == 0 && dwTurn == RENDERTURN_CUSTOMCAM) dwTurn++; if (Config->EnvMapMode == 0 && dwTurn == RENDERTURN_ENVCAM) dwTurn++; - if (!bIrrad && dwTurn == RENDERTURN_IRRADIANCE) dwTurn++; - - if (dwTurn>RENDERTURN_LAST) dwTurn = 0; + if (dwTurn > RENDERTURN_LAST) dwTurn = 0; int RenderCount = max(1, Config->EnvMapFaces); @@ -1344,54 +1393,25 @@ void Scene::RenderMainScene() // ------------------------------------------------------------------------------------------------------- - // Render Environmental Map For the Vessels - // ------------------------------------------------------------------------------------------------------- - - if (dwTurn == RENDERTURN_ENVCAM) { - - if (Config->EnvMapMode) { - DWORD flags = 0; - if (Config->EnvMapMode == 1) flags |= 0x01; - if (Config->EnvMapMode == 2) flags |= (0x03 | 0x20); - - if (vobjEnv == NULL) vobjEnv = vobjFirst; - - while (vobjEnv) { - if (vobjEnv->type == OBJTP_VESSEL && vobjEnv->apprad>8.0f) { - if (vobjEnv->vobj) { - vVessel *vVes = (vVessel *)vobjEnv->vobj; - if (vVes->RenderENVMap(pDevice, RenderCount, flags) == false) break; // Not yet done with this vessel - } - } - vobjEnv = vobjEnv->next; // Move to the next one - } - } - } - - - - // ------------------------------------------------------------------------------------------------------- - // Render Irradiance Map For Vessels + // Render reflection cube maps for vessels // ------------------------------------------------------------------------------------------------------- - if (dwTurn == RENDERTURN_IRRADIANCE) { - - if (Config->EnvMapMode && Config->bIrradiance) { - DWORD flags = 0; - if (Config->EnvMapMode == 1) flags |= 0x01; - if (Config->EnvMapMode == 2) flags |= (0x03 | 0x20); + if (dwTurn == RENDERTURN_ENVCAM && Config->EnvMapMode) + { + DWORD flags = 0; + if (Config->EnvMapMode == 1) flags |= 0x01; + if (Config->EnvMapMode == 2) flags |= (0x03 | 0x20); - if (vobjIrd == NULL) vobjIrd = vobjFirst; + if (vobjEnv == eCamRenderList.end()) vobjEnv = eCamRenderList.begin(); - while (vobjIrd) { - if (vobjIrd->type == OBJTP_VESSEL && vobjIrd->apprad>8.0f) { - if (vobjIrd->vobj) { - vVessel *vVes = (vVessel *)vobjIrd->vobj; - if (vVes->ProbeIrradiance(pDevice, RenderCount, flags) == false) break; // Not yet done with this vessel - } + while (vobjEnv != eCamRenderList.end()) { + auto vV = (*vobjEnv); + if (vV->IsVisible()) { + if (vV->CamDist() < 10e3) { + if (vV->ProcessEnvMaps(pDevice, RenderCount, flags) == false) break; } - vobjIrd = vobjIrd->next; // Move to the next one } + vobjEnv++; } } @@ -1408,15 +1428,11 @@ void Scene::RenderMainScene() RenderList.clear(); - for (pv = vobjFirst; pv; pv = pv->next) { - if (!pv->vobj->IsActive()) continue; - if (!pv->vobj->IsVisible()) continue; - if (pv->type == OBJTP_VESSEL) { - vVessel* vV = (vVessel*)pv->vobj; - RenderList.push_back(vV); - vV->bStencilShadow = true; - vV->BakeLights(pBakeLights); - } + for (auto vV : Active) { + if (!vV->IsVisible()) continue; + vV->bStencilShadow = true; + vV->BakeLights(pBakeLights); + RenderList.push_back(vV); } float znear_for_vessels = ComputeNearClipPlane(); @@ -1441,7 +1457,7 @@ void Scene::RenderMainScene() HR(pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, 0, 1.0f, 0L)); // Render vessels - for (auto* vVes : RenderList) vVes->Render(pDevice, false); + for (auto vVes : RenderList) vVes->Render(pDevice, false); // Render Cockpit if (oapiCameraInternal() && vFocus) vFocus->Render(pDevice, true); @@ -1522,12 +1538,8 @@ void Scene::RenderMainScene() // --------------------------------------------------------------------------------------------- Casters.clear(); - - for (pv = vobjFirst; pv; pv = pv->next) { - if (!pv->vobj->IsActive()) continue; - if (pv->type == OBJTP_VESSEL) Casters.push_back((vVessel *)pv->vobj); - } - + for (auto v : Active) Casters.push_back(v); + Casters.sort(sort_vessels); @@ -1913,27 +1925,16 @@ void Scene::RenderMainScene() // render exhausts // - for (pv=vobjFirst; pv; pv=pv->next) { - if (!pv->vobj->IsActive() || !pv->vobj->IsVisible() || pv->vobj->GetMeshCount() < 1) continue; - OBJHANDLE hObj = pv->vobj->Object(); - if (oapiGetObjectType(hObj) == OBJTP_VESSEL) { - ((vVessel*)pv->vobj)->RenderExhaust(); - } + for (auto v : Active) { + if (!v->IsVisible() || v->GetMeshCount() < 1) continue; + v->RenderExhaust(); } - // render beacons + // render beacons and grapple points // - for (pv=vobjFirst; pv; pv=pv->next) { - if (!pv->vobj->IsActive()) continue; - pv->vobj->RenderBeacons(pDevice); - } - - // render grapple points - // - for (pv=vobjFirst; pv; pv=pv->next) { - if (!pv->vobj->IsActive()) continue; - pv->vobj->RenderGrapplePoints(pDevice); - } + for (auto v : Active) v->RenderBeacons(pDevice); + for (auto v : Active) v->RenderGrapplePoints(pDevice); + // render exhaust particle system // @@ -2192,7 +2193,9 @@ void Scene::RenderMainScene() // if (bFreezeEnable) bFreeze = true; - + + bool bVC = oapiCameraInternal() && (oapiCockpitMode() == COCKPIT_VIRTUAL); + // ------------------------------------------------------------------------------------------------------- // EnvMap Debugger TODO: Should be allowed to visualize other maps as well, not just index 0 // ------------------------------------------------------------------------------------------------------- @@ -2204,22 +2207,40 @@ void Scene::RenderMainScene() switch (sel) { case 1: case 2: case 3: case 4: case 5: - VisualizeCubeMap(vFocus->GetEnvMap(ENVMAP_MAIN), sel - 1); + { + if (bVC) { + auto pE = emVC.pEnv; + if (pE) if (pE->GetType() == D3DRTYPE_CUBETEXTURE) + VisualizeCubeMap((LPDIRECT3DCUBETEXTURE9)pE, sel - 1); + } + else { + auto pE = vFocus->GetEnvMap()->pEnv; + if (pE) if (pE->GetType() == D3DRTYPE_CUBETEXTURE) + VisualizeCubeMap((LPDIRECT3DCUBETEXTURE9)pE, sel - 1); + } break; + } case 6: - VisualizeCubeMap(vFocus->GetIrradEnv(), 0); break; case 7: - VisualizeCubeMap(pIrradTemp, 0); break; case 8: VisualizeShadowMap(); break; case 9: - if (vFocus->GetIrradianceMap()) { - pSketch = GetPooledSketchpad(SKETCHPAD_2D_OVERLAY); - pSketch->CopyRectNative(vFocus->GetIrradianceMap(), NULL, 0, 0); - pSketch->EndDrawing(); + if (bVC) { + if (emVC.pIrrad) { + pSketch = GetPooledSketchpad(SKETCHPAD_2D_OVERLAY); + pSketch->CopyRectNative(emVC.pIrrad, NULL, 0, 0); + pSketch->EndDrawing(); + } + } + else { + if (vFocus->GetEnvMap()->pIrrad) { + pSketch = GetPooledSketchpad(SKETCHPAD_2D_OVERLAY); + pSketch->CopyRectNative(vFocus->GetEnvMap()->pIrrad, NULL, 0, 0); + pSketch->EndDrawing(); + } } break; case 10: @@ -2890,7 +2911,7 @@ bool Scene::RenderBlurredMap(LPDIRECT3DDEVICE9 pDev, LPDIRECT3DCUBETEXTURE9 pSrc LPDIRECT3DSURFACE9 pSrf = NULL; LPDIRECT3DSURFACE9 pTmp = NULL; - // Create clurred mip sub-levels + // Copy Src to Temp // for (DWORD i = 0; i < 6; i++) { pSrc->GetCubeMapSurface(D3DCUBEMAP_FACES(i), 0, &pSrf); @@ -2901,7 +2922,7 @@ bool Scene::RenderBlurredMap(LPDIRECT3DDEVICE9 pDev, LPDIRECT3DCUBETEXTURE9 pSrc } - // Create clurred mip sub-levels + // Create blurred mip sub-levels // for (int mip = 1; mip < 5; mip++) { @@ -2965,86 +2986,126 @@ bool Scene::RenderBlurredMap(LPDIRECT3DDEVICE9 pDev, LPDIRECT3DCUBETEXTURE9 pSrc // =========================================================================================== // -bool Scene::IntegrateIrradiance(vVessel *vV, LPDIRECT3DCUBETEXTURE9 pSrc, LPDIRECT3DTEXTURE9 pOut) +bool Scene::RenderBlurredMap(LPDIRECT3DDEVICE9 pDev, LPDIRECT3DTEXTURE9 pSrc) { + bool bQuality = true; + if (!pSrc) return false; - if (!pIrradiance) { - pIrradiance = new ImageProcessing(pDevice, "Modules/D3D9Client/IrradianceInteg.hlsl", "PSPreInteg"); - pIrradiance->CompileShader("PSInteg"); - pIrradiance->CompileShader("PSPostBlur"); + if (!pBlur2D) { + pBlur2D = new ImageProcessing(pDev, "Modules/D3D9Client/EnvMapBlur.hlsl", "PS2DBlur"); } - if (!pIrradiance->IsOK()) { - LogErr("pIrradiance is not OK"); + if (!pBlur2D->IsOK()) { + LogErr("pBlur is not OK"); return false; } - if (!pIrradDS) { - LogErr("pIrradDS doesn't exists"); + if (!pEnvDS) { + LogErr("EnvDepthStencil doesn't exists"); return false; } - LPDIRECT3DSURFACE9 pOuts = NULL; - HR(pOut->GetSurfaceLevel(0, &pOuts)); + D3DSURFACE_DESC desc; + pEnvDS->GetDesc(&desc); + DWORD width = min((UINT)512, desc.Width); + DWORD height = min((UINT)512, desc.Height); - D3DSURFACE_DESC desc, desc_out; - pIrradDS->GetDesc(&desc); - pOuts->GetDesc(&desc_out); - - if (!pIrradTemp) { - if (D3DXCreateCubeTexture(pDevice, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &pIrradTemp) != S_OK) { - LogErr("Failed to create irradiance temp"); - return false; - } - if (D3DXCreateTexture(pDevice, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &pIrradTemp2) != S_OK) { - LogErr("Failed to create irradiance temp"); - return false; - } - if (D3DXCreateTexture(pDevice, desc_out.Width, desc_out.Height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &pIrradTemp3) != S_OK) { - LogErr("Failed to create irradiance temp"); - return false; - } + if (!pBlrTemp2D[0]) { + if (D3DXCreateTexture(pDev, width >> 0, height >> 0, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pBlrTemp2D[0]) != S_OK) return false; + if (D3DXCreateTexture(pDev, width >> 1, height >> 1, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pBlrTemp2D[1]) != S_OK) return false; + if (D3DXCreateTexture(pDev, width >> 2, height >> 2, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pBlrTemp2D[2]) != S_OK) return false; + if (D3DXCreateTexture(pDev, width >> 3, height >> 3, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pBlrTemp2D[3]) != S_OK) return false; + if (D3DXCreateTexture(pDev, width >> 4, height >> 4, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pBlrTemp2D[4]) != S_OK) return false; } - D3DXVECTOR3 nr, up, cp; LPDIRECT3DSURFACE9 pSrf = NULL; - LPDIRECT3DSURFACE9 pTgt = NULL; - LPDIRECT3DSURFACE9 pTmp2 = NULL; - LPDIRECT3DSURFACE9 pTmp3 = NULL; - - HR(pIrradTemp2->GetSurfaceLevel(0, &pTmp2)); - HR(pIrradTemp3->GetSurfaceLevel(0, &pTmp3)); + LPDIRECT3DSURFACE9 pTmp = NULL; + // Copy Src to Temp + // + pSrc->GetSurfaceLevel(0, &pSrf); + pBlrTemp2D[0]->GetSurfaceLevel(0, &pTmp); + pDevice->StretchRect(pSrf, NULL, pTmp, NULL, D3DTEXF_POINT); + SAFE_RELEASE(pSrf); + SAFE_RELEASE(pTmp); - // --------------------------------------------------------------------- - // Pre-Integrate Irradiance Cube + // Create blurred mip sub-levels // - pIrradiance->Activate("PSPreInteg"); - pIrradiance->SetFloat("fD", ptr(D3DXVECTOR2(1.0f / float(desc.Width), 1.0f / float(desc.Height))), sizeof(D3DXVECTOR2)); + for (int mip = 1; mip < 5; mip++) { - for (DWORD i = 0; i < 6; i++) - { - pSrc->GetCubeMapSurface(D3DCUBEMAP_FACES(i), 0, &pSrf); - pIrradTemp->GetCubeMapSurface(D3DCUBEMAP_FACES(i), 0, &pTgt); - - pDevice->StretchRect(pSrf, NULL, pTmp2, NULL, D3DTEXF_POINT); + pBlur2D->SetFloat("fD", (4.0f / float(256 >> (mip - 1)))); + pBlur2D->SetBool("bDir", false); + pBlur2D->SetTextureNative("tTex", pBlrTemp2D[mip - 1], IPF_LINEAR); - pIrradiance->SetOutputNative(0, pTgt); - pIrradiance->SetTextureNative("tSrc", pIrradTemp2, IPF_POINT | IPF_CLAMP); + pSrc->GetSurfaceLevel(mip, &pSrf); + pBlur2D->SetOutputNative(0, pSrf); + + if (!pBlur2D->Execute(true)) { + LogErr("pBlur2D Execute Failed"); + return false; + } - if (!pIrradiance->Execute(true)) { - LogErr("pIrradiance Execute Failed"); + pBlrTemp2D[mip - 1]->GetSurfaceLevel(0, &pTmp); + pDevice->StretchRect(pSrf, NULL, pTmp, NULL, D3DTEXF_POINT); + SAFE_RELEASE(pTmp); + + pBlur2D->SetBool("bDir", true); + pSrc->GetSurfaceLevel(mip, &pSrf); + pBlur2D->SetOutputNative(0, pSrf); + + if (!pBlur2D->Execute(true)) { + LogErr("pBlur Execute Failed"); return false; } - SAFE_RELEASE(pTgt); + pBlrTemp2D[mip]->GetSurfaceLevel(0, &pTmp); + pDevice->StretchRect(pSrf, NULL, pTmp, NULL, D3DTEXF_POINT); + SAFE_RELEASE(pTmp); SAFE_RELEASE(pSrf); } - + return true; +} + +// =========================================================================================== +// +bool Scene::IntegrateIrradiance(vVessel *vV, LPDIRECT3DBASETEXTURE9 pIn, LPDIRECT3DTEXTURE9 pOut) +{ + if (!pIn) return false; + if (pIn->GetType() != D3DRTYPE_CUBETEXTURE) return false; + + LPDIRECT3DCUBETEXTURE9 pSrc = (LPDIRECT3DCUBETEXTURE9)pIn; + + if (!pIrradiance) { + pIrradiance = new ImageProcessing(pDevice, "Modules/D3D9Client/IrradianceInteg.hlsl", "PSInteg"); + pIrradiance->CompileShader("PSPostBlur"); + } + + if (!pIrradiance->IsOK()) { + LogErr("pIrradiance is not OK"); + return false; + } + + D3DSURFACE_DESC desc; + LPDIRECT3DSURFACE9 pOuts = NULL; + + HR(pOut->GetSurfaceLevel(0, &pOuts)); + HR(pOuts->GetDesc(&desc)); + + + D3DXVECTOR3 nr, up, cp; + LPDIRECT3DSURFACE9 pTmp = NULL; + if (!pIrradTemp) { + if (D3DXCreateTexture(pDevice, desc.Width, desc.Height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pIrradTemp) != S_OK) { + LogErr("Failed to create irradiance temp"); + return false; + } + } + HR(pIrradTemp->GetSurfaceLevel(0, &pTmp)); + // --------------------------------------------------------------------- // Main Integration // @@ -3053,8 +3114,9 @@ bool Scene::IntegrateIrradiance(vVessel *vV, LPDIRECT3DCUBETEXTURE9 pSrc, LPDIRE float Glow = float(Config->PlanetGlow); pIrradiance->Activate("PSInteg"); - pIrradiance->SetOutputNative(0, pTmp3); - pIrradiance->SetTextureNative("tCube", pIrradTemp, IPF_LINEAR); + pIrradiance->SetOutputNative(0, pTmp); + pIrradiance->SetTextureNative("tCube", pSrc, IPF_LINEAR); + pIrradiance->SetTextureNative("tRandom", ptRandom, IPF_POINT); pIrradiance->SetFloat("Kernel", IKernel, sizeof(IKernel)); pIrradiance->SetFloat("vNr", &nr, sizeof(D3DXVECTOR3)); pIrradiance->SetFloat("vUp", &up, sizeof(D3DXVECTOR3)); @@ -3076,21 +3138,21 @@ bool Scene::IntegrateIrradiance(vVessel *vV, LPDIRECT3DCUBETEXTURE9 pSrc, LPDIRE return false; } + SAFE_RELEASE(pTmp); + // --------------------------------------------------------------------- // Post Blur // pIrradiance->Activate("PSPostBlur"); - pIrradiance->SetFloat("fD", ptr(D3DXVECTOR2(1.0f / float(desc_out.Width), 1.0f / float(desc_out.Height))), sizeof(D3DXVECTOR2)); + pIrradiance->SetFloat("fD", ptr(D3DXVECTOR2(1.0f / float(desc.Width), 1.0f / float(desc.Height))), sizeof(D3DXVECTOR2)); pIrradiance->SetOutputNative(0, pOuts); - pIrradiance->SetTextureNative("tSrc", pIrradTemp3, IPF_POINT | IPF_WRAP); + pIrradiance->SetTextureNative("tSrc", pIrradTemp, IPF_POINT | IPF_WRAP); if (!pIrradiance->Execute(true)) { LogErr("pIrradiance Execute Failed"); return false; } - SAFE_RELEASE(pTmp2); - SAFE_RELEASE(pTmp3); SAFE_RELEASE(pOuts); return true; @@ -3307,21 +3369,6 @@ void Scene::RenderObjectMarker(oapi::Sketchpad *pSkp, const VECTOR3 &gpos, const m_celSphere->RenderMarker(pSkp, dp, label1, label2, mode, scale); } -// =========================================================================================== -// -void Scene::NewVessel(OBJHANDLE hVessel) -{ - CheckVisual(hVessel); -} - -// =========================================================================================== -// -void Scene::DeleteVessel(OBJHANDLE hVessel) -{ - VOBJREC *pv = FindVisual(hVessel); - if (pv) DelVisualRec(pv); -} - // =========================================================================================== // void Scene::AddParticleStream (class D3D9ParticleStream *_pstream) diff --git a/OVP/D3D9Client/Scene.h b/OVP/D3D9Client/Scene.h index 22b09aa62..bdb767f84 100644 --- a/OVP/D3D9Client/Scene.h +++ b/OVP/D3D9Client/Scene.h @@ -28,6 +28,7 @@ class vObject; class vPlanet; +class vVessel; class D3D9ParticleStream; class D3D9Text; class D3D9Pad; @@ -59,8 +60,7 @@ class D3D9Pad; #define RENDERTURN_ENVCAM 0 #define RENDERTURN_CUSTOMCAM 1 -#define RENDERTURN_IRRADIANCE 2 -#define RENDERTURN_LAST 2 +#define RENDERTURN_LAST 1 #define SMAP_MODE_FOCUS 1 #define SMAP_MODE_SCENE 2 @@ -107,8 +107,14 @@ class Scene { void* pUser; }; + ENVMAPS emVC; + + std::set RootList; + std::set Vessels; + std::set eCamRenderList; std::set CustomCams; - std::set::const_iterator camCurrent{}; + std::set::const_iterator camCurrent = {}; + std::set::const_iterator vobjEnv = {}; // Camera frustum parameters ======================================================== // @@ -173,7 +179,34 @@ class Scene { //inline const oapi::D3D9Client *GetClient() const { return gc; } inline oapi::D3D9Client *GetClient() const { return gc; } - void OnOptionChanged(int cat, int item); + + void clbkOnOptionChanged(int cat, int item); + void clbkScenarioChanged(OBJHANDLE hV, ScnChgEvent e); + void clbkInitialise(); + + /** + * \brief Update camera position, visuals, etc. + */ + void clbkUpdate(); + + /** + * \brief Render the whole main scene + */ + void clbkRenderMainScene(); + + /** + * \brief Create a visual for a new vessel if within visual range. + * \param hVessel vessel object handle + */ + void clbkNewVessel(OBJHANDLE hVessel); + + /** + * \brief Delete a vessel visual prior to destruction of the logical vessel. + * \param hVessel vessel object handle + */ + void clbkDeleteVessel(OBJHANDLE hVessel); + + const D3D9Sun *GetSun() const { return &sunLight; } const D3D9Light *GetLight(int index) const; @@ -208,18 +241,9 @@ class Scene { inline const DWORD ViewH() const { return viewH; } void UpdateCamVis(); - void Initialise (); - - /** - * \brief Update camera position, visuals, etc. - */ - void Update(); - - /** - * \brief Render the whole main scene - */ - void RenderMainScene(); + + /** * \brief Returns screen space sun visual parameters for Lens Flare rendering. */ @@ -237,11 +261,11 @@ class Scene { int RenderShadowMap(D3DXVECTOR3& pos, D3DXVECTOR3& ld, float rad, bool bInternal = false, bool bListExists = false); int RenderVCShadowMap(D3DXVECTOR3& cdir, D3DXVECTOR3& ld, bool bListExists = false); - bool IntegrateIrradiance(vVessel *vV, LPDIRECT3DCUBETEXTURE9 pSrc, LPDIRECT3DTEXTURE9 pOut); + bool IntegrateIrradiance(vVessel *vV, LPDIRECT3DBASETEXTURE9 pSrc, LPDIRECT3DTEXTURE9 pOut); bool RenderBlurredMap(LPDIRECT3DDEVICE9 pDev, LPDIRECT3DCUBETEXTURE9 pSrc); + bool RenderBlurredMap(LPDIRECT3DDEVICE9 pDev, LPDIRECT3DTEXTURE9 pSrc); void RenderMesh(DEVMESHHANDLE hMesh, const oapi::FMATRIX4 *pWorld); - LPDIRECT3DSURFACE9 GetIrradianceDepthStencil() const { return pIrradDS; } LPDIRECT3DSURFACE9 GetEnvDepthStencil() const { return pEnvDS; } LPDIRECT3DSURFACE9 GetBuffer(int id) const { return psgBuffer[id]; } LPDIRECT3DTEXTURE9 GetSunTexture() const { return pSunTex; } @@ -258,17 +282,7 @@ class Scene { */ void RenderVesselShadows(OBJHANDLE hPlanet, float depth) const; - /** - * \brief Create a visual for a new vessel if within visual range. - * \param hVessel vessel object handle - */ - void NewVessel (OBJHANDLE hVessel); - - /** - * \brief Delete a vessel visual prior to destruction of the logical vessel. - * \param hVessel vessel object handle - */ - void DeleteVessel (OBJHANDLE hVessel); + void AddParticleStream (class D3D9ParticleStream *_pstream); void DelParticleStream (DWORD idx); @@ -489,11 +503,10 @@ class Scene { SurfNative *pLblSrf; - class ImageProcessing *pLightBlur, *pBlur, *pGDIOverlay, *pIrradiance, *pVisDepth, *pCreateGlare, *pBakeLights; + class ImageProcessing *pLightBlur, *pBlur, *pBlur2D, *pGDIOverlay, *pIrradiance, *pVisDepth, *pCreateGlare, *pBakeLights; class ShaderClass *pLocalCompute, *pRenderGlares; class vVessel *vFocus; - VOBJREC *vobjEnv, *vobjIrd; double dVisualAppRad; FVECTOR2 DepthSampleKernel[57]; @@ -504,8 +517,8 @@ class Scene { // Blur Sampling Kernel ============================================================== LPDIRECT3DCUBETEXTURE9 pBlrTemp[5]; - LPDIRECT3DCUBETEXTURE9 pIrradTemp; - LPDIRECT3DTEXTURE9 pIrradTemp2, pIrradTemp3; + LPDIRECT3DTEXTURE9 pBlrTemp2D[5]; + LPDIRECT3DTEXTURE9 pIrradTemp, ptRandom; // Deferred Experiment =============================================================== // @@ -514,7 +527,7 @@ class Scene { LPDIRECT3DSURFACE9 pOffscreenTarget; LPDIRECT3DTEXTURE9 pTextures[TEX_COUNT]; - LPDIRECT3DSURFACE9 pEnvDS, pIrradDS, pDepthNormalDS; + LPDIRECT3DSURFACE9 pEnvDS, pDepthNormalDS; LPDIRECT3DSURFACE9 psShmDS[SHM_LOD_COUNT]; LPDIRECT3DSURFACE9 psShmRT[SHM_LOD_COUNT]; LPDIRECT3DTEXTURE9 ptShmRT[SHM_LOD_COUNT]; diff --git a/OVP/D3D9Client/VBase.cpp b/OVP/D3D9Client/VBase.cpp index a748e7a12..87b1f8413 100644 --- a/OVP/D3D9Client/VBase.cpp +++ b/OVP/D3D9Client/VBase.cpp @@ -400,7 +400,7 @@ bool vBase::RenderSurface(LPDIRECT3DDEVICE9 dev) if (nstructure_bs) { for (DWORD i = 0; i < nstructure_bs; ++i) { structure_bs[i]->SetSunLight(&sunLight); - structure_bs[i]->Render(&mWorld, RENDER_BASEBS); + structure_bs[i]->Render(&mWorld, nullptr, RENDER_BASEBS); ++uCurrentMesh; } } @@ -428,7 +428,7 @@ bool vBase::RenderStructures(LPDIRECT3DDEVICE9 dev) FVECTOR3 qw = TransformCoord(bs, mWorld); D3D9Sun sp = vP->GetObjectAtmoParams(qw._V() + vP->CameraPos()); structure_as[i]->SetSunLight(&sp); - structure_as[i]->Render(&mWorld, RENDER_BASE); + structure_as[i]->Render(&mWorld, nullptr, RENDER_BASE); ++uCurrentMesh; } return true; diff --git a/OVP/D3D9Client/VPlanet.cpp b/OVP/D3D9Client/VPlanet.cpp index 4c25e5cdf..95b2e1c4b 100644 --- a/OVP/D3D9Client/VPlanet.cpp +++ b/OVP/D3D9Client/VPlanet.cpp @@ -1013,7 +1013,7 @@ bool vPlanet::Render(LPDIRECT3DDEVICE9 dev) if (mesh) { mesh->SetSunLight(scn->GetSun()); - mesh->Render(&mWorld, RENDER_ASTEROID); + mesh->RenderFast(&mWorld, RENDER_ASTEROID); } else { RenderSphere (dev); } diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index ed8eb2a38..529f74c09 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -54,17 +54,10 @@ vVessel::vVessel(OBJHANDLE _hObj, const Scene *scene): vObject (_hObj, scene) vessel = oapiGetVesselInterface(_hObj); nmesh = 0; - nEnv = 0; - iFace = 0; - eFace = 0; sunLight = *scene->GetSun(); tCheckLight = oapiGetSimTime()-1.0; vClass = 0; - pIrrad = NULL; - pIrdEnv = NULL; - pMatMgr = new MatMgr(this, scene->GetClient()); - for (int i = 0; i < ARRAYSIZE(pEnv); i++) pEnv[i] = NULL; if (strncmp(vessel->GetClassNameA(), "XR2Ravenstar", 12) == 0) vClass = VCLASS_XR2; if (strncmp(vessel->GetClassNameA(), "SpaceShuttleUltra", 17) == 0) vClass = VCLASS_ULTRA; @@ -82,6 +75,19 @@ vVessel::vVessel(OBJHANDLE _hObj, const Scene *scene): vObject (_hObj, scene) currentstate[i] = anim[i].defstate; if (Config->bAbsAnims) for (UINT k = 0; k < anim[i].ncomp; ++k) StoreDefaultState(anim[i].comp[k]); } + + // Initialize default eCams; + // + ecDefExt.flags = ENVCAM_OMIT_ATTC | ENVCAM_DEFAULT; + ecDefExt.type = EnvCamType::Exterior; + + ecDefVC.flags = ENVCAM_DEFAULT; + ecDefVC.type = EnvCamType::VC; + + D3DXVECTOR3 pos; + if (GetVCPos(nullptr, &pos, nullptr)) { + ecDefVC.lPos = pos; + } /* oapiWriteLogV("%s", vessel->GetClassNameA()); @@ -101,14 +107,15 @@ vVessel::vVessel(OBJHANDLE _hObj, const Scene *scene): vObject (_hObj, scene) vVessel::~vVessel () { SAFE_DELETE(pMatMgr); - SAFE_RELEASE(pIrrad); - SAFE_RELEASE(pIrdEnv); - - for (int i = 0; i < ARRAYSIZE(pEnv); i++) SAFE_RELEASE(pEnv[i]); - LogAlw("Deleting Vessel Visual %s ...", _PTR(this)); DisposeAnimations(); DisposeMeshes(); + + SAFE_RELEASE(ecDefVC.tex.pEnv); + SAFE_RELEASE(ecDefVC.tex.pIrrad); + SAFE_RELEASE(ecDefExt.tex.pEnv); + SAFE_RELEASE(ecDefExt.tex.pIrrad); + LogAlw("Vessel visual deleted succesfully"); } @@ -652,44 +659,71 @@ void vVessel::GetMinMaxLightDist(float *mind, float *maxd) // ============================================================================================ // -bool vVessel::GetVCPos(D3DXVECTOR3* out, float* rad) +bool vVessel::GetVCPos(D3DXVECTOR3* cpos, D3DXVECTOR3* lpos, float* rad) { for (int i = 0; i < nmesh; i++) { if (!meshlist[i].mesh) continue; - if (meshlist[i].mesh->MeshFlags & MESHFLAG_VC) { - D3DXVECTOR3 pos = meshlist[i].mesh->GetBoundingSpherePos(); - - if (meshlist[i].trans) - { - D3DXMATRIX mWT; - D3DXMatrixMultiply(&mWT, (const D3DXMATRIX*)meshlist[i].trans, &mWorld); - D3DXVec3TransformCoord(&pos, &pos, &mWT); - } - else D3DXVec3TransformCoord(&pos, &pos, &mWorld); - if (out) *out = pos; - if (rad) *rad = meshlist[i].mesh->GetBoundingSphereRadius(); - return true; - } + return GetMeshPosition(i, cpos, lpos, rad); + } } return false; } +// ============================================================================================ +// +bool vVessel::GetMeshPosition(int idx, D3DXVECTOR3* cpos, D3DXVECTOR3* lpos, float* rad) +{ + if (!meshlist[idx].mesh) return false; + + D3DXVECTOR3 pos = meshlist[idx].mesh->GetBoundingSpherePos(); + if (rad) *rad = meshlist[idx].mesh->GetBoundingSphereRadius(); + + if (meshlist[idx].trans) + { + D3DXVec3TransformCoord(&pos, &pos, meshlist[idx].trans); + if (lpos) *lpos = pos; + if (cpos) D3DXVec3TransformCoord(&pos, &pos, &mWorld); + } + else { + if (lpos) *lpos = pos; + if (cpos) D3DXVec3TransformCoord(&pos, &pos, &mWorld); + } + if (cpos) *cpos = pos; + return true; +} + + // ============================================================================================ // void vVessel::BakeLights(ImageProcessing *pBaker) { + OBJHANDLE hGRef = vessel->GetGravityRef(); + + MATRIX3 grot; VECTOR3 rpos; LVLH lvlh; + oapiGetRotationMatrix(hGRef, &grot); + vessel->GetRelativePos(hGRef, rpos); + + FMATRIX4 mW(mWorld); + FVECTOR3 polaraxis = mul(grot, _V(0, 1, 0)); + lvlh.Up = unit(rpos); + lvlh.East = unit(cross(polaraxis, lvlh.Up)); + lvlh.North = unit(cross(lvlh.Up, lvlh.East)); + lvlh.Up = tmul(FVECTOR4(lvlh.Up, 0), mW).xyz; + lvlh.East = tmul(FVECTOR4(lvlh.East, 0), mW).xyz; + lvlh.North = tmul(FVECTOR4(lvlh.North, 0), mW).xyz; + for (int i = 0; i < nmesh; i++) { if (!meshlist[i].mesh) continue; if (meshlist[i].vismode & MESHVIS_VC) { - auto vSun = tmul(FVECTOR4(sundir, 0), oapi::FMATRIX4(mWorld)); + auto vSun = tmul(FVECTOR4(sundir, 0), mW); meshlist[i].mesh->BakeLights(pBaker); - meshlist[i].mesh->BakeAO(pBaker, vSun.xyz); + meshlist[i].mesh->BakeAO(pBaker, vSun.xyz, lvlh, ecDefExt.tex.pIrrad); } } } @@ -780,8 +814,6 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass) HR(D3D9Effect::FX->SetBool(D3D9Effect::eShadowToggle, false)); } - HR(D3D9Effect::FX->SetTexture(D3D9Effect::eIrradMap, pIrrad)); - // Check VC MFD screen resolutions ------------------------------------------------ // if (bVC && internalpass) { @@ -872,8 +904,8 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass) meshlist[i].mesh->RenderShadowMap(pWT, pVP, 1); } else { - if (internalpass) meshlist[i].mesh->Render(pWT, RENDER_VC, NULL, 0); - else meshlist[i].mesh->Render(pWT, RENDER_VESSEL, pEnv, nEnv); + if (internalpass) meshlist[i].mesh->Render(pWT, &(scn->emVC), RENDER_VC); + else meshlist[i].mesh->Render(pWT, GetEnvMap(), RENDER_VESSEL); } @@ -1196,17 +1228,17 @@ void vVessel::RenderGroundShadow(LPDIRECT3DDEVICE9 dev, OBJHANDLE hPlanet, float } } + // ============================================================================================ // Return true if it's time to move to a next vessel // false, if more rendereing is required here. // -bool vVessel::RenderENVMap(LPDIRECT3DDEVICE9 pDev, DWORD cnt, DWORD flags) +bool vVessel::ProcessEnvMaps(LPDIRECT3DDEVICE9 pDev, DWORD cnt, DWORD flags) { - bool bReflective = false; if (meshlist) { - for (DWORD i=0;iIsReflective()) { bReflective = true; @@ -1216,8 +1248,22 @@ bool vVessel::RenderENVMap(LPDIRECT3DDEVICE9 pDev, DWORD cnt, DWORD flags) } } - if (!bReflective) return true; + if (!bReflective) return true; // If none of the meshes are reflective then we are done + + // Render vessel specific map + bool bRet = RenderENVMap(pDev, &ecDefExt, cnt, flags); + + if (bRet) ecDefExt.bRendered = false; + + return bRet; +} + +// ============================================================================================ +// Render Env Map, return 'true' if the map is completed +// +bool vVessel::RenderENVMap(LPDIRECT3DDEVICE9 pDev, ENVCAMREC* ec, DWORD cnt, DWORD flags) +{ LPDIRECT3DSURFACE9 pEnvDS = GetScene()->GetEnvDepthStencil(); if (!pEnvDS) { @@ -1225,70 +1271,105 @@ bool vVessel::RenderENVMap(LPDIRECT3DDEVICE9 pDev, DWORD cnt, DWORD flags) return true; } + // Create a EnvMap if doesn't already exists -------------------------------------------------------------------- + // + LPDIRECT3DCUBETEXTURE9 pCube = nullptr; + LPDIRECT3DTEXTURE9 pTex = nullptr; + LPDIRECT3DTEXTURE9 pIrrad = nullptr; - // Create a main EnvMap with mipmap chain for blurred maps -------------------------------------------------------------------- + if (ec->tex.pEnv) // If the maps exists check the type and assign + { + if (ec->tex.pEnv->GetType() == D3DRTYPE_CUBETEXTURE) pCube = (LPDIRECT3DCUBETEXTURE9)ec->tex.pEnv; + if (ec->tex.pEnv->GetType() == D3DRTYPE_TEXTURE) pTex = (LPDIRECT3DTEXTURE9)ec->tex.pEnv; + } + else // Map doesn't exists, then create one + { + if (ec->flags & ENVCAM_PLANE) + { + D3DSURFACE_DESC desc; + pEnvDS->GetDesc(&desc); + if (D3DXCreateTexture(pDev, desc.Width, desc.Height, 5, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pTex) != S_OK) { + LogErr("Failed to create env-plane for visual %s", _PTR(this)); + return true; + } + ec->tex.pEnv = pTex; + } + else + { + D3DSURFACE_DESC desc; + pEnvDS->GetDesc(&desc); + if (D3DXCreateCubeTexture(pDev, desc.Width, 5, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pCube) != S_OK) { + LogErr("Failed to create env-cubemap for visual %s", _PTR(this)); + return true; + } + ec->tex.pEnv = pCube; + } + } + + + // Create a Irradiance map if doesn't already exists -------------------------------------------------------------------- // - if (pEnv[ENVMAP_MAIN] == NULL) { - D3DSURFACE_DESC desc; - pEnvDS->GetDesc(&desc); - if (D3DXCreateCubeTexture(pDev, desc.Width, 5, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pEnv[ENVMAP_MAIN]) != S_OK) { - LogErr("Failed to create env cubemap for visual %s", _PTR(this)); + if (ec->tex.pIrrad) + { + pIrrad = ec->tex.pIrrad; + } + else + { + if (D3DXCreateTexture(pDev, 128, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pIrrad) != S_OK) { + LogErr("Failed to create irradiance map for visual %s", _PTR(this)); return true; } - nEnv++; + ec->tex.pIrrad = pIrrad; } - // Create blurred maps ------------------------------------------------------------------------------- + + // Create blurred maps and irradiance --------------------------------------------------------------------- // - if (eFace >= 6) { - eFace = 0; - scn->RenderBlurredMap(pDev, pEnv[ENVMAP_MAIN]); + if (ec->bRendered) { + if (pCube) { + scn->RenderBlurredMap(pDev, pCube); + scn->IntegrateIrradiance(this, pCube, pIrrad); + } + if (pTex) { + scn->RenderBlurredMap(pDev, pTex); + SAFE_RELEASE(ec->tex.pIrrad); + } return true; } - double tot_env = D3D9GetTime(); - - // Render EnvMaps --------------------------------------------------------------------------------------- // - - std::set RndList = scn->GetVessels(10e3, true); - std::set AddLightSrc; + std::set RndList = scn->GetVessels(10e3, true); + std::set AddLightSrc; AddLightSrc.insert(this); - ENVCAMREC *eCam = pMatMgr->GetCamera(0); - - if ((eCam->flags&ENVCAM_FOCUS) == 0) RndList.erase(this); + if ((ec->flags & ENVCAM_FOCUS) == 0) RndList.erase(this); DWORD nAtc = vessel->AttachmentCount(false); DWORD nDoc = vessel->DockCount(); - if (eCam->flags & ENVCAM_OMIT_ATTC) { - for (DWORD i=0;iflags & ENVCAM_OMIT_ATTC) { + for (DWORD i = 0; i < nAtc; i++) { ATTACHMENTHANDLE hAtc = vessel->GetAttachmentHandle(false, i); if (hAtc) { OBJHANDLE hAtcObj = vessel->GetAttachmentStatus(hAtc); if (hAtcObj) { - vObject *vObj = gc->GetScene()->GetVisObject(hAtcObj); - if (vObj) RndList.erase((vVessel *)vObj); + vObject* vObj = gc->GetScene()->GetVisObject(hAtcObj); + if (vObj) RndList.erase((vVessel*)vObj); } } } } else { - - DWORD nAttc = eCam->nAttc; - - for (DWORD i=0;ipOmitAttc[i]); + for (auto id : ec->omitAttc) { ATTACHMENTHANDLE hAtc = vessel->GetAttachmentHandle(false, id); if (hAtc) { OBJHANDLE hAtcObj = vessel->GetAttachmentStatus(hAtc); if (hAtcObj) { - vObject *vObj = gc->GetScene()->GetVisObject(hAtcObj); - if (vObj) RndList.erase((vVessel *)vObj); + vObject* vObj = gc->GetScene()->GetVisObject(hAtcObj); + if (vObj) RndList.erase((vVessel*)vObj); } } } @@ -1298,167 +1379,121 @@ bool vVessel::RenderENVMap(LPDIRECT3DDEVICE9 pDev, DWORD cnt, DWORD flags) // ----------------------------------------------------------------------------------------------- // VECTOR3 gpos; - vessel->Local2Global(_V(eCam->lPos.x, eCam->lPos.y, eCam->lPos.z), gpos); + vessel->Local2Global(_V(ec->lPos.x, ec->lPos.y, ec->lPos.z), gpos); - // Prepare camera and scene for env map rendering - scn->PushCamera(); - scn->SetupInternalCamera(NULL, &gpos, 0.7853981634, 1.0); - scn->BeginPass(RENDERPASS_ENVCAM); + if (pCube) + { + // Prepare camera and scene for env map rendering + scn->PushCamera(); + scn->SetupInternalCamera(NULL, &gpos, 0.7853981634, 1.0); + scn->BeginPass(RENDERPASS_ENVCAM); + gc->PushRenderTarget(NULL, pEnvDS, RENDERPASS_ENVCAM); - gc->PushRenderTarget(NULL, pEnvDS, RENDERPASS_ENVCAM); + D3DXMATRIX mEnv; + D3DXVECTOR3 dir, up; + LPDIRECT3DSURFACE9 pSrf = NULL; - D3DXMATRIX mEnv; - D3DXVECTOR3 dir, up; - LPDIRECT3DSURFACE9 pSrf = NULL; + for (DWORD i = 0; i < cnt; i++) { + HR(pCube->GetCubeMapSurface(D3DCUBEMAP_FACES(ec->iSide), 0, &pSrf)); - for (DWORD i=0;iAlterRenderTarget(pSrf, pEnvDS); - HR(pEnv[ENVMAP_MAIN]->GetCubeMapSurface(D3DCUBEMAP_FACES(eFace), 0, &pSrf)); - - gc->AlterRenderTarget(pSrf, pEnvDS); + EnvMapDirection(ec->iSide, &dir, &up); + + D3DXVECTOR3 cp; + D3DXVec3Cross(&cp, &up, &dir); + D3DXVec3Normalize(&cp, &cp); + D3DXMatrixIdentity(&mEnv); + D3DMAT_FromAxis(&mEnv, &cp, &up, &dir); - EnvMapDirection(eFace, &dir, &up); + scn->SetCameraFrustumLimits(0.25, 1e8); + scn->SetupInternalCamera(&mEnv, NULL, 0.7853981634, 1.0); + scn->RenderSecondaryScene(RndList, AddLightSrc, flags); - D3DXVECTOR3 cp; - D3DXVec3Cross(&cp, &up, &dir); - D3DXVec3Normalize(&cp, &cp); - D3DXMatrixIdentity(&mEnv); - D3DMAT_FromAxis(&mEnv, &cp, &up, &dir); + SAFE_RELEASE(pSrf); - scn->SetCameraFrustumLimits(0.25, 1e8); - scn->SetupInternalCamera(&mEnv, NULL, 0.7853981634, 1.0); - scn->RenderSecondaryScene(RndList, AddLightSrc, flags); + ec->iSide++; - SAFE_RELEASE(pSrf); + if (ec->iSide >= 6) { + ec->bRendered = true; + ec->iSide = 0; + break; + } + } - eFace++; - if (eFace >= 6) break; + gc->PopRenderTargets(); + scn->PopPass(); + scn->PopCamera(); + + return false; } - gc->PopRenderTargets(); - scn->PopPass(); - scn->PopCamera(); + if (pTex) + { + // TODO: + return true; + } - return false; + return true; } - // ============================================================================================ -// Return true if it's time to move to a next vessel -// false, if more rendereing is required here. +// Return env-map for debug purposes // -bool vVessel::ProbeIrradiance(LPDIRECT3DDEVICE9 pDev, DWORD cnt, DWORD flags) +ENVMAPS *vVessel::GetEnvMap() { - - LPDIRECT3DSURFACE9 pIrDS = GetScene()->GetIrradianceDepthStencil(); - - if (!pIrDS) return true; // Feature disabled - - - // Create a main EnvMap with mipmap chain for blurred maps -------------------------------------------------------------------- - // - if (pIrdEnv == NULL) - { - D3DSURFACE_DESC desc; - pIrDS->GetDesc(&desc); - if (D3DXCreateCubeTexture(pDev, desc.Width, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &pIrdEnv) != S_OK) { - LogErr("Failed to create env cubemap for visual %s", _PTR(this)); - return true; - } - if (D3DXCreateTexture(pDev, 128, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &pIrrad) != S_OK) { - LogErr("Failed to create irradiance map for visual %s", _PTR(this)); - return true; - } - } - - - // Create blurred maps ------------------------------------------------------------------------------- - // - if (iFace >= 6) { - iFace = 0; - scn->IntegrateIrradiance(this, pIrdEnv, pIrrad); - return true; + if (ecDefExt.tex.pEnv) { + if (ecDefExt.tex.pEnv->GetType() == D3DRTYPE_CUBETEXTURE) return &ecDefExt.tex; } - - - // Render EnvMaps --------------------------------------------------------------------------------------- - // - - std::set RndList = scn->GetVessels(1e3, true); - std::set AddLightSrc; - - RndList.erase(this); - AddLightSrc.insert(this); - - ENVCAMREC *eCam = pMatMgr->GetCamera(0); - - DWORD nAtc = vessel->AttachmentCount(false); - DWORD nDoc = vessel->DockCount(); - - for (DWORD i = 0; iGetAttachmentHandle(false, i); - if (hAtc) { - OBJHANDLE hAtcObj = vessel->GetAttachmentStatus(hAtc); - if (hAtcObj) { - vObject *vObj = gc->GetScene()->GetVisObject(hAtcObj); - if (vObj) RndList.erase((vVessel *)vObj); - } - } + else { + if (vRoot != this && vRoot) return vRoot->GetEnvMap(); } - - - - // ----------------------------------------------------------------------------------------------- - // - VECTOR3 gpos; - vessel->Local2Global(_V(0,0,0), gpos); - - // Prepare camera and scene for env map rendering - scn->PushCamera(); - scn->SetupInternalCamera(NULL, &gpos, 0.7853981634, 1.0); - scn->BeginPass(RENDERPASS_ENVCAM); - - gc->PushRenderTarget(NULL, pIrDS, RENDERPASS_ENVCAM); - - D3DXMATRIX mEnv; - D3DXVECTOR3 dir, up; - LPDIRECT3DSURFACE9 pSrf = NULL; - - for (DWORD i = 0; iGetCubeMapSurface(D3DCUBEMAP_FACES(iFace), 0, &pSrf)); - - gc->AlterRenderTarget(pSrf, pIrDS); - - EnvMapDirection(iFace, &dir, &up); + return nullptr; +} - D3DXVECTOR3 cp; - D3DXVec3Cross(&cp, &up, &dir); - D3DXVec3Normalize(&cp, &cp); - D3DXMatrixIdentity(&mEnv); - D3DMAT_FromAxis(&mEnv, &cp, &up, &dir); - scn->SetCameraFrustumLimits(0.25, 1e8); - scn->SetupInternalCamera(&mEnv, NULL, 0.7853981634, 1.0); - scn->RenderSecondaryScene(RndList, AddLightSrc, flags); +// ============================================================================================ +// +ENVCAMREC* vVessel::CreateEnvCam(EnvCamType ec) +{ + auto x = new ENVCAMREC; + x->type = ec; + mesh_cams.push_back(x); + return x; +} - SAFE_RELEASE(pSrf); +// ============================================================================================ +// +bool vVessel::HasOwnEnvCam(EnvCamType ec) +{ + if (ec == EnvCamType::Exterior && (ecDefExt.flags & ENVCAM_DEFAULT)) return false; + if (ec == EnvCamType::VC && (ecDefVC.flags & ENVCAM_DEFAULT)) return false; + if (ec == EnvCamType::Mesh && mesh_cams.size() == 0) return false; + return true; +} - iFace++; - if (iFace >= 6) break; +// ============================================================================================ +// +ENVCAMREC* vVessel::GetEnvCam(EnvCamType ec, int idx) +{ + if (ec == EnvCamType::Mesh) { + if (idx >= mesh_cams.size()) return nullptr; + return mesh_cams[idx]; } - - gc->PopRenderTargets(); - - scn->PopPass(); - scn->PopCamera(); - - return false; + if (ec == EnvCamType::Exterior) return &ecDefExt; + if (ec == EnvCamType::VC) return &ecDefVC; + return nullptr; } +// ============================================================================================ +// +bool vVessel::IsRoot() const +{ + return (vRoot == nullptr) | (vRoot == this); +} // ============================================================================================ // @@ -1520,15 +1555,6 @@ void vVessel::RenderLightCone(LPD3DXMATRIX pWT) } -// ============================================================================================ -// -LPDIRECT3DCUBETEXTURE9 vVessel::GetEnvMap(int idx) -{ - if (idx>=0 && idx<4) return pEnv[idx]; - return NULL; -} - - // ============================================================================================ // bool vVessel::ModLighting() diff --git a/OVP/D3D9Client/VVessel.h b/OVP/D3D9Client/VVessel.h index 5470a6cd1..7edb8cbe6 100644 --- a/OVP/D3D9Client/VVessel.h +++ b/OVP/D3D9Client/VVessel.h @@ -44,6 +44,9 @@ typedef struct { class vVessel: public vObject { public: friend class D3D9Client; + + vVessel* vRoot = nullptr; + /** * \brief Creates a new vessel visual for a scene * \param _hObj vessel object handle @@ -72,7 +75,8 @@ class vVessel: public vObject { void GetMinMaxLightDist(float *mind, float *maxd); int GetMatrixTransform(gcCore::MatrixId matrix_id, DWORD mesh, DWORD group, FMATRIX4 *pMat); int SetMatrixTransform(gcCore::MatrixId matrix_id, DWORD mesh, DWORD group, const FMATRIX4 *pMat); - bool GetVCPos(D3DXVECTOR3* out, float* rad); + bool GetVCPos(D3DXVECTOR3* cpos, D3DXVECTOR3* lpos, float* rad); + bool GetMeshPosition(int idx, D3DXVECTOR3* cpos, D3DXVECTOR3* lpos, float* rad); void BakeLights(ImageProcessing* pBaker); void NoVC(); void UpdateBoundingBox(); @@ -131,13 +135,18 @@ class vVessel: public vObject { void RenderGrapplePoints (LPDIRECT3DDEVICE9 dev); void RenderGroundShadow (LPDIRECT3DDEVICE9 dev, OBJHANDLE hPlanet, float depth); void RenderVectors (LPDIRECT3DDEVICE9 dev, D3D9Pad *pSkp); - bool RenderENVMap (LPDIRECT3DDEVICE9 pDev, DWORD cnt=2, DWORD flags=0xFF); - bool ProbeIrradiance(LPDIRECT3DDEVICE9 pDev, DWORD cnt = 2, DWORD flags = 0xFF); + bool RenderENVMap (LPDIRECT3DDEVICE9 pDev, ENVCAMREC* ec, DWORD cnt = 2, DWORD flags = 0xFF); + bool ProcessEnvMaps(LPDIRECT3DDEVICE9 pDev, DWORD cnt, DWORD flags); + + ENVMAPS* GetEnvMap(); + ENVCAMREC* CreateEnvCam(EnvCamType ec); + ENVCAMREC* GetEnvCam(EnvCamType ec, int idx = 0); - LPDIRECT3DCUBETEXTURE9 GetEnvMap(int idx); - LPDIRECT3DCUBETEXTURE9 GetIrradEnv() { return pIrdEnv; } - LPDIRECT3DTEXTURE9 GetIrradianceMap() { return pIrrad; } + bool HasOwnEnvCam(EnvCamType ec); + bool IsRoot() const; + vVessel* GetRoot() const { return vRoot; } + float GetExhaustLength() const { return ExhaustLength; } D3D9Pick Pick(const D3DXVECTOR3 *vDir, const PickProp* p); @@ -202,18 +211,14 @@ class vVessel: public vObject { std::map defstate; std::unordered_set applyanim; std::map currentstate; + std::vector mesh_cams; + // Default eCam configurations + ENVCAMREC ecDefExt, ecDefVC; VESSEL *vessel; // access instance for the vessel class MatMgr *pMatMgr; - LPDIRECT3DCUBETEXTURE9 pEnv[4], pIrdEnv; - LPDIRECT3DTEXTURE9 pIrrad; - - int nEnv; // Number of environmental maps - int iFace; // EnvMap Face index that is to be rendered next - int eFace; - struct MESHREC { D3D9Mesh *mesh; // DX9 mesh representation D3DXMATRIX *trans; // mesh transformation matrix (rel. to vessel frame) diff --git a/OVP/D3D9Client/shaders/EnvMapBlur.hlsl b/OVP/D3D9Client/shaders/EnvMapBlur.hlsl index 899bccedd..20f791458 100644 --- a/OVP/D3D9Client/shaders/EnvMapBlur.hlsl +++ b/OVP/D3D9Client/shaders/EnvMapBlur.hlsl @@ -38,4 +38,10 @@ float4 PSBlur(float x : TEXCOORD0, float y : TEXCOORD1) : COLOR } color /= (a*2.0f); return float4(color, 1); -} \ No newline at end of file +} + + +float4 PS2DBlur(float x : TEXCOORD0, float y : TEXCOORD1) : COLOR +{ + return float4(0.5, 0.5, 0.5, 1.0); +} diff --git a/OVP/D3D9Client/shaders/IrradianceInteg.hlsl b/OVP/D3D9Client/shaders/IrradianceInteg.hlsl index 83eb47c14..3bc3b37ea 100644 --- a/OVP/D3D9Client/shaders/IrradianceInteg.hlsl +++ b/OVP/D3D9Client/shaders/IrradianceInteg.hlsl @@ -1,5 +1,5 @@ -#define IKernelSize 150 +#define IKernelSize 120 uniform extern float4 Kernel[IKernelSize]; uniform extern float3 vNr; // North @@ -11,6 +11,7 @@ uniform extern bool bUp; sampler tCube; sampler tSrc; +sampler tRandom; float3 Paraboloidal_to_World(float3 i) @@ -22,34 +23,21 @@ float3 Paraboloidal_to_World(float3 i) } -float4 PSPreInteg(float x : TEXCOORD0, float y : TEXCOORD1) : COLOR -{ - float3 color = 0; - float2 p = float2(x, y); - for (int j = 0; j < 8; j++) { - for (int i = 0; i < 8; i++) { - color += tex2D(tSrc, p + (float2(i, j) - 4) * fD).rgb; - } - } - return float4(color * (1.0f/64.0f), 1); -} - - float4 PSInteg(float x : TEXCOORD0, float y : TEXCOORD1, float2 sc : VPOS) : COLOR { + float a = tex2D(tRandom, float2(x,y)).r * 6.283185307; float2 qw = float2(x, y) * 2.0f - 1.0f; float3 vz = Paraboloidal_to_World(float3(qw.xy, (bUp ? 1 : -1))); - - float3 q = lerp(vUp, vCp, frac(x * 21)); // Randomize rotation - float3 w = lerp(q, vNr, frac(y * 17)); // Randomize rotation - float3 vx = normalize(cross(vz, w)); - float3 vy = normalize(cross(vz, vx)); + float3 qx = normalize(cross(vz, vNr)); + float3 qy = normalize(cross(vz, qx)); + float3 vx = qx * sin(a) + qy * cos(a); + float3 vy = qx * cos(a) - qy * sin(a); float3 sum = 0; - for (int i = 0; i < IKernelSize; i++) { + [unroll] for (int i = 0; i < IKernelSize; i++) { float3 d = (vx*Kernel[i].x) + (vy*Kernel[i].y) + (vz*Kernel[i].z); - sum += texCUBE(tCube, d).rgb * Kernel[i].w; + sum += texCUBElod(tCube, float4(d, 1)).rgb * Kernel[i].w; } return float4(sqrt(sum * fIntensity * (0.7f / IKernelSize)), 1.0f); @@ -63,7 +51,15 @@ float4 PSPostBlur(float x : TEXCOORD0, float y : TEXCOORD1) : COLOR color += tex2D(tSrc, p).rgb; color += tex2D(tSrc, p + float2(0, 1)*fD).rgb; color += tex2D(tSrc, p + float2(0, -1)*fD).rgb; + color += tex2D(tSrc, p + float2( 1, 0)*fD).rgb; color += tex2D(tSrc, p + float2(-1, 0)*fD).rgb; - color += tex2D(tSrc, p + float2(-1, 0)*fD).rgb; - return float4(color * 0.2, 1); -} \ No newline at end of file + color += tex2D(tSrc, p + float2(1, 1)*fD).rgb; + color += tex2D(tSrc, p + float2(1, -1)*fD).rgb; + color += tex2D(tSrc, p + float2(-1, 1)*fD).rgb; + color += tex2D(tSrc, p + float2(-1,-1)*fD).rgb; + color += tex2D(tSrc, p + float2(0, 2) * fD).rgb; + color += tex2D(tSrc, p + float2(0, -2) * fD).rgb; + color += tex2D(tSrc, p + float2( 2, 0) * fD).rgb; + color += tex2D(tSrc, p + float2(-2, 0) * fD).rgb; + return float4(color * 0.07, 1); +} diff --git a/OVP/D3D9Client/shaders/PreBakeLights.hlsl b/OVP/D3D9Client/shaders/PreBakeLights.hlsl index e368392c6..5f43bc209 100644 --- a/OVP/D3D9Client/shaders/PreBakeLights.hlsl +++ b/OVP/D3D9Client/shaders/PreBakeLights.hlsl @@ -3,24 +3,43 @@ // licensed under MIT // ============================================================== +uniform extern float3 vParTexPos[6]; // Pre-computed paraboloidal map coords for prime directions uniform extern float3 fControl[16]; uniform extern int iCount; uniform extern bool bEnabled[6]; +uniform extern float fShine; -sampler tMap[16] : register(s0); +sampler tMap[16] : register(s0); // Lightmaps +sampler tAO[6] : register(s0); // AO Textures for prime directions +sampler tIrrad : register(s6); // Paraboloidal irradiance map float cmax(float3 a) { return max(a.x, max(a.y, a.z)); } +// ============================================================================ +// float3 LightFX(float3 c) { float q = cmax(c); return c * 1.2f * rsqrt(2 + q * q); } -// Combine multiple baked lightmaps into a single map + +// ============================================================================ +// +float4 ParaboloidalSampler(sampler s, float3 p) +{ + float4 A = tex2D(s, p.xy + float2(0.25f, 0.5f)); + float4 B = tex2D(s, p.xy + float2(0.75f, 0.5f)); + return lerp(A, B, smoothstep(-0.03, 0.03, p.z)); +} + + + +// ============================================================================ +// Combine multiple (regular) baked lightmaps into a single map // float4 PSMain(float x : TEXCOORD0, float y : TEXCOORD1) : COLOR { @@ -29,14 +48,27 @@ float4 PSMain(float x : TEXCOORD0, float y : TEXCOORD1) : COLOR return float4(LightFX(color), 1.0f); } -// Combine multiple baked lightmaps into a single map + + +// ============================================================================ +// Combine multiple baked (ambient) lightmaps into a single map +// Include sun and planet shine coming through windows // float4 PSSunAO(float x : TEXCOORD0, float y : TEXCOORD1) : COLOR { float3 color = 0; - [unroll] for (int i = 0; i < 6; i++) { + + // For a given pixel in texture (x,y) + [unroll] for (int i = 0; i < 6; i++) { // Browse through direction if (bEnabled[i]) { - color += tex2D(tMap[i], float2(x, y)).rgb * fControl[i]; + // Get planet shine color for a given direction 'i' + float3 cShine = ParaboloidalSampler(tIrrad, vParTexPos[i]).rgb; + // Get ambient distribution inside VC for a given light direction 'i' + float3 ad = tex2D(tAO[i], float2(x, y)).rgb; + // Compute sunlight and planet shine factors + float3 shineAO = ad * cShine * fShine; + float3 sunAO = ad * fControl[i]; + color += (sunAO + shineAO); } } return float4(LightFX(color), 1.0f); diff --git a/Orbitersdk/include/DrawAPI.h b/Orbitersdk/include/DrawAPI.h index dd0def505..3148e9292 100644 --- a/Orbitersdk/include/DrawAPI.h +++ b/Orbitersdk/include/DrawAPI.h @@ -1034,10 +1034,12 @@ class OAPIFUNC Sketchpad RENDER_ALL = 0x04 ///< Render all meshgroups }; - + /** + * \brief Source layout structure for GUI element drawing + */ typedef struct { - RECT intr; - RECT outr; + RECT intr; ///< Interrior rect + RECT outr; ///< Outerrior rect } skpRegion; /** diff --git a/Orbitersdk/include/GraphicsAPI.h b/Orbitersdk/include/GraphicsAPI.h index b7512b1e9..b0740fe11 100644 --- a/Orbitersdk/include/GraphicsAPI.h +++ b/Orbitersdk/include/GraphicsAPI.h @@ -468,6 +468,14 @@ class OAPIFUNC GraphicsClient: public Module { */ virtual void clbkOptionChanged(DWORD cat, DWORD item) {} + /** + * \brief React to vessel creation, deletion, docking, attaching events + * \param hVesselA object handle of first vessel + * \param hVesselB object handle of second vessel + * \param type Event type + */ + virtual void clbkScenarioChanged(OBJHANDLE hVessel, ScnChgEvent type) {} + /** * \brief Texture request * diff --git a/Orbitersdk/include/OrbiterAPI.h b/Orbitersdk/include/OrbiterAPI.h index d923cc3de..044490716 100644 --- a/Orbitersdk/include/OrbiterAPI.h +++ b/Orbitersdk/include/OrbiterAPI.h @@ -463,6 +463,19 @@ enum class MatProp { SpecialFX ///< Heat map effect control variable in [.r] (i.e. average part temperature) }; +enum class ScnChgEvent { + Invalid = 0, ///< Unspecified event + Added = 1, ///< Vessel dynamically added in scenario + Deleted = 2, ///< Vessel dynamically deleted from scenario + Docked = 3, ///< Vessels docked + UnDocked = 4, ///< Vessels undocked + Attached = 5, ///< Vessels attached + Detached = 6, ///< Vessels detached + VisualConfig = 7, ///< Vessel's rendering configuration has changed + VisualCreated = 8, ///< Vessel visual created + VisualDeleted = 9 ///< Vessel visual deleted +}; + enum class MeshProp { BAKED_0, BAKED_1, BAKED_2, BAKED_3, BAKED_4, ///< baked light level BAKED_5, BAKED_6, BAKED_7, BAKED_8, BAKED_9, ///< baked light level @@ -6232,6 +6245,7 @@ OAPIFUNC void oapiWriteLine (FILEHANDLE file, char *line); * \sa oapiWriteLogV */ OAPIFUNC void oapiWriteLog (char *line); +OAPIFUNC void oapiWriteLogVerbose(char* line); /** * \brief Writes a formatted string with variable number of arguments to orbiter.log. diff --git a/Orbitersdk/include/VesselAPI.h b/Orbitersdk/include/VesselAPI.h index b5252582b..37a2446e2 100644 --- a/Orbitersdk/include/VesselAPI.h +++ b/Orbitersdk/include/VesselAPI.h @@ -4561,6 +4561,12 @@ class OAPIFUNC VESSEL { */ ATTACHMENTHANDLE GetAttachmentHandle (bool toparent, DWORD i) const; + /** + * \brief Return the handle of a root object in a attachment hierarchy. (i.e. vessel that has not parent) + * \return Vessel handle. Returns vessel's own handle "this" if no parent exists. + */ + OBJHANDLE GetAttachmentRoot() const; + /** * \brief Attach a child vessel to an attachment point. * \param child handle of child vessel to be attached. diff --git a/Src/Orbiter/Orbiter.cpp b/Src/Orbiter/Orbiter.cpp index 76766ed6b..a12b7f7cd 100644 --- a/Src/Orbiter/Orbiter.cpp +++ b/Src/Orbiter/Orbiter.cpp @@ -1287,10 +1287,12 @@ void Orbiter::InsertVessel (Vessel *vessel) it->pModule->clbkNewVessel((OBJHANDLE)vessel); #ifdef INLINEGRAPHICS - oclient->clbkNewVessel ((OBJHANDLE)vessel); + oclient->clbkNewVessel((OBJHANDLE)vessel); #else - if (gclient) + if (gclient) { gclient->clbkNewVessel((OBJHANDLE)vessel); + gclient->clbkScenarioChanged((OBJHANDLE)vessel, ScnChgEvent::Added); + } #endif // INLINEGRAPHICS if (pDlgMgr) pDlgMgr->BroadcastMessage (MSG_CREATEVESSEL, vessel); @@ -1345,10 +1347,12 @@ bool Orbiter::KillVessels () it->pModule->clbkDeleteVessel((OBJHANDLE)vessel); #ifdef INLINEGRAPHICS - oclient->clbkDeleteVessel ((OBJHANDLE)vessel); + oclient->clbkDeleteVessel((OBJHANDLE)vessel); #else - if (gclient) + if (gclient) { gclient->clbkDeleteVessel((OBJHANDLE)vessel); + gclient->clbkScenarioChanged((OBJHANDLE)vessel, ScnChgEvent::Deleted); + } #endif // broadcast vessel destruction to all vessels g_psys->BroadcastVessel (MSG_KILLVESSEL, vessel); diff --git a/Src/Orbiter/OrbiterAPI.cpp b/Src/Orbiter/OrbiterAPI.cpp index f71e64ad6..6fda3898a 100644 --- a/Src/Orbiter/OrbiterAPI.cpp +++ b/Src/Orbiter/OrbiterAPI.cpp @@ -2344,6 +2344,11 @@ DLLEXPORT void oapiWriteLog (char *line) LOGOUT (line); } +DLLEXPORT void oapiWriteLogVerbose(char* line) +{ + LogOutFine(line); +} + DLLEXPORT void oapiExitOrbiter(int code) { exit(code); diff --git a/Src/Orbiter/Vessel.cpp b/Src/Orbiter/Vessel.cpp index 2b87c8bfa..6be85de01 100644 --- a/Src/Orbiter/Vessel.cpp +++ b/Src/Orbiter/Vessel.cpp @@ -2688,6 +2688,11 @@ int Vessel::Dock (Vessel *target, DWORD mydid, DWORD tgtdid, DWORD mode) g_psys->DockVessels (this, target, mydid, tgtdid); RegisterDocking (mydid, target, tgtdid); target->RegisterDocking (tgtdid, this, mydid); + +#ifndef INLINEGRAPHICS + auto gc = g_pOrbiter->GetGraphicsClient(); + if (gc) gc->clbkScenarioChanged((OBJHANDLE)this, ScnChgEvent::Docked); +#endif return 0; } @@ -2714,6 +2719,11 @@ bool Vessel::Undock (UINT did, const Vessel *exclude, double vsep) for (n = n0; n < n1; ++n) buf += ' ' + std::to_string(n); FRecorder_SaveEvent("UNDOCK", buf.substr(1).data()); } + +#ifndef INLINEGRAPHICS + auto gc = g_pOrbiter->GetGraphicsClient(); + if (gc) gc->clbkScenarioChanged((OBJHANDLE)this, ScnChgEvent::UnDocked); +#endif return undocked; } @@ -2959,6 +2969,11 @@ bool Vessel::AttachChild (Vessel *child, AttachmentSpec *as, AttachmentSpec *asc if (allow_loose) strcat (cbuf, " LOOSE"); FRecorder_SaveEvent ("ATTACH", cbuf); } + +#ifndef INLINEGRAPHICS + auto gc = g_pOrbiter->GetGraphicsClient(); + if (gc) gc->clbkScenarioChanged((OBJHANDLE)this, ScnChgEvent::Attached); +#endif return true; } @@ -2969,6 +2984,11 @@ bool Vessel::AttachToParent (Vessel *parent, AttachmentSpec *asp, AttachmentSpec as->mate = parent; as->mate_attach = asp; InitAttachmentToParent (as, allow_loose); + +#ifndef INLINEGRAPHICS + auto gc = g_pOrbiter->GetGraphicsClient(); + if (gc) gc->clbkScenarioChanged((OBJHANDLE)this, ScnChgEvent::Attached); +#endif return true; } @@ -2983,6 +3003,11 @@ bool Vessel::DetachChild (AttachmentSpec *asp, double v) sprintf (cbuf, "%d, %0.3f", pidx, v); FRecorder_SaveEvent ("DETACH", cbuf); } + +#ifndef INLINEGRAPHICS + auto gc = g_pOrbiter->GetGraphicsClient(); + if (gc) gc->clbkScenarioChanged((OBJHANDLE)this, ScnChgEvent::Detached); +#endif return true; } @@ -3010,6 +3035,10 @@ bool Vessel::DetachFromParent (double v) if (bFRplayback) FRecorder_CheckEnd(); //bFRplayback = false; +#ifndef INLINEGRAPHICS + auto gc = g_pOrbiter->GetGraphicsClient(); + if (gc) gc->clbkScenarioChanged((OBJHANDLE)this, ScnChgEvent::Detached); +#endif return true; } @@ -3105,6 +3134,31 @@ void Vessel::ShiftAttachments (const Vector &ofs) // ============================================================== +Vessel* Vessel::GetAttachmentRoot() +{ + Vessel* mate = nullptr; + int cnt = 0; + for (DWORD i = 0; i < npattach; i++) { + if (pattach[i]) { + if (pattach[i]->toparent == false) { + oapiWriteLog("[ERROR] Parent attachment with no toparent flag"); // Sanity check + DebugBreak(); + } + if (pattach[i]->mate) { mate = pattach[i]->mate; cnt++; } + } + } + if (cnt > 1) { + oapiWriteLog("[ERROR] Vessel has multiple parent attachments"); // Sanity check + DebugBreak(); + } + + if (cnt == 1) return mate->GetAttachmentRoot(); + + return this; +} + +// ============================================================== + void Vessel::AddBeacon (BEACONLIGHTSPEC *bs) { BEACONLIGHTSPEC **tmp = new BEACONLIGHTSPEC*[nbeacon+1]; TRACENEW @@ -7317,6 +7371,11 @@ ATTACHMENTHANDLE VESSEL::GetAttachmentHandle (bool toparent, DWORD i) const } } +OBJHANDLE VESSEL::GetAttachmentRoot() const +{ + return vessel->GetAttachmentRoot(); +} + void VESSEL::AddBeacon (BEACONLIGHTSPEC *bs) { vessel->AddBeacon (bs); diff --git a/Src/Orbiter/Vessel.h b/Src/Orbiter/Vessel.h index 83ebfc09f..c3525d86e 100644 --- a/Src/Orbiter/Vessel.h +++ b/Src/Orbiter/Vessel.h @@ -1065,6 +1065,9 @@ class Vessel: public VesselBase { void ShiftAttachments (const Vector &ofs); // move all attachment points by offset ofs + Vessel* Vessel::GetAttachmentRoot(); + // Get the root vessel. (i.e. vessel with no parent attachments) + // ======================================================================== // navigation radio interface diff --git a/Src/Vessel/DeltaGlider/DeltaGlider.cpp b/Src/Vessel/DeltaGlider/DeltaGlider.cpp index 8d5e710f8..2e091560b 100644 --- a/Src/Vessel/DeltaGlider/DeltaGlider.cpp +++ b/Src/Vessel/DeltaGlider/DeltaGlider.cpp @@ -158,6 +158,8 @@ DeltaGlider::DeltaGlider (OBJHANDLE hObj, int fmodel) { int i; + oapiWriteLogVerbose("[DG] Constructor"); + modelidx = (fmodel ? 1 : 0); // Subsystem definitions @@ -213,6 +215,7 @@ DeltaGlider::DeltaGlider (OBJHANDLE hObj, int fmodel) // -------------------------------------------------------------- DeltaGlider::~DeltaGlider () { + oapiWriteLogVerbose("[DG] Destructor"); DWORD i; if (insignia_tex) oapiDestroySurface(insignia_tex); @@ -875,6 +878,7 @@ void DeltaGlider::InitVCMesh() void DeltaGlider::clbkSetClassCaps (FILEHANDLE cfg) { // *************** physical parameters ********************** + oapiWriteLogVerbose("[DG] clbkSetClassCaps"); bool b; int i; @@ -1110,6 +1114,7 @@ void DeltaGlider::clbkSetClassCaps (FILEHANDLE cfg) // -------------------------------------------------------------- void DeltaGlider::clbkLoadStateEx (FILEHANDLE scn, void *vs) { + oapiWriteLogVerbose("[DG] clbkLoadStateEx"); char *line; while (oapiReadScenario_nextline (scn, line)) { @@ -1150,6 +1155,7 @@ void DeltaGlider::clbkLoadStateEx (FILEHANDLE scn, void *vs) // -------------------------------------------------------------- void DeltaGlider::clbkSaveState (FILEHANDLE scn) { + oapiWriteLogVerbose("[DG] clbkSaveState"); char cbuf[256]; int i; @@ -1186,6 +1192,7 @@ void DeltaGlider::clbkSaveState (FILEHANDLE scn) // -------------------------------------------------------------- void DeltaGlider::clbkPostCreation () { + oapiWriteLogVerbose("[DG] clbkPostCreation"); ComponentVessel::clbkPostCreation (); SetEmptyMass (); @@ -1218,6 +1225,7 @@ void DeltaGlider::clbkPostCreation () // -------------------------------------------------------------- void DeltaGlider::clbkVisualCreated (VISHANDLE vis, int refcount) { + oapiWriteLogVerbose("[DG] clbkVisualCreated"); visual = vis; exmesh = GetDevMesh (vis, 0); vcmesh = GetDevMesh (vis, 1); @@ -1255,6 +1263,7 @@ void DeltaGlider::clbkVisualCreated (VISHANDLE vis, int refcount) // -------------------------------------------------------------- void DeltaGlider::clbkVisualDestroyed (VISHANDLE vis, int refcount) { + oapiWriteLogVerbose("[DG] clbkVisualDestroyed"); visual = NULL; exmesh = NULL; vcmesh = NULL; @@ -1352,6 +1361,7 @@ bool DeltaGlider::clbkLoadGenericCockpit () bool DeltaGlider::clbkLoadPanel2D (int id, PANELHANDLE hPanel, DWORD viewW, DWORD viewH) { + oapiWriteLogVerbose("[DG] clbkLoadPanel2D"); // set up subsystem panel elements ComponentVessel::clbkLoadPanel2D (id, hPanel, viewW, viewH); @@ -1444,6 +1454,8 @@ bool DeltaGlider::clbkPanelRedrawEvent (int id, int event, SURFHANDLE surf, void // -------------------------------------------------------------- bool DeltaGlider::clbkLoadVC (int id) { + oapiWriteLogVerbose("[DG] clbkLoadVC"); + static VCMFDSPEC mfds_left = {1, GRP_LMFD_DISPLAY_VC}; static VCMFDSPEC mfds_right = {1, GRP_RMFD_DISPLAY_VC}; static VCHUDSPEC huds = {1, GRP_HUDDISP_VC, {0,1.462,7.09}, 0.15}; From 4534b7445e1d6b5e0802b64774f0d45737798c84 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Wed, 24 Jan 2024 04:12:15 +0200 Subject: [PATCH 29/42] Improved VC ambient environment debugging. --- OVP/D3D9Client/D3D9Client.rc | 56 ++++++++++++----------- OVP/D3D9Client/DebugControls.cpp | 21 +++++++++ OVP/D3D9Client/DebugControls.h | 3 ++ OVP/D3D9Client/Mesh.cpp | 26 ++++++++--- OVP/D3D9Client/VVessel.cpp | 4 +- OVP/D3D9Client/resource.h | 3 ++ OVP/D3D9Client/shaders/PreBakeLights.hlsl | 9 ++-- 7 files changed, 86 insertions(+), 36 deletions(-) diff --git a/OVP/D3D9Client/D3D9Client.rc b/OVP/D3D9Client/D3D9Client.rc index 710973851..57ec1dbbc 100644 --- a/OVP/D3D9Client/D3D9Client.rc +++ b/OVP/D3D9Client/D3D9Client.rc @@ -40,7 +40,7 @@ EXSTYLE WS_EX_WINDOWEDGE CAPTION "D3D9 Debug Controls" FONT 8, "Ms Shell Dlg" { - GROUPBOX "Mesh Options", IDC_STATIC, 5, 165, 176, 60, 0, WS_EX_LEFT + GROUPBOX "Mesh Options and Flags", IDC_STATIC, 5, 165, 176, 60, 0, WS_EX_LEFT PUSHBUTTON "Close", IDCANCEL, 124, 429, 51, 14, 0, WS_EX_LEFT PUSHBUTTON "Open", IDC_DBG_OPEN, 387, 34, 30, 14, 0, WS_EX_LEFT PUSHBUTTON "Execute", IDC_DBG_EXECUTE, 490, 147, 56, 14, 0, WS_EX_LEFT @@ -56,26 +56,26 @@ FONT 8, "Ms Shell Dlg" EDITTEXT IDC_DBG_FILE, 421, 35, 125, 12, WS_GROUP | ES_AUTOHSCROLL | ES_READONLY, WS_EX_LEFT AUTOCHECKBOX "Highlight selected group", IDC_DBG_HSG, 18, 107, 92, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Highlight selected mesh", IDC_DBG_HSM, 18, 117, 91, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Boxes", IDC_DBG_BOXES, 208, 162, 35, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Boxes", IDC_DBG_BOXES, 208, 202, 35, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Normalize", IDC_DBG_NORM, 400, 79, 47, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Mipmap fade", IDC_DBG_FADE, 400, 92, 57, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Reduce seams", IDC_DBG_SEAMS, 460, 79, 63, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Spheres", IDC_DBG_SPHERES, 208, 171, 42, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Surface Tiles", IDC_DBG_TILEBB, 208, 180, 57, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Selected group only", IDC_DBG_GRPO, 274, 162, 79, 8, 0, WS_EX_LEFT - GROUPBOX "Bounding geometry", IDC_STATIC, 195, 150, 175, 45, 0, WS_EX_LEFT - GROUPBOX "Visualize local light cones", IDC_STATIC, 195, 200, 175, 35, 0, WS_EX_LEFT + AUTOCHECKBOX "Spheres", IDC_DBG_SPHERES, 208, 211, 42, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Surface Tiles", IDC_DBG_TILEBB, 208, 220, 57, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Selected group only", IDC_DBG_GRPO, 274, 202, 79, 8, 0, WS_EX_LEFT + GROUPBOX "Bounding geometry", IDC_STATIC, 195, 190, 175, 45, 0, WS_EX_LEFT + GROUPBOX "Visualize local light cones", IDC_STATIC, 195, 240, 175, 35, 0, WS_EX_LEFT GROUPBOX "Selection and Display Options", IDC_STATIC, 5, 15, 175, 145, 0, WS_EX_LEFT GROUPBOX "Misc.", IDC_STATIC, 195, 10, 173, 70, 0, WS_EX_LEFT - GROUPBOX "Scene Debugger", IDC_STATIC, 195, 85, 173, 60, 0, WS_EX_LEFT + GROUPBOX "Scene Debugger", IDC_STATIC, 195, 85, 173, 95, 0, WS_EX_LEFT GROUPBOX "Texture Tools", IDC_STATIC, 380, 15, 173, 151, 0, WS_EX_LEFT - AUTOCHECKBOX "Selected mesh only", IDC_DBG_MSHO, 274, 171, 77, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Selected mesh only", IDC_DBG_MSHO, 274, 211, 77, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Dual sided", IDC_DBG_DUAL, 120, 107, 49, 8, 0, WS_EX_LEFT PUSHBUTTON "<", IDC_DBG_GRPUP, 102, 90, 9, 12, BS_CENTER, WS_EX_LEFT PUSHBUTTON ">", IDC_DBG_GRPDN, 114, 90, 9, 12, BS_CENTER, WS_EX_LEFT PUSHBUTTON "<", IDC_DBG_MSHUP, 102, 73, 9, 12, BS_CENTER, WS_EX_LEFT PUSHBUTTON ">", IDC_DBG_MSHDN, 114, 73, 9, 12, BS_CENTER, WS_EX_LEFT - AUTOCHECKBOX "Selected visual only", IDC_DBG_VISO, 274, 180, 79, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Selected visual only", IDC_DBG_VISO, 274, 220, 79, 8, 0, WS_EX_LEFT CONTROL "", IDC_DBG_SPEED, TRACKBAR_CLASS, WS_TABSTOP | TBS_BOTH | TBS_NOTICKS, 42, 58, 108, 13, WS_EX_LEFT CONTROL "", IDC_DBG_RESBIAS, TRACKBAR_CLASS, WS_TABSTOP | TBS_AUTOTICKS | TBS_BOTH, 205, 55, 155, 20, WS_EX_LEFT LTEXT "Speed", IDC_STATIC, 18, 58, 22, 8, SS_LEFT, WS_EX_LEFT @@ -85,7 +85,7 @@ FONT 8, "Ms Shell Dlg" GROUPBOX "Material", IDC_DBG_MATGRP, 5, 230, 175, 165, 0, WS_EX_LEFT COMBOBOX IDC_DBG_MATPRP, 77, 240, 96, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT COMBOBOX IDC_DBG_DEFSHADER, 75, 177, 96, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT - COMBOBOX IDC_DBG_CONES, 200, 215, 165, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT + COMBOBOX IDC_DBG_CONES, 200, 255, 165, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT LTEXT "Material property", IDC_STATIC, 18, 242, 53, 8, SS_LEFT, WS_EX_LEFT LTEXT "Mesh Shader", IDC_STATIC, 15, 179, 43, 9, SS_LEFT, WS_EX_LEFT EDITTEXT IDC_DBG_RED, 31, 260, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT @@ -111,7 +111,7 @@ FONT 8, "Ms Shell Dlg" PUSHBUTTON "Save materials", IDC_DBG_MATSAVE, 5, 429, 51, 14, 0, WS_EX_LEFT PUSHBUTTON "Create kernel", IDC_DBG_KERNEL, 315, 430, 47, 14, 0, WS_EX_LEFT PUSHBUTTON "Data window", IDC_DBG_DATAWND, 5, 446, 50, 14, 0, WS_EX_LEFT - PUSHBUTTON "Save envmap", IDC_DBG_ENVSAVE, 205, 128, 60, 12, 0, WS_EX_LEFT + PUSHBUTTON "Save envmap", IDC_DBG_ENVSAVE, 300, 164, 60, 12, 0, WS_EX_LEFT PUSHBUTTON ">>>", IDC_DBG_MORE, 124, 446, 50, 14, 0, WS_EX_LEFT PUSHBUTTON "Reload Shader", IDC_DBG_RELOADSHD, 60, 446, 60, 14, 0, WS_EX_LEFT PUSHBUTTON "Reload Textures", IDC_DBG_RELOADTEX, 60, 430, 60, 14, 0, WS_EX_LEFT @@ -129,28 +129,32 @@ FONT 8, "Ms Shell Dlg" COMBOBOX IDC_DBG_BKLID, 11, 407, 50, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT GROUPBOX "Baked Lights", 0, 6, 395, 175, 30, 0, WS_EX_LEFT CONTROL "", IDC_DBG_BKLADJ, TRACKBAR_CLASS, WS_TABSTOP | TBS_BOTH | TBS_NOTICKS, 65, 405, 115, 15, WS_EX_LEFT - GROUPBOX "Mesh Group Information", IDC_STATIC, 195, 240, 175, 135, 0, WS_EX_LEFT - AUTOCHECKBOX "No Shadow", IDC_DBG_NOSHADOW, 200, 255, 53, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Do not render", IDC_DBG_NORENDER, 200, 265, 59, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Always Lit", IDC_DBG_NOLIGHT, 200, 275, 47, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Additive Blend", IDC_DBG_ADDITIVE, 200, 285, 61, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Texture Alpha Only (No Color)", IDC_DBG_NOCOLOR, 200, 295, 109, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Order Independent Transparency", IDC_DBG_OIT, 200, 305, 121, 8, 0, WS_EX_LEFT - EDITTEXT IDC_DBG_MATIDX, 225, 320, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT - EDITTEXT IDC_DBG_TEXIDX, 225, 335, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT - LTEXT "MatIdx", IDC_STATIC, 200, 321, 22, 9, SS_LEFT, WS_EX_LEFT - LTEXT "TexIdx", IDC_STATIC, 200, 337, 22, 9, SS_LEFT, WS_EX_LEFT + GROUPBOX "Mesh Group Information", IDC_STATIC, 195, 280, 175, 135, 0, WS_EX_LEFT + AUTOCHECKBOX "No Shadow", IDC_DBG_NOSHADOW, 200, 295, 53, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Do not render", IDC_DBG_NORENDER, 200, 305, 59, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Always Lit", IDC_DBG_NOLIGHT, 200, 315, 47, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Additive Blend", IDC_DBG_ADDITIVE, 200, 325, 61, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Texture Alpha Only (No Color)", IDC_DBG_NOCOLOR, 200, 335, 109, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Order Independent Transparency", IDC_DBG_OIT, 200, 345, 121, 8, 0, WS_EX_LEFT + EDITTEXT IDC_DBG_MATIDX, 225, 360, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT + EDITTEXT IDC_DBG_TEXIDX, 225, 375, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT + LTEXT "MatIdx", IDC_STATIC, 200, 361, 22, 9, SS_LEFT, WS_EX_LEFT + LTEXT "TexIdx", IDC_STATIC, 200, 377, 22, 9, SS_LEFT, WS_EX_LEFT PUSHBUTTON "Save Mesh", IDC_DBG_MESHSAVE, 200, 430, 55, 14, 0, WS_EX_LEFT PUSHBUTTON "Unrendered", IDC_DBG_NEXT, 127, 90, 48, 12, 0, WS_EX_LEFT - LTEXT "Label", IDC_STATIC, 201, 352, 18, 9, SS_LEFT, WS_EX_LEFT - EDITTEXT IDC_DBG_GRPLABEL, 225, 350, 140, 12, ES_AUTOHSCROLL, WS_EX_LEFT + LTEXT "Label", IDC_STATIC, 201, 392, 18, 9, SS_LEFT, WS_EX_LEFT + EDITTEXT IDC_DBG_GRPLABEL, 225, 390, 140, 12, ES_AUTOHSCROLL, WS_EX_LEFT AUTOCHECKBOX "Exterior in VC", IDC_DBG_EXTVC, 120, 137, 58, 8, 0, WS_EX_LEFT AUTOCHECKBOX "2cm near clip distance", IDC_DBG_CLIPDIST, 18, 136, 87, 8, 0, WS_EX_LEFT LTEXT "MeshVisMode: ", IDC_DBG_VISMODE, 10, 380, 162, 9, SS_LEFT, WS_EX_LEFT AUTOCHECKBOX "Pick only current mesh", IDC_DBG_PICKCURRENT, 18, 146, 87, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Dynamic", IDC_DBG_DYNAMIC, 285, 255, 43, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Dynamic", IDC_DBG_DYNAMIC, 285, 295, 43, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Is VC Mesh", IDC_DBG_ISVCMESH, 15, 193, 52, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Cast VC Shadow", IDC_DBG_VCSHADOW, 15, 203, 69, 8, 0, WS_EX_LEFT + COMBOBOX IDC_DBG_AMBDIR, 275, 130, 86, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT + LTEXT "VC Ambient View Dir", IDC_STATIC, 205, 132, 66, 9, SS_LEFT, WS_EX_LEFT + AUTOCHECKBOX "No sunlight", IDC_DBG_NOSUNAMB, 205, 143, 51, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "No planet glow", IDC_DBG_NOPLNAMB, 205, 152, 63, 8, 0, WS_EX_LEFT } diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index f1b413016..765d866ff 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -36,6 +36,7 @@ extern D3D9Client *g_client; namespace DebugControls { +int ambdir = -1; int bkl_id = 0; DWORD dwGFX, dwCmd, nMesh, nGroup, sMesh, sGroup, debugFlags, dspMode, camMode, SelColor, sEmitter; double camSpeed; @@ -488,6 +489,8 @@ void UpdateFlags() SETFLAG(debugFlags, DBG_FLAGS_NEARCLIP, (SendDlgItemMessageA(hDlg, IDC_DBG_CLIPDIST, BM_GETCHECK, 0, 0) == BST_CHECKED)); SETFLAG(debugFlags, DBG_FLAGS_RENDEREXT, (SendDlgItemMessageA(hDlg, IDC_DBG_EXTVC, BM_GETCHECK, 0, 0) == BST_CHECKED)); SETFLAG(debugFlags, DBG_FLAGS_PICKCURRENT, (SendDlgItemMessageA(hDlg, IDC_DBG_PICKCURRENT, BM_GETCHECK, 0, 0) == BST_CHECKED)); + SETFLAG(debugFlags, DBG_FLAGS_NOSUNAMB, (SendDlgItemMessageA(hDlg, IDC_DBG_NOSUNAMB, BM_GETCHECK, 0, 0) == BST_CHECKED)); + SETFLAG(debugFlags, DBG_FLAGS_NOPLNAMB, (SendDlgItemMessageA(hDlg, IDC_DBG_NOPLNAMB, BM_GETCHECK, 0, 0) == BST_CHECKED)); Config->EnableLimiter = (int)((debugFlags&DBG_FLAGS_FPSLIM)>0); } @@ -650,6 +653,16 @@ void OpenDlgClbk(void *context) SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"LightVisbil."); SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"BakedLightMap"); SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_SETCURSEL, 0, 0); + + SendDlgItemMessageA(hDlg, IDC_DBG_AMBDIR, CB_RESETCONTENT, 0, 0); + SendDlgItemMessageA(hDlg, IDC_DBG_AMBDIR, CB_ADDSTRING, 0, (LPARAM)"Omnidir"); + SendDlgItemMessageA(hDlg, IDC_DBG_AMBDIR, CB_ADDSTRING, 0, (LPARAM)"From Up (+y)"); + SendDlgItemMessageA(hDlg, IDC_DBG_AMBDIR, CB_ADDSTRING, 0, (LPARAM)"From Down (-y)"); + SendDlgItemMessageA(hDlg, IDC_DBG_AMBDIR, CB_ADDSTRING, 0, (LPARAM)"From Left (-x)"); + SendDlgItemMessageA(hDlg, IDC_DBG_AMBDIR, CB_ADDSTRING, 0, (LPARAM)"From Right (+x)"); + SendDlgItemMessageA(hDlg, IDC_DBG_AMBDIR, CB_ADDSTRING, 0, (LPARAM)"From Fwd (+z)"); + SendDlgItemMessageA(hDlg, IDC_DBG_AMBDIR, CB_ADDSTRING, 0, (LPARAM)"From Aft (-z)"); + SendDlgItemMessageA(hDlg, IDC_DBG_AMBDIR, CB_SETCURSEL, 0, 0); SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_RESETCONTENT, 0, 0); for (int i = 0; i < 16; i++) { @@ -2192,6 +2205,12 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } break; + case IDC_DBG_AMBDIR: + if (HIWORD(wParam) == CBN_SELCHANGE) { + ambdir = int(SendDlgItemMessage(hDlg, IDC_DBG_AMBDIR, CB_GETCURSEL, 0, 0)) - 1; + } + break; + case IDC_DBG_DISPLAY: if (HIWORD(wParam)==CBN_SELCHANGE) dspMode = DWORD(SendDlgItemMessage(hWnd, IDC_DBG_DISPLAY, CB_GETCURSEL, 0, 0)); break; @@ -2322,6 +2341,8 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case IDC_DBG_CLIPDIST: case IDC_DBG_EXTVC: case IDC_DBG_PICKCURRENT: + case IDC_DBG_NOSUNAMB: + case IDC_DBG_NOPLNAMB: UpdateFlags(); break; diff --git a/OVP/D3D9Client/DebugControls.h b/OVP/D3D9Client/DebugControls.h index c56fb8003..dab521fd0 100644 --- a/OVP/D3D9Client/DebugControls.h +++ b/OVP/D3D9Client/DebugControls.h @@ -64,6 +64,8 @@ #define DBG_FLAGS_NEARCLIP 0x8000 ///< Set Clip distance to 2cm #define DBG_FLAGS_RENDEREXT 0x10000 ///< Render exterior meshes for VC view #define DBG_FLAGS_PICKCURRENT 0x20000 ///< Only use Pick for current mesh +#define DBG_FLAGS_NOSUNAMB 0x40000 ///< Disable sun ambient effect in VC +#define DBG_FLAGS_NOPLNAMB 0x80000 ///< Disable planet shine ambient effect in VC /// @} @@ -73,6 +75,7 @@ class vObject; namespace DebugControls { + extern int ambdir; extern DWORD sMesh; extern DWORD sGroup; extern DWORD debugFlags; diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index 2c2ebdd5c..bddac6e9f 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -569,7 +569,7 @@ void D3D9Mesh::LoadBakedLights() } } - for (int i = 0; i < 16; i++) BakedLightsControl[i] = FVECTOR3(1.0f, 1.0f, 1.0f); + for (int i = 0; i < 16; i++) BakedLightsControl[i] = FVECTOR3(0.0f, 0.0f, 0.0f); bli = BakedLights.begin(); } @@ -658,6 +658,7 @@ void D3D9Mesh::BakeAO(ImageProcessing* pBaker, const FVECTOR3 &vSun, const LVLH FVECTOR3 ParTexCoord[6]; bool bSE[6]; float fShine = 1.0f; + bool bShine = true; // Compute texcoords for Irradiance lookup for prime directions // @@ -675,24 +676,37 @@ void D3D9Mesh::BakeAO(ImageProcessing* pBaker, const FVECTOR3 &vSun, const LVLH // for (int i = 0; i < 6; i++) { - auto tex = bli->second.pSunAO[i]; + bSE[i] = false; + control[i] = 0.0f; + + if (DebugControls::IsActive()) + if ((DebugControls::ambdir != i) && (DebugControls::ambdir != -1)) continue; + + auto tex = bli->second.pSunAO[i]; bSE[i] = (tex != NULL); if (tex) { pBaker->SetTextureNative(i, tex, flags); control[i] = saturate(dot(GetDir(i), vSun)); control[i] *= control[i]; - } - else { - control[i] = 0.0f; - } + } } + if (DebugControls::IsActive()) { + if (DebugControls::debugFlags & DBG_FLAGS_NOSUNAMB) + for (int i = 0; i < 6; i++) control[i] = 0; + if (DebugControls::debugFlags & DBG_FLAGS_NOPLNAMB) + fShine = 0.0f, bShine = false; + } + + if (pIrrad == nullptr) fShine = 0.0f, bShine = false; + pBaker->SetTextureNative("tIrrad", pIrrad, IPF_LINEAR | IPF_CLAMP); pBaker->SetFloat("fControl", control, sizeof(control)); pBaker->SetFloat("vParTexPos", ParTexCoord, sizeof(ParTexCoord)); pBaker->SetFloat("fShine", &fShine, sizeof(fShine)); pBaker->SetBool("bEnabled", bSE, sizeof(bSE)); + pBaker->SetBool("bShine", &bShine, sizeof(bShine)); LPDIRECT3DSURFACE9 pSrf = NULL; diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index b8605080b..2177a8269 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -716,6 +716,8 @@ void vVessel::BakeLights(ImageProcessing *pBaker) lvlh.East = tmul(FVECTOR4(lvlh.East, 0), mW).xyz; lvlh.North = tmul(FVECTOR4(lvlh.North, 0), mW).xyz; + auto maps = GetEnvMap(); + for (int i = 0; i < nmesh; i++) { if (!meshlist[i].mesh) continue; @@ -723,7 +725,7 @@ void vVessel::BakeLights(ImageProcessing *pBaker) { auto vSun = tmul(FVECTOR4(sundir, 0), mW); meshlist[i].mesh->BakeLights(pBaker); - meshlist[i].mesh->BakeAO(pBaker, vSun.xyz, lvlh, ecDefExt.tex.pIrrad); + meshlist[i].mesh->BakeAO(pBaker, vSun.xyz, lvlh, maps->pIrrad); } } } diff --git a/OVP/D3D9Client/resource.h b/OVP/D3D9Client/resource.h index cd6394536..104e1df14 100644 --- a/OVP/D3D9Client/resource.h +++ b/OVP/D3D9Client/resource.h @@ -239,3 +239,6 @@ #define IDC_DBG_DYNAMIC 3056 #define IDC_DBG_ISVCMESH 3057 #define IDC_DBG_VCSHADOW 3058 +#define IDC_DBG_AMBDIR 3059 +#define IDC_DBG_NOSUNAMB 3060 +#define IDC_DBG_NOPLNAMB 3061 diff --git a/OVP/D3D9Client/shaders/PreBakeLights.hlsl b/OVP/D3D9Client/shaders/PreBakeLights.hlsl index 5f43bc209..3430c5f95 100644 --- a/OVP/D3D9Client/shaders/PreBakeLights.hlsl +++ b/OVP/D3D9Client/shaders/PreBakeLights.hlsl @@ -8,6 +8,7 @@ uniform extern float3 fControl[16]; uniform extern int iCount; uniform extern bool bEnabled[6]; uniform extern float fShine; +uniform extern bool bShine; sampler tMap[16] : register(s0); // Lightmaps sampler tAO[6] : register(s0); // AO Textures for prime directions @@ -60,11 +61,13 @@ float4 PSSunAO(float x : TEXCOORD0, float y : TEXCOORD1) : COLOR // For a given pixel in texture (x,y) [unroll] for (int i = 0; i < 6; i++) { // Browse through direction - if (bEnabled[i]) { - // Get planet shine color for a given direction 'i' - float3 cShine = ParaboloidalSampler(tIrrad, vParTexPos[i]).rgb; + if (bEnabled[i]) { // Get ambient distribution inside VC for a given light direction 'i' float3 ad = tex2D(tAO[i], float2(x, y)).rgb; + + float3 cShine = 0.0f; + // Get planet shine color for a given direction 'i' + if (bShine) cShine = ParaboloidalSampler(tIrrad, vParTexPos[i]).rgb; // Compute sunlight and planet shine factors float3 shineAO = ad * cShine * fShine; float3 sunAO = ad * fControl[i]; From 8c8055fea4f699f126676816b64eb1970db17260 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Wed, 24 Jan 2024 23:13:15 +0200 Subject: [PATCH 30/42] Renamed GetObject() function to avoid mixup with Windows macro. Moved oapiMeshProperty function to VESSEL interface as SetVisualProperty() --- OVP/D3D9Client/AtmoControls.cpp | 2 +- OVP/D3D9Client/BeaconArray.cpp | 2 +- OVP/D3D9Client/D3D9Client.cpp | 30 +++-------------- OVP/D3D9Client/D3D9Client.h | 4 +-- OVP/D3D9Client/D3D9Pad.cpp | 2 +- OVP/D3D9Client/DebugControls.cpp | 37 ++++++++++---------- OVP/D3D9Client/MaterialMgr.cpp | 6 ++-- OVP/D3D9Client/Mesh.cpp | 32 +----------------- OVP/D3D9Client/Mesh.h | 6 +--- OVP/D3D9Client/RunwayLights.cpp | 4 +-- OVP/D3D9Client/Scene.cpp | 6 ++-- OVP/D3D9Client/VPlanet.cpp | 4 +-- OVP/D3D9Client/VVessel.cpp | 58 ++++++++++++++++++++++++++++++-- OVP/D3D9Client/VVessel.h | 7 ++++ OVP/D3D9Client/gcCore.cpp | 2 +- Orbitersdk/include/GraphicsAPI.h | 2 +- Orbitersdk/include/OrbiterAPI.h | 9 ----- Orbitersdk/include/VesselAPI.h | 18 ++++++++++ Src/Orbiter/OrbiterAPI.cpp | 6 ---- Src/Orbiter/Vessel.cpp | 6 ++++ 20 files changed, 128 insertions(+), 115 deletions(-) diff --git a/OVP/D3D9Client/AtmoControls.cpp b/OVP/D3D9Client/AtmoControls.cpp index e4ec33b13..5ba9060f5 100644 --- a/OVP/D3D9Client/AtmoControls.cpp +++ b/OVP/D3D9Client/AtmoControls.cpp @@ -390,7 +390,7 @@ void SetVisual(vObject *vo) if (!hDlg || !dwCmd) return; - OBJHANDLE hObj = vo->GetObjectA(); + OBJHANDLE hObj = vo->GetObjHandle(); if (oapiGetObjectType(hObj)!=OBJTP_PLANET) { LogErr("Invalid Object Type in AtmoControls"); diff --git a/OVP/D3D9Client/BeaconArray.cpp b/OVP/D3D9Client/BeaconArray.cpp index 3c8092f1d..2ac94e1db 100644 --- a/OVP/D3D9Client/BeaconArray.cpp +++ b/OVP/D3D9Client/BeaconArray.cpp @@ -27,7 +27,7 @@ BeaconArray::BeaconArray(BeaconArrayEntry *pEnt, DWORD nEntry, vBase *_vB) { _TRACE; - if (vB) hBase = vB->GetObject(); + if (vB) hBase = vB->GetObjHandle(); pBeaconPos = new BeaconPos[nEntry]; diff --git a/OVP/D3D9Client/D3D9Client.cpp b/OVP/D3D9Client/D3D9Client.cpp index 1c0f832b7..bff0e8cf4 100644 --- a/OVP/D3D9Client/D3D9Client.cpp +++ b/OVP/D3D9Client/D3D9Client.cpp @@ -1512,32 +1512,10 @@ bool D3D9Client::clbkSetMeshProperty(DEVMESHHANDLE hMesh, DWORD prop, DWORD valu // ============================================================== -bool D3D9Client::clbkSetMeshProperty(DEVMESHHANDLE hMesh, MeshProp prp, const oapi::FVECTOR4& value) +void D3D9Client::clbkSetVisualProperty(VISHANDLE vis, VesselProp prp, int idx, const type_info& t, const void* val) { - D3D9Mesh* mesh = (D3D9Mesh*)hMesh; - switch (prp) { - case MeshProp::BAKED_0: mesh->SetBakedLightLevel(0, value.xyz); return true; - case MeshProp::BAKED_1: mesh->SetBakedLightLevel(1, value.xyz); return true; - case MeshProp::BAKED_2: mesh->SetBakedLightLevel(2, value.xyz); return true; - case MeshProp::BAKED_3: mesh->SetBakedLightLevel(3, value.xyz); return true; - case MeshProp::BAKED_4: mesh->SetBakedLightLevel(4, value.xyz); return true; - case MeshProp::BAKED_5: mesh->SetBakedLightLevel(5, value.xyz); return true; - case MeshProp::BAKED_6: mesh->SetBakedLightLevel(6, value.xyz); return true; - case MeshProp::BAKED_7: mesh->SetBakedLightLevel(7, value.xyz); return true; - case MeshProp::BAKED_8: mesh->SetBakedLightLevel(8, value.xyz); return true; - case MeshProp::BAKED_9: mesh->SetBakedLightLevel(9, value.xyz); return true; - case MeshProp::BAKED_10: mesh->SetBakedLightLevel(10, value.xyz); return true; - case MeshProp::BAKED_11: mesh->SetBakedLightLevel(11, value.xyz); return true; - case MeshProp::BAKED_12: mesh->SetBakedLightLevel(12, value.xyz); return true; - case MeshProp::BAKED_13: mesh->SetBakedLightLevel(13, value.xyz); return true; - case MeshProp::BAKED_14: mesh->SetBakedLightLevel(14, value.xyz); return true; - case MeshProp::BAKED_15: mesh->SetBakedLightLevel(15, value.xyz); return true; - case MeshProp::AMBIENT: mesh->SetAmbientColor(value.xyz); return true; - default: - oapiWriteLogV("oapiSetMeshProperty() FAILED: unknown property %u", DWORD(prp)); - break; - } - return false; + vVessel* vV = (vVessel*)vis; + if (vV && vV->Type() == OBJTP_VESSEL) vV->SetVisualProperty(prp, idx, t, val); } // ============================================================== @@ -1782,7 +1760,7 @@ LRESULT D3D9Client::RenderWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l if (bPckVsl) { gcCore::PickData out; - out.hVessel = pick.vObj->GetObjectA(); + out.hVessel = pick.vObj->GetObjHandle(); out.mesh = MESHHANDLE(pick.pMesh); out.group = pick.group; out.pos = _FV(pick.pos); diff --git a/OVP/D3D9Client/D3D9Client.h b/OVP/D3D9Client/D3D9Client.h index 2fc01f125..14f8e16c7 100644 --- a/OVP/D3D9Client/D3D9Client.h +++ b/OVP/D3D9Client/D3D9Client.h @@ -426,7 +426,7 @@ class D3D9Client : public GraphicsClient * \default None, returns \e false. */ bool clbkSetMeshProperty (DEVMESHHANDLE hMesh, DWORD property, DWORD value); - bool clbkSetMeshProperty(DEVMESHHANDLE hMesh, MeshProp prp, const oapi::FVECTOR4& value); + void clbkSetVisualProperty(VISHANDLE vis, VesselProp prp, int idx, const type_info& t, const void* val); /** * \brief React to vessel docking, attaching events @@ -1472,7 +1472,7 @@ class VisObject { * \brief Returns the object handle associated with the visual. * \return Object handle */ - OBJHANDLE GetObject () const { return hObj; } + OBJHANDLE GetObjHandle () const { return hObj; } /** * \brief Message callback. diff --git a/OVP/D3D9Client/D3D9Pad.cpp b/OVP/D3D9Client/D3D9Pad.cpp index 6b04fecc3..93ba15160 100644 --- a/OVP/D3D9Client/D3D9Pad.cpp +++ b/OVP/D3D9Client/D3D9Pad.cpp @@ -788,7 +788,7 @@ Font *D3D9Pad::SetFont(Font *font) #ifdef SKPDBG LOGFONTA lf; - GetObjectA(font->GetGDIFont(), sizeof(LOGFONT), &lf); + GetObjHandle(font->GetGDIFont(), sizeof(LOGFONT), &lf); Log("SetFont(%s) Face=[%s] Height=%d Weight=%d", _PTR(font), lf.lfFaceName, lf.lfHeight, lf.lfWeight); #endif // No "Change" falgs required here, covered in SetFontTextureNative() diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index 765d866ff..e79b15d42 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -796,7 +796,7 @@ float _Clamp(float value, DWORD p, DWORD v) // void UpdateShader() { - OBJHANDLE hObj = vObj->GetObjectA(); + OBJHANDLE hObj = vObj->GetObjHandle(); if (!oapiIsVessel(hObj)) return; @@ -924,7 +924,7 @@ void NextDoNotRender() // void UpdateMeshMaterial(float value, DWORD MatPrp, DWORD clr) { - OBJHANDLE hObj = vObj->GetObjectA(); + OBJHANDLE hObj = vObj->GetObjHandle(); if (!oapiIsVessel(hObj)) return; if (!hSelMesh) return; @@ -1037,7 +1037,7 @@ DWORD GetModFlags(DWORD MatPrp) // bool IsMaterialModified(DWORD MatPrp) { - OBJHANDLE hObj = vObj->GetObjectA(); + OBJHANDLE hObj = vObj->GetObjHandle(); if (!oapiIsVessel(hObj)) return false; if (!hSelMesh) return false; @@ -1054,7 +1054,7 @@ bool IsMaterialModified(DWORD MatPrp) // void SetMaterialModified(DWORD MatPrp, bool bState) { - OBJHANDLE hObj = vObj->GetObjectA(); + OBJHANDLE hObj = vObj->GetObjHandle(); if (!oapiIsVessel(hObj)) return; if (!hSelMesh) return; @@ -1075,7 +1075,7 @@ void SetMaterialModified(DWORD MatPrp, bool bState) // float GetMaterialValue(DWORD MatPrp, DWORD clr) { - OBJHANDLE hObj = vObj->GetObjectA(); + OBJHANDLE hObj = vObj->GetObjHandle(); if (!oapiIsVessel(hObj)) return 0.0f; if (!hSelMesh) return 0.0f; @@ -1262,7 +1262,7 @@ void UpdateMaterialDisplay(bool bSetup) char lbl[256]; char lbl2[64]; - OBJHANDLE hObj = vObj->GetObjectA(); + OBJHANDLE hObj = vObj->GetObjHandle(); if (!oapiIsVessel(hObj)) return; if (!hSelMesh) return; @@ -1496,11 +1496,11 @@ void SetupMeshGroups() // void UpdateBakedLights(float lvl) { - if (hSelMesh) { - if (bkl_id < 16 && bkl_id >= 0) { - hSelMesh->SetBakedLightLevel(bkl_id, FVECTOR3(lvl, lvl, lvl)); - } - if (bkl_id == 16) hSelMesh->SetAmbientColor(FVECTOR3(lvl, lvl, lvl)); + vVessel* vV = (vVessel*)vObj; + if (vObj->Type() == OBJTP_VESSEL) { + if (bkl_id < 16 && bkl_id >= 0) + vV->SetVisualProperty(VesselProp::BAKED_LIGHT, bkl_id, typeid(FVECTOR3), &FVECTOR3(lvl, lvl, lvl)); + if (bkl_id == 16) vV->SetVisualProperty(VesselProp::AMBIENT, 0, typeid(FVECTOR3), &FVECTOR3(lvl, lvl, lvl)); } } @@ -1508,11 +1508,12 @@ void UpdateBakedLights(float lvl) // void UpdateLightsSlider() { - float val = 0.0f; - if (hSelMesh) { - if (bkl_id < 16 && bkl_id >= 0) val = hSelMesh->GetBakedLightLevel(bkl_id).x; - if (bkl_id == 16) val = hSelMesh->GetAmbientColor().x; - SendDlgItemMessage(hDlg, IDC_DBG_BKLADJ, TBM_SETPOS, 1, WORD(255.0f * val)); + FVECTOR3 val = 0.0f; + vVessel* vV = (vVessel*)vObj; + if (vObj->Type() == OBJTP_VESSEL) { + if (bkl_id < 16 && bkl_id >= 0) vV->GetVisualProperty(VesselProp::BAKED_LIGHT, bkl_id, typeid(val), &val); + if (bkl_id == 16) vV->GetVisualProperty(VesselProp::AMBIENT, 0, typeid(val), &val); + SendDlgItemMessage(hDlg, IDC_DBG_BKLADJ, TBM_SETPOS, 1, WORD(255.0f * val.x)); } } @@ -1532,7 +1533,7 @@ LPDIRECT3DTEXTURE9 GetCombinedMap() double GetVisualSize() { if (hDlg && vObj) { - OBJHANDLE hObj = vObj->GetObjectA(); + OBJHANDLE hObj = vObj->GetObjHandle(); if (hObj) return oapiGetSize(hObj); } return 1.0; @@ -2091,7 +2092,7 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case IDC_DBG_MATSAVE: { - OBJHANDLE hObj = vObj->GetObjectA(); + OBJHANDLE hObj = vObj->GetObjHandle(); if (oapiIsVessel(hObj)) { vVessel *vVes = (vVessel *)vObj; vVes->GetMaterialManager()->SaveConfiguration(); diff --git a/OVP/D3D9Client/MaterialMgr.cpp b/OVP/D3D9Client/MaterialMgr.cpp index e86282430..7bc11f4c1 100644 --- a/OVP/D3D9Client/MaterialMgr.cpp +++ b/OVP/D3D9Client/MaterialMgr.cpp @@ -127,7 +127,7 @@ bool MatMgr::LoadConfiguration(bool bAppend) char meshname[64]; char shadername[64]; - OBJHANDLE hObj = vObj->GetObjectA(); + OBJHANDLE hObj = vObj->GetObjHandle(); if (oapiGetObjectType(hObj)!=OBJTP_VESSEL) return false; @@ -291,7 +291,7 @@ bool MatMgr::SaveConfiguration() char classname[256]; - OBJHANDLE hObj = vObj->GetObjectA(); + OBJHANDLE hObj = vObj->GetObjHandle(); if (oapiGetObjectType(hObj)!=OBJTP_VESSEL) return false; @@ -361,7 +361,7 @@ bool MatMgr::LoadCameraConfig() char path[256]; char classname[256]; - OBJHANDLE hObj = vObj->GetObjectA(); + OBJHANDLE hObj = vObj->GetObjHandle(); if (oapiGetObjectType(hObj)!=OBJTP_VESSEL) return false; diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index bddac6e9f..3f181d98d 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -205,7 +205,6 @@ void D3D9Mesh::Null(const char *meshName /* = NULL */) bIsReflective = false; bCanRenderFast = false; bMtrlModidied = false; - bMustRebake = true; bli = BakedLights.begin(); @@ -523,8 +522,6 @@ void D3D9Mesh::ClearBake(int i) void D3D9Mesh::LoadBakedLights() { if (BakedLights.size()) return; // Already Loaded, skip the rest - - bMustRebake = true; char id[32]; for (int i = 0; i < nTex; i++) @@ -569,41 +566,16 @@ void D3D9Mesh::LoadBakedLights() } } - for (int i = 0; i < 16; i++) BakedLightsControl[i] = FVECTOR3(0.0f, 0.0f, 0.0f); - bli = BakedLights.begin(); } // =========================================================================================== // -void D3D9Mesh::SetBakedLightLevel(int idx, const FVECTOR3 &level) -{ - if (idx >= 0 && idx <= 15) { - if (BakedLightsControl[idx] != level) { - BakedLightsControl[idx] = level; - bMustRebake = true; - } - } -} - - -// =========================================================================================== -// -FVECTOR3 D3D9Mesh::GetBakedLightLevel(int idx) -{ - if (idx >= 0 && idx <= 15) return BakedLightsControl[idx]; - return FVECTOR3(1, 1, 1); -} - - -// =========================================================================================== -// -void D3D9Mesh::BakeLights(ImageProcessing* pBaker) +void D3D9Mesh::BakeLights(ImageProcessing* pBaker, const FVECTOR3* BakedLightsControl) { if (!pBaker->IsOK()) return; // Baker not initialized if (DefShader != SHADER_BAKED_VC) return; // Not supported by shader - if (!bMustRebake) return; // Allready Done if (BakedLights.size() == 0) return; // Nothing to bake DWORD flags = IPF_POINT | IPF_CLAMP; @@ -640,8 +612,6 @@ void D3D9Mesh::BakeLights(ImageProcessing* pBaker) } } } - - bMustRebake = false; // Done } diff --git a/OVP/D3D9Client/Mesh.h b/OVP/D3D9Client/Mesh.h index 0c35ca25a..34eee72b6 100644 --- a/OVP/D3D9Client/Mesh.h +++ b/OVP/D3D9Client/Mesh.h @@ -222,10 +222,8 @@ class D3D9Mesh : private D3D9Effect void Release(); void ClearBake(int i); void LoadBakedLights(); - void BakeLights(ImageProcessing *pBaker); + void BakeLights(ImageProcessing *pBaker, const FVECTOR3* BakedLightsControl); void BakeAO(ImageProcessing* pBaker, const FVECTOR3 &vSun, const LVLH& lvlh, const LPDIRECT3DTEXTURE9 pIrrad); - void SetBakedLightLevel(int idx, const FVECTOR3 &level); - FVECTOR3 GetBakedLightLevel(int idx); void LoadMeshFromHandle(MESHHANDLE hMesh, D3DXVECTOR3 *reorig = NULL, float *scale = NULL); void ReLoadMeshFromHandle(MESHHANDLE hMesh); void ReloadTextures(); @@ -384,7 +382,6 @@ class D3D9Mesh : private D3D9Effect std::map::const_iterator bli; std::vector env_cams; - FVECTOR3 BakedLightsControl[16]; D3DXMATRIX mTransform; D3DXMATRIX mTransformInv; D3DXMATRIX *pGrpTF; @@ -398,7 +395,6 @@ class D3D9Mesh : private D3D9Effect bool bBSRecomputeAll; bool bModulateMatAlpha; // mix material and texture alpha channels bool bGlobalTF; // Mesh has a valid mTransform matrix - bool bMustRebake; // Must run BakeTextures before rendering char name[128]; diff --git a/OVP/D3D9Client/RunwayLights.cpp b/OVP/D3D9Client/RunwayLights.cpp index 7689b2f1f..bfa622419 100644 --- a/OVP/D3D9Client/RunwayLights.cpp +++ b/OVP/D3D9Client/RunwayLights.cpp @@ -2,7 +2,7 @@ // RunwayLights.cpp // Part of the ORBITER VISUALISATION PROJECT (OVP) D3D9 Client // Dual licensed under GPL v3 and LGPL v3 -// Copyright (C) 2012 - 2016 Émile "Bibi Uncle" Grégoire +// Copyright (C) 2012 - 2016 Émile "Bibi Uncle" Grégoire // 2012 - 2016 Jarmo Nikkanen // ============================================================== @@ -33,7 +33,7 @@ RunwayLights::RunwayLights(class vBase *_vB, const class Scene *scn) apr_length = 257.0; iCategory = 0; nPAPI = 0; - hObj = vB->GetObjectA(); + hObj = vB->GetObjHandle(); nVASI = 0; bSingleEnded = false; bDisp2 = false; diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index 6adaca9e0..570245ccd 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -662,7 +662,7 @@ void Scene::DelVisualRec (VOBJREC *pv) DebugControls::RemoveVisual(pv->vobj); // delete the visual, its children and the entry itself - gc->UnregisterVisObject(pv->vobj->GetObject()); + gc->UnregisterVisObject(pv->vobj->GetObjHandle()); if (pv->type == OBJTP_VESSEL) gc->clbkScenarioChanged(pv->vobj, ScnChgEvent::VisualDeleted); delete pv->vobj; delete pv; @@ -679,7 +679,7 @@ void Scene::DeleteAllVisuals() DebugControls::RemoveVisual(pv->vobj); - gc->UnregisterVisObject(pv->vobj->GetObject()); + gc->UnregisterVisObject(pv->vobj->GetObjHandle()); LogAlw("Deleting Visual %s", _PTR(pv->vobj)); delete pv->vobj; @@ -1371,7 +1371,7 @@ void Scene::clbkRenderMainScene() { if (camCurrent == CustomCams.cend()) camCurrent = CustomCams.cbegin(); - OBJHANDLE hVessel = vFocus->GetObjectA(); + OBJHANDLE hVessel = vFocus->GetObjHandle(); vObject *vO = GetVisObject((*camCurrent)->hVessel); double maxd = min(500e3, GetCameraAltitude() + 15e3); diff --git a/OVP/D3D9Client/VPlanet.cpp b/OVP/D3D9Client/VPlanet.cpp index 1d5867083..037a2b122 100644 --- a/OVP/D3D9Client/VPlanet.cpp +++ b/OVP/D3D9Client/VPlanet.cpp @@ -895,8 +895,8 @@ bool vPlanet::Render(LPDIRECT3DDEVICE9 dev) DWORD displ = *(DWORD*)gc->GetConfigParam(CFGPRM_GETDISPLAYMODE); vObject *vSel = DebugControls::GetVisual(); if (vSel && displ>0) { - if (vSel->GetObjectA()) { - if (oapiGetObjectType(vSel->GetObjectA())==OBJTP_VESSEL) return false; + if (vSel->GetObjHandle()) { + if (oapiGetObjectType(vSel->GetObjHandle())==OBJTP_VESSEL) return false; } } } diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index 2177a8269..0abc4eb63 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -97,8 +97,11 @@ vVessel::vVessel(OBJHANDLE _hObj, const Scene *scene): vObject (_hObj, scene) for (UINT k = 0; k < anim[i].ncomp; ++k) LogComp(anim[i].comp[k], 2); }*/ - UpdateAnimations(); + + for (int i = 0; i < 16; i++) BakedLightsControl[i] = FVECTOR3(0.0f, 0.0f, 0.0f); + VCAmbient = FVECTOR3(0.5f, 0.5f, 0.5f); + bMustRebake = true; } @@ -721,13 +724,15 @@ void vVessel::BakeLights(ImageProcessing *pBaker) for (int i = 0; i < nmesh; i++) { if (!meshlist[i].mesh) continue; - if (meshlist[i].vismode & MESHVIS_VC) + if (meshlist[i].vismode & MESHVIS_VC) // TODO: Should check Shader type { auto vSun = tmul(FVECTOR4(sundir, 0), mW); - meshlist[i].mesh->BakeLights(pBaker); + if (bMustRebake) meshlist[i].mesh->BakeLights(pBaker, BakedLightsControl); meshlist[i].mesh->BakeAO(pBaker, vSun.xyz, lvlh, maps->pIrrad); } } + + bMustRebake = false; } @@ -1811,7 +1816,54 @@ void vVessel::AnimateComponent (ANIMATIONCOMP *comp, const D3DXMATRIX &T) // ============================================================================================ // +void vVessel::SetVisualProperty(VesselProp prp, int idx, const type_info& t, const void* val) +{ + if (t == typeid(FVECTOR3)) + { + FVECTOR3* v = (FVECTOR3*)val; + + if (prp == VesselProp::BAKED_LIGHT) { + if (idx >= 0 && idx <= 15) { + if (BakedLightsControl[idx] != *v) { + BakedLightsControl[idx] = *v; + bMustRebake = true; + } + } + return; + } + + if (prp == VesselProp::AMBIENT) { + VCAmbient = *v; + return; + } + } + oapiWriteLogV("Failed to set visual property prp=%d, type=[%s]", int(prp), t.name()); +} + + +// ============================================================================================ +// +bool vVessel::GetVisualProperty(VesselProp prp, int idx, const type_info& t, void* val) +{ + if (t == typeid(FVECTOR3)) + { + if (prp == VesselProp::BAKED_LIGHT) if (idx >= 0 && idx <= 15) { + *((FVECTOR3*)val) = BakedLightsControl[idx]; + return true; + } + + if (prp == VesselProp::AMBIENT) { + *((FVECTOR3*)val) = VCAmbient; + return true; + } + } + return false; +} + + +// ============================================================================================ +// void vVessel::RenderReentry(LPDIRECT3DDEVICE9 dev) { diff --git a/OVP/D3D9Client/VVessel.h b/OVP/D3D9Client/VVessel.h index 7edb8cbe6..126aee9bc 100644 --- a/OVP/D3D9Client/VVessel.h +++ b/OVP/D3D9Client/VVessel.h @@ -166,6 +166,10 @@ class vVessel: public vObject { */ void UpdateAnimations(int mshidx = -1); + void SetVisualProperty(VesselProp prp, int idx, const type_info& t, const void* val); + bool GetVisualProperty(VesselProp prp, int idx, const type_info& t, void* val); + + protected: void LoadMeshes(); @@ -215,6 +219,9 @@ class vVessel: public vObject { // Default eCam configurations ENVCAMREC ecDefExt, ecDefVC; + FVECTOR3 BakedLightsControl[16]; + FVECTOR3 VCAmbient; + bool bMustRebake; VESSEL *vessel; // access instance for the vessel class MatMgr *pMatMgr; diff --git a/OVP/D3D9Client/gcCore.cpp b/OVP/D3D9Client/gcCore.cpp index 7c9330d6a..875ddc3b9 100644 --- a/OVP/D3D9Client/gcCore.cpp +++ b/OVP/D3D9Client/gcCore.cpp @@ -612,7 +612,7 @@ gcCore::PickGround gcCore2::GetTileData(HPLANETMGR vPl, double lng, double lat, pTile->GetElevation(lng, lat, &pg.elev, &pg.normal, NULL, true, false); VECTOR3 pos = vP->GetUnitSurfacePos(lng, lat) * (vP->GetSize() + pg.elev); - MATRIX3 mRot; oapiGetRotationMatrix(vP->GetObjectA(), &mRot); + MATRIX3 mRot; oapiGetRotationMatrix(vP->GetObjHandle(), &mRot); pos = mul(mRot, pos) + vP->PosFromCamera(); diff --git a/Orbitersdk/include/GraphicsAPI.h b/Orbitersdk/include/GraphicsAPI.h index 7f29d4616..36c64d36a 100644 --- a/Orbitersdk/include/GraphicsAPI.h +++ b/Orbitersdk/include/GraphicsAPI.h @@ -616,7 +616,6 @@ class OAPIFUNC GraphicsClient: public Module { * \default None, returns \e false. */ virtual bool clbkSetMeshProperty(DEVMESHHANDLE hMesh, DWORD property, DWORD value) { return false; } - virtual bool clbkSetMeshProperty(DEVMESHHANDLE hMesh, MeshProp prp, const oapi::FVECTOR4 &value) { return false; } // ================================================================== /// \name Visual object interface @@ -680,6 +679,7 @@ class OAPIFUNC GraphicsClient: public Module { * \sa RegisterVisObject, UnregisterVisObject, visevent */ virtual int clbkVisEvent (OBJHANDLE hObj, VISHANDLE vis, DWORD msg, DWORD_PTR context); + virtual void clbkSetVisualProperty(VISHANDLE vis, VesselProp prp, int idx, const type_info& t, const void* val) { } /** * \brief Return a mesh handle for a visual, defined by its index diff --git a/Orbitersdk/include/OrbiterAPI.h b/Orbitersdk/include/OrbiterAPI.h index 18fbfe146..69bb90697 100644 --- a/Orbitersdk/include/OrbiterAPI.h +++ b/Orbitersdk/include/OrbiterAPI.h @@ -480,14 +480,6 @@ enum class ScnChgEvent { VisualDeleted = 9 ///< Vessel visual deleted }; -enum class MeshProp { - BAKED_0, BAKED_1, BAKED_2, BAKED_3, BAKED_4, ///< baked light level - BAKED_5, BAKED_6, BAKED_7, BAKED_8, BAKED_9, ///< baked light level - BAKED_10, BAKED_11, BAKED_12, BAKED_13, ///< baked light level - BAKED_14, BAKED_15, ///< baked light level - AMBIENT ///< ambient light level -}; - /** * \brief Kepler orbital elements * @@ -4868,7 +4860,6 @@ OAPIFUNC bool oapiGetMeshProperty (MESHHANDLE hMesh, DWORD property, DWORD *valu * \sa oapiSetMeshProperty(MESHHANDLE,DWORD,DWORD) */ OAPIFUNC bool oapiSetMeshProperty (DEVMESHHANDLE hMesh, DWORD property, DWORD value); -OAPIFUNC bool oapiSetMeshProperty (DEVMESHHANDLE hMesh, MeshProp prop, const oapi::FVECTOR4 &value); // Particle functions /** diff --git a/Orbitersdk/include/VesselAPI.h b/Orbitersdk/include/VesselAPI.h index 041451c6e..1d03a682e 100644 --- a/Orbitersdk/include/VesselAPI.h +++ b/Orbitersdk/include/VesselAPI.h @@ -26,6 +26,8 @@ #define FRAME_ECL 0 #define FRAME_EQU 1 +#include + class Vessel; // Orbiter internal vessel class class SuperVessel; // Orbiter internal supervessel class @@ -40,6 +42,13 @@ typedef struct { double mu_lng; ///< longitudinal friction coefficient (only used for first 3 points) } TOUCHDOWNVTX; +enum class VesselProp { + BAKED_LIGHT, ///< baked light level + AMBIENT, ///< ambient light level + EXT_PROBE_POS, ///< Exterior probe position + VC_PROBE_POS ///< Virtual cockpit probe position +}; + // ====================================================================== /** * \brief Base class for objects of vessel type (spacecraft and similar) @@ -3833,6 +3842,15 @@ class OAPIFUNC VESSEL { */ void SetMeshVisibilityMode (UINT idx, WORD mode) const; + /** + * \brief Set vessel visual propery + * \param vis visual object handle + * \param prp property id + * \param idx index of property + * \param val value to be set + */ + void SetVisualProperty(VISHANDLE vis, VesselProp prp, int idx, const type_info &t, const void *val); + /** * \brief Affine transformation of a mesh group. * \param vis vessel visual handle diff --git a/Src/Orbiter/OrbiterAPI.cpp b/Src/Orbiter/OrbiterAPI.cpp index 0fcf01e65..396beac0f 100644 --- a/Src/Orbiter/OrbiterAPI.cpp +++ b/Src/Orbiter/OrbiterAPI.cpp @@ -1419,12 +1419,6 @@ DLLEXPORT DWORD oapiMeshTextureCount (MESHHANDLE hMesh) return ((Mesh*)hMesh)->nTexture(); } -DLLEXPORT void oapiMeshProperty(DEVMESHHANDLE hMesh, MeshProp prp, const oapi::FVECTOR4 &value) -{ - oapi::GraphicsClient* gc = g_pOrbiter->GetGraphicsClient(); - if (gc) gc->clbkSetMeshProperty(hMesh, prp, value); -} - DLLEXPORT SURFHANDLE oapiGetTextureHandle (MESHHANDLE hMesh, DWORD texidx) { Mesh *mesh = (Mesh*)hMesh; diff --git a/Src/Orbiter/Vessel.cpp b/Src/Orbiter/Vessel.cpp index 48e798b36..99a581762 100644 --- a/Src/Orbiter/Vessel.cpp +++ b/Src/Orbiter/Vessel.cpp @@ -7679,6 +7679,12 @@ void VESSEL::SetMeshVisibilityMode (UINT idx, WORD mode) const vessel->SetMeshVisibilityMode (idx, mode); } +void VESSEL::SetVisualProperty(VISHANDLE vis, VesselProp prp, int idx, const type_info& t, const void* val) +{ + oapi::GraphicsClient* gc = g_pOrbiter->GetGraphicsClient(); + gc->clbkSetVisualProperty(vis, prp, idx, t, val); +} + void VESSEL::SetMeshVisibleInternal (UINT idx, bool visible) const { vessel->SetMeshVisibilityMode (idx, visible ? MESHVIS_ALWAYS : MESHVIS_EXTERNAL); From 80da3af67c49a2d6eed526b7a82a3fea79c25847 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Thu, 25 Jan 2024 08:14:18 +0200 Subject: [PATCH 31/42] Created a stage-set for object rendering. --- Meshes/D3D9Cube.msh | 27 +++++++++++ OVP/D3D9Client/CMakeLists.txt | 1 + OVP/D3D9Client/D3D9Client.cpp | 3 +- OVP/D3D9Client/D3D9Client.h | 2 +- OVP/D3D9Client/D3D9Util.cpp | 8 ++-- OVP/D3D9Client/D3D9Util.h | 12 ++--- OVP/D3D9Client/DebugControls.cpp | 8 ++-- OVP/D3D9Client/Mesh.h | 2 +- OVP/D3D9Client/Scene.cpp | 72 +++++++++++++++++++++++++----- OVP/D3D9Client/Scene.h | 21 +++++++-- OVP/D3D9Client/VVessel.cpp | 37 ++++++++++----- OVP/D3D9Client/VVessel.h | 4 +- OVP/D3D9Client/shaders/Custom.hlsl | 48 ++++++++++++++++++++ Orbitersdk/include/GraphicsAPI.h | 2 +- Orbitersdk/include/VesselAPI.h | 4 +- Src/Orbiter/Vessel.cpp | 2 +- 16 files changed, 205 insertions(+), 48 deletions(-) create mode 100644 Meshes/D3D9Cube.msh create mode 100644 OVP/D3D9Client/shaders/Custom.hlsl diff --git a/Meshes/D3D9Cube.msh b/Meshes/D3D9Cube.msh new file mode 100644 index 000000000..7298a2268 --- /dev/null +++ b/Meshes/D3D9Cube.msh @@ -0,0 +1,27 @@ +MSHX1 +GROUPS 1 +LABEL Cube +MATERIAL 0 +GEOM 8 12 +1.0 -1.0 1.0 -0.5773491859436035 0.5773491859436035 -0.5773491859436035 +1.0 1.0 1.0 -0.5773491859436035 -0.5773491859436035 -0.5773491859436035 +1.0 -1.0 -1.0 -0.5773491859436035 0.5773491859436035 0.5773491859436035 +1.0 1.0 -1.0 -0.5773491859436035 -0.5773491859436035 0.5773491859436035 +-1.0 -1.0 1.0 0.5773491859436035 0.5773491859436035 -0.5773491859436035 +-1.0 1.0 1.0 0.5773491859436035 -0.5773491859436035 -0.5773491859436035 +-1.0 -1.0 -1.0 0.5773491859436035 0.5773491859436035 0.5773491859436035 +-1.0 1.0 -1.0 0.5773491859436035 -0.5773491859436035 0.5773491859436035 +0 3 2 +3 0 1 +2 7 6 +7 2 3 +6 5 4 +5 6 7 +4 1 0 +1 4 5 +2 4 0 +4 2 6 +7 1 5 +1 7 3 +MATERIALS 0 +TEXTURES 0 \ No newline at end of file diff --git a/OVP/D3D9Client/CMakeLists.txt b/OVP/D3D9Client/CMakeLists.txt index f63f0bdda..aa52653a1 100644 --- a/OVP/D3D9Client/CMakeLists.txt +++ b/OVP/D3D9Client/CMakeLists.txt @@ -143,6 +143,7 @@ set(ShaderFiles ${ShaderDir}/Scatter.hlsl ${ShaderDir}/Glare.hlsl ${ShaderDir}/PreBakeLights.hlsl + ${ShaderDir}/Custom.hlsl ${ShaderDir}/Mesh.fx ${ShaderDir}/Metalness.fx ${ShaderDir}/Particle.fx diff --git a/OVP/D3D9Client/D3D9Client.cpp b/OVP/D3D9Client/D3D9Client.cpp index bff0e8cf4..52408b975 100644 --- a/OVP/D3D9Client/D3D9Client.cpp +++ b/OVP/D3D9Client/D3D9Client.cpp @@ -1512,7 +1512,7 @@ bool D3D9Client::clbkSetMeshProperty(DEVMESHHANDLE hMesh, DWORD prop, DWORD valu // ============================================================== -void D3D9Client::clbkSetVisualProperty(VISHANDLE vis, VesselProp prp, int idx, const type_info& t, const void* val) +void D3D9Client::clbkSetVisualProperty(VISHANDLE vis, VisualProp prp, int idx, const type_info& t, const void* val) { vVessel* vV = (vVessel*)vis; if (vV && vV->Type() == OBJTP_VESSEL) vV->SetVisualProperty(prp, idx, t, val); @@ -1843,6 +1843,7 @@ LRESULT D3D9Client::RenderWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l bool bCtrl = (GetAsyncKeyState(VK_CONTROL) & 0x8000)!=0; if (wParam == 'C' && bShift && bCtrl) bControlPanel = !bControlPanel; if (wParam == 'N' && bShift && bCtrl) Config->bCloudNormals = !Config->bCloudNormals; + if (wParam == 'V' && bShift && bCtrl) GetScene()->bStageSet = !GetScene()->bStageSet; break; } diff --git a/OVP/D3D9Client/D3D9Client.h b/OVP/D3D9Client/D3D9Client.h index 14f8e16c7..cfda87c24 100644 --- a/OVP/D3D9Client/D3D9Client.h +++ b/OVP/D3D9Client/D3D9Client.h @@ -426,7 +426,7 @@ class D3D9Client : public GraphicsClient * \default None, returns \e false. */ bool clbkSetMeshProperty (DEVMESHHANDLE hMesh, DWORD property, DWORD value); - void clbkSetVisualProperty(VISHANDLE vis, VesselProp prp, int idx, const type_info& t, const void* val); + void clbkSetVisualProperty(VISHANDLE vis, VisualProp prp, int idx, const type_info& t, const void* val); /** * \brief React to vessel docking, attaching events diff --git a/OVP/D3D9Client/D3D9Util.cpp b/OVP/D3D9Client/D3D9Util.cpp index b68fc35bc..a5d1a5eb7 100644 --- a/OVP/D3D9Client/D3D9Util.cpp +++ b/OVP/D3D9Client/D3D9Util.cpp @@ -1849,14 +1849,14 @@ HANDLE ShaderClass::GetVSHandle(const char* name) -void ShaderClass::SetTexture(const char* name, LPDIRECT3DTEXTURE9 pTex, UINT flags, UINT aniso) +void ShaderClass::SetTexture(const char* name, LPDIRECT3DBASETEXTURE9 pTex, UINT flags, UINT aniso) { D3DXHANDLE hVar = pPSCB->GetConstantByName(NULL, name); SetTexture((HANDLE)hVar, pTex, flags, aniso); } -void ShaderClass::SetTextureVS(const char* name, LPDIRECT3DTEXTURE9 pTex, UINT flags, UINT aniso) +void ShaderClass::SetTextureVS(const char* name, LPDIRECT3DBASETEXTURE9 pTex, UINT flags, UINT aniso) { D3DXHANDLE hVar = pVSCB->GetConstantByName(NULL, name); SetTextureVS((HANDLE)hVar, pTex, flags, aniso); @@ -1894,7 +1894,7 @@ void ShaderClass::SetVSConstants(const char* name, void* data, UINT bytes) -void ShaderClass::SetTexture(HANDLE hVar, LPDIRECT3DTEXTURE9 pTex, UINT flags, UINT aniso) +void ShaderClass::SetTexture(HANDLE hVar, LPDIRECT3DBASETEXTURE9 pTex, UINT flags, UINT aniso) { #ifdef SHDCLSDBG if (!hVar) { @@ -1919,7 +1919,7 @@ void ShaderClass::SetTexture(HANDLE hVar, LPDIRECT3DTEXTURE9 pTex, UINT flags, U } -void ShaderClass::SetTextureVS(HANDLE hVar, LPDIRECT3DTEXTURE9 pTex, UINT flags, UINT aniso) +void ShaderClass::SetTextureVS(HANDLE hVar, LPDIRECT3DBASETEXTURE9 pTex, UINT flags, UINT aniso) { #ifdef SHDCLSDBG if (!hVar) { diff --git a/OVP/D3D9Client/D3D9Util.h b/OVP/D3D9Client/D3D9Util.h index 63a88575b..9ac38e267 100644 --- a/OVP/D3D9Client/D3D9Util.h +++ b/OVP/D3D9Client/D3D9Util.h @@ -374,13 +374,13 @@ class ShaderClass HANDLE GetPSHandle(const char* name); HANDLE GetVSHandle(const char* name); - void SetTexture(const char* name, LPDIRECT3DTEXTURE9 pTex, UINT Flags = IPF_CLAMP | IPF_ANISOTROPIC, UINT AnisoLvl = 4); - void SetTextureVS(const char* name, LPDIRECT3DTEXTURE9 pTex, UINT flags = IPF_CLAMP | IPF_POINT, UINT AnisoLvl = 0); + void SetTexture(const char* name, LPDIRECT3DBASETEXTURE9 pTex, UINT Flags = IPF_CLAMP | IPF_ANISOTROPIC, UINT AnisoLvl = 4); + void SetTextureVS(const char* name, LPDIRECT3DBASETEXTURE9 pTex, UINT flags = IPF_CLAMP | IPF_POINT, UINT AnisoLvl = 0); void SetPSConstants(const char* name, void* data, UINT bytes); void SetVSConstants(const char* name, void* data, UINT bytes); - void SetTexture(HANDLE hVar, LPDIRECT3DTEXTURE9 pTex, UINT flags = IPF_CLAMP | IPF_POINT, UINT AnisoLvl = 0); - void SetTextureVS(HANDLE hVar, LPDIRECT3DTEXTURE9 pTex, UINT flags, UINT aniso); + void SetTexture(HANDLE hVar, LPDIRECT3DBASETEXTURE9 pTex, UINT flags = IPF_CLAMP | IPF_POINT, UINT AnisoLvl = 0); + void SetTextureVS(HANDLE hVar, LPDIRECT3DBASETEXTURE9 pTex, UINT flags, UINT aniso); void SetPSConstants(HANDLE hVar, void* data, UINT bytes); void SetVSConstants(HANDLE hVar, void* data, UINT bytes); LPDIRECT3DDEVICE9 GetDevice() { return pDev; } @@ -389,8 +389,8 @@ class ShaderClass struct TexParams { - LPDIRECT3DTEXTURE9 pTex; - LPDIRECT3DTEXTURE9 pAssigned; + LPDIRECT3DBASETEXTURE9 pTex; + LPDIRECT3DBASETEXTURE9 pAssigned; UINT Flags; UINT AnisoLvl; bool bSamplerSet; diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index e79b15d42..3343e04f9 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -1499,8 +1499,8 @@ void UpdateBakedLights(float lvl) vVessel* vV = (vVessel*)vObj; if (vObj->Type() == OBJTP_VESSEL) { if (bkl_id < 16 && bkl_id >= 0) - vV->SetVisualProperty(VesselProp::BAKED_LIGHT, bkl_id, typeid(FVECTOR3), &FVECTOR3(lvl, lvl, lvl)); - if (bkl_id == 16) vV->SetVisualProperty(VesselProp::AMBIENT, 0, typeid(FVECTOR3), &FVECTOR3(lvl, lvl, lvl)); + vV->SetVisualProperty(VisualProp::BAKED_LIGHT, bkl_id, typeid(FVECTOR3), &FVECTOR3(lvl, lvl, lvl)); + if (bkl_id == 16) vV->SetVisualProperty(VisualProp::AMBIENT, 0, typeid(FVECTOR3), &FVECTOR3(lvl, lvl, lvl)); } } @@ -1511,8 +1511,8 @@ void UpdateLightsSlider() FVECTOR3 val = 0.0f; vVessel* vV = (vVessel*)vObj; if (vObj->Type() == OBJTP_VESSEL) { - if (bkl_id < 16 && bkl_id >= 0) vV->GetVisualProperty(VesselProp::BAKED_LIGHT, bkl_id, typeid(val), &val); - if (bkl_id == 16) vV->GetVisualProperty(VesselProp::AMBIENT, 0, typeid(val), &val); + if (bkl_id < 16 && bkl_id >= 0) vV->GetVisualProperty(VisualProp::BAKED_LIGHT, bkl_id, typeid(val), &val); + if (bkl_id == 16) vV->GetVisualProperty(VisualProp::AMBIENT, 0, typeid(val), &val); SendDlgItemMessage(hDlg, IDC_DBG_BKLADJ, TBM_SETPOS, 1, WORD(255.0f * val.x)); } } diff --git a/OVP/D3D9Client/Mesh.h b/OVP/D3D9Client/Mesh.h index 34eee72b6..7034d183f 100644 --- a/OVP/D3D9Client/Mesh.h +++ b/OVP/D3D9Client/Mesh.h @@ -69,7 +69,7 @@ const DWORD SPEC_INHERIT = (DWORD)(-2); // "inherit" material/texture flag #define ENVCAM_OMIT_DOCKS 0x0002 ///< Do not render docked vessels, rendered by default #define ENVCAM_FOCUS 0x0004 ///< Force rendering of focus object, omitted by default #define ENVCAM_PLANE 0x0008 ///< Camera view is 160deg square plane, 360deg cube-map by default -#define ENVCAM_DEFAULT 0x0010 ///< Default setup, not user supplied +#define ENVCAM_USER 0x0010 ///< User supplied setup diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index 570245ccd..8b73b06f0 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -110,6 +110,8 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) pLocalResultsSL = NULL; pBakeLights = NULL; ptRandom = NULL; + dmCubeMesh = NULL; + pRenderStage = NULL; vobjEnv = eCamRenderList.begin(); @@ -197,8 +199,17 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) // ------------------------------------------------------------------------------ - // Initialize a shaders for local lights visibility checks and rendering + // Load a mesh to create a stage + // + MESHHANDLE hCubeMesh = oapiLoadMeshGlobal("D3D9Cube"); + if (!hCubeMesh) { oapiWriteLog("Failed to open D3D9Cube.msh"); DebugBreak(); } + dmCubeMesh = gc->GetDevMesh(hCubeMesh); + pRenderStage = new ShaderClass(pDevice, "Modules/D3D9Client/Custom.hlsl", "StageVS", "StagePS", "RenderStage", ""); + + // ------------------------------------------------------------------------------ + // Initialize a shaders for local lights visibility checks and rendering + // if (Config->bGlares || Config->bLocalGlares) { pRenderGlares = new ShaderClass(pDevice, "Modules/D3D9Client/Glare.hlsl", "GlareVS", "GlarePS", "RenderGlares", ""); @@ -264,14 +275,15 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) HR(D3DXCreateTexture(pDevice, viewW, viewH, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &ptgBuffer[GBUF_DEPTH])); } - HR(D3DXCreateTexture(pDevice, 64, 64, 1, D3DUSAGE_DYNAMIC, D3DFMT_R32F, D3DPOOL_DEFAULT, &ptRandom)); + // Create a random number table -------------------------------------------------------------------------------------------------- + // + HR(D3DXCreateTexture(pDevice, 64, 64, 1, D3DUSAGE_DYNAMIC, D3DFMT_R32F, D3DPOOL_DEFAULT, &ptRandom)); D3DLOCKED_RECT rect; if (ptRandom->LockRect(0, &rect, 0, 0) == S_OK) { for (int i = 0; i < (64 * 64); i++) ((float*)rect.pBits)[i] = oapiRand(); ptRandom->UnlockRect(0); - } - else LogErr("Failed to create random table"); + } else LogErr("Failed to create random table"); // Initialize post processing effects -------------------------------------------------------------------------------------------------- // @@ -371,6 +383,7 @@ Scene::~Scene () SAFE_DELETE(pRenderGlares); SAFE_DELETE(pCreateGlare); SAFE_DELETE(pBakeLights); + SAFE_DELETE(pRenderStage); SAFE_RELEASE(pOffscreenTarget); SAFE_RELEASE(pEnvDS); @@ -1968,6 +1981,10 @@ void Scene::clbkRenderMainScene() pSketch->EndDrawing(); // SKETCHPAD_LABELS } + if (vFocus) { + auto a = vFocus->GetEnvMap()->pEnv; + if (a && bStageSet) RenderStage((LPDIRECT3DCUBETEXTURE9)a); + } @@ -2783,7 +2800,7 @@ int Scene::RenderVCShadowMap(D3DXVECTOR3& cdir, D3DXVECTOR3& ld, bool bListExist // =========================================================================================== // -void Scene::RenderSecondaryScene(std::set &RndList, std::set &LightsList, DWORD flags) +void Scene::RenderSecondaryScene(std::set &RndList, std::set &LightsList, DWORD flags, const LPDIRECT3DCUBETEXTURE9 pCT) { _TRACE; RenderFlags = flags; @@ -2822,10 +2839,15 @@ void Scene::RenderSecondaryScene(std::set &RndList, std::set // Clear the viewport HR(pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, 0xFF000000, 1.0f, 0L)); + + // render stage around the scene ---------------------------- + // + if ((flags & SCN_STAGE) && pCT) RenderStage(pCT); + // render planets ------------------------------------------- // - if (flags & 0x01) { + if (flags & SCN_PLANETS) { for (DWORD i = 0; iIsActive(); if (isActive) plist[i].vo->Render(pDevice); @@ -2835,7 +2857,7 @@ void Scene::RenderSecondaryScene(std::set &RndList, std::set // render the vessel objects -------------------------------- // - if (flags & 0x02) { + if (flags & SCN_VESSELS) { for (auto vVes : RndList) { if (!vVes->IsActive()) continue; if (!vVes->IsVisible()) continue; @@ -2845,7 +2867,7 @@ void Scene::RenderSecondaryScene(std::set &RndList, std::set // render exhausts ------------------------------------------- // - if (flags & 0x04) { + if (flags & SCN_EXHAUST) { for (auto vVes : RndList) { if (!vVes->IsActive()) continue; if (!vVes->IsVisible()) continue; @@ -2855,7 +2877,7 @@ void Scene::RenderSecondaryScene(std::set &RndList, std::set // render beacons ------------------------------------------- // - if (flags & 0x08) { + if (flags & SCN_BEACONS) { for (auto vVes : RndList) { if (!vVes->IsActive()) continue; vVes->RenderBeacons(pDevice); @@ -2863,7 +2885,7 @@ void Scene::RenderSecondaryScene(std::set &RndList, std::set } // render exhaust particle system ---------------------------- - if (flags & 0x10) { + if (flags & SCN_PARTICLES) { for (DWORD n = 0; n < nstream; n++) pstream[n]->Render(pDevice); } @@ -2871,6 +2893,36 @@ void Scene::RenderSecondaryScene(std::set &RndList, std::set } +// =========================================================================================== +// Rernder a stage/set to contain some meshes. +// +void Scene::RenderStage(LPDIRECT3DCUBETEXTURE9 pCT) +{ + if (!pRenderStage) return; + + struct { + D3DXMATRIX mVP; + D3DXMATRIX mW; + } ShaderData; + + ShaderData.mVP = Camera.mProjView; + D3DXMatrixIdentity(&ShaderData.mW); + ShaderData.mW._11 = 10e3f; + ShaderData.mW._22 = 10e3f; + ShaderData.mW._33 = 10e3f; + + pRenderStage->ClearTextures(); + pRenderStage->SetPSConstants("cbPS", &ShaderData, sizeof(ShaderData)); + pRenderStage->SetVSConstants("cbPS", &ShaderData, sizeof(ShaderData)); + pRenderStage->SetTexture("tTex", pCT, IPF_CLAMP | IPF_LINEAR); + pRenderStage->Setup(pMeshVertexDecl, false, 0); + pRenderStage->UpdateTextures(); + + ((D3D9Mesh*)dmCubeMesh)->RenderGroup(0); + + pRenderStage->DetachTextures(); +} + // =========================================================================================== // bool Scene::RenderBlurredMap(LPDIRECT3DDEVICE9 pDev, LPDIRECT3DCUBETEXTURE9 pSrc) diff --git a/OVP/D3D9Client/Scene.h b/OVP/D3D9Client/Scene.h index bdb767f84..72d74cd9a 100644 --- a/OVP/D3D9Client/Scene.h +++ b/OVP/D3D9Client/Scene.h @@ -67,6 +67,19 @@ class D3D9Pad; #define OBJTP_BUILDING 1000 +// Secundary scene render flags +#define SCN_PLANETS 0x1 +#define SCN_VESSELS 0x2 +#define SCN_EXHAUST 0x4 +#define SCN_BEACONS 0x8 +#define SCN_PARTICLES 0x10 +#define SCN_BASESTRUCT 0x20 +#define SCN_ALLEXT 0x3F ///< All exterior features +#define SCN_VC 0x40 ///< Virtual cockpit +#define SCN_STAGE 0x100 ///< Render a stage around the world. Cude texture needed. + + + #define CAMERA(x) ((Scene::CAMREC*)x) class Scene { @@ -86,6 +99,7 @@ class Scene { public: FVECTOR3 vPickRay; + bool bStageSet = false; struct FRUSTUM { float znear; @@ -257,7 +271,7 @@ class Scene { /** * \brief Render a secondary scene. (Env Maps, Shadow Maps, MFD Camera Views) */ - void RenderSecondaryScene(std::set &RndList, std::set &AdditionalLightsList, DWORD flags = 0xFF); + void RenderSecondaryScene(std::set &RndList, std::set &AdditionalLightsList, DWORD flags = SCN_ALLEXT, const LPDIRECT3DCUBETEXTURE9 pCT = nullptr); int RenderShadowMap(D3DXVECTOR3& pos, D3DXVECTOR3& ld, float rad, bool bInternal = false, bool bListExists = false); int RenderVCShadowMap(D3DXVECTOR3& cdir, D3DXVECTOR3& ld, bool bListExists = false); @@ -265,6 +279,7 @@ class Scene { bool RenderBlurredMap(LPDIRECT3DDEVICE9 pDev, LPDIRECT3DCUBETEXTURE9 pSrc); bool RenderBlurredMap(LPDIRECT3DDEVICE9 pDev, LPDIRECT3DTEXTURE9 pSrc); void RenderMesh(DEVMESHHANDLE hMesh, const oapi::FMATRIX4 *pWorld); + void RenderStage(LPDIRECT3DCUBETEXTURE9 pCT); LPDIRECT3DSURFACE9 GetEnvDepthStencil() const { return pEnvDS; } LPDIRECT3DSURFACE9 GetBuffer(int id) const { return psgBuffer[id]; } @@ -464,7 +479,7 @@ class Scene { D3D9ParticleStream **pstream; // list of particle streams DWORD nstream; // number of streams - + DEVMESHHANDLE dmCubeMesh; D3DCOLOR bg_rgba; // ambient background colour // GDI resources ==================================================================== @@ -504,7 +519,7 @@ class Scene { SurfNative *pLblSrf; class ImageProcessing *pLightBlur, *pBlur, *pBlur2D, *pGDIOverlay, *pIrradiance, *pVisDepth, *pCreateGlare, *pBakeLights; - class ShaderClass *pLocalCompute, *pRenderGlares; + class ShaderClass *pLocalCompute, *pRenderGlares, *pRenderStage; class vVessel *vFocus; double dVisualAppRad; diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index 0abc4eb63..17d1616ad 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -78,10 +78,10 @@ vVessel::vVessel(OBJHANDLE _hObj, const Scene *scene): vObject (_hObj, scene) // Initialize default eCams; // - ecDefExt.flags = ENVCAM_OMIT_ATTC | ENVCAM_DEFAULT; + ecDefExt.flags = ENVCAM_OMIT_ATTC; ecDefExt.type = EnvCamType::Exterior; - ecDefVC.flags = ENVCAM_DEFAULT; + ecDefVC.flags = 0; ecDefVC.type = EnvCamType::VC; D3DXVECTOR3 pos; @@ -1486,10 +1486,10 @@ ENVCAMREC* vVessel::CreateEnvCam(EnvCamType ec) // bool vVessel::HasOwnEnvCam(EnvCamType ec) { - if (ec == EnvCamType::Exterior && (ecDefExt.flags & ENVCAM_DEFAULT)) return false; - if (ec == EnvCamType::VC && (ecDefVC.flags & ENVCAM_DEFAULT)) return false; - if (ec == EnvCamType::Mesh && mesh_cams.size() == 0) return false; - return true; + if (ec == EnvCamType::Exterior && (ecDefExt.flags & ENVCAM_USER)) return true; + if (ec == EnvCamType::VC && (ecDefVC.flags & ENVCAM_USER)) return true; + if (ec == EnvCamType::Mesh && mesh_cams.size() > 0) return true; + return false; } // ============================================================================================ @@ -1816,13 +1816,13 @@ void vVessel::AnimateComponent (ANIMATIONCOMP *comp, const D3DXMATRIX &T) // ============================================================================================ // -void vVessel::SetVisualProperty(VesselProp prp, int idx, const type_info& t, const void* val) +void vVessel::SetVisualProperty(VisualProp prp, int idx, const type_info& t, const void* val) { if (t == typeid(FVECTOR3)) { FVECTOR3* v = (FVECTOR3*)val; - if (prp == VesselProp::BAKED_LIGHT) { + if (prp == VisualProp::BAKED_LIGHT) { if (idx >= 0 && idx <= 15) { if (BakedLightsControl[idx] != *v) { BakedLightsControl[idx] = *v; @@ -1832,10 +1832,22 @@ void vVessel::SetVisualProperty(VesselProp prp, int idx, const type_info& t, con return; } - if (prp == VesselProp::AMBIENT) { + if (prp == VisualProp::AMBIENT) { VCAmbient = *v; return; } + + if (prp == VisualProp::EXT_PROBE_POS) { + ecDefExt.lPos = *v; + ecDefExt.flags |= ENVCAM_USER; + return; + } + + if (prp == VisualProp::VC_PROBE_POS) { + ecDefVC.lPos = *v; + ecDefVC.flags |= ENVCAM_USER; + return; + } } oapiWriteLogV("Failed to set visual property prp=%d, type=[%s]", int(prp), t.name()); @@ -1844,20 +1856,21 @@ void vVessel::SetVisualProperty(VesselProp prp, int idx, const type_info& t, con // ============================================================================================ // -bool vVessel::GetVisualProperty(VesselProp prp, int idx, const type_info& t, void* val) +bool vVessel::GetVisualProperty(VisualProp prp, int idx, const type_info& t, void* val) { if (t == typeid(FVECTOR3)) { - if (prp == VesselProp::BAKED_LIGHT) if (idx >= 0 && idx <= 15) { + if (prp == VisualProp::BAKED_LIGHT) if (idx >= 0 && idx <= 15) { *((FVECTOR3*)val) = BakedLightsControl[idx]; return true; } - if (prp == VesselProp::AMBIENT) { + if (prp == VisualProp::AMBIENT) { *((FVECTOR3*)val) = VCAmbient; return true; } } + oapiWriteLogV("Failed to get visual property prp=%d, type=[%s]", int(prp), t.name()); return false; } diff --git a/OVP/D3D9Client/VVessel.h b/OVP/D3D9Client/VVessel.h index 126aee9bc..dc11ccfd2 100644 --- a/OVP/D3D9Client/VVessel.h +++ b/OVP/D3D9Client/VVessel.h @@ -166,8 +166,8 @@ class vVessel: public vObject { */ void UpdateAnimations(int mshidx = -1); - void SetVisualProperty(VesselProp prp, int idx, const type_info& t, const void* val); - bool GetVisualProperty(VesselProp prp, int idx, const type_info& t, void* val); + void SetVisualProperty(VisualProp prp, int idx, const type_info& t, const void* val); + bool GetVisualProperty(VisualProp prp, int idx, const type_info& t, void* val); protected: diff --git a/OVP/D3D9Client/shaders/Custom.hlsl b/OVP/D3D9Client/shaders/Custom.hlsl new file mode 100644 index 000000000..d78fef48b --- /dev/null +++ b/OVP/D3D9Client/shaders/Custom.hlsl @@ -0,0 +1,48 @@ +// =================================================== +// Copyright (C) 2022 Jarmo Nikkanen +// licensed under MIT +// =================================================== + + +float ilerp(float a, float b, float x) +{ + return saturate((x - a) / (b - a)); +} + + +struct MESH_VERTEX { + float3 posL : POSITION0; + float3 nrmL : NORMAL0; + float3 tanL : TANGENT0; + float3 tex0 : TEXCOORD0; +}; + +sampler tTex; + +uniform extern struct { + float4x4 mVP; + float4x4 mW; +} cbPS; + + +struct MData { + float4 posH : POSITION0; + float3 camW : TEXCOORD0; +}; + +MData StageVS(MESH_VERTEX vrt) +{ + MData outVS = (MData)0; + float3 posW = mul(float4(vrt.posL, 1.0f), cbPS.mW).xyz; + outVS.posH = mul(float4(posW, 1.0f), cbPS.mVP); + outVS.camW = -posW; + return outVS; +} + +float4 StagePS(MData frg) : COLOR +{ + float3 cA = texCUBElod(tTex, float4(normalize(-frg.camW), 0.0)).rgb; + return float4(cA, 1); +} + + diff --git a/Orbitersdk/include/GraphicsAPI.h b/Orbitersdk/include/GraphicsAPI.h index 36c64d36a..ce67ea328 100644 --- a/Orbitersdk/include/GraphicsAPI.h +++ b/Orbitersdk/include/GraphicsAPI.h @@ -679,7 +679,7 @@ class OAPIFUNC GraphicsClient: public Module { * \sa RegisterVisObject, UnregisterVisObject, visevent */ virtual int clbkVisEvent (OBJHANDLE hObj, VISHANDLE vis, DWORD msg, DWORD_PTR context); - virtual void clbkSetVisualProperty(VISHANDLE vis, VesselProp prp, int idx, const type_info& t, const void* val) { } + virtual void clbkSetVisualProperty(VISHANDLE vis, VisualProp prp, int idx, const type_info& t, const void* val) { } /** * \brief Return a mesh handle for a visual, defined by its index diff --git a/Orbitersdk/include/VesselAPI.h b/Orbitersdk/include/VesselAPI.h index 1d03a682e..0dd226585 100644 --- a/Orbitersdk/include/VesselAPI.h +++ b/Orbitersdk/include/VesselAPI.h @@ -42,7 +42,7 @@ typedef struct { double mu_lng; ///< longitudinal friction coefficient (only used for first 3 points) } TOUCHDOWNVTX; -enum class VesselProp { +enum class VisualProp { BAKED_LIGHT, ///< baked light level AMBIENT, ///< ambient light level EXT_PROBE_POS, ///< Exterior probe position @@ -3849,7 +3849,7 @@ class OAPIFUNC VESSEL { * \param idx index of property * \param val value to be set */ - void SetVisualProperty(VISHANDLE vis, VesselProp prp, int idx, const type_info &t, const void *val); + void SetVisualProperty(VISHANDLE vis, VisualProp prp, int idx, const type_info &t, const void *val); /** * \brief Affine transformation of a mesh group. diff --git a/Src/Orbiter/Vessel.cpp b/Src/Orbiter/Vessel.cpp index 99a581762..8047c575f 100644 --- a/Src/Orbiter/Vessel.cpp +++ b/Src/Orbiter/Vessel.cpp @@ -7679,7 +7679,7 @@ void VESSEL::SetMeshVisibilityMode (UINT idx, WORD mode) const vessel->SetMeshVisibilityMode (idx, mode); } -void VESSEL::SetVisualProperty(VISHANDLE vis, VesselProp prp, int idx, const type_info& t, const void* val) +void VESSEL::SetVisualProperty(VISHANDLE vis, VisualProp prp, int idx, const type_info& t, const void* val) { oapi::GraphicsClient* gc = g_pOrbiter->GetGraphicsClient(); gc->clbkSetVisualProperty(vis, prp, idx, t, val); From 062e5cf42b85f03611ff233355e7727ad584fd69 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Sun, 4 Feb 2024 18:36:16 +0200 Subject: [PATCH 32/42] Added shadows for stage-set, bug fixes and code cleanup. --- OVP/D3D9Client/D3D9Client.cpp | 40 + OVP/D3D9Client/D3D9Client.h | 91 +- OVP/D3D9Client/D3D9Client.rc | 14 +- OVP/D3D9Client/D3D9Pad2.cpp | 2 +- OVP/D3D9Client/D3D9Surface.cpp | 4 +- OVP/D3D9Client/DebugControls.cpp | 36 +- OVP/D3D9Client/DebugControls.h | 12 +- OVP/D3D9Client/MaterialMgr.cpp | 2 +- OVP/D3D9Client/Mesh.cpp | 34 +- OVP/D3D9Client/Mesh.h | 7 +- OVP/D3D9Client/Scene.cpp | 976 ++++++++++++---------- OVP/D3D9Client/Scene.h | 194 +++-- OVP/D3D9Client/Surfmgr2.cpp | 12 +- OVP/D3D9Client/VPlanet.cpp | 4 +- OVP/D3D9Client/VVessel.cpp | 356 +++++--- OVP/D3D9Client/VVessel.h | 36 +- OVP/D3D9Client/resource.h | 2 +- Orbitersdk/include/DrawAPI.h | 11 + Orbitersdk/include/VesselAPI.h | 2 +- Src/Vessel/Atlantis/Atlantis/Atlantis.cpp | 3 + 20 files changed, 1137 insertions(+), 701 deletions(-) diff --git a/OVP/D3D9Client/D3D9Client.cpp b/OVP/D3D9Client/D3D9Client.cpp index 52408b975..483745a44 100644 --- a/OVP/D3D9Client/D3D9Client.cpp +++ b/OVP/D3D9Client/D3D9Client.cpp @@ -3244,3 +3244,43 @@ VisObject::VisObject(OBJHANDLE hObj) : hObj(hObj) VisObject::~VisObject () { } + +// ======================================================================= + +SHADOWMAP::SHADOWMAP(LPDIRECT3DDEVICE9 pDevice, sMapType t, DWORD sz) : SMapInput(), tp(t) +{ + if (Config->ShadowMapMode == 0) return; + + // Single fixed size shadow map + if (tp == sMapType::SingleLod) { + HR(pDevice->CreateTexture(sz, sz, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R32F, D3DPOOL_DEFAULT, &ptShmRT[0], NULL)); + HR(ptShmRT[0]->GetSurfaceLevel(0, &psShmRT[0])); + } + + // Exterior shadows + if (tp == sMapType::MultiLod) { + UINT size = Config->ShadowMapSize; + for (int i = 0; i < SHM_LOD_COUNT; i++) { + HR(pDevice->CreateTexture(size, size, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R32F, D3DPOOL_DEFAULT, &ptShmRT[i], NULL)); + HR(ptShmRT[i]->GetSurfaceLevel(0, &psShmRT[i])); + size >>= 1; + } + } + + // VC Shadows + if (tp == sMapType::Cascaded) { + UINT size = Config->ShadowMapSize; + for (int i = 0; i < SHM_CASCADE_COUNT; i++) { + HR(pDevice->CreateTexture(size, size, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R32F, D3DPOOL_DEFAULT, &ptShmRT[i], NULL)); + HR(ptShmRT[i]->GetSurfaceLevel(0, &psShmRT[i])); + } + } +} + +// ======================================================================= + +SHADOWMAP::~SHADOWMAP() +{ + for (auto& x : psShmRT) SAFE_RELEASE(x); + for (auto& x : ptShmRT) SAFE_RELEASE(x); +} diff --git a/OVP/D3D9Client/D3D9Client.h b/OVP/D3D9Client/D3D9Client.h index cfda87c24..2e549cae9 100644 --- a/OVP/D3D9Client/D3D9Client.h +++ b/OVP/D3D9Client/D3D9Client.h @@ -75,22 +75,25 @@ extern set MeshCatalog; extern set SurfaceCatalog; extern IDirect3D9* g_pD3DObject; -enum class EnvCamType { Undefined, Exterior, VC, Mesh }; +enum class EnvCamType { Undefined, Exterior, Interior, Mesh }; +enum class ShdPackage { None, Main, VC, Stage }; -struct ENVMAPS -{ - LPDIRECT3DBASETEXTURE9 pEnv = nullptr; ///< Reflection map (cube) - LPDIRECT3DTEXTURE9 pIrrad = nullptr; ///< Irradiance map (baraboloidal) -}; /** * \brief Storage structure to keep reflection camera information. */ struct ENVCAMREC { - std::vector omitAttc; - std::vector omitDock; - ENVMAPS tex; + ~ENVCAMREC() + { + SAFE_RELEASE(pCube); + SAFE_RELEASE(pIrrad); + SAFE_RELEASE(pPlane); + oapiWriteLog("ENVCAMREC::Destruct"); + } + + std::vector omitAttc = {}; + std::vector omitDock = {}; EnvCamType type = EnvCamType::Undefined; FVECTOR3 lPos = { 0,0,0 }; ///< Camera local position FVECTOR3 lDir = { 1,0,0 }; ///< Camera local direction (in 'PLANE' mode only) @@ -101,6 +104,9 @@ struct ENVCAMREC int id = -1; ///< User Id, for binding BYTE iSide = 0; ///< [Private] Current side being rendered bool bRendered = false; ///< [Private] Rendering of camera view is completed + LPDIRECT3DCUBETEXTURE9 pCube = nullptr; ///< Reflection cube map + LPDIRECT3DTEXTURE9 pIrrad = nullptr; ///< Irradiance map (baraboloidal) + LPDIRECT3DTEXTURE9 pPlane = nullptr; ///< Reflection 2D map if (flags & ENVCAM_PLANE) }; /** @@ -162,24 +168,55 @@ struct PickProp { bool bDualSided; // Pick also back-facing triangles }; -struct SHADOWMAPPARAM { - LPDIRECT3DTEXTURE9 pShadowMap[SHM_CASCADE_COUNT]; - // Index 0 is also used for exterior map where the map size varies by LOD, distant object may use 128x128 map - // Interior VC cascades are all same size - FMATRIX4 mVP[SHM_CASCADE_COUNT]; - FVECTOR4 Subrect[SHM_CASCADE_COUNT]; - FVECTOR4 SubrectTF[SHM_CASCADE_COUNT]; - FVECTOR2 Center[SHM_CASCADE_COUNT]; - float SubPx[SHM_CASCADE_COUNT]; - FMATRIX4 mLVP; - D3DXVECTOR3 pos; // Shadow map origin i.e. Cascade '0' origin - D3DXVECTOR3 ld; // Light direction - float rad; // radius of the area covered by map [meters] - float dist; // Shadow camera distance from shadow origin - float depth; // near to far plane distance. i.r. depth of the field - int lod; // level of detail, 0 = highest - int size; // Map size in pixels - int cascades; // Number of active cascades +struct SMapInput { + FVECTOR3 pos = { }; ///< Shadow map center in camera centric coords (ecl frame) + FVECTOR3 ld = { }; ///< Direction of sunlight (ecl frame) + float rad = { }; ///< Radius of shadow mapped area +}; + +class SHADOWMAP : public SMapInput +{ +public: + + enum class sMapType { MultiLod, Cascaded, SingleLod }; + + SHADOWMAP(LPDIRECT3DDEVICE9 pDevice, sMapType tp, DWORD sz = 1024); + ~SHADOWMAP(); + + LPDIRECT3DTEXTURE9 Map(int idx) const + { + if (tp == sMapType::MultiLod) { + if (idx == 0) return ptShmRT[lod]; + else return nullptr; + } + return ptShmRT[idx]; + } + + void Clear() { bValid = false; } + bool IsValid() const { return bValid && (Map(0) != nullptr); } + + + + FMATRIX4 mVP[SHM_CASCADE_COUNT] = {}; + FVECTOR4 Subrect[SHM_CASCADE_COUNT] = {}; + FVECTOR4 SubrectTF[SHM_CASCADE_COUNT] = {}; + FVECTOR2 Center[SHM_CASCADE_COUNT] = {}; + float SubPx[SHM_CASCADE_COUNT] = {}; + FMATRIX4 mLVP = {}; + float dist = 0.0f; // Shadow camera distance from shadow origin + float depth = 0.0f; // near to far plane distance. i.r. depth of the field + int lod = 0; // level of detail, 0 = highest + int size = 0; // Map size in pixels + int cascades = 0; // Number of active cascades + bool bValid = false; + sMapType tp; + + + // Cascades are located in entries 0, 1, 2 + // Active entry in MultiLod map is located in index pointed by 'lod' + // Active entry in SingleLod map is in index 0, 'lod' entry is 0 + LPDIRECT3DSURFACE9 psShmRT[max(SHM_LOD_COUNT, SHM_CASCADE_COUNT)] = { nullptr }; + LPDIRECT3DTEXTURE9 ptShmRT[max(SHM_LOD_COUNT, SHM_CASCADE_COUNT)] = { nullptr }; }; struct LVLH { diff --git a/OVP/D3D9Client/D3D9Client.rc b/OVP/D3D9Client/D3D9Client.rc index 57ec1dbbc..eeaabce12 100644 --- a/OVP/D3D9Client/D3D9Client.rc +++ b/OVP/D3D9Client/D3D9Client.rc @@ -67,7 +67,7 @@ FONT 8, "Ms Shell Dlg" GROUPBOX "Visualize local light cones", IDC_STATIC, 195, 240, 175, 35, 0, WS_EX_LEFT GROUPBOX "Selection and Display Options", IDC_STATIC, 5, 15, 175, 145, 0, WS_EX_LEFT GROUPBOX "Misc.", IDC_STATIC, 195, 10, 173, 70, 0, WS_EX_LEFT - GROUPBOX "Scene Debugger", IDC_STATIC, 195, 85, 173, 95, 0, WS_EX_LEFT + GROUPBOX "Scene Debugger", IDC_STATIC, 195, 85, 173, 100, 0, WS_EX_LEFT GROUPBOX "Texture Tools", IDC_STATIC, 380, 15, 173, 151, 0, WS_EX_LEFT AUTOCHECKBOX "Selected mesh only", IDC_DBG_MSHO, 274, 211, 77, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Dual sided", IDC_DBG_DUAL, 120, 107, 49, 8, 0, WS_EX_LEFT @@ -111,7 +111,7 @@ FONT 8, "Ms Shell Dlg" PUSHBUTTON "Save materials", IDC_DBG_MATSAVE, 5, 429, 51, 14, 0, WS_EX_LEFT PUSHBUTTON "Create kernel", IDC_DBG_KERNEL, 315, 430, 47, 14, 0, WS_EX_LEFT PUSHBUTTON "Data window", IDC_DBG_DATAWND, 5, 446, 50, 14, 0, WS_EX_LEFT - PUSHBUTTON "Save envmap", IDC_DBG_ENVSAVE, 300, 164, 60, 12, 0, WS_EX_LEFT + PUSHBUTTON "Save envmap", IDC_DBG_ENVSAVE, 300, 167, 60, 12, 0, WS_EX_LEFT PUSHBUTTON ">>>", IDC_DBG_MORE, 124, 446, 50, 14, 0, WS_EX_LEFT PUSHBUTTON "Reload Shader", IDC_DBG_RELOADSHD, 60, 446, 60, 14, 0, WS_EX_LEFT PUSHBUTTON "Reload Textures", IDC_DBG_RELOADTEX, 60, 430, 60, 14, 0, WS_EX_LEFT @@ -149,12 +149,14 @@ FONT 8, "Ms Shell Dlg" LTEXT "MeshVisMode: ", IDC_DBG_VISMODE, 10, 380, 162, 9, SS_LEFT, WS_EX_LEFT AUTOCHECKBOX "Pick only current mesh", IDC_DBG_PICKCURRENT, 18, 146, 87, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Dynamic", IDC_DBG_DYNAMIC, 285, 295, 43, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Is VC Mesh", IDC_DBG_ISVCMESH, 15, 193, 52, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Cast VC Shadow", IDC_DBG_VCSHADOW, 15, 203, 69, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "This is VC mesh", IDC_DBG_ISVCMESH, 15, 193, 66, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Cast VC shadow", IDC_DBG_VCSHADOW, 15, 203, 68, 8, 0, WS_EX_LEFT COMBOBOX IDC_DBG_AMBDIR, 275, 130, 86, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT LTEXT "VC Ambient View Dir", IDC_STATIC, 205, 132, 66, 9, SS_LEFT, WS_EX_LEFT - AUTOCHECKBOX "No sunlight", IDC_DBG_NOSUNAMB, 205, 143, 51, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "No planet glow", IDC_DBG_NOPLNAMB, 205, 152, 63, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "No sunlight", IDC_DBG_NOSUNAMB, 205, 161, 51, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "No planet glow", IDC_DBG_NOPLNAMB, 205, 172, 63, 8, 0, WS_EX_LEFT + COMBOBOX IDC_DBG_DATASRC, 275, 145, 86, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT + LTEXT "Probe Data Source", IDC_STATIC, 206, 147, 62, 9, SS_LEFT, WS_EX_LEFT } diff --git a/OVP/D3D9Client/D3D9Pad2.cpp b/OVP/D3D9Client/D3D9Pad2.cpp index 7568bcd9c..1ecc0246d 100644 --- a/OVP/D3D9Client/D3D9Pad2.cpp +++ b/OVP/D3D9Client/D3D9Pad2.cpp @@ -327,7 +327,7 @@ void D3D9Pad::StretchRectNative(const LPDIRECT3DTEXTURE9 pSrc, const RECT *_s, c if (Topology(TRIANGLE)) { auto s = _s ? *_s : GetFullRectNative(pSrc); - auto t = *_t; + auto t = _t ? *_t : tgt; AddRectIdx(vI); diff --git a/OVP/D3D9Client/D3D9Surface.cpp b/OVP/D3D9Client/D3D9Surface.cpp index 73a0324e6..806582826 100644 --- a/OVP/D3D9Client/D3D9Surface.cpp +++ b/OVP/D3D9Client/D3D9Surface.cpp @@ -374,7 +374,7 @@ SURFHANDLE NatCreateSurface(int width, int height, DWORD flags) { if (flags & OAPISURFACE_RENDER3D) { - HR(pDev->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, true, &pDepth, NULL)); + HR(pDev->CreateDepthStencilSurface(width, height, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, true, &pDepth, NULL)); } return SURFHANDLE(new SurfNative(pTex, flags, pDepth)); } @@ -390,7 +390,7 @@ SURFHANDLE NatCreateSurface(int width, int height, DWORD flags) { if (flags & OAPISURFACE_RENDER3D) { - HR(pDev->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, Multi, 0, true, &pDepth, NULL)); + HR(pDev->CreateDepthStencilSurface(width, height, D3DFMT_D24X8, Multi, 0, true, &pDepth, NULL)); } return SURFHANDLE(new SurfNative(pSurf, flags, pDepth)); } diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index 3343e04f9..a1dc319f0 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -36,8 +36,10 @@ extern D3D9Client *g_client; namespace DebugControls { +DbgDisplay dbgdsp = {}; int ambdir = -1; int bkl_id = 0; +int probe_id = -1; DWORD dwGFX, dwCmd, nMesh, nGroup, sMesh, sGroup, debugFlags, dspMode, camMode, SelColor, sEmitter; double camSpeed; float cpr, cpg, cpb, cpa; @@ -449,10 +451,10 @@ int GetSceneDebug() // ============================================================================================= // -int GetSelectedEnvMap() +DbgDisplay GetSelectedEnvMap() { - if (!hDlg) return 0; - return (int)SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_GETCURSEL, 0, 0); + if (!hDlg) return DbgDisplay(0); + return (DbgDisplay)SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_GETCURSEL, 0, 0); } // ============================================================================================= @@ -643,9 +645,9 @@ void OpenDlgClbk(void *context) SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"Blur 2"); SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"Blur 3"); SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"Blur 4"); - SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"--unused--"); - SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"--unused--"); - SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"ShadowMap"); + SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"SS_ShadowMap"); + SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"VC_ShadowMap"); + SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"EX_ShadowMap"); SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"Irradiance"); SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"GlowMask"); SendDlgItemMessageA(hDlg, IDC_DBG_ENVMAP, CB_ADDSTRING, 0, (LPARAM)"ScreenDepth"); @@ -664,6 +666,14 @@ void OpenDlgClbk(void *context) SendDlgItemMessageA(hDlg, IDC_DBG_AMBDIR, CB_ADDSTRING, 0, (LPARAM)"From Aft (-z)"); SendDlgItemMessageA(hDlg, IDC_DBG_AMBDIR, CB_SETCURSEL, 0, 0); + SendDlgItemMessageA(hDlg, IDC_DBG_DATASRC, CB_RESETCONTENT, 0, 0); + SendDlgItemMessageA(hDlg, IDC_DBG_DATASRC, CB_ADDSTRING, 0, (LPARAM)"Exterior"); + SendDlgItemMessageA(hDlg, IDC_DBG_DATASRC, CB_ADDSTRING, 0, (LPARAM)"Interior 0"); + SendDlgItemMessageA(hDlg, IDC_DBG_DATASRC, CB_ADDSTRING, 0, (LPARAM)"Interior 1"); + SendDlgItemMessageA(hDlg, IDC_DBG_DATASRC, CB_ADDSTRING, 0, (LPARAM)"Interior 2"); + SendDlgItemMessageA(hDlg, IDC_DBG_DATASRC, CB_ADDSTRING, 0, (LPARAM)"Interior 3"); + SendDlgItemMessageA(hDlg, IDC_DBG_DATASRC, CB_SETCURSEL, 0, 0); + SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_RESETCONTENT, 0, 0); for (int i = 0; i < 16; i++) { sprintf_s(buf, 64, "Baked_%d", i); @@ -1853,7 +1863,7 @@ void SaveEnvMap() if (oapiIsVessel(hObj)) { vVessel *vVes = (vVessel *)vObj; - auto pTex = vVes->GetEnvMap() ? vVes->GetEnvMap()->pEnv : nullptr; + auto pTex = vVes->GetExteriorEnvMap() ? vVes->GetExteriorEnvMap()->pCube : nullptr; if (pTex->GetType() == D3DRTYPE_CUBETEXTURE) { if (D3DXSaveTextureToFileA("EnvMap.dds", D3DXIFF_DDS, (LPDIRECT3DCUBETEXTURE9)pTex, NULL) != S_OK) { LogErr("Failed to save envmap"); @@ -2206,12 +2216,24 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } break; + case IDC_DBG_DATASRC: + if (HIWORD(wParam) == CBN_SELCHANGE) { + probe_id = int(SendDlgItemMessage(hDlg, IDC_DBG_DATASRC, CB_GETCURSEL, 0, 0)) - 1; + } + break; + case IDC_DBG_AMBDIR: if (HIWORD(wParam) == CBN_SELCHANGE) { ambdir = int(SendDlgItemMessage(hDlg, IDC_DBG_AMBDIR, CB_GETCURSEL, 0, 0)) - 1; } break; + case IDC_DBG_ENVMAP: + if (HIWORD(wParam) == CBN_SELCHANGE) { + dbgdsp = DbgDisplay(SendDlgItemMessage(hDlg, IDC_DBG_ENVMAP, CB_GETCURSEL, 0, 0)); + } + break; + case IDC_DBG_DISPLAY: if (HIWORD(wParam)==CBN_SELCHANGE) dspMode = DWORD(SendDlgItemMessage(hWnd, IDC_DBG_DISPLAY, CB_GETCURSEL, 0, 0)); break; diff --git a/OVP/D3D9Client/DebugControls.h b/OVP/D3D9Client/DebugControls.h index dab521fd0..baec4d3eb 100644 --- a/OVP/D3D9Client/DebugControls.h +++ b/OVP/D3D9Client/DebugControls.h @@ -71,11 +71,19 @@ class vObject; +enum class DbgDisplay { + None, Mirror, Blur1, Blur2, Blur3, Blur4, + smSS, smVC, smEX, Irradiance, GlowMask, + ScreenDepth, Normals, LightVisbil, BakedLightMap +}; + // ============================================================== namespace DebugControls { + extern DbgDisplay dbgdsp; extern int ambdir; + extern int probe_id; extern DWORD sMesh; extern DWORD sGroup; extern DWORD debugFlags; @@ -124,7 +132,7 @@ namespace DebugControls { void SelectMesh(D3D9Mesh *pMesh); void SetGroupHighlight(bool bStat); int GetSceneDebug(); - int GetSelectedEnvMap(); + DbgDisplay GetSelectedEnvMap(); bool IsActive(); bool IsSelectedGroupRendered(); @@ -132,6 +140,8 @@ namespace DebugControls { void Append(const char *format, ...); void Refresh(); + inline int GetProbeId() { return probe_id; } + LPDIRECT3DTEXTURE9 GetCombinedMap(); INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); diff --git a/OVP/D3D9Client/MaterialMgr.cpp b/OVP/D3D9Client/MaterialMgr.cpp index 7bc11f4c1..8e89b4bb1 100644 --- a/OVP/D3D9Client/MaterialMgr.cpp +++ b/OVP/D3D9Client/MaterialMgr.cpp @@ -402,7 +402,7 @@ bool MatMgr::LoadCameraConfig() pCamera->flags = 0; // Clear default flags } if (idx == 1) { - pCamera = ((vVessel*)vObj)->CreateEnvCam(EnvCamType::VC); + pCamera = ((vVessel*)vObj)->CreateEnvCam(EnvCamType::Interior); pCamera->id = -1; pCamera->flags = 0; // Clear default flags } diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index 3f181d98d..b3d4d68cc 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -53,6 +53,7 @@ MeshBuffer::MeshBuffer(DWORD _nVtx, DWORD _nFace, const class D3D9Mesh *_pRoot) { nVtx = _nVtx; nIdx = _nFace * 3; + nRef = 1; pVB = NULL; pIB = NULL; @@ -74,6 +75,7 @@ MeshBuffer::MeshBuffer(MeshBuffer *pSrc, const class D3D9Mesh *_pRoot) { nVtx = pSrc->nVtx; nIdx = pSrc->nIdx; + nRef = 1; pVB = NULL; pIB = NULL; @@ -106,6 +108,19 @@ MeshBuffer::~MeshBuffer() SAFE_RELEASE(pVB); SAFE_RELEASE(pGB); SAFE_RELEASE(pSB); + oapiWriteLog("MeshBuffer::Destruct"); +} + +bool MeshBuffer::Release() +{ + nRef--; + return nRef <= 0; +} + +MeshBuffer* MeshBuffer::Reference() +{ + nRef++; + return this; } void MeshBuffer::MustRemap(DWORD mode) @@ -342,7 +357,7 @@ D3D9Mesh::D3D9Mesh(MESHHANDLE hMesh, const D3D9Mesh &hTemp) strcpy_s(name, ARRAYSIZE(name), hTemp.name); // Use Template's Vertex Data directly, no need for a local copy unless locally modified. - pBuf = hTemp.pBuf; + pBuf = hTemp.pBuf->Reference(); BBox = hTemp.BBox; MaxVert = hTemp.MaxVert; @@ -406,7 +421,8 @@ void D3D9Mesh::Release() SAFE_DELETEA(Mtrl); SAFE_DELETEA(pGrpTF); - if (pBuf) if (pBuf->IsLocalTo(this)) delete pBuf; + if (pBuf) if (pBuf->Release()) delete pBuf; + pBuf = nullptr; for (auto x : BakedLights) { for (auto y : x.second.pMap) SAFE_RELEASE(y); @@ -447,7 +463,7 @@ void D3D9Mesh::ReLoadMeshFromHandle(MESHHANDLE hMesh) if (MaxVert == 0 || MaxFace == 0) { if (pBuf) if (pBuf->IsLocalTo(this)) { - delete pBuf; pBuf = NULL; + if (pBuf->Release()) SAFE_DELETE(pBuf); } return; } @@ -1711,11 +1727,11 @@ void D3D9Mesh::ConfigureShadows() // =========================================================================================== // static: -void D3D9Mesh::SetShadows(const SHADOWMAPPARAM *sprm) +void D3D9Mesh::SetShadows(const SHADOWMAP *sprm) { if (sprm) { for (int i = 0; i < SHM_CASCADE_COUNT; i++) { - pShadowMap[i] = sprm->pShadowMap[i]; + pShadowMap[i] = sprm->Map(i); ShdSubRect[i] = sprm->SubrectTF[i]; } } @@ -1731,7 +1747,7 @@ void D3D9Mesh::SetShadows(const SHADOWMAPPARAM *sprm) // ================================================================================================ // This is a rendering routine for a Exterior Mesh, non-spherical moons/asteroids // -void D3D9Mesh::Render(const LPD3DXMATRIX pW, const ENVMAPS* em, int iTech) +void D3D9Mesh::Render(const LPD3DXMATRIX pW, const ENVCAMREC* em, int iTech) { _TRACE; @@ -1901,9 +1917,9 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, const ENVMAPS* em, int iTech) // Setup Env Maps ------------------------------------------- // - if (em && em->pEnv && em->pIrrad) { + if (em && em->pCube && em->pIrrad) { FX->SetBool(eEnvMapEnable, true); - FX->SetTexture(eEnvMapA, em->pEnv); + FX->SetTexture(eEnvMapA, em->pCube); FX->SetTexture(eIrradMap, em->pIrrad); } else { @@ -3038,7 +3054,7 @@ void D3D9Mesh::RenderShadowMap(const LPD3DXMATRIX pW, const LPD3DXMATRIX pVP, in MeshShader* pShader = nullptr; - MeshShader::vs_const.mVP = *pVP; + MeshShader::vs_const.mVP = pVP ? *pVP : FMATRIX4::Identity(); D3DXMatrixIdentity(MeshShader::vs_const.mW); diff --git a/OVP/D3D9Client/Mesh.h b/OVP/D3D9Client/Mesh.h index 7034d183f..3c32dc096 100644 --- a/OVP/D3D9Client/Mesh.h +++ b/OVP/D3D9Client/Mesh.h @@ -137,6 +137,8 @@ class MeshBuffer void Map(LPDIRECT3DDEVICE9 pDev); bool IsLocalTo(const class D3D9Mesh *_pRoot) const { return (_pRoot == pRoot); } void MustRemap(DWORD mode); + bool Release(); + MeshBuffer* Reference(); LPDIRECT3DVERTEXBUFFER9 pVB; LPDIRECT3DVERTEXBUFFER9 pGB; @@ -148,6 +150,7 @@ class MeshBuffer WORD *pIBSys; SMVERTEX *pSBSys; + DWORD nRef; DWORD nVtx; DWORD nIdx; DWORD mapMode; @@ -311,7 +314,7 @@ class D3D9Mesh : private D3D9Effect void RenderGroup(int idx); void RenderBaseTile(const LPD3DXMATRIX pW); void RenderBoundingBox(const LPD3DXMATRIX pW); - void Render(const LPD3DXMATRIX pW, const ENVMAPS *em = NULL, int iTech = RENDER_VESSEL); + void Render(const LPD3DXMATRIX pW, const ENVCAMREC* em = NULL, int iTech = RENDER_VESSEL); void RenderFast(const LPD3DXMATRIX pW, int iTech); void RenderShadowMap(const LPD3DXMATRIX pW, const LPD3DXMATRIX pVP, int flags, bool bNoCull = false); void RenderStencilShadows(float alpha, const LPD3DXMATRIX pP, const LPD3DXMATRIX pW, bool bShadowMap = false, const D3DXVECTOR4 *elev = NULL); @@ -353,7 +356,7 @@ class D3D9Mesh : private D3D9Effect static void GlobalInit(LPDIRECT3DDEVICE9 pDev); static void GlobalExit(); - static void SetShadows(const SHADOWMAPPARAM* sprm); + static void SetShadows(const SHADOWMAP* sprm); private: diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index 8b73b06f0..c6d608c72 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -33,14 +33,6 @@ static D3DXMATRIX ident; const double LABEL_DISTLIMIT = 0.6; -struct PList { // auxiliary structure for object distance sorting - vObject *vo; - double dist; -}; - -const int MAXPLANET = 512; // hard limit; should be fixed -static PList plist[MAXPLANET]; - ID3DXEffect * Scene::FX = 0; D3DXHANDLE Scene::eLine = 0; D3DXHANDLE Scene::eStar = 0; @@ -51,11 +43,16 @@ D3DXHANDLE Scene::eTex0 = 0; D3DXVECTOR4 IKernel[IKernelSize]; -bool sort_vessels(const vVessel *a, const vVessel *b) +bool sort_tgt_dist(const vObject *a, const vObject *b) { return a->CameraTgtDist() < b->CameraTgtDist(); } +bool sort_cdist(const vObject* a, const vObject* b) +{ + return a->CamDist() > b->CamDist(); +} + float Rand() { return float(rand()) / 32768.0f; @@ -113,24 +110,18 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) dmCubeMesh = NULL; pRenderStage = NULL; - vobjEnv = eCamRenderList.begin(); + vobjEnv = eCamRenderList.cend(); + itIC = InteriorCams.cend(); fDisplayScale = float(viewH) / 1080.0f; for (auto& a : DepthSampleKernel) a = FVECTOR2(0, 0); memset(&psShmDS, 0, sizeof(psShmDS)); - memset(&ptShmRT, 0, sizeof(ptShmRT)); - memset(&psShmRT, 0, sizeof(psShmRT)); - - memset(&ptVCShmRT, 0, sizeof(ptShmRT)); - memset(&psVCShmRT, 0, sizeof(psShmRT)); - + memset(&Camera, 0, sizeof(Camera)); pDevice = _gc->GetDevice(); - memset(&Camera, 0, sizeof(Camera)); - D3DXMatrixIdentity(&ident); SetCameraAperture(float(RAD*50.0), float(viewH)/float(viewW)); @@ -142,7 +133,7 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) bLocalLight = *(bool*)gc->GetConfigParam(CFGPRM_LOCALLIGHT); memset(&sunLight, 0, sizeof(D3D9Sun)); - memset(&smap, 0, sizeof(smap)); + CLEARARRAY(pBlrTemp); CLEARARRAY(pBlrTemp2D); @@ -150,7 +141,6 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) CLEARARRAY(ptgBuffer); CLEARARRAY(psgBuffer); - vobjFirst = vobjLast = NULL; nstream = 0; iVCheck = 0; @@ -233,30 +223,26 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) DWORD ShmMapSize = Config->ShadowMapSize; if (Config->EnvMapMode) { - HR(pDevice->CreateDepthStencilSurface(EnvMapSize, EnvMapSize, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, true, &pEnvDS, NULL)); + HR(pDevice->CreateDepthStencilSurface(EnvMapSize, EnvMapSize, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, true, &pEnvDS, NULL)); } - // Exterior shadows + + // Create Depth Stencil buffers for shadow maps + // if (Config->ShadowMapMode) { UINT size = ShmMapSize; for (int i = 0; i < SHM_LOD_COUNT; i++) { HR(pDevice->CreateDepthStencilSurface(size, size, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, true, &psShmDS[i], NULL)); - HR(pDevice->CreateTexture(size, size, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R32F, D3DPOOL_DEFAULT, &ptShmRT[i], NULL)); - HR(ptShmRT[i]->GetSurfaceLevel(0, &psShmRT[i])); size >>= 1; } - - smap.pShadowMap[0] = ptShmRT[0]; } - // VC Shadows - if (Config->ShadowMapMode) { - UINT size = ShmMapSize; - for (int i = 0; i < SHM_CASCADE_COUNT; i++) { - HR(pDevice->CreateTexture(size, size, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R32F, D3DPOOL_DEFAULT, &ptVCShmRT[i], NULL)); - HR(ptVCShmRT[i]->GetSurfaceLevel(0, &psVCShmRT[i])); - } - } + // Create shadow map for vessel exterior shadowing + smEX = new SHADOWMAP(pDevice, SHADOWMAP::sMapType::MultiLod); + // Create shadow map for virtual cockpit shadowing + smVC = new SHADOWMAP(pDevice, SHADOWMAP::sMapType::Cascaded); + // Create shadow map for shadowing in a stage-set + smSS = new SHADOWMAP(pDevice, SHADOWMAP::sMapType::SingleLod); // Create auxiliary color buffer for on screen GDI @@ -271,7 +257,7 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) // Create an auxiliary screen space normal and depth buffer (i.e. Shader readable depth buffer) // if (Config->bGlares || Config->bLocalGlares) { - HR(pDevice->CreateDepthStencilSurface(viewW, viewH, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, true, &pDepthNormalDS, NULL)); + HR(pDevice->CreateDepthStencilSurface(viewW, viewH, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, true, &pDepthNormalDS, NULL)); HR(D3DXCreateTexture(pDevice, viewW, viewH, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &ptgBuffer[GBUF_DEPTH])); } @@ -397,11 +383,11 @@ Scene::~Scene () SAFE_RELEASE(pSunGlareAtm); SAFE_RELEASE(ptRandom); + SAFE_DELETE(smEX); + SAFE_DELETE(smVC); + SAFE_DELETE(smSS); + for (int i = 0; i < ARRAYSIZE(psShmDS); i++) SAFE_RELEASE(psShmDS[i]); - for (int i = 0; i < ARRAYSIZE(ptShmRT); i++) SAFE_RELEASE(ptShmRT[i]); - for (int i = 0; i < ARRAYSIZE(psShmRT); i++) SAFE_RELEASE(psShmRT[i]); - for (int i = 0; i < ARRAYSIZE(ptVCShmRT); i++) SAFE_RELEASE(ptVCShmRT[i]); - for (int i = 0; i < ARRAYSIZE(psVCShmRT); i++) SAFE_RELEASE(psVCShmRT[i]); for (int i = 0; i < ARRAYSIZE(pBlrTemp); i++) SAFE_RELEASE(pBlrTemp[i]); for (int i = 0; i < ARRAYSIZE(pBlrTemp2D); i++) SAFE_RELEASE(pBlrTemp2D[i]); @@ -632,8 +618,7 @@ const D3D9Light *Scene::GetLight(int index) const Scene::VOBJREC *Scene::FindVisual(OBJHANDLE hObj) const { if (hObj==NULL) return NULL; - VOBJREC *pv; - for (pv=vobjFirst; pv; pv=pv->next) if (pv->vobj->Object()==hObj) return pv; + for (auto v : Visuals) if (v->vobj->Object() == hObj) return v; return NULL; } @@ -641,8 +626,8 @@ Scene::VOBJREC *Scene::FindVisual(OBJHANDLE hObj) const // class vObject *Scene::GetVisObject(OBJHANDLE hObj) const { - Scene::VOBJREC *v = FindVisual(hObj); - if (v) return v->vobj; + if (hObj == NULL) return NULL; + for (auto v : Visuals) if (v->vobj->Object() == hObj) return v->vobj; return NULL; } @@ -651,11 +636,10 @@ class vObject *Scene::GetVisObject(OBJHANDLE hObj) const std::set Scene::GetVessels(double max_dst, bool bAct) { std::set List; - VOBJREC *pv; - for (pv = vobjFirst; pv; pv = pv->next) { - if (pv->type != OBJTP_VESSEL) continue; - if (bAct && pv->vobj->IsActive() == false) continue; - if (pv->vobj->CamDist() < max_dst) List.insert((vVessel *)pv->vobj); + for (auto v : Visuals) { + if (v->type != OBJTP_VESSEL) continue; + if (bAct && v->vobj->IsActive() == false) continue; + if (v->vobj->CamDist() < max_dst) List.insert((vVessel *)v->vobj); } return List; } @@ -664,42 +648,26 @@ std::set Scene::GetVessels(double max_dst, bool bAct) // void Scene::DelVisualRec (VOBJREC *pv) { - _TRACE; - // unlink the entry - if (pv->prev) pv->prev->next = pv->next; - else vobjFirst = pv->next; - - if (pv->next) pv->next->prev = pv->prev; - else vobjLast = pv->prev; - - DebugControls::RemoveVisual(pv->vobj); - // delete the visual, its children and the entry itself + DebugControls::RemoveVisual(pv->vobj); gc->UnregisterVisObject(pv->vobj->GetObjHandle()); if (pv->type == OBJTP_VESSEL) gc->clbkScenarioChanged(pv->vobj, ScnChgEvent::VisualDeleted); delete pv->vobj; - delete pv; + Visuals.remove(pv); } // =========================================================================================== // void Scene::DeleteAllVisuals() { - _TRACE; - VOBJREC *pv = vobjFirst; - while (pv) { - VOBJREC *pvn = pv->next; - - DebugControls::RemoveVisual(pv->vobj); - - gc->UnregisterVisObject(pv->vobj->GetObjHandle()); - - LogAlw("Deleting Visual %s", _PTR(pv->vobj)); - delete pv->vobj; - delete pv; - pv = pvn; + for (auto v : Visuals) + { + DebugControls::RemoveVisual(v->vobj); + gc->UnregisterVisObject(v->vobj->GetObjHandle()); + LogAlw("Deleting Visual %s", _PTR(v->vobj)); + delete v->vobj; } - vobjFirst = vobjLast = NULL; + Visuals.clear(); } // =========================================================================================== @@ -715,6 +683,8 @@ Scene::VOBJREC *Scene::AddVisualRec(OBJHANDLE hObj) memset(pv, 0, sizeof(VOBJREC)); + Visuals.push_back(pv); + pv->vobj = vObject::Create(hObj, this); pv->type = oapiGetObjectType(hObj); @@ -723,13 +693,6 @@ Scene::VOBJREC *Scene::AddVisualRec(OBJHANDLE hObj) VESSEL *hVes=NULL; if (pv->type==OBJTP_VESSEL) hVes = oapiGetVesselInterface(hObj); - // link entry to end of list - pv->prev = vobjLast; - pv->next = NULL; - if (vobjLast) vobjLast->next = pv; - else vobjFirst = pv; - vobjLast = pv; - LogAlw("RegisteringVisual (%s) hVessel=%s, hObj=%s, Vis=%s, Rec=%s, Type=%d", buf, _PTR(hVes), _PTR(hObj), _PTR(pv->vobj), _PTR(pv), pv->type); gc->RegisterVisObject(hObj, (VISHANDLE)pv->vobj); @@ -970,7 +933,7 @@ float Scene::ComputeNearClipPlane() float nearpoint = 10e3f; float neardist = 10e3f; - for (pv = vobjFirst; pv; pv = pv->next) { + for (auto pv : Visuals) { float nr = 10e3f; float fr = 0.0f; @@ -1087,7 +1050,7 @@ void Scene::UpdateCamVis() // OBJHANDLE hFocus = oapiGetFocusObject(); vFocus = NULL; - for (VOBJREC *pv=vobjFirst; pv; pv=pv->next) { + for (auto pv : Visuals) { if (pv->type==OBJTP_VESSEL) if (pv->vobj->Object()==hFocus) { vFocus = (vVessel *)pv->vobj; break; @@ -1108,7 +1071,7 @@ void Scene::UpdateCamVis() ClearLocalLights(); VOBJREC *pv = NULL; - for (pv = vobjFirst; pv; pv = pv->next) { + for (auto pv : Visuals) { if (!pv->vobj->IsActive()) continue; OBJHANDLE hObj = pv->vobj->Object(); if (oapiGetObjectType (hObj) == OBJTP_VESSEL) { @@ -1129,21 +1092,14 @@ void Scene::UpdateCamVis() // we render without z-buffer, so need to distance-sort the objects // ---------------------------------------------------------------- - VOBJREC *pv = NULL; - nplanets = 0; + Planets.clear(); - for (pv = vobjFirst; pv && nplanets < MAXPLANET; pv = pv->next) { + for (auto pv : Visuals) { if (pv->apprad < 0.01 && pv->type != OBJTP_STAR) continue; - if (pv->type == OBJTP_PLANET || pv->type == OBJTP_STAR) { - plist[nplanets].vo = pv->vobj; - plist[nplanets].dist = pv->vobj->CamDist(); - nplanets++; - } + if (pv->type == OBJTP_PLANET || pv->type == OBJTP_STAR) Planets.push_back(pv->vobj); } - int distcomp(const void *arg1, const void *arg2); - - qsort((void*)plist, nplanets, sizeof(PList), distcomp); + Planets.sort(sort_cdist); } // =========================================================================================== @@ -1296,9 +1252,9 @@ void Scene::clbkScenarioChanged(OBJHANDLE hVessel, ScnChgEvent e) // Acquire list of vessel visuals // Vessels.clear(); + for (auto v : Visuals) + if (v->type == OBJTP_VESSEL) Vessels.insert((vVessel*)v->vobj); - for (VOBJREC* pv = vobjFirst; pv; pv = pv->next) - if (pv->type == OBJTP_VESSEL) Vessels.insert((vVessel*)pv->vobj); // Update Attachment hierarchy // @@ -1321,8 +1277,18 @@ void Scene::clbkScenarioChanged(OBJHANDLE hVessel, ScnChgEvent e) for (auto v : Vessels) if (v->HasOwnEnvCam(EnvCamType::Exterior)) eCamRenderList.insert(v); - // Return vobjEnv iterator to start of the list + + // --------------------------------------------------------------------------------------- + // Return critical iterators to a start of the list. List context may have changed + // --------------------------------------------------------------------------------------- + vobjEnv = eCamRenderList.begin(); + vobjIP = eCamRenderList.begin(); + + if (e == ScnChgEvent::Deleted) { + InteriorCams.clear(); + itIC = InteriorCams.begin(); + } } @@ -1348,9 +1314,10 @@ void Scene::clbkRenderMainScene() for (auto v : Active) v->UpdateAnimations(); - if (vFocus == NULL) return; + if (vFocus == nullptr) return; - LPDIRECT3DSURFACE9 pBackBuffer; + LPDIRECT3DSURFACE9 pBackBuffer = nullptr; + LPDIRECT3DTEXTURE9 pExtShdMap = nullptr; if (pOffscreenTarget) pBackBuffer = pOffscreenTarget; else pBackBuffer = gc->GetBackBuffer(); @@ -1391,7 +1358,7 @@ void Scene::clbkRenderMainScene() if (vO->CamDist() < maxd && (*camCurrent)->bActive) { - RenderCustomCameraView((*camCurrent)); + RenderCustomCameraView((*camCurrent)); // Note: World origin is changed here if ((*camCurrent)->pRenderProc) { D3D9Pad *pSkp = (D3D9Pad * )gc->clbkGetSketchpad((*camCurrent)->hSurface); @@ -1412,8 +1379,8 @@ void Scene::clbkRenderMainScene() if (dwTurn == RENDERTURN_ENVCAM && Config->EnvMapMode) { DWORD flags = 0; - if (Config->EnvMapMode == 1) flags |= 0x01; - if (Config->EnvMapMode == 2) flags |= (0x03 | 0x20); + if (Config->EnvMapMode == 1) flags |= SCN_PLANETS; + if (Config->EnvMapMode == 2) flags |= SCN_PLANETS | SCN_VESSELS | SCN_BASESTRUCT; if (vobjEnv == eCamRenderList.end()) vobjEnv = eCamRenderList.begin(); @@ -1421,6 +1388,7 @@ void Scene::clbkRenderMainScene() auto vV = (*vobjEnv); if (vV->IsVisible()) { if (vV->CamDist() < 10e3) { + // Note: World origin is changed here if (vV->ProcessEnvMaps(pDevice, RenderCount, flags) == false) break; } } @@ -1429,15 +1397,31 @@ void Scene::clbkRenderMainScene() } + // ------------------------------------------------------------------------------------------------------- + // Render reflection cube maps and irradiance for interior parts + // ------------------------------------------------------------------------------------------------------- + + if (Config->EnvMapMode) + { + if (vobjIP == eCamRenderList.end()) vobjIP = eCamRenderList.begin(); + + while (vobjIP != eCamRenderList.end()) { + auto vV = (*vobjIP); + if (vV->IsVisible()) { + if (vV->CamDist() < 500.0) { + if (RenderVCProbes(vV) == false) break; // Note: World origin is changed here + } + } + vobjIP++; + } + } + + // --------------------------------------------------------------------------------------------- // Init. camera setup and create a render list // --------------------------------------------------------------------------------------------- - VOBJREC* pv = NULL; - LPDIRECT3DTEXTURE9 pShdMap = NULL; - - UpdateCameraFromOrbiter(RENDERPASS_MAINSCENE); - UpdateCamVis(); + ResetOrigin(Camera.pos); // Restore world origin to main camera position RenderList.clear(); @@ -1467,13 +1451,13 @@ void Scene::clbkRenderMainScene() RecallDefaultState(); // Clear buffers - HR(pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, 0, 1.0f, 0L)); + HR(pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 1.0f, 0L)); // Render vessels - for (auto vVes : RenderList) vVes->Render(pDevice, false); + for (auto vVes : RenderList) vVes->Render(pDevice, false, nullptr); // Render Cockpit - if (oapiCameraInternal() && vFocus) vFocus->Render(pDevice, true); + if (oapiCameraInternal() && vFocus) vFocus->Render(pDevice, true, nullptr); gc->PopRenderTargets(); PopPass(); @@ -1550,10 +1534,10 @@ void Scene::clbkRenderMainScene() // Create a caster list for shadow mapping // --------------------------------------------------------------------------------------------- - Casters.clear(); - for (auto v : Active) Casters.push_back(v); + ObjectsToShadowMap.clear(); + for (auto v : Active) ObjectsToShadowMap.push_back(v); - Casters.sort(sort_vessels); + ObjectsToShadowMap.sort(sort_tgt_dist); @@ -1564,10 +1548,12 @@ void Scene::clbkRenderMainScene() int shadow_lod = -1; float bouble_rad = 10.0f; // Terrain shadow mapping coverage - if (Config->ShadowMapMode >= 1 && Config->TerrainShadowing == 2) { - SmapRenderList.clear(); - SmapRenderList.push_back(vFocus); + if (Config->ShadowMapMode >= 1 && Config->TerrainShadowing == 2) + { + // Create a list of objects casting shadows on vFocus + Casters.clear(); + Casters.push_back(vFocus); D3DXVECTOR3 ld = sunLight.Dir; D3DXVECTOR3 pos = vFocus->GetBoundingSpherePosDX(); @@ -1579,7 +1565,7 @@ void Scene::clbkRenderMainScene() // What else should be included besides vFocus ? - for (auto v : Casters) + for (auto v : ObjectsToShadowMap) { if (v == vFocus) continue; if (v->HasShadow() == false) continue; @@ -1606,7 +1592,7 @@ void Scene::clbkRenderMainScene() if (bInclude) { v->bStencilShadow = false; - SmapRenderList.push_back(v); + Casters.push_back(v); if (nrd < rad) continue; @@ -1621,9 +1607,8 @@ void Scene::clbkRenderMainScene() } } - shadow_lod = RenderShadowMap(pos, ld, rad, false, true); - - pShdMap = smap.pShadowMap[0]; + SMapInput smi = { pos, ld, rad }; + RenderShadowMap(&smi, smEX, Casters, true); } @@ -1635,26 +1620,26 @@ void Scene::clbkRenderMainScene() DWORD plnmode = *(DWORD*)gc->GetConfigParam(CFGPRM_PLANETARIUMFLAG); DWORD mkrmode = *(DWORD*)gc->GetConfigParam(CFGPRM_SURFMARKERFLAG); - for (DWORD i=0;iRenderZRange (&nplane, &fplane); // cam->SetFrustumLimits (nplane, fplane); // since we are not using z-buffers here, we can adjust the projection // matrix at will to make sure the object is within the viewing frustum - OBJHANDLE hObj = plist[i].vo->Object(); - bool isActive = plist[i].vo->IsActive(); + OBJHANDLE hObj = pl->Object(); + bool isActive = pl->IsActive(); - if (isActive) plist[i].vo->Render(pDevice); - else plist[i].vo->RenderDot(pDevice); + if (isActive) pl->Render(pDevice); + else pl->RenderDot(pDevice); D3D9Pad *pSketch = GetPooledSketchpad(SKETCHPAD_LABELS); if (pSketch) { - if (isActive) plist[i].vo->RenderVectors(pDevice, pSketch); + if (isActive) pl->RenderVectors(pDevice, pSketch); if (mkrmode & MKR_ENABLE) { @@ -1674,7 +1659,7 @@ void Scene::clbkRenderMainScene() if (label_format < 2 && (mkrmode & MKR_LMARK)) // user-defined planetary surface labels { double rad = oapiGetSize(hObj); - double apprad = rad / (plist[i].dist * tan(GetCameraAperture())); + double apprad = rad / (pl->CamDist() * tan(GetCameraAperture())); const GraphicsClient::LABELLIST *list; DWORD n, nlist; MATRIX3 prot; @@ -1788,19 +1773,19 @@ void Scene::clbkRenderMainScene() m_celSphere->EnsureMarkerDrawingContext((oapi::Sketchpad**)&pSketch, 0, 0, m_celSphere->MarkerPen(6)); int fontidx = -1; - for (DWORD i = 0; i < nplanets; ++i) + for (auto pl : Planets) { - OBJHANDLE hObj = plist[i].vo->Object(); + OBJHANDLE hObj = pl->Object(); if (oapiGetObjectType(hObj) != OBJTP_PLANET) { continue; } if (!surfLabelsActive) { - static_cast( plist[i].vo )->ActivateLabels(true); + static_cast(pl)->ActivateLabels(true); } int label_format = *(int*)oapiGetObjectParam(hObj, OBJPRM_PLANET_LABELENGINE); if (label_format == 2) { - static_cast(plist[i].vo)->RenderLabels(pDevice, pSketch, label_font, &fontidx); + static_cast(pl)->RenderLabels(pDevice, pSketch, label_font, &fontidx); } } @@ -1830,86 +1815,45 @@ void Scene::clbkRenderMainScene() D3D9Pad* pSketch = GetPooledSketchpad(SKETCHPAD_LABELS); m_celSphere->EnsureMarkerDrawingContext((oapi::Sketchpad**)&pSketch, 0, m_celSphere->MarkerColor(0), m_celSphere->MarkerPen(0)); - // Render the vessels inside the shadows - // - if (Config->ShadowMapMode >= 1) { - - D3DXVECTOR3 ld = sunLight.Dir; - D3DXVECTOR3 pos = vFocus->GetBoundingSpherePosDX(); - float rad = vFocus->GetBoundingSphereRadius(); - - int shadow_lod = RenderShadowMap(pos, ld, rad); - if (shadow_lod >= 0) { - - pShdMap = ptShmRT[shadow_lod]; - - auto it = RenderList.begin(); - - while (it != RenderList.end()) { - if ((*it)->IsInsideShadows()) { - (*it)->Render(pDevice); - RenderVesselMarker((*it), pSketch); - it = RenderList.erase(it); - } - else ++it; - } - } + // Render the vessels inside the shadows ( Phase 1 ) ================================ + // + if (Config->ShadowMapMode >= 1) + { + // Get shadowing params for vFocus + SMapInput smi = vFocus->GetSMapRenderData(); + pExtShdMap = RenderObjectsInShadow(&smi, RenderList, pSketch); } + // Render additional shadows ( Phase 2 ) ============================================= + // + if ((Config->ShadowMapMode >= 2) && (DebugControls::IsActive()==false)) + { + // Don't render more shadows if debug controls are open to keep pExtShdMap valid - if ((Config->ShadowMapMode >= 2) && (DebugControls::IsActive()==false)) { - // Don't render more shadows if debug controls are open - - std::list Intersect; + SMapInput smf = vFocus->GetSMapRenderData(); + list RenderThese; - // Select the objects to shadow map + // Select objects to render with shadow map // - if (Config->ShadowMapMode >= 3) { - for (auto it = RenderList.begin(); it != RenderList.end(); ++it) { - if ((*it)->CamDist() < 1e3) Intersect.push_back((*it)); - } - } - else { - for (auto it = RenderList.begin(); it != RenderList.end(); ++it) { - if ((*it)->IntersectShadowTarget()) Intersect.push_back((*it)); - } - } - + if (Config->ShadowMapMode >= 3) for (auto v : RenderList) if (v->CamDist() < 1e3) RenderThese.push_back(v); + else for (auto v : RenderList) if (v->IntersectShadowTarget(&smf)) RenderThese.push_back(v); - while (!Intersect.empty()) { + // Erase objects from render list + for (auto v : RenderThese) RenderList.remove(v); - D3DXVECTOR3 ld = sunLight.Dir; - D3DXVECTOR3 pos = Intersect.front()->GetBoundingSpherePosDX(); - float rad = Intersect.front()->GetBoundingSphereRadius(); - - Intersect.pop_front(); - - int lod = RenderShadowMap(pos, ld, rad); - - if (lod >= 0) { - - // Render objects in shadow - auto it = RenderList.begin(); - - while (it != RenderList.end()) { - if ((*it)->IsInsideShadows()) { - (*it)->Render(pDevice); - RenderVesselMarker((*it), pSketch); - Intersect.remove((*it)); - it = RenderList.erase(it); - } - else ++it; - } - } + while (RenderThese.size()) + { + SMapInput smi = RenderThese.front()->GetSMapRenderData(); + RenderObjectsInShadow(&smi, RenderThese, pSketch); } } // Render the remaining vessels those are not yet renderred // - smap.pShadowMap[SHM_CASCADE_COUNT] = { }; + smEX->Clear(); while (RenderList.empty()==false) { RenderList.front()->Render(pDevice); @@ -1970,7 +1914,7 @@ void Scene::clbkRenderMainScene() pSketch->SetFont(pAxisFont); pSketch->SetTextAlign(Sketchpad::LEFT, Sketchpad::TOP); - for (pv=vobjFirst; pv; pv=pv->next) { + for (auto pv : Visuals) { if (!pv->vobj->IsActive()) continue; if (!pv->vobj->IsVisible()) continue; if (oapiCameraInternal() && vFocus==pv->vobj) continue; @@ -1981,13 +1925,6 @@ void Scene::clbkRenderMainScene() pSketch->EndDrawing(); // SKETCHPAD_LABELS } - if (vFocus) { - auto a = vFocus->GetEnvMap()->pEnv; - if (a && bStageSet) RenderStage((LPDIRECT3DCUBETEXTURE9)a); - } - - - // ------------------------------------------------------------------------------------------------------- // render the internal parts of the focus object in a separate render pass @@ -2021,13 +1958,12 @@ void Scene::clbkRenderMainScene() if (DebugControls::IsActive()) { if (DebugControls::debugFlags & DBG_FLAGS_RENDEREXT) { - vFocus->Render(pDevice, false); + // vFocus->Render(pDevice, false, nullptr); } } if (Config->ShadowMapMode >= 1) { - SmapRenderList.clear(); cascfg[0].dist = 2.5f; cascfg[0].size = 2.5f; float sa = sin(GetCameraApertureCorner()); @@ -2053,14 +1989,13 @@ void Scene::clbkRenderMainScene() //D3D9DebugLog("Aperture = %f, dist=%f", GetCameraApertureCorner() * 2.0 * 180.0 / PI, cascfg[2].dist- cascfg[2].size); - D3DXVECTOR3 ld = sunLight.Dir; - RenderVCShadowMap(Camera.z, ld, false); - - pShdMap = smap.pShadowMap[0]; + D3DXVECTOR3 ld = sunLight.Dir; + Casters.clear(); + RenderVCShadowMap(Camera.z, ld, Casters); } // Render VC - vFocus->Render(pDevice, true); + vFocus->Render(pDevice, true, smVC); } pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); @@ -2214,60 +2149,80 @@ void Scene::clbkRenderMainScene() bool bVC = oapiCameraInternal() && (oapiCockpitMode() == COCKPIT_VIRTUAL); // ------------------------------------------------------------------------------------------------------- - // EnvMap Debugger TODO: Should be allowed to visualize other maps as well, not just index 0 + // EnvMap Debugger // ------------------------------------------------------------------------------------------------------- - if (DebugControls::IsActive()) { - - int sel = DebugControls::GetSelectedEnvMap(); + if (DebugControls::IsActive()) + { + auto sel = DebugControls::GetSelectedEnvMap(); + int probeid = DebugControls::GetProbeId(); + + EnvCamType tp = probeid < 0 ? EnvCamType::Exterior : EnvCamType::Interior; + if (probeid < 0) probeid = 0; switch (sel) { - case 1: case 2: case 3: case 4: - case 5: + case DbgDisplay::Mirror: + case DbgDisplay::Blur1: + case DbgDisplay::Blur2: + case DbgDisplay::Blur3: + case DbgDisplay::Blur4: { - if (bVC) { - auto pE = emVC.pEnv; - if (pE) if (pE->GetType() == D3DRTYPE_CUBETEXTURE) - VisualizeCubeMap((LPDIRECT3DCUBETEXTURE9)pE, sel - 1); - } - else { - auto pE = vFocus->GetEnvMap()->pEnv; - if (pE) if (pE->GetType() == D3DRTYPE_CUBETEXTURE) - VisualizeCubeMap((LPDIRECT3DCUBETEXTURE9)pE, sel - 1); - } + int idx = int(sel) - int(DbgDisplay::Mirror); + auto ec = vFocus->GetEnvCam(tp, probeid); + auto pData = ec ? ec->pCube : nullptr; + if (pData) VisualizeCubeMap((LPDIRECT3DCUBETEXTURE9)pData, idx); + + /*else { + auto ec = vFocus->GetExteriorEnvMap(); + auto pData = ec ? ec->pCube : nullptr; + if (pData) if (pData->GetType() == D3DRTYPE_CUBETEXTURE) + VisualizeCubeMap((LPDIRECT3DCUBETEXTURE9)pData, idx); + }*/ break; } - case 6: + + case DbgDisplay::smSS: + VisualizeShadowMap(smSS); break; - case 7: + + case DbgDisplay::smVC: + VisualizeShadowMap(smVC); break; - case 8: - VisualizeShadowMap(); + + case DbgDisplay::smEX: + VisualizeShadowMap(smEX); break; - case 9: - if (bVC) { - if (emVC.pIrrad) { - pSketch = GetPooledSketchpad(SKETCHPAD_2D_OVERLAY); - pSketch->CopyRectNative(emVC.pIrrad, NULL, 0, 0); - pSketch->EndDrawing(); - } + + case DbgDisplay::Irradiance: + { + auto ec = vFocus->GetEnvCam(tp, probeid); + auto pData = ec ? ec->pIrrad : nullptr; + if (pData) { + pSketch = GetPooledSketchpad(SKETCHPAD_2D_OVERLAY); + pSketch->CopyRectNative(pData, NULL, 0, 0); + pSketch->EndDrawing(); } - else { - if (vFocus->GetEnvMap()->pIrrad) { + /*else { + auto ec = vFocus->GetExteriorEnvMap(); + auto pData = ec ? ec->pIrrad : nullptr; + if (pData) { pSketch = GetPooledSketchpad(SKETCHPAD_2D_OVERLAY); - pSketch->CopyRectNative(vFocus->GetEnvMap()->pIrrad, NULL, 0, 0); + pSketch->CopyRectNative(pData, NULL, 0, 0); pSketch->EndDrawing(); } - } + }*/ break; - case 10: + } + + case DbgDisplay::GlowMask: if (ptgBuffer[GBUF_BLUR]) { pSketch = GetPooledSketchpad(SKETCHPAD_2D_OVERLAY); pSketch->CopyRectNative(ptgBuffer[GBUF_BLUR], NULL, 0, 0); pSketch->EndDrawing(); } break; - case 11: + + case DbgDisplay::ScreenDepth: if (ptgBuffer[GBUF_DEPTH]) { if (pVisDepth) { if (pVisDepth->IsOK()) { @@ -2279,7 +2234,8 @@ void Scene::clbkRenderMainScene() } } break; - case 12: + + case DbgDisplay::Normals: if (ptgBuffer[GBUF_DEPTH]) { if (pVisDepth) { if (pVisDepth->IsOK()) { @@ -2291,7 +2247,8 @@ void Scene::clbkRenderMainScene() } } break; - case 13: + + case DbgDisplay::LightVisbil: if (pLocalResults) { pSketch = GetPooledSketchpad(SKETCHPAD_2D_OVERLAY); pSketch->SetBlendState(Sketchpad::BlendState::FILTER_POINT); @@ -2300,7 +2257,8 @@ void Scene::clbkRenderMainScene() pSketch->EndDrawing(); } break; - case 14: + + case DbgDisplay::BakedLightMap: { LPDIRECT3DTEXTURE9 pTex = DebugControls::GetCombinedMap(); if (pTex) { @@ -2404,6 +2362,66 @@ void Scene::clbkRenderMainScene() } +// =========================================================================================== +// +float Scene::GetLODLevel(SMapInput* smi) +{ + float dist = length(smi->pos); + float tanap = float(GetTanAp()); + float viewh = float(ViewH()); + float rsmax = viewh * smi->rad / (tanap * dist); + return log2f(float(Config->ShadowMapSize) / (rsmax * 1.5f)); +} + + +// =========================================================================================== +// +void Scene::CombineSMaps(SMapInput* a, SMapInput* b, SMapInput* out) +{ + FVECTOR3 ab = b->pos - a->pos; + FVECTOR3 ap = a->pos; + FVECTOR3 bp = a->pos - b->ld * dot(ab, b->ld); // Project 'b' to a plane of 'a' + + ab = bp - ap; + float le = length(ab); // a-b distance + FVECTOR3 uab = ab / le; // Unit vector from a to b + float arad = a->rad; // Store 'a'-rad just in case if out == a + + out->rad = (le + a->rad + b->rad) * 0.5f; + out->pos = ap - uab * arad + uab * out->rad; + out->ld = a->ld; // ld should be identical in a,b +} + + +// =========================================================================================== +// +LPDIRECT3DTEXTURE9 Scene::RenderObjectsInShadow(SMapInput* smi, list& rList, D3D9Pad* pSkp) +{ + Casters.clear(); // Clear shadow casters to auto-generate the list + Shadowed.clear(); // Clear list of objects receiving shadow + + int shadow_lod = RenderShadowMap(smi, smEX, Casters); + + if (shadow_lod >= 0) { + + // Create a list of objects that can be shadowed in a defined shadow volume + for (auto x : rList) + if (x->Type() == OBJTP_VESSEL) + if (((vVessel*)x)->IsInsideShadows(smi)) Shadowed.push_back(x); + + // Render objects in shadow + for (auto it : Shadowed) { + it->Render(pDevice, false, smEX); + if (pSkp) RenderVesselMarker(it, pSkp); + rList.remove(it); // Remove from a list of "objects needing rendering" + } + + // Get the map for debugging + return smEX->ptShmRT[shadow_lod]; + } + return nullptr; +} + // =========================================================================================== // @@ -2560,85 +2578,87 @@ D3DXCOLOR Scene::GetSunDiffColor() // =========================================================================================== // -int Scene::RenderShadowMap(D3DXVECTOR3 &pos, D3DXVECTOR3 &ld, float rad, bool bInternal, bool bListExists) +int Scene::RenderShadowMap(SMapInput* smi, SHADOWMAP *sm, std::list& Casters, bool bInternal) { - - smap.pos = pos; - smap.ld = ld; - smap.rad = rad; - smap.cascades = 1; - smap.Center[0] = { 0, 0 }; - smap.Subrect[0] = { 0, 0, 1, 1 }; - smap.SubrectTF[0] = { 0, 0, 1, 1 }; + assert(sm->tp != SHADOWMAP::sMapType::Cascaded); + float rad = smi->rad * 1.1f; + + sm->pos = smi->pos; + sm->ld = smi->ld; + sm->rad = rad; + sm->cascades = 1; + sm->Center[0] = { 0, 0 }; + sm->Subrect[0] = { 0, 0, 1, 1 }; + sm->SubrectTF[0] = { 0, 0, 1, 1 }; + + float dst = length(smi->pos); float mnd = 1e16f; float mxd = -1e16f; float rsmax = 0.0f; float tanap = float(GetTanAp()); float viewh = float(ViewH()); + bool bExists = Casters.size() != 0; + D3DSURFACE_DESC desc; - if (!bListExists) { - - // If the list doesn't exists then create it... - SmapRenderList.clear(); - + if (!bExists) + { // browse through vessels to find shadowers -------------------------- // - for (VOBJREC *pv = vobjFirst; pv; pv = pv->next) { + for (auto pv : Visuals) { if (pv->type != OBJTP_VESSEL) continue; vVessel *vV = (vVessel *)pv->vobj; if (!vV->IsActive()) continue; - if (vV->IntersectShadowVolume()) { - SmapRenderList.push_back(vV); - vV->GetMinMaxLightDist(&mnd, &mxd); + if (vV->IntersectShadowVolume(smi)) { + Casters.push_back(vV); + vV->GetMinMaxLightDist(smi, &mnd, &mxd); } } - - // Compute shadow lod - rsmax = viewh * rad / (tanap * D3DXVec3Length(&pos)); } + else for (auto vV : Casters) vV->GetMinMaxLightDist(smi, &mnd, &mxd); - if (SmapRenderList.size() == 0) return -1; // The list is empty, Nothing to render + if (Casters.size() == 0) return -1; // The list is empty, Nothing to render + // Compute shadow lod + rsmax = viewh * rad / (tanap * dst); - if (bListExists) { - - for (auto vV : SmapRenderList) - { - // Get shadow min-max distances - vV->GetMinMaxLightDist(&mnd, &mxd); - - // Compute shadow lod - D3DXVECTOR3 bspos = vV->GetBoundingSpherePosDX(); - float rs = viewh * rad / (tanap * D3DXVec3Length(&bspos)); - if (rs > rsmax) rsmax = rs; - } - } - - smap.depth = (mxd + rad); + sm->depth = (mxd + rad); D3DXMATRIX mProj, mView; + D3DXMatrixOrthoOffCenterRH(&mProj, -rad, rad, rad, -rad, -rad, sm->depth); - D3DXMatrixOrthoOffCenterRH(&mProj, -rad, rad, rad, -rad, -rad, smap.depth); + sm->dist = mxd; - smap.dist = mxd; - - D3DXVECTOR3 lp = pos - ld * smap.dist; + D3DXVECTOR3 lp = smi->pos - smi->ld * sm->dist; + D3DXVECTOR3 pos = smi->pos; D3DXMatrixLookAtRH(&mView, &lp, &pos, ptr(D3DXVECTOR3(0, 1, 0))); - D3DXMatrixMultiply(smap.mLVP.toDX(), &mView, &mProj); - - smap.mVP[0] = smap.mLVP; + D3DXMatrixMultiply(sm->mLVP.toDX(), &mView, &mProj); - float lod = log2f(float(Config->ShadowMapSize) / (rsmax*1.5f)); + sm->mVP[0] = sm->mLVP; - smap.lod = min(int(round(lod)), SHM_LOD_COUNT - 1); - smap.lod = max(smap.lod, 0); - smap.size = Config->ShadowMapSize >> smap.lod; - - gc->PushRenderTarget(psShmRT[smap.lod], psShmDS[smap.lod], RENDERPASS_SHADOWMAP); + if (sm->tp == SHADOWMAP::sMapType::SingleLod) // Manual LOD selection + { + sm->psShmRT[0]->GetDesc(&desc); + sm->lod = 0; + sm->size = desc.Width; + auto psDS = GetDepthStencilMatch(sm->psShmRT[0]); + gc->PushRenderTarget(sm->psShmRT[0], psDS, RENDERPASS_SHADOWMAP); + } + else // Automatic LOD selection + { + int lod = round(log2f(float(Config->ShadowMapSize) / (rsmax * 1.5f))); + lod = min(lod, SHM_LOD_COUNT - 1); + lod = max(lod, 0); + sm->psShmRT[lod]->GetDesc(&desc); + sm->lod = lod; + sm->size = desc.Width; + gc->PushRenderTarget(sm->psShmRT[lod], psShmDS[lod], RENDERPASS_SHADOWMAP); + } + sm->bValid = true; + // Clear the viewport HR(pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 1.0f, 0L)); @@ -2647,33 +2667,33 @@ int Scene::RenderShadowMap(D3DXVECTOR3 &pos, D3DXVECTOR3 &ld, float rad, bool bI // BeginPass(RENDERPASS_SHADOWMAP); - while(SmapRenderList.size()>0) { - SmapRenderList.front()->Render(pDevice, bInternal); - SmapRenderList.pop_front(); + for (auto vV : Casters) { + if (vV == vFocus) { + if (bInternal) vV->Render(pDevice, true, sm); + vV->Render(pDevice, false, sm); + } + else vV->Render(pDevice, false, sm); } PopPass(); - gc->PopRenderTargets(); - - for (int i = 1; i < SHM_CASCADE_COUNT; i++) smap.pShadowMap[i] = NULL; - smap.pShadowMap[0] = ptShmRT[smap.lod]; - - return smap.lod; + + return sm->lod; } // =========================================================================================== // -int Scene::RenderVCShadowMap(D3DXVECTOR3& cdir, D3DXVECTOR3& ld, bool bListExists) +int Scene::RenderVCShadowMap(D3DXVECTOR3& cdir, D3DXVECTOR3& ld, std::list& Casters) { + SHADOWMAP* sm = smVC; D3DXVECTOR3 pos = cdir * cascfg[0].dist; float rad = cascfg[0].size; - smap.pos = pos; - smap.ld = ld; - smap.rad = rad; + sm->pos = pos; + sm->ld = ld; + sm->rad = rad; float mnd = 1e16f; float mxd = -1e16f; @@ -2681,55 +2701,50 @@ int Scene::RenderVCShadowMap(D3DXVECTOR3& cdir, D3DXVECTOR3& ld, bool bListExist float tanap = float(GetTanAp()); float viewh = float(ViewH()); + bool bExists = Casters.size() != 0; - if (!bListExists) { - - // If the list doesn't exists then create it... - SmapRenderList.clear(); + if (!bExists) { // browse through vessels to find shadowers -------------------------- // - for (VOBJREC* pv = vobjFirst; pv; pv = pv->next) { + for (auto pv : Visuals) { if (pv->type != OBJTP_VESSEL) continue; vVessel* vV = (vVessel*)pv->vobj; if (!vV->IsActive()) continue; - if (vV->IntersectShadowVolume()) { - SmapRenderList.push_back(vV); - vV->GetMinMaxLightDist(&mnd, &mxd); + if (vV->IntersectShadowVolume(sm)) { + Casters.push_back(vV); + vV->GetMinMaxLightDist(sm, &mnd, &mxd); } } - - // Compute shadow lod - rsmax = viewh * rad / (tanap * D3DXVec3Length(&pos)); } - - - if (SmapRenderList.size() == 0) return -1; // The list is empty, Nothing to render - - - if (bListExists) { - - for (auto vV : SmapRenderList) + else { + for (auto vV : Casters) { // Get shadow min-max distances - vV->GetMinMaxLightDist(&mnd, &mxd); + vV->GetMinMaxLightDist(sm, &mnd, &mxd); // Compute shadow lod - D3DXVECTOR3 bspos = vV->GetBoundingSpherePosDX(); - float rs = viewh * rad / (tanap * D3DXVec3Length(&bspos)); - if (rs > rsmax) rsmax = rs; + //D3DXVECTOR3 bspos = vV->GetBoundingSpherePosDX(); + //float rs = viewh * rad / (tanap * D3DXVec3Length(&bspos)); + //if (rs > rsmax) rsmax = rs; } } - smap.dist = mxd; - smap.lod = 0; - smap.size = Config->ShadowMapSize; - smap.cascades = Config->VCCascadeCount; - smap.depth = (mxd + vFocus->GetSize()); + if (Casters.size() == 0) return -1; // The list is empty, Nothing to render + + // Compute shadow lod + rsmax = viewh * rad / (tanap * D3DXVec3Length(&pos)); + + sm->dist = mxd; + sm->lod = 0; + sm->size = Config->ShadowMapSize; + sm->cascades = Config->VCCascadeCount; + sm->depth = (mxd + vFocus->GetSize()); + sm->bValid = true; D3DXMATRIX mProj, mView; - for (int i = 0; i < smap.cascades; i++) + for (int i = 0; i < sm->cascades; i++) { // Compute mLVP needed to render this cascade. @@ -2738,31 +2753,31 @@ int Scene::RenderVCShadowMap(D3DXVECTOR3& cdir, D3DXVECTOR3& ld, bool bListExist // Project pos to a shadow plane D3DXVECTOR3 sp = pos - ld * D3DXVec3Dot(&pos, &ld); - D3DXVECTOR3 ep = sp - ld * smap.dist; - D3DXMatrixOrthoOffCenterRH(&mProj, -rad, rad, rad, -rad, 0, smap.depth); + D3DXVECTOR3 ep = sp - ld * sm->dist; + D3DXMatrixOrthoOffCenterRH(&mProj, -rad, rad, rad, -rad, 0, sm->depth); D3DXMatrixLookAtRH(&mView, &ep, &sp, ptr(D3DXVECTOR3(0, 1, 0))); - D3DXMatrixMultiply(smap.mVP[i].toDX(), &mView, &mProj); + D3DXMatrixMultiply(sm->mVP[i].toDX(), &mView, &mProj); D3DXVECTOR3 xy; - D3DXVec3TransformCoord(&xy, &pos, smap.mVP[0].toDX()); - float s = 0.5f * rad / smap.rad; + D3DXVec3TransformCoord(&xy, &pos, sm->mVP[0].toDX()); + float s = 0.5f * rad / sm->rad; xy.y = -xy.y; xy = (xy + 1.0f) * 0.5f; // Cascade's center, subrect and subrect-transform within the main level (i.e '0') // All cascades share the same near and far plane and exists inside the previous cascade. - smap.Center[i] = { xy.x, xy.y }; + sm->Center[i] = { xy.x, xy.y }; float l = xy.x - s; float t = xy.y - s; float r = xy.x + s; float b = xy.y + s; - smap.Subrect[i] = FVECTOR4(l, t, r, b); - smap.SubrectTF[i] = FVECTOR4(-l, -t, 1.0f / (r - l), 1.0f / (b - t)); - smap.SubPx[i] = rad / float(smap.size); + sm->Subrect[i] = FVECTOR4(l, t, r, b); + sm->SubrectTF[i] = FVECTOR4(-l, -t, 1.0f / (r - l), 1.0f / (b - t)); + sm->SubPx[i] = rad / float(sm->size); #ifdef CASCADE_DEBUG D3D9DebugLog("Cascade %i pos=[%f, %f]", i, xy.x, xy.y); D3D9DebugLog("Cascade %i rect=[%f, %f, %f, %f]", i, xy.x-r, xy.y-r, xy.x+r, xy.y+r); #endif - gc->PushRenderTarget(psVCShmRT[i], psShmDS[0], RENDERPASS_SHADOWMAP); + gc->PushRenderTarget(sm->psShmRT[i], psShmDS[0], RENDERPASS_SHADOWMAP); // Clear the viewport HR(pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 1.0f, 0L)); @@ -2771,36 +2786,120 @@ int Scene::RenderVCShadowMap(D3DXVECTOR3& cdir, D3DXVECTOR3& ld, bool bListExist // BeginPass(RENDERPASS_VC_SHADOWMAP); - // NOTE: smap.mLVP must containg the projection needed for rendering of the map - smap.mLVP = smap.mVP[i]; + // NOTE: sm.mLVP must containg the projection needed for rendering of the map + sm->mLVP = sm->mVP[i]; - for (auto &a : SmapRenderList) + for (auto &a : Casters) { if (a == vFocus) { - a->Render(pDevice, true); + a->Render(pDevice, true, sm); } else { - a->Render(pDevice, false); + a->Render(pDevice, false, sm); } } PopPass(); gc->PopRenderTargets(); - - smap.pShadowMap[i] = ptVCShmRT[i]; } - // smap.mLVP must point to cascade '0' by default. That's where subrects lie - smap.mLVP = smap.mVP[0]; + // sm.mLVP must point to cascade '0' by default. That's where subrects lie + sm->mLVP = sm->mVP[0]; return 0; } // =========================================================================================== +// Return 'true' if rendering for the vessel is done // -void Scene::RenderSecondaryScene(std::set &RndList, std::set &LightsList, DWORD flags, const LPDIRECT3DCUBETEXTURE9 pCT) +bool Scene::RenderVCProbes(vVessel* vV) +{ + // Render only focus if in debug mode + if (DebugControls::IsActive() && vV != vFocus) return true; + + if (InteriorCams.empty()) // Get Interior cams and render shadow map + { + if (vV->GetInteriorCams(&InteriorCams)) + { + ResetOrigin(Camera.pos); + + SMapInput smi = vV->GetSMapRenderData(); + Casters.clear(); + + if (RenderShadowMap(&smi, smSS, Casters, true) < 0) { + LogErr("Failed to render shadow map for stage-set"); + } + else { + + /*if (DebugControls::IsActive() && psStageSetDbg && vV == vFocus) { + if (DebugControls::dbgdsp == DbgDisplay::smSS) { + HR(pDevice->StretchRect(smSS->psShmRT[0], nullptr, psStageSetDbg, nullptr, D3DTEXF_POINT)); + } + } + */ + + D3D9DebugLog("Rendered SS ShadowMap for %s", vV->GetName()); + D3D9DebugLogVec("Pos ", FVECTOR4(smi.pos)); + D3D9DebugLogVec("Ld ", FVECTOR4(smi.ld)); + D3D9DebugLog("Rad %f", smi.rad); + D3D9DebugLog("Pass %u", GetRenderPass()); + D3D9DebugLog("Cams %d", int(InteriorCams.size())); + } + } + else return true; // Nothing to do for this vessel, All done. + + itIC = InteriorCams.cbegin(); + } + + if (itIC != InteriorCams.cend()) + { + vV->RenderInteriorENVMap(pDevice, *itIC, smSS); + itIC++; + } + + if (itIC == InteriorCams.cend()) // All done for this vessel + { + InteriorCams.clear(); + return true; + } + + return false; // Not done yet, Continue this vessel next frame +} + + +// =========================================================================================== +// +LPDIRECT3DSURFACE9 Scene::GetDepthStencilMatch(LPDIRECT3DSURFACE9 pRef) +{ + D3DSURFACE_DESC desc; + pRef->GetDesc(&desc); + for (int i = 0; i < (SHM_LOD_COUNT - 1); i++) { + D3DSURFACE_DESC d; psShmDS[i]->GetDesc(&d); + if ((d.Width == desc.Width) && (d.Height == desc.Height)) return psShmDS[i]; + } + return nullptr; +} + + +// =========================================================================================== +// +LPDIRECT3DSURFACE9 Scene::GetDepthStencil(DWORD size) +{ + for (int i = 0; i < (SHM_LOD_COUNT - 1); i++) { + D3DSURFACE_DESC d; psShmDS[i]->GetDesc(&d); + if (d.Width == size) return psShmDS[i]; + } + return nullptr; +} + + +// =========================================================================================== +// +void Scene::RenderSecondaryScene(std::set &RndList, + std::set &LightsList, DWORD flags, + const LPDIRECT3DCUBETEXTURE9 pCT, SHADOWMAP *sm) { _TRACE; RenderFlags = flags; @@ -2818,7 +2917,10 @@ void Scene::RenderSecondaryScene(std::set &RndList, std::set DWORD nemitter = vessel->LightEmitterCount(); for (DWORD j = 0; j < nemitter; j++) { const LightEmitter *em = vessel->GetLightEmitter(j); - if ((em->GetVisibility() == LightEmitter::VIS_EXTERNAL) || (em->GetVisibility() == LightEmitter::VIS_ALWAYS)) AddLocalLight(em, vVes); + if (flags & SCN_VC) + if ((em->GetVisibility() == LightEmitter::VIS_COCKPIT) || (em->GetVisibility() == LightEmitter::VIS_ALWAYS)) AddLocalLight(em, vVes); + else + if ((em->GetVisibility() == LightEmitter::VIS_EXTERNAL) || (em->GetVisibility() == LightEmitter::VIS_ALWAYS)) AddLocalLight(em, vVes); } } @@ -2829,7 +2931,11 @@ void Scene::RenderSecondaryScene(std::set &RndList, std::set DWORD nemitter = vessel->LightEmitterCount(); for (DWORD j = 0; j < nemitter; j++) { const LightEmitter *em = vessel->GetLightEmitter(j); - if ((em->GetVisibility() == LightEmitter::VIS_EXTERNAL) || (em->GetVisibility() == LightEmitter::VIS_ALWAYS)) AddLocalLight(em, vVes); + if (flags & SCN_VC) + if ((em->GetVisibility() == LightEmitter::VIS_COCKPIT) || (em->GetVisibility() == LightEmitter::VIS_ALWAYS)) AddLocalLight(em, vVes); + else + if ((em->GetVisibility() == LightEmitter::VIS_EXTERNAL) || (em->GetVisibility() == LightEmitter::VIS_ALWAYS)) AddLocalLight(em, vVes); + } } } @@ -2837,21 +2943,25 @@ void Scene::RenderSecondaryScene(std::set &RndList, std::set D3D9Effect::UpdateEffectCamera(GetCameraProxyBody()); // Clear the viewport - HR(pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, 0xFF000000, 1.0f, 0L)); - + if ((flags & SCN_NOCLEAR) == 0) { + HR(pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xFF000000, 1.0f, 0L)); + } // render stage around the scene ---------------------------- // if ((flags & SCN_STAGE) && pCT) RenderStage(pCT); - + // Don't combine these + if ((flags & SCN_STAGE) && (flags & SCN_PLANETS)) assert(false); + if ((flags & SCN_VC) && (flags & SCN_ALLEXT)) assert(false); + // render planets ------------------------------------------- // if (flags & SCN_PLANETS) { - for (DWORD i = 0; iIsActive(); - if (isActive) plist[i].vo->Render(pDevice); - else plist[i].vo->RenderDot(pDevice); + for (auto pl : Planets) { + bool isActive = pl->IsActive(); + if (isActive) pl->Render(pDevice); + else pl->RenderDot(pDevice); } } @@ -2889,6 +2999,10 @@ void Scene::RenderSecondaryScene(std::set &RndList, std::set for (DWORD n = 0; n < nstream; n++) pstream[n]->Render(pDevice); } + if (flags & SCN_VC) { + + } + // Flags 0x20 = BaseStructures } @@ -2907,15 +3021,15 @@ void Scene::RenderStage(LPDIRECT3DCUBETEXTURE9 pCT) ShaderData.mVP = Camera.mProjView; D3DXMatrixIdentity(&ShaderData.mW); - ShaderData.mW._11 = 10e3f; - ShaderData.mW._22 = 10e3f; - ShaderData.mW._33 = 10e3f; + ShaderData.mW._11 = 1e5f; + ShaderData.mW._22 = 1e5f; + ShaderData.mW._33 = 1e5f; pRenderStage->ClearTextures(); pRenderStage->SetPSConstants("cbPS", &ShaderData, sizeof(ShaderData)); pRenderStage->SetVSConstants("cbPS", &ShaderData, sizeof(ShaderData)); pRenderStage->SetTexture("tTex", pCT, IPF_CLAMP | IPF_LINEAR); - pRenderStage->Setup(pMeshVertexDecl, false, 0); + pRenderStage->Setup(nullptr, false, 0); pRenderStage->UpdateTextures(); ((D3D9Mesh*)dmCubeMesh)->RenderGroup(0); @@ -3216,8 +3330,7 @@ bool Scene::IntegrateIrradiance(vVessel *vV, LPDIRECT3DBASETEXTURE9 pIn, LPDIREC // void Scene::ClearOmitFlags() { - VOBJREC *pv = NULL; - for (pv=vobjFirst; pv; pv=pv->next) pv->vobj->bOmit = false; + for (auto pv : Visuals) pv->vobj->bOmit = false; } @@ -3263,37 +3376,60 @@ void Scene::VisualizeCubeMap(LPDIRECT3DCUBETEXTURE9 pCube, int mip) } } +// =========================================================================================== +// +const SHADOWMAP* Scene::GetSMapData(ShdPackage tp) const +{ + if (tp == ShdPackage::Main) return smEX; + if (tp == ShdPackage::VC) return smVC; + if (tp == ShdPackage::Stage) return smSS; + return nullptr; +} + // =========================================================================================== +// Optional parameters 'sm' or 'pTex' not both // -void Scene::VisualizeShadowMap() +void Scene::VisualizeShadowMap(SHADOWMAP *sm) { - if (smap.pShadowMap[0] == NULL) return; + LPDIRECT3DTEXTURE9 pTex = sm ? sm->Map(0) : nullptr; + if (!pTex) return; D3DSURFACE_DESC desc; - smap.pShadowMap[0]->GetLevelDesc(0, &desc); - + pTex->GetLevelDesc(0, &desc); + + DWORD s = 0; float w, h; - if (desc.Height > viewH) w = h = float(viewH); - else w = h = float(desc.Height); + if (desc.Height > viewH) w = h = float(s = viewH); + else w = h = float(s = desc.Height); D3D9Pad *pSketch = GetPooledSketchpad(SKETCHPAD_2D_OVERLAY); - for (int i=0;icascades; i++) + { + int l = int(w * sm->Subrect[i].x); + int t = int(h * sm->Subrect[i].y); + int r = int(w * sm->Subrect[i].z); + int b = int(h * sm->Subrect[i].w); + + RECT tgt = { l, t, r, b }; + auto map = sm->Map(i); + if (map) { + pSketch->SetRenderParam(Sketchpad::RenderParam::PRM_GAMMA, ptr(FVECTOR4(0.25f, 0.25f, 0.25f, 1.0f))); + pSketch->StretchRectNative(map, nullptr, &tgt); + pSketch->SetRenderParam(Sketchpad::RenderParam::PRM_GAMMA, nullptr); + } + pSketch->QuickBrush(0); + pSketch->QuickPen(0xFFFF00FF); + pSketch->Rectangle(l, t, r, b); + } + } + else if (pTex) { + RECT tgt = { 0, 0, long(s), long(s) }; pSketch->SetRenderParam(Sketchpad::RenderParam::PRM_GAMMA, ptr(FVECTOR4(0.25f, 0.25f, 0.25f, 1.0f))); - pSketch->StretchRectNative(smap.pShadowMap[i], NULL, &tgt); - pSketch->SetRenderParam(Sketchpad::RenderParam::PRM_GAMMA, NULL); - pSketch->QuickBrush(0); - pSketch->QuickPen(0xFFFF00FF); - pSketch->Rectangle(l, t, r, b); + pSketch->StretchRectNative(pTex, nullptr, &tgt); + pSketch->SetRenderParam(Sketchpad::RenderParam::PRM_GAMMA, nullptr); } pSketch->EndDrawing(); } @@ -3308,8 +3444,7 @@ void Scene::RenderVesselShadows (OBJHANDLE hPlanet, float depth) const if (hPlanet != oapiCameraProxyGbody()) return; // render vessel shadows - VOBJREC *pv; - for (pv = vobjFirst; pv; pv = pv->next) { + for (auto pv : Visuals) { if (!pv->vobj->IsActive()) continue; if (oapiGetObjectType(pv->vobj->Object()) == OBJTP_VESSEL) ((vVessel*)(pv->vobj))->RenderGroundShadow(pDevice, hPlanet, depth); @@ -3330,16 +3465,14 @@ void Scene::RenderMesh(DEVMESHHANDLE hMesh, const oapi::FMATRIX4 *pWorld) { D3D9Mesh *pMesh = (D3D9Mesh *)hMesh; - const SHADOWMAPPARAM *shd = GetSMapData(); - - float s = float(shd->size); - float sr = 2.0f * shd->rad / s; + float s = float(smEX->size); + float sr = 2.0f * smEX->rad / s; - HR(D3D9Effect::FX->SetMatrix(D3D9Effect::eLVP, shd->mLVP.toCDX())); + HR(D3D9Effect::FX->SetMatrix(D3D9Effect::eLVP, smEX->mLVP.toCDX())); - if (shd->pShadowMap) { - pMesh->SetShadows(shd); - HR(D3D9Effect::FX->SetVector(D3D9Effect::eSHD, ptr(D3DXVECTOR4(sr, 1.0f / s, float(oapiRand()), 1.0f / shd->depth)))); + if (smEX->IsValid()) { + pMesh->SetShadows(smEX); + HR(D3D9Effect::FX->SetVector(D3D9Effect::eSHD, ptr(D3DXVECTOR4(sr, 1.0f / s, float(oapiRand()), 1.0f / smEX->depth)))); HR(D3D9Effect::FX->SetBool(D3D9Effect::eShadowToggle, true)); } else { @@ -3604,7 +3737,7 @@ D3D9Pick Scene::PickScene(short xpos, short ypos, const PickProp *p) result.group = -1; result.idx = -1; - for (VOBJREC *pv=vobjFirst; pv; pv=pv->next) { + for (auto pv : Visuals) { if (pv->type!=OBJTP_VESSEL) continue; if (!pv->vobj->IsActive()) continue; @@ -3756,7 +3889,7 @@ void Scene::UpdateCameraFromOrbiter(DWORD dwPass) // translational transformation between orbiter global coordinates // and render coordinates. - for (VOBJREC *pv = vobjFirst; pv; pv = pv->next) pv->vobj->Update(true); + for (auto pv : Visuals) pv->vobj->Update(true); SetupInternalCamera(&Camera.mView, NULL, oapiCameraAperture(), double(viewH)/double(viewW)); } @@ -3830,11 +3963,19 @@ void Scene::SetupInternalCamera(D3DXMATRIX *mNew, VECTOR3 *gpos, double apr, dou SetCameraAperture(float(apr), float(asp)); // Finally update world matrices from all visuals - // - if (gpos) for (VOBJREC *pv = vobjFirst; pv; pv = pv->next) pv->vobj->ReOrigin(Camera.pos); + ResetOrigin(Camera.pos); } +// =========================================================================================== +// +void Scene::ResetOrigin(VECTOR3 pos) +{ + // Update world matrices from all visuals + if (origin.x != pos.x || origin.y != pos.y || origin.z != pos.z) + for (auto pv : Visuals) pv->vobj->ReOrigin(pos); + origin = pos; +} // =========================================================================================== @@ -3936,18 +4077,16 @@ void Scene::RenderCustomCameraView(CAMREC *cCur) SetCameraFrustumLimits(0.1, 2e7); SetupInternalCamera(&mEnv, &gpos, cCur->dAperture, double(h)/double(w)); - - VOBJREC *pv = NULL; std::set List; std::set Lights; - for (pv = vobjFirst; pv; pv = pv->next) if (pv->type == OBJTP_VESSEL) List.insert((vVessel *)pv->vobj); + for (auto pv : Visuals) if (pv->type == OBJTP_VESSEL) List.insert((vVessel *)pv->vobj); BeginPass(RENDERPASS_CUSTOMCAM); gc->PushRenderTarget(pSrf, pDSs, RENDERPASS_CUSTOMCAM); - RenderSecondaryScene(List, Lights, 0xFF); + RenderSecondaryScene(List, Lights, SCN_ALLEXT); gc->PopRenderTargets(); @@ -4133,12 +4272,3 @@ void Scene::D3D9TechInit(LPDIRECT3DDEVICE9 pDev, const char *folder) D3D9CelestialSphere::D3D9TechInit(FX); } - -// =========================================================================================== -// -int distcomp (const void *arg1, const void *arg2) -{ - double d1 = ((PList*)arg1)->dist; - double d2 = ((PList*)arg2)->dist; - return (d1 > d2 ? -1 : d1 < d2 ? 1 : 0); -} diff --git a/OVP/D3D9Client/Scene.h b/OVP/D3D9Client/Scene.h index 72d74cd9a..ad94ac06c 100644 --- a/OVP/D3D9Client/Scene.h +++ b/OVP/D3D9Client/Scene.h @@ -54,6 +54,7 @@ class D3D9Pad; #define RENDERPASS_MAINOVERLAY 0x0007 #define RENDERPASS_NORMAL_DEPTH 0x0008 #define RENDERPASS_VC_SHADOWMAP 0x0009 +#define RENDERPASS_STAGESET 0x000A #define RESTORE ((LPDIRECT3DSURFACE9)(-1)) #define CURRENT ((LPDIRECT3DSURFACE9)(-2)) @@ -76,11 +77,13 @@ class D3D9Pad; #define SCN_BASESTRUCT 0x20 #define SCN_ALLEXT 0x3F ///< All exterior features #define SCN_VC 0x40 ///< Virtual cockpit -#define SCN_STAGE 0x100 ///< Render a stage around the world. Cude texture needed. +#define SCN_STAGE 0x1000 ///< Render a stage around the world. Cude texture needed. +#define SCN_NOCLEAR 0x2000 ///< Do not clear render target + +#define CAMERA(x) ((Scene::CAMREC*)x) -#define CAMERA(x) ((Scene::CAMREC*)x) class Scene { @@ -92,8 +95,7 @@ class Scene { vObject *vobj; // visual instance int type; float apprad; - VOBJREC *prev, *next; // previous and next list entry - } *vobjFirst, *vobjLast; // first and last list entry + }; public: @@ -121,14 +123,19 @@ class Scene { void* pUser; }; - ENVMAPS emVC; + //ENVCAMREC ecVC; + std::list InteriorCams; + std::list Planets; + std::list Visuals; std::set RootList; std::set Vessels; std::set eCamRenderList; std::set CustomCams; std::set::const_iterator camCurrent = {}; - std::set::const_iterator vobjEnv = {}; + std::set::const_iterator vobjEnv = {}, vobjIP = {}; + std::list::const_iterator itIC; + // Camera frustum parameters ======================================================== // @@ -175,7 +182,9 @@ class Scene { D3DXCOLOR color; }; - struct SHADOWMAPPARAM smap; + SHADOWMAP* smEX = nullptr; // Exterior shadow map + SHADOWMAP* smVC = nullptr; // Virtual Cockpit shadow map + SHADOWMAP* smSS = nullptr; // Shadow map for rendering in a stage-set static void D3D9TechInit(LPDIRECT3DDEVICE9 pDev, const char *folder); @@ -237,8 +246,10 @@ class Scene { void BeginPass(DWORD dwPass); void PopPass(); + const SHADOWMAP* GetSMapData(ShdPackage tp) const; + inline DWORD GetStencilDepth() const { return stencilDepth; } - inline const SHADOWMAPPARAM * GetSMapData() const { return &smap; } + /** * \brief Get the ambient background colour */ @@ -271,9 +282,13 @@ class Scene { /** * \brief Render a secondary scene. (Env Maps, Shadow Maps, MFD Camera Views) */ - void RenderSecondaryScene(std::set &RndList, std::set &AdditionalLightsList, DWORD flags = SCN_ALLEXT, const LPDIRECT3DCUBETEXTURE9 pCT = nullptr); - int RenderShadowMap(D3DXVECTOR3& pos, D3DXVECTOR3& ld, float rad, bool bInternal = false, bool bListExists = false); - int RenderVCShadowMap(D3DXVECTOR3& cdir, D3DXVECTOR3& ld, bool bListExists = false); + void RenderSecondaryScene(std::set &RndList, + std::set &AdditionalLightsList, DWORD flags = SCN_ALLEXT, + const LPDIRECT3DCUBETEXTURE9 pCT = nullptr, SHADOWMAP* sm = nullptr); + + int RenderShadowMap(SMapInput* smp, SHADOWMAP* out, std::list& Casters, bool bInternal = false); + int RenderVCShadowMap(D3DXVECTOR3& cdir, D3DXVECTOR3& ld, std::list& Casters); + bool RenderVCProbes(vVessel *vFocus); bool IntegrateIrradiance(vVessel *vV, LPDIRECT3DBASETEXTURE9 pSrc, LPDIRECT3DTEXTURE9 pOut); bool RenderBlurredMap(LPDIRECT3DDEVICE9 pDev, LPDIRECT3DCUBETEXTURE9 pSrc); @@ -286,6 +301,9 @@ class Scene { LPDIRECT3DTEXTURE9 GetSunTexture() const { return pSunTex; } LPDIRECT3DTEXTURE9 GetSunGlareAtm() const { return pSunGlareAtm; } + LPDIRECT3DSURFACE9 GetDepthStencilMatch(LPDIRECT3DSURFACE9 pRef); + LPDIRECT3DSURFACE9 GetDepthStencil(DWORD size); + /** * \brief Render any shadows cast by vessels on planet surfaces * \param hPlanet handle of planet to cast shadows on @@ -351,6 +369,7 @@ class Scene { void SetCameraFrustumLimits(double nearlimit, double farlimit); float GetDepthResolution(float dist) const; float CameraInSpace() const; + void ResetOrigin(VECTOR3 pos); // Acquire camera information from the Orbiter and initialize internal camera setup void UpdateCameraFromOrbiter(DWORD dwPass); @@ -433,9 +452,13 @@ class Scene { DWORD GetActiveParticleEffectCount(); float ComputeNearClipPlane(); void VisualizeCubeMap(LPDIRECT3DCUBETEXTURE9 pCube, int mip); - void VisualizeShadowMap(); + void VisualizeShadowMap(SHADOWMAP *sm); VOBJREC * FindVisual (OBJHANDLE hObj) const; void RenderVesselMarker(vVessel *vV, D3D9Pad *pSketch); + float GetLODLevel(SMapInput* smi); + void CombineSMaps(SMapInput* a, SMapInput* b, SMapInput* out); + + LPDIRECT3DTEXTURE9 RenderObjectsInShadow(SMapInput* smi, list& rList, D3D9Pad *pSkp = nullptr); // Locate the visual for hObj in the list if present, or return // NULL if not found @@ -463,94 +486,105 @@ class Scene { struct _cascfg { float size; float dist; - } cascfg[SHM_CASCADE_COUNT]; + } cascfg[SHM_CASCADE_COUNT] = {}; - oapi::D3D9Client* gc; - LPDIRECT3DDEVICE9 pDevice; // render device - DWORD viewW, viewH; // render viewport size - DWORD stencilDepth; // stencil buffer bit depth - D3D9CelestialSphere* m_celSphere; // celestial sphere background - DWORD iVCheck; // index of last object checked for visibility - bool bLocalLight; // enable local light sources - bool surfLabelsActive; // v.2 surface labels activated? + oapi::D3D9Client* gc = {}; + LPDIRECT3DDEVICE9 pDevice = {}; // render device + DWORD viewW = {}; + DWORD viewH = {}; // render viewport size + DWORD stencilDepth = {}; // stencil buffer bit depth + D3D9CelestialSphere* m_celSphere = {}; // celestial sphere background + DWORD iVCheck = {}; // index of last object checked for visibility + bool bLocalLight = {}; // enable local light sources + bool surfLabelsActive = {}; // v.2 surface labels activated? - OBJHANDLE hSun; + OBJHANDLE hSun = {}; - D3D9ParticleStream **pstream; // list of particle streams - DWORD nstream; // number of streams + D3D9ParticleStream **pstream = {}; // list of particle streams + DWORD nstream = {}; // number of streams - DEVMESHHANDLE dmCubeMesh; - D3DCOLOR bg_rgba; // ambient background colour + DEVMESHHANDLE dmCubeMesh = {}; + D3DCOLOR bg_rgba = {}; // ambient background colour // GDI resources ==================================================================== // - oapi::Font *label_font[4]; + oapi::Font *label_font[4] = {}; - std::list RenderList; - std::list SmapRenderList; - std::list Casters; + std::list Shadowed; + std::list RenderList; + std::list ObjectsToShadowMap; + std::list Casters; std::stack CameraStack; std::stack PassStack; std::stack FrustumStack; - CAMERA Camera; - D3D9Light* Lights; - D3D9Sun sunLight; - - VECTOR3 sky_color; - double bglvl; - - float fCascadeRatio; - float fDisplayScale; - float lmaxdst2; - DWORD nLights; - DWORD nplanets; // Number of distance sorted planets to render - DWORD dwTurn; - DWORD dwFrameId; - DWORD camIndex; - DWORD RenderFlags; - bool bRendering; - - oapi::Font *pAxisFont; - oapi::Font *pLabelFont; - oapi::Font *pDebugFont; - - SurfNative *pLblSrf; - - class ImageProcessing *pLightBlur, *pBlur, *pBlur2D, *pGDIOverlay, *pIrradiance, *pVisDepth, *pCreateGlare, *pBakeLights; - class ShaderClass *pLocalCompute, *pRenderGlares, *pRenderStage; - - class vVessel *vFocus; - double dVisualAppRad; - - FVECTOR2 DepthSampleKernel[57]; - - LPDIRECT3DTEXTURE9 pSunTex, pLightGlare, pSunGlare, pSunGlareAtm; - LPDIRECT3DTEXTURE9 pLocalResults; - LPDIRECT3DSURFACE9 pLocalResultsSL; + CAMERA Camera = {}; + D3D9Light* Lights = {}; + D3D9Sun sunLight = {}; + + VECTOR3 origin = {}; + VECTOR3 sky_color = {}; + double bglvl = {}; + + float fCascadeRatio = {}; + float fDisplayScale = {}; + float lmaxdst2 = {}; + DWORD nLights = {}; + DWORD dwTurn = {}; + DWORD dwFrameId = {}; + DWORD camIndex = {}; + DWORD RenderFlags = {}; + bool bRendering = {}; + + oapi::Font *pAxisFont = {}; + oapi::Font *pLabelFont = {}; + oapi::Font *pDebugFont = {}; + + SurfNative *pLblSrf = {}; + + class ImageProcessing* pLightBlur = {}; + class ImageProcessing* pBlur = {}; + class ImageProcessing* pBlur2D = {}; + class ImageProcessing* pGDIOverlay = {}; + class ImageProcessing* pIrradiance = {}; + class ImageProcessing* pVisDepth = {}; + class ImageProcessing* pCreateGlare = {}; + class ImageProcessing* pBakeLights = {}; + class ShaderClass* pLocalCompute = {}; + class ShaderClass* pRenderGlares = {}; + class ShaderClass* pRenderStage = {}; + + class vVessel *vFocus = {}; + double dVisualAppRad = {}; + + FVECTOR2 DepthSampleKernel[57] = {}; + + LPDIRECT3DTEXTURE9 pSunTex = {}; + LPDIRECT3DTEXTURE9 pLightGlare = {}; + LPDIRECT3DTEXTURE9 pSunGlare = {}; + LPDIRECT3DTEXTURE9 pSunGlareAtm = {}; + LPDIRECT3DTEXTURE9 pLocalResults = {}; + LPDIRECT3DSURFACE9 pLocalResultsSL = {}; // Blur Sampling Kernel ============================================================== - LPDIRECT3DCUBETEXTURE9 pBlrTemp[5]; - LPDIRECT3DTEXTURE9 pBlrTemp2D[5]; - LPDIRECT3DTEXTURE9 pIrradTemp, ptRandom; + LPDIRECT3DCUBETEXTURE9 pBlrTemp[5] = {}; + LPDIRECT3DTEXTURE9 pBlrTemp2D[5] = {}; + LPDIRECT3DTEXTURE9 pIrradTemp = {}; + LPDIRECT3DTEXTURE9 ptRandom = {}; // Deferred Experiment =============================================================== // - LPDIRECT3DSURFACE9 psgBuffer[GBUF_COUNT]; - LPDIRECT3DTEXTURE9 ptgBuffer[GBUF_COUNT]; - LPDIRECT3DSURFACE9 pOffscreenTarget; - LPDIRECT3DTEXTURE9 pTextures[TEX_COUNT]; - - LPDIRECT3DSURFACE9 pEnvDS, pDepthNormalDS; - LPDIRECT3DSURFACE9 psShmDS[SHM_LOD_COUNT]; - LPDIRECT3DSURFACE9 psShmRT[SHM_LOD_COUNT]; - LPDIRECT3DTEXTURE9 ptShmRT[SHM_LOD_COUNT]; + LPDIRECT3DSURFACE9 psgBuffer[GBUF_COUNT] = {}; + LPDIRECT3DTEXTURE9 ptgBuffer[GBUF_COUNT] = {}; + LPDIRECT3DSURFACE9 pOffscreenTarget = {}; + LPDIRECT3DTEXTURE9 pTextures[TEX_COUNT] = {}; - LPDIRECT3DSURFACE9 psVCShmRT[SHM_CASCADE_COUNT]; - LPDIRECT3DTEXTURE9 ptVCShmRT[SHM_CASCADE_COUNT]; + LPDIRECT3DSURFACE9 pEnvDS = {}; + LPDIRECT3DSURFACE9 pDepthNormalDS = {}; + LPDIRECT3DSURFACE9 psShmDS[SHM_LOD_COUNT] = {}; - LocalLightsCompute LLCBuf[MAX_SCENE_LIGHTS + 1]; + LocalLightsCompute LLCBuf[MAX_SCENE_LIGHTS + 1] = {}; // Rendering Technique related parameters ============================================ // diff --git a/OVP/D3D9Client/Surfmgr2.cpp b/OVP/D3D9Client/Surfmgr2.cpp index a96f8fb72..1156d760a 100644 --- a/OVP/D3D9Client/Surfmgr2.cpp +++ b/OVP/D3D9Client/Surfmgr2.cpp @@ -985,19 +985,19 @@ void SurfTile::Render () if (pShader->bShdMap) { - const SHADOWMAPPARAM* shd = scene->GetSMapData(); + const SHADOWMAP* shd = scene->GetSMapData(ShdPackage::Main); - D3DXVECTOR3 bc = bs_pos - shd->pos; + FVECTOR3 bc = FVECTOR3(bs_pos) - shd->pos; double alt = scene->GetCameraAltitude() - scene->GetTargetElevation(); if ((alt < 10e3) && (scene->GetCameraProxyVisual() == mgr->GetPlanet())) { - if (shd->pShadowMap && (Config->ShadowMapMode != 0) && (Config->TerrainShadowing == 2)) { + if (shd->IsValid() && (Config->ShadowMapMode != 0) && (Config->TerrainShadowing == 2)) { - float x = D3DXVec3Dot(&bc, &(shd->ld)); + float x = dot(bc, shd->ld); - if (sqrt(D3DXVec3Dot(&bc, &bc) - x * x) < (shd->rad + mesh->bsRad)) { + if (sqrt(dot(bc, bc) - x * x) < (shd->rad + mesh->bsRad)) { float s = float(shd->size); float sr = 2.0f * shd->rad / s; sp->mLVP = shd->mLVP; @@ -1007,7 +1007,7 @@ void SurfTile::Render () } } - pShader->SetTexture(pShader->tShadowMap, shd->pShadowMap[0]); + pShader->SetTexture(pShader->tShadowMap, shd->ptShmRT[0]); } // --------------------------------------------------------------------- diff --git a/OVP/D3D9Client/VPlanet.cpp b/OVP/D3D9Client/VPlanet.cpp index 037a2b122..052470ca9 100644 --- a/OVP/D3D9Client/VPlanet.cpp +++ b/OVP/D3D9Client/VPlanet.cpp @@ -888,7 +888,7 @@ bool vPlanet::Render(LPDIRECT3DDEVICE9 dev) _TRACE; if (!active) return false; - const SHADOWMAPPARAM *shd = scn->GetSMapData(); + const SHADOWMAP *shd = scn->GetSMapData(ShdPackage::Main); if (DebugControls::IsActive()) { // DWORD flags = *(DWORD*)gc->GetConfigParam(CFGPRM_GETDEBUGFLAGS); @@ -920,7 +920,7 @@ bool vPlanet::Render(LPDIRECT3DDEVICE9 dev) HR(D3D9Effect::FX->SetBool(D3D9Effect::eEnvMapEnable, false)); HR(D3D9Effect::FX->SetBool(D3D9Effect::eShadowToggle, false)); - if (shd->pShadowMap && (scn->GetRenderPass() == RENDERPASS_MAINSCENE) && (Config->TerrainShadowing == 2)) { + if (shd->IsValid() && (scn->GetRenderPass() == RENDERPASS_MAINSCENE) && (Config->TerrainShadowing == 2)) { if (scn->GetCameraAltitude() < 10e3 || IsMesh()) { float s = float(shd->size); float is = 1.0f / s; diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index 17d1616ad..ee206dbbc 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -81,14 +81,6 @@ vVessel::vVessel(OBJHANDLE _hObj, const Scene *scene): vObject (_hObj, scene) ecDefExt.flags = ENVCAM_OMIT_ATTC; ecDefExt.type = EnvCamType::Exterior; - ecDefVC.flags = 0; - ecDefVC.type = EnvCamType::VC; - - D3DXVECTOR3 pos; - if (GetVCPos(nullptr, &pos, nullptr)) { - ecDefVC.lPos = pos; - } - /* oapiWriteLogV("%s", vessel->GetClassNameA()); oapiWriteLogV("nanim = %u", na); @@ -114,10 +106,7 @@ vVessel::~vVessel () DisposeAnimations(); DisposeMeshes(); - SAFE_RELEASE(ecDefVC.tex.pEnv); - SAFE_RELEASE(ecDefVC.tex.pIrrad); - SAFE_RELEASE(ecDefExt.tex.pEnv); - SAFE_RELEASE(ecDefExt.tex.pIrrad); + for (auto& x: InteriorCams) SAFE_DELETE(x); LogAlw("Vessel visual deleted succesfully"); } @@ -602,59 +591,64 @@ void vVessel::UpdateAnimations (int mshidx) } } +// ============================================================================================ +// +SMapInput vVessel::GetSMapRenderData() +{ + SMapInput sm = { + GetBoundingSpherePosDX(), + FVECTOR3(-sundir), + GetBoundingSphereRadius() + }; + return sm; +} // ============================================================================================ // -bool vVessel::IsInsideShadows() +bool vVessel::IsInsideShadows(const SMapInput* shd) { D3DXVECTOR3 bc; - const SHADOWMAPPARAM *shd = scn->GetSMapData(); D3DXVec3TransformCoord(&bc, ptr(D3DXVECTOR3f4(BBox.bs)), &mWorld); - bc = bc - shd->pos; - float x = D3DXVec3Dot(&bc, &(shd->ld)); - - if (sqrt(D3DXVec3Dot(&bc, &bc) - x*x) < (shd->rad - BBox.bs.w)) return true; - + FVECTOR3 fbc = FVECTOR3(bc) - shd->pos; + float x = dot(fbc, shd->ld); + if (sqrt(dot(fbc, fbc) - x*x) < ((shd->rad * 1.01f) - BBox.bs.w)) return true; return false; } // ============================================================================================ // -bool vVessel::IntersectShadowVolume() +bool vVessel::IntersectShadowVolume(const SMapInput* shd) { D3DXVECTOR3 bc; - const SHADOWMAPPARAM *shd = scn->GetSMapData(); D3DXVec3TransformCoord(&bc, ptr(D3DXVECTOR3f4(BBox.bs)), &mWorld); - bc = bc - shd->pos; - float x = D3DXVec3Dot(&bc, &(shd->ld)); - if (sqrt(D3DXVec3Dot(&bc, &bc) - x*x) > (shd->rad + BBox.bs.w)) return false; + FVECTOR3 fbc = FVECTOR3(bc) - shd->pos; + float x = dot(fbc, shd->ld); + if (sqrt(dot(fbc, fbc) - x*x) > (shd->rad + BBox.bs.w)) return false; return true; } // ============================================================================================ // -bool vVessel::IntersectShadowTarget() +bool vVessel::IntersectShadowTarget(const SMapInput* shd) { D3DXVECTOR3 bc; - const SHADOWMAPPARAM *shd = scn->GetSMapData(); D3DXVec3TransformCoord(&bc, ptr(D3DXVECTOR3f4(BBox.bs)), &mWorld); - bc = bc - shd->pos; - if (D3DXVec3Length(&bc) < (shd->rad + BBox.bs.w)) return true; + FVECTOR3 fbc = FVECTOR3(bc) - shd->pos; + if (length(fbc) < (shd->rad + BBox.bs.w)) return true; return false; } // ============================================================================================ // -void vVessel::GetMinMaxLightDist(float *mind, float *maxd) +void vVessel::GetMinMaxLightDist(const SMapInput* shd, float *mind, float *maxd) { D3DXVECTOR3 bc; - const SHADOWMAPPARAM *shd = scn->GetSMapData(); D3DXVec3TransformCoord(&bc, ptr(D3DXVECTOR3f4(BBox.bs)), &mWorld); - bc -= shd->pos; - float x = D3DXVec3Dot(&bc, &(shd->ld)); + FVECTOR3 fbc = FVECTOR3(bc) - shd->pos; + float x = dot(fbc, shd->ld); *mind = min(*mind, x - BBox.bs.w); *maxd = max(*maxd, x + BBox.bs.w); } @@ -719,16 +713,18 @@ void vVessel::BakeLights(ImageProcessing *pBaker) lvlh.East = tmul(FVECTOR4(lvlh.East, 0), mW).xyz; lvlh.North = tmul(FVECTOR4(lvlh.North, 0), mW).xyz; - auto maps = GetEnvMap(); + auto maps = GetExteriorEnvMap(); - for (int i = 0; i < nmesh; i++) - { - if (!meshlist[i].mesh) continue; - if (meshlist[i].vismode & MESHVIS_VC) // TODO: Should check Shader type + if (maps) { + for (int i = 0; i < nmesh; i++) { - auto vSun = tmul(FVECTOR4(sundir, 0), mW); - if (bMustRebake) meshlist[i].mesh->BakeLights(pBaker, BakedLightsControl); - meshlist[i].mesh->BakeAO(pBaker, vSun.xyz, lvlh, maps->pIrrad); + if (!meshlist[i].mesh) continue; + if (meshlist[i].vismode & MESHVIS_VC) // TODO: Should check Shader type + { + auto vSun = tmul(FVECTOR4(sundir, 0), mW); + if (bMustRebake) meshlist[i].mesh->BakeLights(pBaker, BakedLightsControl); + meshlist[i].mesh->BakeAO(pBaker, vSun.xyz, lvlh, maps->pIrrad); + } } } @@ -738,12 +734,21 @@ void vVessel::BakeLights(ImageProcessing *pBaker) // ============================================================================================ // -void vVessel::NoVC() +void vVessel::ErrorOnce(Errors e) { - static bool bDisp = true; - if (bDisp) { - bDisp = false; - oapiWriteLogV("ERROR:D3D9: Cannot identify Virtual Cockpit mesh [%s]", vessel->GetClassNameA()); + static bool bDisp[Errors::ITEMS] = { true }; + static DWORD dwDisp[Errors::ITEMS] = { 0 }; + + if (bDisp[e]) { + switch (e) { + case Errors::NoVC: + oapiWriteLogV("[ERROR:D3D9] Cannot identify Virtual Cockpit mesh [%s]", vessel->GetClassNameA()); + break; + default: + oapiWriteLogV("[ERROR:D3D9] Unknows error code [%s]", vessel->GetName()); + } + dwDisp[e]++; // Count the errors; + bDisp[e] = false; // Disable error from printing again } } @@ -755,7 +760,7 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev) if (!active) return false; pCurrentVisual = this; // Set current visual for mesh debugger UpdateBoundingBox(); - bool bRet = Render(dev, false); + bool bRet = Render(dev, false, nullptr); if (oapiCameraInternal()==false) RenderReentry(dev); return bRet; } @@ -763,7 +768,7 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev) // ============================================================================================ // -bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass) +bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass, const SHADOWMAP *shd) { _TRACE; if (!active) return false; @@ -793,28 +798,29 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass) static VCHUDSPEC hudspec_; - const VCHUDSPEC *hudspec = &hudspec_; + const VCHUDSPEC* hudspec = &hudspec_; static bool gotHUDSpec(false); - const VCMFDSPEC *mfdspec[MAXMFD] = { NULL }; + const VCMFDSPEC* mfdspec[MAXMFD] = { NULL }; + float s = 0.0f, sr = 0.0f; - const SHADOWMAPPARAM *shd = scn->GetSMapData(); - - float s = float(shd->size); - float sr = 2.0f * shd->rad / s; - - HR(D3D9Effect::FX->SetBool(D3D9Effect::eEnvMapEnable, false)); - HR(D3D9Effect::FX->SetMatrix(D3D9Effect::eLVP, shd->mLVP.toCDX())); // Cascade 0 for all + if (shd) + { + s = float(shd->size); + sr = 2.0f * shd->rad / s; + HR(D3D9Effect::FX->SetBool(D3D9Effect::eEnvMapEnable, false)); + HR(D3D9Effect::FX->SetMatrix(D3D9Effect::eLVP, shd->mLVP.toCDX())); // Cascade 0 for all + if (scn->GetRenderPass() == RENDERPASS_MAINSCENE) + D3D9DebugLog("[%s] IsValid(%d), Map=0x%X", GetName(), int(shd->IsValid()), shd->Map(0)); + } - if (shd->pShadowMap && (scn->GetRenderPass() == RENDERPASS_MAINSCENE)) { + if (shd && shd->IsValid() && (scn->GetRenderPass() == RENDERPASS_MAINSCENE)) + { D3DXVECTOR4 sh = D3DXVECTOR4(sr, 1.0f / s, float(oapiRand()), 1.0f / shd->depth); D3DXVECTOR4 px = D3DXVECTOR4(shd->SubPx[0], shd->SubPx[1], shd->SubPx[2], 0.0f); HR(D3D9Effect::FX->SetVector(D3D9Effect::eSHD, &sh)); HR(D3D9Effect::FX->SetVector(D3D9Effect::eSHDPx, &px)); HR(D3D9Effect::FX->SetBool(D3D9Effect::eShadowToggle, true)); D3D9Mesh::SetShadows(shd); - - if (bVC) { - } } else { D3D9Mesh::SetShadows(NULL); @@ -893,7 +899,7 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass) } const LPD3DXMATRIX pVP = scn->GetProjectionViewMatrix(); - const LPD3DXMATRIX pLVP = (const LPD3DXMATRIX)&shd->mLVP; + const LPD3DXMATRIX pLVP = shd ? (const LPD3DXMATRIX)&shd->mLVP : nullptr; // Render vessel meshes -------------------------------------------------------------------------- // @@ -911,8 +917,11 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass) meshlist[i].mesh->RenderShadowMap(pWT, pVP, 1); } else { - if (internalpass) meshlist[i].mesh->Render(pWT, &(scn->emVC), RENDER_VC); - else meshlist[i].mesh->Render(pWT, GetEnvMap(), RENDER_VESSEL); + if (internalpass) { + auto ec = GetEnvCam(EnvCamType::Interior, 0); + meshlist[i].mesh->Render(pWT, ec, RENDER_VC); + } + else meshlist[i].mesh->Render(pWT, GetExteriorEnvMap(), RENDER_VESSEL); } @@ -1290,67 +1299,50 @@ bool vVessel::RenderENVMap(LPDIRECT3DDEVICE9 pDev, ENVCAMREC* ec, DWORD cnt, DWO // Create a EnvMap if doesn't already exists -------------------------------------------------------------------- // - LPDIRECT3DCUBETEXTURE9 pCube = nullptr; - LPDIRECT3DTEXTURE9 pTex = nullptr; - LPDIRECT3DTEXTURE9 pIrrad = nullptr; - - if (ec->tex.pEnv) // If the maps exists check the type and assign - { - if (ec->tex.pEnv->GetType() == D3DRTYPE_CUBETEXTURE) pCube = (LPDIRECT3DCUBETEXTURE9)ec->tex.pEnv; - if (ec->tex.pEnv->GetType() == D3DRTYPE_TEXTURE) pTex = (LPDIRECT3DTEXTURE9)ec->tex.pEnv; - } - else // Map doesn't exists, then create one + if (ec->flags & ENVCAM_PLANE) { - if (ec->flags & ENVCAM_PLANE) + if (!ec->pPlane) { D3DSURFACE_DESC desc; pEnvDS->GetDesc(&desc); - if (D3DXCreateTexture(pDev, desc.Width, desc.Height, 5, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pTex) != S_OK) { + if (D3DXCreateTexture(pDev, desc.Width, desc.Height, 5, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &ec->pPlane) != S_OK) { LogErr("Failed to create env-plane for visual %s", _PTR(this)); return true; } - ec->tex.pEnv = pTex; } - else + } + else { + if (!ec->pCube) // If the maps exists check the type and assign { D3DSURFACE_DESC desc; pEnvDS->GetDesc(&desc); - if (D3DXCreateCubeTexture(pDev, desc.Width, 5, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pCube) != S_OK) { + if (D3DXCreateCubeTexture(pDev, desc.Width, 5, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &ec->pCube) != S_OK) { LogErr("Failed to create env-cubemap for visual %s", _PTR(this)); return true; } - ec->tex.pEnv = pCube; } } // Create a Irradiance map if doesn't already exists -------------------------------------------------------------------- // - if (ec->tex.pIrrad) - { - pIrrad = ec->tex.pIrrad; - } - else + if (!ec->pIrrad) { - if (D3DXCreateTexture(pDev, 128, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pIrrad) != S_OK) { + if (D3DXCreateTexture(pDev, 128, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &ec->pIrrad) != S_OK) { LogErr("Failed to create irradiance map for visual %s", _PTR(this)); return true; } - ec->tex.pIrrad = pIrrad; } // Create blurred maps and irradiance --------------------------------------------------------------------- // if (ec->bRendered) { - if (pCube) { - scn->RenderBlurredMap(pDev, pCube); - scn->IntegrateIrradiance(this, pCube, pIrrad); - } - if (pTex) { - scn->RenderBlurredMap(pDev, pTex); - SAFE_RELEASE(ec->tex.pIrrad); + if (ec->pCube) { + scn->RenderBlurredMap(pDev, ec->pCube); + scn->IntegrateIrradiance(this, ec->pCube, ec->pIrrad); } + // TODO: Blur 2D plane map return true; } @@ -1398,7 +1390,7 @@ bool vVessel::RenderENVMap(LPDIRECT3DDEVICE9 pDev, ENVCAMREC* ec, DWORD cnt, DWO VECTOR3 gpos; vessel->Local2Global(_V(ec->lPos.x, ec->lPos.y, ec->lPos.z), gpos); - if (pCube) + if (ec->pCube) { // Prepare camera and scene for env map rendering scn->PushCamera(); @@ -1412,7 +1404,7 @@ bool vVessel::RenderENVMap(LPDIRECT3DDEVICE9 pDev, ENVCAMREC* ec, DWORD cnt, DWO for (DWORD i = 0; i < cnt; i++) { - HR(pCube->GetCubeMapSurface(D3DCUBEMAP_FACES(ec->iSide), 0, &pSrf)); + HR(ec->pCube->GetCubeMapSurface(D3DCUBEMAP_FACES(ec->iSide), 0, &pSrf)); gc->AlterRenderTarget(pSrf, pEnvDS); @@ -1446,8 +1438,7 @@ bool vVessel::RenderENVMap(LPDIRECT3DDEVICE9 pDev, ENVCAMREC* ec, DWORD cnt, DWO return false; } - - if (pTex) + if (ec->pPlane) { // TODO: return true; @@ -1457,38 +1448,150 @@ bool vVessel::RenderENVMap(LPDIRECT3DDEVICE9 pDev, ENVCAMREC* ec, DWORD cnt, DWO } + // ============================================================================================ -// Return env-map for debug purposes -// -ENVMAPS *vVessel::GetEnvMap() +// Render interior Env Map, return 'true' if the map is completed +// +bool vVessel::RenderInteriorENVMap(LPDIRECT3DDEVICE9 pDev, ENVCAMREC* ec, SHADOWMAP *sm) { - if (ecDefExt.tex.pEnv) { - if (ecDefExt.tex.pEnv->GetType() == D3DRTYPE_CUBETEXTURE) return &ecDefExt.tex; + if (!ec) return true; + + LPDIRECT3DSURFACE9 pEnvDS = GetScene()->GetDepthStencil(256); + + if (!pEnvDS) { + LogErr("RenderInteriorENVMap() DS doesn't exists"); + return true; } - else { - if (vRoot != this && vRoot) return vRoot->GetEnvMap(); + + D3DSURFACE_DESC desc; + pEnvDS->GetDesc(&desc); + + // Create a EnvMap if doesn't already exists -------------------------------------------------------------------- + // + if (!ec->pCube) { + LPDIRECT3DCUBETEXTURE9 pCube = nullptr; + if (D3DXCreateCubeTexture(pDev, desc.Width, 5, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &ec->pCube) != S_OK) { + LogErr("Failed to create env-cubemap for visual %s", _PTR(this)); + return true; + } } + + + // Create a Irradiance map if doesn't already exists -------------------------------------------------------------------- + // + if (!ec->pIrrad) { + LPDIRECT3DTEXTURE9 pIrrad = nullptr; + if (D3DXCreateTexture(pDev, 128, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pIrrad) != S_OK) { + LogErr("Failed to create irradiance map for visual %s", _PTR(this)); + return true; + } + ec->pIrrad = pIrrad; + } + + // Render EnvMaps --------------------------------------------------------------------------------------- + // + std::set RndList; + std::set AddLightSrc; // empty + + RndList.insert(this); + + // ----------------------------------------------------------------------------------------------- + // + VECTOR3 gpos; + vessel->Local2Global(ec->lPos._V(), gpos); + + if (ec->pCube) + { + // Prepare camera and scene for env map rendering + scn->PushCamera(); + scn->SetupInternalCamera(NULL, &gpos, 0.7853981634, 1.0); + scn->BeginPass(RENDERPASS_ENVCAM); + gc->PushRenderTarget(NULL, pEnvDS, RENDERPASS_ENVCAM); + + D3DXMATRIX mEnv; + D3DXVECTOR3 dir, up; + LPDIRECT3DSURFACE9 pSrf = NULL; + + for (DWORD i = 0; i < 6; i++) + { + HR(ec->pCube->GetCubeMapSurface(D3DCUBEMAP_FACES(ec->iSide), 0, &pSrf)); + gc->AlterRenderTarget(pSrf, pEnvDS); + EnvMapDirection(ec->iSide, &dir, &up); + D3DXVECTOR3 cp; + D3DXVec3Cross(&cp, &up, &dir); + D3DXVec3Normalize(&cp, &cp); + D3DXMatrixIdentity(&mEnv); + D3DMAT_FromAxis(&mEnv, &cp, &up, &dir); + + scn->SetCameraFrustumLimits(0.1, 1e4); + scn->SetupInternalCamera(&mEnv, NULL, 0.7853981634, 1.0); + scn->RenderSecondaryScene(RndList, AddLightSrc, SCN_STAGE | SCN_VC, ecDefExt.pCube, sm); + + SAFE_RELEASE(pSrf); + } + + gc->PopRenderTargets(); + scn->PopPass(); + scn->PopCamera(); + + if (ec->pCube) { + scn->RenderBlurredMap(pDev, ec->pCube); + scn->IntegrateIrradiance(this, ec->pCube, ec->pIrrad); + } + } + + return true; +} + + +// ============================================================================================ +// Return exterior env-map for a vessel, seek from a root if doesn't exists. +// Root must always have a map +// +ENVCAMREC*vVessel::GetExteriorEnvMap() +{ + if (ecDefExt.pCube) return &ecDefExt; + else if (vRoot != this && vRoot) return vRoot->GetExteriorEnvMap(); + + assert(Config->EnvMapMode != 0); // Should always return valid map if feature is enabled return nullptr; } // ============================================================================================ // -ENVCAMREC* vVessel::CreateEnvCam(EnvCamType ec) +ENVCAMREC* vVessel::CreateEnvCam(EnvCamType ec, int idx) { - auto x = new ENVCAMREC; - x->type = ec; - mesh_cams.push_back(x); - return x; + if (ec == EnvCamType::Interior) + { + if (idx >= MAX_INTCAM) return nullptr; + auto x = new ENVCAMREC; + x->type = ec; + + if (idx < 0) { + for (auto& c : InteriorCams) if (!c) { c = x; return x; } // Use empty slot + idx = 0; // No empty slot + } + SAFE_DELETE(InteriorCams[idx]); + InteriorCams[idx] = x; + return x; + } + if (ec == EnvCamType::Exterior) { + return &ecDefExt; + } + return nullptr; } + // ============================================================================================ // bool vVessel::HasOwnEnvCam(EnvCamType ec) { if (ec == EnvCamType::Exterior && (ecDefExt.flags & ENVCAM_USER)) return true; - if (ec == EnvCamType::VC && (ecDefVC.flags & ENVCAM_USER)) return true; - if (ec == EnvCamType::Mesh && mesh_cams.size() > 0) return true; + if (ec == EnvCamType::Interior) for (auto x : InteriorCams) if (x) return true; + if (ec == EnvCamType::Mesh) { + // TODO: + } return false; } @@ -1496,15 +1599,28 @@ bool vVessel::HasOwnEnvCam(EnvCamType ec) // ENVCAMREC* vVessel::GetEnvCam(EnvCamType ec, int idx) { + if (ec == EnvCamType::Exterior) return &ecDefExt; + if (ec == EnvCamType::Interior) { + if (idx >= MAX_INTCAM) return nullptr; + if (idx < 0) for (auto c : InteriorCams) if (c) return c; // Get any cam + else return InteriorCams[idx]; + } if (ec == EnvCamType::Mesh) { - if (idx >= mesh_cams.size()) return nullptr; - return mesh_cams[idx]; + // TODO: } - if (ec == EnvCamType::Exterior) return &ecDefExt; - if (ec == EnvCamType::VC) return &ecDefVC; return nullptr; } +// ============================================================================================ +// +bool vVessel::GetInteriorCams(std::list* pCams) +{ + pCams->clear(); + for (auto x : InteriorCams) if (x) pCams->push_back(x); + return !pCams->empty(); +} + + // ============================================================================================ // bool vVessel::IsRoot() const @@ -1842,10 +1958,12 @@ void vVessel::SetVisualProperty(VisualProp prp, int idx, const type_info& t, con ecDefExt.flags |= ENVCAM_USER; return; } - - if (prp == VisualProp::VC_PROBE_POS) { - ecDefVC.lPos = *v; - ecDefVC.flags |= ENVCAM_USER; + + if (prp == VisualProp::CREATE_VC_PROBE) { + auto ec = GetEnvCam(EnvCamType::Interior, idx); + if (!ec) ec = CreateEnvCam(EnvCamType::Interior, idx); + ec->lPos = *v; + oapiWriteLogV("-- [ CREATE_VC_PROBE ] --"); return; } } diff --git a/OVP/D3D9Client/VVessel.h b/OVP/D3D9Client/VVessel.h index dc11ccfd2..424a27ce6 100644 --- a/OVP/D3D9Client/VVessel.h +++ b/OVP/D3D9Client/VVessel.h @@ -9,6 +9,8 @@ #ifndef __VVESSEL_H #define __VVESSEL_H +#define MAX_INTCAM 6 + #include "VObject.h" #include "Mesh.h" #include "gcCore.h" @@ -44,7 +46,9 @@ typedef struct { class vVessel: public vObject { public: friend class D3D9Client; - + + enum Errors { NoVC, ITEMS }; // ITEMS must be last entry + vVessel* vRoot = nullptr; /** @@ -72,17 +76,21 @@ class vVessel: public vObject { D3D9Mesh* GetMesh (UINT idx); DWORD GetMeshVisMode(UINT idx); bool GetMinMaxDistance(float *zmin, float *zmax, float *dmin); - void GetMinMaxLightDist(float *mind, float *maxd); int GetMatrixTransform(gcCore::MatrixId matrix_id, DWORD mesh, DWORD group, FMATRIX4 *pMat); int SetMatrixTransform(gcCore::MatrixId matrix_id, DWORD mesh, DWORD group, const FMATRIX4 *pMat); bool GetVCPos(D3DXVECTOR3* cpos, D3DXVECTOR3* lpos, float* rad); bool GetMeshPosition(int idx, D3DXVECTOR3* cpos, D3DXVECTOR3* lpos, float* rad); void BakeLights(ImageProcessing* pBaker); - void NoVC(); + void ErrorOnce(Errors e); void UpdateBoundingBox(); - bool IsInsideShadows(); - bool IntersectShadowVolume(); - bool IntersectShadowTarget(); + + // Shadow Map Methods + bool IsInsideShadows(const SMapInput* shd); + bool IntersectShadowVolume(const SMapInput* shd); + bool IntersectShadowTarget(const SMapInput* shd); + void GetMinMaxLightDist(const SMapInput* shd, float* mind, float* maxd); + SMapInput GetSMapRenderData(); + void ReloadTextures(); inline DWORD GetMeshCount(); @@ -121,7 +129,7 @@ class vVessel: public vObject { * in cockpit camera mode. * \sa Render(LPDIRECT3DDEVICE9) */ - bool Render (LPDIRECT3DDEVICE9 dev, bool bInternalPass); + bool Render (LPDIRECT3DDEVICE9 dev, bool bInternalPass, const SHADOWMAP *sm); bool RenderExhaust(); @@ -136,13 +144,15 @@ class vVessel: public vObject { void RenderGroundShadow (LPDIRECT3DDEVICE9 dev, OBJHANDLE hPlanet, float depth); void RenderVectors (LPDIRECT3DDEVICE9 dev, D3D9Pad *pSkp); bool RenderENVMap (LPDIRECT3DDEVICE9 pDev, ENVCAMREC* ec, DWORD cnt = 2, DWORD flags = 0xFF); + bool RenderInteriorENVMap(LPDIRECT3DDEVICE9 pDev, ENVCAMREC* ec, SHADOWMAP* sm); bool ProcessEnvMaps(LPDIRECT3DDEVICE9 pDev, DWORD cnt, DWORD flags); - ENVMAPS* GetEnvMap(); - ENVCAMREC* CreateEnvCam(EnvCamType ec); - ENVCAMREC* GetEnvCam(EnvCamType ec, int idx = 0); + ENVCAMREC* GetExteriorEnvMap(); + ENVCAMREC* CreateEnvCam(EnvCamType ec, int idx = -1); + ENVCAMREC* GetEnvCam(EnvCamType ec, int idx = -1); + bool GetInteriorCams(std::list* pCams); + bool HasOwnEnvCam(EnvCamType ec); - bool HasOwnEnvCam(EnvCamType ec); bool IsRoot() const; vVessel* GetRoot() const { return vRoot; } @@ -215,10 +225,10 @@ class vVessel: public vObject { std::map defstate; std::unordered_set applyanim; std::map currentstate; - std::vector mesh_cams; + ENVCAMREC* InteriorCams[MAX_INTCAM] = { nullptr }; // Default eCam configurations - ENVCAMREC ecDefExt, ecDefVC; + ENVCAMREC ecDefExt; FVECTOR3 BakedLightsControl[16]; FVECTOR3 VCAmbient; bool bMustRebake; diff --git a/OVP/D3D9Client/resource.h b/OVP/D3D9Client/resource.h index 104e1df14..5371cafdf 100644 --- a/OVP/D3D9Client/resource.h +++ b/OVP/D3D9Client/resource.h @@ -1,4 +1,3 @@ -#include // Fix Microsoft Visual Studio Version 2012 resource compiler RC4011 warnings. // Instead of #include #if defined(RC_INVOKED) @@ -242,3 +241,4 @@ #define IDC_DBG_AMBDIR 3059 #define IDC_DBG_NOSUNAMB 3060 #define IDC_DBG_NOPLNAMB 3061 +#define IDC_DBG_DATASRC 3062 diff --git a/Orbitersdk/include/DrawAPI.h b/Orbitersdk/include/DrawAPI.h index b292e6933..8976fe079 100644 --- a/Orbitersdk/include/DrawAPI.h +++ b/Orbitersdk/include/DrawAPI.h @@ -261,6 +261,11 @@ namespace oapi { return v; } + inline VECTOR3 toV3() const + { + return { x,y,z }; + } + inline FVECTOR3& operator*= (float f) { x *= f; y *= f; z *= f; @@ -697,6 +702,12 @@ namespace oapi { _swap(m24, m42); _swap(m34, m43); } + static FMATRIX4 Identity() { + FMATRIX4 a; + a.m11 = a.m22 = a.m33 = a.m44 = 1.0f; + return a; + } + float data[16]; struct { FVECTOR4 _x, _y, _z, _p; }; struct { float m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44; }; diff --git a/Orbitersdk/include/VesselAPI.h b/Orbitersdk/include/VesselAPI.h index 0dd226585..6d5d275b7 100644 --- a/Orbitersdk/include/VesselAPI.h +++ b/Orbitersdk/include/VesselAPI.h @@ -46,7 +46,7 @@ enum class VisualProp { BAKED_LIGHT, ///< baked light level AMBIENT, ///< ambient light level EXT_PROBE_POS, ///< Exterior probe position - VC_PROBE_POS ///< Virtual cockpit probe position + CREATE_VC_PROBE ///< Virtual cockpit probe position }; // ====================================================================== diff --git a/Src/Vessel/Atlantis/Atlantis/Atlantis.cpp b/Src/Vessel/Atlantis/Atlantis/Atlantis.cpp index 46a94a8cb..b12d4461a 100644 --- a/Src/Vessel/Atlantis/Atlantis/Atlantis.cpp +++ b/Src/Vessel/Atlantis/Atlantis/Atlantis.cpp @@ -27,6 +27,7 @@ using std::min; using std::max; +using namespace oapi; #ifdef _DEBUG // D. Beachy: for BoundsChecker debugging @@ -1781,6 +1782,8 @@ void Atlantis::clbkVisualCreated (VISHANDLE _vis, int refcount) if (refcount > 1) return; // we don't support more than one visual per object vis = _vis; + SetVisualProperty(vis, VisualProp::CREATE_VC_PROBE, 0, typeid(FVECTOR3), &FVECTOR3(0.0f, 2.6f, 14.0f)); + // make sure the RMS attachment point is in sync with the animation state of the visual SetAttachmentParams (rms_attach, arm_tip[0], arm_tip[1]-arm_tip[0], arm_tip[2]-arm_tip[0]); } From 21546352c2b9e2842d2eff74fbe2ee06aaff3b89 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Sun, 4 Feb 2024 22:19:53 +0200 Subject: [PATCH 33/42] Fixed broken 'pick' function. Added dynamic sunlight disable option in DebugControls. --- OVP/D3D9Client/D3D9Client.cpp | 65 ++++++++++++++++---------------- OVP/D3D9Client/D3D9Client.h | 4 +- OVP/D3D9Client/D3D9Client.rc | 51 +++++++++++++------------ OVP/D3D9Client/DebugControls.cpp | 2 + OVP/D3D9Client/DebugControls.h | 1 + OVP/D3D9Client/Mesh.cpp | 28 +++++++------- OVP/D3D9Client/VBase.cpp | 22 +++++------ OVP/D3D9Client/VPlanet.cpp | 2 +- OVP/D3D9Client/VVessel.cpp | 4 +- OVP/D3D9Client/resource.h | 1 + 10 files changed, 93 insertions(+), 87 deletions(-) diff --git a/OVP/D3D9Client/D3D9Client.cpp b/OVP/D3D9Client/D3D9Client.cpp index 483745a44..33f118ed3 100644 --- a/OVP/D3D9Client/D3D9Client.cpp +++ b/OVP/D3D9Client/D3D9Client.cpp @@ -79,8 +79,8 @@ unordered_map ClonedTextures; unordered_map MeshMap; unordered_map MicroTextures; -DWORD uCurrentMesh = 0; -vObject *pCurrentVisual = 0; +DWORD g_uCurrentMesh = 0; +vObject *g_pCurrentVisual = nullptr; _D3D9Stats D3D9Stats; #ifdef _NVAPI_H @@ -1693,8 +1693,6 @@ LRESULT D3D9Client::RenderWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l static bool bTrackMouse = false; static short xpos=0, ypos=0; - D3D9Pick pick; - if (hRenderWnd!=hWnd && uMsg!= WM_NCDESTROY) { LogErr("Invalid Window !! RenderWndProc() called after calling clbkDestroyRenderWindow() uMsg=0x%X", uMsg); return 0; @@ -1756,7 +1754,7 @@ LRESULT D3D9Client::RenderWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l if (DebugControls::debugFlags & DBG_FLAGS_DUALSIDED) prp.bDualSided = true; } - pick = GetScene()->PickScene(xpos, ypos, &prp); + D3D9Pick pick = GetScene()->PickScene(xpos, ypos, &prp); if (bPckVsl) { gcCore::PickData out; @@ -1768,49 +1766,50 @@ LRESULT D3D9Client::RenderWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l out.dist = pick.dist; MakeGenericProcCall(GENERICPROC_PICK_VESSEL, sizeof(gcCore::PickData), &out); } - } - PickTerrain(uMsg, xpos, ypos); - // No Debug Controls - if (bShift && bCtrl && !DebugControls::IsActive() && !oapiCameraInternal()) { + // No Debug Controls + if (bShift && bCtrl && !DebugControls::IsActive() && !oapiCameraInternal()) { - if (!pick.pMesh) break; + if (!pick.pMesh) break; - OBJHANDLE hObj = pick.vObj->Object(); - if (oapiGetObjectType(hObj) == OBJTP_VESSEL) { - oapiSetFocusObject(hObj); - } + OBJHANDLE hObj = pick.vObj->Object(); + if (oapiGetObjectType(hObj) == OBJTP_VESSEL) { + oapiSetFocusObject(hObj); + } - break; - } + break; + } - // With Debug Controls - if (DebugControls::IsActive()) { + // With Debug Controls + if (DebugControls::IsActive()) { - DWORD flags = *(DWORD*)GetConfigParam(CFGPRM_GETDEBUGFLAGS); + DWORD flags = *(DWORD*)GetConfigParam(CFGPRM_GETDEBUGFLAGS); - if (flags&DBG_FLAGS_PICK) { + if (flags & DBG_FLAGS_PICK) { - if (!pick.pMesh) break; + if (!pick.pMesh) break; - if (bShift && bCtrl) { - OBJHANDLE hObj = pick.vObj->Object(); - if (oapiGetObjectType(hObj)==OBJTP_VESSEL) { - oapiSetFocusObject(hObj); - break; + if (bShift && bCtrl) { + OBJHANDLE hObj = pick.vObj->Object(); + if (oapiGetObjectType(hObj) == OBJTP_VESSEL) { + oapiSetFocusObject(hObj); + break; + } + } + else if (pick.group >= 0) { + DebugControls::SetVisual(pick.vObj); + DebugControls::SelectMesh(pick.pMesh); + DebugControls::SelectGroup(pick.group); + DebugControls::SetGroupHighlight(true); + DebugControls::SetPickPos(pick.pos); } - } - else if (pick.group>=0) { - DebugControls::SetVisual(pick.vObj); - DebugControls::SelectMesh(pick.pMesh); - DebugControls::SelectGroup(pick.group); - DebugControls::SetGroupHighlight(true); - DebugControls::SetPickPos(pick.pos); } } } + PickTerrain(uMsg, xpos, ypos); + break; } diff --git a/OVP/D3D9Client/D3D9Client.h b/OVP/D3D9Client/D3D9Client.h index 333633209..be544ff42 100644 --- a/OVP/D3D9Client/D3D9Client.h +++ b/OVP/D3D9Client/D3D9Client.h @@ -62,8 +62,8 @@ class FileParser; class OapiExtension; class D3D9Pad; -extern DWORD uCurrentMesh; -extern class vObject * pCurrentVisual; +extern DWORD g_uCurrentMesh; +extern class vObject* g_pCurrentVisual; typedef char * LPCHAR; typedef void * CAMERAHANDLE; diff --git a/OVP/D3D9Client/D3D9Client.rc b/OVP/D3D9Client/D3D9Client.rc index 69f271346..84aa9ff82 100644 --- a/OVP/D3D9Client/D3D9Client.rc +++ b/OVP/D3D9Client/D3D9Client.rc @@ -56,26 +56,26 @@ FONT 8, "Ms Shell Dlg" EDITTEXT IDC_DBG_FILE, 421, 35, 125, 12, WS_GROUP | ES_AUTOHSCROLL | ES_READONLY, WS_EX_LEFT AUTOCHECKBOX "Highlight selected group", IDC_DBG_HSG, 18, 107, 92, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Highlight selected mesh", IDC_DBG_HSM, 18, 117, 91, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Boxes", IDC_DBG_BOXES, 208, 202, 35, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Boxes", IDC_DBG_BOXES, 208, 217, 35, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Normalize", IDC_DBG_NORM, 400, 79, 47, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Mipmap fade", IDC_DBG_FADE, 400, 92, 57, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Reduce seams", IDC_DBG_SEAMS, 460, 79, 63, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Spheres", IDC_DBG_SPHERES, 208, 211, 42, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Surface Tiles", IDC_DBG_TILEBB, 208, 220, 57, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Selected group only", IDC_DBG_GRPO, 274, 202, 79, 8, 0, WS_EX_LEFT - GROUPBOX "Bounding geometry", IDC_STATIC, 195, 190, 175, 45, 0, WS_EX_LEFT - GROUPBOX "Visualize local light cones", IDC_STATIC, 195, 240, 175, 35, 0, WS_EX_LEFT + AUTOCHECKBOX "Spheres", IDC_DBG_SPHERES, 208, 226, 42, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Surface Tiles", IDC_DBG_TILEBB, 208, 235, 57, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Selected group only", IDC_DBG_GRPO, 274, 217, 79, 8, 0, WS_EX_LEFT + GROUPBOX "Bounding geometry", IDC_STATIC, 195, 205, 175, 45, 0, WS_EX_LEFT + GROUPBOX "Visualize local light cones", IDC_STATIC, 195, 255, 175, 35, 0, WS_EX_LEFT GROUPBOX "Selection and Display Options", IDC_STATIC, 5, 15, 175, 145, 0, WS_EX_LEFT GROUPBOX "Misc.", IDC_STATIC, 195, 10, 173, 70, 0, WS_EX_LEFT - GROUPBOX "Scene Debugger", IDC_STATIC, 195, 85, 173, 100, 0, WS_EX_LEFT + GROUPBOX "Scene Debugger", IDC_STATIC, 195, 85, 173, 115, 0, WS_EX_LEFT GROUPBOX "Texture Tools", IDC_STATIC, 380, 15, 173, 151, 0, WS_EX_LEFT - AUTOCHECKBOX "Selected mesh only", IDC_DBG_MSHO, 274, 211, 77, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Selected mesh only", IDC_DBG_MSHO, 274, 226, 77, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Dual sided", IDC_DBG_DUAL, 120, 107, 49, 8, 0, WS_EX_LEFT PUSHBUTTON "<", IDC_DBG_GRPUP, 102, 90, 9, 12, BS_CENTER, WS_EX_LEFT PUSHBUTTON ">", IDC_DBG_GRPDN, 114, 90, 9, 12, BS_CENTER, WS_EX_LEFT PUSHBUTTON "<", IDC_DBG_MSHUP, 102, 73, 9, 12, BS_CENTER, WS_EX_LEFT PUSHBUTTON ">", IDC_DBG_MSHDN, 114, 73, 9, 12, BS_CENTER, WS_EX_LEFT - AUTOCHECKBOX "Selected visual only", IDC_DBG_VISO, 274, 220, 79, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Selected visual only", IDC_DBG_VISO, 274, 235, 79, 8, 0, WS_EX_LEFT CONTROL "", IDC_DBG_SPEED, TRACKBAR_CLASS, WS_TABSTOP | TBS_BOTH | TBS_NOTICKS, 42, 58, 108, 13, WS_EX_LEFT CONTROL "", IDC_DBG_RESBIAS, TRACKBAR_CLASS, WS_TABSTOP | TBS_AUTOTICKS | TBS_BOTH, 205, 55, 155, 20, WS_EX_LEFT LTEXT "Speed", IDC_STATIC, 18, 58, 22, 8, SS_LEFT, WS_EX_LEFT @@ -85,7 +85,7 @@ FONT 8, "Ms Shell Dlg" GROUPBOX "Material", IDC_DBG_MATGRP, 5, 230, 175, 165, 0, WS_EX_LEFT COMBOBOX IDC_DBG_MATPRP, 77, 240, 96, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT COMBOBOX IDC_DBG_DEFSHADER, 75, 177, 96, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT - COMBOBOX IDC_DBG_CONES, 200, 255, 165, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT + COMBOBOX IDC_DBG_CONES, 200, 270, 165, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT LTEXT "Material property", IDC_STATIC, 18, 242, 53, 8, SS_LEFT, WS_EX_LEFT LTEXT "Mesh Shader", IDC_STATIC, 15, 179, 43, 9, SS_LEFT, WS_EX_LEFT EDITTEXT IDC_DBG_RED, 31, 260, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT @@ -129,34 +129,35 @@ FONT 8, "Ms Shell Dlg" COMBOBOX IDC_DBG_BKLID, 11, 407, 50, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT GROUPBOX "Baked Lights", 0, 6, 395, 175, 30, 0, WS_EX_LEFT CONTROL "", IDC_DBG_BKLADJ, TRACKBAR_CLASS, WS_TABSTOP | TBS_BOTH | TBS_NOTICKS, 65, 405, 115, 15, WS_EX_LEFT - GROUPBOX "Mesh Group Information", IDC_STATIC, 195, 280, 175, 135, 0, WS_EX_LEFT - AUTOCHECKBOX "No Shadow", IDC_DBG_NOSHADOW, 200, 295, 53, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Do not render", IDC_DBG_NORENDER, 200, 305, 59, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Always Lit", IDC_DBG_NOLIGHT, 200, 315, 47, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Additive Blend", IDC_DBG_ADDITIVE, 200, 325, 61, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Texture Alpha Only (No Color)", IDC_DBG_NOCOLOR, 200, 335, 109, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Order Independent Transparency", IDC_DBG_OIT, 200, 345, 121, 8, 0, WS_EX_LEFT - EDITTEXT IDC_DBG_MATIDX, 225, 360, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT - EDITTEXT IDC_DBG_TEXIDX, 225, 375, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT - LTEXT "MatIdx", IDC_STATIC, 200, 361, 22, 9, SS_LEFT, WS_EX_LEFT - LTEXT "TexIdx", IDC_STATIC, 200, 377, 22, 9, SS_LEFT, WS_EX_LEFT + GROUPBOX "Mesh Group Information", IDC_STATIC, 195, 295, 175, 130, 0, WS_EX_LEFT + AUTOCHECKBOX "No Shadow", IDC_DBG_NOSHADOW, 200, 310, 53, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Do not render", IDC_DBG_NORENDER, 200, 320, 59, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Always Lit", IDC_DBG_NOLIGHT, 200, 330, 47, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Additive Blend", IDC_DBG_ADDITIVE, 200, 340, 61, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Texture Alpha Only (No Color)", IDC_DBG_NOCOLOR, 200, 350, 109, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Order Independent Transparency", IDC_DBG_OIT, 200, 360, 121, 8, 0, WS_EX_LEFT + EDITTEXT IDC_DBG_MATIDX, 225, 375, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT + EDITTEXT IDC_DBG_TEXIDX, 225, 390, 30, 12, ES_AUTOHSCROLL, WS_EX_LEFT + LTEXT "MatIdx", IDC_STATIC, 200, 376, 22, 9, SS_LEFT, WS_EX_LEFT + LTEXT "TexIdx", IDC_STATIC, 200, 392, 22, 9, SS_LEFT, WS_EX_LEFT PUSHBUTTON "Save Mesh", IDC_DBG_MESHSAVE, 200, 430, 55, 14, 0, WS_EX_LEFT PUSHBUTTON "Unrendered", IDC_DBG_NEXT, 127, 90, 48, 12, 0, WS_EX_LEFT - LTEXT "Label", IDC_STATIC, 201, 392, 18, 9, SS_LEFT, WS_EX_LEFT - EDITTEXT IDC_DBG_GRPLABEL, 225, 390, 140, 12, ES_AUTOHSCROLL, WS_EX_LEFT + LTEXT "Label", IDC_STATIC, 201, 407, 18, 9, SS_LEFT, WS_EX_LEFT + EDITTEXT IDC_DBG_GRPLABEL, 225, 405, 140, 12, ES_AUTOHSCROLL, WS_EX_LEFT AUTOCHECKBOX "Exterior in VC", IDC_DBG_EXTVC, 120, 137, 58, 8, 0, WS_EX_LEFT AUTOCHECKBOX "2cm near clip distance", IDC_DBG_CLIPDIST, 18, 136, 87, 8, 0, WS_EX_LEFT LTEXT "MeshVisMode: ", IDC_DBG_VISMODE, 10, 380, 162, 9, SS_LEFT, WS_EX_LEFT AUTOCHECKBOX "Pick only current mesh", IDC_DBG_PICKCURRENT, 18, 146, 87, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Dynamic", IDC_DBG_DYNAMIC, 285, 295, 43, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Dynamic", IDC_DBG_DYNAMIC, 285, 310, 43, 8, 0, WS_EX_LEFT AUTOCHECKBOX "This is VC mesh", IDC_DBG_ISVCMESH, 15, 193, 66, 8, 0, WS_EX_LEFT AUTOCHECKBOX "Cast VC shadow", IDC_DBG_VCSHADOW, 15, 203, 68, 8, 0, WS_EX_LEFT COMBOBOX IDC_DBG_AMBDIR, 275, 130, 86, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT LTEXT "VC Ambient View Dir", IDC_STATIC, 205, 132, 66, 9, SS_LEFT, WS_EX_LEFT - AUTOCHECKBOX "No sunlight", IDC_DBG_NOSUNAMB, 205, 161, 51, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "No ambient sunlight", IDC_DBG_NOSUNAMB, 205, 161, 78, 8, 0, WS_EX_LEFT AUTOCHECKBOX "No planet glow", IDC_DBG_NOPLNAMB, 205, 172, 63, 8, 0, WS_EX_LEFT COMBOBOX IDC_DBG_DATASRC, 275, 145, 86, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT LTEXT "Probe Data Source", IDC_STATIC, 206, 147, 62, 9, SS_LEFT, WS_EX_LEFT + AUTOCHECKBOX "No dynamic sunlight", IDC_DBG_NODYNSUN, 205, 184, 79, 8, 0, WS_EX_LEFT } diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index 615912556..9ab4b529e 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -493,6 +493,7 @@ void UpdateFlags() SETFLAG(debugFlags, DBG_FLAGS_PICKCURRENT, (SendDlgItemMessageA(hDlg, IDC_DBG_PICKCURRENT, BM_GETCHECK, 0, 0) == BST_CHECKED)); SETFLAG(debugFlags, DBG_FLAGS_NOSUNAMB, (SendDlgItemMessageA(hDlg, IDC_DBG_NOSUNAMB, BM_GETCHECK, 0, 0) == BST_CHECKED)); SETFLAG(debugFlags, DBG_FLAGS_NOPLNAMB, (SendDlgItemMessageA(hDlg, IDC_DBG_NOPLNAMB, BM_GETCHECK, 0, 0) == BST_CHECKED)); + SETFLAG(debugFlags, DBG_FLAGS_NODYNSUN, (SendDlgItemMessageA(hDlg, IDC_DBG_NODYNSUN, BM_GETCHECK, 0, 0) == BST_CHECKED)); Config->EnableLimiter = (int)((debugFlags&DBG_FLAGS_FPSLIM)>0); } @@ -2367,6 +2368,7 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case IDC_DBG_PICKCURRENT: case IDC_DBG_NOSUNAMB: case IDC_DBG_NOPLNAMB: + case IDC_DBG_NODYNSUN: UpdateFlags(); break; diff --git a/OVP/D3D9Client/DebugControls.h b/OVP/D3D9Client/DebugControls.h index cb3e6d266..2fb3101db 100644 --- a/OVP/D3D9Client/DebugControls.h +++ b/OVP/D3D9Client/DebugControls.h @@ -66,6 +66,7 @@ #define DBG_FLAGS_PICKCURRENT 0x20000 ///< Only use Pick for current mesh #define DBG_FLAGS_NOSUNAMB 0x40000 ///< Disable sun ambient effect in VC #define DBG_FLAGS_NOPLNAMB 0x80000 ///< Disable planet shine ambient effect in VC +#define DBG_FLAGS_NODYNSUN 0x100000 ///< Disable dynamic sunlight /// @} diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index b3d4d68cc..651f8ed28 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -1701,6 +1701,8 @@ void D3D9Mesh::ConfigureAtmo() //LogSunLight(sunLight); float x = 1.0f - saturate(max(sunLight.Color.r, sunLight.Color.b) * 2.0f); FX->SetFloat(eNight, x); + if (DebugControls::IsActive() && DebugControls::debugFlags & DBG_FLAGS_NODYNSUN) + sunLight.Color = sunLight.Ambient = 0; FX->SetValue(eSun, &sunLight, sizeof(D3D9Sun)); } @@ -1779,9 +1781,9 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, const ENVCAMREC* em, int iTech) selmsh = *(DWORD*)gc->GetConfigParam(CFGPRM_GETSELECTEDMESH); selgrp = *(DWORD*)gc->GetConfigParam(CFGPRM_GETSELECTEDGROUP); displ = *(DWORD*)gc->GetConfigParam(CFGPRM_GETDISPLAYMODE); - bActiveVisual = (pCurrentVisual==DebugControls::GetVisual()); + bActiveVisual = (g_pCurrentVisual == DebugControls::GetVisual()); if (displ>0 && !bActiveVisual) return; - if ((displ==2 || displ==3) && uCurrentMesh!=selmsh) return; + if ((displ==2 || displ==3) && g_uCurrentMesh!=selmsh) return; } Scene *scn = gc->GetScene(); @@ -1985,12 +1987,12 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, const ENVCAMREC* em, int iTech) FX->SetVector(eColor, ptr(D3DXVECTOR4(0, 0, 0, 0))); if (flags&DBG_FLAGS_HLMESH) { - if (uCurrentMesh==selmsh) { + if (g_uCurrentMesh==selmsh) { FX->SetVector(eColor, ptr(D3DXVECTOR4(0.0f, 0.0f, 0.5f, 0.5f))); } } - if (flags&DBG_FLAGS_HLGROUP) { - if (g==selgrp && uCurrentMesh==selmsh) { + if (flags&DBG_FLAGS_HLGROUP) { + if (g == selgrp && g_uCurrentMesh == selmsh) { FX->SetVector(eColor, ptr(D3DXVECTOR4(0.0f, 0.5f, 0.0f, 0.5f))); } } @@ -2197,7 +2199,7 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, const ENVCAMREC* em, int iTech) // if (DebugControls::IsActive()) { - if ((bActiveVisual) && (g == selgrp) && (uCurrentMesh == selmsh)) { + if ((bActiveVisual) && (g == selgrp) && (g_uCurrentMesh == selmsh)) { bool bAdd = (Grp[g].UsrFlag & 0x08) != 0; bool bNoS = (Grp[g].UsrFlag & 0x01) != 0; @@ -2207,7 +2209,7 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, const ENVCAMREC* em, int iTech) static const char *RGH[2] = { "Disabled", "Enabled" }; static const char *Shaders[7] = { "PBR", "PBR-ADV", "FAST", "XR2", "METALNESS", "BAKED_VC", "???"}; - DebugControls::Append("MeshIdx = %d, GrpIdx = %d\n", uCurrentMesh, g); + DebugControls::Append("MeshIdx = %d, GrpIdx = %d\n", g_uCurrentMesh, g); DebugControls::Append("MtrlIdx = %d, TexIdx = %d\n", Grp[g].MtrlIdx, Grp[g].TexIdx); DebugControls::Append("FaceCnt = %d, VtxCnt = %d\n", Grp[g].nFace, Grp[g].nVert); @@ -2561,9 +2563,9 @@ void D3D9Mesh::RenderFast(const LPD3DXMATRIX pW, int iTech) selmsh = *(DWORD*)gc->GetConfigParam(CFGPRM_GETSELECTEDMESH); selgrp = *(DWORD*)gc->GetConfigParam(CFGPRM_GETSELECTEDGROUP); displ = *(DWORD*)gc->GetConfigParam(CFGPRM_GETDISPLAYMODE); - bActiveVisual = (pCurrentVisual == DebugControls::GetVisual()); + bActiveVisual = (g_pCurrentVisual == DebugControls::GetVisual()); if (displ>0 && !bActiveVisual) return; - if ((displ == 2 || displ == 3) && uCurrentMesh != selmsh) return; + if ((displ == 2 || displ == 3) && g_uCurrentMesh != selmsh) return; } Scene *scn = gc->GetScene(); @@ -2709,12 +2711,12 @@ void D3D9Mesh::RenderFast(const LPD3DXMATRIX pW, int iTech) FX->SetVector(eColor, ptr(D3DXVECTOR4(0, 0, 0, 0))); if (flags&DBG_FLAGS_HLMESH) { - if (uCurrentMesh == selmsh) { + if (g_uCurrentMesh == selmsh) { FX->SetVector(eColor, ptr(D3DXVECTOR4(0.0f, 0.0f, 0.5f, 0.5f))); } } if (flags&DBG_FLAGS_HLGROUP) { - if (g == selgrp && uCurrentMesh == selmsh) { + if (g == selgrp && g_uCurrentMesh == selmsh) { FX->SetVector(eColor, ptr(D3DXVECTOR4(0.0f, 0.5f, 0.0f, 0.5f))); } } @@ -3296,10 +3298,10 @@ void D3D9Mesh::RenderBoundingBox(const LPD3DXMATRIX pW) DWORD flags = *(DWORD*)gc->GetConfigParam(CFGPRM_GETDEBUGFLAGS); DWORD selmsh = *(DWORD*)gc->GetConfigParam(CFGPRM_GETSELECTEDMESH); DWORD selgrp = *(DWORD*)gc->GetConfigParam(CFGPRM_GETSELECTEDGROUP); - bool bSel = (uCurrentMesh==selmsh); + bool bSel = (g_uCurrentMesh==selmsh); - if (flags&(DBG_FLAGS_SELVISONLY|DBG_FLAGS_SELMSHONLY|DBG_FLAGS_SELGRPONLY) && DebugControls::GetVisual()!=pCurrentVisual) return; + if (flags&(DBG_FLAGS_SELVISONLY|DBG_FLAGS_SELMSHONLY|DBG_FLAGS_SELGRPONLY) && DebugControls::GetVisual()!=g_pCurrentVisual) return; if (flags&DBG_FLAGS_SELMSHONLY && !bSel) return; if (flags&DBG_FLAGS_SELGRPONLY && !bSel) return; diff --git a/OVP/D3D9Client/VBase.cpp b/OVP/D3D9Client/VBase.cpp index 87b1f8413..e2079119b 100644 --- a/OVP/D3D9Client/VBase.cpp +++ b/OVP/D3D9Client/VBase.cpp @@ -386,14 +386,14 @@ bool vBase::RenderSurface(LPDIRECT3DDEVICE9 dev) if (!active) return false; if (!IsVisible()) return false; - pCurrentVisual = this; + g_pCurrentVisual = this; // render tiles if (tilemesh) { - uCurrentMesh = 0; // Used for debugging + g_uCurrentMesh = 0; // Used for debugging tilemesh->SetSunLight(&sunLight); tilemesh->RenderBaseTile(&mWorld); - ++uCurrentMesh; + ++g_uCurrentMesh; } // render generic objects under shadows @@ -401,7 +401,7 @@ bool vBase::RenderSurface(LPDIRECT3DDEVICE9 dev) for (DWORD i = 0; i < nstructure_bs; ++i) { structure_bs[i]->SetSunLight(&sunLight); structure_bs[i]->Render(&mWorld, nullptr, RENDER_BASEBS); - ++uCurrentMesh; + ++g_uCurrentMesh; } } @@ -416,11 +416,11 @@ bool vBase::RenderStructures(LPDIRECT3DDEVICE9 dev) if (!active) return false; if (!IsVisible()) return false; - pCurrentVisual = this; - uCurrentMesh = 0; // Used for debugging + g_pCurrentVisual = this; + g_uCurrentMesh = 0; // Used for debugging - if (tilemesh) uCurrentMesh++; - uCurrentMesh += nstructure_bs; + if (tilemesh) g_uCurrentMesh++; + g_uCurrentMesh += nstructure_bs; // render generic objects above shadows for (DWORD i=0; iGetObjectAtmoParams(qw._V() + vP->CameraPos()); structure_as[i]->SetSunLight(&sp); structure_as[i]->Render(&mWorld, nullptr, RENDER_BASE); - ++uCurrentMesh; + ++g_uCurrentMesh; } return true; } @@ -442,7 +442,7 @@ void vBase::RenderRunwayLights(LPDIRECT3DDEVICE9 dev) if (!active) return; if (!IsVisible()) return; - pCurrentVisual = this; + g_pCurrentVisual = this; for(int i=0; iTerrainShadowing == 0) return; - pCurrentVisual = this; + g_pCurrentVisual = this; VECTOR3 sd; oapiGetGlobalPos(hObj, &sd); normalise(sd); diff --git a/OVP/D3D9Client/VPlanet.cpp b/OVP/D3D9Client/VPlanet.cpp index cce7a4b66..6c55b6d1d 100644 --- a/OVP/D3D9Client/VPlanet.cpp +++ b/OVP/D3D9Client/VPlanet.cpp @@ -936,7 +936,7 @@ bool vPlanet::Render(LPDIRECT3DDEVICE9 dev) memset(fcv, 0, sizeof(FlowControlVS)); - pCurrentVisual = this; + g_pCurrentVisual = this; if (renderpix) { // render as 2x2 pixel block RenderDot (dev); diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index a010a272e..9ce45f2c0 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -758,7 +758,6 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev) { _TRACE; if (!active) return false; - pCurrentVisual = this; // Set current visual for mesh debugger UpdateBoundingBox(); bool bRet = Render(dev, false, nullptr); if (oapiCameraInternal()==false) RenderReentry(dev); @@ -775,6 +774,7 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass, const SHADOWMAP * UINT i, mfd; + g_pCurrentVisual = this; // Set current visual for mesh debugger DWORD flags = *(DWORD*)gc->GetConfigParam(CFGPRM_GETDEBUGFLAGS); DWORD displ = *(DWORD*)gc->GetConfigParam(CFGPRM_GETDISPLAYMODE); @@ -849,7 +849,7 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass, const SHADOWMAP * if (!meshlist[i].mesh) continue; - uCurrentMesh = i; // Used for debugging + g_uCurrentMesh = i; // Used for debugging // check if mesh should be rendered in this pass WORD vismode = meshlist[i].vismode; diff --git a/OVP/D3D9Client/resource.h b/OVP/D3D9Client/resource.h index 5371cafdf..6679acfad 100644 --- a/OVP/D3D9Client/resource.h +++ b/OVP/D3D9Client/resource.h @@ -242,3 +242,4 @@ #define IDC_DBG_NOSUNAMB 3060 #define IDC_DBG_NOPLNAMB 3061 #define IDC_DBG_DATASRC 3062 +#define IDC_DBG_NODYNSUN 3063 From cf964a8b312a287d52391bdc65a680e1a3e64d18 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Fri, 9 Feb 2024 19:39:55 +0200 Subject: [PATCH 34/42] Added rendering of VC reflection and irradiance maps --- OVP/D3D9Client/D3D9Util.cpp | 9 -- OVP/D3D9Client/D3D9Util.h | 1 - OVP/D3D9Client/Log.cpp | 36 +++++++ OVP/D3D9Client/Log.h | 5 + OVP/D3D9Client/Mesh.cpp | 4 +- OVP/D3D9Client/Scene.cpp | 146 +++++++++++++++---------- OVP/D3D9Client/Scene.h | 8 +- OVP/D3D9Client/VPlanet.cpp | 4 +- OVP/D3D9Client/VVessel.cpp | 201 +++++++++++++++++++---------------- OVP/D3D9Client/VVessel.h | 13 ++- Orbitersdk/include/DrawAPI.h | 19 ++-- 11 files changed, 270 insertions(+), 176 deletions(-) diff --git a/OVP/D3D9Client/D3D9Util.cpp b/OVP/D3D9Client/D3D9Util.cpp index 91b98fadc..b26d1fa5d 100644 --- a/OVP/D3D9Client/D3D9Util.cpp +++ b/OVP/D3D9Client/D3D9Util.cpp @@ -232,15 +232,6 @@ bool CopyBuffer(LPDIRECT3DRESOURCE9 _pDst, LPDIRECT3DRESOURCE9 _pSrc) return false; } -void LogMatrix(D3DXMATRIX *pM, const char *name) -{ - LogAlw("%s", name); - LogAlw("[%9.9g, %9.9g, %9.9g, %9.9g]", pM->_11, pM->_12, pM->_13, pM->_14); - LogAlw("[%9.9g, %9.9g, %9.9g, %9.9g]", pM->_21, pM->_22, pM->_23, pM->_24); - LogAlw("[%9.9g, %9.9g, %9.9g, %9.9g]", pM->_31, pM->_32, pM->_33, pM->_34); - LogAlw("[%9.9g, %9.9g, %9.9g, %9.9g]", pM->_41, pM->_42, pM->_43, pM->_44); -} - inline D3DXVECTOR4 CV2VEC4(const D3DCOLORVALUE &in) { return D3DXVECTOR4(in.r, in.g, in.b, in.a); diff --git a/OVP/D3D9Client/D3D9Util.h b/OVP/D3D9Client/D3D9Util.h index 3eda04f39..ffcc7b3d2 100644 --- a/OVP/D3D9Client/D3D9Util.h +++ b/OVP/D3D9Client/D3D9Util.h @@ -418,7 +418,6 @@ inline double wrap(double a) return a; } -void LogMatrix(D3DXMATRIX *pM, const char *name); inline void LogSunLight(D3D9Sun& s) { LogAlw("Sunlight.Dir = [%f, %f, %f]", s.Dir.x, s.Dir.y, s.Dir.z); diff --git a/OVP/D3D9Client/Log.cpp b/OVP/D3D9Client/Log.cpp index 2492a5827..f8a969d93 100644 --- a/OVP/D3D9Client/Log.cpp +++ b/OVP/D3D9Client/Log.cpp @@ -152,6 +152,21 @@ void D3D9DebugLogVec(const char* lbl, oapi::FVECTOR4 &v) D3D9DebugQueue.push(std::string(ErrBuf)); } +//------------------------------------------------------------------------------------------- +// +void D3D9DebugLogMatrix(const char* name, D3DXMATRIX* pM) +{ + D3D9DebugQueue.push(std::string(name)); + sprintf_s(ErrBuf, ERRBUF, "[%9.9g, %9.9g, %9.9g, %9.9g]", pM->_11, pM->_12, pM->_13, pM->_14); + D3D9DebugQueue.push(std::string(ErrBuf)); + sprintf_s(ErrBuf, ERRBUF, "[%9.9g, %9.9g, %9.9g, %9.9g]", pM->_21, pM->_22, pM->_23, pM->_24); + D3D9DebugQueue.push(std::string(ErrBuf)); + sprintf_s(ErrBuf, ERRBUF, "[%9.9g, %9.9g, %9.9g, %9.9g]", pM->_31, pM->_32, pM->_33, pM->_34); + D3D9DebugQueue.push(std::string(ErrBuf)); + sprintf_s(ErrBuf, ERRBUF, "[%9.9g, %9.9g, %9.9g, %9.9g]", pM->_41, pM->_42, pM->_43, pM->_44); + D3D9DebugQueue.push(std::string(ErrBuf)); +} + //------------------------------------------------------------------------------------------- // void D3D9InitLog(const char *file) @@ -514,3 +529,24 @@ void LogOk(const char *format, ...) LeaveCriticalSection(&LogCrit); }*/ } + +void LogMatrix(D3DXMATRIX* pM, const char* name) +{ + LogAlw("%s", name); + LogAlw("[%9.9g, %9.9g, %9.9g, %9.9g]", pM->_11, pM->_12, pM->_13, pM->_14); + LogAlw("[%9.9g, %9.9g, %9.9g, %9.9g]", pM->_21, pM->_22, pM->_23, pM->_24); + LogAlw("[%9.9g, %9.9g, %9.9g, %9.9g]", pM->_31, pM->_32, pM->_33, pM->_34); + LogAlw("[%9.9g, %9.9g, %9.9g, %9.9g]", pM->_41, pM->_42, pM->_43, pM->_44); +} + +void LogVec(D3DXVECTOR4* pM, const char* name) +{ + LogAlw("%s", name); + LogAlw("[%9.9g, %9.9g, %9.9g, %9.9g]", pM->x, pM->y, pM->z, pM->w); +} + +void LogVec(VECTOR3* pM, const char* name) +{ + LogAlw("%s", name); + LogAlw("[%9.9g, %9.9g, %9.9g]", pM->x, pM->y, pM->z); +} diff --git a/OVP/D3D9Client/Log.h b/OVP/D3D9Client/Log.h index 13ef8eb30..9a9934132 100644 --- a/OVP/D3D9Client/Log.h +++ b/OVP/D3D9Client/Log.h @@ -47,6 +47,7 @@ extern std::queue D3D9DebugQueue; void RuntimeError(const char* File, const char* Fnc, UINT Line); void D3D9DebugLog(const char *format, ...); void D3D9DebugLogVec(const char* lbl, oapi::FVECTOR4 &v); +void D3D9DebugLogMatrix(const char* name, D3DXMATRIX* pM); void D3D9InitLog(const char *file); void D3D9CloseLog(); void LogTrace(const char *format, ...); @@ -61,12 +62,16 @@ void LogAlw(const char *format, ...); void LogDbg(const char *color, const char *format, ...); void LogClr(const char *color, const char *format, ...); + double D3D9GetTime(); void D3D9SetTime(D3D9Time &inout, double ref); void MissingRuntimeError(); void FailedDeviceError(); void LogAttribs(DWORD attrib, DWORD w, DWORD h, LPCSTR origin); +void LogVec(D3DXVECTOR4* pM, const char* name); +void LogVec(VECTOR3* pM, const char* name); +void LogMatrix(D3DXMATRIX* pM, const char* name); #define HALT() { RuntimeError(__FILE__,__FUNCTION__,__LINE__); } diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index 651f8ed28..0c6a7a637 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -207,7 +207,7 @@ void D3D9Mesh::Null(const char *meshName /* = NULL */) MaxFace = 0; MaxVert = 0; vClass = 0; - DefShader = SHADER_NULL; + DefShader = SHADER_LEGACY; hOapiMesh = NULL; MeshFlags = 0; Flags = 0; @@ -3056,7 +3056,7 @@ void D3D9Mesh::RenderShadowMap(const LPD3DXMATRIX pW, const LPD3DXMATRIX pVP, in MeshShader* pShader = nullptr; - MeshShader::vs_const.mVP = pVP ? *pVP : FMATRIX4::Identity(); + MeshShader::vs_const.mVP = pVP ? *pVP : FMATRIX4(); D3DXMatrixIdentity(MeshShader::vs_const.mW); diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index 9737871e8..c89bd91c1 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -1821,7 +1821,7 @@ void Scene::clbkRenderMainScene() if (Config->ShadowMapMode >= 1) { // Get shadowing params for vFocus - SMapInput smi = vFocus->GetSMapRenderData(); + SMapInput smi = vFocus->GetSMapRenderData(vVessel::SMI::Visual); pExtShdMap = RenderObjectsInShadow(&smi, RenderList, pSketch); } @@ -1832,7 +1832,7 @@ void Scene::clbkRenderMainScene() { // Don't render more shadows if debug controls are open to keep pExtShdMap valid - SMapInput smf = vFocus->GetSMapRenderData(); + SMapInput smf = vFocus->GetSMapRenderData(vVessel::SMI::Visual); list RenderThese; // Select objects to render with shadow map @@ -1845,7 +1845,7 @@ void Scene::clbkRenderMainScene() while (RenderThese.size()) { - SMapInput smi = RenderThese.front()->GetSMapRenderData(); + SMapInput smi = RenderThese.front()->GetSMapRenderData(vVessel::SMI::Visual); RenderObjectsInShadow(&smi, RenderThese, pSketch); } } @@ -1930,8 +1930,8 @@ void Scene::clbkRenderMainScene() // render the internal parts of the focus object in a separate render pass // ------------------------------------------------------------------------------------------------------- - if (oapiCameraInternal() && vFocus) { - + if (oapiCameraInternal() && vFocus && (oapiCockpitMode() == COCKPIT_VIRTUAL)) + { // switch cockpit lights on, external-only lights off // if (bLocalLight) { @@ -2596,7 +2596,7 @@ D3DXCOLOR Scene::GetSunDiffColor() // =========================================================================================== // -int Scene::RenderShadowMap(SMapInput* smi, SHADOWMAP *sm, std::list& Casters, bool bInternal) +int Scene::RenderShadowMap(SMapInput* smi, SHADOWMAP *sm, std::list& Casters, bool bInterior) { assert(sm->tp != SHADOWMAP::sMapType::Cascaded); @@ -2656,13 +2656,16 @@ int Scene::RenderShadowMap(SMapInput* smi, SHADOWMAP *sm, std::list& C sm->mVP[0] = sm->mLVP; + WORD Pass = RENDERPASS_SHADOWMAP; + if (sm->tp == SHADOWMAP::sMapType::SingleLod) // Manual LOD selection { + Pass = RENDERPASS_VC_SHADOWMAP; sm->psShmRT[0]->GetDesc(&desc); sm->lod = 0; sm->size = desc.Width; auto psDS = GetDepthStencilMatch(sm->psShmRT[0]); - gc->PushRenderTarget(sm->psShmRT[0], psDS, RENDERPASS_SHADOWMAP); + gc->PushRenderTarget(sm->psShmRT[0], psDS, Pass); } else // Automatic LOD selection { @@ -2672,7 +2675,7 @@ int Scene::RenderShadowMap(SMapInput* smi, SHADOWMAP *sm, std::list& C sm->psShmRT[lod]->GetDesc(&desc); sm->lod = lod; sm->size = desc.Width; - gc->PushRenderTarget(sm->psShmRT[lod], psShmDS[lod], RENDERPASS_SHADOWMAP); + gc->PushRenderTarget(sm->psShmRT[lod], psShmDS[lod], Pass); } sm->bValid = true; @@ -2683,14 +2686,14 @@ int Scene::RenderShadowMap(SMapInput* smi, SHADOWMAP *sm, std::list& C // render the vessel objects -------------------------------- // - BeginPass(RENDERPASS_SHADOWMAP); + BeginPass(Pass); for (auto vV : Casters) { if (vV == vFocus) { - if (bInternal) vV->Render(pDevice, true, sm); - vV->Render(pDevice, false, sm); + if (bInterior) vV->Render(pDevice, sm, vVessel::Render::VC); + else vV->Render(pDevice, sm, 0); } - else vV->Render(pDevice, false, sm); + else vV->Render(pDevice, sm, 0); } PopPass(); @@ -2740,11 +2743,6 @@ int Scene::RenderVCShadowMap(D3DXVECTOR3& cdir, D3DXVECTOR3& ld, std::listGetMinMaxLightDist(sm, &mnd, &mxd); - - // Compute shadow lod - //D3DXVECTOR3 bspos = vV->GetBoundingSpherePosDX(); - //float rs = viewh * rad / (tanap * D3DXVec3Length(&bspos)); - //if (rs > rsmax) rsmax = rs; } } @@ -2809,12 +2807,7 @@ int Scene::RenderVCShadowMap(D3DXVECTOR3& cdir, D3DXVECTOR3& ld, std::listRender(pDevice, true, sm); - } - else { - a->Render(pDevice, false, sm); - } + a->Render(pDevice, sm, vVessel::Render::VC | vVessel::Render::IP); } PopPass(); @@ -2841,39 +2834,29 @@ bool Scene::RenderVCProbes(vVessel* vV) { if (vV->GetInteriorCams(&InteriorCams)) { - ResetOrigin(Camera.pos); - - SMapInput smi = vV->GetSMapRenderData(); - Casters.clear(); - - if (RenderShadowMap(&smi, smSS, Casters, true) < 0) { - LogErr("Failed to render shadow map for stage-set"); - } - else { - - /*if (DebugControls::IsActive() && psStageSetDbg && vV == vFocus) { - if (DebugControls::dbgdsp == DbgDisplay::smSS) { - HR(pDevice->StretchRect(smSS->psShmRT[0], nullptr, psStageSetDbg, nullptr, D3DTEXF_POINT)); - } - } - */ - - D3D9DebugLog("Rendered SS ShadowMap for %s", vV->GetName()); - D3D9DebugLogVec("Pos ", FVECTOR4(smi.pos)); - D3D9DebugLogVec("Ld ", FVECTOR4(smi.ld)); - D3D9DebugLog("Rad %f", smi.rad); - D3D9DebugLog("Pass %u", GetRenderPass()); - D3D9DebugLog("Cams %d", int(InteriorCams.size())); - } } - else return true; // Nothing to do for this vessel, All done. + else return true; itIC = InteriorCams.cbegin(); } + if (itIC != InteriorCams.cend()) { - vV->RenderInteriorENVMap(pDevice, *itIC, smSS); + auto ec = *itIC; + VECTOR3 gp; + vV->GetInterface()->Local2Global(ec->lPos._V(), gp); + ResetOrigin(gp); + + SMapInput smi = vV->GetSMapRenderData(vVessel::SMI::VC); + Casters.clear(); + + if (RenderShadowMap(&smi, smSS, Casters, true) < 0) { + LogErr("Failed to render shadow map for stage-set"); + } + else { + vV->RenderInteriorENVMap(pDevice, ec, smSS); + } itIC++; } @@ -2967,7 +2950,9 @@ void Scene::RenderSecondaryScene(std::set &RndList, // render stage around the scene ---------------------------- // - if ((flags & SCN_STAGE) && pCT) RenderStage(pCT); + if (flags & SCN_STAGE) { + RenderStage(pCT); + } // Don't combine these if ((flags & SCN_STAGE) && (flags & SCN_PLANETS)) assert(false); @@ -2989,7 +2974,7 @@ void Scene::RenderSecondaryScene(std::set &RndList, for (auto vVes : RndList) { if (!vVes->IsActive()) continue; if (!vVes->IsVisible()) continue; - vVes->Render(pDevice); + vVes->Render(pDevice, nullptr, 0); } } @@ -3017,14 +3002,38 @@ void Scene::RenderSecondaryScene(std::set &RndList, for (DWORD n = 0; n < nstream; n++) pstream[n]->Render(pDevice); } - if (flags & SCN_VC) { - + if (flags & SCN_VC) + { + vFocus->Render(pDevice, smSS, vVessel::Render::VC | vVessel::Render::IP); } // Flags 0x20 = BaseStructures } +// =========================================================================================== +// +void Scene::RenderStageSet(const LPDIRECT3DCUBETEXTURE9 pCT) +{ + if (bLocalLight) { + ClearLocalLights(); + VESSEL* vessel = vFocus->GetInterface(); + DWORD nemitter = vessel->LightEmitterCount(); + for (DWORD j = 0; j < nemitter; j++) { + const LightEmitter* em = vessel->GetLightEmitter(j); + if ((em->GetVisibility() == LightEmitter::VIS_COCKPIT) || (em->GetVisibility() == LightEmitter::VIS_ALWAYS)) + AddLocalLight(em, vFocus); + } + } + + HR(pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xFF000000, 1.0f, 0L)); + + RenderStage(pCT); + + vFocus->Render(pDevice, smSS, vVessel::Render::VC | vVessel::Render::IP); +} + + // =========================================================================================== // Rernder a stage/set to contain some meshes. // @@ -3039,9 +3048,11 @@ void Scene::RenderStage(LPDIRECT3DCUBETEXTURE9 pCT) ShaderData.mVP = Camera.mProjView; D3DXMatrixIdentity(&ShaderData.mW); - ShaderData.mW._11 = 1e5f; - ShaderData.mW._22 = 1e5f; - ShaderData.mW._33 = 1e5f; + ShaderData.mW._11 = 1e3f; + ShaderData.mW._22 = 1e3f; + ShaderData.mW._33 = 1e3f; + + HR(pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE)); pRenderStage->ClearTextures(); pRenderStage->SetPSConstants("cbPS", &ShaderData, sizeof(ShaderData)); @@ -3801,7 +3812,6 @@ void Scene::SetCameraAperture(float ap, float as) Camera.aspect = as; float tanap = tan(ap); - float opa = 1.0f / as; float cor = sqrt(tanap * tanap + tanap * tanap * as * as); Camera.corner = atan(cor); @@ -3913,6 +3923,26 @@ void Scene::UpdateCameraFromOrbiter(DWORD dwPass) } +// =========================================================================================== +// +void Scene::CameraOffOrigin90(D3DXMATRIX *mView, FVECTOR3 pos) +{ + Camera.mView = *mView; + Camera.x = D3DXVECTOR3(Camera.mView._11, Camera.mView._21, Camera.mView._31); + Camera.y = D3DXVECTOR3(Camera.mView._12, Camera.mView._22, Camera.mView._32); + Camera.z = D3DXVECTOR3(Camera.mView._13, Camera.mView._23, Camera.mView._33); + + auto x = D3DXVECTOR3(Camera.mView._11, Camera.mView._12, Camera.mView._13); + auto y = D3DXVECTOR3(Camera.mView._21, Camera.mView._22, Camera.mView._23); + auto z = D3DXVECTOR3(Camera.mView._31, Camera.mView._32, Camera.mView._33); + + Camera.mView._14 = -D3DXVec3Dot(&x, (const D3DXVECTOR3*)&pos); + Camera.mView._24 = -D3DXVec3Dot(&y, (const D3DXVECTOR3*)&pos); + Camera.mView._34 = -D3DXVec3Dot(&z, (const D3DXVECTOR3*)&pos); + + SetCameraAperture(0.7853981634, 1.0f); +} + // =========================================================================================== // @@ -3984,7 +4014,7 @@ void Scene::SetupInternalCamera(D3DXMATRIX *mNew, VECTOR3 *gpos, double apr, dou // Something is very wrong... abort... - if (Camera.hObj_proxy == NULL || Camera.hObj_proxy == NULL || Camera.hNear == NULL) return; + if (Camera.hObj_proxy == NULL || Camera.hGravRef == NULL || Camera.hNear == NULL) return; // Camera altitude over the proxy VECTOR3 pos; MATRIX3 grot; double rad; diff --git a/OVP/D3D9Client/Scene.h b/OVP/D3D9Client/Scene.h index 1e6a45790..b4ea12ad2 100644 --- a/OVP/D3D9Client/Scene.h +++ b/OVP/D3D9Client/Scene.h @@ -123,8 +123,6 @@ class Scene { void* pUser; }; - //ENVCAMREC ecVC; - std::list InteriorCams; std::list Planets; std::list Visuals; @@ -132,8 +130,8 @@ class Scene { std::set Vessels; std::set eCamRenderList; std::set CustomCams; - std::set::const_iterator camCurrent = {}; - std::set::const_iterator vobjEnv = {}, vobjIP = {}; + std::set::const_iterator camCurrent; + std::set::const_iterator vobjEnv, vobjIP; std::list::const_iterator itIC; @@ -286,6 +284,7 @@ class Scene { /** * \brief Render a secondary scene. (Env Maps, Shadow Maps, MFD Camera Views) */ + void RenderStageSet(const LPDIRECT3DCUBETEXTURE9 pCT); void RenderSecondaryScene(std::set &RndList, std::set &AdditionalLightsList, DWORD flags = SCN_ALLEXT, const LPDIRECT3DCUBETEXTURE9 pCT = nullptr, SHADOWMAP* sm = nullptr); @@ -380,6 +379,7 @@ class Scene { // Manually initialize client's internal camera setup void SetupInternalCamera(D3DXMATRIX *mView, VECTOR3 *pos, double apr, double asp); + void CameraOffOrigin90(D3DXMATRIX* mView, FVECTOR3 pos); // Pan Camera in a mesh debugger bool CameraPan(VECTOR3 pan, double speed); diff --git a/OVP/D3D9Client/VPlanet.cpp b/OVP/D3D9Client/VPlanet.cpp index 6c55b6d1d..f3688c080 100644 --- a/OVP/D3D9Client/VPlanet.cpp +++ b/OVP/D3D9Client/VPlanet.cpp @@ -1332,8 +1332,8 @@ void vPlanet::SetupEclipse() float s = sunsize / 1e6f; float p = plnsize / 1e6f; - D3D9DebugLog("Eclipse of %s by %s Sun(%1.1fGm) %s(%1.1fGm)", - GetName(), vE->GetName(), s, vE->GetName(), p); + //D3D9DebugLog("Eclipse of %s by %s Sun(%1.1fGm) %s(%1.1fGm)", + // GetName(), vE->GetName(), s, vE->GetName(), p); } else { Eclipse.bEnable = false; diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index 9ce45f2c0..a0ee6078f 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -593,13 +593,21 @@ void vVessel::UpdateAnimations (int mshidx) // ============================================================================================ // -SMapInput vVessel::GetSMapRenderData() +SMapInput vVessel::GetSMapRenderData(SMI type, int idx) { - SMapInput sm = { - GetBoundingSpherePosDX(), - FVECTOR3(-sundir), - GetBoundingSphereRadius() - }; + SMapInput sm; D3DXVECTOR3 cpos; float rad; + + if (type == SMI::Visual) { + sm = { GetBoundingSpherePosDX(), FVECTOR3(-sundir), GetBoundingSphereRadius() }; + } + if (type == SMI::VC) { + GetVCPos(&cpos, NULL, &rad); + sm = { cpos, FVECTOR3(-sundir), rad }; + } + if (type == SMI::Mesh) { + GetMeshPosition(idx, &cpos, nullptr, &rad); + sm = { cpos, FVECTOR3(-sundir), rad }; + } return sm; } @@ -764,10 +772,24 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev) return bRet; } +// ============================================================================================ +// +bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass, const SHADOWMAP* shd) +{ + bool bCockpit = (oapiCameraInternal() && (hObj == oapiGetFocusObject())); + bool bVC = (bCockpit && (oapiCockpitMode() == COCKPIT_VIRTUAL)); + + DWORD flags = 0; + flags |= bCockpit ? Render::D2 : 0; + flags |= bVC ? Render::VC : 0; + flags |= internalpass ? Render::IP : 0; + + return Render(dev, shd, flags); +} // ============================================================================================ // -bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass, const SHADOWMAP *shd) +bool vVessel::Render(LPDIRECT3DDEVICE9 dev, const SHADOWMAP *shd, DWORD flg) { _TRACE; if (!active) return false; @@ -778,45 +800,28 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass, const SHADOWMAP * DWORD flags = *(DWORD*)gc->GetConfigParam(CFGPRM_GETDEBUGFLAGS); DWORD displ = *(DWORD*)gc->GetConfigParam(CFGPRM_GETDISPLAYMODE); - bool bCockpit = (oapiCameraInternal() && (hObj == oapiGetFocusObject())); - // render cockpit view - - bool bVC = (bCockpit && (oapiCockpitMode() == COCKPIT_VIRTUAL)); - // render virtual cockpit + bool bCockpit = (flg & Render::D2) | (flg & Render::VC); + bool bVC = (flg & Render::VC); + bool bInternal = (flg & Render::IP); if (scn->GetRenderPass() == RENDERPASS_CUSTOMCAM) bCockpit = bVC = false; // Always render exterior view for custom cams - if (scn->GetRenderPass() == RENDERPASS_ENVCAM) bCockpit = bVC = false; - // Always render exterior view for envmaps - - // if (scn->GetRenderPass() == RENDERPASS_SHADOWMAP) bCockpit = bVC = false; - // Always render exterior view for envmaps - - // if (scn->GetRenderPass() == RENDERPASS_NORMAL_DEPTH) bCockpit = bVC = false; - // Always render exterior view for envmaps - static VCHUDSPEC hudspec_; const VCHUDSPEC* hudspec = &hudspec_; static bool gotHUDSpec(false); const VCMFDSPEC* mfdspec[MAXMFD] = { NULL }; - float s = 0.0f, sr = 0.0f; - if (shd) - { - s = float(shd->size); - sr = 2.0f * shd->rad / s; - HR(D3D9Effect::FX->SetBool(D3D9Effect::eEnvMapEnable, false)); - HR(D3D9Effect::FX->SetMatrix(D3D9Effect::eLVP, shd->mLVP.toCDX())); // Cascade 0 for all - if (scn->GetRenderPass() == RENDERPASS_MAINSCENE) - D3D9DebugLog("[%s] IsValid(%d), Map=0x%X", GetName(), int(shd->IsValid()), shd->Map(0)); - } + HR(D3D9Effect::FX->SetBool(D3D9Effect::eEnvMapEnable, false)); - if (shd && shd->IsValid() && (scn->GetRenderPass() == RENDERPASS_MAINSCENE)) + if (shd && shd->IsValid()) { + float s = float(shd->size); + float sr = 2.0f * shd->rad / s; D3DXVECTOR4 sh = D3DXVECTOR4(sr, 1.0f / s, float(oapiRand()), 1.0f / shd->depth); D3DXVECTOR4 px = D3DXVECTOR4(shd->SubPx[0], shd->SubPx[1], shd->SubPx[2], 0.0f); + HR(D3D9Effect::FX->SetMatrix(D3D9Effect::eLVP, shd->mLVP.toCDX())); // Cascade 0 for all HR(D3D9Effect::FX->SetVector(D3D9Effect::eSHD, &sh)); HR(D3D9Effect::FX->SetVector(D3D9Effect::eSHDPx, &px)); HR(D3D9Effect::FX->SetBool(D3D9Effect::eShadowToggle, true)); @@ -829,7 +834,7 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass, const SHADOWMAP * // Check VC MFD screen resolutions ------------------------------------------------ // - if (bVC && internalpass) { + if (bVC && bInternal) { for (mfd = 0; mfd < MAXMFD; mfd++) gc->GetVCMFDSurface(mfd, &mfdspec[mfd]); gotHUDSpec = !!gc->GetVCHUDSurface(&hudspec); } @@ -842,12 +847,12 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass, const SHADOWMAP * MeshShader::ps_const.Cam_Z = *scn->GetCameraZ(); - // Render Exterior and Interior (VC) meshes -------------------------------------------- // - for (i=0;iGetRenderPass() != RENDERPASS_VC_SHADOWMAP) { if (vismode == 0) continue; - if (internalpass == false) { + if (bInternal == false) { if (vismode == MESHVIS_VC) continue; // Added 3-jan-2011 to prevent VC interior double rendering during exterior and interior passes if ((vismode & MESHVIS_EXTPASS) == 0 && bCockpit) continue; } if (bCockpit) { - if (internalpass && (vismode & MESHVIS_EXTPASS)) continue; + if (bInternal && (vismode & MESHVIS_EXTPASS)) continue; if (!(vismode & MESHVIS_COCKPIT)) { if ((!bVC) || (!(vismode & MESHVIS_VC))) continue; } @@ -874,26 +879,33 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass, const SHADOWMAP * } } + WORD Shader = pMesh->GetDefaultShader(); + DWORD mFlags = pMesh->MeshFlags; + D3DXMATRIX mWT; LPD3DXMATRIX pWT; - - // transform mesh - if (meshlist[i].trans) pWT = D3DXMatrixMultiply(&mWT, (const D3DXMATRIX *)meshlist[i].trans, &mWorld); + + if (meshlist[i].trans) pWT = D3DXMatrixMultiply(&mWT, (const D3DXMATRIX*)meshlist[i].trans, &mWorld); else pWT = &mWorld; - - - if (bVC && internalpass) { + + if (bVC && bInternal && (pMesh->GetDefaultShader() == SHADER_LEGACY)) { D3D9Sun local = sunLight; local.Color *= 0.5f; - meshlist[i].mesh->SetSunLight(&local); + pMesh->SetSunLight(&local); } - else meshlist[i].mesh->SetSunLight(&sunLight); + else pMesh->SetSunLight(&sunLight); - if (bVC && internalpass) { + if (bVC && bInternal) + { for (mfd=0;mfdnmesh == i) { - meshlist[i].mesh->SetMFDScreenId(mfdspec[mfd]->ngroup, 1 + mfd); + pMesh->SetMFDScreenId(mfdspec[mfd]->ngroup, 1 + mfd); + } + } + if (gotHUDSpec) { + if (hudspec->nmesh == i) { + pMesh->SetMFDScreenId(hudspec->ngroup, 0x100); } } } @@ -905,33 +917,34 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass, const SHADOWMAP * // if (scn->GetRenderPass() == RENDERPASS_VC_SHADOWMAP) { - if (meshlist[i].mesh->MeshFlags & MESHFLAG_SHADOW_VC || meshlist[i].mesh->MeshFlags & MESHFLAG_VC) - meshlist[i].mesh->RenderShadowMap(pWT, pLVP, 0, bVC); + if (mFlags & MESHFLAG_SHADOW_VC || mFlags & MESHFLAG_VC) + pMesh->RenderShadowMap(pWT, pLVP, 0, bVC); } else if (scn->GetRenderPass() == RENDERPASS_SHADOWMAP) { - meshlist[i].mesh->RenderShadowMap(pWT, pLVP, 0, bVC); + pMesh->RenderShadowMap(pWT, pLVP, 0, bVC); } else if (scn->GetRenderPass() == RENDERPASS_NORMAL_DEPTH) { - meshlist[i].mesh->RenderShadowMap(pWT, pVP, 1); + pMesh->RenderShadowMap(pWT, pVP, 1); } - else { - if (internalpass) { - auto ec = GetEnvCam(EnvCamType::Interior, 0); - meshlist[i].mesh->Render(pWT, ec, RENDER_VC); - } - else meshlist[i].mesh->Render(pWT, GetExteriorEnvMap(), RENDER_VESSEL); - } - + else + { + auto ec = GetEnvCam(EnvCamType::Interior, 0); + bool bSL = false; + if (shd) bSL = (shd->tp == SHADOWMAP::sMapType::SingleLod); - // render VC HUD and MFDs ------------------------------------------------------------------------ - // - if (scn->GetRenderPass() == RENDERPASS_MAINSCENE) { - if (bVC && internalpass && gotHUDSpec) { - if (hudspec->nmesh == i) { - meshlist[i].mesh->SetMFDScreenId(hudspec->ngroup, 0x100); + if (Shader != SHADER_LEGACY) + { + if (mFlags & MESHFLAG_VC) { + if (bSL) pMesh->Render(pWT, ec, RENDER_VESSEL); + else pMesh->Render(pWT, ec, RENDER_VC); } + else pMesh->Render(pWT, GetExteriorEnvMap(), RENDER_VESSEL); + } + else { + if (bInternal) pMesh->Render(pWT, ec, RENDER_VC); + else pMesh->Render(pWT, GetExteriorEnvMap(), RENDER_VESSEL); } } } @@ -942,7 +955,7 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, bool internalpass, const SHADOWMAP * if (scn->GetRenderPass() == RENDERPASS_MAINSCENE) { if (DebugControls::IsActive()) { if (flags&DBG_FLAGS_SELVISONLY && this != DebugControls::GetVisual()) return true; - if (flags&DBG_FLAGS_BOXES && !internalpass) { + if (flags&DBG_FLAGS_BOXES && !bInternal) { D3DXMATRIX id; D3D9Effect::RenderBoundingBox(&mWorld, D3DXMatrixIdentity(&id), &BBox.min, &BBox.max, ptr(D3DXVECTOR4(1, 0, 0, 0.75f))); } @@ -1469,7 +1482,6 @@ bool vVessel::RenderInteriorENVMap(LPDIRECT3DDEVICE9 pDev, ENVCAMREC* ec, SHADOW // Create a EnvMap if doesn't already exists -------------------------------------------------------------------- // if (!ec->pCube) { - LPDIRECT3DCUBETEXTURE9 pCube = nullptr; if (D3DXCreateCubeTexture(pDev, desc.Width, 5, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &ec->pCube) != S_OK) { LogErr("Failed to create env-cubemap for visual %s", _PTR(this)); return true; @@ -1480,32 +1492,38 @@ bool vVessel::RenderInteriorENVMap(LPDIRECT3DDEVICE9 pDev, ENVCAMREC* ec, SHADOW // Create a Irradiance map if doesn't already exists -------------------------------------------------------------------- // if (!ec->pIrrad) { - LPDIRECT3DTEXTURE9 pIrrad = nullptr; - if (D3DXCreateTexture(pDev, 128, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pIrrad) != S_OK) { + if (D3DXCreateTexture(pDev, 128, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &ec->pIrrad) != S_OK) { LogErr("Failed to create irradiance map for visual %s", _PTR(this)); return true; } - ec->pIrrad = pIrrad; } + // Render EnvMaps --------------------------------------------------------------------------------------- // std::set RndList; std::set AddLightSrc; // empty RndList.insert(this); - - // ----------------------------------------------------------------------------------------------- - // - VECTOR3 gpos; - vessel->Local2Global(ec->lPos._V(), gpos); if (ec->pCube) { + auto eStage = GetExteriorEnvMap(); + + VECTOR3 gp; + vessel->Local2Global(ec->lPos._V(), gp); + + //FVECTOR3 rpos = TransformCoord(ec->lPos, FMATRIX4(mWorld)); + //D3DXMATRIX mW, mWI; + //D3DXMatrixIdentity(&mW); + //D3DMAT_SetTranslation(&mW, &rpos._V()); + //D3DXMatrixInverse(&mWI, NULL, &mW); + // Prepare camera and scene for env map rendering scn->PushCamera(); - scn->SetupInternalCamera(NULL, &gpos, 0.7853981634, 1.0); scn->BeginPass(RENDERPASS_ENVCAM); + scn->SetCameraFrustumLimits(0.1, 3e4); + gc->PushRenderTarget(NULL, pEnvDS, RENDERPASS_ENVCAM); D3DXMATRIX mEnv; @@ -1514,18 +1532,19 @@ bool vVessel::RenderInteriorENVMap(LPDIRECT3DDEVICE9 pDev, ENVCAMREC* ec, SHADOW for (DWORD i = 0; i < 6; i++) { - HR(ec->pCube->GetCubeMapSurface(D3DCUBEMAP_FACES(ec->iSide), 0, &pSrf)); + HR(ec->pCube->GetCubeMapSurface(D3DCUBEMAP_FACES(i), 0, &pSrf)); gc->AlterRenderTarget(pSrf, pEnvDS); - EnvMapDirection(ec->iSide, &dir, &up); + EnvMapDirection(i, &dir, &up); D3DXVECTOR3 cp; D3DXVec3Cross(&cp, &up, &dir); D3DXVec3Normalize(&cp, &cp); D3DXMatrixIdentity(&mEnv); D3DMAT_FromAxis(&mEnv, &cp, &up, &dir); - - scn->SetCameraFrustumLimits(0.1, 1e4); - scn->SetupInternalCamera(&mEnv, NULL, 0.7853981634, 1.0); - scn->RenderSecondaryScene(RndList, AddLightSrc, SCN_STAGE | SCN_VC, ecDefExt.pCube, sm); + //D3DXMatrixMultiply(&mEnv, &mWI, &mEnv); + + //scn->CameraOffOrigin90(&mEnv, rpos); + scn->SetupInternalCamera(&mEnv, &gp, 0.7853981634, 1.0); + scn->RenderStageSet(eStage->pCube); SAFE_RELEASE(pSrf); } @@ -1533,11 +1552,9 @@ bool vVessel::RenderInteriorENVMap(LPDIRECT3DDEVICE9 pDev, ENVCAMREC* ec, SHADOW gc->PopRenderTargets(); scn->PopPass(); scn->PopCamera(); - - if (ec->pCube) { - scn->RenderBlurredMap(pDev, ec->pCube); - scn->IntegrateIrradiance(this, ec->pCube, ec->pIrrad); - } + + scn->RenderBlurredMap(pDev, ec->pCube); + scn->IntegrateIrradiance(this, ec->pCube, ec->pIrrad); } return true; @@ -1602,8 +1619,10 @@ ENVCAMREC* vVessel::GetEnvCam(EnvCamType ec, int idx) if (ec == EnvCamType::Exterior) return &ecDefExt; if (ec == EnvCamType::Interior) { if (idx >= MAX_INTCAM) return nullptr; - if (idx < 0) for (auto c : InteriorCams) if (c) return c; // Get any cam - else return InteriorCams[idx]; + if (idx < 0) { + for (auto c : InteriorCams) if (c) return c; // Get any cam + } + else return InteriorCams[clamp(idx, 0, MAX_INTCAM - 1)]; } if (ec == EnvCamType::Mesh) { // TODO: diff --git a/OVP/D3D9Client/VVessel.h b/OVP/D3D9Client/VVessel.h index 424a27ce6..42ef8715c 100644 --- a/OVP/D3D9Client/VVessel.h +++ b/OVP/D3D9Client/VVessel.h @@ -49,6 +49,14 @@ class vVessel: public vObject { enum Errors { NoVC, ITEMS }; // ITEMS must be last entry + enum class SMI { VC, Visual, Mesh }; + + struct Render { + static const int VC = 0x1; // Camera in VC view + static const int D2 = 0x2; // Camera in 2D panel view + static const int IP = 0x4; // Internal pass + }; + vVessel* vRoot = nullptr; /** @@ -89,7 +97,7 @@ class vVessel: public vObject { bool IntersectShadowVolume(const SMapInput* shd); bool IntersectShadowTarget(const SMapInput* shd); void GetMinMaxLightDist(const SMapInput* shd, float* mind, float* maxd); - SMapInput GetSMapRenderData(); + SMapInput GetSMapRenderData(SMI type, int idx = 0); void ReloadTextures(); @@ -129,7 +137,8 @@ class vVessel: public vObject { * in cockpit camera mode. * \sa Render(LPDIRECT3DDEVICE9) */ - bool Render (LPDIRECT3DDEVICE9 dev, bool bInternalPass, const SHADOWMAP *sm); + bool Render (LPDIRECT3DDEVICE9 dev, const SHADOWMAP *sm, DWORD flags); + bool Render(LPDIRECT3DDEVICE9 dev, bool internalpass, const SHADOWMAP* shd); bool RenderExhaust(); diff --git a/Orbitersdk/include/DrawAPI.h b/Orbitersdk/include/DrawAPI.h index 8976fe079..c9a614e87 100644 --- a/Orbitersdk/include/DrawAPI.h +++ b/Orbitersdk/include/DrawAPI.h @@ -637,10 +637,19 @@ namespace oapi { */ typedef union __declspec(align(16)) FMATRIX4 { + FMATRIX4() { - m11 = m12 = m13, m14 = m21 = m22 = m23 = m24 = m31 = m32 = m33 = m34 = m41 = m42 = m43 = m44 = 0; + m21 = m31 = m41 = m12 = m32 = m42 = 0.0f; + m13 = m23 = m43 = m14 = m24 = m34 = 0.0f; + m11 = m22 = m33 = m44 = 1.0f; + } + + + FMATRIX4(float f) { + m11 = m12 = m13, m14 = m21 = m22 = m23 = m24 = m31 = m32 = m33 = m34 = m41 = m42 = m43 = m44 = f; } + FMATRIX4(float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24, float m31, float m32, float m33, float m34, @@ -689,7 +698,8 @@ namespace oapi { void Ident() { - for (int i = 0; i < 16; i++) data[i] = 0.0; + m21 = m31 = m41 = m12 = m32 = m42 = 0.0f; + m13 = m23 = m43 = m14 = m24 = m34 = 0.0f; m11 = m22 = m33 = m44 = 1.0f; } @@ -702,11 +712,6 @@ namespace oapi { _swap(m24, m42); _swap(m34, m43); } - static FMATRIX4 Identity() { - FMATRIX4 a; - a.m11 = a.m22 = a.m33 = a.m44 = 1.0f; - return a; - } float data[16]; struct { FVECTOR4 _x, _y, _z, _p; }; From 9f4811516e0302b29554e9b8540794232407e20b Mon Sep 17 00:00:00 2001 From: jarmonik Date: Wed, 14 Feb 2024 16:05:07 +0200 Subject: [PATCH 35/42] Dynamic cockpit lighting prototype operational. --- OVP/D3D9Client/D3D9Client.h | 5 +- OVP/D3D9Client/D3D9Client.rc | 2 +- OVP/D3D9Client/D3D9Effect.cpp | 10 ++-- OVP/D3D9Client/D3D9Effect.h | 4 +- OVP/D3D9Client/DebugControls.cpp | 26 +++++++-- OVP/D3D9Client/Mesh.cpp | 26 +++++++-- OVP/D3D9Client/Scene.cpp | 27 ++++++--- OVP/D3D9Client/Scene.h | 2 +- OVP/D3D9Client/VVessel.cpp | 55 +++++++++++++++--- OVP/D3D9Client/resource.h | 1 + OVP/D3D9Client/shaders/BakedVC.fx | 64 +++++++++++++-------- OVP/D3D9Client/shaders/D3D9Client.fx | 6 +- OVP/D3D9Client/shaders/IrradianceInteg.hlsl | 27 +++++++-- OVP/D3D9Client/shaders/Mesh.fx | 7 +-- OVP/D3D9Client/shaders/Metalness.fx | 2 +- OVP/D3D9Client/shaders/PBR.fx | 6 +- OVP/D3D9Client/shaders/Vessel.fx | 2 +- Orbitersdk/include/VesselAPI.h | 5 +- 18 files changed, 203 insertions(+), 74 deletions(-) diff --git a/OVP/D3D9Client/D3D9Client.h b/OVP/D3D9Client/D3D9Client.h index be544ff42..a681fd76a 100644 --- a/OVP/D3D9Client/D3D9Client.h +++ b/OVP/D3D9Client/D3D9Client.h @@ -94,11 +94,14 @@ struct ENVCAMREC std::vector omitAttc = {}; std::vector omitDock = {}; + DWORD flags = 0; ///< Camera flags EnvCamType type = EnvCamType::Undefined; FVECTOR3 lPos = { 0,0,0 }; ///< Camera local position FVECTOR3 lDir = { 1,0,0 }; ///< Camera local direction (in 'PLANE' mode only) float near_clip = 0.1f; ///< Near clip-plane distance - DWORD flags = 0; ///< Camera flags + float da_curve = 0.5f; + float da_bounch = 0.38f; + float da_force = 0.055f; int mesh_idx = -1; ///< Camera is attached to a mesh int group_idx = -1; ///< Camera is attached to a group int id = -1; ///< User Id, for binding diff --git a/OVP/D3D9Client/D3D9Client.rc b/OVP/D3D9Client/D3D9Client.rc index 84aa9ff82..ce11f4f67 100644 --- a/OVP/D3D9Client/D3D9Client.rc +++ b/OVP/D3D9Client/D3D9Client.rc @@ -127,7 +127,7 @@ FONT 8, "Ms Shell Dlg" AUTOCHECKBOX "FPS Limiter", IDC_DBG_FPSLIM, 205, 25, 51, 8, 0, WS_EX_LEFT PUSHBUTTON "Export textures", IDC_DBG_EXPTEX, 315, 445, 52, 14, 0, WS_EX_LEFT COMBOBOX IDC_DBG_BKLID, 11, 407, 50, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT - GROUPBOX "Baked Lights", 0, 6, 395, 175, 30, 0, WS_EX_LEFT + GROUPBOX "Baked Lights", IDC_DBG_BKLGROUP, 6, 395, 175, 30, 0, WS_EX_LEFT CONTROL "", IDC_DBG_BKLADJ, TRACKBAR_CLASS, WS_TABSTOP | TBS_BOTH | TBS_NOTICKS, 65, 405, 115, 15, WS_EX_LEFT GROUPBOX "Mesh Group Information", IDC_STATIC, 195, 295, 175, 130, 0, WS_EX_LEFT AUTOCHECKBOX "No Shadow", IDC_DBG_NOSHADOW, 200, 310, 53, 8, 0, WS_EX_LEFT diff --git a/OVP/D3D9Client/D3D9Effect.cpp b/OVP/D3D9Client/D3D9Effect.cpp index 62c299bf7..74973e473 100644 --- a/OVP/D3D9Client/D3D9Effect.cpp +++ b/OVP/D3D9Client/D3D9Effect.cpp @@ -115,10 +115,9 @@ D3DXHANDLE D3D9Effect::eRghnSw = 0; // BOOL D3DXHANDLE D3D9Effect::eShadowToggle = 0; // BOOL D3DXHANDLE D3D9Effect::eEnvMapEnable = 0; // BOOL D3DXHANDLE D3D9Effect::eInSpace = 0; // BOOL -D3DXHANDLE D3D9Effect::eNoColor = 0; // BOOL D3DXHANDLE D3D9Effect::eLightsEnabled = 0; // BOOL D3DXHANDLE D3D9Effect::eBaseBuilding = 0; // BOOL -D3DXHANDLE D3D9Effect::eCockpit = 0; +D3DXHANDLE D3D9Effect::eCockpit = 0; // BOOL D3DXHANDLE D3D9Effect::eOITEnable = 0; // BOOL // -------------------------------------------------------------- D3DXHANDLE D3D9Effect::eExposure = 0; @@ -132,6 +131,8 @@ D3DXHANDLE D3D9Effect::eAttennuate = 0; D3DXHANDLE D3D9Effect::eInScatter = 0; D3DXHANDLE D3D9Effect::eInvProxySize = 0; D3DXHANDLE D3D9Effect::eGlowConst = 0; +D3DXHANDLE D3D9Effect::eNoColor = 0; +D3DXHANDLE D3D9Effect::eVCIrrad = 0; // -------------------------------------------------------------- D3DXHANDLE D3D9Effect::eGlobalAmb = 0; D3DXHANDLE D3D9Effect::eSunAppRad = 0; @@ -433,13 +434,14 @@ void D3D9Effect::D3D9TechInit(D3D9Client *_gc, LPDIRECT3DDEVICE9 _pDev, const ch eSwitch = FX->GetParameterByName(0,"gPBRSw"); eRghnSw = FX->GetParameterByName(0,"gRghnSw"); eInSpace = FX->GetParameterByName(0,"gInSpace"); - eNoColor = FX->GetParameterByName(0,"gNoColor"); eLightsEnabled = FX->GetParameterByName(0,"gLightsEnabled"); eBaseBuilding = FX->GetParameterByName(0,"gBaseBuilding"); eCockpit = FX->GetParameterByName(0,"gCockpit"); eOITEnable = FX->GetParameterByName(0,"gOITEnable"); - // General parameters -------------------------------------------------- + // General parameters -------------------------------------------------- + eNoColor = FX->GetParameterByName(0, "gNoColor"); + eVCIrrad = FX->GetParameterByName(0, "gVCIrrad"); eSpecularMode = FX->GetParameterByName(0,"gSpecMode"); eLights = FX->GetParameterByName(0,"gLights"); eColor = FX->GetParameterByName(0,"gColor"); diff --git a/OVP/D3D9Client/D3D9Effect.h b/OVP/D3D9Client/D3D9Effect.h index e320ebcc5..27530f609 100644 --- a/OVP/D3D9Client/D3D9Effect.h +++ b/OVP/D3D9Client/D3D9Effect.h @@ -29,6 +29,7 @@ struct TexFlow { BOOL Heat; // Enable heat map BOOL Baked; // Enable pre-baked maps BOOL BakedAO; // Enable pre-baked AO map + BOOL BakedAmb; // Enable pre-baked Ambient light map }; @@ -132,7 +133,6 @@ class D3D9Effect { static D3DXHANDLE eShadowToggle; ///< BOOL static D3DXHANDLE eEnvMapEnable; ///< BOOL static D3DXHANDLE eInSpace; ///< BOOL - static D3DXHANDLE eNoColor; ///< BOOL static D3DXHANDLE eLightsEnabled;///< BOOL static D3DXHANDLE eBaseBuilding; ///< BOOL static D3DXHANDLE eCockpit; ///< BOOL @@ -142,6 +142,8 @@ class D3D9Effect { static D3DXHANDLE eTextured; ///< BOOL static D3DXHANDLE eOITEnable; ///< BOOL static D3DXHANDLE eInvProxySize; + static D3DXHANDLE eNoColor; + static D3DXHANDLE eVCIrrad; static D3DXHANDLE eMix; ///< FLOAT Auxiliary factor/multiplier static D3DXHANDLE eColor; ///< Auxiliary color input static D3DXHANDLE eFogColor; ///< Fog color input diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index 9ab4b529e..0a3e263b6 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -682,6 +682,9 @@ void OpenDlgClbk(void *context) SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)buf); } SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"Ambient"); + SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"DA.Curve"); + SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"DA.Bounch"); + SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_ADDSTRING, 0, (LPARAM)"DA.Force"); SendDlgItemMessageA(hDlg, IDC_DBG_BKLID, CB_SETCURSEL, 0, 0); @@ -1509,10 +1512,17 @@ void SetupMeshGroups() void UpdateBakedLights(float lvl) { vVessel* vV = (vVessel*)vObj; - if (vObj->Type() == OBJTP_VESSEL) { + if (vObj->Type() == OBJTP_VESSEL) + { if (bkl_id < 16 && bkl_id >= 0) vV->SetVisualProperty(VisualProp::BAKED_LIGHT, bkl_id, typeid(FVECTOR3), &FVECTOR3(lvl, lvl, lvl)); if (bkl_id == 16) vV->SetVisualProperty(VisualProp::AMBIENT, 0, typeid(FVECTOR3), &FVECTOR3(lvl, lvl, lvl)); + if (bkl_id == 17) vV->SetVisualProperty(VisualProp::DA_CURVE, 0, typeid(float), &lvl); + if (bkl_id == 18) vV->SetVisualProperty(VisualProp::DA_BOUNCH, 0, typeid(float), &lvl); + if (bkl_id == 19) vV->SetVisualProperty(VisualProp::DA_FORCE, 0, typeid(float), &lvl); + + char lbl[128]; sprintf_s(lbl, 128, "Light Controls (%1.3f)", lvl); + SetWindowText(GetDlgItem(hDlg, IDC_DBG_BKLGROUP), lbl); } } @@ -1521,11 +1531,19 @@ void UpdateBakedLights(float lvl) void UpdateLightsSlider() { FVECTOR3 val = 0.0f; + float fVal = 0.0f; vVessel* vV = (vVessel*)vObj; - if (vObj->Type() == OBJTP_VESSEL) { + if (vObj->Type() == OBJTP_VESSEL) + { if (bkl_id < 16 && bkl_id >= 0) vV->GetVisualProperty(VisualProp::BAKED_LIGHT, bkl_id, typeid(val), &val); if (bkl_id == 16) vV->GetVisualProperty(VisualProp::AMBIENT, 0, typeid(val), &val); - SendDlgItemMessage(hDlg, IDC_DBG_BKLADJ, TBM_SETPOS, 1, WORD(255.0f * val.x)); + fVal = val.x; + if (bkl_id == 17) vV->GetVisualProperty(VisualProp::DA_CURVE, 0, typeid(float), &fVal); + if (bkl_id == 18) vV->GetVisualProperty(VisualProp::DA_BOUNCH, 0, typeid(float), &fVal); + if (bkl_id == 19) vV->GetVisualProperty(VisualProp::DA_FORCE, 0, typeid(float), &fVal); + SendDlgItemMessage(hDlg, IDC_DBG_BKLADJ, TBM_SETPOS, 1, WORD(255.0f * fVal)); + char lbl[128]; sprintf_s(lbl, 128, "Light Controls (%1.3f)", fVal); + SetWindowText(GetDlgItem(hDlg, IDC_DBG_BKLGROUP), lbl); } } @@ -1594,7 +1612,7 @@ void UpdateVisual() SendDlgItemMessageA(hDlg, IDC_DBG_CONES, CB_ADDSTRING, 0, (LPARAM)"NONE"); Emitters[0] = NULL; - char line[64]; + char line[64]; strcpy(line, ""); vVessel *vV = static_cast(vObj); VESSEL *vessel = vV->GetInterface(); diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index 0c6a7a637..db7dbb9b8 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -1918,8 +1918,8 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, const ENVCAMREC* em, int iTech) // Setup Env Maps ------------------------------------------- - // - if (em && em->pCube && em->pIrrad) { + // + if (em && em->pCube && em->pIrrad) { FX->SetBool(eEnvMapEnable, true); FX->SetTexture(eEnvMapA, em->pCube); FX->SetTexture(eIrradMap, em->pIrrad); @@ -1928,6 +1928,13 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, const ENVCAMREC* em, int iTech) FX->SetBool(eEnvMapEnable, false); } + bool bNoAmbient = false; + + if (DebugControls::IsActive()) { + bNoAmbient = (flags & DBG_FLAGS_NOSUNAMB) != 0 & (flags & DBG_FLAGS_NOPLNAMB) != 0; + } + + UINT numPasses = 0; HR(FX->Begin(&numPasses, D3DXFX_DONOTSAVESTATE)); @@ -2086,6 +2093,7 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, const ENVCAMREC* em, int iTech) FC.Baked = (pComb != NULL); FC.BakedAO = (pAmbi != NULL); + FC.BakedAmb = (pSun != NULL) & !bNoAmbient; } FC.Emis = (pEmis != NULL); @@ -2175,16 +2183,18 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, const ENVCAMREC* em, int iTech) FX->SetBool(eOITEnable, bOIT); FX->SetBool(eTextured, bTextured); FX->SetBool(eFullyLit, bNoL); - FX->SetBool(eNoColor, bNoC); FX->SetBool(eSwitch, bPBR); FX->SetBool(eRghnSw, bRGH); + if (bNoC) FX->SetValue(eNoColor, &D3DXVECTOR3(1, 1, 1), sizeof(D3DXVECTOR3)); + else FX->SetValue(eNoColor, &D3DXVECTOR3(0, 0, 0), sizeof(D3DXVECTOR3)); + // Update envmap and fresnel status as required if (bRefl) { bFRS = (Grp[g].PBRStatus & 0x1E) >= 0x10; FX->SetBool(eFresnel, bFRS); if (IsReflective()) { - bENV = ((Grp[g].PBRStatus & 0x1E) >= 0xA) | (Grp[g].Shader == SHADER_METALNESS); + bENV = ((Grp[g].PBRStatus & 0x1E) >= 0xA) | (Grp[g].Shader == SHADER_METALNESS) | (Grp[g].Shader == SHADER_BAKED_VC); FX->SetBool(eEnvMapEnable, bENV); } } @@ -2514,10 +2524,12 @@ void D3D9Mesh::RenderSimplified(const LPD3DXMATRIX pW, LPDIRECT3DCUBETEXTURE9 *p FX->SetBool(eOITEnable, bOIT); FX->SetBool(eTextured, bTextured); FX->SetBool(eFullyLit, bNoL); - FX->SetBool(eNoColor, bNoC); FX->SetBool(eSwitch, bPBR); FX->SetBool(eRghnSw, bRGH); + if (bNoC) FX->SetValue(eNoColor, &D3DXVECTOR3(1, 1, 1), sizeof(D3DXVECTOR3)); + else FX->SetValue(eNoColor, &D3DXVECTOR3(0, 0, 0), sizeof(D3DXVECTOR3)); + // Update envmap and fresnel status as required // @@ -2831,9 +2843,11 @@ void D3D9Mesh::RenderFast(const LPD3DXMATRIX pW, int iTech) // FX->SetBool(eTextured, bTextured); FX->SetBool(eFullyLit, (Grp[g].UsrFlag & 0x4) != 0); - FX->SetBool(eNoColor, (Grp[g].UsrFlag & 0x10) != 0); FX->SetBool(eOITEnable, (Grp[g].UsrFlag & 0x20) != 0); + if ((Grp[g].UsrFlag & 0x10) != 0) FX->SetValue(eNoColor, &D3DXVECTOR3(1, 1, 1), sizeof(D3DXVECTOR3)); + else FX->SetValue(eNoColor, &D3DXVECTOR3(0, 0, 0), sizeof(D3DXVECTOR3)); + FX->CommitChanges(); if (bHUD) { diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index c89bd91c1..3e9169dd8 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -2851,13 +2851,20 @@ bool Scene::RenderVCProbes(vVessel* vV) SMapInput smi = vV->GetSMapRenderData(vVessel::SMI::VC); Casters.clear(); - if (RenderShadowMap(&smi, smSS, Casters, true) < 0) { - LogErr("Failed to render shadow map for stage-set"); + if (ec->bRendered) { + vV->RenderInteriorENVMap(pDevice, ec, smSS); } else { - vV->RenderInteriorENVMap(pDevice, ec, smSS); + if (RenderShadowMap(&smi, smSS, Casters, true) < 0) { + LogErr("Failed to render shadow map for stage-set"); + } + else { + vV->RenderInteriorENVMap(pDevice, ec, smSS); + return false; + } } - itIC++; + + itIC++; // Pick next camera } if (itIC == InteriorCams.cend()) // All done for this vessel @@ -3265,12 +3272,12 @@ bool Scene::RenderBlurredMap(LPDIRECT3DDEVICE9 pDev, LPDIRECT3DTEXTURE9 pSrc) // =========================================================================================== // -bool Scene::IntegrateIrradiance(vVessel *vV, LPDIRECT3DBASETEXTURE9 pIn, LPDIRECT3DTEXTURE9 pOut) +bool Scene::IntegrateIrradiance(vVessel *vV, ENVCAMREC *ec, bool bInterior) { - if (!pIn) return false; - if (pIn->GetType() != D3DRTYPE_CUBETEXTURE) return false; + if (!ec) return false; - LPDIRECT3DCUBETEXTURE9 pSrc = (LPDIRECT3DCUBETEXTURE9)pIn; + LPDIRECT3DCUBETEXTURE9 pSrc = ec->pCube; + LPDIRECT3DTEXTURE9 pOut = ec->pIrrad; if (!pIrradiance) { pIrradiance = new ImageProcessing(pDevice, "Modules/D3D9Client/IrradianceInteg.hlsl", "PSInteg"); @@ -3293,7 +3300,7 @@ bool Scene::IntegrateIrradiance(vVessel *vV, LPDIRECT3DBASETEXTURE9 pIn, LPDIREC LPDIRECT3DSURFACE9 pTmp = NULL; if (!pIrradTemp) { - if (D3DXCreateTexture(pDevice, desc.Width, desc.Height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pIrradTemp) != S_OK) { + if (D3DXCreateTexture(pDevice, desc.Width*4, desc.Height*4, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &pIrradTemp) != S_OK) { LogErr("Failed to create irradiance temp"); return false; } @@ -3308,6 +3315,8 @@ bool Scene::IntegrateIrradiance(vVessel *vV, LPDIRECT3DBASETEXTURE9 pIn, LPDIREC float Glow = float(Config->PlanetGlow); + if (bInterior) Glow = 4.0f; + pIrradiance->Activate("PSInteg"); pIrradiance->SetOutputNative(0, pTmp); pIrradiance->SetTextureNative("tCube", pSrc, IPF_LINEAR); diff --git a/OVP/D3D9Client/Scene.h b/OVP/D3D9Client/Scene.h index b4ea12ad2..a3d684698 100644 --- a/OVP/D3D9Client/Scene.h +++ b/OVP/D3D9Client/Scene.h @@ -293,7 +293,7 @@ class Scene { int RenderVCShadowMap(D3DXVECTOR3& cdir, D3DXVECTOR3& ld, std::list& Casters); bool RenderVCProbes(vVessel *vFocus); - bool IntegrateIrradiance(vVessel *vV, LPDIRECT3DBASETEXTURE9 pSrc, LPDIRECT3DTEXTURE9 pOut); + bool IntegrateIrradiance(vVessel *vV, ENVCAMREC* ec, bool bInterior); bool RenderBlurredMap(LPDIRECT3DDEVICE9 pDev, LPDIRECT3DCUBETEXTURE9 pSrc); bool RenderBlurredMap(LPDIRECT3DDEVICE9 pDev, LPDIRECT3DTEXTURE9 pSrc); void RenderMesh(DEVMESHHANDLE hMesh, const oapi::FMATRIX4 *pWorld); diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index a0ee6078f..aee6fbc65 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -937,6 +937,15 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, const SHADOWMAP *shd, DWORD flg) if (Shader != SHADER_LEGACY) { if (mFlags & MESHFLAG_VC) { + if (ec) { + float f = ec->da_force * 60.0f; + float b = ec->da_bounch * 2.0f; + float c = ec->da_curve * 3.0f; + if (scn->GetRenderPass() != RENDERPASS_MAINSCENE) + D3D9Effect::FX->SetValue(D3D9Effect::eVCIrrad, &D3DXVECTOR4(b, b, b, 1.0f), sizeof(D3DXVECTOR4)); + else + D3D9Effect::FX->SetValue(D3D9Effect::eVCIrrad, &D3DXVECTOR4(f, f, f, c), sizeof(D3DXVECTOR4)); + } if (bSL) pMesh->Render(pWT, ec, RENDER_VESSEL); else pMesh->Render(pWT, ec, RENDER_VC); } @@ -1341,7 +1350,7 @@ bool vVessel::RenderENVMap(LPDIRECT3DDEVICE9 pDev, ENVCAMREC* ec, DWORD cnt, DWO // if (!ec->pIrrad) { - if (D3DXCreateTexture(pDev, 128, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &ec->pIrrad) != S_OK) { + if (D3DXCreateTexture(pDev, 128, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &ec->pIrrad) != S_OK) { LogErr("Failed to create irradiance map for visual %s", _PTR(this)); return true; } @@ -1353,7 +1362,7 @@ bool vVessel::RenderENVMap(LPDIRECT3DDEVICE9 pDev, ENVCAMREC* ec, DWORD cnt, DWO if (ec->bRendered) { if (ec->pCube) { scn->RenderBlurredMap(pDev, ec->pCube); - scn->IntegrateIrradiance(this, ec->pCube, ec->pIrrad); + scn->IntegrateIrradiance(this, ec, false); } // TODO: Blur 2D plane map return true; @@ -1498,7 +1507,18 @@ bool vVessel::RenderInteriorENVMap(LPDIRECT3DDEVICE9 pDev, ENVCAMREC* ec, SHADOW } } - + + // Compute blur and irradiance -------------------------------------------------------------------------- + // + if (ec->bRendered) { + scn->RenderBlurredMap(pDev, ec->pCube); + scn->IntegrateIrradiance(this, ec, true); + ec->bRendered = false; + return true; + } + + + // Render EnvMaps --------------------------------------------------------------------------------------- // std::set RndList; @@ -1552,12 +1572,11 @@ bool vVessel::RenderInteriorENVMap(LPDIRECT3DDEVICE9 pDev, ENVCAMREC* ec, SHADOW gc->PopRenderTargets(); scn->PopPass(); scn->PopCamera(); - - scn->RenderBlurredMap(pDev, ec->pCube); - scn->IntegrateIrradiance(this, ec->pCube, ec->pIrrad); + + ec->bRendered = true; } - return true; + return false; } @@ -1999,6 +2018,17 @@ void vVessel::SetVisualProperty(VisualProp prp, int idx, const type_info& t, con } } + if (t == typeid(float)) + { + float* v = (float*)val; + auto ec = GetEnvCam(EnvCamType::Interior, idx); + if (ec) { + if (prp == VisualProp::DA_CURVE) ec->da_curve = *v; + if (prp == VisualProp::DA_BOUNCH) ec->da_bounch = *v; + if (prp == VisualProp::DA_FORCE) ec->da_force = *v; + } + } + oapiWriteLogV("Failed to set visual property prp=%d, type=[%s]", int(prp), t.name()); } @@ -2019,6 +2049,17 @@ bool vVessel::GetVisualProperty(VisualProp prp, int idx, const type_info& t, voi return true; } } + + if (t == typeid(float)) + { + auto ec = GetEnvCam(EnvCamType::Interior, idx); + if (ec) { + if (prp == VisualProp::DA_CURVE) *((float*)val) = ec->da_curve; + if (prp == VisualProp::DA_BOUNCH) *((float*)val) = ec->da_bounch; + if (prp == VisualProp::DA_FORCE) *((float*)val) = ec->da_force; + } + } + oapiWriteLogV("Failed to get visual property prp=%d, type=[%s]", int(prp), t.name()); return false; } diff --git a/OVP/D3D9Client/resource.h b/OVP/D3D9Client/resource.h index 6679acfad..11d445564 100644 --- a/OVP/D3D9Client/resource.h +++ b/OVP/D3D9Client/resource.h @@ -243,3 +243,4 @@ #define IDC_DBG_NOPLNAMB 3061 #define IDC_DBG_DATASRC 3062 #define IDC_DBG_NODYNSUN 3063 +#define IDC_DBG_BKLGROUP 3064 diff --git a/OVP/D3D9Client/shaders/BakedVC.fx b/OVP/D3D9Client/shaders/BakedVC.fx index 1bca1a88e..6c9b52ab3 100644 --- a/OVP/D3D9Client/shaders/BakedVC.fx +++ b/OVP/D3D9Client/shaders/BakedVC.fx @@ -17,6 +17,9 @@ float4 BakedVC_PS(float4 sc : VPOS, PBRData frg) : COLOR float3 nrmW; float3 cEmis; float4 cDiff; + float3 cBL; + float3 cBA; + float3 cBAO; float fSmth, fMetal; // ====================================================================== @@ -44,16 +47,21 @@ float4 BakedVC_PS(float4 sc : VPOS, PBRData frg) : COLOR // if (gCfg.Emis) cEmis = tex2D(EmisS, frg.tex0.xy).rgb; else cEmis = 0; + + // Load baked light emitters + // + if (gCfg.Baked) cBL = tex2D(BakedLightS, frg.tex0.xy).rgb; + else cBL = 0.0f; - float3 cBL = 0; - float3 cBS = 0; - float3 cBAO = 0; + // Load baked ambient lights + // + if (gCfg.BakedAmb) cBA = tex2D(BakedSunS, frg.tex0.xy).rgb; + else cBA = 1.0f; - if (gCfg.Baked) { - cBL = tex2D(BakedLightS, frg.tex0.xy).rgb; - cBS = tex2D(BakedSunS, frg.tex0.xy).rgb; - } + // Load baked ambient occlusion (note: gCfg.BakedAO ahouldn't be enabled at the same time with gCfg.BakedAmb) + // if (gCfg.BakedAO) cBAO = tex2D(BakedAOS, frg.tex0.xy).rgb; + else cBAO = 1.0f; @@ -87,7 +95,8 @@ float4 BakedVC_PS(float4 sc : VPOS, PBRData frg) : COLOR // ====================================================================== cDiff.a = saturate(cDiff.a * gMtrlAlpha); - if (gNoColor) cDiff.rgb = 1; + cDiff.rgb = saturate(cDiff.rgb + gNoColor.rgb); + // ====================================================================== // Some Precomputations @@ -116,29 +125,32 @@ float4 BakedVC_PS(float4 sc : VPOS, PBRData frg) : COLOR float fRgh = saturate(1.0f - fSmth); float fRgh3 = fRgh*fRgh*fRgh; -/* + + // ====================================================================== + // Sample reflections and irradiance + // ====================================================================== + #if defined(_ENVMAP) - if (gEnvMapEnable) { - // ====================================================================== - // Sample Env Map + if (gEnvMapEnable) + { SampleEnvMap(cEnv, dCN, fRgh, fMetal, rflW, nrmW); + + // Use dynamic ambient light if baked doesn't exists + if (!gCfg.BakedAmb) { + float3 cP = Paraboloidal_LVLH(IrradS, nrmW).rgb; + cBA *= pow(abs(cP), gVCIrrad.w) * cBAO * gVCIrrad.rgb; + } } - // ====================================================================== - // Sample Irradiance Map - float3 cAmbient = Paraboloidal_LVLH(IrradS, nrmW).rgb; - cAmbient *= cAmbient; - //cAmbient = saturate(cAmbient * (1.0f + 15.0f * gNightTime)); - // Apply base ambient light - cAmbient = max(cAmbient, gSun.Ambient); #else #endif - cAmbient *= (1.0f - fMetal); // No ambient for metals -*/ + + cBA *= (1.0f - fMetal); // No ambient for metals // ====================================================================== // Add vessel self-shadows // ====================================================================== + #if SHDMAP > 0 if (gCockpit) { cSun *= smoothstep(0, 0.72, ComputeShadowVC(frg.shdH, dLN, sc)); @@ -149,9 +161,11 @@ float4 BakedVC_PS(float4 sc : VPOS, PBRData frg) : COLOR #endif + // ====================================================================== // Main shader core MetalnessPS // ====================================================================== + float fD = GGX_NDF(dHN, lerp(0.01f, 1.0f, fRgh3)); float fG = SchlickBeckmanGSF(dLN, dCN, fRgh); float fR = DiffuseRetroReflectance(dLN, dCN, dLH, fRgh, fMetal); @@ -189,12 +203,16 @@ float4 BakedVC_PS(float4 sc : VPOS, PBRData frg) : COLOR // Add a faint diffuse hue for rough metals. Rough metal doesn't look good if it's totally black fA += fRgh * fMetal * 0.05f; + // Light + float3 zL = Sq(cSun * fR * dLN) + Sq(cBL) + Sq(cBA) + Sq(gVCAmbient); + // gVCAmbient is an application and debug controls controllable variable - float3 zD = cDiff.rgb * fA * LightFXSq(gMtrl.diffuse.rgb * (Sq(cSun * fR * dLN)) + Sq(gMtrl.emissive.rgb) + Sq(cBL) + Sq(cBS) + Sq(gVCAmbient)); + float3 zD = cDiff.rgb * fA * LightFXSq(gMtrl.diffuse.rgb * zL + Sq(gMtrl.emissive.rgb)); // Combine specular terms float3 zS = cS * (cSun * dLN); - + + // Combine Diffuse, Specular and Environment cDiff.rgb = zD + zS + cE; // Override material alpha to make reflections visible diff --git a/OVP/D3D9Client/shaders/D3D9Client.fx b/OVP/D3D9Client/shaders/D3D9Client.fx index d362685f4..73a6cce38 100644 --- a/OVP/D3D9Client/shaders/D3D9Client.fx +++ b/OVP/D3D9Client/shaders/D3D9Client.fx @@ -69,8 +69,9 @@ struct Flow bool Norm; // Enable normal map bool Metl; // Enable metalness map bool Heat; // Enable heat map - bool Baked; // Enable pre-baked maps + bool Baked; // Enable pre-baked local light map bool BakedAO; // Enable pre-baked AO map + bool BakedAmb; // Enable pre-baked Ambient light map }; @@ -100,10 +101,12 @@ uniform extern float4 gRadius; // PlanetRad, AtmOuterLimit, CameraR uniform extern float4 gSHD; // ShadowMap data uniform extern float4 gSHDPx; // Shadow resolution [Pixels / meter] for each cascade uniform extern float4 gSHDSubRect[3]; // Shadow cascade sub-rects +uniform extern float4 gVCIrrad; // Virtual Cockpit ambient lighting control uniform extern float3 gCameraPos; // Planet relative camera position, Unit vector uniform extern float3 gNorth; uniform extern float3 gEast; uniform extern float3 gVCAmbient; // Ambient level inside virtual cockpit +uniform extern float3 gNoColor; // No Color option. uniform extern Sun gSun; // Sun light direction uniform extern Mat gMat; // Material input structure TODO: Remove all reference to this. Use gMtrl uniform extern Mat gWater; // Water material input structure @@ -120,7 +123,6 @@ uniform extern bool gNight; // Nighttime/Daytime uniform extern bool gShadowsEnabled; // Enable shadow maps uniform extern bool gEnvMapEnable; // Enable Environment mapping uniform extern bool gInSpace; // True if a mesh is located in space -uniform extern bool gNoColor; // No color flag uniform extern bool gBaseBuilding; uniform extern bool gOITEnable; uniform extern bool gCockpit; diff --git a/OVP/D3D9Client/shaders/IrradianceInteg.hlsl b/OVP/D3D9Client/shaders/IrradianceInteg.hlsl index 3bc3b37ea..e1735db80 100644 --- a/OVP/D3D9Client/shaders/IrradianceInteg.hlsl +++ b/OVP/D3D9Client/shaders/IrradianceInteg.hlsl @@ -25,7 +25,7 @@ float3 Paraboloidal_to_World(float3 i) float4 PSInteg(float x : TEXCOORD0, float y : TEXCOORD1, float2 sc : VPOS) : COLOR { - float a = tex2D(tRandom, float2(x,y)).r * 6.283185307; + float a = tex2D(tRandom, float2(x*8,y*4)).r * 6.283185307; float2 qw = float2(x, y) * 2.0f - 1.0f; float3 vz = Paraboloidal_to_World(float3(qw.xy, (bUp ? 1 : -1))); float3 qx = normalize(cross(vz, vNr)); @@ -37,13 +37,17 @@ float4 PSInteg(float x : TEXCOORD0, float y : TEXCOORD1, float2 sc : VPOS) : COL [unroll] for (int i = 0; i < IKernelSize; i++) { float3 d = (vx*Kernel[i].x) + (vy*Kernel[i].y) + (vz*Kernel[i].z); - sum += texCUBElod(tCube, float4(d, 1)).rgb * Kernel[i].w; + float3 k = texCUBElod(tCube, float4(d, 0)).rgb; + sum += k * Kernel[i].w; } - - return float4(sqrt(sum * fIntensity * (0.7f / IKernelSize)), 1.0f); -} + sum = sum * (2.0f / IKernelSize); + sum = sum * fIntensity; + + return float4(sum, 1.0f); +} +/* float4 PSPostBlur(float x : TEXCOORD0, float y : TEXCOORD1) : COLOR { float3 color = 0; @@ -62,4 +66,17 @@ float4 PSPostBlur(float x : TEXCOORD0, float y : TEXCOORD1) : COLOR color += tex2D(tSrc, p + float2( 2, 0) * fD).rgb; color += tex2D(tSrc, p + float2(-2, 0) * fD).rgb; return float4(color * 0.07, 1); +}*/ + +float4 PSPostBlur(float x : TEXCOORD0, float y : TEXCOORD1) : COLOR +{ + float3 color = 0; + float2 p = float2(x, y); + [unroll] for (int k = -4; k < 5; k++) { + [unroll] for (int i = -4; i < 5; i++) { + color += tex2D(tSrc, p + float2(i+0.5, k+0.5) * fD).rgb; + } + } + return float4(color / 81, 1); + //return float4(color / 49, 1); } diff --git a/OVP/D3D9Client/shaders/Mesh.fx b/OVP/D3D9Client/shaders/Mesh.fx index 970908d24..ee9477438 100644 --- a/OVP/D3D9Client/shaders/Mesh.fx +++ b/OVP/D3D9Client/shaders/Mesh.fx @@ -61,10 +61,9 @@ float4 TinyMeshTechPS(MeshVS frg) : COLOR float4 cSpec = gMtrl.specular; float4 cTex = 1; - if (gTextured) { - if (gNoColor) cTex.a = tex2D(WrapS, frg.tex0.xy).a; - else cTex = tex2D(WrapS, frg.tex0.xy); - } + if (gTextured) cTex = tex2D(WrapS, frg.tex0.xy); + + cTex.rgb = saturate(cTex.rgb + gNoColor.rgb); if (gFullyLit) return float4(cTex.rgb*saturate(gMtrl.diffuse.rgb + gMtrl.emissive.rgb), cTex.a); diff --git a/OVP/D3D9Client/shaders/Metalness.fx b/OVP/D3D9Client/shaders/Metalness.fx index 268352f25..8bd0fbaf9 100644 --- a/OVP/D3D9Client/shaders/Metalness.fx +++ b/OVP/D3D9Client/shaders/Metalness.fx @@ -217,7 +217,7 @@ float4 MetalnessPS(float4 sc : VPOS, PBRData frg) : COLOR // ====================================================================== cDiff.a = saturate(cDiff.a * gMtrlAlpha); - if (gNoColor) cDiff.rgb = 1; + cDiff.rgb = saturate(cDiff.rgb + gNoColor.rgb); // ====================================================================== diff --git a/OVP/D3D9Client/shaders/PBR.fx b/OVP/D3D9Client/shaders/PBR.fx index 89127c892..febfc9f33 100644 --- a/OVP/D3D9Client/shaders/PBR.fx +++ b/OVP/D3D9Client/shaders/PBR.fx @@ -239,7 +239,7 @@ float4 PBR_PS(float4 sc : VPOS, PBRData frg) : COLOR // Special alpha only texture in use, set the .rgb to 1.0f // Used for panel background lighting in Delta Glider - if (gNoColor) cDiff.rgb = 1; + cDiff.rgb = saturate(cDiff.rgb + gNoColor.rgb); // ------------------------------------------------------------------------ cDiff.rgb *= diffBaked; // Lit the texture @@ -408,7 +408,7 @@ float4 FAST_PS(float4 sc : VPOS, FASTData frg) : COLOR if (gOITEnable) if (cDiff.a < 0.5f) clip(-1); if (gFullyLit) { - if (gNoColor) cDiff.rgb = 1; + cDiff.rgb = saturate(cDiff.rgb + gNoColor.rgb); cDiff.rgb *= saturate(gMtrl.diffuse.rgb + gMtrl.emissive.rgb); } else { @@ -422,7 +422,7 @@ float4 FAST_PS(float4 sc : VPOS, FASTData frg) : COLOR float3 cSun = saturate(gSun.Color); float dLN = saturate(-dot(gSun.Dir, nrmW)); - if (gNoColor) cDiff.rgb = 1; + cDiff.rgb = saturate(cDiff.rgb + gNoColor.rgb); // ---------------------------------------------------------------------- // Add vessel self-shadows diff --git a/OVP/D3D9Client/shaders/Vessel.fx b/OVP/D3D9Client/shaders/Vessel.fx index 7edcb2e26..b23e7b03b 100644 --- a/OVP/D3D9Client/shaders/Vessel.fx +++ b/OVP/D3D9Client/shaders/Vessel.fx @@ -116,7 +116,7 @@ float4 AdvancedPS(float4 sc : VPOS, PBRData frg) : COLOR if (dLN == 0) fSun = 0; // Special alpha only texture in use - if (gNoColor) cTex.rgb = 1; + cTex.rgb = saturate(cTex.rgb + gNoColor.rgb); // ---------------------------------------------------------------------- diff --git a/Orbitersdk/include/VesselAPI.h b/Orbitersdk/include/VesselAPI.h index 6d5d275b7..453c1b930 100644 --- a/Orbitersdk/include/VesselAPI.h +++ b/Orbitersdk/include/VesselAPI.h @@ -46,7 +46,10 @@ enum class VisualProp { BAKED_LIGHT, ///< baked light level AMBIENT, ///< ambient light level EXT_PROBE_POS, ///< Exterior probe position - CREATE_VC_PROBE ///< Virtual cockpit probe position + CREATE_VC_PROBE, ///< Virtual cockpit probe position + DA_CURVE, + DA_BOUNCH, + DA_FORCE }; // ====================================================================== From b1d4a4b7d347ad0ed14e98ad4ccdb4690c507017 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Thu, 15 Feb 2024 07:40:39 +0200 Subject: [PATCH 36/42] Made some improvements and optimizations. --- OVP/D3D9Client/D3D9Client.h | 8 ++-- OVP/D3D9Client/D3D9Config.cpp | 3 ++ OVP/D3D9Client/D3D9Config.h | 3 +- OVP/D3D9Client/Mesh.cpp | 27 +++++++------ OVP/D3D9Client/Scene.cpp | 19 ++++++--- OVP/D3D9Client/VVessel.cpp | 8 ++-- OVP/D3D9Client/shaders/IrradianceInteg.hlsl | 44 +++++++++------------ OVP/D3D9Client/shaders/Metalness.fx | 5 ++- 8 files changed, 65 insertions(+), 52 deletions(-) diff --git a/OVP/D3D9Client/D3D9Client.h b/OVP/D3D9Client/D3D9Client.h index a681fd76a..e9c7015ae 100644 --- a/OVP/D3D9Client/D3D9Client.h +++ b/OVP/D3D9Client/D3D9Client.h @@ -34,7 +34,7 @@ #include "WindowMgr.h" #define SHM_CASCADE_COUNT 3 -#define SHM_LOD_COUNT 5 +#define SHM_LOD_COUNT 6 #define PP_DEFAULT 0x1 @@ -99,9 +99,9 @@ struct ENVCAMREC FVECTOR3 lPos = { 0,0,0 }; ///< Camera local position FVECTOR3 lDir = { 1,0,0 }; ///< Camera local direction (in 'PLANE' mode only) float near_clip = 0.1f; ///< Near clip-plane distance - float da_curve = 0.5f; - float da_bounch = 0.38f; - float da_force = 0.055f; + float da_curve = 0.4f; + float da_bounch = 0.5f; + float da_force = 0.2f; int mesh_idx = -1; ///< Camera is attached to a mesh int group_idx = -1; ///< Camera is attached to a group int id = -1; ///< User Id, for binding diff --git a/OVP/D3D9Client/D3D9Config.cpp b/OVP/D3D9Client/D3D9Config.cpp index 49d5e9956..030946760 100644 --- a/OVP/D3D9Client/D3D9Config.cpp +++ b/OVP/D3D9Client/D3D9Config.cpp @@ -98,6 +98,7 @@ void D3D9Config::Reset () bAtmoQuality = 1; NoPlanetAA = 0; VCCascadeCount = 2; + ExpVCLight = 0; GFXIntensity = 0.5; GFXDistance = 0.8; @@ -196,6 +197,7 @@ bool D3D9Config::ReadParams () if (oapiReadItem_int (hFile, (char*)"ShaderCacheUse", i)) ShaderCacheUse = max(0, min(1, i)); if (oapiReadItem_int (hFile, (char*)"NoPlanetAA", i)) NoPlanetAA = max(0, min(1, i)); if (oapiReadItem_int (hFile, (char*)"VCCascadeCount", i)) VCCascadeCount = max(1, min(3, i)); + if (oapiReadItem_int (hFile, (char*)"ExperimentalVCLight", i)) ExpVCLight = max(0, min(1, i)); if (oapiReadItem_float (hFile, (char*)"OrbitalShadowMult", d)) OrbitalShadowMult = max(0.5, min(10.0, d)); if (oapiReadItem_float (hFile, (char*)"GFXIntensity", d)) GFXIntensity = max(0.0, min(1.0, d)); @@ -287,6 +289,7 @@ void D3D9Config::WriteParams () oapiWriteItem_int (hFile, (char*)"ShaderCacheUse", ShaderCacheUse); oapiWriteItem_int (hFile, (char*)"NoPlanetAA", NoPlanetAA); oapiWriteItem_int (hFile, (char*)"VCCascadeCount", VCCascadeCount); + oapiWriteItem_int (hFile, (char*)"ExperimentalVCLight", ExpVCLight); oapiWriteItem_float (hFile, (char*)"OrbitalShadowMult", OrbitalShadowMult); oapiWriteItem_float (hFile, (char*)"GFXIntensity", GFXIntensity); diff --git a/OVP/D3D9Client/D3D9Config.h b/OVP/D3D9Client/D3D9Config.h index 3759cd05a..8b5a8d201 100644 --- a/OVP/D3D9Client/D3D9Config.h +++ b/OVP/D3D9Client/D3D9Config.h @@ -97,7 +97,8 @@ class D3D9Config { int bIrradiance; int bAtmoQuality; int NoPlanetAA; ///< Disable planet surface anti-aliasing to prevent white pixels at horizon - int VCCascadeCount; + int VCCascadeCount; + int ExpVCLight; char *DebugFont; ///< Font face for debug lines (default="Fixed") char *SolCfg; ///< Solar system to use (default="Sol") double GFXIntensity; ///< Post Processing | Light glow intensity (0.0...1.0, default=0.5) diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index db7dbb9b8..987ef71a2 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -554,21 +554,24 @@ void D3D9Mesh::LoadBakedLights() } } - for (int j = 0; j < 6; j++) + if (Config->ExpVCLight == 0) { - sprintf_s(id, " baked sunlight %s", GetDirName(j, 0)); - LPDIRECT3DTEXTURE9 pTex = NatLoadSpecialTexture(Tex[i]->GetPath(), id, true); - if (pTex) { - if (BakedLights.find(i) == BakedLights.end()) ClearBake(i); - BakedLights[i].pSunAO[j] = pTex; - } - else { - sprintf_s(id, "_bs%s", GetDirName(j, 1)); + for (int j = 0; j < 6; j++) + { + sprintf_s(id, " baked sunlight %s", GetDirName(j, 0)); LPDIRECT3DTEXTURE9 pTex = NatLoadSpecialTexture(Tex[i]->GetPath(), id, true); if (pTex) { if (BakedLights.find(i) == BakedLights.end()) ClearBake(i); BakedLights[i].pSunAO[j] = pTex; } + else { + sprintf_s(id, "_bs%s", GetDirName(j, 1)); + LPDIRECT3DTEXTURE9 pTex = NatLoadSpecialTexture(Tex[i]->GetPath(), id, true); + if (pTex) { + if (BakedLights.find(i) == BakedLights.end()) ClearBake(i); + BakedLights[i].pSunAO[j] = pTex; + } + } } } } @@ -1928,11 +1931,11 @@ void D3D9Mesh::Render(const LPD3DXMATRIX pW, const ENVCAMREC* em, int iTech) FX->SetBool(eEnvMapEnable, false); } - bool bNoAmbient = false; + bool bNoAmbient = (Config->ExpVCLight == 1); - if (DebugControls::IsActive()) { + /*if (DebugControls::IsActive()) { bNoAmbient = (flags & DBG_FLAGS_NOSUNAMB) != 0 & (flags & DBG_FLAGS_NOPLNAMB) != 0; - } + }*/ diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index 3e9169dd8..2ea1ba52f 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -264,10 +264,10 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) // Create a random number table -------------------------------------------------------------------------------------------------- // - HR(D3DXCreateTexture(pDevice, 64, 64, 1, D3DUSAGE_DYNAMIC, D3DFMT_R32F, D3DPOOL_DEFAULT, &ptRandom)); + HR(D3DXCreateTexture(pDevice, 128, 128, 1, D3DUSAGE_DYNAMIC, D3DFMT_R32F, D3DPOOL_DEFAULT, &ptRandom)); D3DLOCKED_RECT rect; if (ptRandom->LockRect(0, &rect, 0, 0) == S_OK) { - for (int i = 0; i < (64 * 64); i++) ((float*)rect.pBits)[i] = oapiRand(); + for (int i = 0; i < (128 * 128); i++) ((float*)rect.pBits)[i] = oapiRand(); ptRandom->UnlockRect(0); } else LogErr("Failed to create random table"); @@ -3282,6 +3282,7 @@ bool Scene::IntegrateIrradiance(vVessel *vV, ENVCAMREC *ec, bool bInterior) if (!pIrradiance) { pIrradiance = new ImageProcessing(pDevice, "Modules/D3D9Client/IrradianceInteg.hlsl", "PSInteg"); pIrradiance->CompileShader("PSPostBlur"); + pIrradiance->CompileShader("PSPostBlurIntr"); } if (!pIrradiance->IsOK()) { @@ -3299,8 +3300,14 @@ bool Scene::IntegrateIrradiance(vVessel *vV, ENVCAMREC *ec, bool bInterior) D3DXVECTOR3 nr, up, cp; LPDIRECT3DSURFACE9 pTmp = NULL; + UINT size = bInterior ? 3 : 1; + UINT W = desc.Width * size; + UINT H = desc.Height * size; + + + if (!pIrradTemp) { - if (D3DXCreateTexture(pDevice, desc.Width*4, desc.Height*4, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &pIrradTemp) != S_OK) { + if (D3DXCreateTexture(pDevice, W, H, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &pIrradTemp) != S_OK) { LogErr("Failed to create irradiance temp"); return false; } @@ -3347,8 +3354,10 @@ bool Scene::IntegrateIrradiance(vVessel *vV, ENVCAMREC *ec, bool bInterior) // --------------------------------------------------------------------- // Post Blur // - pIrradiance->Activate("PSPostBlur"); - pIrradiance->SetFloat("fD", ptr(D3DXVECTOR2(1.0f / float(desc.Width), 1.0f / float(desc.Height))), sizeof(D3DXVECTOR2)); + if (bInterior) pIrradiance->Activate("PSPostBlurIntr"); + else pIrradiance->Activate("PSPostBlur"); + + pIrradiance->SetFloat("fD", ptr(D3DXVECTOR2(1.0f / float(W), 1.0f / float(H))), sizeof(D3DXVECTOR2)); pIrradiance->SetOutputNative(0, pOuts); pIrradiance->SetTextureNative("tSrc", pIrradTemp, IPF_POINT | IPF_WRAP); diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index aee6fbc65..41a95c8f8 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -731,7 +731,7 @@ void vVessel::BakeLights(ImageProcessing *pBaker) { auto vSun = tmul(FVECTOR4(sundir, 0), mW); if (bMustRebake) meshlist[i].mesh->BakeLights(pBaker, BakedLightsControl); - meshlist[i].mesh->BakeAO(pBaker, vSun.xyz, lvlh, maps->pIrrad); + if (Config->ExpVCLight == 0) meshlist[i].mesh->BakeAO(pBaker, vSun.xyz, lvlh, maps->pIrrad); } } } @@ -917,7 +917,7 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, const SHADOWMAP *shd, DWORD flg) // if (scn->GetRenderPass() == RENDERPASS_VC_SHADOWMAP) { - if (mFlags & MESHFLAG_SHADOW_VC || mFlags & MESHFLAG_VC) + if (mFlags & MESHFLAG_SHADOW_VC) pMesh->RenderShadowMap(pWT, pLVP, 0, bVC); } else if (scn->GetRenderPass() == RENDERPASS_SHADOWMAP) @@ -1478,7 +1478,7 @@ bool vVessel::RenderInteriorENVMap(LPDIRECT3DDEVICE9 pDev, ENVCAMREC* ec, SHADOW { if (!ec) return true; - LPDIRECT3DSURFACE9 pEnvDS = GetScene()->GetDepthStencil(256); + LPDIRECT3DSURFACE9 pEnvDS = GetScene()->GetDepthStencil(128); if (!pEnvDS) { LogErr("RenderInteriorENVMap() DS doesn't exists"); @@ -1512,7 +1512,7 @@ bool vVessel::RenderInteriorENVMap(LPDIRECT3DDEVICE9 pDev, ENVCAMREC* ec, SHADOW // if (ec->bRendered) { scn->RenderBlurredMap(pDev, ec->pCube); - scn->IntegrateIrradiance(this, ec, true); + if (Config->ExpVCLight) scn->IntegrateIrradiance(this, ec, true); ec->bRendered = false; return true; } diff --git a/OVP/D3D9Client/shaders/IrradianceInteg.hlsl b/OVP/D3D9Client/shaders/IrradianceInteg.hlsl index e1735db80..209dbd861 100644 --- a/OVP/D3D9Client/shaders/IrradianceInteg.hlsl +++ b/OVP/D3D9Client/shaders/IrradianceInteg.hlsl @@ -25,7 +25,7 @@ float3 Paraboloidal_to_World(float3 i) float4 PSInteg(float x : TEXCOORD0, float y : TEXCOORD1, float2 sc : VPOS) : COLOR { - float a = tex2D(tRandom, float2(x*8,y*4)).r * 6.283185307; + float a = tex2D(tRandom, float2(x*3,y*1.5)).r * 6.283185307; float2 qw = float2(x, y) * 2.0f - 1.0f; float3 vz = Paraboloidal_to_World(float3(qw.xy, (bUp ? 1 : -1))); float3 qx = normalize(cross(vz, vNr)); @@ -38,45 +38,39 @@ float4 PSInteg(float x : TEXCOORD0, float y : TEXCOORD1, float2 sc : VPOS) : COL [unroll] for (int i = 0; i < IKernelSize; i++) { float3 d = (vx*Kernel[i].x) + (vy*Kernel[i].y) + (vz*Kernel[i].z); float3 k = texCUBElod(tCube, float4(d, 0)).rgb; - sum += k * Kernel[i].w; + sum += k; // *Kernel[i].w; } - sum = sum * (2.0f / IKernelSize); + sum = sum * (1.0f / IKernelSize); sum = sum * fIntensity; return float4(sum, 1.0f); } -/* +// Exterior Irradiance blur +// float4 PSPostBlur(float x : TEXCOORD0, float y : TEXCOORD1) : COLOR { float3 color = 0; float2 p = float2(x, y); - color += tex2D(tSrc, p).rgb; - color += tex2D(tSrc, p + float2(0, 1)*fD).rgb; - color += tex2D(tSrc, p + float2(0, -1)*fD).rgb; - color += tex2D(tSrc, p + float2( 1, 0)*fD).rgb; - color += tex2D(tSrc, p + float2(-1, 0)*fD).rgb; - color += tex2D(tSrc, p + float2(1, 1)*fD).rgb; - color += tex2D(tSrc, p + float2(1, -1)*fD).rgb; - color += tex2D(tSrc, p + float2(-1, 1)*fD).rgb; - color += tex2D(tSrc, p + float2(-1,-1)*fD).rgb; - color += tex2D(tSrc, p + float2(0, 2) * fD).rgb; - color += tex2D(tSrc, p + float2(0, -2) * fD).rgb; - color += tex2D(tSrc, p + float2( 2, 0) * fD).rgb; - color += tex2D(tSrc, p + float2(-2, 0) * fD).rgb; - return float4(color * 0.07, 1); -}*/ + [unroll] for (int k = -2; k < 3; k++) { + [unroll] for (int i = -2; i < 3; i++) { + color += tex2D(tSrc, p + float2(i+0.5, k+0.5) * fD).rgb; + } + } + return float4(color / 25, 1); +} -float4 PSPostBlur(float x : TEXCOORD0, float y : TEXCOORD1) : COLOR +// Interior Irradiance blur +// +float4 PSPostBlurIntr(float x : TEXCOORD0, float y : TEXCOORD1) : COLOR { float3 color = 0; float2 p = float2(x, y); - [unroll] for (int k = -4; k < 5; k++) { - [unroll] for (int i = -4; i < 5; i++) { - color += tex2D(tSrc, p + float2(i+0.5, k+0.5) * fD).rgb; + [unroll] for (int k = -5; k < 6; k++) { + [unroll] for (int i = -5; i < 6; i++) { + color += tex2D(tSrc, p + float2(i + 0.5, k + 0.5) * fD).rgb; } } - return float4(color / 81, 1); - //return float4(color / 49, 1); + return float4(color / 121, 1); } diff --git a/OVP/D3D9Client/shaders/Metalness.fx b/OVP/D3D9Client/shaders/Metalness.fx index 8bd0fbaf9..82953c790 100644 --- a/OVP/D3D9Client/shaders/Metalness.fx +++ b/OVP/D3D9Client/shaders/Metalness.fx @@ -357,7 +357,10 @@ float4 MetalnessPS(float4 sc : VPOS, PBRData frg) : COLOR // Add a faint diffuse hue for rough metals. Rough metal doesn't look good if it's totally black fA += fRgh * fMetal * 0.05f; - float3 zD = cDiff.rgb * fA * LightFXSq(gMtrl.diffuse.rgb * (Sq(cSun * fR * dLN) + cDiffLocal + Sq(cAmbient)) + Sq(gMtrl.emissive.rgb)); + // Light terms + float3 zL = Sq(cSun * fR * dLN) + cDiffLocal + Sq(cAmbient); + + float3 zD = cDiff.rgb * fA * LightFXSq(gMtrl.diffuse.rgb * zL + Sq(gMtrl.emissive.rgb)); // Combine specular terms // float3 zS = cS * (cSun * dLN) + cSpec * LightFX(cSpecLocal) * 0.5f; From f58f1e787e3a35ef2c56e321378cc2ce5f67537a Mon Sep 17 00:00:00 2001 From: jarmonik Date: Fri, 16 Feb 2024 06:12:09 +0200 Subject: [PATCH 37/42] Added Debug Visualization of Virtual Cockpit click zones. --- Meshes/D3D9Box.msh | 49 +++++++++++++++++++++ OVP/D3D9Client/D3D9Client.h | 1 - OVP/D3D9Client/D3D9Client.rc | 9 ++-- OVP/D3D9Client/D3D9Effect.h | 1 + OVP/D3D9Client/DebugControls.cpp | 2 + OVP/D3D9Client/DebugControls.h | 1 + OVP/D3D9Client/Mesh.cpp | 3 ++ OVP/D3D9Client/Scene.cpp | 4 +- OVP/D3D9Client/VObject.cpp | 2 + OVP/D3D9Client/VVessel.cpp | 57 ++++++++++++++++++++++++ OVP/D3D9Client/VVessel.h | 2 + OVP/D3D9Client/resource.h | 1 + OVP/D3D9Client/shaders/Custom.hlsl | 69 +++++++++++++++++++++++++++--- Orbitersdk/include/OrbiterAPI.h | 15 +++++++ Src/Orbiter/OrbiterAPI.cpp | 5 +++ Src/Orbiter/Pane.cpp | 5 +++ Src/Orbiter/Pane.h | 1 + Src/Orbiter/VCockpit.cpp | 14 ++++++ Src/Orbiter/VCockpit.h | 8 ++++ 19 files changed, 235 insertions(+), 14 deletions(-) create mode 100644 Meshes/D3D9Box.msh diff --git a/Meshes/D3D9Box.msh b/Meshes/D3D9Box.msh new file mode 100644 index 000000000..1d57a4b98 --- /dev/null +++ b/Meshes/D3D9Box.msh @@ -0,0 +1,49 @@ +MSHX1 +GROUPS 1 +LABEL Box +MATERIAL 1 // Material.001 +GEOM 24 12 +-1.000000 1.000000 1.000000 0.000000 0.000000 1.000000 +1.000000 -1.000000 1.000000 0.000000 0.000000 1.000000 +1.000000 1.000000 1.000000 0.000000 0.000000 1.000000 +1.000000 -1.000000 1.000000 0.000000 -1.000000 0.000000 +-1.000000 -1.000000 -1.000000 0.000000 -1.000000 0.000000 +1.000000 -1.000000 -1.000000 0.000000 -1.000000 0.000000 +-1.000000 -1.000000 1.000000 -1.000000 0.000000 0.000000 +-1.000000 1.000000 -1.000000 -1.000000 0.000000 0.000000 +-1.000000 -1.000000 -1.000000 -1.000000 0.000000 0.000000 +1.000000 1.000000 -1.000000 0.000000 0.000000 -1.000000 +-1.000000 -1.000000 -1.000000 0.000000 0.000000 -1.000000 +-1.000000 1.000000 -1.000000 0.000000 0.000000 -1.000000 +1.000000 1.000000 1.000000 1.000000 0.000000 -0.000000 +1.000000 -1.000000 -1.000000 1.000000 0.000000 -0.000000 +1.000000 1.000000 -1.000000 1.000000 0.000000 -0.000000 +-1.000000 1.000000 1.000000 0.000000 1.000000 -0.000000 +1.000000 1.000000 -1.000000 0.000000 1.000000 -0.000000 +-1.000000 1.000000 -1.000000 0.000000 1.000000 -0.000000 +-1.000000 -1.000000 1.000000 0.000000 -0.000000 1.000000 +-1.000000 -1.000000 1.000000 0.000000 -1.000000 0.000000 +-1.000000 1.000000 1.000000 -1.000000 0.000000 0.000000 +1.000000 -1.000000 -1.000000 0.000000 0.000000 -1.000000 +1.000000 -1.000000 1.000000 1.000000 0.000000 0.000000 +1.000000 1.000000 1.000000 0.000000 1.000000 -0.000000 +0 1 2 +3 4 5 +6 7 8 +9 10 11 +12 13 14 +15 16 17 +0 18 1 +3 19 4 +6 20 7 +9 21 10 +12 22 13 +15 23 16 +MATERIALS 1 +Material.001 +MATERIAL Material.001 +1 1 1 1 +0 0 0 1 +0 0 0 0 1 +0 0 0 1 +TEXTURES 0 diff --git a/OVP/D3D9Client/D3D9Client.h b/OVP/D3D9Client/D3D9Client.h index e9c7015ae..97e5297a3 100644 --- a/OVP/D3D9Client/D3D9Client.h +++ b/OVP/D3D9Client/D3D9Client.h @@ -1416,7 +1416,6 @@ class D3D9Client : public GraphicsClient LPDIRECT3DSURFACE9 pDepthStencil; CD3DFramework9 * pFramework; const D3DCAPS9 * pCaps; - //FileParser * parser; std::string scenarioName; HANDLE hMainThread; WindowManager * pWM; diff --git a/OVP/D3D9Client/D3D9Client.rc b/OVP/D3D9Client/D3D9Client.rc index ce11f4f67..46ed64d52 100644 --- a/OVP/D3D9Client/D3D9Client.rc +++ b/OVP/D3D9Client/D3D9Client.rc @@ -70,7 +70,7 @@ FONT 8, "Ms Shell Dlg" GROUPBOX "Scene Debugger", IDC_STATIC, 195, 85, 173, 115, 0, WS_EX_LEFT GROUPBOX "Texture Tools", IDC_STATIC, 380, 15, 173, 151, 0, WS_EX_LEFT AUTOCHECKBOX "Selected mesh only", IDC_DBG_MSHO, 274, 226, 77, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Dual sided", IDC_DBG_DUAL, 120, 107, 49, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Dual sided", IDC_DBG_DUAL, 115, 107, 49, 8, 0, WS_EX_LEFT PUSHBUTTON "<", IDC_DBG_GRPUP, 102, 90, 9, 12, BS_CENTER, WS_EX_LEFT PUSHBUTTON ">", IDC_DBG_GRPDN, 114, 90, 9, 12, BS_CENTER, WS_EX_LEFT PUSHBUTTON "<", IDC_DBG_MSHUP, 102, 73, 9, 12, BS_CENTER, WS_EX_LEFT @@ -81,7 +81,7 @@ FONT 8, "Ms Shell Dlg" LTEXT "Speed", IDC_STATIC, 18, 58, 22, 8, SS_LEFT, WS_EX_LEFT LTEXT "Static", IDC_DBG_SPEEDDSP, 150, 58, 21, 10, SS_LEFT, WS_EX_LEFT AUTOCHECKBOX "Add ambient light", IDC_DBG_AMBIENT, 18, 127, 70, 8, 0, WS_EX_LEFT - AUTOCHECKBOX "Wireframe", IDC_DBG_WIRE, 120, 117, 48, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Wireframe", IDC_DBG_WIRE, 115, 117, 48, 8, 0, WS_EX_LEFT GROUPBOX "Material", IDC_DBG_MATGRP, 5, 230, 175, 165, 0, WS_EX_LEFT COMBOBOX IDC_DBG_MATPRP, 77, 240, 96, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT COMBOBOX IDC_DBG_DEFSHADER, 75, 177, 96, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT @@ -116,7 +116,7 @@ FONT 8, "Ms Shell Dlg" PUSHBUTTON "Reload Shader", IDC_DBG_RELOADSHD, 60, 446, 60, 14, 0, WS_EX_LEFT PUSHBUTTON "Reload Textures", IDC_DBG_RELOADTEX, 60, 430, 60, 14, 0, WS_EX_LEFT LTEXT "Texture: None", IDC_DBG_TEXTURE, 9, 347, 168, 10, SS_LEFT, WS_EX_LEFT - AUTOCHECKBOX "Pick", IDC_DBG_PICK, 120, 127, 30, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Pick", IDC_DBG_PICK, 115, 127, 30, 8, 0, WS_EX_LEFT LTEXT "Mesh: None", IDC_DBG_MESHNAME, 9, 358, 168, 10, SS_LEFT, WS_EX_LEFT LTEXT "Group Status:", IDC_DBG_GROUPSTAT, 10, 369, 170, 10, SS_LEFT, WS_EX_LEFT PUSHBUTTON "Paste", IDC_DBG_PASTE, 133, 295, 37, 14, 0, WS_EX_LEFT @@ -144,7 +144,7 @@ FONT 8, "Ms Shell Dlg" PUSHBUTTON "Unrendered", IDC_DBG_NEXT, 127, 90, 48, 12, 0, WS_EX_LEFT LTEXT "Label", IDC_STATIC, 201, 407, 18, 9, SS_LEFT, WS_EX_LEFT EDITTEXT IDC_DBG_GRPLABEL, 225, 405, 140, 12, ES_AUTOHSCROLL, WS_EX_LEFT - AUTOCHECKBOX "Exterior in VC", IDC_DBG_EXTVC, 120, 137, 58, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Exterior in VC", IDC_DBG_EXTVC, 115, 137, 58, 8, 0, WS_EX_LEFT AUTOCHECKBOX "2cm near clip distance", IDC_DBG_CLIPDIST, 18, 136, 87, 8, 0, WS_EX_LEFT LTEXT "MeshVisMode: ", IDC_DBG_VISMODE, 10, 380, 162, 9, SS_LEFT, WS_EX_LEFT AUTOCHECKBOX "Pick only current mesh", IDC_DBG_PICKCURRENT, 18, 146, 87, 8, 0, WS_EX_LEFT @@ -158,6 +158,7 @@ FONT 8, "Ms Shell Dlg" COMBOBOX IDC_DBG_DATASRC, 275, 145, 86, 15, CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_LEFT LTEXT "Probe Data Source", IDC_STATIC, 206, 147, 62, 9, SS_LEFT, WS_EX_LEFT AUTOCHECKBOX "No dynamic sunlight", IDC_DBG_NODYNSUN, 205, 184, 79, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "VC Click Zones", IDC_DBG_VCZONES, 115, 147, 60, 8, 0, WS_EX_LEFT } diff --git a/OVP/D3D9Client/D3D9Effect.h b/OVP/D3D9Client/D3D9Effect.h index 27530f609..75f062494 100644 --- a/OVP/D3D9Client/D3D9Effect.h +++ b/OVP/D3D9Client/D3D9Effect.h @@ -9,6 +9,7 @@ #define D3D9SM_SPHERE 0x01 #define D3D9SM_ARROW 0x02 +#define D3D9SM_BOX 0x03 #include "D3D9Client.h" #include diff --git a/OVP/D3D9Client/DebugControls.cpp b/OVP/D3D9Client/DebugControls.cpp index 0a3e263b6..749b8cdea 100644 --- a/OVP/D3D9Client/DebugControls.cpp +++ b/OVP/D3D9Client/DebugControls.cpp @@ -494,6 +494,7 @@ void UpdateFlags() SETFLAG(debugFlags, DBG_FLAGS_NOSUNAMB, (SendDlgItemMessageA(hDlg, IDC_DBG_NOSUNAMB, BM_GETCHECK, 0, 0) == BST_CHECKED)); SETFLAG(debugFlags, DBG_FLAGS_NOPLNAMB, (SendDlgItemMessageA(hDlg, IDC_DBG_NOPLNAMB, BM_GETCHECK, 0, 0) == BST_CHECKED)); SETFLAG(debugFlags, DBG_FLAGS_NODYNSUN, (SendDlgItemMessageA(hDlg, IDC_DBG_NODYNSUN, BM_GETCHECK, 0, 0) == BST_CHECKED)); + SETFLAG(debugFlags, DBG_FLAGS_VCZONES, (SendDlgItemMessageA(hDlg, IDC_DBG_VCZONES, BM_GETCHECK, 0, 0) == BST_CHECKED)); Config->EnableLimiter = (int)((debugFlags&DBG_FLAGS_FPSLIM)>0); } @@ -2387,6 +2388,7 @@ INT_PTR CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case IDC_DBG_NOSUNAMB: case IDC_DBG_NOPLNAMB: case IDC_DBG_NODYNSUN: + case IDC_DBG_VCZONES: UpdateFlags(); break; diff --git a/OVP/D3D9Client/DebugControls.h b/OVP/D3D9Client/DebugControls.h index 2fb3101db..e2fb00570 100644 --- a/OVP/D3D9Client/DebugControls.h +++ b/OVP/D3D9Client/DebugControls.h @@ -67,6 +67,7 @@ #define DBG_FLAGS_NOSUNAMB 0x40000 ///< Disable sun ambient effect in VC #define DBG_FLAGS_NOPLNAMB 0x80000 ///< Disable planet shine ambient effect in VC #define DBG_FLAGS_NODYNSUN 0x100000 ///< Disable dynamic sunlight +#define DBG_FLAGS_VCZONES 0x200000 ///< Display VC Click Zones /// @} diff --git a/OVP/D3D9Client/Mesh.cpp b/OVP/D3D9Client/Mesh.cpp index 987ef71a2..ce5360637 100644 --- a/OVP/D3D9Client/Mesh.cpp +++ b/OVP/D3D9Client/Mesh.cpp @@ -246,6 +246,9 @@ D3D9Mesh::D3D9Mesh(const char *fname) : D3D9Effect() LoadMeshFromHandle(hMesh); oapiDeleteMesh(hMesh); } + else { + LogErr("Failed to load [%s]", fname); + } MeshCatalog.insert(this); if (pBuf) pBuf->Map(pDev); diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index 2ea1ba52f..baa5f3237 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -191,9 +191,7 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h) // ------------------------------------------------------------------------------ // Load a mesh to create a stage // - MESHHANDLE hCubeMesh = oapiLoadMeshGlobal("D3D9Cube"); - if (!hCubeMesh) { oapiWriteLog("Failed to open D3D9Cube.msh"); DebugBreak(); } - dmCubeMesh = gc->GetDevMesh(hCubeMesh); + dmCubeMesh = (DEVMESHHANDLE) new D3D9Mesh("D3D9Cube"); pRenderStage = new ShaderClass(pDevice, "Modules/D3D9Client/Custom.hlsl", "StageVS", "StagePS", "RenderStage", ""); diff --git a/OVP/D3D9Client/VObject.cpp b/OVP/D3D9Client/VObject.cpp index d18642ba2..56b946aa1 100644 --- a/OVP/D3D9Client/VObject.cpp +++ b/OVP/D3D9Client/VObject.cpp @@ -102,8 +102,10 @@ void vObject::GlobalInit(D3D9Client *gclient) // hStockMesh[D3D9SM_ARROW] = new D3D9Mesh("D3D9Arrow"); hStockMesh[D3D9SM_SPHERE] = new D3D9Mesh("D3D9Sphere"); + hStockMesh[D3D9SM_BOX] = new D3D9Mesh("D3D9Box"); hStockMesh[D3D9SM_SPHERE]->SetDualSided(0, true); + hStockMesh[D3D9SM_BOX]->SetDualSided(0, true); } diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index 41a95c8f8..693e45a8a 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -117,8 +117,10 @@ vVessel::~vVessel () void vVessel::GlobalInit(D3D9Client *gc) { _TRACE; + auto pDevice = gc->GetDevice(); defreentrytex = SURFACE(gc->clbkLoadTexture("Reentry.dds", 0)); defexhausttex = SURFACE(gc->clbkLoadTexture("Exhaust.dds", 0)); + pRenderZone = new ShaderClass(pDevice, "Modules/D3D9Client/Custom.hlsl", "QuadVS", "QuadPS", "RenderZones", ""); } @@ -128,6 +130,7 @@ void vVessel::GlobalExit () { DELETE_SURFACE(defexhausttex); DELETE_SURFACE(defreentrytex); + SAFE_DELETE(pRenderZone); } @@ -970,6 +973,9 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, const SHADOWMAP *shd, DWORD flg) } RenderLightCone(&mWorld); + + dev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + if (flags & DBG_FLAGS_VCZONES) RenderClickZones(); } } @@ -979,6 +985,56 @@ bool vVessel::Render(LPDIRECT3DDEVICE9 dev, const SHADOWMAP *shd, DWORD flg) } +// ============================================================================================ +// +void vVessel::RenderClickZones() +{ + std::list Zones; + oapiVCGetAreaClickZones(&Zones); + + auto hPS = pRenderZone->GetPSHandle("cb"); + auto hVS = pRenderZone->GetVSHandle("cb"); + + pRenderZone->Setup(nullptr, false, 1); + + struct { + FVECTOR3 pt[4]; + FVECTOR4 color; + FMATRIX4 mW; + FMATRIX4 mVP; + BOOL bSphere; + } cb; + + cb.mW = mWorld; + cb.mVP = scn->GetProjectionViewMatrix(); + + cb.bSphere = false; + for (auto& z : Zones) + { + if (z.mode == 2) { // Quadrilateral + for (int i = 0; i < 4; i++) cb.pt[i] = z.pt[i]; + cb.color = FVECTOR4(1.0f, 1.0f, 0.0f, 1.0f); + pRenderZone->SetPSConstants(hPS, &cb, sizeof(cb)); + pRenderZone->SetVSConstants(hVS, &cb, sizeof(cb)); + hStockMesh[D3D9SM_BOX]->RenderGroup(0); + } + } + + cb.bSphere = true; + for (auto& z : Zones) + { + if (z.mode == 1) { // Spherical + cb.pt[0] = z.cnt; + cb.pt[1] = z.rad; + cb.color = FVECTOR4(0.3f, 1.0f, 1.0f, 1.0f); + pRenderZone->SetPSConstants(hPS, &cb, sizeof(cb)); + pRenderZone->SetVSConstants(hVS, &cb, sizeof(cb)); + hStockMesh[D3D9SM_SPHERE]->RenderGroup(0); + } + } +} + + // ============================================================================================ // void vVessel::RenderVectors (LPDIRECT3DDEVICE9 dev, D3D9Pad *pSkp) @@ -2333,6 +2389,7 @@ void vVessel::ReloadTextures() SurfNative * vVessel::defreentrytex = 0; SurfNative * vVessel::defexhausttex = 0; +ShaderClass* vVessel::pRenderZone = 0; // ============================================================== diff --git a/OVP/D3D9Client/VVessel.h b/OVP/D3D9Client/VVessel.h index 42ef8715c..331993149 100644 --- a/OVP/D3D9Client/VVessel.h +++ b/OVP/D3D9Client/VVessel.h @@ -152,6 +152,7 @@ class vVessel: public vObject { void RenderGrapplePoints (LPDIRECT3DDEVICE9 dev); void RenderGroundShadow (LPDIRECT3DDEVICE9 dev, OBJHANDLE hPlanet, float depth); void RenderVectors (LPDIRECT3DDEVICE9 dev, D3D9Pad *pSkp); + void RenderClickZones(); bool RenderENVMap (LPDIRECT3DDEVICE9 pDev, ENVCAMREC* ec, DWORD cnt = 2, DWORD flags = 0xFF); bool RenderInteriorENVMap(LPDIRECT3DDEVICE9 pDev, ENVCAMREC* ec, SHADOWMAP* sm); bool ProcessEnvMaps(LPDIRECT3DDEVICE9 pDev, DWORD cnt, DWORD flags); @@ -258,6 +259,7 @@ class vVessel: public vObject { float ExhaustLength; static class SurfNative *defreentrytex, *defexhausttex; + static class ShaderClass* pRenderZone; }; #endif // !__VVESSEL_H diff --git a/OVP/D3D9Client/resource.h b/OVP/D3D9Client/resource.h index 11d445564..8d2473d2f 100644 --- a/OVP/D3D9Client/resource.h +++ b/OVP/D3D9Client/resource.h @@ -244,3 +244,4 @@ #define IDC_DBG_DATASRC 3062 #define IDC_DBG_NODYNSUN 3063 #define IDC_DBG_BKLGROUP 3064 +#define IDC_DBG_VCZONES 3065 diff --git a/OVP/D3D9Client/shaders/Custom.hlsl b/OVP/D3D9Client/shaders/Custom.hlsl index d78fef48b..fd15cb10d 100644 --- a/OVP/D3D9Client/shaders/Custom.hlsl +++ b/OVP/D3D9Client/shaders/Custom.hlsl @@ -17,6 +17,17 @@ struct MESH_VERTEX { float3 tex0 : TEXCOORD0; }; +struct MData { + float4 posH : POSITION0; + float3 camW : TEXCOORD0; +}; + + + +// ================================================================================================== +// Stage-Set for renderin auxiliary camera views +// ================================================================================================== + sampler tTex; uniform extern struct { @@ -24,12 +35,6 @@ uniform extern struct { float4x4 mW; } cbPS; - -struct MData { - float4 posH : POSITION0; - float3 camW : TEXCOORD0; -}; - MData StageVS(MESH_VERTEX vrt) { MData outVS = (MData)0; @@ -44,5 +49,57 @@ float4 StagePS(MData frg) : COLOR float3 cA = texCUBElod(tTex, float4(normalize(-frg.camW), 0.0)).rgb; return float4(cA, 1); } + + + +// ================================================================================================== +// Quadrilateral VC Click Zones +// ================================================================================================== + +struct { + float3 pt[4]; + float4 color; + float4x4 mW; + float4x4 mVP; + bool bSphere; +} cb; +MData QuadVS(MESH_VERTEX vrt) +{ + MData outVS = (MData)0; + float3 pt; + float3 posL = vrt.posL; + + if (cb.bSphere) { + pt = cb.pt[0] + posL * cb.pt[1].x; + } + else { + posL = (posL + 1.0f) * 0.5f; + float3 h0 = normalize(cross(cb.pt[1] - cb.pt[0], cb.pt[2] - cb.pt[0])) * posL.z * 0.02f; + float3 p0 = lerp(cb.pt[0], cb.pt[1], posL.x); + float3 p1 = lerp(cb.pt[2], cb.pt[3], posL.x); + pt = lerp(p0, p1, posL.y) + h0; + } + float3 nrmW = mul(float4(vrt.nrmL, 0.0f), cb.mW).xyz; + float3 posW = mul(float4(pt, 1.0f), cb.mW).xyz; + outVS.posH = mul(float4(posW, 1.0f), cb.mVP); + + if (cb.bSphere) outVS.camW = 1.0f - abs(dot(normalize(posW), nrmW)) * 0.9f; + else outVS.camW = posL; + + return outVS; +} + +float4 QuadPS(MData frg) : COLOR +{ + if (cb.bSphere) { + float b = frg.camW.z; + return float4(cb.color.rgb, cb.color.a * b); + } + else { + float a = 1 - frg.camW.z; + float b = a > 0.9 ? 0.2 : a; + return float4(cb.color.rgb, cb.color.a * b); + } +} diff --git a/Orbitersdk/include/OrbiterAPI.h b/Orbitersdk/include/OrbiterAPI.h index 69bb90697..fab8e1c54 100644 --- a/Orbitersdk/include/OrbiterAPI.h +++ b/Orbitersdk/include/OrbiterAPI.h @@ -28,6 +28,7 @@ #include #include #include +#include #if defined(_MSC_VER) && (_MSC_VER < 1920 ) // Microsoft Visual Studio Version 2017 and lower #include @@ -330,6 +331,18 @@ typedef struct { float TexMixEx[MAXTEX]; ///< texture mix values } MESHGROUPEX; + +typedef struct { + union { + VECTOR3 pt[4]; + struct { + VECTOR3 cnt; + float rad; + }; + }; + int id, mode; +} VCClickZone; + /** * \ingroup defines * \defgroup surfacecaps Surface and texture attributes @@ -5870,6 +5883,8 @@ OAPIFUNC void oapiVCSetAreaClickmode_Spherical (int id, const VECTOR3 &cnt */ OAPIFUNC void oapiVCSetAreaClickmode_Quadrilateral (int id, const VECTOR3 &p1, const VECTOR3 &p2, const VECTOR3 &p3, const VECTOR3 &p4); +OAPIFUNC void oapiVCGetAreaClickZones(std::list* p_List); + /** * \brief Defines the neighbouring virtual cockpit camera positions in relation to the current * position. The user can switch to neighbour positions with Ctrl-Arrow keys. diff --git a/Src/Orbiter/OrbiterAPI.cpp b/Src/Orbiter/OrbiterAPI.cpp index 396beac0f..82101610e 100644 --- a/Src/Orbiter/OrbiterAPI.cpp +++ b/Src/Orbiter/OrbiterAPI.cpp @@ -1893,6 +1893,11 @@ DLLEXPORT void oapiVCSetAreaClickmode_Quadrilateral (int id, const VECTOR3 &p1, g_pane->SetVCAreaClickmode_Quadrilateral (id, Vector(p1.x, p1.y, p1.z), Vector(p2.x,p2.y,p2.z), Vector(p3.x,p3.y,p3.z), Vector(p4.x,p4.y,p4.z)); } +DLLEXPORT void oapiVCGetAreaClickZones(std::list* p_List) +{ + g_pane->GetVCAreaClickZones(p_List); +} + DLLEXPORT oapi::Sketchpad *oapiGetSketchpad (SURFHANDLE surf) { oapi::GraphicsClient *gc = g_pOrbiter->GetGraphicsClient(); diff --git a/Src/Orbiter/Pane.cpp b/Src/Orbiter/Pane.cpp index af3ee19e1..2079e994d 100644 --- a/Src/Orbiter/Pane.cpp +++ b/Src/Orbiter/Pane.cpp @@ -1175,6 +1175,11 @@ void Pane::SetVCAreaClickmode_Quadrilateral (int aid, const Vector &p1, const Ve } } +void Pane::GetVCAreaClickZones(std::list* p_List) +{ + if (vcockpit) vcockpit->GetClickZones(p_List); +} + Instrument::Spec Pane::GetVCMFDSpec () { Instrument::Spec spec; diff --git a/Src/Orbiter/Pane.h b/Src/Orbiter/Pane.h index 6bc1ded42..a024e8ef9 100644 --- a/Src/Orbiter/Pane.h +++ b/Src/Orbiter/Pane.h @@ -234,6 +234,7 @@ class Pane { void SetVCAreaClickmode_Quadrilateral (int id, const Vector &p1, const Vector &p2, const Vector &p3, const Vector &p4); void TriggerVCRedrawArea (int vcid, int area_id); void TriggerRedrawArea (int pid, int vcid, int area_id); + void GetVCAreaClickZones(std::list* p_List); void SetPanel2DBlink (VECTOR3 v[4]); diff --git a/Src/Orbiter/VCockpit.cpp b/Src/Orbiter/VCockpit.cpp index c6fe3b49a..60982dbaf 100644 --- a/Src/Orbiter/VCockpit.cpp +++ b/Src/Orbiter/VCockpit.cpp @@ -346,6 +346,20 @@ bool VirtualCockpit::SetClickZone_Quadrilateral (int i, return true; } +void VirtualCockpit::GetClickZones(std::list* p_List) +{ + if (!p_List) return; + for (int i = 0; i < narea; i++) { + auto& a = area[i]; + VCClickZone A; + A.id = a->id; + A.mode = a->cmode; + if (a->cmode == Area::ClickMode::CMODE_QUAD) for (int k = 0; k < 4; k++) A.pt[k] = _V(a->p[k]); + if (a->cmode == Area::ClickMode::CMODE_SPHERICAL) { A.cnt = _V(a->cnt); A.rad = a->rad; } + p_List->push_back(A); + } +} + bool VirtualCockpit::ProcessMouse (UINT event, DWORD state, int x, int y) { mstate = 0; diff --git a/Src/Orbiter/VCockpit.h b/Src/Orbiter/VCockpit.h index 8c70eea4a..f244702d2 100644 --- a/Src/Orbiter/VCockpit.h +++ b/Src/Orbiter/VCockpit.h @@ -62,6 +62,7 @@ class VirtualCockpit { bool SetClickZone_Spherical (int i, const Vector &cnt, double rad); bool SetClickZone_Quadrilateral (int i, const Vector &p1, const Vector &p2, const Vector &p3, const Vector &p4); + void GetClickZones(std::list* p_List); bool ProcessMouse (UINT event, DWORD state, int x, int y); void GetMouseState (int &idx, int &state, Vector &xs) const; @@ -78,6 +79,13 @@ class VirtualCockpit { virtual void OptionChanged(DWORD cat, DWORD item); private: + + inline VECTOR3 _V(const Vector& v) + { + VECTOR3 vec = { v.x, v.y, v.z }; + return vec; + } + inline int AreaIndex (int aid) const { for (int i = 0; i < narea; i++) if (area[i]->id == aid) return i; From 439ba619791b5ebc25688761c2bdd846019a65c3 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Sat, 17 Feb 2024 11:35:54 +0200 Subject: [PATCH 38/42] Fixed flickering local lights --- OVP/D3D9Client/D3D9Client.h | 2 +- OVP/D3D9Client/Scene.cpp | 114 ++++++++++++++---------------------- OVP/D3D9Client/Scene.h | 2 + 3 files changed, 47 insertions(+), 71 deletions(-) diff --git a/OVP/D3D9Client/D3D9Client.h b/OVP/D3D9Client/D3D9Client.h index 97e5297a3..e6f13479f 100644 --- a/OVP/D3D9Client/D3D9Client.h +++ b/OVP/D3D9Client/D3D9Client.h @@ -100,7 +100,7 @@ struct ENVCAMREC FVECTOR3 lDir = { 1,0,0 }; ///< Camera local direction (in 'PLANE' mode only) float near_clip = 0.1f; ///< Near clip-plane distance float da_curve = 0.4f; - float da_bounch = 0.5f; + float da_bounch = 0.35f; float da_force = 0.2f; int mesh_idx = -1; ///< Camera is attached to a mesh int group_idx = -1; ///< Camera is attached to a group diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index baa5f3237..6b678e944 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -1062,29 +1062,6 @@ void Scene::UpdateCamVis() bg_rgba = D3DCOLOR_RGBA ((int)(sky_color.x*255), (int)(sky_color.y*255), (int)(sky_color.z*255), 255); - // Process Local Light Sources ------------------------------------- - // - if (bLocalLight) { - - ClearLocalLights(); - - VOBJREC *pv = NULL; - for (auto pv : Visuals) { - if (!pv->vobj->IsActive()) continue; - OBJHANDLE hObj = pv->vobj->Object(); - if (oapiGetObjectType (hObj) == OBJTP_VESSEL) { - VESSEL *vessel = oapiGetVesselInterface (hObj); - DWORD nemitter = vessel->LightEmitterCount(); - for (DWORD j = 0; j < nemitter; j++) { - const LightEmitter *em = vessel->GetLightEmitter(j); - if ((em->GetVisibility() == LightEmitter::VIS_EXTERNAL) || (em->GetVisibility() == LightEmitter::VIS_ALWAYS)) - AddLocalLight(em, pv->vobj); - } - } - } - } - - // ---------------------------------------------------------------- // render solar system celestial objects (planets and moons) // we render without z-buffer, so need to distance-sort the objects @@ -1139,6 +1116,38 @@ void Scene::AddLocalLight(const LightEmitter *le, const vObject *vo) } } +// =========================================================================================== +// +void Scene::ActivateAllLocalLights(bool bInterior) +{ + if (bLocalLight) { + ClearLocalLights(); + for (auto pv : Visuals) if (pv) ActivateLocalLights(pv->vobj, bInterior); + } +} + + +// =========================================================================================== +// +void Scene::ActivateLocalLights(vObject *vO, bool bInterior) +{ + if (!vO) return; + if (!vO->IsActive()) return; + if (vO->Type() == OBJTP_VESSEL) { + VESSEL* vessel = ((vVessel*)vO)->GetInterface(); + DWORD nemitter = vessel->LightEmitterCount(); + for (DWORD j = 0; j < nemitter; j++) { + const LightEmitter* em = vessel->GetLightEmitter(j); + if (em->GetVisibility() == LightEmitter::VIS_ALWAYS) AddLocalLight(em, vO); + else { + if ((em->GetVisibility() == LightEmitter::VIS_COCKPIT) && bInterior) AddLocalLight(em, vO); + if ((em->GetVisibility() == LightEmitter::VIS_EXTERNAL) && !bInterior) AddLocalLight(em, vO); + } + } + } +} + + // =========================================================================================== // void Scene::ComputeLocalLightsVisibility() @@ -1302,6 +1311,7 @@ void Scene::clbkRenderMainScene() D3D9SetTime(D3D9Stats.Timer.CamVis, scene_time); UpdateCamVis(); + ActivateAllLocalLights(false); set Active; for (auto v : Vessels) if (v->IsActive()) Active.insert(v); @@ -1466,6 +1476,7 @@ void Scene::clbkRenderMainScene() // --------------------------------------------------------------------------------------------- ComputeLocalLightsVisibility(); + ActivateAllLocalLights(false); // ------------------------------------------------------------------------------------------------------- @@ -1930,18 +1941,9 @@ void Scene::clbkRenderMainScene() if (oapiCameraInternal() && vFocus && (oapiCockpitMode() == COCKPIT_VIRTUAL)) { - // switch cockpit lights on, external-only lights off - // - if (bLocalLight) { - ClearLocalLights(); - VESSEL *vessel = oapiGetFocusInterface(); - DWORD nemitter = vessel->LightEmitterCount(); - for (DWORD j = 0; j < nemitter; j++) { - const LightEmitter *em = vessel->GetLightEmitter(j); - if ((em->GetVisibility() == LightEmitter::VIS_COCKPIT) || (em->GetVisibility() == LightEmitter::VIS_ALWAYS)) - AddLocalLight(em, vFocus); - } - } + // Activate local lights for interior + ClearLocalLights(); + ActivateLocalLights(vFocus, true); pDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0L); // clear z-buffer @@ -2913,36 +2915,16 @@ void Scene::RenderSecondaryScene(std::set &RndList, // Process Local Light Sources ------------------------------------- // And toggle external lights on // - if (bLocalLight) { - - ClearLocalLights(); - + if (bLocalLight) + { + ClearLocalLights(); for (auto vVes : RndList) { - if (!vVes->IsActive()) continue; - VESSEL *vessel = vVes->GetInterface(); - DWORD nemitter = vessel->LightEmitterCount(); - for (DWORD j = 0; j < nemitter; j++) { - const LightEmitter *em = vessel->GetLightEmitter(j); - if (flags & SCN_VC) - if ((em->GetVisibility() == LightEmitter::VIS_COCKPIT) || (em->GetVisibility() == LightEmitter::VIS_ALWAYS)) AddLocalLight(em, vVes); - else - if ((em->GetVisibility() == LightEmitter::VIS_EXTERNAL) || (em->GetVisibility() == LightEmitter::VIS_ALWAYS)) AddLocalLight(em, vVes); - } + ActivateLocalLights(vVes, (flags && SCN_VC) != 0); } - for (auto vVes : LightsList) { if (!vVes->IsActive()) continue; if (RndList.count(vVes)) continue; // Already included skip it - VESSEL *vessel = vVes->GetInterface(); - DWORD nemitter = vessel->LightEmitterCount(); - for (DWORD j = 0; j < nemitter; j++) { - const LightEmitter *em = vessel->GetLightEmitter(j); - if (flags & SCN_VC) - if ((em->GetVisibility() == LightEmitter::VIS_COCKPIT) || (em->GetVisibility() == LightEmitter::VIS_ALWAYS)) AddLocalLight(em, vVes); - else - if ((em->GetVisibility() == LightEmitter::VIS_EXTERNAL) || (em->GetVisibility() == LightEmitter::VIS_ALWAYS)) AddLocalLight(em, vVes); - - } + ActivateLocalLights(vVes, (flags && SCN_VC) != 0); } } @@ -3020,16 +3002,8 @@ void Scene::RenderSecondaryScene(std::set &RndList, // void Scene::RenderStageSet(const LPDIRECT3DCUBETEXTURE9 pCT) { - if (bLocalLight) { - ClearLocalLights(); - VESSEL* vessel = vFocus->GetInterface(); - DWORD nemitter = vessel->LightEmitterCount(); - for (DWORD j = 0; j < nemitter; j++) { - const LightEmitter* em = vessel->GetLightEmitter(j); - if ((em->GetVisibility() == LightEmitter::VIS_COCKPIT) || (em->GetVisibility() == LightEmitter::VIS_ALWAYS)) - AddLocalLight(em, vFocus); - } - } + ClearLocalLights(); + ActivateLocalLights(vFocus, true); HR(pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xFF000000, 1.0f, 0L)); diff --git a/OVP/D3D9Client/Scene.h b/OVP/D3D9Client/Scene.h index a3d684698..7f0b03a18 100644 --- a/OVP/D3D9Client/Scene.h +++ b/OVP/D3D9Client/Scene.h @@ -452,6 +452,8 @@ class Scene { void RenderGlares(); private: + void ActivateLocalLights(vObject* vO, bool bInterior); + void ActivateAllLocalLights(bool bInterior); void ComputeLocalLightsVisibility(); DWORD GetActiveParticleEffectCount(); float ComputeNearClipPlane(); From d1c156639e3796481353d7e949c3f6a66d7fea3f Mon Sep 17 00:00:00 2001 From: jarmonik Date: Sun, 18 Feb 2024 13:26:08 +0200 Subject: [PATCH 39/42] Some small fixes. --- OVP/D3D9Client/Scene.cpp | 40 ++++++++++++++++++++++++-------------- OVP/D3D9Client/VVessel.cpp | 19 ++++++++++-------- OVP/D3D9Client/VVessel.h | 2 +- Src/Orbiter/VCockpit.h | 6 ------ Src/Orbiter/Vecmat.h | 10 ++++++++++ 5 files changed, 47 insertions(+), 30 deletions(-) diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index 6b678e944..f92904986 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -1830,8 +1830,11 @@ void Scene::clbkRenderMainScene() if (Config->ShadowMapMode >= 1) { // Get shadowing params for vFocus - SMapInput smi = vFocus->GetSMapRenderData(vVessel::SMI::Visual); - pExtShdMap = RenderObjectsInShadow(&smi, RenderList, pSketch); + SMapInput smi; + if (vFocus->GetSMapRenderData(vVessel::SMI::Visual, 0, &smi)) { + pExtShdMap = RenderObjectsInShadow(&smi, RenderList, pSketch); + } + else pExtShdMap = nullptr; } @@ -1841,7 +1844,9 @@ void Scene::clbkRenderMainScene() { // Don't render more shadows if debug controls are open to keep pExtShdMap valid - SMapInput smf = vFocus->GetSMapRenderData(vVessel::SMI::Visual); + SMapInput smf; + vFocus->GetSMapRenderData(vVessel::SMI::Visual, 0, &smf); + list RenderThese; // Select objects to render with shadow map @@ -1854,8 +1859,10 @@ void Scene::clbkRenderMainScene() while (RenderThese.size()) { - SMapInput smi = RenderThese.front()->GetSMapRenderData(vVessel::SMI::Visual); - RenderObjectsInShadow(&smi, RenderThese, pSketch); + SMapInput smi; + if (RenderThese.front()->GetSMapRenderData(vVessel::SMI::Visual, 0, &smi)) { + RenderObjectsInShadow(&smi, RenderThese, pSketch); + } } } @@ -2848,19 +2855,22 @@ bool Scene::RenderVCProbes(vVessel* vV) vV->GetInterface()->Local2Global(ec->lPos._V(), gp); ResetOrigin(gp); - SMapInput smi = vV->GetSMapRenderData(vVessel::SMI::VC); - Casters.clear(); + SMapInput smi; - if (ec->bRendered) { - vV->RenderInteriorENVMap(pDevice, ec, smSS); - } - else { - if (RenderShadowMap(&smi, smSS, Casters, true) < 0) { - LogErr("Failed to render shadow map for stage-set"); + if (vV->GetSMapRenderData(vVessel::SMI::VC, 0, &smi)) + { + if (ec->bRendered) { + vV->RenderInteriorENVMap(pDevice, ec, smSS); } else { - vV->RenderInteriorENVMap(pDevice, ec, smSS); - return false; + Casters.clear(); + if (RenderShadowMap(&smi, smSS, Casters, true) < 0) { + LogErr("Failed to render shadow map for stage-set"); + } + else { + vV->RenderInteriorENVMap(pDevice, ec, smSS); + return false; + } } } diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index 693e45a8a..95c6db73d 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -596,22 +596,25 @@ void vVessel::UpdateAnimations (int mshidx) // ============================================================================================ // -SMapInput vVessel::GetSMapRenderData(SMI type, int idx) +bool vVessel::GetSMapRenderData(SMI type, int idx, SMapInput *sm) { - SMapInput sm; D3DXVECTOR3 cpos; float rad; + D3DXVECTOR3 cpos; float rad; if (type == SMI::Visual) { - sm = { GetBoundingSpherePosDX(), FVECTOR3(-sundir), GetBoundingSphereRadius() }; + *sm = { GetBoundingSpherePosDX(), FVECTOR3(-sundir), GetBoundingSphereRadius() }; + return true; } if (type == SMI::VC) { - GetVCPos(&cpos, NULL, &rad); - sm = { cpos, FVECTOR3(-sundir), rad }; + bool bRet = GetVCPos(&cpos, NULL, &rad); + *sm = { cpos, FVECTOR3(-sundir), rad }; + return bRet; } if (type == SMI::Mesh) { - GetMeshPosition(idx, &cpos, nullptr, &rad); - sm = { cpos, FVECTOR3(-sundir), rad }; + bool bRet = GetMeshPosition(idx, &cpos, nullptr, &rad); + *sm = { cpos, FVECTOR3(-sundir), rad }; + return bRet; } - return sm; + return false; } // ============================================================================================ diff --git a/OVP/D3D9Client/VVessel.h b/OVP/D3D9Client/VVessel.h index 331993149..6177e2e1e 100644 --- a/OVP/D3D9Client/VVessel.h +++ b/OVP/D3D9Client/VVessel.h @@ -97,7 +97,7 @@ class vVessel: public vObject { bool IntersectShadowVolume(const SMapInput* shd); bool IntersectShadowTarget(const SMapInput* shd); void GetMinMaxLightDist(const SMapInput* shd, float* mind, float* maxd); - SMapInput GetSMapRenderData(SMI type, int idx = 0); + bool GetSMapRenderData(SMI type, int idx, SMapInput* sm); void ReloadTextures(); diff --git a/Src/Orbiter/VCockpit.h b/Src/Orbiter/VCockpit.h index f244702d2..561a4a2b1 100644 --- a/Src/Orbiter/VCockpit.h +++ b/Src/Orbiter/VCockpit.h @@ -80,12 +80,6 @@ class VirtualCockpit { private: - inline VECTOR3 _V(const Vector& v) - { - VECTOR3 vec = { v.x, v.y, v.z }; - return vec; - } - inline int AreaIndex (int aid) const { for (int i = 0; i < narea; i++) if (area[i]->id == aid) return i; diff --git a/Src/Orbiter/Vecmat.h b/Src/Orbiter/Vecmat.h index cf1179f53..74446cfea 100644 --- a/Src/Orbiter/Vecmat.h +++ b/Src/Orbiter/Vecmat.h @@ -1,12 +1,15 @@ // Copyright (c) Martin Schweiger // Licensed under the MIT License +#define OAPI_IMPLEMENTATION + #ifndef __VECMAT_H #define __VECMAT_H #include #include #include +#include // ======================================================================= // Some useful constants @@ -167,6 +170,13 @@ class Vector { }; }; + +inline VECTOR3 _V(const Vector& v) +{ + return { v.x, v.y, v.z }; +} + + // ======================================================================= // class Matrix From 6c25b598b3e2b2c73153a40ff420414be6df050b Mon Sep 17 00:00:00 2001 From: jarmonik Date: Sun, 18 Feb 2024 13:42:14 +0200 Subject: [PATCH 40/42] Fixed build errors --- Src/Orbiter/VCockpit.cpp | 13 +++++++++++-- Src/Orbiter/Vecmat.h | 7 ------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Src/Orbiter/VCockpit.cpp b/Src/Orbiter/VCockpit.cpp index 60982dbaf..c565967e1 100644 --- a/Src/Orbiter/VCockpit.cpp +++ b/Src/Orbiter/VCockpit.cpp @@ -354,8 +354,17 @@ void VirtualCockpit::GetClickZones(std::list* p_List) VCClickZone A; A.id = a->id; A.mode = a->cmode; - if (a->cmode == Area::ClickMode::CMODE_QUAD) for (int k = 0; k < 4; k++) A.pt[k] = _V(a->p[k]); - if (a->cmode == Area::ClickMode::CMODE_SPHERICAL) { A.cnt = _V(a->cnt); A.rad = a->rad; } + if (a->cmode == Area::ClickMode::CMODE_QUAD) for (int k = 0; k < 4; k++) { + A.pt[k].x = a->p[k].x; + A.pt[k].y = a->p[k].y; + A.pt[k].z = a->p[k].z; + } + if (a->cmode == Area::ClickMode::CMODE_SPHERICAL) { + A.cnt.x = a->cnt.x; + A.cnt.y = a->cnt.y; + A.cnt.z = a->cnt.z; + A.rad = a->rad; + } p_List->push_back(A); } } diff --git a/Src/Orbiter/Vecmat.h b/Src/Orbiter/Vecmat.h index 74446cfea..1086466b5 100644 --- a/Src/Orbiter/Vecmat.h +++ b/Src/Orbiter/Vecmat.h @@ -9,7 +9,6 @@ #include #include #include -#include // ======================================================================= // Some useful constants @@ -171,12 +170,6 @@ class Vector { }; -inline VECTOR3 _V(const Vector& v) -{ - return { v.x, v.y, v.z }; -} - - // ======================================================================= // class Matrix From 3c2779ba8b4b720fbac4944c1633468ade347d4f Mon Sep 17 00:00:00 2001 From: jarmonik Date: Fri, 24 Jan 2025 04:36:51 +0200 Subject: [PATCH 41/42] Fixing merge errors --- OVP/D3D9Client/D3D9Client.h | 4 ++-- OVP/D3D9Client/Scene.cpp | 18 ++++++++++-------- OVP/D3D9Client/Scene.h | 4 ++-- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/OVP/D3D9Client/D3D9Client.h b/OVP/D3D9Client/D3D9Client.h index c912c1540..b651c3013 100644 --- a/OVP/D3D9Client/D3D9Client.h +++ b/OVP/D3D9Client/D3D9Client.h @@ -222,8 +222,8 @@ extern _D3D9Stats D3D9Stats; extern bool bFreeze; extern bool bFreezeEnable; extern bool bFreezeRenderAll; -extern DWORD uCurrentMesh; -extern class vObject* pCurrentVisual; +extern DWORD g_uCurrentMesh; +extern class vObject* g_pCurrentVisual; extern set MeshCatalog; extern set SurfaceCatalog; extern IDirect3D9* g_pD3DObject; diff --git a/OVP/D3D9Client/Scene.cpp b/OVP/D3D9Client/Scene.cpp index 2dfe0e5de..708e41a42 100644 --- a/OVP/D3D9Client/Scene.cpp +++ b/OVP/D3D9Client/Scene.cpp @@ -1828,10 +1828,9 @@ void Scene::clbkRenderMainScene() D3D9Effect::UpdateEffectCamera(Camera.hObj_proxy); - Resolve These - auto RenderMarkers = RenderList - //D3D9Pad* pSketch = GetPooledSketchpad(SKETCHPAD_LABELS); - //m_celSphere->EnsureMarkerDrawingContext((oapi::Sketchpad**)&pSketch, 0, m_celSphere->MarkerColor(0), m_celSphere->MarkerPen(0)); + auto RenderMarkers = RenderList; + D3D9Pad* pSketch = GetPooledSketchpad(SKETCHPAD_LABELS); + m_celSphere->EnsureMarkerDrawingContext((oapi::Sketchpad**)&pSketch, 0, m_celSphere->MarkerColor(0), m_celSphere->MarkerPen(0)); // Render the vessels inside the shadows ( Phase 1 ) ================================ @@ -1885,11 +1884,10 @@ void Scene::clbkRenderMainScene() RenderList.pop_front(); } - D3D9Pad* pSketch = GetPooledSketchpad(SKETCHPAD_LABELS); if (pSketch) { m_celSphere->EnsureMarkerDrawingContext((oapi::Sketchpad**)&pSketch, 0, m_celSphere->MarkerColor(0), m_celSphere->MarkerPen(0)); for (auto x : RenderMarkers) RenderVesselMarker(x, pSketch); - pSketch->EndDrawing(); // SKETCHPAD_LABELS + pSketch->EndDrawing(); // SKETCHPAD_LABELS } @@ -4042,8 +4040,10 @@ bool Scene::SetupInternalCamera(D3DXMATRIX *mNew, VECTOR3 *gpos, double apr, dou Camera.alt_proxy = dist(Camera.pos, pos) - oapiGetSize(Camera.hObj_proxy); - if (Camera.vProxy->Type() == OBJTP_PLANET) - rad = oapiSurfaceElevation(Camera.hObj_proxy, Camera.lng, Camera.lat); + if (Camera.vProxy) { + if (Camera.vProxy->Type() == OBJTP_PLANET) + rad = oapiSurfaceElevation(Camera.hObj_proxy, Camera.lng, Camera.lat); + } Camera.elev = Camera.alt_proxy - rad; @@ -4056,6 +4056,8 @@ bool Scene::SetupInternalCamera(D3DXMATRIX *mNew, VECTOR3 *gpos, double apr, dou // Finally update world matrices from all visuals ResetOrigin(Camera.pos); + + return true; } diff --git a/OVP/D3D9Client/Scene.h b/OVP/D3D9Client/Scene.h index 48d6d044d..38238a366 100644 --- a/OVP/D3D9Client/Scene.h +++ b/OVP/D3D9Client/Scene.h @@ -267,7 +267,7 @@ class Scene { */ inline const DWORD ViewH() const { return viewH; } - void UpdateCamVis(); + bool UpdateCamVis(); @@ -378,7 +378,7 @@ class Scene { bool UpdateCameraFromOrbiter(DWORD dwPass); // Manually initialize client's internal camera setup - void SetupInternalCamera(D3DXMATRIX *mView, VECTOR3 *pos, double apr, double asp); + bool SetupInternalCamera(D3DXMATRIX *mView, VECTOR3 *pos, double apr, double asp); void CameraOffOrigin90(D3DXMATRIX* mView, FVECTOR3 pos); // Pan Camera in a mesh debugger From b813d7ee9f7fab772925b060d72f404034b942c5 Mon Sep 17 00:00:00 2001 From: jarmonik Date: Fri, 24 Jan 2025 17:51:51 +0200 Subject: [PATCH 42/42] Fixing merge errors --- OVP/D3D9Client/VVessel.cpp | 3 ++- Orbitersdk/include/OrbiterAPI.h | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/OVP/D3D9Client/VVessel.cpp b/OVP/D3D9Client/VVessel.cpp index 95c6db73d..c93a40a1b 100644 --- a/OVP/D3D9Client/VVessel.cpp +++ b/OVP/D3D9Client/VVessel.cpp @@ -7,6 +7,7 @@ // ============================================================== #include +#include #include "VVessel.h" #include "VPlanet.h" #include "MeshMgr.h" @@ -1700,7 +1701,7 @@ ENVCAMREC* vVessel::GetEnvCam(EnvCamType ec, int idx) if (idx < 0) { for (auto c : InteriorCams) if (c) return c; // Get any cam } - else return InteriorCams[clamp(idx, 0, MAX_INTCAM - 1)]; + else return InteriorCams[std::clamp(idx, 0, MAX_INTCAM - 1)]; } if (ec == EnvCamType::Mesh) { // TODO: diff --git a/Orbitersdk/include/OrbiterAPI.h b/Orbitersdk/include/OrbiterAPI.h index b50acc0bc..9cee907c5 100644 --- a/Orbitersdk/include/OrbiterAPI.h +++ b/Orbitersdk/include/OrbiterAPI.h @@ -467,7 +467,7 @@ typedef struct { } MATERIAL; -enum class MatProp { +enum MatProp { Diffuse, ///< Material Diffuse color or Albedo depending on shader used. [.rgba] Ambient, ///< Ambient color or Ambien occlusion [.rgb] Specular, ///< Specular color [.rgb] power in [.a] @@ -7635,4 +7635,4 @@ void calldummy () { dummy(); } DLLCLBK char *ModuleDate () { return (char*)__DATE__; } #endif -#endif // !__ORBITERAPI_H \ No newline at end of file +#endif // !__ORBITERAPI_H