Render YpCbCr iPhone 4 Camera Frame to an OpenGL ES 2.0 Texture in iOS 4.3

前端 未结 2 1140
孤独总比滥情好
孤独总比滥情好 2021-02-03 13:27

I\'m trying to render a native planar image to an OpenGL ES 2.0 texture in iOS 4.3 on an iPhone 4. The texture however winds up all black. My camera is configured as such:

2条回答
  •  傲寒
    傲寒 (楼主)
    2021-02-03 14:09

    OK. We have a working success here. The key was passing the Y and the UV as two separate textures to the fragment shader. Here is the final shader:

    #ifdef GL_ES
    precision mediump float;
    #endif
    
    varying vec2 textureCoordinate;
    
    uniform sampler2D videoFrame; 
    uniform sampler2D videoFrameUV;
    
    const mat3 yuv2rgb = mat3(
                                1, 0, 1.2802,
                                1, -0.214821, -0.380589,
                                1, 2.127982, 0
                                );
    
    void main() {    
        vec3 yuv = vec3(
                        1.1643 * (texture2D(videoFrame, textureCoordinate).r - 0.0625),
                        texture2D(videoFrameUV, textureCoordinate).r - 0.5,
                        texture2D(videoFrameUV, textureCoordinate).a - 0.5
                        );
        vec3 rgb = yuv * yuv2rgb;
    
        gl_FragColor = vec4(rgb, 1.0);
    } 
    

    You'll need to create your textures along like this:

    int bufferHeight = CVPixelBufferGetHeight(cameraFrame);
    int bufferWidth = CVPixelBufferGetWidth(cameraFrame);
    glBindTexture(GL_TEXTURE_2D, videoFrameTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, bufferWidth, bufferHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, CVPixelBufferGetBaseAddressOfPlane(cameraFrame, 0));
    
    glBindTexture(GL_TEXTURE_2D, videoFrameTextureUV);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, bufferWidth/2, bufferHeight/2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, CVPixelBufferGetBaseAddressOfPlane(cameraFrame, 1));
    

    and then pass them like this:

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, videoFrameTexture);
    
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, videoFrameTextureUV);
    
    glActiveTexture(GL_TEXTURE0);
    glUniform1i(videoFrameUniform, 0);
    glUniform1i(videoFrameUniformUV, 1);
    

    Boy am I relieved!

    P.S. The values for the yuv2rgb matrix are from here http://en.wikipedia.org/wiki/YUV and I copied code from here http://www.ogre3d.org/forums/viewtopic.php?f=5&t=25877 to figure out how to get the correct YUV values to begin with.

提交回复
热议问题