开发者

Bind Opengl texture from the first fbo to a second fbo, use shader and render the second result (ping pong)

I've been working on ping pong shading and had thought that I had cracked it after my previous question. However, with further shader knowledge it looks like while I'm able to run the shader on FBO A and on FBO B, the output from A is not used as the source to B. In other words I'm not binding it correctly.

The code I'm using is below. The output of 开发者_JAVA百科the second shader is showing colour based output but the first shader sets the data to grayscale. So consquently I know this isn't working as required.

I'd be grateful for any (yet further!!) assistance.

Code below,

Cheers,

Simon

- (void) PingPong:(CVImageBufferRef)cameraframe; 
{
// Standard texture coords for the rendering pipeline
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,
};

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

// Create two textures with the same configuration
int bufferHeight = CVPixelBufferGetHeight(cameraframe);
int bufferWidth = CVPixelBufferGetWidth(cameraframe);

// texture 1
glGenTextures(1, &tex_A);
glBindTexture(GL_TEXTURE_2D, tex_A);
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));

// Texture 2
glGenTextures(1, &tex_B);
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);

// Bind framebuffer A
glBindFramebuffer(GL_FRAMEBUFFER, fbo_A);
glViewport(0, 0, backingWidth, backingHeight);

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

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

// Use the first shader
glUseProgram(greyscaleProgram);

// Render a quad
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

// Use the second shader
glUseProgram(program);

// Bind framebuffer B
glBindFramebuffer(GL_FRAMEBUFFER, fbo_B);

// Bind texture A and setup texture units for the shader
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex_A);

// Render output of FBO b is texture B
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_B, 0);

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

// Render a quad
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

// Render the whole thing
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER];

glDeleteTextures(1, &tex_A);
glDeleteTextures(1, &tex_B);
}


I think what might be happening is that you are still rendering into frame buffer memory and not texture memory. iirc glFramebufferTexture2D does not act as a resolve/copy but instead binds the framebuffer to the texture so that future render operations get written to the texture. You could have more problems however I'm pretty sure that your call to glFramebufferTexture2D should happen directly after your first call to glBindFramebuffer. This may not be your only problem, but it seems to be a significant one.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜