2013-04-19 8 views
8

Voglio copiare texture1 in texture2. Il modo più stupido è copiare i dati tex1 dalla GPU alla CPU e quindi copiare i dati della CPU in GPU. Il codice stupido è come qui sotto:Come copiare texture1 in texture2 in modo efficiente?

float *data = new float[width*height*4]; 
glBindTexture(GL_TEXTURE_2D, tex1); 
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, data); 
glBindTexture(GL_TEXTURE_2D, tex2]); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, data); 

Per quanto ne so, deve esistere un metodo che supporta la copia dei dati da GPU tex a GPU tex Senza CPU coinvolti. Considero di usare FBO che esegue il rendering di un tex1 quad in tex2. Ma in qualche modo penso che sia ancora ingenuo. Quindi qual è il modo più efficace per implementarlo?

+0

glCopyTexImage2D? –

+1

glCopyTexImage2D copia dal buffer colore alla trama. Penso che dovrebbe avere un modo per evitare il rendering nel buffer del colore o nel frame buffer. – rtrobin

+0

Il buffer colore in FBO può essere anche una texture. –

risposta

11

Se si dispone di supporto per OpenGL 4.3, v'è la straight-forward glCopyImageSubData proprio per questo scopo:

glCopyImageSubData(tex1, GL_TEXTURE_2D, 0, 0, 0, 0, 
        tex2, GL_TEXTURE_2D, 0, 0, 0, 0, 
        width, height, 1); 

Naturalmente questo richiede la texture destinazione da già stanziati con un'immagine di dimensioni e formato appropriato (usando un semplice glTexImage2D(..., nullptr), o forse ancora meglio glTexStorage2D se hai GL 4 comunque).


Se non si dispone di quello, quindi il rendering di una trama nell'altro utilizzando un FBO potrebbe essere ancora l'approccio migliore. Alla fine non hai nemmeno bisogno di renderizzare la texture sorgente. È possibile collegare entrambe le trame a un FBO e inserire un solo colore nell'altro utilizzando glBlitFramebuffer (core da OpenGL 3 o con GL_EXT_framebuffer_blit extension in 2.x, praticamente ovunque siano gli FBO):

glBindFramebuffer(GL_FRAMEBUFFER, fbo); 
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
         GL_TEXTURE_2D, tex1, 0); 
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, 
         GL_TEXTURE_2D, tex2, 0); 
glDrawBuffer(GL_COLOR_ATTACHMENT1); 
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, 
        GL_COLOR_BUFFER_BIT, GL_NEAREST); 

Ovviamente se lo fai più volte, potrebbe essere una buona idea mantenere vivo questo FBO. Allo stesso modo, ciò richiede anche che l'immagine della trama di destinazione abbia le dimensioni e il formato appropriati in anticipo. Oppure puoi anche utilizzare il suggerimento di Michael di allegare solo la texture di origine all'FBO e fare un buon vecchio glCopyTex(Sub)Image2D nella trama di destinazione. Ha bisogno di essere valutato che si comporta meglio (se presente).


E se non hanno nemmeno bisogno che uno, allora si potrebbe ancora usare il tuo approccio di leggere una consistenza e la scrittura che i dati nell'altro. Ma invece di utilizzare la memoria della CPU come buffer temporaneo, utilizzare un pixel buffer object (PBO) (core da OpenGL 2.1). Avrai ancora una copia aggiuntiva, ma almeno questa sarà (o è probabile che sia) una copia GPU-GPU.

+0

Sei sicuro che questa funzione non sia disponibile anche per 4.0, 4.1, 4.2? –

+1

@MichaelIV Probabilmente è disponibile per qualsiasi 4.x da un'estensione core back-ported (ma è solo core in 4.3), ma poi di nuovo, scegliere tra un particolare 4.x è di solito solo una domanda di driver. Se hai 4.1, è probabile che tu abbia 4.3 dopo aver istallato i driver più recenti (dato che stai usando l'hardware con driver ragionevoli in primo luogo, come xXxxxx, e non qualcosa come XXX spazzatura;)). –

+0

@Christian Rau. fantastico! Penso che tu spieghi tutto. Inoltre, voglio chiedere: 1).Devo creare il contesto GL4 o GL3 per utilizzare i primi due metodi? O potrei semplicemente usare queste funzioni nel mio codice esistente? 2). La mia scheda grafica supporta OpenGL3.3. Quindi glCopyImageSubData non è disponibile per me in ogni caso? Ho trovato la funzione [CopyImageSubDataNV] (http://www.opengl.org/registry/specs/NV/copy_image.txt). È disponibile per la mia carta? – rtrobin

Problemi correlati