Ottenere una trama da un renderbuffer in OpenGL?


13

Ho un renderbuffer (DepthStencil) in un FBO e ho bisogno di ricavarne una trama. A quanto pare, non posso avere sia una trama DepthComponent che un renderbuffer DepthStencil nell'FBO, quindi ho bisogno di un modo per convertire il renderbuffer in una trama DepthComponent dopo che ho finito con esso per usarlo successivamente nella pipeline.

Ho provato molte tecniche per afferrare il componente di profondità dal renderbuffer per settimane, ma esco sempre con la spazzatura. Tutto quello che voglio alla fine è la stessa trama che otterrei da un FBO se non usassi un renderbuffer. Qualcuno può pubblicare alcune istruzioni complete o codice che copre questa operazione apparentemente semplice?

MODIFICARE:

Collegato a una versione di estrazione del codice http://dl.dropbox.com/u/9279501/fbo.cs

Effetto Screeny of the Depth of Field + FBO - senza profondità (!) Http://i.stack.imgur.com/Hj9Oe.jpg

Screeny senza effetto Profondità di campo + FBO - profondità funzionante bene http://i.stack.imgur.com/boOm1.jpg

Risposte:


2

In alternativa, puoi semplicemente passare da un FBO a un altro, ad esempio da uno basato su renderbuffer a uno basato su trama. Lo faccio in questo modo:

glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_renderBufferSurface->m_fbo);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_textureSurface->m_fbo);
glBlitFramebufferEXT(0, 0, m_renderBufferSurface->m_width, m_renderBufferSurface->m_height, 0, 0, m_textureSurface->m_width, m_textureSurface->m_height, GL_COLOR_BUFFER_BIT, GL_NEAREST);

(Nel tuo caso, dove vuoi approfondire il buffer, puoi usare GL_DEPTH_BUFFER_BIT invece di GL_COLOR_BUFFER_BIT)

Dopo aver eseguito il blitting nel renderbuffer basato su texture, puoi usare la texture normalmente; passandolo negli shader come uniforme o come preferisci.


1

No, non è possibile. Al massimo puoi glReadPixels i dati sulla CPU e crearne una trama, ma sarà ingombrante e lento. I renderbuffer non sono pensati per questo, quella funzionalità è fornita solo dalle trame.


Detto questo, qual è l'alternativa? Come è possibile mantenere la profondità nel buffer di disegno e acquisire anche il componente di profondità come trama?
Rushyo,

@Rushyo: Un'alternativa potrebbe essere quella di sbarazzarsi del buffer di stencil (se possibile!) E rendere il renderbuffer di profondità una trama di profondità. Perché stai usando uno stencil?
Calvin1602,

Essenzialmente ogni volta che acquisisco la trama di profondità, i miei test di profondità si interrompono. Se allego un allegato di profondità al mio FBO, l'FBO non scrive alcuna informazione di profondità altrove, quindi quando provo a recuperare l'allegato di colore non viene eseguito alcun test di profondità (che normalmente accade se non ho un allegato di profondità ). Ho provato tutte le combinazioni che mi vengono in mente, incluso il suddetto metodo "ingombrante e lento". Qualunque cosa faccia, non riesco a ottenere sia un rendering "tipico" della mia scena in una trama, sia la profondità in un'altra.
Rushyo,

@ Calvin1602 Quando mi dilettavo con il renderbuffer, ho scoperto che l'uso dell'allegato di profondità senza l'attacco stencil produceva risultati indesiderati.
Rushyo,

@Rushyo Scommetto che non stai impostando correttamente la trama, la pubblicazione di codice ci permetterà di aiutarti :)
Matias Valdenegro

1

Quello che stai chiedendo è possibile in OpenGL 3.2. Ho il mio FBO che distribuisce il colore diffuso a una trama a colori, le normali a un'altra trama a colori e la profondità a una trama a profondità, senza bisogno di renderbuffer. In effetti i renderbuffer sono solo un problema, perché non puoi campionarli, quindi dovresti usare glReadPixels(...)o in qualche modo copiare i dati dall'RBO e in una trama sulla CPU, invece di mantenere tutto nella memoria GPU. Così...

Se vuoi davvero, puoi scrivere il codice nel tuo shader di primo passaggio per produrre manualmente cose come la profondità, su un allegato di trama di colore separato nel tuo FBO. Sarebbe utile per te nei tuoi shader post pass. Per l' utilizzo di OpenGL nei test di profondità interni, è inoltre necessario un RBO o un set di texture come GL_DEPTH_ATTACHMENT dell'FBO. Ma puoi impostare una singola trama per servire entrambi - questo è più efficiente e più facile da usare.

Il mio codice di configurazione della trama di profondità è simile al seguente (Java, ignoro solo le cose di ByteBuffer ... e nota che uso "id" per fare riferimento a handle / puntatori di numeri interi, dal momento che quel concetto non si adatta bene a Java):

        gBufferDepthTexture = new Texture();
        gBufferDepthTexture.id = glGenTextures();
        gBufferDepthTexture.unit = 2;
        gBufferDepthTexture.width = Display.getWidth();
        gBufferDepthTexture.height = Display.getHeight();
        gBufferDepthTexture.bytes = ByteBuffer.allocateDirect(Display.getWidth()*Display.getHeight() * 4);
        glActiveTexture(gBufferDepthTexture.unit + GL_TEXTURE0); //eg. 0 + 33984 = GL_TEXTURE0, while 31 + 33984 = GL_TEXTURE31.
        glBindTexture(GL_TEXTURE_2D, gBufferDepthTexture.id);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, gBufferDepthTexture.width, gBufferDepthTexture.height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, gBufferDepthTexture.bytes);
        //...GL_UNSIGNED_INT or GL_UNSIGNED_BYTE may work better for you, instead... YMMV.

        //glPixelStorei(GL_PACK_ALIGNMENT, 4);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

E più tardi:

        glBindFrameBuffer(GL_DRAW_FRAMEBUFFER, fbo.id);
        //your existing glFramebufferTexture2D(...) calls here
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, gBufferDepthTexture.id, 0);

Ora puoi passare gBufferDepthTexture(o cosa hai) in uniforme al tuo secondo, terzo passaggio shader di frammenti. Penso che possiamo tranquillamente presumere che tu possa fare esattamente la stessa cosa con il buffer di stencil.


0

Dovresti essere in grado di creare una trama (anziché un RenderBuffer) usando il formato GL_DEPTH_STENCIL. Non sono sicuro del processo esatto per usare la profondità da una trama simile in un programma shader (che presumo tu stia usando, dal momento che stai usando gli FBO), ma le specifiche OpenGL dovrebbero specificare quali canali di colore ottengono quali valori ( la mia ipotesi sarebbe che R, G e B siano tutti impostati sulla profondità e che A sia impostato sullo stencil).

Oggi mi rivolgo a OpenGL 3.2, quindi potrebbe essere necessario verificare che il formato della trama sia fattibile per te. Non ricordo mai quali versioni introducono funzionalità diverse.


Il problema non è quindi quello di acquisire il componente GL_DEPTH_STENCIL in una trama, ma il fatto che tutte le informazioni sulla profondità vanno perse nell'FBO ogni volta che lo fai. L'FBO diventa inutile per il rendering della scena nel buffer di disegno. Quindi stavo usando un Renderbuffer nella speranza di aggirare questo problema. Penso che per ora non ho altra scelta che fare due passaggi per afferrare la profondità + disegnare informazioni separatamente = (costoso come l'inferno fino a quando non riesco a trovare un modo per
aggirarlo

@Rushyo Ho pubblicato una risposta a questa antica domanda :) Potresti dare un'occhiata, anche se probabilmente hai risolto questi anni fa.
Ingegnere

@NickWiggill I wish! Sfumò qualcosa e andò avanti con la mia vita. Non posso effettivamente testare la tua risposta fino a quando non ricreare le risorse che ho usato in questo prototipo. Potrebbe
aggirarlo
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.