OpenGL ES Запуск нескольких шейдеров

Основываясь на предыдущем вопросе, я исследовал, как запускать несколько шейдеров за один проход (т.е. иметь один FBO и рендерить в текстуру). Это OpenGLES 2 на Iphone.

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

Входные данные — это основной видеобуфер с камеры.

Любые указатели или исправления чрезвычайно приветствуются :).

Спасибо,

Саймон

PS: Пока я объединил все в один метод — просто чтобы я мог просто сосредоточиться на том, чтобы заставить его работать!

- (void) PingPong:(CVImageBufferRef)cameraframe;
{
int bufferHeight = CVPixelBufferGetHeight(cameraframe);

int bufferWidth = CVPixelBufferGetWidth(cameraframe);

// Build the first FBO - this is wasteful - don't do this everytime
GLuint firstFBO;
glGenFramebuffers(1, &firstFBO);
glBindFramebuffer(GL_FRAMEBUFFER, firstFBO);

// Build the first texture and copy the video stuff into it
GLuint sourcetexture;
glGenTextures(1, &sourcetexture);
glBindTexture(GL_TEXTURE_2D, sourcetexture);
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);


// Build the second texture
GLuint nextTexture;
glGenTextures(1, &nextTexture);
glBindTexture(GL_TEXTURE_2D, nextTexture);
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);

// Attach the texture to our first FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sourcetexture, 0);


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

//glDrawBuffer(sourcetexture);
glEnable(GL_TEXTURE_2D);
glViewport(0, 0, backingWidth, backingHeight);
glBindTexture(GL_TEXTURE_2D, sourcetexture);
glUseProgram(greyscaleProgram);

// Now do the 2nd pass using the sourcetexture as input
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, nextTexture, 0);
glBindTexture(GL_TEXTURE_2D, nextTexture);
glUseProgram(program);

// Present the framebuffer to the render buffer
[EAGLContext setCurrentContext:context];

glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);

[context presentRenderbuffer:GL_RENDERBUFFER];

// Clean up stuff
glDeleteTextures(1, &sourcetexture);
glDeleteTextures(1, &nextTexture);

}


person Simon    schedule 28.03.2011    source источник


Ответы (1)


Где твой код отрисовки? Рисование — это то, что запускает выполнение шейдера, и ваш код, как я его сейчас вижу, не имеет вызовов рисования (glDrawArrays, glDrawElements и т. д.), поэтому он не работает, потому что вы не рисуете.

Нарисуйте полноэкранный четырехугольник, чтобы запускать выполнение шейдера для каждого прохода, и он будет работать.

Также рекомендуется использовать glCheckFramebufferStatus, чтобы убедиться, что ваша конфигурация FBO поддерживается и будет работать в вашей реализации GL.

person Dr. Snoopy    schedule 29.03.2011
comment
Спасибо. Я так понимаю, мне нужно будет сделать по одному для каждой glUseProgram, чтобы запустить рендеринг в буфер/текстуру? Итак, один идет в текстуру, а другой в конечный буфер рендеринга? - person Simon; 29.03.2011
comment
@Simon - Да, вам нужно будет выполнять glDraw * каждый раз, когда вы хотите что-то визуализировать с помощью шейдерной программы. Если вам нужен пример этого в действии, см. этот пример приложения. , где я выполняю двухэтапный рендеринг с использованием шейдеров, как и вы. - person Brad Larson; 29.03.2011
comment
@Brad - Ааа, это где вы используете пиксели чтения для чтения в fbo через rawPositionPixels, а затем вызываете setDisplay ... и UseProgram? - person Simon; 29.03.2011
comment
@Simon - вам не нужно использовать glReadPixels() только для передачи информации между FBO. Я делаю это, потому что еще не нашел хорошего способа усреднения цвета всего изображения на графическом процессоре, поэтому я считываю пиксели обратно в приложение и выполняю для них процедуру обработки, связанную с процессором. Если вам не нужен доступ к значениям пикселей таким образом, не используйте glReadPixels(), потому что это очень медленно. - person Brad Larson; 29.03.2011
comment
@Кто-нибудь :). Я возился с этим уже несколько дней, и, хотя вы оба были достаточно любезны, чтобы ответить, я все еще получаю либо черные экраны, либо один шейдер перезаписывает другой. Что здесь лучше? Спросить еще раз или вставить мой исходный код в качестве другого ответа и создать еще одну ветку на этот вопрос? - person Simon; 30.03.2011
comment
@Matias - я разместил еще один вопрос, но с моим исходным кодом, прежде чем я начал. Немного шаг назад, но я рисковал просто программированием карго-культа, поэтому я хотел начать все сначала с чистого листа. Кстати, спасибо за все ваши советы! - person Simon; 30.03.2011