Отримання текстури від рендербуфера в OpenGL?


13

У мене є рендербуфер (DepthStencil) у ФБО, і мені потрібно отримати текстуру від нього. Я не можу мати як текстуру DepthComponent, так і рендербуфер DepthStencil у FBO, здається, тому мені потрібен певний спосіб перетворити рендербуфер у текстуру DepthComponent після того, як я закінчую його використання для використання пізніше в конвеєрі.

Я випробував безліч методів, щоб схопити компонент глибини з рендербуфера протягом тижнів, але завжди виходжу зі сміттям. Все, що я хочу в кінці, - це одна і та ж текстура, яку я отримав би від ФБО, якби я не використовував рендербуфер. Чи може хтось опублікувати якісь вичерпні інструкції чи код, який охоплює цю, здавалося б, просту операцію?

Редагувати:

Посилання на витягну версію коду http://dl.dropbox.com/u/9279501/fbo.cs

Екран ефекту Глибина поля + FBO - без глибини (!) Http://i.stack.imgur.com/Hj9Oe.jpg

Екранний без ефекту Глибина поля + FBO - глибока робота http://i.stack.imgur.com/boOm1.jpg

Відповіді:


2

Крім того, ви можете просто переходити від одного FBO до іншого, наприклад, від рендербуфера до текстурного. Я роблю це так:

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

(У вашому випадку, де ви хочете поглибити буфер, ви можете використовувати GL_DEPTH_BUFFER_BIT замість GL_COLOR_BUFFER_BIT)

Після промацування текстури на основі текстури, ви можете використовувати текстуру як звичайну; передаючи його в шейдери як уніформу або що завгодно.


1

Ні, це неможливо. Максимум, ви можете glReadPixels отримати дані до процесора та створити їх текстуру, але це буде громіздко і повільно. Renderbuffers не призначені для цього, а функціональність забезпечується лише текстурами.


Враховуючи це, яка альтернатива? Як можна зберегти глибину буфера малювання, а також придбати компонент глибини як текстуру?
Rushyo

@Rushyo: Альтернативою може бути позбавлення від буфера трафарету (якщо це можливо!) І зробити рендеринг глибини текстурою глибини. Для чого ви використовуєте трафарет?
Calvin1602

По суті, коли я набуваю текстуру глибини, мої глибинні випробування перериваються. Якщо я додаю вкладення на глибину до свого ФБО, ФБО не записує жодної інформації про глибину в іншому місці - тому, коли я намагаюся отримати кольоровий додаток, на ньому не проводиться глибоке тестування (що, як правило, є, якщо я не маю глибинного вкладення ). Я випробував будь-яку комбінацію, про яку я можу придумати, включаючи вищезгаданий метод «громіздкий і повільний». Що б я не робив, я не можу отримати як "типовий" вигляд моєї сцени в одній текстурі, так і глибину в іншій.
Rushyo

@ Calvin1602 Коли я справлявся з рендербуфером, я виявив, що використання кріплення глибини без вкладення трафарету дало небажані результати.
Rushyo

@Rushyo Б'юсь об заклад, ви не правильно налаштували текстуру, розміщення коду дозволить нам допомогти :)
Matias Valdenegro

1

Те, що ви запитуєте, можливо у OpenGL 3.2. У мене FBO виплюнув розсіяний колір на кольорову текстуру, нормальний на іншу кольорову текстуру і глибину на глибину текстури - не потрібні візуалізатори. Насправді рендербуфери - це лише проблема, тому що ви не можете зробити вибірку з них, тому вам доведеться використовувати glReadPixels(...)або іншим чином якось скопіювати дані з RBO та передати текстуру на процесор, а не просто підтримувати все в пам'яті GPU. Так...

Якщо ви дійсно хочете, ви можете написати код у вашому шейдері першого проходу, щоб вручну виводити такі речі, як глибина, до окремої вкладки кольорової текстури у вашому FBO. Це було б для використання вами у ваших шейдерах після проходу. Для використання OpenGL у його внутрішньому глибинному тестуванні вам додатково знадобиться або RBO, або набір текстур як GL_DEPTH_ATTACHMENT вашого FBO. Але ви можете налаштувати одну текстуру для обслуговування обох - це більш ефективно та простіше у використанні.

Мій код настройки текстури глибини виглядає приблизно так (Java, просто ігноруйте речі ByteBuffer ... і зауважте, що я використовую "id" для позначення цілих ручок / покажчиків, оскільки ця концепція не дуже добре відповідає 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);

І пізніше:

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

Тепер ви можете передати gBufferDepthTexture(або що у вас є) уніформу вашим другим, третім прохідним шейдерам. Я думаю, ми можемо сміливо припустити, що ви можете зробити те саме, що і з буфером трафарету.


0

Ви повинні мати змогу створити текстуру (замість RenderBuffer), використовуючи формат GL_DEPTH_STENCIL. Я не впевнений у точному процесі використання глибини такої текстури у програмі шейдерів (який, я вважаю, ви використовуєте, оскільки ви використовуєте FBO), але специфікація OpenGL повинна вказати, які кольорові канали отримують, які значення ( я гадаю, що R, G і B всі встановлюються на глибину, а A встановлюється за трафаретом).

Цього дня я націлюю OpenGL 3.2, тому вам може знадобитися переконатися, що формат текстури для вас справний. Я ніколи не можу згадати, які версії вводять різні функції.


Проблема тоді полягає не в тому, щоб зафіксувати компонент GL_DEPTH_STENCIL текстурою, а те, що вся інформація про глибину втрачається у FBO, коли ви це робите. ФБО стає марним для того, щоб потім передати сцену в буфер нічиї. Отже, я використовував Renderbuffer в надії обійти цю проблему. Я думаю, що зараз у мене немає іншого можливості, як зробити два проходи, щоб схопити глибину + намалювати інформацію окремо = (дорого-як-до-пекло, поки я не зможу знайти спосіб її
подорожі

@Rushyo Я опублікував відповідь на це давнє запитання :) Можливо, ви захочете поглянути, хоча ви, мабуть, вирішили це років тому.
Інженер

@NickWiggill Я бажаю! Щось розім’яв і продовжив своє життя. Насправді не можна перевірити вашу відповідь, поки я не відтворять активи, які я використовував у цьому прототипі. Можливо, в якийсь момент
обійдусь цим
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.