void FTextRenderSceneProxy::GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const { QUICK_SCOPE_CYCLE_COUNTER( STAT_TextRenderSceneProxy_GetDynamicMeshElements ); // Vertex factory will not been initialized when the text string is empty or font is invalid. if(VertexFactory.IsInitialized()) { for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { if (VisibilityMap & (1 << ViewIndex)) { const FSceneView* View = Views[ViewIndex]; // Draw the mesh. FMeshBatch& Mesh = Collector.AllocateMesh(); FMeshBatchElement& BatchElement = Mesh.Elements[0]; BatchElement.IndexBuffer = &IndexBuffer; Mesh.VertexFactory = &VertexFactory; BatchElement.PrimitiveUniformBufferResource = &GetUniformBuffer(); BatchElement.FirstIndex = 0; BatchElement.NumPrimitives = IndexBuffer.Indices.Num() / 3; BatchElement.MinVertexIndex = 0; BatchElement.MaxVertexIndex = VertexBuffer.Vertices.Num() - 1; Mesh.ReverseCulling = IsLocalToWorldDeterminantNegative(); Mesh.bDisableBackfaceCulling = false; Mesh.Type = PT_TriangleList; Mesh.DepthPriorityGroup = SDPG_World; const bool bUseSelectedMaterial = GIsEditor && (View->Family->EngineShowFlags.Selection) ? IsSelected() : false; Mesh.MaterialRenderProxy = TextMaterial->GetRenderProxy(bUseSelectedMaterial); Mesh.bCanApplyViewModeOverrides = !bAlwaysRenderAsText; Collector.AddMesh(ViewIndex, Mesh); #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) RenderBounds(Collector.GetPDI(ViewIndex), View->Family->EngineShowFlags, GetBounds(), IsSelected()); #endif } } } }
virtual void GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const override { QUICK_SCOPE_CYCLE_COUNTER( STAT_SpriteSceneProxy_GetDynamicMeshElements ); FTexture* TextureResource = (Texture != NULL) ? Texture->Resource : NULL; if (TextureResource) { for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { if (VisibilityMap & (1 << ViewIndex)) { const FSceneView* View = Views[ViewIndex]; // Calculate the view-dependent scaling factor. float ViewedSizeX = SizeX; float ViewedSizeY = SizeY; if (bIsScreenSizeScaled && (View->ViewMatrices.ProjMatrix.M[3][3] != 1.0f)) { const float ZoomFactor = FMath::Min<float>(View->ViewMatrices.ProjMatrix.M[0][0], View->ViewMatrices.ProjMatrix.M[1][1]); if(ZoomFactor != 0.0f) { const float Radius = View->WorldToScreen(Origin).W * (ScreenSize / ZoomFactor); if (Radius < 1.0f) { ViewedSizeX *= Radius; ViewedSizeY *= Radius; } } } #if WITH_EDITORONLY_DATA ViewedSizeX *= EditorScale; ViewedSizeY *= EditorScale; #endif FLinearColor ColorToUse = Color; // Set the selection/hover color from the current engine setting. // The color is multiplied by 10 because this value is normally expected to be blended // additively, this is not how the sprites work and therefore need an extra boost // to appear the same color as previously #if WITH_EDITOR if( View->bHasSelectedComponents && !IsIndividuallySelected() ) { ColorToUse = FLinearColor::White + (GEngine->GetSubduedSelectionOutlineColor() * GEngine->SelectionHighlightIntensityBillboards * 10); } else #endif if (IsSelected()) { ColorToUse = FLinearColor::White + (GEngine->GetSelectedMaterialColor() * GEngine->SelectionHighlightIntensityBillboards * 10); } else if (IsHovered()) { ColorToUse = FLinearColor::White + (GEngine->GetHoveredMaterialColor() * GEngine->HoverHighlightIntensity * 10); } // Sprites of locked actors draw in red. if (bIsActorLocked) { ColorToUse = FColor::Red; } FLinearColor LevelColorToUse = IsSelected() ? ColorToUse : (FLinearColor)LevelColor; FLinearColor PropertyColorToUse = PropertyColor; const FLinearColor& SpriteColor = View->Family->EngineShowFlags.LevelColoration ? LevelColorToUse : ( (View->Family->EngineShowFlags.PropertyColoration) ? PropertyColorToUse : ColorToUse ); Collector.GetPDI(ViewIndex)->DrawSprite( Origin, ViewedSizeX, ViewedSizeY, TextureResource, SpriteColor, GetDepthPriorityGroup(View), U,UL,V,VL ); } } #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { if (VisibilityMap & (1 << ViewIndex)) { const FSceneView* View = Views[ViewIndex]; RenderBounds(Collector.GetPDI(ViewIndex), View->Family->EngineShowFlags, GetBounds(), IsSelected()); } } #endif } }
void FGeometryCacheSceneProxy::GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const { SCOPE_CYCLE_COUNTER(STAT_GeometryCacheSceneProxy_GetMeshElements); // Set up wireframe material (if needed) const bool bWireframe = AllowDebugViewmodes() && ViewFamily.EngineShowFlags.Wireframe; FColoredMaterialRenderProxy* WireframeMaterialInstance = NULL; if (bWireframe) { WireframeMaterialInstance = new FColoredMaterialRenderProxy( GEngine->WireframeMaterial ? GEngine->WireframeMaterial->GetRenderProxy(IsSelected()) : NULL, FLinearColor(0, 0.5f, 1.f) ); Collector.RegisterOneFrameMaterialProxy(WireframeMaterialInstance); } // Iterate over sections for (const FGeomCacheTrackProxy* TrackProxy : Sections ) { // QQQ if (TrackProxy != nullptr) { INC_DWORD_STAT_BY(STAT_GeometryCacheSceneProxy_MeshBatchCount, TrackProxy->MeshData->BatchesInfo.Num()); int32 BatchIndex = 0; for (FGeometryCacheMeshBatchInfo& BatchInfo : TrackProxy->MeshData->BatchesInfo) { FMaterialRenderProxy* MaterialProxy = bWireframe ? WireframeMaterialInstance : TrackProxy->Materials[BatchIndex]->GetRenderProxy(IsSelected()); for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { if (VisibilityMap & (1 << ViewIndex)) { const FSceneView* View = Views[ViewIndex]; // Draw the mesh. FMeshBatch& Mesh = Collector.AllocateMesh(); FMeshBatchElement& BatchElement = Mesh.Elements[0]; BatchElement.IndexBuffer = &TrackProxy->IndexBuffer; Mesh.bWireframe = bWireframe; Mesh.VertexFactory = &TrackProxy->VertexFactory; Mesh.MaterialRenderProxy = MaterialProxy; BatchElement.PrimitiveUniformBuffer = CreatePrimitiveUniformBufferImmediate(TrackProxy->WorldMatrix * GetLocalToWorld(), GetBounds(), GetLocalBounds(), true, UseEditorDepthTest()); BatchElement.FirstIndex = BatchInfo.StartIndex; BatchElement.NumPrimitives = BatchInfo.NumTriangles; BatchElement.MinVertexIndex = 0; BatchElement.MaxVertexIndex = TrackProxy->VertexBuffer.Vertices.Num() - 1; Mesh.ReverseCulling = IsLocalToWorldDeterminantNegative(); Mesh.Type = PT_TriangleList; Mesh.DepthPriorityGroup = SDPG_World; Mesh.bCanApplyViewModeOverrides = false; Collector.AddMesh(ViewIndex, Mesh); INC_DWORD_STAT_BY(STAT_GeometryCacheSceneProxy_TriangleCount, BatchElement.NumPrimitives); } } ++BatchIndex; } } } // Draw bounds #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { if (VisibilityMap & (1 << ViewIndex)) { // Render bounds RenderBounds(Collector.GetPDI(ViewIndex), ViewFamily.EngineShowFlags, GetBounds(), IsSelected()); } } #endif }
void FPaperTileMapRenderSceneProxy::GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const { QUICK_SCOPE_CYCLE_COUNTER(STAT_FPaperTileMapRenderSceneProxy_GetDynamicMeshElements); checkSlow(IsInRenderingThread()); // Slight depth bias so that the wireframe grid overlay doesn't z-fight with the tiles themselves const float DepthBias = 0.0001f; for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { if (VisibilityMap & (1 << ViewIndex)) { const FSceneView* View = Views[ViewIndex]; FPrimitiveDrawInterface* PDI = Collector.GetPDI(ViewIndex); // Draw the tile maps //@TODO: RenderThread race condition if (TileMap != nullptr) { FColor WireframeColor = FColor(0, 255, 255, 255); if ((View->Family->EngineShowFlags.Collision /*@TODO: && bIsCollisionEnabled*/) && AllowDebugViewmodes()) { if (UBodySetup2D* BodySetup2D = Cast<UBodySetup2D>(TileMap->BodySetup)) { //@TODO: Draw 2D debugging geometry } else if (UBodySetup* BodySetup = TileMap->BodySetup) { if (FMath::Abs(GetLocalToWorld().Determinant()) < SMALL_NUMBER) { // Catch this here or otherwise GeomTransform below will assert // This spams so commented out //UE_LOG(LogStaticMesh, Log, TEXT("Zero scaling not supported (%s)"), *StaticMesh->GetPathName()); } else { // Make a material for drawing solid collision stuff const UMaterial* LevelColorationMaterial = View->Family->EngineShowFlags.Lighting ? GEngine->ShadedLevelColorationLitMaterial : GEngine->ShadedLevelColorationUnlitMaterial; auto CollisionMaterialInstance = new FColoredMaterialRenderProxy( LevelColorationMaterial->GetRenderProxy(IsSelected(), IsHovered()), WireframeColor ); // Draw the static mesh's body setup. // Get transform without scaling. FTransform GeomTransform(GetLocalToWorld()); // In old wireframe collision mode, always draw the wireframe highlighted (selected or not). bool bDrawWireSelected = IsSelected(); if (View->Family->EngineShowFlags.Collision) { bDrawWireSelected = true; } // Differentiate the color based on bBlockNonZeroExtent. Helps greatly with skimming a level for optimization opportunities. FColor CollisionColor = FColor(157, 149, 223, 255); const bool bPerHullColor = false; const bool bDrawSimpleSolid = false; BodySetup->AggGeom.GetAggGeom(GeomTransform, GetSelectionColor(CollisionColor, bDrawWireSelected, IsHovered()), CollisionMaterialInstance, bPerHullColor, bDrawSimpleSolid, UseEditorDepthTest(), ViewIndex, Collector); } } } // Draw the bounds RenderBounds(PDI, View->Family->EngineShowFlags, GetBounds(), IsSelected()); #if WITH_EDITOR // Draw the debug outline if (View->Family->EngineShowFlags.Grid) { const uint8 DPG = SDPG_Foreground;//GetDepthPriorityGroup(View); // Draw separation wires if selected FLinearColor OverrideColor; bool bUseOverrideColor = false; const bool bShowAsSelected = !(GIsEditor && View->Family->EngineShowFlags.Selection) || IsSelected(); if (bShowAsSelected || IsHovered()) { bUseOverrideColor = true; OverrideColor = GetSelectionColor(FLinearColor::White, bShowAsSelected, IsHovered()); } FTransform LocalToWorld(GetLocalToWorld()); if (bUseOverrideColor) { const int32 SelectedLayerIndex = TileMap->SelectedLayerIndex; // Draw a bound for any invisible layers for (int32 LayerIndex = 0; LayerIndex < TileMap->TileLayers.Num(); ++LayerIndex) { if (LayerIndex != SelectedLayerIndex) { const FVector TL(LocalToWorld.TransformPosition(TileMap->GetTilePositionInLocalSpace(0, 0, LayerIndex))); const FVector TR(LocalToWorld.TransformPosition(TileMap->GetTilePositionInLocalSpace(TileMap->MapWidth, 0, LayerIndex))); const FVector BL(LocalToWorld.TransformPosition(TileMap->GetTilePositionInLocalSpace(0, TileMap->MapHeight, LayerIndex))); const FVector BR(LocalToWorld.TransformPosition(TileMap->GetTilePositionInLocalSpace(TileMap->MapWidth, TileMap->MapHeight, LayerIndex))); PDI->DrawLine(TL, TR, OverrideColor, DPG, 0.0f, DepthBias); PDI->DrawLine(TR, BR, OverrideColor, DPG, 0.0f, DepthBias); PDI->DrawLine(BR, BL, OverrideColor, DPG, 0.0f, DepthBias); PDI->DrawLine(BL, TL, OverrideColor, DPG, 0.0f, DepthBias); } } if (SelectedLayerIndex != INDEX_NONE) { // Draw horizontal lines on the selection for (int32 Y = 0; Y <= TileMap->MapHeight; ++Y) { int32 X = 0; const FVector Start(TileMap->GetTilePositionInLocalSpace(X, Y, SelectedLayerIndex)); X = TileMap->MapWidth; const FVector End(TileMap->GetTilePositionInLocalSpace(X, Y, SelectedLayerIndex)); PDI->DrawLine(LocalToWorld.TransformPosition(Start), LocalToWorld.TransformPosition(End), OverrideColor, DPG, 0.0f, DepthBias); } // Draw vertical lines for (int32 X = 0; X <= TileMap->MapWidth; ++X) { int32 Y = 0; const FVector Start(TileMap->GetTilePositionInLocalSpace(X, Y, SelectedLayerIndex)); Y = TileMap->MapHeight; const FVector End(TileMap->GetTilePositionInLocalSpace(X, Y, SelectedLayerIndex)); PDI->DrawLine(LocalToWorld.TransformPosition(Start), LocalToWorld.TransformPosition(End), OverrideColor, DPG, 0.0f, DepthBias); } } } } #endif } } } // Draw all of the queued up sprites FPaperRenderSceneProxy::GetDynamicMeshElements(Views, ViewFamily, VisibilityMap, Collector); }
void FPaperTileMapRenderSceneProxy::GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const { SCOPE_CYCLE_COUNTER(STAT_TileMap_GetDynamicMeshElements); checkSlow(IsInRenderingThread()); for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { SCOPE_CYCLE_COUNTER(STAT_TileMap_EditorWireDrawing); if (VisibilityMap & (1 << ViewIndex)) { const FSceneView* View = Views[ViewIndex]; FPrimitiveDrawInterface* PDI = Collector.GetPDI(ViewIndex); // Draw the tile maps //@TODO: RenderThread race condition if (TileMap != nullptr) { if ((View->Family->EngineShowFlags.Collision /*@TODO: && bIsCollisionEnabled*/) && AllowDebugViewmodes()) { if (UBodySetup2D* BodySetup2D = Cast<UBodySetup2D>(TileMap->BodySetup)) { //@TODO: Draw 2D debugging geometry } else if (UBodySetup* BodySetup = TileMap->BodySetup) { if (FMath::Abs(GetLocalToWorld().Determinant()) < SMALL_NUMBER) { // Catch this here or otherwise GeomTransform below will assert // This spams so commented out //UE_LOG(LogStaticMesh, Log, TEXT("Zero scaling not supported (%s)"), *StaticMesh->GetPathName()); } else { // Make a material for drawing solid collision stuff const UMaterial* LevelColorationMaterial = View->Family->EngineShowFlags.Lighting ? GEngine->ShadedLevelColorationLitMaterial : GEngine->ShadedLevelColorationUnlitMaterial; auto CollisionMaterialInstance = new FColoredMaterialRenderProxy( LevelColorationMaterial->GetRenderProxy(IsSelected(), IsHovered()), WireframeColor ); // Draw the static mesh's body setup. // Get transform without scaling. FTransform GeomTransform(GetLocalToWorld()); // In old wireframe collision mode, always draw the wireframe highlighted (selected or not). bool bDrawWireSelected = IsSelected(); if (View->Family->EngineShowFlags.Collision) { bDrawWireSelected = true; } // Differentiate the color based on bBlockNonZeroExtent. Helps greatly with skimming a level for optimization opportunities. FColor CollisionColor = FColor(157, 149, 223, 255); const bool bPerHullColor = false; const bool bDrawSimpleSolid = false; BodySetup->AggGeom.GetAggGeom(GeomTransform, GetSelectionColor(CollisionColor, bDrawWireSelected, IsHovered()).ToFColor(true), CollisionMaterialInstance, bPerHullColor, bDrawSimpleSolid, UseEditorDepthTest(), ViewIndex, Collector); } } } // Draw the bounds RenderBounds(PDI, View->Family->EngineShowFlags, GetBounds(), IsSelected()); #if WITH_EDITOR const bool bShowAsSelected = IsSelected(); const bool bEffectivelySelected = bShowAsSelected || IsHovered(); const uint8 DPG = SDPG_Foreground;//GetDepthPriorityGroup(View); // Draw separation wires if selected const FLinearColor OverrideColor = GetSelectionColor(FLinearColor::White, bShowAsSelected, IsHovered(), /*bUseOverlayIntensity=*/ false); // Draw the debug outline if (bEffectivelySelected) { const int32 SelectedLayerIndex = (OnlyLayerIndex != INDEX_NONE) ? OnlyLayerIndex : TileMap->SelectedLayerIndex; if (bShowPerLayerGrid) { if (OnlyLayerIndex == INDEX_NONE) { // Draw a bound for every layer but the selected one (and even that one if the per-tile grid is off) for (int32 LayerIndex = 0; LayerIndex < TileMap->TileLayers.Num(); ++LayerIndex) { if ((LayerIndex != SelectedLayerIndex) || !bShowPerTileGrid) { DrawBoundsForLayer(PDI, OverrideColor, LayerIndex); } } } else if (!bShowPerTileGrid) { DrawBoundsForLayer(PDI, OverrideColor, OnlyLayerIndex); } } if (bShowPerTileGrid && (SelectedLayerIndex != INDEX_NONE)) { switch (TileMap->ProjectionMode) { default: case ETileMapProjectionMode::Orthogonal: case ETileMapProjectionMode::IsometricDiamond: DrawNormalGridLines(PDI, OverrideColor, SelectedLayerIndex); break; case ETileMapProjectionMode::IsometricStaggered: DrawStaggeredGridLines(PDI, OverrideColor, SelectedLayerIndex); break; case ETileMapProjectionMode::HexagonalStaggered: DrawHexagonalGridLines(PDI, OverrideColor, SelectedLayerIndex); break; } } } else if (View->Family->EngineShowFlags.Grid && bShowOutlineWhenUnselected) { // Draw a layer rectangle even when not selected, so you can see where the tile map is in the editor DrawBoundsForLayer(PDI, WireframeColor, /*LayerIndex=*/ (OnlyLayerIndex != INDEX_NONE) ? OnlyLayerIndex : 0); } #endif } } } // Draw all of the queued up sprites FPaperRenderSceneProxy::GetDynamicMeshElements(Views, ViewFamily, VisibilityMap, Collector); }