2011-12-28 24 views
8

Sto disegnando in un DrawingContext e mi piacerebbe applicare un effetto ombra esterna a una parte del disegno. Al momento di creare le parti rilevanti in un DrawingGroup e applicare una BitmapEffect, ma questo non ha alcun effetto:Come applicare un effetto ombra discendente durante il disegno su un DrawingContext in WPF?

var layer = new DrawingGroup(); 
using (var lcontext = layer.Open()) 
{ 
    // draw stuff in lcontext 
} 
layer.BitmapEffect = new DropShadowBitmapEffect { Color = Colors.Black, ShadowDepth = 3, Opacity = 0.5 }; 
context.DrawDrawing(layer); 

Questo disegna tutto all'interno della layer correttamente, ma senza l'effetto ombra.

Cosa sto facendo male/in quale altro modo potrei applicare un'ombra esterna a un gruppo di primitive in un DrawingContext?

risposta

2

BitmapEffect è una vecchia proprietà (hanno utilizzato effetti di rendering della CPU) dalla versione 3.5 di .NET. La proprietà has no effect in 4.0.

In 4.0 è necessario utilizzare la proprietà Effect, che utilizza Pixel Shader.

DrawingGroup tuttavia non sembra avere una proprietà di effetto - sembra che potrebbe essere necessario set the effect on the parent UI element instead.

+1

Hmm ... Non ho un elemento dell'interfaccia utente padre; questo 'DrawingGroup' è reso direttamente in un' RenderTargetBitmap'. Strano come devo usare gli elementi dell'interfaccia utente per il rendering puro, eh? ... –

+0

Non penso che sia strano - quando si crea una bitmap in memoria, non è stata inviata alla GPU, e quindi la GPU non lo fa arrivare a eseguire i pixel shader. Il vecchio 'BitmapEffects' non usava pixel shader, essi giravano sulla CPU, ed è per questo che hanno lavorato in questo caso. BitmapEffects era però troppo lento la maggior parte del tempo, ed è per questo che sono obsoleti. –

+0

In questa situazione puoi probabilmente usare il gruppo di disegno per riempire un rettangolo e rendere il rettangolo a RenderTargetBitmap (non dimenticare di ridimensionare prima l'elemento) - che dovrebbe (penso) invocare la GPU per chiamare lo shader. –

-3

Se siete in esecuzione su .NET Framework 3.5 SP1 o superiore, è necessario utilizzare UIElement.Effect o Visual.VisualEffect (questo è protetto in modo si avrebbe bisogno di ricavare da esso), invece, con un'istanza di System.Windows.Media.Effects.DropShadowEffect.

+0

Un 'DrawingGroup' non è né un 'Visual' né un' UIElement', quindi dove applico quell'effetto? –

+0

@romkyns - sì, perché DrawingGroup è un concetto di gerarchia/albero, non un concetto "visivo". Cosa metti nel tuo gruppo? Devi avere qualcosa di "visivo" che servirà da base per l'ombra esterna. –

+1

Disegna cose come immagini e primitive nel mio 'DrawingGroup' (usando il codice che ho citato nella domanda). Quindi lo renderizzo usando 'DrawDrawing'. Mi piacerebbe fare lo stesso, ma avere tutto dentro il 'DrawingGroup' per gettare un'ombra. –