diff --git a/res/gamedata/shaders/.gitattributes b/res/gamedata/shaders/.gitattributes index 7f32264ea16..85721c9398a 100644 --- a/res/gamedata/shaders/.gitattributes +++ b/res/gamedata/shaders/.gitattributes @@ -5,17 +5,17 @@ *.ps -binary # DirectX renderer shader extension names -r*/*.ps text diff=cpp linguist-language=HLSL -r*/*.vs text diff=cpp linguist-language=HLSL -r*/*.gs text diff=cpp linguist-language=HLSL -r*/*.cs text diff=cpp linguist-language=HLSL -r*/*.hs text diff=cpp linguist-language=HLSL -r*/*.ds text diff=cpp linguist-language=HLSL +r*/*.ps text diff=cpp linguist-language=HLSL linguist-detectable=true linguist-documentation=false +r*/*.vs text diff=cpp linguist-language=HLSL linguist-detectable=true linguist-documentation=false +r*/*.gs text diff=cpp linguist-language=HLSL linguist-detectable=true linguist-documentation=false +r*/*.cs text diff=cpp linguist-language=HLSL linguist-detectable=true linguist-documentation=false +r*/*.hs text diff=cpp linguist-language=HLSL linguist-detectable=true linguist-documentation=false +r*/*.ds text diff=cpp linguist-language=HLSL linguist-detectable=true linguist-documentation=false # OpenGL renderer uses the same extensions -gl/*.ps text diff=cpp linguist-language=GLSL -gl/*.vs text diff=cpp linguist-language=GLSL -gl/*.gs text diff=cpp linguist-language=GLSL -gl/*.cs text diff=cpp linguist-language=GLSL -gl/*.hs text diff=cpp linguist-language=GLSL -gl/*.ds text diff=cpp linguist-language=GLSL +gl/*.ps text diff=cpp linguist-language=GLSL linguist-detectable=true linguist-documentation=false +gl/*.vs text diff=cpp linguist-language=GLSL linguist-detectable=true linguist-documentation=false +gl/*.gs text diff=cpp linguist-language=GLSL linguist-detectable=true linguist-documentation=false +gl/*.cs text diff=cpp linguist-language=GLSL linguist-detectable=true linguist-documentation=false +gl/*.hs text diff=cpp linguist-language=GLSL linguist-detectable=true linguist-documentation=false +gl/*.ds text diff=cpp linguist-language=GLSL linguist-detectable=true linguist-documentation=false diff --git a/src/Layers/xrRender/Blender_Recorder.h b/src/Layers/xrRender/Blender_Recorder.h index bf4e3445fda..d4532859b32 100644 --- a/src/Layers/xrRender/Blender_Recorder.h +++ b/src/Layers/xrRender/Blender_Recorder.h @@ -28,6 +28,7 @@ class CBlender_Compile bool bDetail_Bump; BOOL bUseSteepParallax; int iElement; + bool HudElement = false; public: CSimulator RS; diff --git a/src/Layers/xrRender/Blender_Recorder_StandartBinding.cpp b/src/Layers/xrRender/Blender_Recorder_StandartBinding.cpp index b69b3f14338..7ac3513da03 100644 --- a/src/Layers/xrRender/Blender_Recorder_StandartBinding.cpp +++ b/src/Layers/xrRender/Blender_Recorder_StandartBinding.cpp @@ -191,7 +191,7 @@ class cl_fog_params : public R_constant_setup float n = g_pGamePersistent->Environment().CurrentEnv.fog_near; float f = g_pGamePersistent->Environment().CurrentEnv.fog_far; float r = 1 / (f - n); - result.set(-n * r, r, r, r); + result.set(-n * r, n, f, r); } cmd_list.set_c(C, result); } @@ -208,7 +208,7 @@ class cl_fog_color : public R_constant_setup if (marker != Device.dwFrame) { const auto& desc = g_pGamePersistent->Environment().CurrentEnv; - result.set(desc.fog_color.x, desc.fog_color.y, desc.fog_color.z, 0); + result.set(desc.fog_color.x, desc.fog_color.y, desc.fog_color.z, desc.fog_density); } cmd_list.set_c(C, result); } @@ -387,6 +387,189 @@ class cl_entity_data : public R_constant_setup //--#SM+#-- }; static cl_entity_data binder_entity_data; +// Ascii1457's Screen Space Shaders +extern ENGINE_API Fvector4 ps_ssfx_hud_drops_1; +extern ENGINE_API Fvector4 ps_ssfx_hud_drops_2; +extern ENGINE_API Fvector4 ps_ssfx_blood_decals; +extern ENGINE_API Fvector4 ps_ssfx_wpn_dof_1; +extern ENGINE_API float ps_ssfx_wpn_dof_2; + +class cl_inv_v : public R_constant_setup +{ + Fmatrix result; + void setup(CBackend& cmd_list, R_constant* C) override + { + result.invert(Device.mView); + cmd_list.set_c(C, result); + } +}; +static cl_inv_v binder_inv_v; + +class cl_rain_params : public R_constant_setup +{ + void setup(CBackend& cmd_list, R_constant* C) override + { + float rainDensity = g_pGamePersistent->Environment().CurrentEnv.rain_density; + float rainWetness = g_pGamePersistent->Environment().wetness_factor; + cmd_list.set_c(C, rainDensity, rainWetness, 0.0f, 0.0f); + } +}; +static cl_rain_params binder_rain_params; + +class pp_image_corrections : public R_constant_setup +{ + virtual void setup(CBackend& cmd_list, R_constant* C) override + { + cmd_list.set_c(C, ps_r2_img_exposure, ps_r2_img_gamma, ps_r2_img_saturation, 1.f); + } +}; +static pp_image_corrections binder_image_corrections; + +class pp_color_grading : public R_constant_setup +{ + virtual void setup(CBackend& cmd_list, R_constant* C) override + { + cmd_list.set_c(C, ps_r2_img_cg.x, ps_r2_img_cg.y, ps_r2_img_cg.z, 1.f); + } +}; +static pp_color_grading binder_color_grading; + +class cl_sky_color : public R_constant_setup +{ + u32 marker; + Fvector4 result; + + void setup(CBackend& cmd_list, R_constant* C) override + { + if (marker != Device.dwFrame) + { + CEnvDescriptor& desc = g_pGamePersistent->Environment().CurrentEnv; + result.set(desc.sky_color.x, desc.sky_color.y, desc.sky_color.z, desc.sky_rotation); + } + cmd_list.set_c(C, result); + } +}; +static cl_sky_color binder_sky_color; + +//Sneaky debug stuff +extern ENGINE_API Fvector4 ps_dev_param_1; +extern ENGINE_API Fvector4 ps_dev_param_2; +extern ENGINE_API Fvector4 ps_dev_param_3; +extern ENGINE_API Fvector4 ps_dev_param_4; +extern ENGINE_API Fvector4 ps_dev_param_5; +extern ENGINE_API Fvector4 ps_dev_param_6; +extern ENGINE_API Fvector4 ps_dev_param_7; +extern ENGINE_API Fvector4 ps_dev_param_8; + +static class dev_param_1 : public R_constant_setup +{ + void setup(CBackend& cmd_list, R_constant* C) override + { + cmd_list.set_c(C, ps_dev_param_1.x, ps_dev_param_1.y, ps_dev_param_1.z, ps_dev_param_1.w); + } +} dev_param_1; + +static class dev_param_2 : public R_constant_setup +{ + void setup(CBackend& cmd_list, R_constant* C) override + { + cmd_list.set_c(C, ps_dev_param_2.x, ps_dev_param_2.y, ps_dev_param_2.z, ps_dev_param_2.w); + } +} dev_param_2; + +static class dev_param_3 : public R_constant_setup +{ + void setup(CBackend& cmd_list, R_constant* C) override + { + cmd_list.set_c(C, ps_dev_param_3.x, ps_dev_param_3.y, ps_dev_param_3.z, ps_dev_param_3.w); + } +} dev_param_3; + +static class dev_param_4 : public R_constant_setup +{ + void setup(CBackend& cmd_list, R_constant* C) override + { + cmd_list.set_c(C, ps_dev_param_4.x, ps_dev_param_4.y, ps_dev_param_4.z, ps_dev_param_4.w); + } +} dev_param_4; + +static class dev_param_5 : public R_constant_setup +{ + void setup(CBackend& cmd_list, R_constant* C) override + { + cmd_list.set_c(C, ps_dev_param_5.x, ps_dev_param_5.y, ps_dev_param_5.z, ps_dev_param_5.w); + } +} dev_param_5; + +static class dev_param_6 : public R_constant_setup +{ + void setup(CBackend& cmd_list, R_constant* C) override + { + cmd_list.set_c(C, ps_dev_param_6.x, ps_dev_param_6.y, ps_dev_param_6.z, ps_dev_param_6.w); + } +} dev_param_6; + +static class dev_param_7 : public R_constant_setup +{ + void setup(CBackend& cmd_list, R_constant* C) override + { + cmd_list.set_c(C, ps_dev_param_7.x, ps_dev_param_7.y, ps_dev_param_7.z, ps_dev_param_7.w); + } +} dev_param_7; + +static class dev_param_8 : public R_constant_setup +{ + void setup(CBackend& cmd_list, R_constant* C) override + { + cmd_list.set_c(C, ps_dev_param_8.x, ps_dev_param_8.y, ps_dev_param_8.z, ps_dev_param_8.w); + } +} dev_param_8; + +class ssfx_wpn_dof_1 : public R_constant_setup +{ + void setup(CBackend& cmd_list, R_constant* C) override + { + cmd_list.set_c(C, ps_ssfx_wpn_dof_1.x, ps_ssfx_wpn_dof_1.y, ps_ssfx_wpn_dof_1.z, ps_ssfx_wpn_dof_1.w); + } +}; +static ssfx_wpn_dof_1 binder_ssfx_wpn_dof_1; + +class ssfx_wpn_dof_2 : public R_constant_setup +{ + void setup(CBackend& cmd_list, R_constant* C) override + { + cmd_list.set_c(C, ps_ssfx_wpn_dof_2, 0.f, 0.f, 0.f); + } +}; +static ssfx_wpn_dof_2 binder_ssfx_wpn_dof_2; + +class ssfx_blood_decals : public R_constant_setup +{ + void setup(CBackend& cmd_list, R_constant* C) override + { + cmd_list.set_c(C, ps_ssfx_blood_decals); + } +}; +static ssfx_blood_decals binder_ssfx_blood_decals; + +class ssfx_hud_drops_1 : public R_constant_setup +{ + void setup(CBackend& cmd_list, R_constant* C) override + { + cmd_list.set_c(C, ps_ssfx_hud_drops_1); + } +}; +static ssfx_hud_drops_1 binder_ssfx_hud_drops_1; + +class ssfx_hud_drops_2 : public R_constant_setup +{ + void setup(CBackend& cmd_list, R_constant* C) override + { + cmd_list.set_c(C, ps_ssfx_hud_drops_2); + } +}; +static ssfx_hud_drops_2 binder_ssfx_hud_drops_2; + // Standart constant-binding void CBlender_Compile::SetMapping() { @@ -466,4 +649,27 @@ void CBlender_Compile::SetMapping() std::pair cs = RImplementation.Resources->v_constant_setup[it]; r_Constant(*cs.first, cs.second); } + + // Anomaly + r_Constant("rain_params", &binder_rain_params); + r_Constant("pp_img_corrections", &binder_image_corrections); + r_Constant("pp_img_cg", &binder_color_grading); + r_Constant("m_inv_V", &binder_inv_v); + + r_Constant("shader_param_1", &dev_param_1); + r_Constant("shader_param_2", &dev_param_2); + r_Constant("shader_param_3", &dev_param_3); + r_Constant("shader_param_4", &dev_param_4); + r_Constant("shader_param_5", &dev_param_5); + r_Constant("shader_param_6", &dev_param_6); + r_Constant("shader_param_7", &dev_param_7); + r_Constant("shader_param_8", &dev_param_8); + + // Ascii1457's Screen Space Shaders + r_Constant("sky_color", &binder_sky_color); + r_Constant("ssfx_wpn_dof_1", &binder_ssfx_wpn_dof_1); + r_Constant("ssfx_wpn_dof_2", &binder_ssfx_wpn_dof_2); + r_Constant("ssfx_blood_decals", &binder_ssfx_blood_decals); + r_Constant("ssfx_hud_drops_1", &binder_ssfx_hud_drops_1); + r_Constant("ssfx_hud_drops_2", &binder_ssfx_hud_drops_2); } diff --git a/src/Layers/xrRender/ColorMapManager.cpp b/src/Layers/xrRender/ColorMapManager.cpp index aaa967a6b96..7f1c9ab3f29 100644 --- a/src/Layers/xrRender/ColorMapManager.cpp +++ b/src/Layers/xrRender/ColorMapManager.cpp @@ -42,7 +42,7 @@ void ColorMapManager::UpdateTexture(const shared_str& strTexName, int iTex) ref_texture tmp; tmp.create(strTexName.c_str()); - m_TexCache.insert(std::make_pair(strTexName, tmp)); + m_TexCache.emplace(strTexName, tmp); #if defined(USE_DX9) || defined(USE_DX11) ID3DBaseTexture* e0 = tmp->surface_get(); diff --git a/src/Layers/xrRender/DetailManager.cpp b/src/Layers/xrRender/DetailManager.cpp index 0d6030b100b..56e701fd8c5 100644 --- a/src/Layers/xrRender/DetailManager.cpp +++ b/src/Layers/xrRender/DetailManager.cpp @@ -268,7 +268,9 @@ void CDetailManager::UpdateVisibleM() continue; } u32 mask = 0xff; - u32 res = View.testSAABB(MS.vis.sphere.P, MS.vis.sphere.R, MS.vis.box.data(), mask); + + u32 res = View.testSphere(MS.vis.sphere.P, MS.vis.sphere.R, mask); + if (fcvNone == res) { continue; // invisible-view frustum @@ -295,7 +297,7 @@ void CDetailManager::UpdateVisibleM() if (fcvPartial == res) { u32 _mask = mask; - u32 _res = View.testSAABB(S.vis.sphere.P, S.vis.sphere.R, S.vis.box.data(), _mask); + u32 _res = View.testSphere(S.vis.sphere.P, S.vis.sphere.R, _mask); if (fcvNone == _res) { continue; // invisible-view frustum @@ -347,6 +349,8 @@ void CDetailManager::UpdateVisibleM() sp.r_items[vis_id].push_back(siIT); + Item.distance = dist_sq; + Item.position = S.vis.sphere.P; // 2 visible[vis_id][sp.id].push_back(&Item); } } @@ -444,3 +448,26 @@ void CDetailManager::MT_CALC() } MT.Leave(); } + +void CDetailManager::details_clear() +{ + // Disable fade, next render will be scene + fade_distance = 99999; + + if (ps_ssfx_grass_shadows.x <= 0) + return; + + for (u32 x = 0; x < 3; x++) + { + vis_list& list = m_visibles[x]; + for (u32 O = 0; O < objects.size(); O++) + { + CDetail & Object = *objects[O]; + xr_vector&vis = list[O]; + if (!vis.empty()) + { + vis.erase(vis.begin(), vis.end()); + } + } + } +} diff --git a/src/Layers/xrRender/DetailManager.h b/src/Layers/xrRender/DetailManager.h index 5e9bc3a0999..8038027080b 100644 --- a/src/Layers/xrRender/DetailManager.h +++ b/src/Layers/xrRender/DetailManager.h @@ -53,6 +53,10 @@ extern float ps_current_detail_height; class ECORE_API CDetailManager { public: + float fade_distance = 99999; + Fvector light_position; + void details_clear(); + struct SlotItem { // один кустик float scale; @@ -61,6 +65,8 @@ class ECORE_API CDetailManager u32 vis_ID; // индекс в visibility списке он же тип [не качается, качается1, качается2] float c_hemi; float c_sun; + float distance; + Fvector position; #if RENDER == R_R1 Fvector c_rgb; #endif diff --git a/src/Layers/xrRender/FTreeVisual.cpp b/src/Layers/xrRender/FTreeVisual.cpp index a5497bbe526..ea4f4481ff2 100644 --- a/src/Layers/xrRender/FTreeVisual.cpp +++ b/src/Layers/xrRender/FTreeVisual.cpp @@ -15,6 +15,8 @@ shared_str c_wind; shared_str c_c_bias; shared_str c_c_scale; shared_str c_c_sun; +shared_str c_c_BendersPos; +shared_str c_c_BendersSetup; FTreeVisual::FTreeVisual(void) {} FTreeVisual::~FTreeVisual(void) {} @@ -101,6 +103,8 @@ void FTreeVisual::Load(const char* N, IReader* data, u32 dwFlags) c_c_bias = "c_bias"; c_c_scale = "c_scale"; c_c_sun = "c_sun"; + c_c_BendersPos = "benders_pos"; + c_c_BendersSetup = "benders_setup"; } struct FTreeVisual_setup @@ -167,6 +171,45 @@ void FTreeVisual::Render(CBackend& cmd_list, float /*LOD*/, bool use_fast_geo) s * c_bias.rgb.z + desc.ambient.z, s * c_bias.hemi); // bias #endif cmd_list.tree.set_c_sun(s * c_scale.sun, s * c_bias.sun, 0, 0); // sun + +#if RENDER == R_R4 + if (ps_ssfx_grass_interactive.y > 0) + { + // Inter grass Settings + cmd_list.set_c(c_c_BendersSetup, ps_ssfx_int_grass_params_1); + + // Grass benders data ( Player + Characters ) + IGame_Persistent::grass_data& GData = g_pGamePersistent->grass_shader_data; + Fvector4 player_pos = { 0, 0, 0, 0 }; + int BendersQty = _min(16, (int)(ps_ssfx_grass_interactive.y + 1)); + + // Add Player? + if (ps_ssfx_grass_interactive.x > 0) + { + player_pos.set(Device.vCameraPosition.x, Device.vCameraPosition.y, Device.vCameraPosition.z, -1); + } + + Fvector4* c_grass{}; + { + void* GrassData; + cmd_list.get_ConstantDirect(c_c_BendersPos, BendersQty * sizeof(Fvector4) * 2, &GrassData, 0, 0); + + c_grass = (Fvector4*)GrassData; + } + + if (c_grass) + { + c_grass[0].set(player_pos); + c_grass[16].set(0.0f, -99.0f, 0.0f, 1.0f); + + for (int Bend = 1; Bend < BendersQty; Bend++) + { + c_grass[Bend].set(GData.pos[Bend].x, GData.pos[Bend].y, GData.pos[Bend].z, GData.radius_curr[Bend]); + c_grass[Bend + 16].set(GData.dir[Bend].x, GData.dir[Bend].y, GData.dir[Bend].z, GData.str[Bend]); + } + } + } +#endif } #define PCOPY(a) a = pFrom->a diff --git a/src/Layers/xrRender/ModelPool.cpp b/src/Layers/xrRender/ModelPool.cpp index bbe342faeba..4ed9125ba83 100644 --- a/src/Layers/xrRender/ModelPool.cpp +++ b/src/Layers/xrRender/ModelPool.cpp @@ -253,7 +253,7 @@ dxRender_Visual* CModelPool::Create(const char* name, IReader* data) } // 3. If found - return (cloned) reference dxRender_Visual* Model = Instance_Duplicate(Base); - Registry.insert(std::make_pair(Model, low_name)); + Registry.emplace(Model, low_name); return Model; } } @@ -300,7 +300,7 @@ void CModelPool::DeleteInternal(dxRender_Visual*& V, BOOL bDiscard) if (it != Registry.end()) { // Registry entry found - move it to pool - Pool.insert(std::make_pair(it->second, V)); + Pool.emplace(it->second, V); } else { diff --git a/src/Layers/xrRender/ParticleEffectDef.cpp b/src/Layers/xrRender/ParticleEffectDef.cpp index 4c2a4ea2a28..9d51ad48a48 100644 --- a/src/Layers/xrRender/ParticleEffectDef.cpp +++ b/src/Layers/xrRender/ParticleEffectDef.cpp @@ -112,7 +112,7 @@ void CPEDef::ExecuteAnimate(Particle* particles, u32 p_cnt, float dt) } void CPEDef::ExecuteCollision( - PAPI::Particle* particles, u32 p_cnt, float dt, CParticleEffect* owner, CollisionCallback cb) + PAPI::Particle* particles, u32 p_cnt, float dt, CParticleEffect* owner, CollisionCallback cb) const { pVector pt, n; // Must traverse list in reverse order so Remove will work @@ -127,7 +127,7 @@ void CPEDef::ExecuteCollision( pick_needed = false; Fvector dir; dir.sub(m.pos, m.posB); - float dist = dir.magnitude(); + const float dist = dir.magnitude(); if (dist >= EPS) { dir.div(dist); @@ -162,9 +162,9 @@ void CPEDef::ExecuteCollision( else { // Compute tangential and normal components of velocity - float nmag = m.vel * n; - pVector vn(n * nmag); // Normal Vn = (V.N)N - pVector vt(m.vel - vn); // Tangent Vt = V - Vn + const float nmag = m.vel * n; + const pVector vn(n * nmag); // Normal Vn = (V.N)N + const pVector vt(m.vel - vn); // Tangent Vt = V - Vn // Compute _new velocity heading out: // Don't apply friction if tangential velocity < cutoff diff --git a/src/Layers/xrRender/ParticleEffectDef.h b/src/Layers/xrRender/ParticleEffectDef.h index 60edaba64a9..0c98efa40ef 100644 --- a/src/Layers/xrRender/ParticleEffectDef.h +++ b/src/Layers/xrRender/ParticleEffectDef.h @@ -93,7 +93,7 @@ class ECORE_API CPEDef BOOL LoadActionList(IReader& F); // execute void ExecuteAnimate(PAPI::Particle* particles, u32 p_cnt, float dt); - void ExecuteCollision(PAPI::Particle* particles, u32 p_cnt, float dt, CParticleEffect* owner, CollisionCallback cb); + void ExecuteCollision(PAPI::Particle* particles, u32 p_cnt, float dt, CParticleEffect* owner, CollisionCallback cb) const; CPEDef(); ~CPEDef(); diff --git a/src/Layers/xrRender/R_DStreams.cpp b/src/Layers/xrRender/R_DStreams.cpp index b70f0a0fa0b..4eb06452065 100644 --- a/src/Layers/xrRender/R_DStreams.cpp +++ b/src/Layers/xrRender/R_DStreams.cpp @@ -37,13 +37,13 @@ void* _VertexStream::Lock(u32 vl_Count, u32 Stride, u32& vOffset) #endif // Ensure there is enough space in the VB for this data - u32 bytes_need = vl_Count * Stride; + const u32 bytes_need = vl_Count * Stride; R_ASSERT2((bytes_need <= mSize) && vl_Count, make_string("bytes_need = %d, mSize = %d, vl_Count = %d", bytes_need, mSize, vl_Count)); // Vertex-local info - u32 vl_mSize = mSize / Stride; - u32 vl_mPosition = mPosition / Stride + 1; + const u32 vl_mSize = mSize / Stride; + const u32 vl_mPosition = mPosition / Stride + 1; // Check if there is need to flush and perform lock bool bFlush = false; diff --git a/src/Layers/xrRender/ResourceManager.cpp b/src/Layers/xrRender/ResourceManager.cpp index 69d7c25977e..686a9beff44 100644 --- a/src/Layers/xrRender/ResourceManager.cpp +++ b/src/Layers/xrRender/ResourceManager.cpp @@ -69,7 +69,7 @@ void CResourceManager::ED_UpdateBlender(LPCSTR Name, IBlender* data) } else { - m_blenders.insert(std::make_pair(xr_strdup(Name), data)); + m_blenders.emplace(xr_strdup(Name), data); } } @@ -122,9 +122,9 @@ ShaderElement* CResourceManager::_CreateElement(ShaderElement&& S) return nullptr; // Search equal in shaders array - for (u32 it = 0; it < v_elements.size(); it++) - if (S.equal(*(v_elements[it]))) - return v_elements[it]; + for (ShaderElement* elem : v_elements) + if (S.equal(*elem)) + return elem; // Create _new_ entry ShaderElement* N = v_elements.emplace_back(xr_new(std::move(S))); @@ -154,6 +154,8 @@ Shader* CResourceManager::_cpp_Create( C.BT = B; C.bFFP = RImplementation.o.ffp; C.bDetail = FALSE; + C.HudElement = false; + #ifdef _EDITOR if (!C.BT) { @@ -170,6 +172,13 @@ Shader* CResourceManager::_cpp_Create( _ParseList(C.L_constants, s_constants); _ParseList(C.L_matrices, s_matrices); +#if defined(USE_DX11) + if (RImplementation.hud_loading && RImplementation.o.ssfx_hud_raindrops) + { + C.HudElement = true; + } +#endif + // Compile element (LOD0 - HQ) { C.iElement = SE_R1_NORMAL_HQ; @@ -437,7 +446,7 @@ void CResourceManager::_DumpMemoryUsage() { u32 m = I->second->flags.MemoryUsage; shared_str n = I->second->cName; - mtex.insert(std::make_pair(m, std::make_pair(I->second->ref_count.load(), n))); + mtex.emplace(m, std::make_pair(I->second->ref_count.load(), n)); } } diff --git a/src/Layers/xrRender/ResourceManager_Loader.cpp b/src/Layers/xrRender/ResourceManager_Loader.cpp index a03074d61fc..b19acb0cdc4 100644 --- a/src/Layers/xrRender/ResourceManager_Loader.cpp +++ b/src/Layers/xrRender/ResourceManager_Loader.cpp @@ -111,7 +111,7 @@ void CResourceManager::OnDeviceCreate(IReader* F) chunk->seek(0); B->Load(*chunk, desc.version); - auto I = m_blenders.insert(std::make_pair(xr_strdup(desc.cName), B)); + auto I = m_blenders.emplace(xr_strdup(desc.cName), B); R_ASSERT2(I.second, "shader.xr - found duplicate name!!!"); } chunk->close(); diff --git a/src/Layers/xrRender/ShaderResourceTraits.h b/src/Layers/xrRender/ShaderResourceTraits.h index 88a8a5de028..380c07c774d 100644 --- a/src/Layers/xrRender/ShaderResourceTraits.h +++ b/src/Layers/xrRender/ShaderResourceTraits.h @@ -595,7 +595,7 @@ T* CResourceManager::CreateShader(cpcstr name, pcstr filename /*= nullptr*/, u32 T* sh = xr_new(); sh->dwFlags |= xr_resource_flagged::RF_REGISTERED; - sh_map.insert(std::make_pair(sh->set_name(name), sh)); + sh_map.emplace(sh->set_name(name), sh); if (0 == xr_stricmp(name, "null")) { sh->sh = 0; diff --git a/src/Layers/xrRender/blenders/Blender_Blur.cpp b/src/Layers/xrRender/blenders/Blender_Blur.cpp index 7e0918f9a49..4da1576b4e4 100644 --- a/src/Layers/xrRender/blenders/Blender_Blur.cpp +++ b/src/Layers/xrRender/blenders/Blender_Blur.cpp @@ -8,10 +8,6 @@ * Consider removing. */ -#if RENDER != R_R1 -#error "The blender can't be used in this renderer generation" -#endif - CBlender_Blur::CBlender_Blur() { description.CLS = B_BLUR; @@ -22,6 +18,7 @@ LPCSTR CBlender_Blur::getComment() return "INTERNAL: blur"; } +#if RENDER != R_R4 void CBlender_Blur::Compile(CBlender_Compile& C) { IBlender::Compile(C); @@ -54,3 +51,73 @@ void CBlender_Blur::Compile(CBlender_Compile& C) } C.PassEnd(); } +#else +void CBlender_Blur::Compile(CBlender_Compile& C) +{ + IBlender::Compile(C); + + switch (C.iElement) + { + case 0: //Fullres Horizontal + C.r_Pass("stub_screen_space", "pp_blur", FALSE, FALSE, FALSE); + C.r_dx11Texture("s_image", r2_RT_generic0); + C.r_dx11Texture("s_position", r2_RT_P); + C.r_dx11Texture("s_lut_atlas", "shaders\\lut_atlas"); + + C.r_dx11Sampler("smp_nofilter"); + C.r_dx11Sampler("smp_rtlinear"); + C.r_End(); + break; + case 1: //Fullres Vertical + C.r_Pass("stub_screen_space", "pp_blur", FALSE, FALSE, FALSE); + C.r_dx11Texture("s_image", r2_RT_blur_h_2); + C.r_dx11Texture("s_position", r2_RT_P); + C.r_dx11Texture("s_lut_atlas", "shaders\\lut_atlas"); + + C.r_dx11Sampler("smp_nofilter"); + C.r_dx11Sampler("smp_rtlinear"); + C.r_End(); + break; + case 2: //Halfres Horizontal + C.r_Pass("stub_screen_space", "pp_blur", FALSE, FALSE, FALSE); + C.r_dx11Texture("s_image", r2_RT_generic0); + C.r_dx11Texture("s_position", r2_RT_P); + C.r_dx11Texture("s_lut_atlas", "shaders\\lut_atlas"); + + C.r_dx11Sampler("smp_nofilter"); + C.r_dx11Sampler("smp_rtlinear"); + C.r_End(); + break; + case 3: //Halfres Vertical + C.r_Pass("stub_screen_space", "pp_blur", FALSE, FALSE, FALSE); + C.r_dx11Texture("s_image", r2_RT_blur_h_4); + C.r_dx11Texture("s_position", r2_RT_P); + C.r_dx11Texture("s_lut_atlas", "shaders\\lut_atlas"); + + C.r_dx11Sampler("smp_nofilter"); + C.r_dx11Sampler("smp_rtlinear"); + C.r_End(); + break; + case 4: //Quarterres Horizontal + C.r_Pass("stub_screen_space", "pp_blur", FALSE, FALSE, FALSE); + C.r_dx11Texture("s_image", r2_RT_generic0); + C.r_dx11Texture("s_position", r2_RT_P); + C.r_dx11Texture("s_lut_atlas", "shaders\\lut_atlas"); + + C.r_dx11Sampler("smp_nofilter"); + C.r_dx11Sampler("smp_rtlinear"); + C.r_End(); + break; + case 5: //Quarterres Vertical + C.r_Pass("stub_screen_space", "pp_blur", FALSE, FALSE, FALSE); + C.r_dx11Texture("s_image", r2_RT_blur_h_8); + C.r_dx11Texture("s_position", r2_RT_P); + C.r_dx11Texture("s_lut_atlas", "shaders\\lut_atlas"); + + C.r_dx11Sampler("smp_nofilter"); + C.r_dx11Sampler("smp_rtlinear"); + C.r_End(); + break; + } +} +#endif diff --git a/src/Layers/xrRender/blenders/Blender_BmmD_deferred.cpp b/src/Layers/xrRender/blenders/Blender_BmmD_deferred.cpp index 3f2b1c4ceea..9e8ba641059 100644 --- a/src/Layers/xrRender/blenders/Blender_BmmD_deferred.cpp +++ b/src/Layers/xrRender/blenders/Blender_BmmD_deferred.cpp @@ -98,6 +98,11 @@ void CBlender_BmmD::Compile(CBlender_Compile& C) C.r_Sampler("s_dn_b", strconcat(sizeof(mask), mask, oB_Name, "_bump")); C.r_Sampler("s_dn_a", strconcat(sizeof(mask), mask, oA_Name, "_bump")); + C.r_Sampler("s_puddles_normal", "fx\\water_normal"); + C.r_Sampler("s_puddles_perlin", "fx\\puddles_perlin"); + C.r_Sampler("s_puddles_mask", strconcat(sizeof(mask), mask, C.L_textures[0].c_str(), "_puddles_mask")); + C.r_Sampler("s_rainsplash", "fx\\water_sbumpvolume"); + if (C.bUseSteepParallax) { C.r_Sampler("s_dn_rX", strconcat(sizeof(mask), mask, oR_Name, "_bump#")); @@ -225,6 +230,11 @@ void CBlender_BmmD::Compile(CBlender_Compile& C) C.r_dx11Texture("s_dn_b", strconcat(sizeof(mask), mask, oB_Name, "_bump")); C.r_dx11Texture("s_dn_a", strconcat(sizeof(mask), mask, oA_Name, "_bump")); + C.r_dx11Texture("s_puddles_normal", "fx\\water_normal"); + C.r_dx11Texture("s_puddles_perlin", "fx\\puddles_perlin"); + C.r_dx11Texture("s_puddles_mask", strconcat(sizeof(mask), mask, C.L_textures[0].c_str(), "_puddles_mask")); + C.r_dx11Texture("s_rainsplash", "fx\\water_sbumpvolume"); + if (C.bUseSteepParallax) { C.r_dx11Texture("s_dn_rX", strconcat(sizeof(mask), mask, oR_Name, "_bump#")); diff --git a/src/Layers/xrRender/blenders/Blender_Model_EbB_deferred.cpp b/src/Layers/xrRender/blenders/Blender_Model_EbB_deferred.cpp index 26679402d6f..3bc70647b11 100644 --- a/src/Layers/xrRender/blenders/Blender_Model_EbB_deferred.cpp +++ b/src/Layers/xrRender/blenders/Blender_Model_EbB_deferred.cpp @@ -166,7 +166,13 @@ void CBlender_Model_EbB::Compile(CBlender_Compile& C) switch (C.iElement) { case SE_R2_NORMAL_HQ: // deffer - uber_deffer(C, true, "model", "base", false, 0, true); + if (C.HudElement) + { + uber_deffer(C, true, "model_hud", "base_hud", false, 0, true); + C.r_dx11Texture("s_hud_rain", "fx\\hud_rain"); + } + else + uber_deffer(C, true, "model", "base", false, 0, true); C.r_Stencil(TRUE, D3DCMP_ALWAYS, 0xff, 0x7f, D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE, D3DSTENCILOP_KEEP); C.r_StencilRef(0x01); C.r_End(); diff --git a/src/Layers/xrRender/blenders/Blender_tree_deferred.cpp b/src/Layers/xrRender/blenders/Blender_tree_deferred.cpp index d418138fa56..bd59f491ee6 100644 --- a/src/Layers/xrRender/blenders/Blender_tree_deferred.cpp +++ b/src/Layers/xrRender/blenders/Blender_tree_deferred.cpp @@ -101,6 +101,10 @@ void CBlender_Tree::Compile(CBlender_Compile& C) switch (C.iElement) { case SE_R2_NORMAL_HQ: // deffer + // Is a branch/bush. Use a different VS + if (ps_r2_ls_flags_ext.test(R4FLAGEXT_NEW_SHADER_SUPPORT) && oBlend.value && RImplementation.o.ssfx_branches) + tvs = "tree_branch"; + if (bUseATOC) { uber_deffer(C, true, tvs, "base_atoc", oBlend.value, 0, true); diff --git a/src/Layers/xrRender/blenders/blender_combine.cpp b/src/Layers/xrRender/blenders/blender_combine.cpp index 5e7ab09c067..43ce6061019 100644 --- a/src/Layers/xrRender/blenders/blender_combine.cpp +++ b/src/Layers/xrRender/blenders/blender_combine.cpp @@ -192,6 +192,9 @@ void CBlender_combine::Compile(CBlender_Compile& C) C.r_dx11Texture("s_image", r2_RT_generic0); C.r_dx11Texture("s_bloom", r2_RT_bloom1); C.r_dx11Texture("s_distort", r2_RT_generic1); + C.r_dx11Texture("s_blur_2", r2_RT_blur_2); + C.r_dx11Texture("s_blur_4", r2_RT_blur_4); + C.r_dx11Texture("s_blur_8", r2_RT_blur_8); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_rtlinear"); @@ -211,6 +214,9 @@ void CBlender_combine::Compile(CBlender_Compile& C) C.r_dx11Texture("s_image", r2_RT_generic0); C.r_dx11Texture("s_bloom", r2_RT_bloom1); C.r_dx11Texture("s_distort", r2_RT_generic1); + C.r_dx11Texture("s_blur_2", r2_RT_blur_2); + C.r_dx11Texture("s_blur_4", r2_RT_blur_4); + C.r_dx11Texture("s_blur_8", r2_RT_blur_8); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_rtlinear"); @@ -229,6 +235,9 @@ void CBlender_combine::Compile(CBlender_Compile& C) C.r_dx11Texture("s_image", r2_RT_generic0); C.r_dx11Texture("s_bloom", r2_RT_bloom1); C.r_dx11Texture("s_distort", r2_RT_generic1); + C.r_dx11Texture("s_blur_2", r2_RT_blur_2); + C.r_dx11Texture("s_blur_4", r2_RT_blur_4); + C.r_dx11Texture("s_blur_8", r2_RT_blur_8); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_rtlinear"); @@ -248,6 +257,9 @@ void CBlender_combine::Compile(CBlender_Compile& C) C.r_dx11Texture("s_image", r2_RT_generic0); C.r_dx11Texture("s_bloom", r2_RT_bloom1); C.r_dx11Texture("s_distort", r2_RT_generic1); + C.r_dx11Texture("s_blur_2", r2_RT_blur_2); + C.r_dx11Texture("s_blur_4", r2_RT_blur_4); + C.r_dx11Texture("s_blur_8", r2_RT_blur_8); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_rtlinear"); @@ -390,6 +402,9 @@ void CBlender_combine_msaa::Compile(CBlender_Compile& C) C.r_dx11Texture("s_image", r2_RT_generic0); C.r_dx11Texture("s_bloom", r2_RT_bloom1); C.r_dx11Texture("s_distort", r2_RT_generic1_r); + C.r_dx11Texture("s_blur_2", r2_RT_blur_2); + C.r_dx11Texture("s_blur_4", r2_RT_blur_4); + C.r_dx11Texture("s_blur_8", r2_RT_blur_8); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_rtlinear"); @@ -409,6 +424,9 @@ void CBlender_combine_msaa::Compile(CBlender_Compile& C) C.r_dx11Texture("s_image", r2_RT_generic0); C.r_dx11Texture("s_bloom", r2_RT_bloom1); C.r_dx11Texture("s_distort", r2_RT_generic1_r); + C.r_dx11Texture("s_blur_2", r2_RT_blur_2); + C.r_dx11Texture("s_blur_4", r2_RT_blur_4); + C.r_dx11Texture("s_blur_8", r2_RT_blur_8); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_rtlinear"); @@ -427,6 +445,9 @@ void CBlender_combine_msaa::Compile(CBlender_Compile& C) C.r_dx11Texture("s_image", r2_RT_generic0); C.r_dx11Texture("s_bloom", r2_RT_bloom1); C.r_dx11Texture("s_distort", r2_RT_generic1_r); + C.r_dx11Texture("s_blur_2", r2_RT_blur_2); + C.r_dx11Texture("s_blur_4", r2_RT_blur_4); + C.r_dx11Texture("s_blur_8", r2_RT_blur_8); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_rtlinear"); @@ -446,6 +467,9 @@ void CBlender_combine_msaa::Compile(CBlender_Compile& C) C.r_dx11Texture("s_image", r2_RT_generic0); C.r_dx11Texture("s_bloom", r2_RT_bloom1); C.r_dx11Texture("s_distort", r2_RT_generic1_r); + C.r_dx11Texture("s_blur_2", r2_RT_blur_2); + C.r_dx11Texture("s_blur_4", r2_RT_blur_4); + C.r_dx11Texture("s_blur_8", r2_RT_blur_8); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_rtlinear"); diff --git a/src/Layers/xrRender/blenders/blender_deffer_model.cpp b/src/Layers/xrRender/blenders/blender_deffer_model.cpp index 87925a3c828..caac90a525b 100644 --- a/src/Layers/xrRender/blenders/blender_deffer_model.cpp +++ b/src/Layers/xrRender/blenders/blender_deffer_model.cpp @@ -271,7 +271,13 @@ void CBlender_deffer_model::Compile(CBlender_Compile& C) C.r_End(); } - uber_deffer(C, true, "model", "base", bAref, 0, true); + if (C.HudElement) + { + uber_deffer(C, true, "model_hud", "base_hud", bAref, 0, true); + C.r_dx11Texture("s_hud_rain", "fx\\hud_rain"); + } + else + uber_deffer(C, true, "model", "base", bAref, 0, true); C.r_Stencil(TRUE, D3DCMP_ALWAYS, 0xff, 0x7f, D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE, D3DSTENCILOP_KEEP); C.r_StencilRef(0x01); diff --git a/src/Layers/xrRender/blenders/blender_dof.cpp b/src/Layers/xrRender/blenders/blender_dof.cpp new file mode 100644 index 00000000000..485dc6036f0 --- /dev/null +++ b/src/Layers/xrRender/blenders/blender_dof.cpp @@ -0,0 +1,43 @@ +#include "stdafx.h" + +#include "blender_dof.h" + +CBlender_dof::CBlender_dof() +{ + description.CLS = B_BLUR; +} + +LPCSTR CBlender_dof::getComment() +{ + return "INTERNAL: dof"; +} + +void CBlender_dof::Compile(CBlender_Compile& C) +{ + IBlender::Compile(C); +#if RENDER == R_R4 + switch (C.iElement) + { + case 0: + C.r_Pass("stub_screen_space", "depth_of_field", FALSE, FALSE, FALSE); + C.r_dx11Texture("s_position", r2_RT_P); + C.r_dx11Texture("s_image", r2_RT_generic0); + C.r_dx11Texture("s_blur_2", r2_RT_blur_2); + + C.r_dx11Sampler("smp_base"); + C.r_dx11Sampler("smp_nofilter"); + C.r_dx11Sampler("smp_rtlinear"); + C.r_End(); + break; + case 1: + C.r_Pass("stub_screen_space", "post_processing", FALSE, FALSE, FALSE); + C.r_dx11Texture("samplero_pepero", r2_RT_dof); + + C.r_dx11Sampler("smp_base"); + C.r_dx11Sampler("smp_nofilter"); + C.r_dx11Sampler("smp_rtlinear"); + C.r_End(); + break; + } +#endif +} diff --git a/src/Layers/xrRender/blenders/blender_dof.h b/src/Layers/xrRender/blenders/blender_dof.h new file mode 100644 index 00000000000..e92936e17f8 --- /dev/null +++ b/src/Layers/xrRender/blenders/blender_dof.h @@ -0,0 +1,11 @@ +#pragma once + +class CBlender_dof : public IBlender +{ +public: + CBlender_dof(); + ~CBlender_dof() override = default; + + LPCSTR getComment() override; + void Compile(CBlender_Compile& C) override; +}; diff --git a/src/Layers/xrRender/blenders/blender_gasmask_drops.cpp b/src/Layers/xrRender/blenders/blender_gasmask_drops.cpp new file mode 100644 index 00000000000..233441d705a --- /dev/null +++ b/src/Layers/xrRender/blenders/blender_gasmask_drops.cpp @@ -0,0 +1,26 @@ +#include "stdafx.h" + +#include "blender_gasmask_drops.h" + +CBlender_gasmask_drops::CBlender_gasmask_drops() +{ + description.CLS = B_BLUR; +} + +LPCSTR CBlender_gasmask_drops::getComment() +{ + return "INTERNAL: beef's nightvision"; +} + +void CBlender_gasmask_drops::Compile(CBlender_Compile& C) +{ + IBlender::Compile(C); + + C.r_Pass("stub_screen_space", "gasmask_drops", FALSE, FALSE, FALSE); + C.r_dx11Texture("s_image", r2_RT_generic0); + + C.r_dx11Sampler("smp_base"); + C.r_dx11Sampler("smp_nofilter"); + C.r_dx11Sampler("smp_rtlinear"); + C.r_End(); +} diff --git a/src/Layers/xrRender/blenders/blender_gasmask_drops.h b/src/Layers/xrRender/blenders/blender_gasmask_drops.h new file mode 100644 index 00000000000..3ee80b9c5ff --- /dev/null +++ b/src/Layers/xrRender/blenders/blender_gasmask_drops.h @@ -0,0 +1,11 @@ +#pragma once + +class CBlender_gasmask_drops : public IBlender +{ +public: + CBlender_gasmask_drops(); + ~CBlender_gasmask_drops() override = default; + + LPCSTR getComment() override; + void Compile(CBlender_Compile& C) override; +}; diff --git a/src/Layers/xrRender/blenders/blender_gasmask_dudv.cpp b/src/Layers/xrRender/blenders/blender_gasmask_dudv.cpp new file mode 100644 index 00000000000..3dbb461e8ab --- /dev/null +++ b/src/Layers/xrRender/blenders/blender_gasmask_dudv.cpp @@ -0,0 +1,38 @@ +#include "stdafx.h" + +#include "blender_gasmask_dudv.h" + +CBlender_gasmask_dudv::CBlender_gasmask_dudv() +{ + description.CLS = B_BLUR; +} + +LPCSTR CBlender_gasmask_dudv::getComment() +{ + return "INTERNAL: beef's nightvision"; +} + +void CBlender_gasmask_dudv::Compile(CBlender_Compile& C) +{ + IBlender::Compile(C); + + C.r_Pass("stub_screen_space", "gasmask_dudv", FALSE, FALSE, FALSE); + C.r_dx11Texture("s_image", r2_RT_generic0); + C.r_dx11Texture("s_mask_droplets", "shaders\\gasmasks\\mask_droplets"); + + C.r_dx11Texture("s_mask_nm_1", "shaders\\gasmasks\\mask_nm_1"); + C.r_dx11Texture("s_mask_nm_2", "shaders\\gasmasks\\mask_nm_2"); + C.r_dx11Texture("s_mask_nm_3", "shaders\\gasmasks\\mask_nm_3"); + C.r_dx11Texture("s_mask_nm_4", "shaders\\gasmasks\\mask_nm_4"); + C.r_dx11Texture("s_mask_nm_5", "shaders\\gasmasks\\mask_nm_5"); + C.r_dx11Texture("s_mask_nm_6", "shaders\\gasmasks\\mask_nm_6"); + C.r_dx11Texture("s_mask_nm_7", "shaders\\gasmasks\\mask_nm_7"); + C.r_dx11Texture("s_mask_nm_8", "shaders\\gasmasks\\mask_nm_8"); + C.r_dx11Texture("s_mask_nm_9", "shaders\\gasmasks\\mask_nm_9"); + C.r_dx11Texture("s_mask_nm_10", "shaders\\gasmasks\\mask_nm_10"); + + C.r_dx11Sampler("smp_base"); + C.r_dx11Sampler("smp_nofilter"); + C.r_dx11Sampler("smp_rtlinear"); + C.r_End(); +} diff --git a/src/Layers/xrRender/blenders/blender_gasmask_dudv.h b/src/Layers/xrRender/blenders/blender_gasmask_dudv.h new file mode 100644 index 00000000000..248b5877d96 --- /dev/null +++ b/src/Layers/xrRender/blenders/blender_gasmask_dudv.h @@ -0,0 +1,11 @@ +#pragma once + +class CBlender_gasmask_dudv : public IBlender +{ +public: + CBlender_gasmask_dudv(); + ~CBlender_gasmask_dudv() override = default; + + LPCSTR getComment() override; + void Compile(CBlender_Compile& C) override; +}; diff --git a/src/Layers/xrRender/blenders/blender_light_direct.cpp b/src/Layers/xrRender/blenders/blender_light_direct.cpp index 6b18144d57a..12da7e1d9d5 100644 --- a/src/Layers/xrRender/blenders/blender_light_direct.cpp +++ b/src/Layers/xrRender/blenders/blender_light_direct.cpp @@ -208,6 +208,7 @@ void CBlender_accum_direct::Compile(CBlender_Compile& C) C.r_dx11Texture("s_lmap", r2_sunmask); C.r_dx11Texture("s_smap", r2_RT_smap_depth); C.r_dx11Texture("s_smap_minmax", r2_RT_smap_depth_minmax); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); @@ -249,6 +250,7 @@ void CBlender_accum_direct::Compile(CBlender_Compile& C) C.r_dx11Texture("s_accumulator", r2_RT_accum); C.r_dx11Texture("s_lmap", r2_sunmask); C.r_dx11Texture("s_smap", r2_RT_smap_depth); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); @@ -276,6 +278,7 @@ void CBlender_accum_direct::Compile(CBlender_Compile& C) C.r_dx11Texture("s_normal", r2_RT_N); C.r_dx11Texture("s_material", r2_material); C.r_dx11Texture("s_smap", r2_RT_generic0); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); @@ -304,6 +307,7 @@ void CBlender_accum_direct::Compile(CBlender_Compile& C) C.r_dx11Texture("s_lmap", r2_sunmask); C.r_dx11Texture("s_smap", r2_RT_smap_depth); C.r_dx11Texture("s_smap_minmax", r2_RT_smap_depth_minmax); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); @@ -473,6 +477,7 @@ void CBlender_accum_direct_msaa::Compile(CBlender_Compile& C) C.r_dx11Texture("s_accumulator", r2_RT_accum); C.r_dx11Texture("s_lmap", r2_sunmask); C.r_dx11Texture("s_smap", r2_RT_smap_depth); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); @@ -514,6 +519,7 @@ void CBlender_accum_direct_msaa::Compile(CBlender_Compile& C) C.r_dx11Texture("s_accumulator", r2_RT_accum); C.r_dx11Texture("s_lmap", r2_sunmask); C.r_dx11Texture("s_smap", r2_RT_smap_depth); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); @@ -541,6 +547,7 @@ void CBlender_accum_direct_msaa::Compile(CBlender_Compile& C) C.r_dx11Texture("s_normal", r2_RT_N); C.r_dx11Texture("s_material", r2_material); C.r_dx11Texture("s_smap", r2_RT_generic0); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); @@ -569,6 +576,7 @@ void CBlender_accum_direct_msaa::Compile(CBlender_Compile& C) C.r_dx11Texture("s_lmap", r2_sunmask); C.r_dx11Texture("s_smap", r2_RT_smap_depth); C.r_dx11Texture("s_smap_minmax", r2_RT_smap_depth_minmax); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); diff --git a/src/Layers/xrRender/blenders/blender_light_direct_cascade.cpp b/src/Layers/xrRender/blenders/blender_light_direct_cascade.cpp index 427d458ae49..22388bac47d 100644 --- a/src/Layers/xrRender/blenders/blender_light_direct_cascade.cpp +++ b/src/Layers/xrRender/blenders/blender_light_direct_cascade.cpp @@ -48,6 +48,7 @@ void CBlender_accum_direct_cascade::Compile(CBlender_Compile& C) // C.i_Address (s, D3DTADDRESS_BORDER); // C.i_BorderColor (s, D3DCOLOR_ARGB(255, 255, 255, 255)); // } + C.r_Sampler_rtf("s_diffuse", r2_RT_albedo); C.r_End(); break; case SE_SUN_FAR: // far pass, only stencil clipping performed @@ -72,6 +73,7 @@ void CBlender_accum_direct_cascade::Compile(CBlender_Compile& C) C.i_Address(s, D3DTADDRESS_BORDER); C.i_BorderColor(s, D3DCOLOR_ARGB(255, 255, 255, 255)); } + C.r_Sampler_rtf("s_diffuse", r2_RT_albedo); C.r_End(); break; } diff --git a/src/Layers/xrRender/blenders/blender_light_mask.cpp b/src/Layers/xrRender/blenders/blender_light_mask.cpp index 064c324e87b..5c33294fc85 100644 --- a/src/Layers/xrRender/blenders/blender_light_mask.cpp +++ b/src/Layers/xrRender/blenders/blender_light_mask.cpp @@ -121,6 +121,7 @@ void CBlender_accum_direct_mask::Compile(CBlender_Compile& C) // C.r_Sampler_rtf ("s_normal", r2_RT_N); C.r_dx11Texture("s_normal", r2_RT_N); C.r_dx11Texture("s_position", r2_RT_P); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_ColorWriteEnable(false, false, false, false); C.r_End(); @@ -244,6 +245,7 @@ void CBlender_accum_direct_mask_msaa::Compile(CBlender_Compile& C) // C.r_Sampler_rtf ("s_normal", r2_RT_N); C.r_dx11Texture("s_normal", r2_RT_N); C.r_dx11Texture("s_position", r2_RT_P); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_ColorWriteEnable(false, false, false, false); C.r_End(); diff --git a/src/Layers/xrRender/blenders/blender_light_point.cpp b/src/Layers/xrRender/blenders/blender_light_point.cpp index 1e87d06b3ba..a5e81cc9885 100644 --- a/src/Layers/xrRender/blenders/blender_light_point.cpp +++ b/src/Layers/xrRender/blenders/blender_light_point.cpp @@ -172,6 +172,7 @@ void CBlender_accum_point::Compile(CBlender_Compile& C) C.r_dx11Texture("s_material", r2_material); C.r_dx11Texture("s_lmap", C.L_textures[0]); C.r_dx11Texture("s_accumulator", r2_RT_accum); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); @@ -197,6 +198,7 @@ void CBlender_accum_point::Compile(CBlender_Compile& C) C.r_dx11Texture("s_lmap", C.L_textures[0]); C.r_dx11Texture("s_smap", r2_RT_smap_depth); C.r_dx11Texture("s_accumulator", r2_RT_accum); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); @@ -224,6 +226,7 @@ void CBlender_accum_point::Compile(CBlender_Compile& C) C.r_dx11Texture("s_lmap", C.L_textures[0]); C.r_dx11Texture("s_smap", r2_RT_smap_depth); C.r_dx11Texture("s_accumulator", r2_RT_accum); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); @@ -251,6 +254,7 @@ void CBlender_accum_point::Compile(CBlender_Compile& C) C.r_dx11Texture("s_lmap", C.L_textures[0]); C.r_dx11Texture("s_smap", r2_RT_smap_depth); C.r_dx11Texture("s_accumulator", r2_RT_accum); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); @@ -352,6 +356,7 @@ void CBlender_accum_point_msaa::Compile(CBlender_Compile& C) C.r_dx11Texture("s_material", r2_material); C.r_dx11Texture("s_lmap", C.L_textures[0]); C.r_dx11Texture("s_accumulator", r2_RT_accum); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); @@ -377,6 +382,7 @@ void CBlender_accum_point_msaa::Compile(CBlender_Compile& C) C.r_dx11Texture("s_lmap", C.L_textures[0]); C.r_dx11Texture("s_smap", r2_RT_smap_depth); C.r_dx11Texture("s_accumulator", r2_RT_accum); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); @@ -404,6 +410,7 @@ void CBlender_accum_point_msaa::Compile(CBlender_Compile& C) C.r_dx11Texture("s_lmap", C.L_textures[0]); C.r_dx11Texture("s_smap", r2_RT_smap_depth); C.r_dx11Texture("s_accumulator", r2_RT_accum); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); @@ -431,6 +438,7 @@ void CBlender_accum_point_msaa::Compile(CBlender_Compile& C) C.r_dx11Texture("s_lmap", C.L_textures[0]); C.r_dx11Texture("s_smap", r2_RT_smap_depth); C.r_dx11Texture("s_accumulator", r2_RT_accum); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); diff --git a/src/Layers/xrRender/blenders/blender_light_reflected.cpp b/src/Layers/xrRender/blenders/blender_light_reflected.cpp index bcbefbfa271..ad53644b52f 100644 --- a/src/Layers/xrRender/blenders/blender_light_reflected.cpp +++ b/src/Layers/xrRender/blenders/blender_light_reflected.cpp @@ -33,6 +33,7 @@ void CBlender_accum_reflected::Compile(CBlender_Compile& C) C.r_dx11Texture("s_normal", r2_RT_N); C.r_dx11Texture("s_material", r2_material); C.r_dx11Texture("s_accumulator", r2_RT_accum); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); @@ -68,6 +69,7 @@ void CBlender_accum_reflected_msaa::Compile(CBlender_Compile& C) C.r_dx11Texture("s_normal", r2_RT_N); C.r_dx11Texture("s_material", r2_material); C.r_dx11Texture("s_accumulator", r2_RT_accum); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); diff --git a/src/Layers/xrRender/blenders/blender_light_spot.cpp b/src/Layers/xrRender/blenders/blender_light_spot.cpp index 41978610c8a..43d5fe5b73b 100644 --- a/src/Layers/xrRender/blenders/blender_light_spot.cpp +++ b/src/Layers/xrRender/blenders/blender_light_spot.cpp @@ -170,6 +170,7 @@ void CBlender_accum_spot::Compile(CBlender_Compile& C) C.r_dx11Texture("s_material", r2_material); C.r_dx11Texture("s_lmap", C.L_textures[0]); C.r_dx11Texture("s_accumulator", r2_RT_accum); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); @@ -196,6 +197,7 @@ void CBlender_accum_spot::Compile(CBlender_Compile& C) C.r_dx11Texture("s_lmap", C.L_textures[0]); C.r_dx11Texture("s_smap", r2_RT_smap_depth); C.r_dx11Texture("s_accumulator", r2_RT_accum); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); @@ -224,6 +226,7 @@ void CBlender_accum_spot::Compile(CBlender_Compile& C) C.r_dx11Texture("s_lmap", C.L_textures[0]); C.r_dx11Texture("s_smap", r2_RT_smap_depth); C.r_dx11Texture("s_accumulator", r2_RT_accum); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); @@ -251,6 +254,7 @@ void CBlender_accum_spot::Compile(CBlender_Compile& C) C.r_dx11Texture("s_lmap", C.L_textures[0]); C.r_dx11Texture("s_smap", r2_RT_smap_depth); C.r_dx11Texture("s_accumulator", r2_RT_accum); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); @@ -351,6 +355,7 @@ void CBlender_accum_spot_msaa::Compile(CBlender_Compile& C) C.r_dx11Texture("s_material", r2_material); C.r_dx11Texture("s_lmap", C.L_textures[0]); C.r_dx11Texture("s_accumulator", r2_RT_accum); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); @@ -377,6 +382,7 @@ void CBlender_accum_spot_msaa::Compile(CBlender_Compile& C) C.r_dx11Texture("s_lmap", C.L_textures[0]); C.r_dx11Texture("s_smap", r2_RT_smap_depth); C.r_dx11Texture("s_accumulator", r2_RT_accum); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); @@ -405,6 +411,7 @@ void CBlender_accum_spot_msaa::Compile(CBlender_Compile& C) C.r_dx11Texture("s_lmap", C.L_textures[0]); C.r_dx11Texture("s_smap", r2_RT_smap_depth); C.r_dx11Texture("s_accumulator", r2_RT_accum); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); @@ -432,6 +439,7 @@ void CBlender_accum_spot_msaa::Compile(CBlender_Compile& C) C.r_dx11Texture("s_lmap", C.L_textures[0]); C.r_dx11Texture("s_smap", r2_RT_smap_depth); C.r_dx11Texture("s_accumulator", r2_RT_accum); + C.r_dx11Texture("s_diffuse", r2_RT_albedo); C.r_dx11Sampler("smp_nofilter"); C.r_dx11Sampler("smp_material"); diff --git a/src/Layers/xrRender/blenders/blender_nightvision.cpp b/src/Layers/xrRender/blenders/blender_nightvision.cpp new file mode 100644 index 00000000000..fb0320d4dda --- /dev/null +++ b/src/Layers/xrRender/blenders/blender_nightvision.cpp @@ -0,0 +1,74 @@ +#include "stdafx.h" + +#include "blender_nightvision.h" + +CBlender_nightvision::CBlender_nightvision() +{ + description.CLS = B_BLUR; +} + +LPCSTR CBlender_nightvision::getComment() +{ + return "INTERNAL: beef's nightvision"; +} + +void CBlender_nightvision::Compile(CBlender_Compile& C) +{ + IBlender::Compile(C); +#if RENDER == R_R4 + switch (C.iElement) + { + case 0: //Dummy shader - because IDK what gonna happen when r2_nightvision will be 0 + C.r_Pass("stub_screen_space", "copy_nomsaa", FALSE, FALSE, FALSE); + C.r_dx11Texture("s_generic", r2_RT_generic0); + + C.r_dx11Sampler("smp_base"); + C.r_dx11Sampler("smp_nofilter"); + C.r_dx11Sampler("smp_rtlinear"); + C.r_End(); + break; + case 1: + C.r_Pass("stub_screen_space", "nightvision_gen_1", FALSE, FALSE, FALSE); + C.r_dx11Texture("s_position", r2_RT_P); + C.r_dx11Texture("s_image", r2_RT_generic0); + //C.r_dx11Texture("s_bloom_new", r2_RT_pp_bloom); + C.r_dx11Texture("s_blur_2", r2_RT_blur_2); + C.r_dx11Texture("s_blur_4", r2_RT_blur_4); + C.r_dx11Texture("s_blur_8", r2_RT_blur_8); + + C.r_dx11Sampler("smp_base"); + C.r_dx11Sampler("smp_nofilter"); + C.r_dx11Sampler("smp_rtlinear"); + C.r_End(); + break; + case 2: + C.r_Pass("stub_screen_space", "nightvision_gen_2", FALSE, FALSE, FALSE); + C.r_dx11Texture("s_position", r2_RT_P); + C.r_dx11Texture("s_image", r2_RT_generic0); + //C.r_dx11Texture("s_bloom_new", r2_RT_pp_bloom); + C.r_dx11Texture("s_blur_2", r2_RT_blur_2); + C.r_dx11Texture("s_blur_4", r2_RT_blur_4); + C.r_dx11Texture("s_blur_8", r2_RT_blur_8); + + C.r_dx11Sampler("smp_base"); + C.r_dx11Sampler("smp_nofilter"); + C.r_dx11Sampler("smp_rtlinear"); + C.r_End(); + break; + case 3: + C.r_Pass("stub_screen_space", "nightvision_gen_3", FALSE, FALSE, FALSE); + C.r_dx11Texture("s_position", r2_RT_P); + C.r_dx11Texture("s_image", r2_RT_generic0); + //C.r_dx11Texture("s_bloom_new", r2_RT_pp_bloom); + C.r_dx11Texture("s_blur_2", r2_RT_blur_2); + C.r_dx11Texture("s_blur_4", r2_RT_blur_4); + C.r_dx11Texture("s_blur_8", r2_RT_blur_8); + + C.r_dx11Sampler("smp_base"); + C.r_dx11Sampler("smp_nofilter"); + C.r_dx11Sampler("smp_rtlinear"); + C.r_End(); + break; + } +#endif +} diff --git a/src/Layers/xrRender/blenders/blender_nightvision.h b/src/Layers/xrRender/blenders/blender_nightvision.h new file mode 100644 index 00000000000..880951b4b43 --- /dev/null +++ b/src/Layers/xrRender/blenders/blender_nightvision.h @@ -0,0 +1,11 @@ +#pragma once + +class CBlender_nightvision : public IBlender +{ +public: + CBlender_nightvision(); + ~CBlender_nightvision() override = default; + + LPCSTR getComment() override; + void Compile(CBlender_Compile& C) override; +}; diff --git a/src/Layers/xrRender/dxRainRender.cpp b/src/Layers/xrRender/dxRainRender.cpp index b0cb62873ac..0adc12819eb 100644 --- a/src/Layers/xrRender/dxRainRender.cpp +++ b/src/Layers/xrRender/dxRainRender.cpp @@ -34,6 +34,11 @@ dxRainRender::dxRainRender() hGeom_Rain.create(FVF::F_LIT, RImplementation.Vertex.Buffer(), RImplementation.QuadIB); hGeom_Drops.create(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1, RImplementation.Vertex.Buffer(), RImplementation.Index.Buffer()); +#if defined(USE_DX11) + if (RImplementation.o.ssfx_rain) + SH_Splash.create("effects\\rain_splash", "fx\\fx_rain"); +#endif + FS.r_close(F); } @@ -46,6 +51,23 @@ void dxRainRender::Render(CEffect_Rain& owner) if (factor < EPS_L) return; + float _drop_len = drop_length; + float _drop_width = drop_width; + float _drop_speed = 1.0f; + ref_shader& _splash_SH = DM_Drop->shader; + static shared_str s_shader_setup = "ssfx_rain_setup"; + + // SSS Rain shader is available +#if defined(USE_DX11) + if (RImplementation.o.ssfx_rain) + { + _drop_len = ps_ssfx_rain_1.x; + _drop_width = ps_ssfx_rain_1.y; + _drop_speed = ps_ssfx_rain_1.z; + _splash_SH = SH_Splash; + } +#endif + const u32 desired_items = iFloor(0.5f * (1.f + factor) * float(max_desired_items)); // born _new_ if needed @@ -55,7 +77,7 @@ void dxRainRender::Render(CEffect_Rain& owner) while (owner.items.size() < desired_items) { CEffect_Rain::Item one; - owner.Born(one, source_radius); + owner.Born(one, source_radius, _drop_speed); owner.items.push_back(one); } } @@ -87,7 +109,7 @@ void dxRainRender::Render(CEffect_Rain& owner) if (one.dwTime_Hit < Device.dwTimeGlobal) owner.Hit(one.Phit); if (one.dwTime_Life < Device.dwTimeGlobal) - owner.Born(one, source_radius); + owner.Born(one, source_radius, _drop_speed); // последняя дельта ?? //. float xdt = float(one.dwTime_Hit-Device.dwTimeGlobal)/1000.f; @@ -147,7 +169,10 @@ void dxRainRender::Render(CEffect_Rain& owner) // Build line Fvector& pos_head = one.P; Fvector pos_trail; - pos_trail.mad(pos_head, one.D, -drop_length * factor_visual); + if (ps_r2_ls_flags_ext.test(R4FLAGEXT_NEW_SHADER_SUPPORT)) + pos_trail.mad(pos_head, one.D, -_drop_len * factor_visual); + else + pos_trail.mad(pos_head, one.D, -drop_length * factor_visual); // Culling Fvector sC, lineD; @@ -167,7 +192,7 @@ void dxRainRender::Render(CEffect_Rain& owner) camDir.sub(sC, vEye); camDir.normalize(); lineTop.crossproduct(camDir, lineD); - float w = drop_width; + float w = ps_r2_ls_flags_ext.test(R4FLAGEXT_NEW_SHADER_SUPPORT) ? _drop_width : drop_width; u32 s = one.uv_set; P.mad(pos_trail, lineTop, -w); verts->set(P, u_rain_color, UV[s][0].x, UV[s][0].y); @@ -196,6 +221,7 @@ void dxRainRender::Render(CEffect_Rain& owner) RCache.Render(D3DPT_TRIANGLELIST, vOffset, 0, vCount, 0, vCount / 2); // HW.pDevice->SetRenderState (D3DRS_CULLMODE,D3DCULL_CCW); RCache.set_CullMode(CULL_CCW); + RCache.set_c(s_shader_setup, ps_ssfx_rain_2); // Alpha, Brigthness, Refraction, Reflection } // Particles @@ -206,7 +232,15 @@ void dxRainRender::Render(CEffect_Rain& owner) { float dt = Device.fTimeDelta; _IndexStream& _IS = RImplementation.Index; - RCache.set_Shader(DM_Drop->shader); + if (ps_r2_ls_flags_ext.test(R4FLAGEXT_NEW_SHADER_SUPPORT)) + { + RCache.set_Shader(_splash_SH); + RCache.set_c(s_shader_setup, ps_ssfx_rain_3); // Alpha, Refraction + } + else + { + RCache.set_Shader(DM_Drop->shader); + } Fmatrix mXform, mScale; int pcount = 0; diff --git a/src/Layers/xrRender/dxRainRender.h b/src/Layers/xrRender/dxRainRender.h index 117cc95b3f1..f9daff1288e 100644 --- a/src/Layers/xrRender/dxRainRender.h +++ b/src/Layers/xrRender/dxRainRender.h @@ -23,6 +23,7 @@ class dxRainRender : public IRainRender // Visualization (drops) IRender_DetailModel* DM_Drop; ref_geom hGeom_Drops; + ref_shader SH_Splash; }; #endif // RainRender_included diff --git a/src/Layers/xrRender/dxWallMarkArray.cpp b/src/Layers/xrRender/dxWallMarkArray.cpp index e0f528fcf72..eaa2b1640ad 100644 --- a/src/Layers/xrRender/dxWallMarkArray.cpp +++ b/src/Layers/xrRender/dxWallMarkArray.cpp @@ -13,7 +13,16 @@ dxWallMarkArray::~dxWallMarkArray() void dxWallMarkArray::AppendMark(LPCSTR s_textures) { ref_shader s; - s.create("effects" DELIMITER "wallmark", s_textures); + LPCSTR sh_name = "effects" DELIMITER "wallmark"; +#if defined(USE_DX11) + if (RImplementation.o.ssfx_blood) + { + // Use the blood shader for any texture with the name wm_blood_* + if (strstr(s_textures, "wm_blood_")) + sh_name = "effects" DELIMITER "wallmark_blood"; + } +#endif + s.create(sh_name, s_textures); m_CollideMarks.push_back(s); } diff --git a/src/Layers/xrRender/light.h b/src/Layers/xrRender/light.h index 4a5478b77f1..84c0917358e 100644 --- a/src/Layers/xrRender/light.h +++ b/src/Layers/xrRender/light.h @@ -72,6 +72,7 @@ class light : public IRender_Light, public SpatialBase bool visible; // visible/invisible bool pending; // test is still pending u16 smap_ID; + float distance; } vis; union _xform diff --git a/src/Layers/xrRender/light_vis.cpp b/src/Layers/xrRender/light_vis.cpp index d558652f15b..27674c1f2a9 100644 --- a/src/Layers/xrRender/light_vis.cpp +++ b/src/Layers/xrRender/light_vis.cpp @@ -40,7 +40,9 @@ void light::vis_prepare(CBackend& cmd_list) if (ps_r2_ls_flags.test(R2FLAG_EXP_DONT_TEST_SHADOWED) && flags.bShadow) skiptest = true; - if (skiptest || Device.vCameraPosition.distance_to(spatial.sphere.P) <= (spatial.sphere.R * 1.01f + safe_area)) + vis.distance = Device.vCameraPosition.distance_to(spatial.sphere.P); + + if (skiptest || vis.distance <= (spatial.sphere.R * 1.01f + safe_area)) { // small error vis.visible = true; vis.pending = false; diff --git a/src/Layers/xrRender/r__dsgraph_build.cpp b/src/Layers/xrRender/r__dsgraph_build.cpp index 6c680c7e5cc..8d6a54987de 100644 --- a/src/Layers/xrRender/r__dsgraph_build.cpp +++ b/src/Layers/xrRender/r__dsgraph_build.cpp @@ -56,10 +56,14 @@ void R_dsgraph_structure::insert_dynamic(IRenderable* root, dxRender_Visual* pVi // a) Allow to optimize RT order // b) Should be rendered to special distort buffer in another pass VERIFY(pVisual->shader._get()); - ShaderElement* sh_d = pVisual->shader->E[4]._get(); // 4=L_special - if (RImplementation.o.distortion && sh_d && sh_d->flags.bDistort && o.pmask[sh_d->flags.iPriority / 2]) + const Shader* vis_sh = pVisual->shader._get(); + ShaderElement* sh_d = vis_sh ? vis_sh->E[4]._get() : nullptr; // 4=L_special + if (sh_d) { - mapDistort.insert_anyway(distSQ, _MatrixItemS({ SSA, root, pVisual, xform, sh_d })); // sh_d -> L_special + if (RImplementation.o.distortion && sh_d && sh_d->flags.bDistort && o.pmask[sh_d->flags.iPriority / 2]) + { + mapDistort.insert_anyway(distSQ, _MatrixItemS({ SSA, root, pVisual, xform, sh_d })); // sh_d -> L_special + } } // Select shader @@ -80,7 +84,7 @@ void R_dsgraph_structure::insert_dynamic(IRenderable* root, dxRender_Visual* pVi mapHUD.insert_anyway(distSQ, _MatrixItemS({ SSA, root, pVisual, xform, sh })); #if RENDER != R_R1 - if (sh->flags.bEmissive) + if (sh->flags.bEmissive && sh_d) mapHUDEmissive.insert_anyway(distSQ, _MatrixItemS({ SSA, root, pVisual, xform, sh_d })); // sh_d -> L_special #endif return; @@ -165,10 +169,14 @@ void R_dsgraph_structure::insert_static(dxRender_Visual* pVisual) // a) Allow to optimize RT order // b) Should be rendered to special distort buffer in another pass VERIFY(pVisual->shader._get()); - ShaderElement* sh_d = pVisual->shader->E[4]._get(); // 4=L_special - if (RImplementation.o.distortion && sh_d && sh_d->flags.bDistort && o.pmask[sh_d->flags.iPriority / 2]) + const Shader* vis_sh = pVisual->shader._get(); + ShaderElement* sh_d = vis_sh ? vis_sh->E[4]._get() : nullptr; // 4=L_special + if (sh_d) { - mapDistort.insert_anyway(distSQ, _MatrixItemS({ SSA, nullptr, pVisual, Fidentity, sh_d })); // sh_d -> L_special + if (RImplementation.o.distortion && sh_d && sh_d->flags.bDistort && o.pmask[sh_d->flags.iPriority / 2]) + { + mapDistort.insert_anyway(distSQ, _MatrixItemS({ SSA, nullptr, pVisual, Fidentity, sh_d })); // sh_d -> L_special + } } // Select shader @@ -193,7 +201,7 @@ void R_dsgraph_structure::insert_static(dxRender_Visual* pVisual) // b) Allow to make them 100% lit and really bright // c) Should not cast shadows // d) Should be rendered to accumulation buffer in the second pass - if (sh->flags.bEmissive) + if (sh->flags.bEmissive && sh_d) { mapEmissive.insert_anyway(distSQ, _MatrixItemS({ SSA, nullptr, pVisual, Fidentity, sh_d })); // sh_d -> L_special } diff --git a/src/Layers/xrRender/r__dsgraph_render_lods.cpp b/src/Layers/xrRender/r__dsgraph_render_lods.cpp index 87f8bafc4af..0f5b6b49de7 100644 --- a/src/Layers/xrRender/r__dsgraph_render_lods.cpp +++ b/src/Layers/xrRender/r__dsgraph_render_lods.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "FLOD.h" +#include "xrCommon/xr_array.h" #ifdef _EDITOR #include "IGame_Persistent.h" @@ -88,25 +89,24 @@ void R_dsgraph_structure::render_lods(bool _setup_zb, bool _clear) return v1.first < v2.first; }); - float dot_best = selector[selector.size() - 1].first; - float dot_next = selector[selector.size() - 2].first; - float dot_next_2 = selector[selector.size() - 3].first; - u32 id_best = selector[selector.size() - 1].second; - u32 id_next = selector[selector.size() - 2].second; + const float dot_best = selector[selector.size() - 1].first; + const float dot_next = selector[selector.size() - 2].first; + const float dot_next_2 = selector[selector.size() - 3].first; + size_t id_best = selector[selector.size() - 1].second; + size_t id_next = selector[selector.size() - 2].second; // Now we have two "best" planes, calculate factor, and approx normal - float fA = dot_best, fB = dot_next, fC = dot_next_2; - float alpha = 0.5f + 0.5f * (1 - (fB - fC) / (fA - fC)); - int iF = iFloor(alpha * 255.5f); - u32 uF = u32(clampr(iF, 0, 255)); + const float fA = dot_best, fB = dot_next, fC = dot_next_2; + const float alpha = 0.5f + 0.5f * (1 - (fB - fC) / (fA - fC)); + const int iF = iFloor(alpha * 255.5f); + const u32 uF = u32(clampr(iF, 0, 255)); // Fill VB - FLOD::_face& FA = facets[id_best]; - FLOD::_face& FB = facets[id_next]; - static int vid[4] = {3, 0, 2, 1}; - for (u32 vit = 0; vit < 4; vit++) + const FLOD::_face& FA = facets[id_best]; + const FLOD::_face& FB = facets[id_next]; + xr_array vid = {3, 0, 2, 1}; + for (int id : vid) { - int id = vid[vit]; V->p0.add(FB.v[id].v, shift); V->p1.add(FA.v[id].v, shift); V->n0 = FB.N; @@ -129,9 +129,8 @@ void R_dsgraph_structure::render_lods(bool _setup_zb, bool _clear) int current = 0; u32 vCurOffset = vOffset; - for (u32 g = 0; g < lstLODgroups.size(); g++) + for (int p_count : lstLODgroups) { - int p_count = lstLODgroups[g]; u32 uiNumPasses = lstLODs[current].pVisual->shader->E[shid]->passes.size(); if (uiPass < uiNumPasses) { diff --git a/src/Layers/xrRender/rendertarget_phase_blur.cpp b/src/Layers/xrRender/rendertarget_phase_blur.cpp new file mode 100644 index 00000000000..b1144f60307 --- /dev/null +++ b/src/Layers/xrRender/rendertarget_phase_blur.cpp @@ -0,0 +1,149 @@ +#include "stdafx.h" + +void CRenderTarget::phase_blur() +{ + //Get common data + u32 Offset = 0; + float d_Z = EPS_S; + float d_W = 1.0f; + u32 C = color_rgba(0, 0, 0, 255); + + //Full resolution + float w = float(Device.dwWidth); + float h = float(Device.dwHeight); + + Fvector2 p0, p1; + p0.set(0.0f, 0.0f); + p1.set(1.0f, 1.0f); + +/////////////////////////////////////////////////////////////////////////////////// +////Horizontal blur +/////////////////////////////////////////////////////////////////////////////////// + w = float(Device.dwWidth) * 0.5f; + h = float(Device.dwHeight) * 0.5f; + + u_setrt(RCache, rt_blur_h_2, 0, 0, get_base_zb()); + RCache.set_CullMode(CULL_NONE); + RCache.set_Stencil(FALSE); + + // Fill vertex buffer + FVF::TL* pv = (FVF::TL*)RImplementation.Vertex.Lock(4, g_combine->vb_stride, Offset); + pv->set(0, float(h), d_Z, d_W, C, p0.x, p1.y); pv++; + pv->set(0, 0, d_Z, d_W, C, p0.x, p0.y); pv++; + pv->set(float(w), float(h), d_Z, d_W, C, p1.x, p1.y); pv++; + pv->set(float(w), 0, d_Z, d_W, C, p1.x, p0.y); pv++; + RImplementation.Vertex.Unlock(4, g_combine->vb_stride); + + // Draw COLOR + RCache.set_Element(s_blur->E[0]); + RCache.set_c("blur_params", 1.f, 0.f, w, h); + RCache.set_Geometry(g_combine); + RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); +/////////////////////////////////////////////////////////////////////////////////// +////Final blur +/////////////////////////////////////////////////////////////////////////////////// + u_setrt(RCache, rt_blur_2, 0, 0, get_base_zb()); + RCache.set_CullMode(CULL_NONE); + RCache.set_Stencil(FALSE); + + // Fill vertex buffer + pv = (FVF::TL*)RImplementation.Vertex.Lock(4, g_combine->vb_stride, Offset); + pv->set(0, float(h), d_Z, d_W, C, p0.x, p1.y); pv++; + pv->set(0, 0, d_Z, d_W, C, p0.x, p0.y); pv++; + pv->set(float(w), float(h), d_Z, d_W, C, p1.x, p1.y); pv++; + pv->set(float(w), 0, d_Z, d_W, C, p1.x, p0.y); pv++; + RImplementation.Vertex.Unlock(4, g_combine->vb_stride); + + // Draw COLOR + RCache.set_Element(s_blur->E[1]); + RCache.set_c("blur_params", 0.f, 1.f, w, h); + RCache.set_Geometry(g_combine); + RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); +/////////////////////////////////////////////////////////////////////////////////// +////Horizontal blur / Half res +/////////////////////////////////////////////////////////////////////////////////// + w = float(Device.dwWidth) * 0.25f; + h = float(Device.dwHeight) * 0.25f; + + u_setrt(RCache, rt_blur_h_4, 0, 0, get_base_zb()); + RCache.set_CullMode(CULL_NONE); + RCache.set_Stencil(FALSE); + + // Fill vertex buffer + pv = (FVF::TL*)RImplementation.Vertex.Lock(4, g_combine->vb_stride, Offset); + pv->set(0, float(h), d_Z, d_W, C, p0.x, p1.y); pv++; + pv->set(0, 0, d_Z, d_W, C, p0.x, p0.y); pv++; + pv->set(float(w), float(h), d_Z, d_W, C, p1.x, p1.y); pv++; + pv->set(float(w), 0, d_Z, d_W, C, p1.x, p0.y); pv++; + RImplementation.Vertex.Unlock(4, g_combine->vb_stride); + + // Draw COLOR + RCache.set_Element(s_blur->E[2]); + RCache.set_c("blur_params", 1.f, 0.f, w, h); + RCache.set_Geometry(g_combine); + RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); +/////////////////////////////////////////////////////////////////////////////////// +////Final blur +/////////////////////////////////////////////////////////////////////////////////// + u_setrt(RCache, rt_blur_4, 0, 0, get_base_zb()); + RCache.set_CullMode(CULL_NONE); + RCache.set_Stencil(FALSE); + + // Fill vertex buffer + pv = (FVF::TL*)RImplementation.Vertex.Lock(4, g_combine->vb_stride, Offset); + pv->set(0, float(h), d_Z, d_W, C, p0.x, p1.y); pv++; + pv->set(0, 0, d_Z, d_W, C, p0.x, p0.y); pv++; + pv->set(float(w), float(h), d_Z, d_W, C, p1.x, p1.y); pv++; + pv->set(float(w), 0, d_Z, d_W, C, p1.x, p0.y); pv++; + RImplementation.Vertex.Unlock(4, g_combine->vb_stride); + + // Draw COLOR + RCache.set_Element(s_blur->E[3]); + RCache.set_c("blur_params", 0.f, 1.f, w, h); + RCache.set_Geometry(g_combine); + RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); +/////////////////////////////////////////////////////////////////////////////////// +////Horizontal blur +/////////////////////////////////////////////////////////////////////////////////// + w = float(Device.dwWidth) * 0.125f; + h = float(Device.dwHeight) * 0.125f; + + u_setrt(RCache, rt_blur_h_8, 0, 0, get_base_zb()); + RCache.set_CullMode(CULL_NONE); + RCache.set_Stencil(FALSE); + + // Fill vertex buffer + pv = (FVF::TL*)RImplementation.Vertex.Lock(4, g_combine->vb_stride, Offset); + pv->set(0, float(h), d_Z, d_W, C, p0.x, p1.y); pv++; + pv->set(0, 0, d_Z, d_W, C, p0.x, p0.y); pv++; + pv->set(float(w), float(h), d_Z, d_W, C, p1.x, p1.y); pv++; + pv->set(float(w), 0, d_Z, d_W, C, p1.x, p0.y); pv++; + RImplementation.Vertex.Unlock(4, g_combine->vb_stride); + + // Draw COLOR + RCache.set_Element(s_blur->E[4]); + RCache.set_c("blur_params", 1.f, 0.f, w, h); + RCache.set_Geometry(g_combine); + RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); +/////////////////////////////////////////////////////////////////////////////////// +////Final blur +/////////////////////////////////////////////////////////////////////////////////// + u_setrt(RCache, rt_blur_8, 0, 0, get_base_zb()); + RCache.set_CullMode(CULL_NONE); + RCache.set_Stencil(FALSE); + + // Fill vertex buffer + pv = (FVF::TL*)RImplementation.Vertex.Lock(4, g_combine->vb_stride, Offset); + pv->set(0, float(h), d_Z, d_W, C, p0.x, p1.y); pv++; + pv->set(0, 0, d_Z, d_W, C, p0.x, p0.y); pv++; + pv->set(float(w), float(h), d_Z, d_W, C, p1.x, p1.y); pv++; + pv->set(float(w), 0, d_Z, d_W, C, p1.x, p0.y); pv++; + RImplementation.Vertex.Unlock(4, g_combine->vb_stride); + + // Draw COLOR + RCache.set_Element(s_blur->E[5]); + RCache.set_c("blur_params", 0.f, 1.f, w, h); + RCache.set_Geometry(g_combine); + RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); +/////////////////////////////////////////////////////////////////////////////////// +}; diff --git a/src/Layers/xrRender/rendertarget_phase_dof.cpp b/src/Layers/xrRender/rendertarget_phase_dof.cpp new file mode 100644 index 00000000000..9dd5ff2b80d --- /dev/null +++ b/src/Layers/xrRender/rendertarget_phase_dof.cpp @@ -0,0 +1,52 @@ +#include "stdafx.h" + +void CRenderTarget::phase_dof() +{ + //Constants + u32 Offset = 0; + u32 C = color_rgba(0, 0, 0, 255); + + float d_Z = EPS_S; + float d_W = 1.0f; + float w = float(Device.dwWidth); + float h = float(Device.dwHeight); + + Fvector2 p0, p1; + p0.set(0.0f, 0.0f); + p1.set(1.0f, 1.0f); + + //DoF vectors + Fvector2 vDofKernel; + vDofKernel.set(0.5f / Device.dwWidth, 0.5f / Device.dwHeight); + vDofKernel.mul(ps_r2_dof_kernel_size); + Fvector3 dof; + g_pGamePersistent->GetCurrentDof(dof); + + ////////////////////////////////////////////////////////////////////////// + //Set MSAA/NonMSAA rendertarget + u_setrt(RCache, rt_dof, 0, 0, get_base_zb()); + + RCache.set_CullMode(CULL_NONE); + RCache.set_Stencil(FALSE); + + //Fill vertex buffer + FVF::TL* pv = (FVF::TL*)RImplementation.Vertex.Lock(4, g_combine->vb_stride, Offset); + pv->set(0, float(h), d_Z, d_W, C, p0.x, p1.y); pv++; + pv->set(0, 0, d_Z, d_W, C, p0.x, p0.y); pv++; + pv->set(float(w), float(h), d_Z, d_W, C, p1.x, p1.y); pv++; + pv->set(float(w), 0, d_Z, d_W, C, p1.x, p0.y); pv++; + RImplementation.Vertex.Unlock(4, g_combine->vb_stride); + + //Set pass + RCache.set_Element(s_dof->E[0]); + + //Set paramterers + //RCache.set_c("taa_params", ps_taa_params.x, ps_taa_params.y, 0, 0); + RCache.set_c("dof_params", dof.x, dof.y, dof.z, ps_r2_dof_sky); + RCache.set_c("dof_kernel", vDofKernel.x, vDofKernel.y, ps_r2_dof_kernel_size, 0.f); + + //Set geometry + RCache.set_Geometry(g_combine); + RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); + HW.get_context(CHW::IMM_CTX_ID)->CopyResource(rt_Generic_0->pTexture->surface_get(), rt_dof->pTexture->surface_get()); +}; diff --git a/src/Layers/xrRender/rendertarget_phase_gasmask_drops.cpp b/src/Layers/xrRender/rendertarget_phase_gasmask_drops.cpp new file mode 100644 index 00000000000..2eee547075b --- /dev/null +++ b/src/Layers/xrRender/rendertarget_phase_gasmask_drops.cpp @@ -0,0 +1,57 @@ +#include "stdafx.h" + +void CRenderTarget::phase_gasmask_drops() +{ + //Constants + u32 Offset = 0; + u32 C = color_rgba(0, 0, 0, 255); + + float d_Z = EPS_S; + float d_W = 1.0f; + float w = float(Device.dwWidth); + float h = float(Device.dwHeight); + + Fvector2 p0, p1; +#if defined(USE_DX11) + p0.set(0.0f, 0.0f); + p1.set(1.0f, 1.0f); +#else + p0.set(0.5f / w, 0.5f / h); + p1.set((w + 0.5f) / w, (h + 0.5f) / h); +#endif + + ////////////////////////////////////////////////////////////////////////// + //Set MSAA/NonMSAA rendertarget +#if defined(USE_DX11) + ref_rt& dest_rt = RImplementation.o.msaa ? rt_Generic : rt_Color; + u_setrt(RCache, dest_rt, nullptr, nullptr, nullptr); +#else + u_setrt(rt_Generic_0, nullptr, nullptr, nullptr); +#endif + + RCache.set_CullMode(CULL_NONE); + RCache.set_Stencil(FALSE); + + //Fill vertex buffer + FVF::TL* pv = (FVF::TL*)RImplementation.Vertex.Lock(4, g_combine->vb_stride, Offset); + pv->set(0, float(h), d_Z, d_W, C, p0.x, p1.y); pv++; + pv->set(0, 0, d_Z, d_W, C, p0.x, p0.y); pv++; + pv->set(float(w), float(h), d_Z, d_W, C, p1.x, p1.y); pv++; + pv->set(float(w), 0, d_Z, d_W, C, p1.x, p0.y); pv++; + RImplementation.Vertex.Unlock(4, g_combine->vb_stride); + + //Set pass + RCache.set_Element(s_gasmask_drops->E[0]); + + //Set parameters + RCache.set_c("drops_control", ps_r2_drops_control.x, ps_r2_drops_control.y, ps_r2_drops_control.z, 0.f); + RCache.set_c("mask_control", ps_r2_mask_control.x, ps_r2_mask_control.y, ps_r2_mask_control.z, ps_r2_mask_control.w); + + //Set geometry + RCache.set_Geometry(g_combine); + RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); + +#if defined(USE_DX11) + HW.get_context(CHW::IMM_CTX_ID)->CopyResource(rt_Generic_0->pTexture->surface_get(), dest_rt->pTexture->surface_get()); +#endif +}; diff --git a/src/Layers/xrRender/rendertarget_phase_gasmask_dudv.cpp b/src/Layers/xrRender/rendertarget_phase_gasmask_dudv.cpp new file mode 100644 index 00000000000..edaf493ad7b --- /dev/null +++ b/src/Layers/xrRender/rendertarget_phase_gasmask_dudv.cpp @@ -0,0 +1,60 @@ +#include "stdafx.h" + +void CRenderTarget::phase_gasmask_dudv() +{ + //Constants + u32 Offset = 0; + u32 C = color_rgba(0, 0, 0, 255); + + float d_Z = EPS_S; + float d_W = 1.0f; + float w = float(Device.dwWidth); + float h = float(Device.dwHeight); + + Fvector2 p0, p1; +#if defined(USE_DX11) + p0.set(0.0f, 0.0f); + p1.set(1.0f, 1.0f); +#else + p0.set(0.5f / w, 0.5f / h); + p1.set((w + 0.5f) / w, (h + 0.5f) / h); +#endif + + ////////////////////////////////////////////////////////////////////////// + //Set MSAA/NonMSAA rendertarget +#if defined(USE_DX11) + ref_rt& dest_rt = RImplementation.o.msaa ? rt_Generic : rt_Color; + u_setrt(RCache, dest_rt, nullptr, nullptr, nullptr); +#else + u_setrt(rt_Generic_0, nullptr, nullptr, nullptr); +#endif + + RCache.set_CullMode(CULL_NONE); + RCache.set_Stencil(FALSE); + + //Fill vertex buffer + FVF::TL* pv = (FVF::TL*)RImplementation.Vertex.Lock(4, g_combine->vb_stride, Offset); + pv->set(0, float(h), d_Z, d_W, C, p0.x, p1.y); + pv++; + pv->set(0, 0, d_Z, d_W, C, p0.x, p0.y); + pv++; + pv->set(float(w), float(h), d_Z, d_W, C, p1.x, p1.y); + pv++; + pv->set(float(w), 0, d_Z, d_W, C, p1.x, p0.y); + pv++; + RImplementation.Vertex.Unlock(4, g_combine->vb_stride); + + //Set pass + RCache.set_Element(s_gasmask_dudv->E[0]); + + //Set parameters + RCache.set_c("mask_control", ps_r2_mask_control.x, ps_r2_mask_control.y, ps_r2_mask_control.z, ps_r2_mask_control.w); + + //Set geometry + RCache.set_Geometry(g_combine); + RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); + +#if defined(USE_DX11) + HW.get_context(CHW::IMM_CTX_ID)->CopyResource(rt_Generic_0->pTexture->surface_get(), dest_rt->pTexture->surface_get()); +#endif +}; diff --git a/src/Layers/xrRender/rendertarget_phase_nightvision.cpp b/src/Layers/xrRender/rendertarget_phase_nightvision.cpp new file mode 100644 index 00000000000..52a3a0f8c43 --- /dev/null +++ b/src/Layers/xrRender/rendertarget_phase_nightvision.cpp @@ -0,0 +1,46 @@ +#include "stdafx.h" + +void CRenderTarget::phase_nightvision() +{ + //Constants + u32 Offset = 0; + u32 C = color_rgba(0, 0, 0, 255); + + float d_Z = EPS_S; + float d_W = 1.0f; + float w = float(Device.dwWidth); + float h = float(Device.dwHeight); + + Fvector2 p0, p1; + p0.set(0.0f, 0.0f); + p1.set(1.0f, 1.0f); + + ////////////////////////////////////////////////////////////////////////// + //Set MSAA/NonMSAA rendertarget + ref_rt& dest_rt = RImplementation.o.msaa ? rt_Generic : rt_Color; + u_setrt(RCache, dest_rt, nullptr, nullptr, nullptr); + + RCache.set_CullMode(CULL_NONE); + RCache.set_Stencil(FALSE); + + //Fill vertex buffer + FVF::TL* pv = (FVF::TL*)RImplementation.Vertex.Lock(4, g_combine->vb_stride, Offset); + pv->set(0, float(h), d_Z, d_W, C, p0.x, p1.y); + pv++; + pv->set(0, 0, d_Z, d_W, C, p0.x, p0.y); + pv++; + pv->set(float(w), float(h), d_Z, d_W, C, p1.x, p1.y); + pv++; + pv->set(float(w), 0, d_Z, d_W, C, p1.x, p0.y); + pv++; + RImplementation.Vertex.Unlock(4, g_combine->vb_stride); + + //Set pass + RCache.set_Element(s_nightvision->E[ps_r2_nightvision]); + + //Set geometry + RCache.set_Geometry(g_combine); + RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); + + HW.get_context(CHW::IMM_CTX_ID)->CopyResource(rt_Generic_0->pTexture->surface_get(), dest_rt->pTexture->surface_get()); +}; diff --git a/src/Layers/xrRender/xrRender_console.cpp b/src/Layers/xrRender/xrRender_console.cpp index 48f97642273..9fd2ea41319 100644 --- a/src/Layers/xrRender/xrRender_console.cpp +++ b/src/Layers/xrRender/xrRender_console.cpp @@ -210,6 +210,40 @@ int ps_r2_wait_timeout = 500; float ps_r2_lt_smooth = 1.f; // 1.f float ps_r2_slight_fade = 0.5f; // 1.f +// Anomaly +extern ENGINE_API float ps_r2_img_exposure; // r2-only +extern ENGINE_API float ps_r2_img_gamma; // r2-only +extern ENGINE_API float ps_r2_img_saturation; // r2-only +extern ENGINE_API Fvector ps_r2_img_cg; // r2-only +extern ENGINE_API Fvector4 ps_r2_mask_control; // r2-only +extern ENGINE_API Fvector ps_r2_drops_control; // r2-only +extern ENGINE_API int ps_r2_nightvision; + +//debug +extern ENGINE_API Fvector4 ps_dev_param_1; +extern ENGINE_API Fvector4 ps_dev_param_2; +extern ENGINE_API Fvector4 ps_dev_param_3; +extern ENGINE_API Fvector4 ps_dev_param_4; +extern ENGINE_API Fvector4 ps_dev_param_5; +extern ENGINE_API Fvector4 ps_dev_param_6; +extern ENGINE_API Fvector4 ps_dev_param_7; +extern ENGINE_API Fvector4 ps_dev_param_8; + +// Ascii1457's Screen Space Shaders +extern ENGINE_API Fvector4 ps_ssfx_hud_drops_1; +extern ENGINE_API Fvector4 ps_ssfx_hud_drops_2; +extern ENGINE_API Fvector4 ps_ssfx_blood_decals; +extern ENGINE_API Fvector4 ps_ssfx_rain_1; +extern ENGINE_API Fvector4 ps_ssfx_rain_2; +extern ENGINE_API Fvector4 ps_ssfx_rain_3; +extern ENGINE_API Fvector3 ps_ssfx_shadow_cascades; +extern ENGINE_API Fvector4 ps_ssfx_grass_shadows; +extern ENGINE_API Fvector4 ps_ssfx_grass_interactive; +extern ENGINE_API Fvector4 ps_ssfx_int_grass_params_1; +extern ENGINE_API Fvector4 ps_ssfx_int_grass_params_2; +extern ENGINE_API Fvector4 ps_ssfx_wpn_dof_1; +extern ENGINE_API float ps_ssfx_wpn_dof_2; + // x - min (0), y - focus (1.4), z - max (100) Fvector3 ps_r2_dof = Fvector3().set(-1.25f, 1.4f, 600.f); float ps_r2_dof_sky = 30; // distance to sky @@ -245,6 +279,7 @@ xr_token ext_quality_token[] = {{"qt_off", 0}, {"qt_low", 1}, {"qt_medium", 2}, //- Mad Max float ps_r2_gloss_factor = 4.0f; +float ps_r2_gloss_min = 0.0f; //- Mad Max #ifndef _EDITOR #include "xrEngine/XR_IOConsole.h" @@ -753,6 +788,11 @@ void xrRender_initconsole() CMD4(CCC_Integer, "r__supersample", &ps_r__Supersample, 1, 8); + // Anomaly + CMD4(CCC_Float, "r__exposure", &ps_r2_img_exposure, 0.5f, 4.0f); + CMD4(CCC_Float, "r__gamma", &ps_r2_img_gamma, 0.5f, 2.2f); + CMD4(CCC_Float, "r__saturation", &ps_r2_img_saturation, 0.0f, 2.0f); + Fvector tw_min, tw_max; CMD4(CCC_Float, "r__geometry_lod", &ps_r__LOD, 0.1f, 2.f); @@ -834,7 +874,8 @@ void xrRender_initconsole() //- Mad Max CMD4(CCC_Float, "r2_gloss_factor", &ps_r2_gloss_factor, .0f, 10.f); -//- Mad Max + CMD4(CCC_Float, "r2_gloss_min", &ps_r2_gloss_min, .0f, 1.f); + //- Mad Max #ifdef DEBUG CMD3(CCC_Mask, "r2_use_nvdbt", &ps_r2_ls_flags, R2FLAG_USE_NVDBT); @@ -950,6 +991,7 @@ void xrRender_initconsole() CMD3(CCC_Token, "r3_water_refl", &ps_r_water_reflection, qwater_reflection_quality_token); CMD3(CCC_Mask, "r3_water_refl_half_depth", &ps_r2_ls_flags_ext, R3FLAGEXT_SSR_HALF_DEPTH); CMD3(CCC_Mask, "r3_water_refl_jitter", &ps_r2_ls_flags_ext, R3FLAGEXT_SSR_JITTER); + CMD3(CCC_Mask, "r4_new_shader_support", &ps_r2_ls_flags_ext, R4FLAGEXT_NEW_SHADER_SUPPORT); //CMD3(CCC_Mask, "r3_msaa", &ps_r2_ls_flags, R3FLAG_MSAA); CMD3(CCC_Token, "r3_msaa", &ps_r3_msaa, qmsaa_token); @@ -982,6 +1024,45 @@ void xrRender_initconsole() #if RENDER == R_R4 CMD4(CCC_Integer, "r2_mt_render", &ps_r2_mt_render, 0, 1); #endif + + // Anomaly + Fvector4 tw2_min = { 0.f, 0.f, 0.f, 0.f }; + Fvector4 tw2_max = { 10.f, 3.f, 1.f, 1.f }; + tw_min.set(0.f, 0.f, 0.f); + tw_max.set(1.f, 2.f, 1.f); + CMD4(CCC_Integer, "r__nightvision", &ps_r2_nightvision, 0, 3); //For beef's nightvision shader or other stuff + CMD4(CCC_Vector4, "r2_mask_control", &ps_r2_mask_control, tw2_min, tw2_max); + CMD4(CCC_Vector3, "r2_drops_control", &ps_r2_drops_control, tw_min, tw_max); + + tw2_max.set(-100.f, -100.f, -100.f, -100.f); + tw2_max.set(100.f, 100.f, 100.f, 100.f); + CMD4(CCC_Vector4, "shader_param_1", &ps_dev_param_1, tw2_min, tw2_max); + CMD4(CCC_Vector4, "shader_param_2", &ps_dev_param_2, tw2_min, tw2_max); + CMD4(CCC_Vector4, "shader_param_3", &ps_dev_param_3, tw2_min, tw2_max); + CMD4(CCC_Vector4, "shader_param_4", &ps_dev_param_4, tw2_min, tw2_max); + CMD4(CCC_Vector4, "shader_param_5", &ps_dev_param_5, tw2_min, tw2_max); + CMD4(CCC_Vector4, "shader_param_6", &ps_dev_param_6, tw2_min, tw2_max); + CMD4(CCC_Vector4, "shader_param_7", &ps_dev_param_7, tw2_min, tw2_max); + CMD4(CCC_Vector4, "shader_param_8", &ps_dev_param_8, tw2_min, tw2_max); + + // Ascii's Screen Space Shaders + CMD4(CCC_Vector4, "ssfx_hud_drops_1", &ps_ssfx_hud_drops_1, Fvector4{}, Fvector4({ 100000.f, 100.f, 100.f, 100.f })); + CMD4(CCC_Vector4, "ssfx_hud_drops_2", &ps_ssfx_hud_drops_2, Fvector4{}, tw2_max); + CMD4(CCC_Vector4, "ssfx_blood_decals", &ps_ssfx_blood_decals, Fvector4{}, Fvector4({ 5.f, 5.f, 0.f, 0.f })); + CMD4(CCC_Vector4, "ssfx_rain_1", &ps_ssfx_rain_1, Fvector4{}, Fvector4({ 10.f, 5.f, 5.f, 2.f })); + CMD4(CCC_Vector4, "ssfx_rain_2", &ps_ssfx_rain_2, Fvector4{}, Fvector4({ 1.f, 10.f, 10.f, 10.f })); + CMD4(CCC_Vector4, "ssfx_rain_3", &ps_ssfx_rain_3, Fvector4{}, Fvector4({ 1.f, 10.f, 10.f, 10.f })); + CMD4(CCC_Vector4, "ssfx_grass_shadows", &ps_ssfx_grass_shadows, Fvector4{}, Fvector4({ 3.f, 1.f, 100.f, 100.f })); + CMD4(CCC_Vector3, "ssfx_shadow_cascades", &ps_ssfx_shadow_cascades, Fvector3({ 1.0f, 1.0f, 1.0f }), Fvector3({ 300.f, 300.f, 300.f })); + CMD4(CCC_Vector4, "ssfx_grass_interactive", &ps_ssfx_grass_interactive, Fvector4{}, Fvector4({ 1.f, 15.f, 5000.f, 1.f })); + CMD4(CCC_Vector4, "ssfx_int_grass_params_1", &ps_ssfx_int_grass_params_1, Fvector4{}, Fvector4({ 5.f, 5.f, 5.f, 60.f })); + CMD4(CCC_Vector4, "ssfx_int_grass_params_2", &ps_ssfx_int_grass_params_2, Fvector4{}, Fvector4({ 5.f, 20.f, 1.f, 5.f })); + CMD4(CCC_Vector4, "ssfx_wpn_dof_1", &ps_ssfx_wpn_dof_1, tw2_min, tw2_max); + CMD4(CCC_Float, "ssfx_wpn_dof_2", &ps_ssfx_wpn_dof_2, 0.f, 1.f); + + tw_min.set(0, 0, 0); + tw_max.set(1, 1, 1); + CMD4(CCC_Vector3, "r__color_grading", &ps_r2_img_cg, tw_min, tw_max); } #endif diff --git a/src/Layers/xrRender/xrRender_console.h b/src/Layers/xrRender/xrRender_console.h index 82d00532d9c..b476c8084b9 100644 --- a/src/Layers/xrRender/xrRender_console.h +++ b/src/Layers/xrRender/xrRender_console.h @@ -214,6 +214,7 @@ enum R2FLAGEXT_SUN_OLD = (1 << 9), R3FLAGEXT_SSR_HALF_DEPTH = (1 << 10), R3FLAGEXT_SSR_JITTER = (1 << 11), + R4FLAGEXT_NEW_SHADER_SUPPORT = (1 << 12), }; extern void xrRender_initconsole(); diff --git a/src/Layers/xrRenderDX11/dx11DetailManager_VS.cpp b/src/Layers/xrRenderDX11/dx11DetailManager_VS.cpp index 18482de5510..e87cf83400e 100644 --- a/src/Layers/xrRenderDX11/dx11DetailManager_VS.cpp +++ b/src/Layers/xrRenderDX11/dx11DetailManager_VS.cpp @@ -95,6 +95,17 @@ void CDetailManager::hw_Render_dump(CBackend& cmd_list, static shared_str strDir2D("dir2D"); static shared_str strArray("array"); static shared_str strXForm("xform"); + static shared_str strPos("benders_pos"); + static shared_str strGrassSetup("benders_setup"); + + // Grass benders data + IGame_Persistent::grass_data& GData = g_pGamePersistent->grass_shader_data; + Fvector4 player_pos = { 0, 0, 0, 0 }; + int BendersQty = _min(16, (int)(ps_ssfx_grass_interactive.y + 1)); + + // Add Player? + if (ps_ssfx_grass_interactive.x > 0) + player_pos.set(Device.vCameraPosition.x, Device.vCameraPosition.y, Device.vCameraPosition.z, -1); RImplementation.BasicStats.DetailCount = 0; @@ -132,6 +143,30 @@ void CDetailManager::hw_Render_dump(CBackend& cmd_list, cmd_list.set_c(strDir2D, wind); cmd_list.set_c(strXForm, Device.mFullTransform); + if (ps_ssfx_grass_interactive.y > 0) + { + cmd_list.set_c(strGrassSetup, ps_ssfx_int_grass_params_1); + + Fvector4* c_grass{}; + { + void* GrassData; + cmd_list.get_ConstantDirect(strPos, BendersQty * sizeof(Fvector4), &GrassData, 0, 0); + c_grass = (Fvector4*)GrassData; + } + + if (c_grass) + { + c_grass[0].set(player_pos); + c_grass[16].set(0.0f, -99.0f, 0.0f, 1.0f); + + for (int Bend = 1; Bend < BendersQty; Bend++) + { + c_grass[Bend].set(GData.pos[Bend].x, GData.pos[Bend].y, GData.pos[Bend].z, GData.radius_curr[Bend]); + c_grass[Bend + 16].set(GData.dir[Bend].x, GData.dir[Bend].y, GData.dir[Bend].z, GData.str[Bend]); + } + } + } + // ref_constant constArray = RCache.get_c(strArray); // VERIFY(constArray); @@ -163,6 +198,17 @@ void CDetailManager::hw_Render_dump(CBackend& cmd_list, // Build matrix ( 3x4 matrix, last row - color ) float scale = Instance.scale_calculated; + + // Sort of fade using the scale + // fade_distance == -1 use light_position to define "fade", anything else uses fade_distance + if (fade_distance <= -1) + scale *= 1.0f - Instance.position.distance_to_xz_sqr(light_position) * 0.005f; + else if (Instance.distance > fade_distance) + scale *= 1.0f - abs(Instance.distance - fade_distance) * 0.005f; + + if (scale <= 0) + break; + Fmatrix& M = Instance.mRotY; c_storage[base + 0].set(M._11 * scale, M._21 * scale, M._31 * scale, M._41); c_storage[base + 1].set(M._12 * scale, M._22 * scale, M._32 * scale, M._42); diff --git a/src/Layers/xrRenderDX11/dx11ResourceManager_Scripting.cpp b/src/Layers/xrRenderDX11/dx11ResourceManager_Scripting.cpp index 3b54afe35c5..5f2c757d268 100644 --- a/src/Layers/xrRenderDX11/dx11ResourceManager_Scripting.cpp +++ b/src/Layers/xrRenderDX11/dx11ResourceManager_Scripting.cpp @@ -286,6 +286,11 @@ class adopt_compiler C->r_StencilRef(Ref); return *this; } + adopt_compiler& _dx10CullMode(u32 Ref) + { + C->r_CullMode((D3DCULL)Ref); + return *this; + } adopt_compiler& _dx10ATOC(bool Enable) { C->RS.SetRS(XRDX11RS_ALPHATOCOVERAGE, Enable); @@ -374,6 +379,7 @@ void CResourceManager::LS_Load() .def("dx10texture", &adopt_compiler::_dx10texture, return_reference_to<1>()) .def("dx10stencil", &adopt_compiler::_dx10Stencil, return_reference_to<1>()) .def("dx10stencil_ref", &adopt_compiler::_dx10StencilRef, return_reference_to<1>()) + .def("dx10cullmode", &adopt_compiler::_dx10CullMode, return_reference_to<1>()) .def("dx10atoc", &adopt_compiler::_dx10ATOC, return_reference_to<1>()) .def("dx10zfunc", &adopt_compiler::_dx10ZFunc, return_reference_to<1>()) diff --git a/src/Layers/xrRenderDX11/dx11Texture.cpp b/src/Layers/xrRenderDX11/dx11Texture.cpp index e7bfbc5bb7c..d7f64a67ac5 100644 --- a/src/Layers/xrRenderDX11/dx11Texture.cpp +++ b/src/Layers/xrRenderDX11/dx11Texture.cpp @@ -338,8 +338,8 @@ ID3DBaseTexture* CRender::texture_load(LPCSTR fRName, u32& ret_msize) _DDS_CUBE: { - R_CHK(CreateTextureEx(HW.pDevice, texture.GetImages(), texture.GetImageCount(), IMG, D3D_USAGE_IMMUTABLE, - D3D_BIND_SHADER_RESOURCE, 0, IMG.miscFlags, DirectX::CREATETEX_DEFAULT, &pTexture2D)); + R_CHK2(CreateTextureEx(HW.pDevice, texture.GetImages(), texture.GetImageCount(), IMG, D3D_USAGE_IMMUTABLE, + D3D_BIND_SHADER_RESOURCE, 0, IMG.miscFlags, DirectX::CREATETEX_DEFAULT, &pTexture2D), fn); FS.r_close(S); // OK @@ -362,9 +362,9 @@ ID3DBaseTexture* CRender::texture_load(LPCSTR fRName, u32& ret_msize) mip_lod = old_mipmap_cnt - IMG.mipLevels; } - R_CHK(CreateTextureEx(HW.pDevice, texture.GetImages() + mip_lod, texture.GetImageCount(), IMG, + R_CHK2(CreateTextureEx(HW.pDevice, texture.GetImages() + mip_lod, texture.GetImageCount(), IMG, D3D_USAGE_IMMUTABLE, D3D_BIND_SHADER_RESOURCE, 0, IMG.miscFlags, DirectX::CREATETEX_DEFAULT, - &pTexture2D) + &pTexture2D), fn ); @@ -386,8 +386,7 @@ ID3DBaseTexture* CRender::texture_load(LPCSTR fRName, u32& ret_msize) R_ASSERT2(FS.exist(fn, "$game_textures$", "ed\\ed_dummy_bump#", ".dds"), "ed_dummy_bump#"); S = FS.r_open(fn); R_ASSERT2(S, fn); - img_size = S->length(); - goto _DDS_2D; + goto _DDS; } if (strstr(fname, "_bump")) { @@ -395,9 +394,7 @@ ID3DBaseTexture* CRender::texture_load(LPCSTR fRName, u32& ret_msize) S = FS.r_open(fn); R_ASSERT2(S, fn); - - img_size = S->length(); - goto _DDS_2D; + goto _DDS; } ////////////////// } diff --git a/src/Layers/xrRenderPC_GL/gl_rendertarget.h b/src/Layers/xrRenderPC_GL/gl_rendertarget.h index b1ed6c570de..c6167b5b216 100644 --- a/src/Layers/xrRenderPC_GL/gl_rendertarget.h +++ b/src/Layers/xrRenderPC_GL/gl_rendertarget.h @@ -90,6 +90,10 @@ class CRenderTarget : public IRender_Target ref_texture t_noise_mipped; ref_texture t_base; + + // Anomaly + ref_rt rt_Generic_temp; + private: // OCCq ref_shader s_occq; diff --git a/src/Layers/xrRenderPC_R2/r2_rendertarget.h b/src/Layers/xrRenderPC_R2/r2_rendertarget.h index b3a1dabc0c0..79420105091 100644 --- a/src/Layers/xrRenderPC_R2/r2_rendertarget.h +++ b/src/Layers/xrRenderPC_R2/r2_rendertarget.h @@ -79,6 +79,9 @@ class CRenderTarget : public IRender_Target ref_texture t_material; ref_texture t_noise[TEX_jitter_count]; + // Anomaly + ref_rt rt_Generic_temp; + private: // OCCq ref_shader s_occq; diff --git a/src/Layers/xrRenderPC_R2/r2_shaders.cpp b/src/Layers/xrRenderPC_R2/r2_shaders.cpp index b0ac98feb71..fab6b9e7a1d 100644 --- a/src/Layers/xrRenderPC_R2/r2_shaders.cpp +++ b/src/Layers/xrRenderPC_R2/r2_shaders.cpp @@ -72,6 +72,10 @@ HRESULT CRender::shader_compile( string32 c_ssao; string32 c_sun_quality; + // Ascii's Screen Space Shaders - SSS preprocessor stuff + char c_rain_quality[32]; + char c_inter_grass[32]; + char sh_name[MAX_PATH] = ""; u32 len = 0; // options @@ -403,6 +407,42 @@ HRESULT CRender::shader_compile( ++len; } + if (ps_ssfx_rain_1.w > 0) + { + xr_sprintf(c_rain_quality, "%d", ps_ssfx_rain_1.w); + defines[def_it].Name = "SSFX_RAIN_QUALITY"; + defines[def_it].Definition = c_rain_quality; + def_it++; + xr_strcat(sh_name, c_rain_quality); + len += xr_strlen(c_rain_quality); + } + else + { + sh_name[len] = '0'; + ++len; + } + + if (ps_ssfx_grass_interactive.y > 0) + { + xr_sprintf(c_inter_grass, "%d", ps_ssfx_grass_interactive.y); + defines[def_it].Name = "SSFX_INT_GRASS"; + defines[def_it].Definition = c_inter_grass; + def_it++; + xr_strcat(sh_name, c_inter_grass); + len += xr_strlen(c_inter_grass); + } + else + { + sh_name[len] = '0'; + ++len; + } + + defines[def_it].Name = "SSFX_MODEXE"; + defines[def_it].Definition = "1"; + def_it++; + sh_name[len] = '1'; + ++len; + sh_name[len] = '\0'; #ifndef USE_D3DX diff --git a/src/Layers/xrRenderPC_R4/r4_rendertarget.h b/src/Layers/xrRenderPC_R4/r4_rendertarget.h index 8ce7ccddc9d..a0cde0c26fc 100644 --- a/src/Layers/xrRenderPC_R4/r4_rendertarget.h +++ b/src/Layers/xrRenderPC_R4/r4_rendertarget.h @@ -85,6 +85,21 @@ class CRenderTarget : public IRender_Target ref_texture t_noise[TEX_jitter_count]; ref_texture t_noise_mipped; + // Anomaly + //Rendertargets + ref_rt rt_Generic_temp; + + ref_rt rt_dof; + + ref_rt rt_blur_h_2; + ref_rt rt_blur_2; + + ref_rt rt_blur_h_4; + ref_rt rt_blur_4; + + ref_rt rt_blur_h_8; + ref_rt rt_blur_8; + private: // OCCq ref_shader s_occq; @@ -106,6 +121,13 @@ class CRenderTarget : public IRender_Target ref_shader s_accum_volume; ref_shader s_accum_volume_msaa[8]; + //Anomaly + ref_shader s_blur; + ref_shader s_dof; + ref_shader s_gasmask_drops; + ref_shader s_gasmask_dudv; + ref_shader s_nightvision; + // generate min/max ref_shader s_create_minmax_sm; @@ -265,6 +287,13 @@ class CRenderTarget : public IRender_Target void phase_accumulator(CBackend& cmd_list); void phase_vol_accumulator(CBackend& cmd_list); + //Anomaly renderphases + void phase_blur(); + void phase_dof(); + void phase_gasmask_drops(); + void phase_gasmask_dudv(); + void phase_nightvision(); + // Generates min/max sm void create_minmax_SM(CBackend& cmd_list); diff --git a/src/Layers/xrRenderPC_R4/r4_rendertarget_phase_combine.cpp b/src/Layers/xrRenderPC_R4/r4_rendertarget_phase_combine.cpp index ee5208c5d14..af0504138de 100644 --- a/src/Layers/xrRenderPC_R4/r4_rendertarget_phase_combine.cpp +++ b/src/Layers/xrRenderPC_R4/r4_rendertarget_phase_combine.cpp @@ -249,6 +249,12 @@ void CRenderTarget::phase_combine() } } + //Copy previous rt + if (!RImplementation.o.msaa) + HW.get_context(CHW::IMM_CTX_ID)->CopyResource(rt_Generic_temp->pTexture->surface_get(), rt_Generic_0->pTexture->surface_get()); + else + HW.get_context(CHW::IMM_CTX_ID)->CopyResource(rt_Generic_temp->pTexture->surface_get(), rt_Generic_0_r->pTexture->surface_get()); + // Forward rendering { PIX_EVENT(Forward_rendering); @@ -304,6 +310,26 @@ void CRenderTarget::phase_combine() RCache.set_Stencil(FALSE); + if (ps_r2_ls_flags_ext.test(R4FLAGEXT_NEW_SHADER_SUPPORT)) + { + //(Anomaly) Compute blur textures + phase_blur(); + + //(Anomaly) Compute depth of field effect + if (ps_r2_ls_flags.test(R2FLAG_DOF)) + phase_dof(); + + //(Anomaly) Compute night vision effect + if (ps_r2_nightvision > 0) + phase_nightvision(); + + if (ps_r2_mask_control.x > 0) + { + phase_gasmask_dudv(); + phase_gasmask_drops(); + } + } + // PP enabled ? // Render to RT texture to be able to copy RT even in windowed mode. BOOL PP_Complex = u_need_PP() | (BOOL)RImplementation.m_bMakeAsyncSS; diff --git a/src/Layers/xrRenderPC_R4/r4_shaders.cpp b/src/Layers/xrRenderPC_R4/r4_shaders.cpp index 79e9ee62ccf..b9eb8dc8e1a 100644 --- a/src/Layers/xrRenderPC_R4/r4_shaders.cpp +++ b/src/Layers/xrRenderPC_R4/r4_shaders.cpp @@ -226,6 +226,8 @@ HRESULT CRender::shader_compile(pcstr name, IReader* fs, pcstr pFunctionName, string32 c_sun_quality; char c_msaa_samples[2]; char c_msaa_current_sample[2]; + char c_rain_quality[32]; + char c_inter_grass[32]; // options: const auto appendShaderOption = [&](u32 option, cpcstr macro, cpcstr value) @@ -416,6 +418,27 @@ HRESULT CRender::shader_compile(pcstr name, IReader* fs, pcstr pFunctionName, // Minmax SM appendShaderOption(o.minmax_sm, "USE_MINMAX_SM", "1"); + // Ascii's Screen Space Shaders - SSS preprocessor stuff + if (ps_ssfx_rain_1.w > 0) + { + xr_sprintf(c_rain_quality, "%d", ps_ssfx_rain_1.w); + options.add("SSFX_RAIN_QUALITY", c_rain_quality); + sh_name.append(c_rain_quality); + } + else + sh_name.append(static_cast(0)); + + if (ps_ssfx_grass_interactive.y > 0) + { + xr_sprintf(c_inter_grass, "%d", ps_ssfx_grass_interactive.y); + options.add("SSFX_INT_GRASS", c_inter_grass); + sh_name.append(c_inter_grass); + } + else + sh_name.append(static_cast(0)); + + appendShaderOption(1, "SSFX_MODEXE", "1"); + // Be carefull!!!!! this should be at the end to correctly generate // compiled shader name; // add a #define for DX10_1 MSAA support diff --git a/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj b/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj index 943685856c9..5de283e05aa 100644 --- a/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj +++ b/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj @@ -70,6 +70,11 @@ + + + + + @@ -234,9 +239,14 @@ + + + + + @@ -320,6 +330,11 @@ + + + + + diff --git a/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj.filters b/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj.filters index e9c9b4f8d8d..1959eeca3c1 100644 --- a/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj.filters +++ b/src/Layers/xrRenderPC_R4/xrRender_R4.vcxproj.filters @@ -726,6 +726,21 @@ Interface implementations\ImGuiRender + + Shading templates + + + Shading templates + + + Shading templates + + + Shading templates + + + Shading templates + @@ -1331,6 +1346,36 @@ Core + + Shading templates + + + Shading templates + + + Shading templates + + + Core_Target + + + Core_Target + + + Core_Target + + + Shading templates + + + Shading templates + + + Core_Target + + + Core_Target + diff --git a/src/Layers/xrRender_R2/r2.cpp b/src/Layers/xrRender_R2/r2.cpp index b6b62103725..e955c97e0ee 100644 --- a/src/Layers/xrRender_R2/r2.cpp +++ b/src/Layers/xrRender_R2/r2.cpp @@ -47,6 +47,8 @@ ShaderElement* CRender::rimp_select_sh_dynamic(dxRender_Visual* pVisual, float c ////////////////////////////////////////////////////////////////////////// ShaderElement* CRender::rimp_select_sh_static(dxRender_Visual* pVisual, float cdist_sq, u32 phase) { + if (!pVisual->shader) + return nullptr; int id = SE_R2_SHADOW; if (CRender::PHASE_NORMAL == phase) { @@ -579,6 +581,20 @@ void CRender::create() } #endif +#if defined(USE_DX11) + // Ascii's Screen Space Shaders - Check if SSS shaders exist + string_path fn; + o.ssfx_rain = FS.exist(fn, "$game_shaders$", "r3\\effects_rain_splash", ".ps") ? 1 : 0; + o.ssfx_blood = FS.exist(fn, "$game_shaders$", "r3\\effects_wallmark_blood", ".ps") ? 1 : 0; + o.ssfx_branches = FS.exist(fn, "$game_shaders$", "r3\\deffer_tree_branch_bump-hq", ".vs") ? 1 : 0; + o.ssfx_hud_raindrops = FS.exist(fn, "$game_shaders$", "r3\\deffer_base_hud_bump", ".ps") ? 1 : 0; + + Msg("- SSS HUD RAINDROPS SHADER INSTALLED %i", o.ssfx_hud_raindrops); + Msg("- SSS RAIN SHADER INSTALLED %i", o.ssfx_rain); + Msg("- SSS BLOOD SHADER INSTALLED %i", o.ssfx_blood); + Msg("- SSS BRANCHES SHADER INSTALLED %i", o.ssfx_branches); +#endif + // constants Resources->RegisterConstantSetup("parallax", &binder_parallax); Resources->RegisterConstantSetup("water_intensity", &binder_water_intensity); @@ -722,6 +738,9 @@ void CRender::OnFrame() Device.seqParallel.insert( Device.seqParallel.begin(), fastdelegate::FastDelegate0<>(Details, &CDetailManager::MT_CALC)); } + + if (Details) + g_pGamePersistent->GrassBendersUpdateAnimations(); } #ifdef USE_OGL diff --git a/src/Layers/xrRender_R2/r2.h b/src/Layers/xrRender_R2/r2.h index 987809a7248..196f8b32dc2 100644 --- a/src/Layers/xrRender_R2/r2.h +++ b/src/Layers/xrRender_R2/r2.h @@ -270,6 +270,12 @@ class CRender final : public D3DXRenderBase u32 support_rt_arrays : 1; float forcegloss_v; + + // Ascii - Screen Space Shaders + u32 ssfx_branches : 1; + u32 ssfx_blood : 1; + u32 ssfx_rain : 1; + u32 ssfx_hud_raindrops : 1; } o; struct RenderR2Statistics diff --git a/src/Layers/xrRender_R2/r2_R_lights.cpp b/src/Layers/xrRender_R2/r2_R_lights.cpp index 521e4cc8488..4e8b413619d 100644 --- a/src/Layers/xrRender_R2/r2_R_lights.cpp +++ b/src/Layers/xrRender_R2/r2_R_lights.cpp @@ -1,5 +1,23 @@ #include "stdafx.h" +bool check_grass_shadow(light* L, CFrustum VB) +{ + // Grass shadows are allowed? + if (ps_ssfx_grass_shadows.x < 3 || !ps_r2_ls_flags.test(R2FLAG_SUN_DETAILS)) + return false; + + // Inside the range? + if (L->vis.distance > ps_ssfx_grass_shadows.z) + return false; + + // Is in view? L->vis.visible? + u32 mask = 0xff; + if (!VB.testSphere(L->position, L->range * 0.6f, mask)) + return false; + + return true; +} + void CRender::render_lights(light_Package& LP) { ////////////////////////////////////////////////////////////////////////// @@ -135,7 +153,14 @@ void CRender::render_lights(light_Package& LP) dsgraph.cmd_list.set_xform_project(L->X.S.project); dsgraph.render_graph(0); if (ps_r2_ls_flags.test(R2FLAG_SUN_DETAILS)) - Details->Render(dsgraph.cmd_list); + { + if (check_grass_shadow(L, ViewBase)) + { + Details->fade_distance = -1; // Use light position to calc "fade" + Details->light_position.set(L->position); + Details->Render(dsgraph.cmd_list); + } + } L->X.S.transluent = FALSE; if (bSpecial) { diff --git a/src/Layers/xrRender_R2/r2_R_render.cpp b/src/Layers/xrRender_R2/r2_R_render.cpp index d90b0ea7a4f..df78c903e70 100644 --- a/src/Layers/xrRender_R2/r2_R_render.cpp +++ b/src/Layers/xrRender_R2/r2_R_render.cpp @@ -383,6 +383,9 @@ void CRender::Render() Target->phase_combine(); } + if (Details) + Details->details_clear(); + VERIFY(dsgraph.mapDistort.empty()); } diff --git a/src/Layers/xrRender_R2/r2_rendertarget.cpp b/src/Layers/xrRender_R2/r2_rendertarget.cpp index adfb8a00ddd..97ad9e208d3 100644 --- a/src/Layers/xrRender_R2/r2_rendertarget.cpp +++ b/src/Layers/xrRender_R2/r2_rendertarget.cpp @@ -25,6 +25,14 @@ # endif #endif +//Anomaly blenders +#if defined(USE_DX11) + #include "Layers/xrRender/blenders/Blender_Blur.h" + #include "Layers/xrRender/blenders/blender_dof.h" + #include "Layers/xrRender/blenders/blender_nightvision.h" + #include "Layers/xrRender/blenders/blender_gasmask_drops.h" + #include "Layers/xrRender/blenders/blender_gasmask_dudv.h" +#endif #if defined(USE_DX9) void CRenderTarget::u_stencil_optimize(CBackend& cmd_list, BOOL common_stencil) #elif defined(USE_DX11) || defined(USE_OGL) @@ -370,8 +378,44 @@ CRenderTarget::CRenderTarget() // temp: for higher quality blends if (options.advancedpp) rt_Generic_2.create(r2_RT_generic2, w, h, D3DFMT_A16B16G16R16F, SampleCount); + + rt_Generic_temp.create("$user$generic_temp", w, h, D3DFMT_A8R8G8B8, SampleCount); } +#if defined(USE_DX11) + //Anomaly stuff + { + //Base resolution + u32 w = Device.dwWidth, h = Device.dwHeight; + + //Blenders + CBlender_Blur b_blur; + CBlender_dof b_dof; + CBlender_gasmask_drops b_gasmask_drops; + CBlender_gasmask_dudv b_gasmask_dudv; + CBlender_nightvision b_nightvision; + + //Rendertargets + rt_dof.create(r2_RT_dof, w, h, D3DFMT_A8R8G8B8); + + rt_blur_h_2.create(r2_RT_blur_h_2, u32(w / 2), u32(h / 2), D3DFMT_A8R8G8B8); + rt_blur_2.create(r2_RT_blur_2, u32(w / 2), u32(h / 2), D3DFMT_A8R8G8B8); + + rt_blur_h_4.create(r2_RT_blur_h_4, u32(w / 4), u32(h / 4), D3DFMT_A8R8G8B8); + rt_blur_4.create(r2_RT_blur_4, u32(w / 4), u32(h / 4), D3DFMT_A8R8G8B8); + + rt_blur_h_8.create(r2_RT_blur_h_8, u32(w / 8), u32(h / 8), D3DFMT_A8R8G8B8); + rt_blur_8.create(r2_RT_blur_8, u32(w / 8), u32(h / 8), D3DFMT_A8R8G8B8); + + //Shader + s_blur.create(&b_blur, "r2\\blur"); + s_dof.create(&b_dof, "r2\\dof"); + s_gasmask_drops.create(&b_gasmask_drops, "r2\\gasmask_drops"); + s_gasmask_dudv.create(&b_gasmask_dudv, "r2\\gasmask_dudv"); + s_nightvision.create(&b_nightvision, "r2\\nightvision"); + } +#endif + // OCCLUSION { CBlender_light_occq b_occq; diff --git a/src/Layers/xrRender_R2/r2_types.h b/src/Layers/xrRender_R2/r2_types.h index 3753ee1142e..9867a57552a 100644 --- a/src/Layers/xrRender_R2/r2_types.h +++ b/src/Layers/xrRender_R2/r2_types.h @@ -59,6 +59,18 @@ #define r2_base "$user$base" +//Anomaly +#define r2_RT_dof "$user$dof" + +#define r2_RT_blur_h_2 "$user$blur_h_2" +#define r2_RT_blur_2 "$user$blur_2" + +#define r2_RT_blur_h_4 "$user$blur_h_4" +#define r2_RT_blur_4 "$user$blur_4" + +#define r2_RT_blur_h_8 "$user$blur_h_8" +#define r2_RT_blur_8 "$user$blur_8" + static constexpr auto c_lmaterial = "L_material"; static constexpr auto c_sbase = "s_base"; static constexpr auto c_snoise = "s_noise"; @@ -115,10 +127,12 @@ const u32 LUMINANCE_size = 16; #define SE_SUN_RAIN_SMAP 5 extern float ps_r2_gloss_factor; +extern float ps_r2_gloss_min; + IC float u_diffuse2s(float x, float y, float z) { float v = (x + y + z) / 3.f; - return ps_r2_gloss_factor * ((v < 1) ? powf(v, 2.f / 3.f) : v); + return ps_r2_gloss_min + ps_r2_gloss_factor * ((v < 1) ? powf(v, 2.f / 3.f) : v); } IC float u_diffuse2s(Fvector3& c) diff --git a/src/Layers/xrRender_R2/render_phase_sun.cpp b/src/Layers/xrRender_R2/render_phase_sun.cpp index d7edcb7caaa..4ef69478465 100644 --- a/src/Layers/xrRender_R2/render_phase_sun.cpp +++ b/src/Layers/xrRender_R2/render_phase_sun.cpp @@ -7,15 +7,30 @@ void render_sun::init() { float fBias = -0.0000025f; - m_sun_cascades[0].reset_chain = true; - m_sun_cascades[0].size = 20; - m_sun_cascades[0].bias = m_sun_cascades[0].size * fBias; + if (ps_r2_ls_flags_ext.test(R4FLAGEXT_NEW_SHADER_SUPPORT)) + { + m_sun_cascades[0].reset_chain = true; + m_sun_cascades[0].size = ps_ssfx_shadow_cascades.x; + m_sun_cascades[0].bias = m_sun_cascades[0].size * fBias; + + m_sun_cascades[1].size = ps_ssfx_shadow_cascades.y; + m_sun_cascades[1].bias = m_sun_cascades[1].size * fBias; - m_sun_cascades[1].size = 40; - m_sun_cascades[1].bias = m_sun_cascades[1].size * fBias; + m_sun_cascades[2].size = ps_ssfx_shadow_cascades.z; + m_sun_cascades[2].bias = m_sun_cascades[2].size * fBias; + } + else + { + m_sun_cascades[0].reset_chain = true; + m_sun_cascades[0].size = 20; + m_sun_cascades[0].bias = m_sun_cascades[0].size * fBias; - m_sun_cascades[2].size = 160; - m_sun_cascades[2].bias = m_sun_cascades[2].size * fBias; + m_sun_cascades[1].size = 40; + m_sun_cascades[1].bias = m_sun_cascades[1].size * fBias; + + m_sun_cascades[2].size = 160; + m_sun_cascades[2].bias = m_sun_cascades[2].size * fBias; + } // for( u32 i = 0; i < cascade_count; ++i ) // { @@ -318,7 +333,20 @@ void render_sun::render() dsgraph.cmd_list.set_xform_project(sun->X.D[cascade_ind].combine); dsgraph.render_graph(0); if (ps_r2_ls_flags.test(R2FLAG_SUN_DETAILS)) - RImplementation.Details->Render(dsgraph.cmd_list); + { + if (ps_r2_ls_flags_ext.test(R4FLAGEXT_NEW_SHADER_SUPPORT)) + { + if (cascade_ind <= ps_ssfx_grass_shadows.x) + { + RImplementation.Details->fade_distance = dm_fade * dm_fade * ps_ssfx_grass_shadows.y; + RImplementation.Details->Render(dsgraph.cmd_list); + } + } + else + { + RImplementation.Details->Render(dsgraph.cmd_list); + } + } sun->X.D[cascade_ind].transluent = FALSE; if (bSpecial) { diff --git a/src/xrEngine/Environment.cpp b/src/xrEngine/Environment.cpp index 0a11a721ac5..dba4fda6e8f 100644 --- a/src/xrEngine/Environment.cpp +++ b/src/xrEngine/Environment.cpp @@ -55,6 +55,8 @@ CEnvironment::CEnvironment() : m_ambients_config(0) wind_strength_factor = 0.f; wind_gust_factor = 0.f; + wetness_factor = 0.f; + wind_blast_strength = 0.f; wind_blast_direction.set(1.f, 0.f, 0.f); diff --git a/src/xrEngine/Environment.h b/src/xrEngine/Environment.h index e0ea1408ad9..2beda21cb6a 100644 --- a/src/xrEngine/Environment.h +++ b/src/xrEngine/Environment.h @@ -262,6 +262,8 @@ class ENGINE_API CEnvironment float wind_strength_factor; float wind_gust_factor; + float wetness_factor; + // wind blast params float wind_blast_strength; Fvector wind_blast_direction; diff --git a/src/xrEngine/Environment_misc.cpp b/src/xrEngine/Environment_misc.cpp index 3764f11d5a5..7c7b499003b 100644 --- a/src/xrEngine/Environment_misc.cpp +++ b/src/xrEngine/Environment_misc.cpp @@ -11,6 +11,7 @@ #include "Common/LevelGameDef.h" ENGINE_API float SunshaftsIntensity = 0.f; +extern Fvector3 ssfx_wetness_multiplier; void CEnvModifier::load(IReader* fs, u32 version) { @@ -585,6 +586,13 @@ void CEnvDescriptorMixer::lerp(CEnvironment& parent, CEnvDescriptor& A, CEnvDesc sun_color.lerp(A.sun_color, B.sun_color, f); + if (rain_density > 0.f) + parent.wetness_factor += (rain_density * ssfx_wetness_multiplier.x) / 10000.f; + else + parent.wetness_factor -= 0.0001f * ssfx_wetness_multiplier.y; + + clamp(parent.wetness_factor, 0.f, 1.f); + sun_azimuth = (fi * A.sun_azimuth + f * B.sun_azimuth); // Igor. Dynamic sun position. diff --git a/src/xrEngine/IGame_Persistent.cpp b/src/xrEngine/IGame_Persistent.cpp index 67781584ca0..5ecb664868f 100644 --- a/src/xrEngine/IGame_Persistent.cpp +++ b/src/xrEngine/IGame_Persistent.cpp @@ -13,6 +13,7 @@ #include "Render.h" #include "PS_instance.h" #include "CustomHUD.h" +#include "perlin.h" #endif ENGINE_API IGame_Persistent* g_pGamePersistent = nullptr; @@ -37,6 +38,9 @@ IGame_Persistent::IGame_Persistent() Device.seqAppDeactivate.Add(this); m_pMainMenu = nullptr; + PerlinNoise1D = xr_new(Random.randI(0, 0xFFFF)); + PerlinNoise1D->SetOctaves(2); + PerlinNoise1D->SetAmplitude(0.66666f); pEnvironment = xr_new(); @@ -45,6 +49,7 @@ IGame_Persistent::IGame_Persistent() IGame_Persistent::~IGame_Persistent() { + xr_delete(PerlinNoise1D); Device.seqFrame.Remove(this); Device.seqAppStart.Remove(this); Device.seqAppEnd.Remove(this); @@ -238,6 +243,319 @@ void IGame_Persistent::OnAssetsChanged() #endif } +void IGame_Persistent::GrassBendersUpdate(u16 id, u8& data_idx, u32& data_frame, Fvector& position, float init_radius, float init_str, bool CheckDistance) +{ + // Interactive grass disabled + if (ps_ssfx_grass_interactive.y < 1) + return; + + // Just update position if not NULL + if (data_idx != 0) + { + // Explosions can take the mem spot, unassign and try to get a spot later. + if (grass_shader_data.id[data_idx] != id) + { + data_idx = 0; + data_frame = Device.dwFrame + Random.randI(10, 35); + } + else + { + grass_shader_data.pos[data_idx] = position; + } + } + + if (Device.dwFrame < data_frame) + return; + + // Wait some random frames to split the checks + data_frame = Device.dwFrame + Random.randI(10, 35); + + // Check Distance + if (CheckDistance) + { + if (position.distance_to_xz_sqr(Device.vCameraPosition) > ps_ssfx_grass_interactive.z) + { + GrassBendersRemoveByIndex(data_idx); + return; + } + } + + CFrustum& view_frust = GEnv.Render->ViewBase; + u32 mask = 0xff; + float rad = data_idx == 0 ? 1.0 : std::max(1.0f, grass_shader_data.radius_curr[data_idx] + 0.5f); + + // In view frustum? + if (!view_frust.testSphere(position, rad, mask)) + { + GrassBendersRemoveByIndex(data_idx); + return; + } + + // Empty slot, let's use this + if (data_idx == 0) + { + u8 idx = grass_shader_data.index + 1; + + // Add to grass blenders array + if (grass_shader_data.id[idx] == 0) + { + data_idx = idx; + GrassBendersSet(idx, id, position, Fvector3().set(0, -99, 0), 0, 0, 0.0f, init_radius, BENDER_ANIM_DEFAULT, true); + + grass_shader_data.str_target[idx] = init_str; + grass_shader_data.radius_curr[idx] = init_radius; + } + // Back to 0 when the array limit is reached + grass_shader_data.index = idx < ps_ssfx_grass_interactive.y ? idx : 0; + } + else + { + // Already in view, let's add more time to re-check + data_frame += 60; + grass_shader_data.pos[data_idx] = position; + } +} + +void IGame_Persistent::GrassBendersAddExplosion(u16 id, Fvector position, Fvector3 dir, float fade, float speed, float intensity, float radius) +{ + if (ps_ssfx_grass_interactive.y < 1) + return; + + for (int idx = 1; idx < ps_ssfx_grass_interactive.y + 1; idx++) + { + // Add explosion to any spot not already taken by an explosion. + if (grass_shader_data.anim[idx] != BENDER_ANIM_EXPLOSION) + { + // Add 99 to the ID to avoid conflicts between explosions and basic benders happening at the same time with the same ID. + GrassBendersSet(idx, id + 99, position, dir, fade, speed, intensity, radius, BENDER_ANIM_EXPLOSION, true); + grass_shader_data.str_target[idx] = intensity; + break; + } + } +} + +void IGame_Persistent::GrassBendersAddShot(u16 id, Fvector position, Fvector3 dir, float fade, float speed, float intensity, float radius) +{ + // Is disabled? + if (ps_ssfx_grass_interactive.y < 1 || intensity <= 0.0f) + return; + + // Check distance + if (position.distance_to_xz_sqr(Device.vCameraPosition) > ps_ssfx_grass_interactive.z) + return; + + int AddAt = -1; + + // Look for a spot + for (int idx = 1; idx < ps_ssfx_grass_interactive.y + 1; idx++) + { + // Already exist, just update and increase intensity + if (grass_shader_data.id[idx] == id) + { + float currentSTR = grass_shader_data.str[idx]; + GrassBendersSet(idx, id, position, dir, fade, speed, currentSTR, radius, BENDER_ANIM_EXPLOSION, false); + grass_shader_data.str_target[idx] += intensity; + AddAt = -1; + break; + } + else + { + // Check all indexes and keep usable index to use later if needed... + if (AddAt == -1 && fsimilar(grass_shader_data.radius[idx], 0.f)) + AddAt = idx; + } + } + + // We got an available index... Add bender at AddAt + if (AddAt != -1) + { + GrassBendersSet(AddAt, id, position, dir, fade, speed, 0.001f, radius, BENDER_ANIM_EXPLOSION, true); + grass_shader_data.str_target[AddAt] = intensity; + } +} + +void IGame_Persistent::GrassBendersUpdateAnimations() +{ + for (int idx = 1; idx < ps_ssfx_grass_interactive.y + 1; idx++) + { + if (grass_shader_data.id[idx] != 0) + { + switch (grass_shader_data.anim[idx]) + { + case BENDER_ANIM_EXPLOSION: // Internal Only ( You can use BENDER_ANIM_PULSE for anomalies ) + { + // Radius + grass_shader_data.time[idx] += Device.fTimeDelta * grass_shader_data.speed[idx]; + grass_shader_data.radius_curr[idx] = grass_shader_data.radius[idx] * std::min(1.0f, grass_shader_data.time[idx]); + + grass_shader_data.str_target[idx] = std::min(1.0f, grass_shader_data.str_target[idx]); + + // Easing + float diff = abs(grass_shader_data.str[idx] - grass_shader_data.str_target[idx]); + diff = std::max(0.1f, diff); + + // Intensity + if (grass_shader_data.str_target[idx] <= grass_shader_data.str[idx]) + { + grass_shader_data.str[idx] -= Device.fTimeDelta * grass_shader_data.fade[idx] * diff; + } + else + { + grass_shader_data.str[idx] += Device.fTimeDelta * grass_shader_data.speed[idx] * diff; + + if (grass_shader_data.str[idx] >= grass_shader_data.str_target[idx]) + grass_shader_data.str_target[idx] = 0; + } + + // Remove Bender + if (grass_shader_data.str[idx] < 0.0f) + GrassBendersReset(idx); + } + break; + + case BENDER_ANIM_WAVY: + { + // Anim Speed + grass_shader_data.time[idx] += Device.fTimeDelta * 1.5f * grass_shader_data.speed[idx]; + + // Curve + float curve = sin(grass_shader_data.time[idx]); + + // Intensity using curve + grass_shader_data.str[idx] = curve * cos(curve * 1.4f) * 1.8f * grass_shader_data.str_target[idx]; + } + + break; + + case BENDER_ANIM_SUCK: + { + // Anim Speed + grass_shader_data.time[idx] += Device.fTimeDelta * grass_shader_data.speed[idx]; + + // Perlin Noise + float curve = clampr(PerlinNoise1D->GetContinious(grass_shader_data.time[idx]) + 0.5f, 0.f, 1.f) * -1.0; + + // Intensity using Perlin + grass_shader_data.str[idx] = curve * grass_shader_data.str_target[idx]; + } + break; + + case BENDER_ANIM_BLOW: + { + // Anim Speed + grass_shader_data.time[idx] += Device.fTimeDelta * 1.2f * grass_shader_data.speed[idx]; + + // Perlin Noise + float curve = clampr(PerlinNoise1D->GetContinious(grass_shader_data.time[idx]) + 1.0f, 0.f, 2.0f) * 0.25f; + + // Intensity using Perlin + grass_shader_data.str[idx] = curve * grass_shader_data.str_target[idx]; + } + break; + + case BENDER_ANIM_PULSE: + { + // Anim Speed + grass_shader_data.time[idx] += Device.fTimeDelta * grass_shader_data.speed[idx]; + + // Radius + grass_shader_data.radius_curr[idx] = grass_shader_data.radius[idx] * std::min(1.0f, grass_shader_data.time[idx]); + + // Diminish intensity when radius target is reached + if (grass_shader_data.radius_curr[idx] >= grass_shader_data.radius[idx]) + grass_shader_data.str[idx] += GrassBenderToValue(grass_shader_data.str[idx], 0.0f, grass_shader_data.speed[idx] * 0.6f, true); + + // Loop when intensity is <= 0 + if (grass_shader_data.str[idx] <= 0.0f) + { + grass_shader_data.str[idx] = grass_shader_data.str_target[idx]; + grass_shader_data.radius_curr[idx] = 0.0f; + grass_shader_data.time[idx] = 0.0f; + } + + } + break; + + case BENDER_ANIM_DEFAULT: + + // Just fade to target strength + grass_shader_data.str[idx] += GrassBenderToValue(grass_shader_data.str[idx], grass_shader_data.str_target[idx], 2.0f, true); + + break; + } + } + } +} + +void IGame_Persistent::GrassBendersRemoveByIndex(u8& idx) +{ + if (idx != 0) + { + GrassBendersReset(idx); + idx = 0; + } +} + +void IGame_Persistent::GrassBendersRemoveById(u16 id) +{ + // Search by Object ID ( Used when removing benders CPHMovementControl::DestroyCharacter() ) + for (int i = 1; i < ps_ssfx_grass_interactive.y + 1; i++) + if (grass_shader_data.id[i] == id) + GrassBendersReset(i); +} + +void IGame_Persistent::GrassBendersReset(u8 idx) +{ + // Reset Everything + GrassBendersSet(idx, 0, Fvector3().set(0, 0, 0), Fvector3().set(0, -99, 0), 0, 0, 0, 0, BENDER_ANIM_DEFAULT, true); + grass_shader_data.str_target[idx] = 0; +} + +void IGame_Persistent::GrassBendersSet(u8 idx, u16 id, Fvector position, Fvector3 dir, float fade, float speed, float intensity, float radius, GrassBenders_Anim anim, bool resetTime) +{ + // Set values + grass_shader_data.anim[idx] = anim; + grass_shader_data.pos[idx] = position; + grass_shader_data.id[idx] = id; + grass_shader_data.radius[idx] = radius; + grass_shader_data.str[idx] = intensity; + grass_shader_data.fade[idx] = fade; + grass_shader_data.speed[idx] = speed; + grass_shader_data.dir[idx] = dir; + + if (resetTime) + { + grass_shader_data.radius_curr[idx] = 0.01f; + grass_shader_data.time[idx] = 0; + } +} + +float IGame_Persistent::GrassBenderToValue(float& current, float go_to, float intensity, bool use_easing) +{ + float diff = abs(current - go_to); + + float r_value = Device.fTimeDelta * intensity * (use_easing ? std::min(0.5f, diff) : 1.0f); + + if (diff - r_value <= 0) + { + current = go_to; + return 0; + } + + return current < go_to ? r_value : -r_value; +} + +bool IGame_Persistent::IsActorInHideout() +{ + if (Device.dwTimeGlobal > m_last_ray_pick_time) + { // Апдейт рейтрейса - раз в секунду. Чаще апдейтить нет смысла. + m_last_ray_pick_time = Device.dwTimeGlobal + 1000; + collide::rq_result RQ; + m_isInHideout = !!g_pGameLevel->ObjectSpace.RayPick(Device.vCameraPosition, Fvector{ 0.f, 1.f, 0.f }, 50.f, collide::rqtBoth, RQ, g_pGameLevel->CurrentViewEntity()); + } + return m_isInHideout; +} + void IGame_Persistent::DumpStatistics(IGameFont& font, IPerformanceAlert* alert) { // XXX: move to particle engine diff --git a/src/xrEngine/IGame_Persistent.h b/src/xrEngine/IGame_Persistent.h index 0aaa926014d..e922c426f08 100644 --- a/src/xrEngine/IGame_Persistent.h +++ b/src/xrEngine/IGame_Persistent.h @@ -80,6 +80,51 @@ class ENGINE_API IGame_Persistent : xr_vector ps_destroy; xr_vector ps_needtoplay; +public: + enum GrassBenders_Anim + { + BENDER_ANIM_EXPLOSION = 0, + BENDER_ANIM_DEFAULT = 1, + BENDER_ANIM_WAVY = 2, + BENDER_ANIM_SUCK = 3, + BENDER_ANIM_BLOW = 4, + BENDER_ANIM_PULSE = 5, + }; + + void GrassBendersUpdateAnimations(); + void GrassBendersAddExplosion(u16 id, Fvector position, Fvector3 dir, float fade, float speed, float intensity, float radius); + void GrassBendersAddShot(u16 id, Fvector position, Fvector3 dir, float fade, float speed, float intensity, float radius); + void GrassBendersRemoveById(u16 id); + void GrassBendersRemoveByIndex(u8& idx); + void GrassBendersUpdate(u16 id, u8& data_idx, u32& data_frame, Fvector& position, float radius, float str, bool CheckDistance); + void GrassBendersReset(u8 idx); + void GrassBendersSet(u8 idx, u16 id, Fvector position, Fvector3 dir, float fade, float speed, float str, float radius, GrassBenders_Anim anim, bool resetTime); + float GrassBenderToValue(float& current, float go_to, float intensity, bool use_easing); + + CPerlinNoise1D* PerlinNoise1D{}; + + struct grass_data + { + u8 index; + s8 anim[16]; + u16 id[16]; + Fvector pos[16]; + Fvector3 dir[16]; + float radius[16]; + float radius_curr[16]; + float str[16]; + float str_target[16]; + float time[16]; + float fade[16]; + float speed[16]; + } grass_shader_data{}; + + u32 m_last_ray_pick_time{}; + + bool m_isInHideout{}; + + bool IsActorInHideout(); + public: void destroy_particles(const bool& all_particles); @@ -158,5 +203,37 @@ class IMainMenu virtual void DestroyInternal(bool bForce) = 0; }; +// Anomaly +extern ENGINE_API float ps_r2_img_exposure; // r2-only +extern ENGINE_API float ps_r2_img_gamma; // r2-only +extern ENGINE_API float ps_r2_img_saturation; // r2-only +extern ENGINE_API Fvector ps_r2_img_cg; // r2-only + +extern ENGINE_API Fvector4 ps_r2_mask_control; +extern ENGINE_API Fvector ps_r2_drops_control; +extern ENGINE_API int ps_r2_nightvision; + +extern ENGINE_API Fvector4 ps_dev_param_1; +extern ENGINE_API Fvector4 ps_dev_param_2; +extern ENGINE_API Fvector4 ps_dev_param_3; +extern ENGINE_API Fvector4 ps_dev_param_4; +extern ENGINE_API Fvector4 ps_dev_param_5; +extern ENGINE_API Fvector4 ps_dev_param_6; +extern ENGINE_API Fvector4 ps_dev_param_7; +extern ENGINE_API Fvector4 ps_dev_param_8; + +// Ascii's shaders +extern ENGINE_API Fvector4 ps_ssfx_hud_drops_1; +extern ENGINE_API Fvector4 ps_ssfx_hud_drops_2; +extern ENGINE_API Fvector4 ps_ssfx_blood_decals; +extern ENGINE_API Fvector4 ps_ssfx_rain_1; +extern ENGINE_API Fvector4 ps_ssfx_rain_2; +extern ENGINE_API Fvector4 ps_ssfx_rain_3; +extern ENGINE_API Fvector4 ps_ssfx_grass_shadows; +extern ENGINE_API Fvector3 ps_ssfx_shadow_cascades; +extern ENGINE_API Fvector4 ps_ssfx_grass_interactive; +extern ENGINE_API Fvector4 ps_ssfx_int_grass_params_1; +extern ENGINE_API Fvector4 ps_ssfx_int_grass_params_2; + extern ENGINE_API IGame_Persistent* g_pGamePersistent; #endif // IGame_PersistentH diff --git a/src/xrEngine/ILoadingScreen.h b/src/xrEngine/ILoadingScreen.h index dfeb0381791..8d32f71d276 100644 --- a/src/xrEngine/ILoadingScreen.h +++ b/src/xrEngine/ILoadingScreen.h @@ -15,8 +15,9 @@ class XR_NOVTABLE ILoadingScreen virtual void Initialize() = 0; + [[nodiscard]] + virtual bool IsShown() const = 0; virtual void Show(bool show) = 0; - virtual bool IsShown() = 0; virtual void Update(int stagesCompleted, int stagesTotal) = 0; virtual void Draw() = 0; diff --git a/src/xrEngine/Rain.cpp b/src/xrEngine/Rain.cpp index c914e81b468..53a9f677d63 100644 --- a/src/xrEngine/Rain.cpp +++ b/src/xrEngine/Rain.cpp @@ -53,7 +53,7 @@ CEffect_Rain::~CEffect_Rain() } // Born -void CEffect_Rain::Born(Item& dest, float radius) +void CEffect_Rain::Born(Item& dest, float radius, float speed) { Fvector axis; axis.set(0, -1, 0); @@ -72,7 +72,7 @@ void CEffect_Rain::Born(Item& dest, float radius) dest.D.random_dir(axis, deg2rad(drop_angle)); dest.P.set(x + view.x - dest.D.x * source_offset, source_offset + view.y, z + view.z - dest.D.z * source_offset); // dest.P.set (x+view.x,height+view.y,z+view.z); - dest.fSpeed = ::Random.randF(drop_speed_min, drop_speed_max); + dest.fSpeed = ::Random.randF(drop_speed_min, drop_speed_max) * speed; float height = max_distance; RenewItem(dest, height, RayPick(dest.P, dest.D, height, collide::rqtBoth)); @@ -139,6 +139,7 @@ void CEffect_Rain::OnFrame() float t = Device.fTimeDelta; clamp(t, 0.001f, 1.0f); hemi_factor = hemi_factor * (1.0f - t) + f * t; + rain_hemi = hemi_val; } #endif diff --git a/src/xrEngine/Rain.h b/src/xrEngine/Rain.h index bc89bf5362d..f1945819db6 100644 --- a/src/xrEngine/Rain.h +++ b/src/xrEngine/Rain.h @@ -58,6 +58,7 @@ class ENGINE_API CEffect_Rain // Sounds ref_sound snd_Ambient; + float rain_hemi = 0.0f; // Utilities void p_create(); @@ -70,7 +71,7 @@ class ENGINE_API CEffect_Rain void p_free(Particle* P); // Some methods - void Born(Item& dest, float radius); + void Born(Item& dest, float radius, float speed); void Hit(Fvector& pos); bool RayPick(const Fvector& s, const Fvector& d, float& range, collide::rq_target tgt); void RenewItem(Item& dest, float height, bool bHit); @@ -81,6 +82,8 @@ class ENGINE_API CEffect_Rain void Render(); void OnFrame(); + + float GetRainHemi() { return rain_hemi; } }; #endif // RainH diff --git a/src/xrEngine/Render.h b/src/xrEngine/Render.h index aa71e922dac..13e7f4764f9 100644 --- a/src/xrEngine/Render.h +++ b/src/xrEngine/Render.h @@ -273,6 +273,8 @@ class ENGINE_API IRender // data CFrustum ViewBase; + bool hud_loading; + public: // feature level virtual GenerationLevel GetGeneration() const = 0; diff --git a/src/xrEngine/Text_Console.cpp b/src/xrEngine/Text_Console.cpp index 90debde9d0b..238396e6588 100644 --- a/src/xrEngine/Text_Console.cpp +++ b/src/xrEngine/Text_Console.cpp @@ -336,22 +336,22 @@ void TextLoadingScreen::Initialize() } -void TextLoadingScreen::Show(bool status) +bool TextLoadingScreen::IsShown() const { - + return false; } -void TextLoadingScreen::Draw() +void TextLoadingScreen::Show(bool status) { } -bool TextLoadingScreen::IsShown() +void TextLoadingScreen::Update(int stagesCompleted, int stagesTotal) { - return false; + } -void TextLoadingScreen::Update(int stagesCompleted, int stagesTotal) +void TextLoadingScreen::Draw() { } diff --git a/src/xrEngine/Text_Console.h b/src/xrEngine/Text_Console.h index 9dd9006d34c..3b80155702e 100644 --- a/src/xrEngine/Text_Console.h +++ b/src/xrEngine/Text_Console.h @@ -6,15 +6,14 @@ class TextLoadingScreen : public ILoadingScreen { public: - ~TextLoadingScreen() = default; - void Initialize() override; + [[nodiscard]] + bool IsShown() const override; void Show(bool status) override; - void Draw() override; - bool IsShown() override; void Update(int stagesCompleted, int stagesTotal) override; + void Draw() override; void SetLevelLogo(cpcstr name) override; void SetStageTitle(cpcstr title) override; diff --git a/src/xrEngine/xr_ioc_cmd.cpp b/src/xrEngine/xr_ioc_cmd.cpp index 8644d1a1e4e..795aa177c39 100644 --- a/src/xrEngine/xr_ioc_cmd.cpp +++ b/src/xrEngine/xr_ioc_cmd.cpp @@ -565,6 +565,51 @@ virtual void Save (IWriter *F) {}; ENGINE_API bool renderer_allow_override = false; +// Anomaly +ENGINE_API float ps_r2_img_exposure = 1.0f; // r2-only +ENGINE_API float ps_r2_img_gamma = 1.0f; // r2-only +ENGINE_API float ps_r2_img_saturation = 1.0f; // r2-only +ENGINE_API Fvector ps_r2_img_cg = { .0f, .0f, .0f }; // r2-only +ENGINE_API Fvector4 ps_r2_mask_control = { .0f, .0f, .0f, .0f }; // r2-only, condition, vignette?, visor reflection, null? +ENGINE_API Fvector ps_r2_drops_control = { .0f, 1.15f, .0f }; // r2-only, power, null, speed +ENGINE_API int ps_r2_nightvision = 0; // beef's nvg enable + +ENGINE_API Fvector4 ps_dev_param_1 = { .0f, .0f, .0f, .0f }; +ENGINE_API Fvector4 ps_dev_param_2 = { .0f, .0f, .0f, .0f }; +ENGINE_API Fvector4 ps_dev_param_3 = { .0f, .0f, .0f, .0f }; +ENGINE_API Fvector4 ps_dev_param_4 = { .0f, .0f, .0f, .0f }; +ENGINE_API Fvector4 ps_dev_param_5 = { .0f, .0f, .0f, .0f }; +ENGINE_API Fvector4 ps_dev_param_6 = { .0f, .0f, .0f, .0f }; +// beef's nvg +// x = generation (1.0-3.0) . num_tubes (0.10, 0.20, 0.40, 0.11, 0.12) +// y = gain_adjust (0.1-3.0) . washout_threshold (0.0 - 0.9) +// z = vignette power (0.0-1.0) . glitch power (0-0.9) +// w = gain offset (0.5-3.0) . mode (0.0-1.0) +// TODO: put into it's own var, keep dev params for dev work +ENGINE_API Fvector4 ps_dev_param_7 = { .0f, .0f, .0f, .0f }; +// beef's nvg +// x = flipdown amount (1.0-100.0) . unused +// y = unused . nvg_radius (0.0, 0.9) +// z = unused +// w = unused +// TODO: put into it's own var, keep dev params for dev work +ENGINE_API Fvector4 ps_dev_param_8 = { .0f, .0f, .0f, .0f }; + +// Ascii1457's Screen Space Shaders +ENGINE_API Fvector4 ps_ssfx_hud_drops_1 = { 1.0f, 1.0f, 30.f, .05f }; // Anim Speed, Int, Reflection, Refraction +ENGINE_API Fvector4 ps_ssfx_hud_drops_2 = { .0225f, 1.f, 0.0f, 2.0f }; // Density, Size, Extra Gloss, Gloss +ENGINE_API Fvector4 ps_ssfx_blood_decals = { 0.6f, 0.6f, 0.f, 0.f }; +ENGINE_API Fvector4 ps_ssfx_rain_1 = { 2.0f, 0.1f, 0.6f, 2.f }; // Len, Width, Speed, Quality +ENGINE_API Fvector4 ps_ssfx_rain_2 = { 0.7f, 0.1f, 1.0f, 0.5f }; // Alpha, Brigthness, Refraction, Reflection +ENGINE_API Fvector4 ps_ssfx_rain_3 = { 0.01f, 1.0f, 0.0f, 0.0f }; // Alpha, Refraction ( Splashes ) - Yohji: Alpha was edited (0.5->0.01f) due to a bug with transparency and other particles. +ENGINE_API Fvector3 ps_ssfx_shadow_cascades = { 20.f, 40.f, 160.f }; +ENGINE_API Fvector4 ps_ssfx_grass_shadows = { .0f, .35f, 30.0f, .0f }; +ENGINE_API Fvector4 ps_ssfx_grass_interactive = { 1.0f, 8.f, 2000.0f, 1.0f }; +ENGINE_API Fvector4 ps_ssfx_int_grass_params_1 = { 1.0f, 1.0f, 1.0f, 25.0f }; +ENGINE_API Fvector4 ps_ssfx_int_grass_params_2 = { 1.0f, 5.0f, 1.0f, 1.0f }; +ENGINE_API Fvector4 ps_ssfx_wpn_dof_1 = { .0f, .0f, .0f, .0f }; +ENGINE_API float ps_ssfx_wpn_dof_2 = 1.0f; + class CCC_renderer : public CCC_Token { typedef CCC_Token inherited; @@ -748,6 +793,8 @@ ENGINE_API int ps_r__Supersample = 1; ENGINE_API int ps_r__WallmarksOnSkeleton = 0; ENGINE_API shared_str current_player_hud_sect{}; +Fvector3 ssfx_wetness_multiplier = { 1.0f, 0.3f, 0.0f }; + extern int ps_fps_limit; extern int ps_fps_limit_in_menu; @@ -914,4 +961,6 @@ void CCC_Register() extern int g_bShowRedText; CMD4(CCC_Integer, "debug_show_red_text", &g_bShowRedText, 0, 1); #endif + + CMD4(CCC_Vector3, "ssfx_wetness_multiplier", &ssfx_wetness_multiplier, Fvector3({ 0.1f, 0.1f, 0.0f} ), Fvector3({ 20.0f, 20.0f, 0.0f })); }; diff --git a/src/xrEngine/xr_ioc_cmd.h b/src/xrEngine/xr_ioc_cmd.h index 71987264403..3045d63642f 100644 --- a/src/xrEngine/xr_ioc_cmd.h +++ b/src/xrEngine/xr_ioc_cmd.h @@ -30,6 +30,38 @@ extern ENGINE_API bool renderer_allow_override; // allows to change renderer setting +// Anomaly +extern ENGINE_API float ps_r2_img_exposure; +extern ENGINE_API float ps_r2_img_gamma; +extern ENGINE_API float ps_r2_img_saturation; +extern ENGINE_API Fvector ps_r2_img_cg; + +extern ENGINE_API Fvector4 ps_r2_mask_control; +extern ENGINE_API Fvector ps_r2_drops_control; +extern ENGINE_API int ps_r2_nightvision; + +extern ENGINE_API Fvector4 ps_dev_param_1; +extern ENGINE_API Fvector4 ps_dev_param_2; +extern ENGINE_API Fvector4 ps_dev_param_3; +extern ENGINE_API Fvector4 ps_dev_param_4; +extern ENGINE_API Fvector4 ps_dev_param_5; +extern ENGINE_API Fvector4 ps_dev_param_6; +extern ENGINE_API Fvector4 ps_dev_param_7; +extern ENGINE_API Fvector4 ps_dev_param_8; + +// Ascii's Shaders +extern ENGINE_API Fvector4 ps_ssfx_hud_drops_1; +extern ENGINE_API Fvector4 ps_ssfx_hud_drops_2; +extern ENGINE_API Fvector4 ps_ssfx_blood_decals; +extern ENGINE_API Fvector4 ps_ssfx_rain_1; +extern ENGINE_API Fvector4 ps_ssfx_rain_2; +extern ENGINE_API Fvector4 ps_ssfx_rain_3; +extern ENGINE_API Fvector4 ps_ssfx_grass_shadows; +extern ENGINE_API Fvector3 ps_ssfx_shadow_cascades; +extern ENGINE_API Fvector4 ps_ssfx_grass_interactive; +extern ENGINE_API Fvector4 ps_ssfx_int_grass_params_1; +extern ENGINE_API Fvector4 ps_ssfx_int_grass_params_2; + class ENGINE_API IConsole_Command { public: @@ -332,6 +364,69 @@ class ENGINE_API CCC_Vector3 : public IConsole_Command } }; +class CCC_Vector4 : public IConsole_Command +{ +protected: + Fvector4* value; + Fvector4 min, max; + +public: + CCC_Vector4(pcstr name, Fvector4* val, const Fvector4 _min, const Fvector4 _max) + : IConsole_Command(name), value(val), min(_min), max(_max) {} + + [[nodiscard]] + Fvector4 GetValue() const { return *value; } + + [[nodiscard]] + Fvector4* GetValuePtr() const { return value; } + + void Execute(pcstr args) override + { + Fvector4 v; + if (4 != sscanf(args, "%f,%f,%f,%f", &v.x, &v.y, &v.z, &v.w)) + { + if (4 != sscanf(args, "(%f,%f,%f,%f)", &v.x, &v.y, &v.z, &v.w)) + { + InvalidSyntax(); + return; + } + } + + if (v.x < min.x || v.y < min.y || v.z < min.z || v.w < min.w) + { + InvalidSyntax(); + return; + } + if (v.x > max.x || v.y > max.y || v.z > max.z || v.w > max.w) + { + InvalidSyntax(); + return; + } + value->set(v); + } + + void GetStatus(TStatus& S) override + { + xr_sprintf(S, "(%f, %f, %f, %f)", value->x, value->y, value->z, value->w); + } + + void Info(TInfo& I) override + { + xr_sprintf(I, "vector4 in range [%e,%e,%e,%e]-[%e,%e,%e,%e]", min.x, min.y, min.z, min.w, max.x, + max.y, max.z, max.w); + } + + void fill_tips(vecTips& tips, u32 mode) override + { + TStatus str; + xr_sprintf(str, "(%e, %e, %e, %e) (current) [(%e,%e,%e,%e)-(%e,%e,%e,%e)]", + value->x, value->y, value->z, value->w, + min.x, min.y, min.z, min.w, max.x, max.y, max.z, max.w); + tips.emplace_back(str); + IConsole_Command::fill_tips(tips, mode); + } +}; + class ENGINE_API CCC_Integer : public IConsole_Command { protected: diff --git a/src/xrGame/Actor.cpp b/src/xrGame/Actor.cpp index 60e27c2fec4..a2f8e3e2eb4 100644 --- a/src/xrGame/Actor.cpp +++ b/src/xrGame/Actor.cpp @@ -75,6 +75,8 @@ #include "ui/UIDragDropReferenceList.h" #include "xrCore/xr_token.h" +#include "xrEngine/Rain.h" + //const u32 patch_frames = 50; //const float respawn_delay = 1.f; //const float respawn_auto = 7.f; @@ -83,6 +85,9 @@ constexpr float default_feedback_duration = 0.2f; extern float cammera_into_collision_shift; extern int g_first_person_death; +extern ENGINE_API Fvector4 ps_ssfx_hud_drops_1; +extern ENGINE_API Fvector4 ps_r2_mask_control; +extern ENGINE_API Fvector ps_r2_drops_control; string32 ACTOR_DEFS::g_quick_use_slots[4] = {}; // skeleton @@ -1015,6 +1020,111 @@ float CActor::currentFOV() } } +// Ascii hud rain drops support +void CActor::UpdateHudRainDrops() +{ + constexpr float animSpeed = 1.f; + constexpr float buildSpeed = 2.f; + constexpr float dryingSpeed = 1.f; + float rainFactor = g_pGamePersistent->Environment().CurrentEnv.rain_density; + CEffect_Rain* rain = g_pGamePersistent->pEnvironment->eff_Rain; + + if (rainFactor > 0.f) + { + if (!g_pGamePersistent->IsActorInHideout()) + { + float rainSpeedFactor = (1.5f - rainFactor) * 10.f; + m_dropsAnimIncrementor += (animSpeed * Device.fTimeDelta) / rainSpeedFactor; + m_dropsIntensity += (buildSpeed * Device.fTimeDelta) / 100.f; + } + else + { + m_dropsIntensity -= (dryingSpeed * Device.fTimeDelta) / 100.f; + } + } + else + { + m_dropsIntensity -= (dryingSpeed * Device.fTimeDelta) / 100.f; + } + + clamp(m_dropsIntensity, 0.f, 1.f); + + if (fsimilar(m_dropsAnimIncrementor, FLT_MAX, 1.f)) + m_dropsAnimIncrementor = 0.f; + + ps_ssfx_hud_drops_1.x = m_dropsAnimIncrementor; + ps_ssfx_hud_drops_1.y = m_dropsIntensity; +} + +// Currently WIP +// Visor Rain Drops +void CActor::UpdateVisorRainDrops() +{ + float visorBuildSpeed = 4.f; + float visorDryingSpeed = 8.f; + float rainFactor = g_pGamePersistent->Environment().CurrentEnv.rain_density; + static u32 dropsUpdateTime = 0; + bool isInHideout = g_pGamePersistent->IsActorInHideout(); + + if (rainFactor > 0.f) + { + if (!isInHideout) + { + if (ps_r2_drops_control.x < 0.1f) // jump start the rain effect when we move out of cover + ps_r2_drops_control.x = 0.1f; + + if (ps_r2_drops_control.x < 0.5f) + ps_r2_drops_control.x += (visorBuildSpeed * Device.fTimeDelta) / 100.f; + else if (Device.dwTimeGlobal > dropsUpdateTime) + { + ps_r2_drops_control.x += .0025f; + dropsUpdateTime = Device.dwTimeGlobal + 1000; + } + } + else + { + ps_r2_drops_control.x -= (visorDryingSpeed * Device.fTimeDelta) / 100.f; + } + } + else + { + ps_r2_drops_control.x -= (visorDryingSpeed * Device.fTimeDelta) / 100.f; + } + + clamp(ps_r2_drops_control.x, 0.f, 1.f); + + if ((rainFactor > 0.f && !isInHideout) || fsimilar(ps_r2_drops_control.x, 0.f, 0.05f)) + ps_r2_drops_control.z = m_dropsIntensity / 2.f; +} + +// Visor Condition, Reflection +void CActor::UpdateVisor() +{ + PIItem pVisor = inventory().ItemFromSlot(HELMET_SLOT); + if (!pVisor) + { + auto pOutfit = smart_cast(inventory().ItemFromSlot(OUTFIT_SLOT)); + if (pOutfit && !pOutfit->bIsHelmetAvaliable) // if our outfit blocks the helmet, it probably includes it's own helmet + pVisor = pOutfit->cast_inventory_item(); + } + + if (pVisor) + { + float condition = 1.1f - pVisor->GetCondition(); + ps_r2_mask_control.x = round(condition * 10.f); + // TODO: dont hardcode these + // and add cracking sounds when the condition changes + ps_r2_mask_control.y = 1.f; + ps_r2_mask_control.z = 1.f; + } + else + { + ps_r2_mask_control.x = 0.f; + ps_r2_mask_control.y = 0.f; + ps_r2_mask_control.z = 0.f; + } +} + void CActor::UpdateCL() { if (g_Alive() && Level().CurrentViewEntity() == this) @@ -1181,6 +1291,10 @@ void CActor::UpdateCL() if (psActorFlags.test(AF_MULTI_ITEM_PICKUP)) m_bPickupMode = false; + + UpdateHudRainDrops(); + UpdateVisorRainDrops(); + UpdateVisor(); } float NET_Jump = 0; diff --git a/src/xrGame/Actor.h b/src/xrGame/Actor.h index 77b5bd48247..319b25220c1 100644 --- a/src/xrGame/Actor.h +++ b/src/xrGame/Actor.h @@ -333,6 +333,10 @@ class CActor : public CEntityAlive, void cam_UnsetLadder(); float currentFOV(); + void UpdateHudRainDrops(); + void UpdateVisorRainDrops(); + void UpdateVisor(); + // Cameras CCameraBase* cameras[eacMaxCam]; EActorCameras cam_active; @@ -412,6 +416,9 @@ class CActor : public CEntityAlive, bool AnyMove() { return (mstate_real & mcAnyMove) != 0; }; bool is_jump(); u32 MovingState() const { return mstate_real; } + float m_dropsIntensity{}; + float m_dropsAnimIncrementor{}; + protected: u32 mstate_wishful; u32 mstate_old; diff --git a/src/xrGame/CustomZone.cpp b/src/xrGame/CustomZone.cpp index d5916d0ec5f..ee5e7a8eeb0 100644 --- a/src/xrGame/CustomZone.cpp +++ b/src/xrGame/CustomZone.cpp @@ -23,6 +23,8 @@ #define WIND_RADIUS (4 * Radius()) //расстояние до актера, когда появляется ветер #define FASTMODE_DISTANCE (50.f) // distance to camera from sphere, when zone switches to fast update sequence +extern ENGINE_API Fvector4 ps_ssfx_int_grass_params_1; + CCustomZone::CCustomZone(void) { m_zone_flags.zero(); @@ -60,6 +62,7 @@ CCustomZone::CCustomZone(void) CCustomZone::~CCustomZone(void) { + g_pGamePersistent->GrassBendersRemoveByIndex(grassbender_id); m_idle_sound.destroy(); m_accum_sound.destroy(); m_awaking_sound.destroy(); @@ -101,6 +104,58 @@ void CCustomZone::Load(LPCSTR section) LPCSTR sound_str = NULL; + // -- Interactive Grass - IDLE + if (pSettings->line_exist(section, "bend_grass_idle_anim")) + m_BendGrass_idle_anim = pSettings->r_s8(section, "bend_grass_idle_anim"); + else + m_BendGrass_idle_anim = -1; + + if (pSettings->line_exist(section, "bend_grass_idle_str")) + m_BendGrass_idle_str = pSettings->r_float(section, "bend_grass_idle_str"); + else + m_BendGrass_idle_str = 1.0f; + + if (pSettings->line_exist(section, "bend_grass_idle_radius")) + m_BendGrass_idle_radius = pSettings->r_float(section, "bend_grass_idle_radius"); + else + m_BendGrass_idle_radius = 1.0f; + + if (pSettings->line_exist(section, "bend_grass_idle_speed")) + m_BendGrass_idle_speed = pSettings->r_float(section, "bend_grass_idle_speed"); + else + m_BendGrass_idle_speed = 1.0f; + + // -- Interactive Grass - ACTIVE + if (pSettings->line_exist(section, "bend_grass_whenactive_anim")) + m_BendGrass_whenactive_anim = pSettings->r_s8(section, "bend_grass_whenactive_anim"); + else + m_BendGrass_whenactive_anim = -1; + + if (pSettings->line_exist(section, "bend_grass_whenactive_speed")) + m_BendGrass_whenactive_speed = pSettings->r_float(section, "bend_grass_whenactive_speed"); + else + m_BendGrass_whenactive_speed = -1; + + if (pSettings->line_exist(section, "bend_grass_whenactive_str")) + m_BendGrass_whenactive_str = pSettings->r_float(section, "bend_grass_whenactive_str"); + else + m_BendGrass_whenactive_str = -1; + + // -- Interactive Grass - BLOWOUT + if (pSettings->line_exist(section, "bend_grass_blowout_duration")) + m_BendGrass_Blowout_time = pSettings->r_u32(section, "bend_grass_blowout_duration"); + else + m_BendGrass_Blowout_time = -1; + + if (pSettings->line_exist(section, "bend_grass_blowout")) + m_BendGrass_Blowout = pSettings->r_bool(section, "bend_grass_blowout"); + + if (pSettings->line_exist(section, "bend_grass_blowout_speed")) + m_BendGrass_Blowout_speed = pSettings->r_float(section, "bend_grass_blowout_speed"); + + if (pSettings->line_exist(section, "bend_grass_blowout_radius")) + m_BendGrass_Blowout_radius = pSettings->r_float(section, "bend_grass_blowout_radius"); + if (pSettings->line_exist(section, "idle_sound")) { sound_str = pSettings->r_string(section, "idle_sound"); @@ -593,6 +648,32 @@ void CCustomZone::shedule_Update(u32 dt) if (!m_zone_flags.test(eFastMode)) UpdateWorkload(dt); + + const float act_distance = Level().CurrentControlEntity()->Position().distance_to(P) - s.R; + if (act_distance < ps_ssfx_int_grass_params_1.w) + GrassZoneUpdate(); + else + { + // Out of range, fadeOut if a grassbender_id is assigned + if (grassbender_id) + { + IGame_Persistent::grass_data& GData = g_pGamePersistent->grass_shader_data; + + // If the ID doesn't match... Just remove the grassbender_id. + if (GData.id[grassbender_id] == ID()) + { + GData.str_target[grassbender_id] += g_pGamePersistent->GrassBenderToValue(GData.str_target[grassbender_id], 0.0f, 4.0f, false); + + // Remove ( Don't worry, GrassBenderToValue() it's going to get the == 0 ) + if (GData.str_target[grassbender_id] == 0) + g_pGamePersistent->GrassBendersRemoveByIndex(grassbender_id); + } + else + { + grassbender_id = 0; + } + } + } }; UpdateOnOffState(); @@ -783,6 +864,7 @@ void CCustomZone::PlayBlowoutParticles() pParticles = CParticlesObject::Create(*m_sBlowoutParticles, TRUE); pParticles->UpdateParent(XFORM(), zero_vel); pParticles->Play(false); + m_fBlowoutTimeLeft = (float)Device.dwTimeGlobal + m_BendGrass_Blowout_time; } void CCustomZone::PlayHitParticles(CGameObject* pObject) @@ -1100,6 +1182,8 @@ void CCustomZone::UpdateBlowout() { AffectObjects(); BornArtefact(); + if (m_BendGrass_Blowout) + g_pGamePersistent->GrassBendersAddExplosion(ID(), Position(), Fvector().set(0, -99, 0), 1.33f, m_BendGrass_Blowout_speed, 1.0f, m_BendGrass_Blowout_radius); } } @@ -1133,6 +1217,13 @@ void CCustomZone::OnMove() if (m_pIdleLight && m_pIdleLight->get_active()) m_pIdleLight->set_position(Position()); + + if (grassbender_id) + { + // Check ID, just in case... + if (g_pGamePersistent->grass_shader_data.id[grassbender_id] == ID()) + g_pGamePersistent->grass_shader_data.pos[grassbender_id] = Position(); + } } } @@ -1664,3 +1755,61 @@ void CCustomZone::load(IReader& input_packet) else m_eZoneState = eZoneStateIdle; } + +void CCustomZone::GrassZoneUpdate() +{ + if (m_BendGrass_idle_anim == -1 && m_BendGrass_whenactive_anim == -1) + return; + + IGame_Persistent::grass_data& GData = g_pGamePersistent->grass_shader_data; + bool IsActive; + s8 targetAnim = -1; + + // If m_BendGrass_Blowout_time is not set, use m_eZoneState to detect activation + if (m_BendGrass_Blowout_time <= -1) + IsActive = m_eZoneState != eZoneStateIdle; + else + IsActive = m_fBlowoutTimeLeft > (float)Device.dwTimeGlobal; + + // Target animation depending if Zone is active + if (IsActive) + targetAnim = (m_BendGrass_whenactive_anim > -1) ? m_BendGrass_whenactive_anim : m_BendGrass_idle_anim; + else + targetAnim = m_BendGrass_idle_anim; + + // Update grass bender if the animation is > -1 + if (targetAnim > 0 || (grassbender_id > 0 && GData.anim[grassbender_id] > 0)) + g_pGamePersistent->GrassBendersUpdate(ID(), grassbender_id, grassbender_frame, Position(), m_BendGrass_idle_radius, 0.0f, false); + else + g_pGamePersistent->GrassBendersRemoveByIndex(grassbender_id); + + // Return if grassbender_id doesn't exist + if (grassbender_id <= 0) + return; + + // Animation transition, diminish intensity to 0 and change. + if (GData.anim[grassbender_id] != targetAnim) + { + GData.str_target[grassbender_id] += g_pGamePersistent->GrassBenderToValue(GData.str_target[grassbender_id], 0.0f, 7.5f, false); + + if (GData.str_target[grassbender_id] <= 0.05f) + GData.anim[grassbender_id] = targetAnim; + + return; + } + + // Apply settings when needed + if (IsActive) + { + if (m_BendGrass_whenactive_speed >= 0) + GData.speed[grassbender_id] += g_pGamePersistent->GrassBenderToValue(GData.speed[grassbender_id], m_BendGrass_whenactive_speed, 10.0f, true); + + if (m_BendGrass_whenactive_str >= 0) + GData.str_target[grassbender_id] += g_pGamePersistent->GrassBenderToValue(GData.str_target[grassbender_id], m_BendGrass_whenactive_str, 10.0f, true); + } + else + { + GData.speed[grassbender_id] += g_pGamePersistent->GrassBenderToValue(GData.speed[grassbender_id], m_BendGrass_idle_speed, 10.0f, true); + GData.str_target[grassbender_id] += g_pGamePersistent->GrassBenderToValue(GData.str_target[grassbender_id], m_BendGrass_idle_str, 10.0f, true); + } +} diff --git a/src/xrGame/CustomZone.h b/src/xrGame/CustomZone.h index 90711a1ce2c..4582a0b814a 100644 --- a/src/xrGame/CustomZone.h +++ b/src/xrGame/CustomZone.h @@ -351,4 +351,27 @@ class CCustomZone : public CSpaceRestrictor, public Feel::Touch // Lain: added private: virtual bool light_in_slow_mode() { return true; } + +protected: + // Interactive grass Settings + float m_fBlowoutTimeLeft{}; + + s8 m_BendGrass_idle_anim{}; + float m_BendGrass_idle_radius{}; + float m_BendGrass_idle_speed{}; + float m_BendGrass_idle_str{}; + + s8 m_BendGrass_whenactive_anim{}; + float m_BendGrass_whenactive_speed{}; + float m_BendGrass_whenactive_str{}; + + bool m_BendGrass_Blowout{}; + s32 m_BendGrass_Blowout_time{}; + float m_BendGrass_Blowout_speed{}; + float m_BendGrass_Blowout_radius{}; + + u8 grassbender_id{}; + u32 grassbender_frame{}; + + void GrassZoneUpdate(); }; diff --git a/src/xrGame/Explosive.cpp b/src/xrGame/Explosive.cpp index 5493c6550f2..17af0a63dbd 100644 --- a/src/xrGame/Explosive.cpp +++ b/src/xrGame/Explosive.cpp @@ -321,6 +321,8 @@ float CExplosive::TestPassEffect(const Fvector& source_p, const Fvector& dir, fl return dist_factor; return shoot_factor * dist_factor; } + +extern ENGINE_API Fvector4 ps_ssfx_int_grass_params_2; void CExplosive::Explode() { VERIFY(0xffff != Initiator()); @@ -339,6 +341,9 @@ void CExplosive::Explode() DBG_DrawPoint(pos, 0.3f, color_xrgb(255, 0, 0)); } #endif + // Interactive Grass FX + g_pGamePersistent->GrassBendersAddExplosion(cast_game_object()->ID(), pos, Fvector().set(0, -99, 0), 1.33f, ps_ssfx_int_grass_params_2.y, ps_ssfx_int_grass_params_2.x, m_fBlastRadius * 2.0f); + // Msg("---------CExplosive Explode [%d] frame[%d]",cast_game_object()->ID(), Device.dwFrame); OnBeforeExplosion(); diff --git a/src/xrGame/GamePersistent.cpp b/src/xrGame/GamePersistent.cpp index 495209cbdb7..5eb2bb968fd 100644 --- a/src/xrGame/GamePersistent.cpp +++ b/src/xrGame/GamePersistent.cpp @@ -269,7 +269,7 @@ void CGamePersistent::WeathersUpdate() CActor* actor = smart_cast(Level().CurrentViewEntity()); BOOL bIndoor = TRUE; if (actor) - bIndoor = actor->renderable_ROS()->get_luminocity_hemi() < 0.05f; + bIndoor = g_pGamePersistent->IsActorInHideout() && (actor->renderable_ROS()->get_luminocity_hemi() < 0.05f); if (CEnvAmbient* env_amb = Environment().CurrentEnv.env_ambient) { @@ -433,17 +433,19 @@ bool allow_game_intro() void CGamePersistent::start_logo_intro() { + const bool notLoadingLevel = xr_strlen(m_game_params.m_game_or_spawn) == 0 && g_pGameLevel == nullptr; if (!allow_intro()) { m_intro_event = nullptr; - Console->Execute("main_menu on"); + if (notLoadingLevel) + m_pMainMenu->Activate(true); return; } if (Device.dwPrecacheFrame == 0) { m_intro_event = nullptr; - if (!GEnv.isDedicatedServer && 0 == xr_strlen(m_game_params.m_game_or_spawn) && NULL == g_pGameLevel) + if (!GEnv.isDedicatedServer && notLoadingLevel) { VERIFY(NULL == m_intro); m_intro = xr_new(); @@ -456,7 +458,7 @@ void CGamePersistent::start_logo_intro() void CGamePersistent::update_logo_intro() { xr_delete(m_intro); - Console->Execute("main_menu on"); + m_pMainMenu->Activate(true); } extern int g_keypress_on_start; diff --git a/src/xrGame/MainMenu.cpp b/src/xrGame/MainMenu.cpp index 2dc986ba265..7b59e08255f 100644 --- a/src/xrGame/MainMenu.cpp +++ b/src/xrGame/MainMenu.cpp @@ -80,7 +80,13 @@ CMainMenu::CMainMenu() public: CResetEventCb(CID cid, CMainMenu* mm) : CEventNotifierCallbackWithCid(cid), m_mainmenu(mm) {} - void ProcessEvent() override { m_mainmenu->DestroyInternal(true); } + void ProcessEvent() override + { + if (m_mainmenu->IsActive()) + m_mainmenu->ReloadUI(); + else + m_mainmenu->DestroyInternal(true); + } }; m_script_reset_event_cid = ai().template Subscribe(CAI_Space::EVENT_SCRIPT_ENGINE_RESET, this); @@ -671,7 +677,10 @@ void CMainMenu::SwitchToMultiplayerMenu() { m_startDialog->Dispatch(2, 1); }; void CMainMenu::DestroyInternal(bool bForce) { if (m_startDialog && ((m_deactivated_frame < Device.dwFrame + 4) || bForce)) + { + m_startDialog->HideDialog(); xr_delete(m_startDialog); + } } void CMainMenu::OnPatchCheck(bool success, LPCSTR VersionName, LPCSTR URL) diff --git a/src/xrGame/PHMovementControl.cpp b/src/xrGame/PHMovementControl.cpp index 6a551365c4d..c07ce222bd6 100644 --- a/src/xrGame/PHMovementControl.cpp +++ b/src/xrGame/PHMovementControl.cpp @@ -1115,6 +1115,10 @@ void CPHMovementControl::PHReleaseObject() void CPHMovementControl::DestroyCharacter() { VERIFY(m_character); + // Remove Grass bender if PHCharacter is not NULL + if (m_character->PhysicsRefObject() != NULL) + g_pGamePersistent->GrassBendersRemoveById(m_character->PhysicsRefObject()->ObjectID()); + m_character->Destroy(); phcapture_destroy(m_capture); // xr_delete(m_capture); diff --git a/src/xrGame/WeaponFire.cpp b/src/xrGame/WeaponFire.cpp index 8786abc40c6..fbbe67b9104 100644 --- a/src/xrGame/WeaponFire.cpp +++ b/src/xrGame/WeaponFire.cpp @@ -51,6 +51,8 @@ void random_dir(Fvector& tgt_dir, const Fvector& src_dir, float dispersion) } float CWeapon::GetWeaponDeterioration() { return conditionDecreasePerShot; }; + +extern ENGINE_API Fvector4 ps_ssfx_int_grass_params_2; void CWeapon::FireTrace(const Fvector& P, const Fvector& D) { VERIFY(m_magazine.size()); @@ -117,6 +119,10 @@ void CWeapon::FireTrace(const Fvector& P, const Fvector& D) if (m_bLightShotEnabled) Light_Start(); + // Interactive Grass FX + Fvector ShotPos = Fvector().mad(P, D, 1.5f); + g_pGamePersistent->GrassBendersAddShot(cast_game_object()->ID(), ShotPos, D, 3.0f, 20.0f, ps_ssfx_int_grass_params_2.z, ps_ssfx_int_grass_params_2.w); + // Ammo m_magazine.pop_back(); --iAmmoElapsed; diff --git a/src/xrGame/ai/monsters/burer/burer_state_attack_gravi_inline.h b/src/xrGame/ai/monsters/burer/burer_state_attack_gravi_inline.h index 9a954ef451a..5f7e6e3691b 100644 --- a/src/xrGame/ai/monsters/burer/burer_state_attack_gravi_inline.h +++ b/src/xrGame/ai/monsters/burer/burer_state_attack_gravi_inline.h @@ -124,6 +124,7 @@ void CStateBurerAttackGravi::ExecuteGraviContinue() } } +extern ENGINE_API Fvector4 ps_ssfx_grass_interactive; template void CStateBurerAttackGravi::ExecuteGraviFire() { @@ -137,4 +138,6 @@ void CStateBurerAttackGravi::ExecuteGraviFire() this->object->StopGraviPrepare(); this->object->sound().play(CBurer::eMonsterSoundGraviAttack); + // Interactive Grass FX + g_pGamePersistent->GrassBendersAddExplosion(this->object->ID(), from_pos, this->object->Direction(), 1.33f, 3.0f, ps_ssfx_grass_interactive.w, 13.0f); } diff --git a/src/xrGame/ai/monsters/pseudogigant/pseudo_gigant.cpp b/src/xrGame/ai/monsters/pseudogigant/pseudo_gigant.cpp index af8fa7e6e61..6e395abc856 100644 --- a/src/xrGame/ai/monsters/pseudogigant/pseudo_gigant.cpp +++ b/src/xrGame/ai/monsters/pseudogigant/pseudo_gigant.cpp @@ -287,6 +287,7 @@ void CPseudoGigant::on_activate_control(ControlCom::EControlType type) } } +extern ENGINE_API Fvector4 ps_ssfx_grass_interactive; void CPseudoGigant::on_threaten_execute() { // разбросить объекты @@ -313,6 +314,9 @@ void CPseudoGigant::on_threaten_execute() pos.y += 0.1f; m_sound_threaten_hit.play_at_pos(this, pos); + // Interactive Grass FX + g_pGamePersistent->GrassBendersAddExplosion(ID(), pos, Fvector().set(0, -99, 0), 1.33f, 5.0f, ps_ssfx_grass_interactive.w, 20); + // играть партиклы PlayParticles(m_kick_particles, pos, Direction()); diff --git a/src/xrGame/level_script.cpp b/src/xrGame/level_script.cpp index eef0b9a8b52..bda80dcc7cc 100644 --- a/src/xrGame/level_script.cpp +++ b/src/xrGame/level_script.cpp @@ -41,6 +41,7 @@ #include "raypick.h" #include "xrCDB/xr_collide_defs.h" #include "xrNetServer/NET_Messages.h" +#include "xrEngine/Rain.h" LPCSTR command_line() { return Core.Params; } bool IsDynamicMusic() { return !!psActorFlags.test(AF_DYNAMIC_MUSIC); } @@ -191,6 +192,33 @@ float low_cover_in_direction(u32 level_vertex_id, const Fvector& direction) } float rain_factor() { return (g_pGamePersistent->Environment().CurrentEnv.rain_density); } +float rain_wetness() { return (g_pGamePersistent->Environment().wetness_factor); } +float rain_hemi() +{ + CEffect_Rain* rain = g_pGamePersistent->pEnvironment->eff_Rain; + + if (rain) + { + return rain->GetRainHemi(); + } + else + { + IGameObject* E = g_pGameLevel->CurrentViewEntity(); + if (E && E->renderable_ROS()) + { + float* hemi_cube = E->renderable_ROS()->get_luminocity_hemi_cube(); + float hemi_val = _max(hemi_cube[0], hemi_cube[1]); + hemi_val = _max(hemi_val, hemi_cube[2]); + hemi_val = _max(hemi_val, hemi_cube[3]); + hemi_val = _max(hemi_val, hemi_cube[5]); + + return hemi_val; + } + + return 0.f; + } +} + u32 vertex_in_direction(u32 level_vertex_id, Fvector direction, float max_distance) { direction.normalize_safe(); @@ -747,6 +775,7 @@ IC static void CLevel_Export(lua_State* luaState) def("high_cover_in_direction", high_cover_in_direction), def("low_cover_in_direction", low_cover_in_direction), def("vertex_in_direction", vertex_in_direction), def("rain_factor", rain_factor), + def("rain_wetness", rain_wetness), def("rain_hemi", rain_hemi), def("patrol_path_exists", patrol_path_exists), def("vertex_position", vertex_position), def("name", +[]() { return Level().name().c_str(); }), def("prefetch_sound", prefetch_sound), diff --git a/src/xrGame/movement_manager.cpp b/src/xrGame/movement_manager.cpp index b166372312f..f445f07448c 100644 --- a/src/xrGame/movement_manager.cpp +++ b/src/xrGame/movement_manager.cpp @@ -338,6 +338,9 @@ void CMovementManager::on_frame(CPHMovementControl* movement_control, Fvector& d update_path(); move_along_path(movement_control, dest_position, object().client_update_fdelta()); + + // Update Grass benders + g_pGamePersistent->GrassBendersUpdate(object().ID(), grassbender_id, grassbender_frame, object().Position(), -1.0f, 1.0f, true); } void CMovementManager::on_travel_point_change(const u32& previous_travel_point_index) diff --git a/src/xrGame/movement_manager.h b/src/xrGame/movement_manager.h index 10f5584bde9..959b4fdf49b 100644 --- a/src/xrGame/movement_manager.h +++ b/src/xrGame/movement_manager.h @@ -247,6 +247,8 @@ class CMovementManager const float& prediction_speed) const; Fvector predict_position(const float& time_delta) const; Fvector target_position() const; + u8 grassbender_id{}; + u32 grassbender_frame{}; }; #include "movement_manager_inline.h" diff --git a/src/xrGame/player_hud.cpp b/src/xrGame/player_hud.cpp index e1fbbdb9372..ae82710b3a8 100644 --- a/src/xrGame/player_hud.cpp +++ b/src/xrGame/player_hud.cpp @@ -387,9 +387,9 @@ attachable_hud_item::attachable_hud_item(player_hud* parent, const shared_str& s m_visual_name = pSettings->r_string(m_sect_name, "visual"); } R_ASSERT3(!m_visual_name.empty(), "Missing 'item_visual' from weapon hud section.", m_sect_name.c_str()); - + GEnv.Render->hud_loading = true; m_model = smart_cast(GEnv.Render->model_Create(m_visual_name.c_str())); - + GEnv.Render->hud_loading = false; m_attach_place_idx = pSettings->read_if_exists(m_sect_name, "attach_place_idx", 0); IKinematicsAnimated* animatedHudItem; @@ -539,7 +539,9 @@ void player_hud::load(const shared_str& player_hud_sect) } const shared_str& model_name = pSettings->r_string(m_sect_name, "visual"); + GEnv.Render->hud_loading = true; m_model = smart_cast(GEnv.Render->model_Create(model_name.c_str())); + GEnv.Render->hud_loading = false; load_ancors(); // Msg("hands visual changed to [%s] [%s] [%s]", model_name.c_str(), b_reload ? "R" : "", m_attached_items[0] ? "Y" : ""); @@ -852,7 +854,7 @@ void player_hud::attach_item(CHudItem* item) attachable_hud_item* pi = create_hud_item(item->HudSection()); const int item_idx = pi->m_attach_place_idx; - if (m_attached_items[item_idx] != pi) + if (m_attached_items[item_idx] != pi || pi->m_parent_hud_item != item) { if (m_attached_items[item_idx]) m_attached_items[item_idx]->m_parent_hud_item->on_b_hud_detach(); diff --git a/src/xrGame/script_game_object_script2.cpp b/src/xrGame/script_game_object_script2.cpp index a6a0d902982..fdf38acfcc3 100644 --- a/src/xrGame/script_game_object_script2.cpp +++ b/src/xrGame/script_game_object_script2.cpp @@ -82,7 +82,7 @@ luabind::class_& script_register_game_object1(luabind::class_ .property("morale", &CScriptGameObject::GetMorale, &CScriptGameObject::SetMorale) .property("bleeding", &CScriptGameObject::GetBleeding, &CScriptGameObject::SetBleeding) - // .def("get_bleeding", &CScriptGameObject::GetBleeding) + .def("get_bleeding", &CScriptGameObject::GetBleeding) .def("center", &CScriptGameObject::Center) .def("position", &CScriptGameObject::Position) .def("direction", &CScriptGameObject::Direction) diff --git a/src/xrGame/ui/UILoadingScreen.cpp b/src/xrGame/ui/UILoadingScreen.cpp index aab31a61a53..32db07cd000 100644 --- a/src/xrGame/ui/UILoadingScreen.cpp +++ b/src/xrGame/ui/UILoadingScreen.cpp @@ -144,7 +144,7 @@ void UILoadingScreen::Show(bool show) } } -bool UILoadingScreen::IsShown() +bool UILoadingScreen::IsShown() const { return CUIWindow::IsShown(); } diff --git a/src/xrGame/ui/UILoadingScreen.h b/src/xrGame/ui/UILoadingScreen.h index 7a4febb5684..6ca0c28c936 100644 --- a/src/xrGame/ui/UILoadingScreen.h +++ b/src/xrGame/ui/UILoadingScreen.h @@ -34,7 +34,9 @@ class UILoadingScreen final : public ILoadingScreen, public CUIWindow void Initialize() override; void Show(bool show) override; - bool IsShown() override; + + [[nodiscard]] + bool IsShown() const override; void Update(const int stagesCompleted, const int stagesTotal) override; void Draw() override; diff --git a/src/xrUICore/Windows/UIWindow.h b/src/xrUICore/Windows/UIWindow.h index 2a577cf8119..191f45d2de6 100644 --- a/src/xrUICore/Windows/UIWindow.h +++ b/src/xrUICore/Windows/UIWindow.h @@ -16,21 +16,26 @@ class XRUICORE_API CUIWindow : public CUISimpleWindow, public CUIDebuggable { public: CUIWindow(pcstr window_name); - virtual ~CUIWindow(); + ~CUIWindow() override; //////////////////////////////////// //работа с дочерними и родительскими окнами virtual void AttachChild(CUIWindow* pChild); virtual void DetachChild(CUIWindow* pChild); - virtual bool IsChild(CUIWindow* pChild) const; virtual void DetachAll(); + [[nodiscard]] + virtual bool IsChild(CUIWindow* pPossibleChild) const; + [[nodiscard]] u32 GetChildNum() const { return (u32)m_ChildWndList.size(); } - void SetParent(CUIWindow* pNewParent); + [[nodiscard]] CUIWindow* GetParent() const { return m_pParentWnd; } + void SetParent(CUIWindow* pNewParent); + //получить окно самого верхнего уровня + [[nodiscard]] CUIWindow* GetTop() { if (m_pParentWnd == NULL) @@ -60,6 +65,7 @@ class XRUICORE_API CUIWindow : public CUISimpleWindow, public CUIDebuggable //сообщение посылается дочерним окном родительскому void SetCapture(CUIWindow* pChildWindow, bool capture_status); CUIWindow* GetMouseCapturer() { return m_pMouseCapturer; } + //окошко, которому пересылаются сообщения, //если NULL, то шлем на GetParent() void SetMessageTarget(CUIWindow* pWindow) { m_pMessageTarget = pWindow; } @@ -74,14 +80,20 @@ class XRUICORE_API CUIWindow : public CUISimpleWindow, public CUIDebuggable virtual void SendMessage(CUIWindow* pWnd, s16 msg, void* pData = NULL); virtual void Enable(bool status) { m_bIsEnabled = status; } - bool IsEnabled() { return m_bIsEnabled; } + + [[nodiscard]] + bool IsEnabled() const { return m_bIsEnabled; } + //убрать/показать окно и его дочерние окна virtual void Show(bool status) { SetVisible(status); Enable(status); } - virtual bool IsShown() { return GetVisible(); } + + [[nodiscard]] + virtual bool IsShown() const { return GetVisible(); } + void ShowChildren(bool show); //абсолютные координаты @@ -123,7 +135,8 @@ class XRUICORE_API CUIWindow : public CUISimpleWindow, public CUIDebuggable WINDOW_LIST& GetChildWndList() { return m_ChildWndList; } - IC bool IsAutoDelete() { return m_bAutoDelete; } + [[nodiscard]] + IC bool IsAutoDelete() const { return m_bAutoDelete; } IC void SetAutoDelete(bool auto_delete) { m_bAutoDelete = auto_delete; } // Name of the window @@ -132,8 +145,12 @@ class XRUICORE_API CUIWindow : public CUISimpleWindow, public CUIDebuggable CUIWindow* FindChild(const shared_str name); + [[nodiscard]] IC bool CursorOverWindow() const { return m_bCursorOverWindow; } + + [[nodiscard]] IC u32 FocusReceiveTime() const { return m_dwFocusReceiveTime; } + IC bool GetCustomDraw() const { return m_bCustomDraw; } IC void SetCustomDraw(bool b) { m_bCustomDraw = b; } diff --git a/src/xrUICore/XML/UIXmlInitBase.cpp b/src/xrUICore/XML/UIXmlInitBase.cpp index 65572088ab3..9371fd750b9 100644 --- a/src/xrUICore/XML/UIXmlInitBase.cpp +++ b/src/xrUICore/XML/UIXmlInitBase.cpp @@ -307,8 +307,14 @@ bool CUIXmlInitBase::InitText(CUIXml& xml_doc, LPCSTR path, int index, CUILines* CGameFont* pTmpFont = NULL; InitFont(xml_doc, path, index, color, pTmpFont); pLines->SetTextColor(color); - R_ASSERT(pTmpFont); - pLines->SetFont(pTmpFont); + if (pTmpFont) + pLines->SetFont(pTmpFont); + else + { +#ifndef MASTER_GOLD + Msg("~ Missing 'font' attribute in node [%s] in file [%s]", path, xml_doc.m_xml_file_name); +#endif + } // Load font alignment shared_str al = xml_doc.ReadAttrib(path, index, "align");