From d9f671d94dfc810a4fa41b15a53d1fc767d66eeb Mon Sep 17 00:00:00 2001 From: Andi Date: Sun, 17 Aug 2025 18:48:14 +0200 Subject: [PATCH 1/2] Additive mesh transparency tests --- .../Libraries/Source/WWVegas/WW3D2/rinfo.cpp | 1 + .../GameEngine/Include/GameClient/Drawable.h | 7 +++++ .../GameEngine/Source/GameClient/Drawable.cpp | 4 ++- .../Update/DynamicGeometryClientUpdate.cpp | 20 ++++++++++++-- .../Source/W3DDevice/GameClient/W3DScene.cpp | 2 ++ .../Source/WWVegas/WW3D2/dx8renderer.cpp | 26 +++++++++++++++++++ .../Libraries/Source/WWVegas/WW3D2/mesh.cpp | 15 +++++++++++ .../Libraries/Source/WWVegas/WW3D2/mesh.h | 2 ++ .../Libraries/Source/WWVegas/WW3D2/rinfo.h | 1 + 9 files changed, 75 insertions(+), 3 deletions(-) diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/rinfo.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/rinfo.cpp index cea7f87bce..da1a4d335b 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/rinfo.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/rinfo.cpp @@ -56,6 +56,7 @@ RenderInfoClass::RenderInfoClass(CameraClass & cam) : OverrideFlagLevel(0), Texture_Projector(NULL), alphaOverride(1.0f), + emissiveOverride(1.0f), materialPassAlphaOverride(1.0f), materialPassEmissiveOverride(1.0f) { diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Drawable.h b/GeneralsMD/Code/GameEngine/Include/GameClient/Drawable.h index 7fa5df5ea0..411308013e 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/Drawable.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/Drawable.h @@ -540,6 +540,11 @@ class Drawable : public Thing, inline Real getEffectiveOpacity() const { return m_explicitOpacity * m_effectiveStealthOpacity; } ///< get alpha/opacity value used to override defaults when drawing. void setEffectiveOpacity( Real pulseFactor, Real explicitOpacity = -1.0f ); + // AW: new params for additive transparency scaling (=emissive) + inline void setEmissiveOpacityScaling(bool value) { m_isEmissiveOpacityScaling = value; } + inline bool getEmissiveOpacityScaling() const { return m_isEmissiveOpacityScaling; } + inline Real getEmissiveOpacity() const { if (m_isEmissiveOpacityScaling) return getEffectiveOpacity(); else return 1.0; } + // this is for the add'l pass fx which operates completely independently of the stealth opacity effects. Draw() does the fading every frame. inline Real getSecondMaterialPassOpacity() const { return m_secondMaterialPassOpacity; } ///< get alpha/opacity value used to render add'l rendering pass. void setSecondMaterialPassOpacity( Real op ) { m_secondMaterialPassOpacity = op; }; ///< set alpha/opacity value used to render add'l rendering pass. @@ -663,6 +668,8 @@ class Drawable : public Thing, Real m_stealthOpacity; ///< <> opacity due to stealth. pulse is between opaque and this Real m_effectiveStealthOpacity; ///< opacity actually used to render with, after the pulse and stuff. + Bool m_isEmissiveOpacityScaling; ///< should emissive color be scaled with opacity (needed for fading out additive objects) + Real m_decalOpacityFadeTarget; Real m_decalOpacityFadeRate; Real m_decalOpacity; diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp index c7dc3ee9c2..047461e418 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp @@ -1122,7 +1122,6 @@ void Drawable::fadeIn( UnsignedInt frames ) ///< decloak object m_timeElapsedFade = 0; } - //------------------------------------------------------------------------------------------------- Real Drawable::getScale (void) const { @@ -5235,6 +5234,9 @@ void Drawable::xfer( Xfer *xfer ) // effective stealth opacity xfer->xferReal( &m_effectiveStealthOpacity ); + // Emissiv Opacity Scaling + xfer->xferBool(&m_isEmissiveOpacityScaling); + // decalOpacityFadeTarget xfer->xferReal( &m_decalOpacityFadeTarget ); diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable/Update/DynamicGeometryClientUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable/Update/DynamicGeometryClientUpdate.cpp index 6d062cc346..3a951c20d6 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable/Update/DynamicGeometryClientUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable/Update/DynamicGeometryClientUpdate.cpp @@ -191,13 +191,29 @@ void DynamicGeometryClientUpdate::clientUpdate( void ) progress = 0.5 - (Cos(progress * PI) * 0.5); } - // DEBUG_LOG((">>> DGCU - progress = %f", progress)); - Real alpha = (1.0 - progress) * alpha0 + progress * alpha1; Real scale = (1.0 - progress) * scale0 + progress * scale1; + draw->setInstanceScale(m_overrideScale * scale); + + // This doesn't work for additive! draw->setDrawableOpacity(m_overrideAlpha * alpha); + + // For additive with emissive color, this seems to work. + // But apparently not for all of them, and only for Static sorting? + draw->setEmissiveOpacityScaling(true); + + // This doesn't seem to work for all models either + //Real factor = (1.0 - alpha) * -2.5; + //RGBColor color; + //color.red = factor; + //color.green = factor; + //color.blue = factor; + //draw->colorTint(&color); + + // DEBUG_LOG((">>> DGCU - progress = %f, alpha = %f, scale = %f, effectiveOpacity = %f, factor = %f", progress, alpha, scale, draw->getEffectiveOpacity(), factor)); + } // ------------------------------------------------------------------------------------------------ diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DScene.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DScene.cpp index 8a102ca1da..4d5249b487 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DScene.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DScene.cpp @@ -1612,6 +1612,7 @@ void RTS3DScene::flushTranslucentObjects(RenderInfoClass & rinfo) draw = ((DrawableInfo *)robj->Get_User_Data())->m_drawable; rinfo.alphaOverride = draw->getEffectiveOpacity(); + rinfo.emissiveOverride = draw->getEmissiveOpacity(); renderOneObject(rinfo, robj, localPlayerIndex);//WW3D::Render(*robj,rinfo); } @@ -1620,6 +1621,7 @@ void RTS3DScene::flushTranslucentObjects(RenderInfoClass & rinfo) TheDX8MeshRenderer.Flush(); WW3D::Render_And_Clear_Static_Sort_Lists(rinfo); //draws things like water rinfo.alphaOverride = 1.0f; //disable forced alpha + rinfo.emissiveOverride = 1.0f; //disable forced alpha m_translucentObjectsCount = 0; } diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp index 83054de085..99102f39fe 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp @@ -1879,6 +1879,13 @@ void DX8TextureCategoryClass::Render(void) if (!DX8RendererDebugger::Is_Enabled() || !mesh->Is_Disabled_By_Debugger()) { if ((!!mesh->Peek_Model()->Get_Flag(MeshGeometryClass::SORT)) && WW3D::Is_Sorting_Enabled()) { + + if (std::strcmp(mesh->Get_Name(),"EXPRTBLSTBBBL.SPHERE01") == 0) { + DEBUG_LOG((">>>DX8Renderer: (render sorted?) mesh = '%s' - alpha = %f - isAdditive = %d", + mesh->Get_Name(), + mesh->Get_Alpha_Override(), mesh->Is_Additive())); + } + renderer->Render_Sorted(mesh->Get_Base_Vertex_Offset(),mesh->Get_Bounding_Sphere()); } else { //non-transparent mesh that will be rendered immediately. Okay to adjust the shader/material @@ -1887,10 +1894,18 @@ void DX8TextureCategoryClass::Render(void) { //mesh has material override of some kind //adjust the opacity of this model float oldOpacity=vmaterial->Get_Opacity(); + Vector3 oldDiffuse; + Vector3 oldEmissive; + + Vector2 oldUVOffset; unsigned int oldUVOffsetSyncTime; vmaterial->Get_Diffuse(&oldDiffuse); + + vmaterial->Get_Emissive(&oldEmissive); + + LinearOffsetTextureMapperClass *oldMapper=(LinearOffsetTextureMapperClass *)vmaterial->Peek_Mapper(); if ( mesh->Get_User_Data() && *(int *)mesh->Get_User_Data() == RenderObjClass::USER_DATA_MATERIAL_OVERRIDE && oldMapper && oldMapper->Mapper_ID() == TextureMapperClass::MAPPER_ID_LINEAR_OFFSET) { RenderObjClass::Material_Override *matOverride=(RenderObjClass::Material_Override *)mesh->Get_User_Data(); @@ -1903,10 +1918,18 @@ void DX8TextureCategoryClass::Render(void) oldMapper=NULL; if (mesh->Get_Alpha_Override() != 1.0) { + DEBUG_LOG((">>>DX8Renderer: ALPHA OVERRIDE - mesh = '%s' - alpha = %f - isAdditive = %d", + mesh->Get_Name(), + mesh->Get_Alpha_Override(), mesh->Is_Additive())); if (mesh->Is_Additive()) { //additvie blended mesh can't switch to alpha or we will get a black outline. //so adjust diffuse color instead. + DEBUG_LOG((">>>DX8Renderer: ADDITIVE + ALPHA OVERRIDE - alpha = %f", mesh->Get_Alpha_Override())); vmaterial->Set_Diffuse(mesh->Get_Alpha_Override(),mesh->Get_Alpha_Override(),mesh->Get_Alpha_Override()); + + //debug (this actually works) + vmaterial->Set_Emissive(mesh->Get_Emissive_Override(), mesh->Get_Emissive_Override(), mesh->Get_Emissive_Override()); + theAlphaShader = theShader; //keep using additive blending. } vmaterial->Set_Opacity(mesh->Get_Alpha_Override()); @@ -1917,6 +1940,9 @@ void DX8TextureCategoryClass::Render(void) DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHAREF,0x60); vmaterial->Set_Opacity(oldOpacity); //restore previous value vmaterial->Set_Diffuse(oldDiffuse.X,oldDiffuse.Y,oldDiffuse.Z); + + vmaterial->Set_Emissive(oldEmissive.X, oldEmissive.Y, oldEmissive.Z); + DX8Wrapper::Set_Shader(theShader); //restore previous value } else diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/mesh.cpp b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/mesh.cpp index 0243c55963..0648070c43 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/mesh.cpp +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/mesh.cpp @@ -673,9 +673,16 @@ void MeshClass::Render(RenderInfoClass & rinfo) Set_Lighting_Environment(rinfo.light_environment); //Add custom alpha m_alphaOverride = rinfo.alphaOverride; + m_emissiveOverride = rinfo.emissiveOverride; m_materialPassAlphaOverride = rinfo.materialPassAlphaOverride; m_materialPassEmissiveOverride = rinfo.materialPassEmissiveOverride; + /*if (m_alphaOverride != 1.0) { + DEBUG_LOG((">>>mesh.cpp - Render (static sort) - '%s' - m_alphaOverride = %f, m_materialPassAlphaOverride = %f, m_materialPassEmissiveOverride = %f", + Model->Get_Name(), + m_alphaOverride, m_materialPassAlphaOverride, m_materialPassEmissiveOverride)); + }*/ + WW3D::Add_To_Static_Sort_List(this, sort_level); } else { @@ -710,9 +717,17 @@ void MeshClass::Render(RenderInfoClass & rinfo) { Set_Lighting_Environment(rinfo.light_environment); //Add custom alpha + m_alphaOverride = rinfo.alphaOverride; + m_emissiveOverride = rinfo.emissiveOverride; m_materialPassAlphaOverride = rinfo.materialPassAlphaOverride; m_materialPassEmissiveOverride = rinfo.materialPassEmissiveOverride; + + //if (m_alphaOverride != 1.0) { + // DEBUG_LOG((">>>mesh.cpp - Render - '%s' - m_alphaOverride = %f, m_materialPassAlphaOverride = %f, m_materialPassEmissiveOverride = %f", + // Model->Get_Name(), + // m_alphaOverride, m_materialPassAlphaOverride, m_materialPassEmissiveOverride)); + //} } /* diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/mesh.h b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/mesh.h index cfdb6afa5b..9bb82441ba 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/mesh.h +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/mesh.h @@ -145,6 +145,7 @@ class MeshClass : public W3DMPO, public RenderObjClass void Set_Lighting_Environment(LightEnvironmentClass * light_env) { if (light_env) {m_localLightEnv=*light_env;LightEnvironment = &m_localLightEnv;} else {LightEnvironment = NULL;} } LightEnvironmentClass * Get_Lighting_Environment(void) { return LightEnvironment; } inline float Get_Alpha_Override(void) { return m_alphaOverride;} + inline float Get_Emissive_Override(void) { return m_emissiveOverride;} void Set_Next_Visible_Skin(MeshClass * next_visible) { NextVisibleSkin = next_visible; } MeshClass * Peek_Next_Visible_Skin(void) { return NextVisibleSkin; } @@ -181,6 +182,7 @@ class MeshClass : public W3DMPO, public RenderObjClass LightEnvironmentClass * LightEnvironment; // cached pointer to the light environment for this mesh LightEnvironmentClass m_localLightEnv; //added for 'Generals' float m_alphaOverride; //added for 'Generals' to allow variable alpha on meshes. + float m_emissiveOverride; //added by AW for variable additive scaling float m_materialPassEmissiveOverride; //added for 'Generals' to allow variable emissive on additional passes. float m_materialPassAlphaOverride; //added for 'Generals' to allow variable alpha on additional render passes. int BaseVertexOffset; // offset to our first vertex in whatever vb this mesh is in. diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/rinfo.h b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/rinfo.h index 653af89af4..77919d14a2 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/rinfo.h +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/rinfo.h @@ -103,6 +103,7 @@ class RenderInfoClass float fog_start; float fog_end; float alphaOverride; //added for 'Generals' to allow variable alpha -MW + float emissiveOverride; //added by AW for variable additive scaling float materialPassAlphaOverride; ////added for 'Generals' to allow variable alpha on additional render passes.-MW float materialPassEmissiveOverride; ////added for 'Generals' to allow variable emissive on additional render passes.-MW From 897a73829e23fe4f63dc68c800a977e4474ddec0 Mon Sep 17 00:00:00 2001 From: andreasw Date: Wed, 20 Aug 2025 15:53:30 +0200 Subject: [PATCH 2/2] remove log output --- .../Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp index 99102f39fe..af7ed35a27 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp @@ -1879,13 +1879,6 @@ void DX8TextureCategoryClass::Render(void) if (!DX8RendererDebugger::Is_Enabled() || !mesh->Is_Disabled_By_Debugger()) { if ((!!mesh->Peek_Model()->Get_Flag(MeshGeometryClass::SORT)) && WW3D::Is_Sorting_Enabled()) { - - if (std::strcmp(mesh->Get_Name(),"EXPRTBLSTBBBL.SPHERE01") == 0) { - DEBUG_LOG((">>>DX8Renderer: (render sorted?) mesh = '%s' - alpha = %f - isAdditive = %d", - mesh->Get_Name(), - mesh->Get_Alpha_Override(), mesh->Is_Additive())); - } - renderer->Render_Sorted(mesh->Get_Base_Vertex_Offset(),mesh->Get_Bounding_Sphere()); } else { //non-transparent mesh that will be rendered immediately. Okay to adjust the shader/material @@ -1918,16 +1911,12 @@ void DX8TextureCategoryClass::Render(void) oldMapper=NULL; if (mesh->Get_Alpha_Override() != 1.0) { - DEBUG_LOG((">>>DX8Renderer: ALPHA OVERRIDE - mesh = '%s' - alpha = %f - isAdditive = %d", - mesh->Get_Name(), - mesh->Get_Alpha_Override(), mesh->Is_Additive())); if (mesh->Is_Additive()) { //additvie blended mesh can't switch to alpha or we will get a black outline. //so adjust diffuse color instead. - DEBUG_LOG((">>>DX8Renderer: ADDITIVE + ALPHA OVERRIDE - alpha = %f", mesh->Get_Alpha_Override())); + //DEBUG_LOG((">>>DX8Renderer: ADDITIVE + ALPHA OVERRIDE - alpha = %f", mesh->Get_Alpha_Override())); vmaterial->Set_Diffuse(mesh->Get_Alpha_Override(),mesh->Get_Alpha_Override(),mesh->Get_Alpha_Override()); - //debug (this actually works) vmaterial->Set_Emissive(mesh->Get_Emissive_Override(), mesh->Get_Emissive_Override(), mesh->Get_Emissive_Override()); theAlphaShader = theShader; //keep using additive blending.