2012-11-12 10 views
6

Sto cercando un modo per leggere un colore di pixel al punto. In OpenGL è stato fatto chiamando la funzione "glReadPixels" dopo aver disegnato la scena (o parti di essa). Voglio fare una semplice routine di selezione del colore in background, per identificare forme/linee in 3D Space.Una funzione come "glReadPixels" in DirectX/SharpDX

Quindi, c'è qualche metodo/funzione/suggerimento equivalente per fare lo stesso in SharpDX (DirectX10/DirectX11)?

risposta

8

Questo è perfettamente possibile con Direct3D11: è sufficiente attenersi alla seguente procedura:

  • Usa DeviceContext.CopySubResourceRegion per copiare parte dalla consistenza di origine a una messa in scena trama (dimensione dell'area di pixel che si desidera di rilettura, stesso formato, ma con ResourceUsage.Staging)
  • Recupera il pixel da questa trama di staging utilizzando Device.Map/UnMap.

C'è un sacco di discussione su questo tema in giro per la rete (ad esempio: "Reading one pixel from texture to CPU in DX11")

+0

È possibile qualcosa del genere in DX9? – jjxtra

1

Poiché si utilizza C#, il mio suggerimento sarebbe di utilizzare GDI +, in quanto non esiste alcuna funzione come "glReadPixels" in DX. GDI + offre metodi molto semplici per leggere il colore di un pixel sul puntatore del mouse. Fare riferimento a stackoverflow.com/questions/1483928.

Se GDI + è un no-go, in quanto non è molto veloce, non è possibile attenersi al solito prelievo di oggetti utilizzando un "raggio"? Vuoi identificare (suppongo forme/linee tridimensionali), sarebbe facile usare un raggio (e controllare l'intersezione) per selezionarli.

+0

[..] oggetto picking utilizzando un "Ray" [..] - questo è stato il mio pensiero secolare, ma ho pensato, se c'è qualche funzione come "ReadPixels", potrei usarlo - in alcuni casi, colour picking può essere molto buono, ma hai ragione, per i miei bisogni, i raggi farebbero il lavoro. E, GDI + - non ho pensato a questo .. ma hai ragione, dopo il rendering, posso leggere il pixel dal controllo - perché vorrei leggere solo un pixel per frame/aggiornamento, la velocità non è così importante . Grazie per la tua risposta :) – lunatix

+0

Quindi, ho provato a implementare il suggerimento GDI + (voglio provarlo, e funziona bene :)) ma c'è rimasto un problema - ho una finestra WPF con WindowsFormsHost e un pannello in esso, disegnando per i pannelli gestire tramite DirectX.Ma ottengo solo il backcolor di quel pannello, non quello che è veramente lì =/Se utilizzo la finestra del desktop, ottengo i miei colori .. qualche soluzione per questo = /? – lunatix

+0

Quindi, ho una soluzione: proietto le coordinate del mouse sullo spazio dello schermo e utilizzo il pixel "desktop" - così, quando la mia finestra è in cima, ottengo il pixel riacquisito. La soluzione è Ok, ma preferirei usare il pannello di output "reale". – lunatix

2

Un'altra opzione è quella di utilizzare una piccola shader di calcolo, come:

Texture2D<float4> TextureInput: register(t0); 
StructuredBuffer<float2> UVBuffer: register(t1); 
RWStructuredBuffer<float4> RWColorBuffer : register(u0); 

SamplerState Sampler : register(s0); 

[numthreads(1, 1, 1)] 
void CSGetPixels(uint3 DTid : SV_DispatchThreadID) 
{ 
float4 c = TextureInput.SampleLevel(Sampler , UVBuffer[DTid.x].xy, 0); 
RWColorBuffer [DTid.x] = c; 
} 

Dà hai il vantaggio di essere un po 'più "formato agnostico".

Il processo è quindi così.

  • Creare un buffer strutturato piccolo per UV (float2) (posizione pixel/dimensione della trama, non dimenticare di capovolgere l'asse Y, naturalmente). Copia la posizione dei pixel che vuoi campionare in questo buffer.
  • Creare un buffer scrivibile e un buffer di staging (float4). Deve essere lo stesso conteggio degli elementi del tuo buffer uv.
  • Lega tutto e Invio
  • Copia buffer scrivibile in staging.
  • Mappa e leggere i dati in float4 cpu

Si prega di notare ho omesso gruppo di thread di ottimizzazione/controlli a Compute Shader per semplicità.

+0

Interresting e nice one o_o Metterò alla prova questo se ho tempo per :) In realtà, ho implementato un alkorythm ray picking con test di intersezione :) – lunatix

Problemi correlati