eConti - программирование в вопросах и ответах

Как я могу сохранить ранее визуализированный из фрагментного шейдера OpenGL для последующего использования?

Я пишу плагин видеоэффектов FFGL (используя этот порт шейдерта). Я хочу сохранить ранее обработанный кадр для использования в будущих вычислениях. В частности, я пытаюсь сделать эквивалент задержки видео.

Можно ли записать во внешний буфер из фрагментного шейдера, а затем использовать это сохраненное значение позже (скажем, через 30 кадров)?


  • Конечно. Рендерим в текстуру, а затем используем текстуру в качестве входных данных. 04.02.2018

Ответы:


1

вы создаете FBO и привязываете его. все, что вы визуализируете дальше, попадает на него. поэтому, если вы используете шейдер, это по-прежнему применимо к FBO по умолчанию.

вот некоторый код, чтобы помочь вам

import java.nio.ByteBuffer;

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL14.*;
import static org.lwjgl.opengl.GL30.*;

public class FBO {
    public int fbo,tex,depth;

    public void delete() {glDeleteTextures(tex);glDeleteRenderbuffers(depth);glDeleteFramebuffers(fbo);}
    public void bindTexture() {glBindTexture(GL_TEXTURE_2D,tex);}
    public void bind() {glBindFramebuffer(GL_FRAMEBUFFER,fbo);}
    public static void unbind() {glBindFramebuffer(GL_FRAMEBUFFER,0);}

    public FBO(){ // create the fbo
        glBindTexture(GL_TEXTURE_2D,tex=glGenTextures()); // create texture, set correct filters
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);

        glBindRenderbuffer(GL_RENDERBUFFER,depth=glGenRenderbuffers()); // create buffer for depth

        glBindFramebuffer(GL_FRAMEBUFFER,fbo=glGenFramebuffers()); // create framebuffer
        glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,tex,0); // attach texture
        glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_RENDERBUFFER,depth); // attach depth
        unbind(); // incase not using immediately
    }

    public void resize(int w,int h) {
        glBindTexture(GL_TEXTURE_2D,tex); // update texture size
        glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,w,h,0,GL_RGBA,GL_UNSIGNED_BYTE,(ByteBuffer)null);
        glBindRenderbuffer(GL_RENDERBUFFER,depth); // update depth size
        glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH_COMPONENT24,w,h);
    }

    public void render() {
//      glColor4f(1,1,1,1); // you may want to do these customly
//      glDisable(GL_BLEND);

        glBindTexture(GL_TEXTURE_2D, tex);
        Tess.begin();
        Tess.vertex(    0, height, 0, 0, 0);
        Tess.vertex(width, height, 0, 1, 0);
        Tess.vertex(width,      0, 0, 1, 1);
        Tess.vertex(    0,      0, 0, 0, 1);
        Tess.draw();
        // Tess btw, just manually handles verts and tex coords
        // that could be pure pipeline, or by vbo / vao / interleaved vbo
        // width / height are just the 2d size. could render for post processing
    }
}
04.02.2018
  • Превосходно! Благодарю вас! Дополняющий вопрос. Если я хочу, чтобы текстура заполнялась только каждые n кадров, есть ли способ, чтобы шейдер знал, сколько кадров прошло с момента последней записи в текстуру? то есть для эффекта, над которым я работаю, потребуется параметризованное значение задержки (в кадрах или времени). Эффект будет использовать эту сохраненную текстуру при каждом проходе в шейдере, НО будет устанавливать шейдер только после n-кадров. 11.02.2018
  • звучит так, как будто вы просто хотите ограничить рендеринг fps для fbo. Правильно? 11.02.2018
  • если вы хотите рисовать только каждые n кадров, вы можете просто сделать n++; n%=10 (или сколько угодно); если(n==0) ничья. я не думаю, что вы можете просто сказать opengl сделать это. вам придется управлять этим на вашем реальном языке. 11.02.2018
  • Новые материалы

    ИИ для общего блага, часть вторая
    В нашем последнем блоге мы исследовали возможности ИИ для общего блага, указав на несколько инициатив по поиску действенных решений для продвижения справедливых и беспристрастных систем ИИ. По..

    Время расцвета закончилось
    Большую часть своей карьеры в индустрии программного обеспечения программисты работали с головой в песок. Успех в отрасли требует навыков презентации и обучения других. Ценность улучшенных..

    Будущее сельского хозяйства: новый уровень производительности с современными технологиями
    По мере роста населения мира растет и спрос на продукты питания. Фермеры сталкиваются с растущим давлением необходимости повышать урожайность и максимизировать производительность, манипулируя..

    Состояние совместной фильтрации в 2022 году, часть 1
    ResBeMF: Улучшение прогнозируемого охвата совместной фильтрации на основе классификации (arXiv) Автор: Анхель Гонсалес-Прието , Авраам Гутьеррес , Фернандо Ортега , Рауль Лара-Кабрера..

    Зачем изучать PYTHON в 2022 году !
    Python — востребованный, доступный язык программирования с активным, постоянно растущим сообществом пользователей. Для тех, кто хочет сменить профессию в мире технологий с помощью..

    Решение капч с помощью Puppeteer
    Это руководство предназначено для текстовых кодов, а не для reCAPTCHA Google (см. конец этого сообщения). Требования: Антикапча или любой другой сервис по разгадыванию капчи. Модуль..

    7 встроенных библиотек Python, которые необходимо знать
    7 встроенных библиотек Python, которые необходимо знать Стандартная библиотека Python значительно упрощает жизнь программистов, предоставляя широкий набор функций. Мы выбираем несколько..