Запустите несколько шейдеров OpenGL на CVImageBuffer - PullRequest
4 голосов
/ 30 марта 2011

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

Не имея момента с Эврикой, я сейчас застрял :). Код для компиляции и связывания шейдеров не показан для краткости. Все это рендерится (успешно - но один шейдер перезаписывает другой - так что пропускает жизненно важный шаг) в слой, совместимый с GL, и под ним располагается UIToolbar, который, в конце концов, будет иметь кнопку для каждого шейдера и кнопку для запуска всех шейдеров.

Спасибо

Simon

-(void) DrawFrame:(CVImageBufferRef)cameraframe;
{
    int bufferHeight = CVPixelBufferGetHeight(cameraframe);
    int bufferWidth = CVPixelBufferGetWidth(cameraframe);

    // Create a new texture from the camera frame data, display that using the shaders
    glGenTextures(1, &videoFrameTexture);
    glBindTexture(GL_TEXTURE_2D, videoFrameTexture);
    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_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    // Using BGRA extension to pull in video frame data directly
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bufferWidth, bufferHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, CVPixelBufferGetBaseAddress(cameraframe));

    static const GLfloat squareVertices[] = {
        -1.0f, -1.0f,
        1.0f, -1.0f,
        -1.0f,  1.0f,
        1.0f,  1.0f,
    };

    static const GLfloat textureVertices[] = {
        1.0f, 1.0f,
        1.0f, 0.0f,
        0.0f,  1.0f,
        0.0f,  0.0f,
    };

    [self setDisplayFramebuffer];

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, videoFrameTexture);

    // Update uniform values
    glUniform1i(uniforms[UNIFORM_VIDEOFRAME], 0);   

    // Update attribute values.
    glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices);
    glEnableVertexAttribArray(ATTRIB_VERTEX);
    glVertexAttribPointer(ATTRIB_TEXTUREPOSITON, 2, GL_FLOAT, 0, 0, textureVertices);
    glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITON);


    glUseProgram(greyscaleProgram);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    [self presentFramebuffer];

    // Obviously here is where the ping pong starts (assuming correct mods 
    // to the framebuffer setup method below
    glUseProgram(program);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    [self presentFramebuffer];

    glDeleteTextures(1, &videoFrameTexture);
}

- (void)setDisplayFramebuffer;
{
    if (context)
    {
        [EAGLContext setCurrentContext:context];

        if (!viewFramebuffer)
        {
            [self createFramebuffers];
        }

        glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);



        glViewport(0, 0, backingWidth, backingHeight);

    }
}

- (BOOL)presentFramebuffer;
{
    BOOL success = FALSE;

    if (context)
    {
        [EAGLContext setCurrentContext:context];

        glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);

        success = [context presentRenderbuffer:GL_RENDERBUFFER];
    }

    return success;
}

- (BOOL)createFramebuffers
{   
    glEnable(GL_TEXTURE_2D);
    glDisable(GL_DEPTH_TEST);

    // Onscreen framebuffer object
    glGenFramebuffers(1, &viewFramebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);

    // Render buffer for final output
    glGenRenderbuffers(1, &viewRenderbuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);

    [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer];

    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
    NSLog(@"Backing width: %d, height: %d", backingWidth, backingHeight);

    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, viewRenderbuffer);


    if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 
    {
        NSLog(@"Failure with framebuffer generation");
        return NO;
    }

    return YES;
}

Редактировать: Уточнено, чего не хватает

1 Ответ

4 голосов
/ 02 апреля 2011

Чтобы выполнить рендеринг в пинг-понге, вам необходимо сделать следующее:

  • Создать 2 текстуры с одинаковой конфигурацией
  • Создать 2 буфера кадров с одинаковой конфигурацией, иприкрепить одну текстуру к каждому кадровому буферу.

Давайте назовем кадровые буферы A и B, а прикрепленные текстуры texA и texB:

Для рендеринга:

  • Используйте первый шейдер с glUseProgram.
  • Bind Framebuffer A.
  • Визуализация квадрата.

Теперь у вас есть результат выполнения шейдера в texA.Чтобы выполнить пинг-понг:

  • Используйте второй шейдер с glUseProgram.
  • Bind Framebuffer B.
  • Привязка texA и настройка текстурных блоков для вашего шейдера.
  • Визуализация квадрата.
  • Использование шейдера с glUseProgram.
  • Связывание кадрового буфера A.
  • Связывание texB и настройка текстурных блоков.
  • Визуализацияквад.

Теперь у вас есть результат в texA, и вы можете повторить процесс снова, надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...