简体   繁体   中英

nv12 to rgb opengl render issue

I'm trying to render a camera nv12 buffer to OpenGL ES surface in C++ and here is the output. 在此处输入图像描述

Let's look to my shaders:

const char gVertexShader[] =
    "#version 320 es\n"
    "layout (location = 0) in vec4 vertex;\n"
    "out vec2 TexCoords;\n"
    "uniform mat4 projection;\n"
    "void main() {\n"
    "  gl_Position = projection * vec4(vertex.xy, 1.0, 1.0);\n"
    "  TexCoords = vertex.zw;\n"
    "}\n";

const char gFragmentNV12ToRGB[] =
    "#version 320 es\n"
    "precision highp float;\n"
    "in vec2 TexCoords;\n"
    "out vec4 color;\n"
    "uniform sampler2D text;\n"
    "uniform sampler2D textUV;\n"
    "void main (void) {\n"
    "float r, g, b, y, u, v;\n"
    "y = texture(text, TexCoords).r;\n"
    "u = texture(textUV, TexCoords).r - 0.5;\n"
    "v = texture(textUV, TexCoords).a - 0.5;\n"
    "r = y + 1.13983*v;\n"
    "g = y - 0.39465*u - 0.58060*v;\n"
    "b = y + 2.03211*u;\n"
    "color = vec4(r, g, b, 1.0);\n"
    "}\n";

And here is the code, first of all I create a cameraTexture with NULL data then every 10ms I refresh the display

void Camera::createCameraTexture(const int width, const int height)
{
    if (cameraTexId == 0)
    {
        GLuint idTex;
        glGenTextures(1, &idTex);
        glBindTexture(GL_TEXTURE_2D, idTex);

        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

        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, GL_ZERO, GL_BGRA_EXT, width, height, GL_ZERO, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL);
        glBindTexture(GL_TEXTURE_2D, GL_ZERO);

        cameraTexId = idTex;
    }
}

void Camera::refreshCamera()
{
    GLfloat xpos = 0;
    GLfloat ypos = 0;

    GLfloat w = mSurfaceWidth;
    GLfloat h = mSurfaceHeight;

    GLfloat vertices[6][4] = {
        {xpos, ypos + h, 0.0, 0.0},
        {xpos, ypos, 0.0, 1.0},
        {xpos + w, ypos, 1.0, 1.0},

        {xpos, ypos + h, 0.0, 0.0},
        {xpos + w, ypos, 1.0, 1.0},
        {xpos + w, ypos + h, 1.0, 0.0}};

    glBindTexture(GL_TEXTURE_2D, cameraTexId);
    glUniform1i(mTextShaderHandle, GL_ZERO);
    glBindVertexArray(VAO);

    glActiveTexture(GL_TEXTURE0);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glTexSubImage2D(GL_TEXTURE_2D, GL_ZERO, GL_ZERO, GL_ZERO, mVideoCapture.getWidth(),
                    mVideoCapture.getHeight(), GL_BGRA_EXT, GL_UNSIGNED_BYTE, mVideoCapture.getRawBufferCamera());
    glBufferSubData(GL_ARRAY_BUFFER, GL_ZERO, sizeof(vertices), vertices);

    glDrawArrays(GL_TRIANGLES, GL_ZERO, 6);

    //end
    glBindTexture(GL_TEXTURE_2D, GL_ZERO);
    glBindBuffer(GL_ARRAY_BUFFER, GL_ZERO);
}

I think that I have to pass an other buffer with UV buffer but I know that buffer Y and UV are the same.

Please can someone tell me what's the right way to achieve that?

Thanks for your help.

You need to repack yuv color buffer to rgb structure:

Look here:

Convert YV12 to NV21 (YUV YCrCb 4:2:0)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM