使用FBO渲染YUV数据

时间:2012-09-03 13:30:12

标签: opengl yuv fbo

我能够使用着色器在屏幕上渲染YUV图像。 为了提高性能,我想使用FBO。但我无法做到。

我的初始化代码如下

void opengl_init(int w, int h) {
    glGenFramebuffers(1, &framebuffer);
    checkGlError("glGenFramebuffers");

    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    checkGlError("glBindFramebuffer");

    glActiveTexture(GL_TEXTURE0);

    glGenTextures(1, &gYTexture);
    glBindTexture(GL_TEXTURE_2D, gYTexture);

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

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, FRAME_WIDTH, FRAME_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glBindTexture(GL_TEXTURE_2D, 0);

    glGenRenderbuffers(1, &colorbuffer);
    checkGlError("glGenRenderbuffers");
    glBindRenderbuffer(GL_RENDERBUFFER, colorbuffer);
    checkGlError("glBindRenderbuffer");
    glRenderbufferStorage(GL_RENDERBUFFER,
                GL_RGB565, FRAME_WIDTH, FRAME_HEIGHT);
    checkGlError("glRenderbufferStorage");

    glFramebufferRenderbuffer(GL_FRAMEBUFFER,
                              GL_COLOR_ATTACHMENT0,
                              GL_RENDERBUFFER, depthbuffer);
    checkGlError("glFramebufferRenderbuffer");


    glFramebufferTexture2D(GL_FRAMEBUFFER,
                           GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                           gYTexture, 0);
    checkGlError("glFramebufferTexture2D");

    int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    printf("Framebuffer is not complete: *status* = %d", status);
    if (status != GL_FRAMEBUFFER_COMPLETE) {
        printf("Framebuffer is not complete: *status* = %d", status);
    }
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    checkGlError("glBindFramebuffer");

    glGenBuffers(1, ioBuf);
    checkGlError("glGenBuffers");

    glActiveTexture(GL_TEXTURE1);

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

    glActiveTexture(GL_TEXTURE2);

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

    glViewport(0, 0, w, h);
    checkGlError("glViewport");
}

我使用下面的代码

渲染我的框架
void opengl_renderframe(void *yuvbuf,int framewidth, int frameheight) {
    static void *ubuf, *vbuf;
    ubuf = (char *)yuvbuf + (framewidth * frameheight);
    vbuf = (char *)ubuf + ((framewidth * frameheight) / 4);

    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    checkGlError("glBindFramebuffer");

    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
    checkGlError("glClearColor");
    glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    checkGlError("glClear");

    glUseProgram(gProgram);
    checkGlError("glUseProgram");

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, gYTexture);
    glBindBuffer(GL_ARRAY_BUFFER, ioBuf);
    checkGlError("glBindBuffer");
    glBufferData(GL_ARRAY_BUFFER, (FRAME_WIDTH * FRAME_HEIGHT) , yuvbuf, GL_STATIC_DRAW);
    checkGlError("glBufferData");

    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, FRAME_WIDTH, FRAME_HEIGHT, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
    checkGlError("glTexImage2D");
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    checkGlError("glBindBuffer");
    glUniform1i(Ysamp, 0);

    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, gUTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, framewidth/2, frameheight/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, ubuf );
    glUniform1i(Usamp, 1);

    glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_2D, gVTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, framewidth/2, frameheight/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, vbuf );
    glUniform1i(Vsamp, 2);

    glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
    checkGlError("glVertexAttribPointer");
    glEnableVertexAttribArray(gvPositionHandle);
    checkGlError("glEnableVertexAttribArray");

    glVertexAttribPointer(gaTextureCoordHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices2);
    checkGlError("glVertexAttribPointer");
    glEnableVertexAttribArray(gaTextureCoordHandle);
    checkGlError("glEnableVertexAttribArray");

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    checkGlError("glDrawArrays");

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    checkGlError("glBindFramebuffer 0");    
}

我的片段着色器只渲染Y数据如下

static const char gGrayScaleFragmentShader[] =
    "precision mediump float;\n"
    "varying vec2 vTextureCoord;\n"
    "uniform sampler2D sTexture;\n"
    "void main() {\n"
    "  gl_FragColor = texture2D(sTexture, vTextureCoord);\n"
    "}\n";

0 个答案:

没有答案