Domanda

Ho del codice OpenGL che si comporta in modo incoerente tra diversi hardware. Ho del codice che:

  1. Crea un buffer di rendering e associa una trama al suo buffer di colore (Texture A)
  2. Imposta questo buffer di rendering come attivo e regola il viewport, ecc.
  3. Attiva un pixel shader (sfocatura gaussiana, in questo caso).
  4. Disegna un quad a schermo intero, con la trama A su di esso.
  5. Rimuove il renderbuffer, ecc.

Sulla mia macchina di sviluppo funziona benissimo e ha lo scopo effetto di sfocare la trama "in atto", tuttavia su altro hardware questo non sembra funzionare.

Ho ottenuto due possibilità.

A) Il rendering di un renderbuffer su se stesso non dovrebbe funzionare e funziona solo sulla mia macchina di sviluppo a causa di una sorta di colpo di fortuna.

o

B) Questo approccio dovrebbe funzionare, ma qualcos'altro sta andando storto.

Qualche idea? Onestamente ho avuto difficoltà a trovare dettagli su questo problema.

È stato utile?

Soluzione

A) è la risposta corretta. Il rendering nello stesso buffer durante la lettura da esso non è definito. Potrebbe funzionare, potrebbe non farlo - che è esattamente ciò che sta accadendo.

Nel caso di OpenGL, framebuffer_object extension ha sezione "4.4.3 Rendering quando un'immagine di un oggetto Texture associato è anche collegata al Framebuffer" che dice cosa succede (sostanzialmente, indefinito). In Direct3D9, il runtime di debug si lamenta rumorosamente se si utilizza tale impostazione (ma potrebbe funzionare a seconda dell'hardware / del driver). In D3D10 il runtime separa sempre il target utilizzato come destinazione, credo.

Perché questo non è definito? Uno dei motivi per cui le GPU sono così veloci è che possono fare molte ipotesi. Ad esempio, possono presumere che le unità che prendono pixel non debbano comunicare con unità che scrivono pixel. Quindi una superficie può essere letta, N cicli dopo il completamento della lettura, N cicli dopo il pixel shader termina la sua esecuzione, quindi inserisce alcuni buffer di unione di output sulla GPU, e infine a un certo punto viene scritto in memoria. Inoltre, le GPU si rasterizzano in "non definito". ordine (una GPU potrebbe rasterizzarsi in righe, un'altra in un ordine compatibile con la cache, un'altra in un altro ordine), quindi non sai in quali parti della superficie verrà scritta per prima.

Quindi, ciò che dovresti fare è creare diversi buffer. In caso di sfocatura / bagliore, due sono in genere sufficienti: esegui prima il rendering, quindi leggi & amp; sfocatura che mentre si scrive al secondo. Ripetere questo processo se necessario in modo ping-pong.

Altri suggerimenti

In alcuni casi speciali, anche il backbuffer potrebbe essere sufficiente. Semplicemente non fai un glClear, e ciò che hai disegnato in precedenza è ancora lì. L'avvertenza è, ovviamente, che non puoi davvero leggere dal backbuffer. Ma per effetti come dissolvenza in entrata e in uscita, funziona.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top