void FStaticMesh::AddToDrawLists(FScene* Scene) { if (GRHIFeatureLevel >= ERHIFeatureLevel::SM3) { if (CastShadow) { FShadowDepthDrawingPolicyFactory::AddStaticMesh(Scene,this); } if (!bShadowOnly && PrimitiveSceneInfo->Proxy->ShouldRenderInMainPass()) { // not all platforms need this const bool bRequiresHitProxies = Scene->RequiresHitProxies(); if ( bRequiresHitProxies && PrimitiveSceneInfo->Proxy->IsSelectable() ) { // Add the static mesh to the DPG's hit proxy draw list. FHitProxyDrawingPolicyFactory::AddStaticMesh(Scene,this); } if(!IsTranslucent()) { extern TAutoConsoleVariable<int32> CVarEarlyZPass; int32 EarlyZPass = CVarEarlyZPass.GetValueOnRenderThread(); extern int32 GEarlyZPassMovable; // Render non-masked materials in the depth only pass if (PrimitiveSceneInfo->Proxy->ShouldUseAsOccluder() && (!IsMasked() || EarlyZPass == 2) && (!PrimitiveSceneInfo->Proxy->IsMovable() || GEarlyZPassMovable)) { FDepthDrawingPolicyFactory::AddStaticMesh(Scene,this); } // Add the static mesh to the DPG's base pass draw list. FBasePassOpaqueDrawingPolicyFactory::AddStaticMesh(Scene,this); FVelocityDrawingPolicyFactory::AddStaticMesh(Scene, this); } } } else { if (!bShadowOnly && !IsTranslucent()) { // Add the static mesh to the DPG's base pass draw list. FBasePassForwardOpaqueDrawingPolicyFactory::AddStaticMesh(Scene,this); } } }
void FStaticMesh::AddToDrawLists(FRHICommandListImmediate& RHICmdList, FScene* Scene) { const auto FeatureLevel = Scene->GetFeatureLevel(); if (CastShadow) { FShadowDepthDrawingPolicyFactory::AddStaticMesh(Scene, this); } if (!PrimitiveSceneInfo->Proxy->ShouldRenderInMainPass()) { return; } if (bUseForMaterial && Scene->RequiresHitProxies() && PrimitiveSceneInfo->Proxy->IsSelectable()) { // Add the static mesh to the DPG's hit proxy draw list. FHitProxyDrawingPolicyFactory::AddStaticMesh(Scene, this); } if (IsTranslucent(FeatureLevel)) { return; } if (Scene->ShouldUseDeferredRenderer()) { if (bUseAsOccluder) { // Render non-masked materials in the depth only pass extern TAutoConsoleVariable<int32> CVarEarlyZPass; int32 EarlyZPass = CVarEarlyZPass.GetValueOnRenderThread(); extern int32 GEarlyZPassMovable; // WARNING : If you change this condition, also change the logic in FStaticMeshSceneProxy::DrawStaticElements. if (PrimitiveSceneInfo->Proxy->ShouldUseAsOccluder() && (!IsMasked(FeatureLevel) || EarlyZPass == 2) && (!PrimitiveSceneInfo->Proxy->IsMovable() || GEarlyZPassMovable)) { FDepthDrawingPolicyFactory::AddStaticMesh(Scene,this); } } if (bUseForMaterial) { // Add the static mesh to the DPG's base pass draw list. FBasePassOpaqueDrawingPolicyFactory::AddStaticMesh(RHICmdList, Scene, this); FVelocityDrawingPolicyFactory::AddStaticMesh(Scene, this); } } else { if (bUseForMaterial) { // Add the static mesh to the DPG's base pass draw list. FBasePassForwardOpaqueDrawingPolicyFactory::AddStaticMesh(RHICmdList, Scene, this); } } }
void CWsWindow::SetVisibleRegion(const TRegion& aNewRegion, const TRegion* aTop, TRegion& aNewFadableRegion) { STACK_REGION difference; TBool diffs = EFalse; difference.Copy(iVisibleRegion); difference.SubRegion(aNewRegion); if (!difference.IsEmpty()) { diffs = ETrue; if (IsTranslucent()) { // Andy - If this is a client window (what else could it be) we can also subtract the // user defined opaque region before doing this: iScreen->AddRedrawRegion(difference, EFalse); } } difference.Copy(aNewRegion); if (HasBeenDrawnToScreen()) { difference.SubRegion(iVisibleRegion); } if (!difference.IsEmpty()) { diffs = ETrue; STACK_REGION topDiff; topDiff.Copy(difference); WS_ASSERT_DEBUG(aTop,EWsPanicRegion); topDiff.Intersect(*aTop); difference.SubRegion(topDiff); iScreen->AddRedrawRegion(topDiff, EFalse, ERedrawTopOnly); iScreen->AddRedrawRegion(difference, EFalse, ERedrawAll); topDiff.Close(); } difference.Close(); AbortDsaIfRequired(aNewRegion, aTop); if (diffs) { ResetVisibleRegion(); iVisibleRegion.Copy(aNewRegion); PossibleVisibilityChangedEvent(EFalse); } iFadableRegion.Copy( aNewFadableRegion ); // Just because the visible region (screen coordinates) didn't change doesn't // mean the invalid region (window coordinates) didn't change, so we always call this. iRedraw->VisibleRegionChange(); }
void hsVertexShader::IShadeSpan( plGeometrySpan *span, INode* node ) { hsColorRGBA preDiffuse, rtDiffuse, matAmbient; hsBitVector dirtyVector; int i; bool translucent, shadeIt, addingIt; plLayerInterface *layer = nil; hsGuardBegin("hsVertexShader::ShadeSpan"); const char* dbgNodeName = node->GetName(); if( span->fNumVerts == 0 ) return; fShadeColorTable = new hsColorRGBA[ span->fNumVerts ]; fIllumColorTable = new hsColorRGBA[ span->fNumVerts ]; translucent = IsTranslucent( span->fMaterial ); /// Get material layer #0 addingIt = false; shadeIt = !( span->fProps & plGeometrySpan::kPropNoPreShade ); if( span->fMaterial->GetNumLayers() != 0 ) { layer = span->fMaterial->GetLayer( 0 ); if( layer->GetShadeFlags() & hsGMatState::kShadeNoShade ) shadeIt = false; if( layer->GetBlendFlags() & hsGMatState::kBlendAdd ) addingIt = true; } float opacity = 1.f; for( i = 0; i < span->fMaterial->GetNumLayers(); i++ ) { plLayerInterface* lay = span->fMaterial->GetLayer(i); if( (lay->GetBlendFlags() & hsGMatState::kBlendAlpha) && ( !i || (lay->GetMiscFlags() & hsGMatState::kMiscRestartPassHere) ) ) { opacity = span->fMaterial->GetLayer(i)->GetOpacity(); } } /// Generate color table if( shadeIt ) IShadeVertices( span, &dirtyVector, node, translucent ); else { for( i = 0; i < span->fNumVerts; i++ ) { /// This is good for the old way, but not sure about the new way. Test once new way is in again -mcn // fShadeColorTable[ i ].Set( 1, 1, 1, 1 ); // fIllumColorTable[ i ].Set( 0, 0, 0, 1 ); hsPoint3 position; hsVector3 normal; hsColorRGBA color, illum; span->ExtractVertex( i, &position, &normal, &color, &illum ); span->ExtractInitColor( i, &color, &illum ); fShadeColorTable[ i ].Set( color.r, color.g, color.b, color.a ); fIllumColorTable[ i ].Set( illum.r, illum.g, illum.b, 1 ); } } /// Get mat colors to modulate by if( layer == nil ) { preDiffuse.Set( 1, 1, 1, 1 ); rtDiffuse.Set( 1, 1, 1, 1 ); matAmbient.Set( 0, 0, 0, 0 ); } else { if( layer->GetShadeFlags() & hsGMatState::kShadeWhite ) { preDiffuse.Set( 1, 1, 1, 1 ); rtDiffuse.Set( 1, 1, 1, 1 ); matAmbient.Set( 0, 0, 0, 0 ); } else { preDiffuse = layer->GetPreshadeColor(); // This is for vertex-based lighting, which basically ignores preshading rtDiffuse = layer->GetRuntimeColor(); // This is for vertex-based lighting, which basically ignores preshading matAmbient = layer->GetAmbientColor(); matAmbient.a = 0; } preDiffuse.a = opacity; rtDiffuse.a = opacity; } #if 0 /// Multiply by the material color, and scale by opacity if we're additive blending /// Apply colors now, multiplying by the material color as we go for( i = 0; i < span->fNumVerts; i++ ) { fShadeColorTable[ i ] *= matDiffuse; fShadeColorTable[ i ] += matAmbient; fIllumColorTable[ i ] *= matDiffuse; fIllumColorTable[ i ] += matAmbient; } if( addingIt ) { for( i = 0; i < span->fNumVerts; i++ ) { float opacity = fShadeColorTable[ i ].a; fShadeColorTable[ i ] *= opacity; fIllumColorTable[ i ] *= opacity; } } #else /// Combine shade and illum together into the diffuse color if( ( span->fProps & plGeometrySpan::kLiteMask ) != plGeometrySpan::kLiteMaterial ) { /// The two vertex lighting formulas take in a vetex color pre-processed, i.e. in /// the form of: vtxColor = ( maxVtxColor * materialDiffuse + maxIllumColor ) span->fProps |= plGeometrySpan::kDiffuseFoldedIn; if( !shadeIt ) { for( i = 0; i < span->fNumVerts; i++ ) { fIllumColorTable[ i ].a = 0; fShadeColorTable[ i ] = (fShadeColorTable[ i ] * rtDiffuse) + fIllumColorTable[ i ]; fIllumColorTable[ i ].Set( 0, 0, 0, 0 ); } } else { for( i = 0; i < span->fNumVerts; i++ ) { fIllumColorTable[ i ].a = 1.f; // Following needs to be changed to allow user input vertex colors to modulate // the runtime light values. // fShadeColorTable[ i ] = fIllumColorTable[ i ] * rtDiffuse; fShadeColorTable[ i ] = fShadeColorTable[ i ] * fIllumColorTable[ i ] * rtDiffuse; fIllumColorTable[ i ].Set( 0, 0, 0, 0 ); } } } else { if( !shadeIt ) { // Not shaded, so runtime lit, so we want BLACK vertex colors for( i = 0; i < span->fNumVerts; i++ ) { fShadeColorTable[ i ].Set( 0, 0, 0, 0 ); fIllumColorTable[ i ].Set( 0, 0, 0, 0 ); } } else { for( i = 0; i < span->fNumVerts; i++ ) { fShadeColorTable[ i ] *= fIllumColorTable[ i ]; fIllumColorTable[ i ].Set( 0, 0, 0, 0 ); } } } #endif /// Loop and stuff for( i = 0; i < span->fNumVerts; i++ ) span->StuffVertex( i, fShadeColorTable + i, fIllumColorTable + i ); delete [] fShadeColorTable; delete [] fIllumColorTable; hsGuardEnd; }
//This function sets up the quick fadable region. //It removes anything that cannot be quick faded, and schedules it to be drawn in the normal fashion. void CWsWindow::SetFadeableRegion(const TRegion& aNewFadableRegion, const TRegion& aTop) { WS_ASSERT_DEBUG(iScreen, EWsPanicNoScreen); iFadableRegion.Copy(aNewFadableRegion); //Try to figure out if any part of iFadableRegion can be quick faded (i.e. fading applied to //the screen without first having to redraw all visible windows intersecting the region). if ( !iFadableRegion.IsEmpty() && iScreen->IsQuickFadeScheduled(this) ) { if (IsTranslucent()) { //If a window is semitransparent, then we cannot apply a quickfade to it if //the window below is faded too. iScreen->AddRedrawRegion(iVisibleRegion, EFalse, ERedrawAll); iScreen->RemoveFromQuickFadeList(this); } else { iQuickFadeRegion.Intersection(iFadableRegion, aTop); //Remove any regions not possible to quick fade from iQuickFadeRegion and //schedule these regions for full back-front rendering instead. STACK_REGION nonQuickFadableRegion; for(CWsSpriteBase * sprite = iSpriteList; sprite; sprite = sprite->Next()) { nonQuickFadableRegion.AddRect(sprite->Rect()); } for(CWsAnim * anim = iAnimList; anim; anim = anim->Next()) { nonQuickFadableRegion.AddRect(anim->BestRect()); } RWsTextCursor* const cursor = CWsTop::CurrentTextCursor(); if( cursor && (cursor->Window()==this) && cursor->IsStandardCursorActive() ) { nonQuickFadableRegion.AddRect(cursor->Rect()); } //Any regions scheduled for fading but partly or fully covered by transparent windows above them STACK_REGION coveredFadableRegion; coveredFadableRegion.Copy(iFadableRegion); coveredFadableRegion.SubRegion(iQuickFadeRegion); nonQuickFadableRegion.Union(coveredFadableRegion); coveredFadableRegion.Close(); nonQuickFadableRegion.Tidy(); //Remove any regions not possible to quick fade from iQuickFadeRegion iQuickFadeRegion.SubRegion(nonQuickFadableRegion); if (!nonQuickFadableRegion.CheckError()) { //Schedule normal drawing (full back to front rendering) for the region not possible to quick fade if (!nonQuickFadableRegion.IsEmpty()) { iScreen->AddRedrawRegion(nonQuickFadableRegion, EFalse, ERedrawAll); } } else { //Schedule normal drawing for the whole iVisibleRegion if the calculations are broken iScreen->AddRedrawRegion(iVisibleRegion, EFalse, ERedrawAll); } nonQuickFadableRegion.Close(); } } else { iQuickFadeRegion.Reset(); } }
void CWsWindow::SetVisibleRegion(const TRegion& aNewRegion, const TRegion* aTop) { WS_ASSERT_DEBUG(iScreen, EWsPanicNoScreen); STACK_REGION difference; TBool diffs = EFalse; difference.Copy(iVisibleRegion); difference.SubRegion(aNewRegion); if (!difference.IsEmpty()) { diffs = ETrue; if (IsTranslucent()) { iScreen->AddRedrawRegion(difference, EFalse); } } difference.Copy(aNewRegion); if (HasBeenDrawnToScreen()) { difference.SubRegion(iVisibleRegion); } if (!difference.IsEmpty()) { diffs = ETrue; if(!iScreen->ChangeTracking()) { //the following code will restart animations STACK_REGION topDiff; topDiff.Copy(difference); WS_ASSERT_DEBUG(aTop,EWsPanicRegion); topDiff.Intersect(*aTop); difference.SubRegion(topDiff); iScreen->AddRedrawRegion(topDiff, EFalse, ERedrawTopOnly); iScreen->AddRedrawRegion(difference, EFalse, ERedrawAll); topDiff.Close(); } else if(IsVisible()) { RestartAnimations(aNewRegion); } } difference.Close(); AbortDsaIfRequired(aNewRegion, aTop); if (diffs) { ResetVisibleRegion(); iVisibleRegion.Copy(aNewRegion); PossibleVisibilityChangedEvent(EFalse); if (Redraw()->HasElement()) { WS_ASSERT_DEBUG(WinType()==EWinTypeClient,EWsPanicWindowType); if (WinType()==EWinTypeClient) { iScreen->WindowElements().SetVisibleRegion(*static_cast<CWsClientWindow*>(this)); } } } // Just because the visible region (screen coordinates) didn't change doesn't // mean the invalid region (window coordinates) didn't change, so we always call this. iRedraw->VisibleRegionChange(); }