2013-04-19 8 views
8

Chcę skopiować texture1 do texture2. Najbardziej głupim sposobem jest kopiowanie danych tex1 z procesora graficznego do procesora, a następnie kopiowanie danych procesora na GPU. Głupi Kod jest jak poniżej:Jak skutecznie skopiować texture1 do texture2?

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); 

tego co wiem, to musi istnieć sposób, który obsługuje kopiowania danych z tex GPU tex GPU bez CPU zaangażowanych. Zastanawiam się nad wykorzystaniem FBO, które renderuje tex1 quad do tex2. Ale jakoś myślę, że to wciąż jest naiwne. Jaki jest najskuteczniejszy sposób wdrożenia tego?

+0

glCopyTexImage2D? –

+1

glCopyTexImage2D kopiowanie z bufora kolorów do tekstury. Myślę, że powinien mieć sposób, który unika renderowania do bufora kolorów lub bufora ramki. – rtrobin

+0

Bufor kolorów w FBO może być również teksturą. –

Odpowiedz

11

Jeśli masz wsparcie dla OpenGL 4.3, jest dokładnie tym celu prosta glCopyImageSubData:

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

Oczywiście wymaga to docelowy teksturę już zostać przydzielone z obrazem odpowiedniego rozmiaru i formatu (używając zwykłego glTexImage2D(..., nullptr), a może nawet lepiej glTexStorage2D, jeśli mimo to masz GL 4).

Jeśli tego nie zrobisz, to najlepszym sposobem będzie nadal renderowanie jednej tekstury do drugiej przy użyciu FBO. Na końcu nie trzeba nawet renderować tekstury źródłowej. Możesz po prostu dołączyć obie tekstury do pliku FBO i przenieść jeden kolorowy załącznik do drugiego przy użyciu glBlitFramebuffer (rdzeń od OpenGL 3 lub z rozszerzeniem GL_EXT_framebuffer_blit w 2.x, praktycznie wszędzie tam, gdzie znajdują się pliki 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); 

Oczywiście, jeśli robisz to wiele razy, dobrym pomysłem może być utrzymanie tego pliku FBO przy życiu. Podobnie również wymaga to, aby docelowy obraz tekstury miał wcześniej odpowiedni format i format. Możesz także użyć sugestii, aby Michael dołączyć teksturę źródłową do FBO i zrobić dobrą starą glCopyTex(Sub)Image2D w docelowej teksturze. Wymaga oceny, która działa lepiej (jeśli występuje).


A jeśli nawet nie masz tego, to możesz nadal używać swojego podejścia do czytania jednej tekstury i zapisywania tych danych w drugiej. Ale zamiast używać pamięci procesora jako tymczasowego bufora, użyj pixel buffer object (PBO) (rdzeń od OpenGL 2.1). Nadal będziesz mieć dodatkową kopię, ale przynajmniej będzie to (lub prawdopodobnie będzie) kopia GPU-GPU.

+0

Czy jesteś pewien, że ta funkcja nie jest dostępna również dla wersji 4.0, 4.1, 4.2? –

+1

@MichaelIV Najprawdopodobniej jest dostępny dla każdego 4.x przez back-port core extension (ale jest to tylko rdzeń w 4.3), ale potem znowu, wybierając między konkretnym 4.x jest zwykle pytanie kierowca tak czy inaczej. Jeśli masz 4.1, prawdopodobnie masz 4.3 po zainstalowaniu najnowszych sterowników (biorąc pod uwagę, że używasz sprzętu z rozsądnymi sterownikami, np. XXxxxx, a nie czymś takim jak XXX śmieci;)). –

+0

@ Christian Rau. sooooo świetnie! Myślę, że wszystko wyjaśniasz. Ponadto chcę zapytać: 1).Czy muszę utworzyć kontekst GL4 lub GL3, aby użyć dwóch pierwszych metod? Czy mógłbym po prostu użyć tych funkcji w moim istniejącym kodzie? 2). Moja karta graficzna obsługuje OpenGL3.3. A więc czy glCopyImageSubData jest dla mnie niedostępna? Znalazłem funkcję [CopyImageSubDataNV] (http://www.opengl.org/registry/specs/NV/copy_image.txt). Czy jest to dostępne dla mojej karty? – rtrobin

Powiązane problemy