From 2a54e1dedeb1fc5629e67191aac552d7316863db Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sat, 18 Oct 2025 14:21:05 +0200 Subject: [PATCH 1/2] bugfix(scene): Fix translucent objects drawn without translucency when no occluders are in the scene (#1710) --- .../Source/W3DDevice/GameClient/W3DScene.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DScene.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DScene.cpp index c0733c4061..b31d0d6a8e 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DScene.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DScene.cpp @@ -1411,6 +1411,7 @@ void RTS3DScene::flushOccludedObjectsIntoStencil(RenderInfoClass & rinfo) DrawableInfo *drawInfo=((DrawableInfo *)(*renderList)->Get_User_Data()); if (drawInfo->m_flags & DrawableInfo::ERF_IS_TRANSLUCENT) { + // TheSuperHackers @info This only draws the occlusion of translucent objects. TheDX8MeshRenderer.Flush(); //render all the submitted meshes using current stencil function SHD_FLUSH; //Disable writing to color buffer since translucent objects are rendered at end of frame. @@ -1497,7 +1498,13 @@ void RTS3DScene::flushOccludedObjectsIntoStencil(RenderInfoClass & rinfo) Int k=0; for (; k((*occludeeList)->Get_User_Data()); + if ((drawInfo->m_flags & DrawableInfo::ERF_IS_TRANSLUCENT) == 0) + { + renderOneObject(rinfo, (*occludeeList), localPlayerIndex); + } occludeeList++; //advance to next one } From 34acc85753a5c4d150a7edb55618f302379c5b8c Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sat, 18 Oct 2025 14:43:49 +0200 Subject: [PATCH 2/2] refactor(scene): Clean formatting, comments in W3DScene (#1710) --- .../Include/W3DDevice/GameClient/W3DScene.h | 27 +-- .../Source/W3DDevice/GameClient/W3DScene.cpp | 193 +++++++++-------- .../Include/W3DDevice/GameClient/W3DScene.h | 27 +-- .../Source/W3DDevice/GameClient/W3DScene.cpp | 205 ++++++++++-------- 4 files changed, 241 insertions(+), 211 deletions(-) diff --git a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DScene.h b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DScene.h index 0b623a35de..0aa3b58eee 100644 --- a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DScene.h +++ b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DScene.h @@ -43,6 +43,7 @@ #include "WW3D2/rinfo.h" #include "WW3D2/coltest.h" #include "WW3D2/lightenvironment.h" + /////////////////////////////////////////////////////////////////////////////// // PROTOTYPES ///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// @@ -64,7 +65,7 @@ class RTS3DScene : public SimpleSceneClass, public SubsystemInterface public: RTS3DScene(); ///< RTSScene constructor - ~RTS3DScene(); ///< RTSScene desctructor + ~RTS3DScene(); ///< RTSScene destructor /// ray picking against objects in scene Bool castRay(RayCollisionTestClass & raytest, Bool testAll, Int collisionType); @@ -85,13 +86,13 @@ class RTS3DScene : public SimpleSceneClass, public SubsystemInterface void renderSpecificDrawables(RenderInfoClass &rinfo, Int numDrawables, Drawable **theDrawables) ; /// Lighting methods - void addDynamicLight(W3DDynamicLight * obj); - void removeDynamicLight(W3DDynamicLight * obj); - RefRenderObjListIterator * createLightsIterator(void); - void destroyLightsIterator(RefRenderObjListIterator * it); - RefRenderObjListClass *getDynamicLights(void) {return &m_dynamicLightList;}; + void addDynamicLight(W3DDynamicLight * obj); + void removeDynamicLight(W3DDynamicLight * obj); + RefRenderObjListIterator *createLightsIterator(void); + void destroyLightsIterator(RefRenderObjListIterator * it); + RefRenderObjListClass *getDynamicLights(void) {return &m_dynamicLightList;}; W3DDynamicLight *getADynamicLight(void); - void setGlobalLight(LightClass *pLight,Int lightIndex=0); + void setGlobalLight(LightClass *pLight,Int lightIndex=0); LightEnvironmentClass &getDefaultLightEnv(void) {return m_defaultLightEnv;} void init() {} @@ -101,8 +102,8 @@ class RTS3DScene : public SimpleSceneClass, public SubsystemInterface void doRender(CameraClass * cam); protected: - void renderOneObject(RenderInfoClass &rinfo, RenderObjClass *robj, Int localPlayerIndex); - void updateFixedLightEnvironments(RenderInfoClass & rinfo); + void renderOneObject(RenderInfoClass &rinfo, RenderObjClass *robj, Int localPlayerIndex); + void updateFixedLightEnvironments(RenderInfoClass & rinfo); void flushTranslucentObjects(RenderInfoClass & rinfo); void flushOccludedObjects(RenderInfoClass & rinfo); void flagOccludedObjects(CameraClass * camera); @@ -147,7 +148,6 @@ class RTS3DScene : public SimpleSceneClass, public SubsystemInterface //----------------------------------------------------------------------------- class RTS2DScene : public SimpleSceneClass, public SubsystemInterface { - public: RTS2DScene(); @@ -162,9 +162,9 @@ class RTS2DScene : public SimpleSceneClass, public SubsystemInterface void doRender(CameraClass * cam); protected: + RenderObjClass *m_status; CameraClass *m_camera; - }; //----------------------------------------------------------------------------- @@ -173,9 +173,7 @@ class RTS2DScene : public SimpleSceneClass, public SubsystemInterface /** Scene management for 3D interface overlay on top of 3D scene */ //----------------------------------------------------------------------------- class RTS3DInterfaceScene : public SimpleSceneClass - { - public: RTS3DInterfaceScene(); @@ -183,9 +181,6 @@ class RTS3DInterfaceScene : public SimpleSceneClass /// customizable renderer for the RTS3DInterfaceScene virtual void Customized_Render( RenderInfoClass &rinfo ); - -protected: - }; #endif // end __W3DSCENE_H_ diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DScene.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DScene.cpp index f0bf636f65..2b60391f2c 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DScene.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DScene.cpp @@ -94,7 +94,8 @@ RTS3DScene::RTS3DScene() m_numGlobalLights=0; Int i=0; for (; iSet_Material(heatVisionMtl); m_heatVisionOnlyPass->Set_Shader(heatVisionShader); - //Allocate memory to hold queue of visible renderobjects that need to be drawn last + //Allocate memory to hold queue of visible render objects that need to be drawn last //because they are forced translucent. m_translucentObjectsCount = 0; if (TheGlobalData->m_maxVisibleTranslucentObjects > 0) @@ -165,7 +166,8 @@ RTS3DScene::RTS3DScene() #ifdef USE_NON_STENCIL_OCCLUSION for (i=0; iSet_Lighting(true); vmtl->Set_Ambient(0,0,0); //we're only using emissive so kill all other lights. @@ -211,9 +213,9 @@ RTS3DScene::~RTS3DScene() delete [] m_potentialOccluders; for (i=0; iGet_User_Data(); drawInfo->m_flags |= DrawableInfo::ERF_IS_OCCLUDED; m_potentialOccludees[m_occludedObjectsCount++] = *occludee; @@ -393,9 +397,9 @@ void RTS3DScene::Visibility_Check(CameraClass * camera) if (currentFrame <= TheGlobalData->m_defaultOcclusionDelay) currentFrame = TheGlobalData->m_defaultOcclusionDelay+1; //make sure occlusion is enabled when game starts (frame 0). - if (ShaderClass::Is_Backface_Culling_Inverted()) - { //we are rendering reflections + { + //we are rendering reflections ///@todo: Have better flag to detect reflection pass // Loop over all top-level RenderObjects in this scene. If the bounding sphere is not in front @@ -418,7 +422,8 @@ void RTS3DScene::Visibility_Check(CameraClass * camera) } } else - { //perform normal culling on non-drawables + { + //perform normal culling on non-drawables if (robj->Is_Force_Visible()) { robj->Set_Visible(true); } else { @@ -445,7 +450,8 @@ void RTS3DScene::Visibility_Check(CameraClass * camera) bool isVisible=!camera->Cull_Sphere(robj->Get_Bounding_Sphere()); if (isVisible) - { //need to keep track of occluders and ocludees for subsequent code. + { + //need to keep track of occluders and occludees for subsequent code. drawInfo = (DrawableInfo *)robj->Get_User_Data(); if (drawInfo && (draw=drawInfo->m_drawable) != NULL) { @@ -457,29 +463,30 @@ void RTS3DScene::Visibility_Check(CameraClass * camera) drawInfo->m_flags = DrawableInfo::ERF_IS_NORMAL; //clear any rendering flags that may be in effect. if (draw->getEffectiveOpacity() != 1.0f && m_translucentObjectsCount < TheGlobalData->m_maxVisibleTranslucentObjects) - { drawInfo->m_flags = DrawableInfo::ERF_IS_TRANSLUCENT; //object is translucent + { + drawInfo->m_flags = DrawableInfo::ERF_IS_TRANSLUCENT; m_translucentObjectsBuffer[m_translucentObjectsCount++] = robj; } - else - if (TheGlobalData->m_enableBehindBuildingMarkers && TheGameLogic && TheGameLogic->getShowBehindBuildingMarkers()) + else if (TheGlobalData->m_enableBehindBuildingMarkers && TheGameLogic && TheGameLogic->getShowBehindBuildingMarkers()) { //visible drawable. Check if it's either an occluder or occludee if (draw->isKindOf(KINDOF_STRUCTURE) && m_numPotentialOccluders < TheGlobalData->m_maxVisibleOccluderObjects) - { //object which could occlude other objects that need to be visible. + { + //object which could occlude other objects that need to be visible. m_potentialOccluders[m_numPotentialOccluders++]=robj; drawInfo->m_flags |= DrawableInfo::ERF_POTENTIAL_OCCLUDER; } - else - if (draw->getObject() && + else if (draw->getObject() && (draw->isKindOf(KINDOF_SCORE) || draw->isKindOf(KINDOF_SCORE_CREATE) || draw->isKindOf(KINDOF_SCORE_DESTROY) || draw->isKindOf(KINDOF_MP_COUNT_FOR_VICTORY)) && (draw->getObject()->getSafeOcclusionFrame()) <= currentFrame && m_numPotentialOccludees < TheGlobalData->m_maxVisibleOccludeeObjects) - { //object which could be occluded but still needs to be visible. + { + //object which could be occluded but still needs to be visible. m_potentialOccludees[m_numPotentialOccludees++]=robj; drawInfo->m_flags |= DrawableInfo::ERF_POTENTIAL_OCCLUDEE; } - else - if (drawInfo->m_flags == DrawableInfo::ERF_IS_NORMAL && m_numNonOccluderOrOccludee < TheGlobalData->m_maxVisibleNonOccluderOrOccludeeObjects) - { //regular object with no custom effects but still needs to be delayed to get the occlusion feature to work correctly. + else if (drawInfo->m_flags == DrawableInfo::ERF_IS_NORMAL && m_numNonOccluderOrOccludee < TheGlobalData->m_maxVisibleNonOccluderOrOccludeeObjects) + { + //regular object with no custom effects but still needs to be delayed to get the occlusion feature to work correctly. m_nonOccludersOrOccludees[m_numNonOccluderOrOccludee++]=robj; drawInfo->m_flags |= DrawableInfo::ERF_IS_NON_OCCLUDER_OR_OCCLUDEE; } @@ -549,7 +556,6 @@ void RTS3DScene::renderSpecificDrawables(RenderInfoClass &rinfo, Int numDrawable //============================================================================= void RTS3DScene::renderOneObject(RenderInfoClass &rinfo, RenderObjClass *robj, Int localPlayerIndex) { - Drawable *draw = NULL; DrawableInfo *drawInfo = NULL; Bool drawableHidden=FALSE; @@ -560,7 +566,8 @@ void RTS3DScene::renderOneObject(RenderInfoClass &rinfo, RenderObjClass *robj, I LightClass **sceneLights=m_globalLight; if (robj->Class_ID() == RenderObjClass::CLASSID_IMAGE3D ) - { robj->Render(rinfo); //notify decals system that this track is visible + { + robj->Render(rinfo); //notify decals system that this track is visible return; //decals are not lit by this system yet so skip rest of lighting } @@ -568,7 +575,8 @@ void RTS3DScene::renderOneObject(RenderInfoClass &rinfo, RenderObjClass *robj, I SphereClass sph = robj->Get_Bounding_Sphere(); drawInfo = (DrawableInfo *)robj->Get_User_Data(); if (drawInfo) - { draw = drawInfo->m_drawable; + { + draw = drawInfo->m_drawable; //If we have a drawInfo but not drawable, we must be dealing with //a ghost object which is always fogged. if (!draw) @@ -609,19 +617,22 @@ void RTS3DScene::renderOneObject(RenderInfoClass &rinfo, RenderObjClass *robj, I return; //this object was removed by the getShroudedStatus() call. } else - { //drawable with no object so no way to know if it's shrouded. + { + //drawable with no object so no way to know if it's shrouded. ss = OBJECTSHROUD_CLEAR; //assume not shrouded/fogged. //Check to see if there is another unrelated object which controls the shroud status //(Hack for prison camps which contain enemy prisoner drawables) if (drawInfo->m_shroudStatusObjectID != INVALID_ID) - { Object *shroudObject=TheGameLogic->findObjectByID(drawInfo->m_shroudStatusObjectID); + { + Object *shroudObject=TheGameLogic->findObjectByID(drawInfo->m_shroudStatusObjectID); if (shroudObject && shroudObject->getShroudedStatus(localPlayerIndex) >= OBJECTSHROUD_FOGGED) ss = OBJECTSHROUD_SHROUDED; //we will assume that drawables without objects are 'particle' like and therefore don't need drawing if fogged/shrouded. } } if (draw->isKindOf(KINDOF_INFANTRY)) - { ambient = m_infantryAmbient; + { + ambient = m_infantryAmbient; sceneLights = m_infantryLight; } @@ -694,13 +705,15 @@ void RTS3DScene::renderOneObject(RenderInfoClass &rinfo, RenderObjClass *robj, I } } else - { //either no drawable or it is hidden + { + //either no drawable or it is hidden if (drawableHidden) return; //don't bother with anything else //Render object without a drawable. Must be either some fluff/debug object or a ghostObject. if (ss == OBJECTSHROUD_FOGGED) - { //Must be ghost object because we don't fog normal things. Fogged objects always have a predefined + { + //Must be ghost object because we don't fog normal things. Fogged objects always have a predefined //lighting environment applied which emulates the look of fog. rinfo.light_environment = &m_foggedLightEnv; robj->Render(rinfo); @@ -708,7 +721,8 @@ void RTS3DScene::renderOneObject(RenderInfoClass &rinfo, RenderObjClass *robj, I return; } else - { lightEnv.Reset(sph.Center, ambient); + { + lightEnv.Reset(sph.Center, ambient); for (Int globalLightIndex = 0; globalLightIndex < m_numGlobalLights; globalLightIndex++) lightEnv.Add_Light(*m_globalLight[globalLightIndex]); } @@ -756,17 +770,19 @@ void RTS3DScene::renderOneObject(RenderInfoClass &rinfo, RenderObjClass *robj, I if (m_customPassMode == SCENE_PASS_DEFAULT) { if (ss <= OBJECTSHROUD_CLEAR) + { robj->Render(rinfo); + } else { - rinfo.Push_Material_Pass(m_shroudMaterialPass); - robj->Render(rinfo); - rinfo.Pop_Material_Pass(); + rinfo.Push_Material_Pass(m_shroudMaterialPass); + robj->Render(rinfo); + rinfo.Pop_Material_Pass(); } } - else - if (m_maskMaterialPass) - { rinfo.Push_Material_Pass(m_maskMaterialPass); + else if (m_maskMaterialPass) + { + rinfo.Push_Material_Pass(m_maskMaterialPass); rinfo.Push_Override_Flags(RenderInfoClass::RINFO_OVERRIDE_ADDITIONAL_PASSES_ONLY); robj->Render(rinfo); rinfo.Pop_Override_Flags(); @@ -798,6 +814,7 @@ void RTS3DScene::Flush(RenderInfoClass & rinfo) //don't draw shadows in this mode because they interfere with destination alpha or are invisible (wireframe) if (m_customPassMode == SCENE_PASS_DEFAULT && Get_Extra_Pass_Polygon_Mode() == EXTRA_PASS_DISABLE) DoShadows(rinfo, false); //draw all non-stencil shadows (decals) since they fall under other objects. + TheDX8MeshRenderer.Flush(); //draw all non-translucent objects. //draw all non-translucent objects which were separated because they are hidden and need custom rendering. @@ -813,10 +830,11 @@ void RTS3DScene::Flush(RenderInfoClass & rinfo) //don't draw shadows in this mode because they interfere with destination alpha if (m_customPassMode == SCENE_PASS_DEFAULT && Get_Extra_Pass_Polygon_Mode() == EXTRA_PASS_DISABLE) DoShadows(rinfo, true); //draw all stencil shadows + WW3D::Render_And_Clear_Static_Sort_Lists(rinfo); //draws things like water if (m_customPassMode == SCENE_PASS_DEFAULT && Get_Extra_Pass_Polygon_Mode() == EXTRA_PASS_DISABLE) - flushTranslucentObjects(rinfo); //draw all translucent meshes which don't need per-poly sorting. + flushTranslucentObjects(rinfo); //draw all translucent meshes which don't need per-polygon sorting. { //USE_PERF_TIMER(translucentRender) @@ -825,13 +843,13 @@ void RTS3DScene::Flush(RenderInfoClass & rinfo) if (m_customPassMode == SCENE_PASS_DEFAULT && Get_Extra_Pass_Polygon_Mode() == EXTRA_PASS_DISABLE) DoParticles(rinfo); //queue up particles for rendering. - SortingRendererClass::Flush(); //draw sorted translucent polys like particles. + SortingRendererClass::Flush(); //draw sorted translucent polygons like particles. } TheDX8MeshRenderer.Clear_Pending_Delete_Lists(); } /**Generate a predefined light environment(s) that will be applied to many objects. Useful for things like totally fogged -objects and most generaic map objects that are not lit by dynamic lights.*/ +objects and most generic map objects that are not lit by dynamic lights.*/ void RTS3DScene::updateFixedLightEnvironments(RenderInfoClass & rinfo) { //Figure out how dimly lit fogged objects should be compared to fully lit. @@ -848,7 +866,8 @@ void RTS3DScene::updateFixedLightEnvironments(RenderInfoClass & rinfo) m_foggedLightEnv.Reset(Vector3(0,0,0), Get_Ambient_Light()*foggedLightFrac); for (Int globalLightIndex = 0; globalLightIndex < m_numGlobalLights; globalLightIndex++) - { m_defaultLightEnv.Add_Light(*m_globalLight[globalLightIndex]); + { + m_defaultLightEnv.Add_Light(*m_globalLight[globalLightIndex]); //copy default lighting for infantry so we can tweak it. *m_infantryLight[globalLightIndex]=*m_globalLight[globalLightIndex]; m_globalLight[globalLightIndex]->Get_Diffuse(&oldDiffuse); @@ -913,14 +932,14 @@ void RTS3DScene::Render(RenderInfoClass & rinfo) if (Get_Extra_Pass_Polygon_Mode() == EXTRA_PASS_DISABLE) { if (m_customPassMode == SCENE_PASS_DEFAULT) - { //Regular rendering pass with no effects + { + //Regular rendering pass with no effects updatePlayerColorPasses();///@todo: this probably doesn't need to be done each frame. updateFixedLightEnvironments(rinfo); Customized_Render(rinfo); Flush(rinfo); } - else - if (m_customPassMode == SCENE_PASS_ALPHA_MASK) + else if (m_customPassMode == SCENE_PASS_ALPHA_MASK) { //a projected alpha texture which will later be used to determine where //wireframe should be visible. @@ -944,7 +963,8 @@ void RTS3DScene::Render(RenderInfoClass & rinfo) { Bool old_enable=WW3D::Is_Texturing_Enabled(); if (Get_Extra_Pass_Polygon_Mode() == EXTRA_PASS_CLEAR_LINE) - { //render scene with solid black color but have destination alpha store + { + //render scene with solid black color but have destination alpha store //a projected alpha texture which will later be used to determine where //wireframe should be visible. ///@todo: Clearing to black may not be needed if the scene already did the clear. @@ -989,7 +1009,8 @@ void RTS3DScene::Render(RenderInfoClass & rinfo) ShaderClass::Invalidate(); } else - { //old W3D custom rendering code. + { + //old W3D custom rendering code. //Disable writes to color buffer to save memory bandwidth - we only need Z. DX8Wrapper::Set_DX8_Render_State(D3DRS_COLORWRITEENABLE,0); @@ -1081,8 +1102,7 @@ void RTS3DScene::Customized_Render( RenderInfoClass &rinfo ) robj->Render(rinfo); rinfo.Pop_Material_Pass(); } - else - if (m_customPassMode == SCENE_PASS_ALPHA_MASK && m_maskMaterialPass) + else if (m_customPassMode == SCENE_PASS_ALPHA_MASK && m_maskMaterialPass) { rinfo.Push_Material_Pass(m_maskMaterialPass); robj->Render(rinfo); @@ -1104,7 +1124,6 @@ void RTS3DScene::Customized_Render( RenderInfoClass &rinfo ) // loop through all render objects in the list: for (it.First(&RenderList); !it.Is_Done();) { - // get the render object robj = it.Peek_Obj(); it.Next(); //advance to next object in case this one gets deleted during renderOneObject(). @@ -1130,14 +1149,16 @@ void RTS3DScene::Customized_Render( RenderInfoClass &rinfo ) //Don't draw shadows if there is no terrain present. if (TheW3DShadowManager && terrainObject && !ShaderClass::Is_Backface_Culling_Inverted() && Get_Extra_Pass_Polygon_Mode() == EXTRA_PASS_DISABLE) + { TheW3DShadowManager->queueShadows(TRUE); + } // only render particles once per frame if (terrainObject != NULL && TheParticleSystemManager != NULL && Get_Extra_Pass_Polygon_Mode() == EXTRA_PASS_DISABLE) - { TheParticleSystemManager->queueParticleRender(); + { + TheParticleSystemManager->queueParticleRender(); } - } /**Convert a player index to a color index, we use this because color indices are @@ -1157,11 +1178,13 @@ Int playerIndexToColorIndex(Int playerIndex) flippedPosition = NUMBER_PLAYER_COLOR_BITS-1-i; //correct position of bit after it's flipped left/right if (flippedPosition > i) - { //shifting left + { + //shifting left result |= (tmp & (1<>(i-flippedPosition); } } @@ -1196,7 +1219,7 @@ void renderStenciledPlayerColor( UnsignedInt color, UnsignedInt stencilRef, Bool VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE); DX8Wrapper::Set_Material(vmat); REF_PTR_RELEASE(vmat); - DX8Wrapper::Apply_Render_State_Changes(); //force update all renderstates + DX8Wrapper::Apply_Render_State_Changes(); //force update all render states LPDIRECT3DDEVICE8 m_pDev=DX8Wrapper::_Get_D3D_Device8(); @@ -1212,7 +1235,8 @@ void renderStenciledPlayerColor( UnsignedInt color, UnsignedInt stencilRef, Bool DX8Wrapper::Set_DX8_Render_State(D3DRS_ZENABLE, TRUE ); DWORD oldColorWriteEnable=0x12345678; if (clear) - { //we want to clear the stencil buffer to some known value whereever a player index is stored + { + //we want to clear the stencil buffer to some known value whereever a player index is stored Int occludedMask=TheW3DShadowManager->getStencilShadowMask(); DX8Wrapper::Set_DX8_Render_State(D3DRS_STENCILREF, 0x80808080 ); DX8Wrapper::Set_DX8_Render_State(D3DRS_STENCILMASK, occludedMask ); //isolate bits containing occluder|playerIndex @@ -1225,18 +1249,21 @@ void renderStenciledPlayerColor( UnsignedInt color, UnsignedInt stencilRef, Bool //disable writes to color buffer if (DX8Wrapper::Get_Current_Caps()->Get_DX8_Caps().PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) - { DX8Wrapper::_Get_D3D_Device8()->GetRenderState(D3DRS_COLORWRITEENABLE, &oldColorWriteEnable); + { + DX8Wrapper::_Get_D3D_Device8()->GetRenderState(D3DRS_COLORWRITEENABLE, &oldColorWriteEnable); DX8Wrapper::Set_DX8_Render_State(D3DRS_COLORWRITEENABLE,0); } else - { //device does not support disabling writes to color buffer so fake it through alpha blending + { + //device does not support disabling writes to color buffer so fake it through alpha blending DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE, TRUE); DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND, D3DBLEND_ZERO ); DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND, D3DBLEND_ONE ); } } else - { DX8Wrapper::Set_DX8_Render_State(D3DRS_STENCILREF, stencilRef ); + { + DX8Wrapper::Set_DX8_Render_State(D3DRS_STENCILREF, stencilRef ); DX8Wrapper::Set_DX8_Render_State(D3DRS_STENCILMASK, 0xffffffff ); DX8Wrapper::Set_DX8_Render_State(D3DRS_STENCILWRITEMASK,0xffffffff ); DX8Wrapper::Set_DX8_Render_State(D3DRS_STENCILFUNC, D3DCMP_EQUAL ); @@ -1285,7 +1312,8 @@ void RTS3DScene::flushOccludedObjectsIntoStencil(RenderInfoClass & rinfo) //state changes needed when drawing them. Int i=0; for (; isetStencilShadowMask(usedPlayerColorBits); if (numVisiblePlayerColors >= 8 && TheGlobalData->m_useShadowVolumes) - { //for cases where we have 8 or more visible players, we're only left with 3 bits to store + { + //for cases where we have 8 or more visible players, we're only left with 3 bits to store //stencil shadows. That's probably not enough since it will only allow 7 overlapping shadows. //So we clear the stencil buffer, leaving only the MSB set on any occluded player pixels so that //shadow code knows not to overwrite these pixels. @@ -1428,7 +1458,8 @@ void RTS3DScene::flushOccludedObjectsIntoStencil(RenderInfoClass & rinfo) } else if (m_numNonOccluderOrOccludee || m_numPotentialOccluders || m_numPotentialOccludees) - { //no occluded objects so don't need to render anything special. Just draw the queued up + { + //no occluded objects so don't need to render anything special. Just draw the queued up //objects like normal because they were skipped in the main scene traversal. RenderObjClass **occludeeList=m_potentialOccludees; @@ -1606,21 +1637,21 @@ void RTS3DScene::addDynamicLight(W3DDynamicLight * obj) //============================================================================= W3DDynamicLight * RTS3DScene::getADynamicLight(void) { - RefRenderObjListIterator dynaLightIt(&m_dynamicLightList); - W3DDynamicLight *pLight; - for (dynaLightIt.First(); !dynaLightIt.Is_Done(); dynaLightIt.Next()) - { - pLight = (W3DDynamicLight*)dynaLightIt.Peek_Obj(); - if (!pLight->isEnabled()) { - pLight->setEnabled(true); - return(pLight); - } + RefRenderObjListIterator dynaLightIt(&m_dynamicLightList); + W3DDynamicLight *pLight; + for (dynaLightIt.First(); !dynaLightIt.Is_Done(); dynaLightIt.Next()) + { + pLight = (W3DDynamicLight*)dynaLightIt.Peek_Obj(); + if (!pLight->isEnabled()) { + pLight->setEnabled(true); + return(pLight); } - pLight = NEW_REF(W3DDynamicLight, ()); - addDynamicLight( pLight ); - pLight->Release_Ref(); - pLight->setEnabled(true); - return(pLight); + } + pLight = NEW_REF(W3DDynamicLight, ()); + addDynamicLight( pLight ); + pLight->Release_Ref(); + pLight->setEnabled(true); + return(pLight); } //============================================================================= @@ -1653,14 +1684,11 @@ void RTS3DScene::doRender( CameraClass * cam ) //============================================================================= void RTS3DScene::draw( ) { - if (m_camera == NULL) { DEBUG_CRASH(("Null m_camera in RTS3DScene::draw")); return; } WW3D::Render( this, m_camera ); - - } @@ -1698,10 +1726,8 @@ RTS2DScene::~RTS2DScene() //============================================================================= void RTS2DScene::Customized_Render( RenderInfoClass &rinfo ) { - // call simple scene class renderer SimpleSceneClass::Customized_Render( rinfo ); - } //============================================================================= @@ -1711,11 +1737,9 @@ void RTS2DScene::Customized_Render( RenderInfoClass &rinfo ) //============================================================================= void RTS2DScene::doRender( CameraClass * cam ) { - m_camera = cam; DRAW(); m_camera = NULL; - } //============================================================================= @@ -1725,14 +1749,11 @@ void RTS2DScene::doRender( CameraClass * cam ) //============================================================================= void RTS2DScene::draw( ) { - if (m_camera == NULL) { DEBUG_CRASH(("Null m_camera in RTS2DScene::draw")); return; } WW3D::Render( this, m_camera ); - - } @@ -1766,10 +1787,8 @@ RTS3DInterfaceScene::~RTS3DInterfaceScene() //============================================================================= void RTS3DInterfaceScene::Customized_Render( RenderInfoClass &rinfo ) { - // call simple scene class renderer SimpleSceneClass::Customized_Render( rinfo ); - } diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DScene.h b/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DScene.h index 4ec5fd3bf2..466d0fb8bf 100644 --- a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DScene.h +++ b/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DScene.h @@ -43,6 +43,7 @@ #include "WW3D2/rinfo.h" #include "WW3D2/coltest.h" #include "WW3D2/lightenvironment.h" + /////////////////////////////////////////////////////////////////////////////// // PROTOTYPES ///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// @@ -64,7 +65,7 @@ class RTS3DScene : public SimpleSceneClass, public SubsystemInterface public: RTS3DScene(); ///< RTSScene constructor - ~RTS3DScene(); ///< RTSScene desctructor + ~RTS3DScene(); ///< RTSScene destructor /// ray picking against objects in scene Bool castRay(RayCollisionTestClass & raytest, Bool testAll, Int collisionType); @@ -85,13 +86,13 @@ class RTS3DScene : public SimpleSceneClass, public SubsystemInterface void renderSpecificDrawables(RenderInfoClass &rinfo, Int numDrawables, Drawable **theDrawables) ; /// Lighting methods - void addDynamicLight(W3DDynamicLight * obj); - void removeDynamicLight(W3DDynamicLight * obj); - RefRenderObjListIterator * createLightsIterator(void); - void destroyLightsIterator(RefRenderObjListIterator * it); - RefRenderObjListClass *getDynamicLights(void) {return &m_dynamicLightList;}; + void addDynamicLight(W3DDynamicLight * obj); + void removeDynamicLight(W3DDynamicLight * obj); + RefRenderObjListIterator *createLightsIterator(void); + void destroyLightsIterator(RefRenderObjListIterator * it); + RefRenderObjListClass *getDynamicLights(void) {return &m_dynamicLightList;}; W3DDynamicLight *getADynamicLight(void); - void setGlobalLight(LightClass *pLight,Int lightIndex=0); + void setGlobalLight(LightClass *pLight,Int lightIndex=0); LightEnvironmentClass &getDefaultLightEnv(void) {return m_defaultLightEnv;} void init() {} @@ -101,8 +102,8 @@ class RTS3DScene : public SimpleSceneClass, public SubsystemInterface void doRender(CameraClass * cam); protected: - void renderOneObject(RenderInfoClass &rinfo, RenderObjClass *robj, Int localPlayerIndex); - void updateFixedLightEnvironments(RenderInfoClass & rinfo); + void renderOneObject(RenderInfoClass &rinfo, RenderObjClass *robj, Int localPlayerIndex); + void updateFixedLightEnvironments(RenderInfoClass & rinfo); void flushTranslucentObjects(RenderInfoClass & rinfo); void flushOccludedObjects(RenderInfoClass & rinfo); void flagOccludedObjects(CameraClass * camera); @@ -148,7 +149,6 @@ class RTS3DScene : public SimpleSceneClass, public SubsystemInterface //----------------------------------------------------------------------------- class RTS2DScene : public SimpleSceneClass, public SubsystemInterface { - public: RTS2DScene(); @@ -163,9 +163,9 @@ class RTS2DScene : public SimpleSceneClass, public SubsystemInterface void doRender(CameraClass * cam); protected: + RenderObjClass *m_status; CameraClass *m_camera; - }; //----------------------------------------------------------------------------- @@ -174,9 +174,7 @@ class RTS2DScene : public SimpleSceneClass, public SubsystemInterface /** Scene management for 3D interface overlay on top of 3D scene */ //----------------------------------------------------------------------------- class RTS3DInterfaceScene : public SimpleSceneClass - { - public: RTS3DInterfaceScene(); @@ -184,9 +182,6 @@ class RTS3DInterfaceScene : public SimpleSceneClass /// customizable renderer for the RTS3DInterfaceScene virtual void Customized_Render( RenderInfoClass &rinfo ); - -protected: - }; #endif // end __W3DSCENE_H_ diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DScene.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DScene.cpp index b31d0d6a8e..66a19d43b9 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DScene.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DScene.cpp @@ -95,7 +95,8 @@ RTS3DScene::RTS3DScene() m_numGlobalLights=0; Int i=0; for (; iSet_Shader(frenzyShader); - //Allocate memory to hold queue of visible renderobjects that need to be drawn last + //Allocate memory to hold queue of visible render objects that need to be drawn last //because they are forced translucent. m_translucentObjectsCount = 0; if (TheGlobalData->m_maxVisibleTranslucentObjects > 0) @@ -181,7 +182,8 @@ RTS3DScene::RTS3DScene() #ifdef USE_NON_STENCIL_OCCLUSION for (i=0; iSet_Lighting(true); vmtl->Set_Ambient(0,0,0); //we're only using emissive so kill all other lights. @@ -227,9 +229,9 @@ RTS3DScene::~RTS3DScene() delete [] m_potentialOccluders; for (i=0; iGet_User_Data(); drawInfo->m_flags |= DrawableInfo::ERF_IS_OCCLUDED; m_potentialOccludees[m_occludedObjectsCount++] = *occludee; @@ -409,9 +413,9 @@ void RTS3DScene::Visibility_Check(CameraClass * camera) if (currentFrame <= TheGlobalData->m_defaultOcclusionDelay) currentFrame = TheGlobalData->m_defaultOcclusionDelay+1; //make sure occlusion is enabled when game starts (frame 0). - if (ShaderClass::Is_Backface_Culling_Inverted()) - { //we are rendering reflections + { + //we are rendering reflections ///@todo: Have better flag to detect reflection pass // Loop over all top-level RenderObjects in this scene. If the bounding sphere is not in front @@ -434,7 +438,8 @@ void RTS3DScene::Visibility_Check(CameraClass * camera) } } else - { //perform normal culling on non-drawables + { + //perform normal culling on non-drawables if (robj->Is_Force_Visible()) { robj->Set_Visible(true); } else { @@ -461,7 +466,8 @@ void RTS3DScene::Visibility_Check(CameraClass * camera) bool isVisible=!camera->Cull_Sphere(robj->Get_Bounding_Sphere()); if (isVisible) - { //need to keep track of occluders and ocludees for subsequent code. + { + //need to keep track of occluders and occludees for subsequent code. drawInfo = (DrawableInfo *)robj->Get_User_Data(); if (drawInfo && (draw=drawInfo->m_drawable) != NULL) { @@ -477,33 +483,36 @@ void RTS3DScene::Visibility_Check(CameraClass * camera) continue; if (draw->getEffectiveOpacity() != 1.0f && m_translucentObjectsCount < TheGlobalData->m_maxVisibleTranslucentObjects) - { drawInfo->m_flags |= DrawableInfo::ERF_IS_TRANSLUCENT; //object is translucent + { + drawInfo->m_flags |= DrawableInfo::ERF_IS_TRANSLUCENT; m_translucentObjectsBuffer[m_translucentObjectsCount++] = robj; } if (TheGlobalData->m_enableBehindBuildingMarkers && TheGameLogic && TheGameLogic->getShowBehindBuildingMarkers()) { + const Bool isTranslucent = (drawInfo->m_flags & DrawableInfo::ERF_IS_TRANSLUCENT) != 0; //visible drawable. Check if it's either an occluder or occludee if (draw->isKindOf(KINDOF_STRUCTURE) && m_numPotentialOccluders < TheGlobalData->m_maxVisibleOccluderObjects) - { //object which could occlude other objects that need to be visible. + { + //object which could occlude other objects that need to be visible. //Make sure this object is not translucent so it's not rendered twice (from m_potentialOccluders and m_translucentObjectsBuffer) - if (drawInfo->m_flags ^ DrawableInfo::ERF_IS_TRANSLUCENT) + if (!isTranslucent) m_potentialOccluders[m_numPotentialOccluders++]=robj; drawInfo->m_flags |= DrawableInfo::ERF_POTENTIAL_OCCLUDER; } - else - if (draw->getObject() && + else if (draw->getObject() && (draw->isKindOf(KINDOF_SCORE) || draw->isKindOf(KINDOF_SCORE_CREATE) || draw->isKindOf(KINDOF_SCORE_DESTROY) || draw->isKindOf(KINDOF_MP_COUNT_FOR_VICTORY)) && (draw->getObject()->getSafeOcclusionFrame()) <= currentFrame && m_numPotentialOccludees < TheGlobalData->m_maxVisibleOccludeeObjects) - { //object which could be occluded but still needs to be visible. - //We process transucent units twice (also in m_translucentObjectsBuffer) because we need to see them when occluded. + { + //object which could be occluded but still needs to be visible. + //We process translucent units twice (also in m_translucentObjectsBuffer) because we need to see them when occluded. m_potentialOccludees[m_numPotentialOccludees++]=robj; drawInfo->m_flags |= DrawableInfo::ERF_POTENTIAL_OCCLUDEE; } - else - if (drawInfo->m_flags == DrawableInfo::ERF_IS_NORMAL && m_numNonOccluderOrOccludee < TheGlobalData->m_maxVisibleNonOccluderOrOccludeeObjects) - { //regular object with no custom effects but still needs to be delayed to get the occlusion feature to work correctly. - //Make sure this object is not translucent so it's not rendered twice (from m_potentialOccluders and m_translucentObjectsBuffer) - if (drawInfo->m_flags ^ DrawableInfo::ERF_IS_TRANSLUCENT) //make sure not translucent + else if (drawInfo->m_flags == DrawableInfo::ERF_IS_NORMAL && m_numNonOccluderOrOccludee < TheGlobalData->m_maxVisibleNonOccluderOrOccludeeObjects) + { + //regular object with no custom effects but still needs to be delayed to get the occlusion feature to work correctly. + //Make sure this object is not translucent so it's not rendered twice (from m_nonOccludersOrOccludees and m_translucentObjectsBuffer) + if (!isTranslucent) m_nonOccludersOrOccludees[m_numNonOccluderOrOccludee++]=robj; drawInfo->m_flags |= DrawableInfo::ERF_IS_NON_OCCLUDER_OR_OCCLUDEE; } @@ -573,7 +582,6 @@ void RTS3DScene::renderSpecificDrawables(RenderInfoClass &rinfo, Int numDrawable //============================================================================= void RTS3DScene::renderOneObject(RenderInfoClass &rinfo, RenderObjClass *robj, Int localPlayerIndex) { - Drawable *draw = NULL; DrawableInfo *drawInfo = NULL; Bool drawableHidden=FALSE; @@ -583,10 +591,9 @@ void RTS3DScene::renderOneObject(RenderInfoClass &rinfo, RenderObjClass *robj, I Bool doExtraFlagsPop=FALSE; LightClass **sceneLights=m_globalLight; - - if (robj->Class_ID() == RenderObjClass::CLASSID_IMAGE3D ) - { robj->Render(rinfo); //notify decals system that this track is visible + { + robj->Render(rinfo); //notify decals system that this track is visible return; //decals are not lit by this system yet so skip rest of lighting } @@ -594,7 +601,8 @@ void RTS3DScene::renderOneObject(RenderInfoClass &rinfo, RenderObjClass *robj, I SphereClass sph = robj->Get_Bounding_Sphere(); drawInfo = (DrawableInfo *)robj->Get_User_Data(); if (drawInfo) - { draw = drawInfo->m_drawable; + { + draw = drawInfo->m_drawable; //If we have a drawInfo but not drawable, we must be dealing with //a ghost object which is always fogged. if (!draw) @@ -635,19 +643,22 @@ void RTS3DScene::renderOneObject(RenderInfoClass &rinfo, RenderObjClass *robj, I return; //this object was removed by the getShroudedStatus() call. } else - { //drawable with no object so no way to know if it's shrouded. + { + //drawable with no object so no way to know if it's shrouded. ss = OBJECTSHROUD_CLEAR; //assume not shrouded/fogged. //Check to see if there is another unrelated object which controls the shroud status //(Hack for prison camps which contain enemy prisoner drawables) if (drawInfo->m_shroudStatusObjectID != INVALID_ID) - { Object *shroudObject=TheGameLogic->findObjectByID(drawInfo->m_shroudStatusObjectID); + { + Object *shroudObject=TheGameLogic->findObjectByID(drawInfo->m_shroudStatusObjectID); if (shroudObject && shroudObject->getShroudedStatus(localPlayerIndex) >= OBJECTSHROUD_FOGGED) ss = OBJECTSHROUD_SHROUDED; //we will assume that drawables without objects are 'particle' like and therefore don't need drawing if fogged/shrouded. } } if (draw->isKindOf(KINDOF_INFANTRY)) - { //ambient = m_infantryAmbient; //has no effect - see comment on m_infantryAmbient + { + //ambient = m_infantryAmbient; //has no effect - see comment on m_infantryAmbient sceneLights = m_infantryLight; } @@ -729,13 +740,15 @@ void RTS3DScene::renderOneObject(RenderInfoClass &rinfo, RenderObjClass *robj, I } } else - { //either no drawable or it is hidden + { + //either no drawable or it is hidden if (drawableHidden) return; //don't bother with anything else //Render object without a drawable. Must be either some fluff/debug object or a ghostObject. if (ss == OBJECTSHROUD_FOGGED) - { //Must be ghost object because we don't fog normal things. Fogged objects always have a predefined + { + //Must be ghost object because we don't fog normal things. Fogged objects always have a predefined //lighting environment applied which emulates the look of fog. rinfo.light_environment = &m_foggedLightEnv; robj->Render(rinfo); @@ -743,7 +756,8 @@ void RTS3DScene::renderOneObject(RenderInfoClass &rinfo, RenderObjClass *robj, I return; } else - { lightEnv.Reset(sph.Center, ambient); + { + lightEnv.Reset(sph.Center, ambient); for (Int globalLightIndex = 0; globalLightIndex < m_numGlobalLights; globalLightIndex++) lightEnv.Add_Light(*m_globalLight[globalLightIndex]); } @@ -794,17 +808,19 @@ void RTS3DScene::renderOneObject(RenderInfoClass &rinfo, RenderObjClass *robj, I if (m_customPassMode == SCENE_PASS_DEFAULT) { if (ss <= OBJECTSHROUD_CLEAR) + { robj->Render(rinfo); + } else { - rinfo.Push_Material_Pass(m_shroudMaterialPass); - robj->Render(rinfo); - rinfo.Pop_Material_Pass(); + rinfo.Push_Material_Pass(m_shroudMaterialPass); + robj->Render(rinfo); + rinfo.Pop_Material_Pass(); } } - else - if (m_maskMaterialPass) - { rinfo.Push_Material_Pass(m_maskMaterialPass); + else if (m_maskMaterialPass) + { + rinfo.Push_Material_Pass(m_maskMaterialPass); rinfo.Push_Override_Flags(RenderInfoClass::RINFO_OVERRIDE_ADDITIONAL_PASSES_ONLY); robj->Render(rinfo); rinfo.Pop_Override_Flags(); @@ -818,7 +834,7 @@ void RTS3DScene::renderOneObject(RenderInfoClass &rinfo, RenderObjClass *robj, I } rinfo.light_environment = NULL; - if (doExtraMaterialPop) //check if there is an extra material on the stack from the add'l material effect. + if (doExtraMaterialPop) //check if there is an extra material on the stack from the added material effect. rinfo.Pop_Material_Pass(); if (doExtraFlagsPop) rinfo.Pop_Override_Flags(); //flags used to disable base pass and only render custom heat vision pass. @@ -836,6 +852,7 @@ void RTS3DScene::Flush(RenderInfoClass & rinfo) //don't draw shadows in this mode because they interfere with destination alpha or are invisible (wireframe) if (m_customPassMode == SCENE_PASS_DEFAULT && Get_Extra_Pass_Polygon_Mode() == EXTRA_PASS_DISABLE) DoShadows(rinfo, false); //draw all non-stencil shadows (decals) since they fall under other objects. + TheDX8MeshRenderer.Flush(); //draw all non-translucent objects. //draw all non-translucent objects which were separated because they are hidden and need custom rendering. @@ -855,10 +872,11 @@ void RTS3DScene::Flush(RenderInfoClass & rinfo) //don't draw shadows in this mode because they interfere with destination alpha if (m_customPassMode == SCENE_PASS_DEFAULT && Get_Extra_Pass_Polygon_Mode() == EXTRA_PASS_DISABLE) DoShadows(rinfo, true); //draw all stencil shadows + WW3D::Render_And_Clear_Static_Sort_Lists(rinfo); //draws things like water if (m_customPassMode == SCENE_PASS_DEFAULT && Get_Extra_Pass_Polygon_Mode() == EXTRA_PASS_DISABLE) - flushTranslucentObjects(rinfo); //draw all translucent meshes which don't need per-poly sorting. + flushTranslucentObjects(rinfo); //draw all translucent meshes which don't need per-polygon sorting. { //USE_PERF_TIMER(translucentRender) @@ -867,13 +885,13 @@ void RTS3DScene::Flush(RenderInfoClass & rinfo) if (m_customPassMode == SCENE_PASS_DEFAULT && Get_Extra_Pass_Polygon_Mode() == EXTRA_PASS_DISABLE) DoParticles(rinfo); //queue up particles for rendering. - SortingRendererClass::Flush(); //draw sorted translucent polys like particles. + SortingRendererClass::Flush(); //draw sorted translucent polygons like particles. } TheDX8MeshRenderer.Clear_Pending_Delete_Lists(); } /**Generate a predefined light environment(s) that will be applied to many objects. Useful for things like totally fogged -objects and most generaic map objects that are not lit by dynamic lights.*/ +objects and most generic map objects that are not lit by dynamic lights.*/ void RTS3DScene::updateFixedLightEnvironments(RenderInfoClass & rinfo) { //Figure out how dimly lit fogged objects should be compared to fully lit. @@ -890,7 +908,8 @@ void RTS3DScene::updateFixedLightEnvironments(RenderInfoClass & rinfo) Vector3 oldDiffuse, oldAmbient; for (Int globalLightIndex = 0; globalLightIndex < m_numGlobalLights; globalLightIndex++) - { m_defaultLightEnv.Add_Light(*m_globalLight[globalLightIndex]); + { + m_defaultLightEnv.Add_Light(*m_globalLight[globalLightIndex]); //copy default lighting for infantry so we can tweak it. *m_infantryLight[globalLightIndex]=*m_globalLight[globalLightIndex]; m_infantryLight[globalLightIndex]->Set_Transform(m_globalLight[globalLightIndex]->Get_Transform()); @@ -961,14 +980,14 @@ void RTS3DScene::Render(RenderInfoClass & rinfo) if (Get_Extra_Pass_Polygon_Mode() == EXTRA_PASS_DISABLE) { if (m_customPassMode == SCENE_PASS_DEFAULT) - { //Regular rendering pass with no effects + { + //Regular rendering pass with no effects updatePlayerColorPasses();///@todo: this probably doesn't need to be done each frame. updateFixedLightEnvironments(rinfo); Customized_Render(rinfo); Flush(rinfo); } - else - if (m_customPassMode == SCENE_PASS_ALPHA_MASK) + else if (m_customPassMode == SCENE_PASS_ALPHA_MASK) { //a projected alpha texture which will later be used to determine where //wireframe should be visible. @@ -992,7 +1011,8 @@ void RTS3DScene::Render(RenderInfoClass & rinfo) { Bool old_enable=WW3D::Is_Texturing_Enabled(); if (Get_Extra_Pass_Polygon_Mode() == EXTRA_PASS_CLEAR_LINE) - { //render scene with solid black color but have destination alpha store + { + //render scene with solid black color but have destination alpha store //a projected alpha texture which will later be used to determine where //wireframe should be visible. ///@todo: Clearing to black may not be needed if the scene already did the clear. @@ -1037,7 +1057,8 @@ void RTS3DScene::Render(RenderInfoClass & rinfo) ShaderClass::Invalidate(); } else - { //old W3D custom rendering code. + { + //old W3D custom rendering code. //Disable writes to color buffer to save memory bandwidth - we only need Z. DX8Wrapper::Set_DX8_Render_State(D3DRS_COLORWRITEENABLE,0); @@ -1129,8 +1150,7 @@ void RTS3DScene::Customized_Render( RenderInfoClass &rinfo ) robj->Render(rinfo); rinfo.Pop_Material_Pass(); } - else - if (m_customPassMode == SCENE_PASS_ALPHA_MASK && m_maskMaterialPass) + else if (m_customPassMode == SCENE_PASS_ALPHA_MASK && m_maskMaterialPass) { rinfo.Push_Material_Pass(m_maskMaterialPass); robj->Render(rinfo); @@ -1152,7 +1172,6 @@ void RTS3DScene::Customized_Render( RenderInfoClass &rinfo ) // loop through all render objects in the list: for (it.First(&RenderList); !it.Is_Done();) { - // get the render object robj = it.Peek_Obj(); it.Next(); //advance to next object in case this one gets deleted during renderOneObject(). @@ -1178,14 +1197,16 @@ void RTS3DScene::Customized_Render( RenderInfoClass &rinfo ) //Don't draw shadows if there is no terrain present. if (TheW3DShadowManager && terrainObject && !ShaderClass::Is_Backface_Culling_Inverted() && Get_Extra_Pass_Polygon_Mode() == EXTRA_PASS_DISABLE) + { TheW3DShadowManager->queueShadows(TRUE); + } // only render particles once per frame if (terrainObject != NULL && TheParticleSystemManager != NULL && Get_Extra_Pass_Polygon_Mode() == EXTRA_PASS_DISABLE) - { TheParticleSystemManager->queueParticleRender(); + { + TheParticleSystemManager->queueParticleRender(); } - } /**Convert a player index to a color index, we use this because color indices are @@ -1205,11 +1226,13 @@ Int playerIndexToColorIndex(Int playerIndex) flippedPosition = NUMBER_PLAYER_COLOR_BITS-1-i; //correct position of bit after it's flipped left/right if (flippedPosition > i) - { //shifting left + { + //shifting left result |= (tmp & (1<>(i-flippedPosition); } } @@ -1244,7 +1267,7 @@ void renderStenciledPlayerColor( UnsignedInt color, UnsignedInt stencilRef, Bool VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE); DX8Wrapper::Set_Material(vmat); REF_PTR_RELEASE(vmat); - DX8Wrapper::Apply_Render_State_Changes(); //force update all renderstates + DX8Wrapper::Apply_Render_State_Changes(); //force update all render states LPDIRECT3DDEVICE8 m_pDev=DX8Wrapper::_Get_D3D_Device8(); @@ -1260,7 +1283,8 @@ void renderStenciledPlayerColor( UnsignedInt color, UnsignedInt stencilRef, Bool DX8Wrapper::Set_DX8_Render_State(D3DRS_ZENABLE, TRUE ); DWORD oldColorWriteEnable=0x12345678; if (clear) - { //we want to clear the stencil buffer to some known value whereever a player index is stored + { + //we want to clear the stencil buffer to some known value whereever a player index is stored Int occludedMask=TheW3DShadowManager->getStencilShadowMask(); DX8Wrapper::Set_DX8_Render_State(D3DRS_STENCILREF, 0x80808080 ); DX8Wrapper::Set_DX8_Render_State(D3DRS_STENCILMASK, occludedMask ); //isolate bits containing occluder|playerIndex @@ -1273,18 +1297,21 @@ void renderStenciledPlayerColor( UnsignedInt color, UnsignedInt stencilRef, Bool //disable writes to color buffer if (DX8Wrapper::Get_Current_Caps()->Get_DX8_Caps().PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) - { DX8Wrapper::_Get_D3D_Device8()->GetRenderState(D3DRS_COLORWRITEENABLE, &oldColorWriteEnable); + { + DX8Wrapper::_Get_D3D_Device8()->GetRenderState(D3DRS_COLORWRITEENABLE, &oldColorWriteEnable); DX8Wrapper::Set_DX8_Render_State(D3DRS_COLORWRITEENABLE,0); } else - { //device does not support disabling writes to color buffer so fake it through alpha blending + { + //device does not support disabling writes to color buffer so fake it through alpha blending DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE, TRUE); DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND, D3DBLEND_ZERO ); DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND, D3DBLEND_ONE ); } } else - { DX8Wrapper::Set_DX8_Render_State(D3DRS_STENCILREF, stencilRef ); + { + DX8Wrapper::Set_DX8_Render_State(D3DRS_STENCILREF, stencilRef ); DX8Wrapper::Set_DX8_Render_State(D3DRS_STENCILMASK, 0xffffffff ); DX8Wrapper::Set_DX8_Render_State(D3DRS_STENCILWRITEMASK,0xffffffff ); DX8Wrapper::Set_DX8_Render_State(D3DRS_STENCILFUNC, D3DCMP_EQUAL ); @@ -1332,7 +1359,8 @@ void RTS3DScene::flushOccludedObjectsIntoStencil(RenderInfoClass & rinfo) //We do this so that all objects are sorted by color which reduces the number of //state changes needed when drawing them. for (Int i=0; isetStencilShadowMask(usedPlayerColorBits); if (numVisiblePlayerColors >= 8 && TheGlobalData->m_useShadowVolumes) - { //for cases where we have 8 or more visible players, we're only left with 3 bits to store + { + //for cases where we have 8 or more visible players, we're only left with 3 bits to store //stencil shadows. That's probably not enough since it will only allow 7 overlapping shadows. //So we clear the stencil buffer, leaving only the MSB set on any occluded player pixels so that //shadow code knows not to overwrite these pixels. @@ -1491,7 +1523,8 @@ void RTS3DScene::flushOccludedObjectsIntoStencil(RenderInfoClass & rinfo) } else if (m_numNonOccluderOrOccludee || m_numPotentialOccluders || m_numPotentialOccludees) - { //no occluded objects so don't need to render anything special. Just draw the queued up + { + //no occluded objects so don't need to render anything special. Just draw the queued up //objects like normal because they were skipped in the main scene traversal. RenderObjClass **occludeeList=m_potentialOccludees; @@ -1676,21 +1709,21 @@ void RTS3DScene::addDynamicLight(W3DDynamicLight * obj) //============================================================================= W3DDynamicLight * RTS3DScene::getADynamicLight(void) { - RefRenderObjListIterator dynaLightIt(&m_dynamicLightList); - W3DDynamicLight *pLight; - for (dynaLightIt.First(); !dynaLightIt.Is_Done(); dynaLightIt.Next()) - { - pLight = (W3DDynamicLight*)dynaLightIt.Peek_Obj(); - if (!pLight->isEnabled()) { - pLight->setEnabled(true); - return(pLight); - } + RefRenderObjListIterator dynaLightIt(&m_dynamicLightList); + W3DDynamicLight *pLight; + for (dynaLightIt.First(); !dynaLightIt.Is_Done(); dynaLightIt.Next()) + { + pLight = (W3DDynamicLight*)dynaLightIt.Peek_Obj(); + if (!pLight->isEnabled()) { + pLight->setEnabled(true); + return(pLight); } - pLight = NEW_REF(W3DDynamicLight, ()); - addDynamicLight( pLight ); - pLight->Release_Ref(); - pLight->setEnabled(true); - return(pLight); + } + pLight = NEW_REF(W3DDynamicLight, ()); + addDynamicLight( pLight ); + pLight->Release_Ref(); + pLight->setEnabled(true); + return(pLight); } //============================================================================= @@ -1723,14 +1756,11 @@ void RTS3DScene::doRender( CameraClass * cam ) //============================================================================= void RTS3DScene::draw( ) { - if (m_camera == NULL) { DEBUG_CRASH(("Null m_camera in RTS3DScene::draw")); return; } WW3D::Render( this, m_camera ); - - } @@ -1768,10 +1798,8 @@ RTS2DScene::~RTS2DScene() //============================================================================= void RTS2DScene::Customized_Render( RenderInfoClass &rinfo ) { - // call simple scene class renderer SimpleSceneClass::Customized_Render( rinfo ); - } //============================================================================= @@ -1781,11 +1809,9 @@ void RTS2DScene::Customized_Render( RenderInfoClass &rinfo ) //============================================================================= void RTS2DScene::doRender( CameraClass * cam ) { - m_camera = cam; DRAW(); m_camera = NULL; - } //============================================================================= @@ -1795,14 +1821,11 @@ void RTS2DScene::doRender( CameraClass * cam ) //============================================================================= void RTS2DScene::draw( ) { - if (m_camera == NULL) { DEBUG_CRASH(("Null m_camera in RTS2DScene::draw")); return; } WW3D::Render( this, m_camera ); - - } @@ -1836,10 +1859,8 @@ RTS3DInterfaceScene::~RTS3DInterfaceScene() //============================================================================= void RTS3DInterfaceScene::Customized_Render( RenderInfoClass &rinfo ) { - // call simple scene class renderer SimpleSceneClass::Customized_Render( rinfo ); - }