0
\$\begingroup\$

I have a problem where I have YUV, but UV texture is embedded into one texture.. How would I convert Y-UV into RGB ?

const char* pFragmentShaderSource = "\
    precision highp float;\
    uniform sampler2D gsuTexture0;\
    uniform sampler2D gsuTexture1;\
    uniform sampler2D gsuTexture2;\
    varying vec2 gsvTexCoordLuma;\
    varying vec2 gsvTexCoordChroma;\
    \
    void main()\
    {\
        float y = texture2D(gsuTexture0, gsvTexCoordLuma).r;\
        float u = texture2D(gsuTexture1, gsvTexCoordChroma).r;\
        float v = texture2D(gsuTexture2, gsvTexCoordChroma).r;\
        u = u - 0.5;\
        v = v - 0.5;\
        vec3 rgb;\
        rgb.r = y + (1.403 * v);\
        rgb.g = y - (0.344 * u) - (0.714 * v);\
        rgb.b = y + (1.770 * u);\
        gl_FragColor = vec4(rgb, 1.0);\
    }";



// TODO: optimization in Shader
int32_t sx = bitmap_.dx() / bitmap_uv.dx();
int32_t sy = bitmap_.dy() / bitmap_uv.dy();

unsigned int textures[2];
glGenTextures(2, &textures[0]);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glBindTexture(GL_TEXTURE_2D, textures[1]);

// set the texture wrapping parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);    // set texture wrapping to GL_REPEAT (default wrapping method)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, bitmap_.dx(), bitmap_.dy(), 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, bitmap_.ptr());
glGenerateMipmap(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);

glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, bitmap_uv.dx(), bitmap_uv.dy(), 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, bitmap_uv.ptr());
glGenerateMipmap(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textures[1]);          

setBitmapVertices(a, ab, ad, m_bitmapVBO);

udi::BitmapShader *shader = m_bitmapShaderNV12;
if (m_shaderPtr != shader) {
    glUseProgram(shader->getShaderProgram());
    m_shaderPtr = shader;
}
glEnableVertexAttribArray(shader->posAttrib);
glVertexAttribPointer(shader->posAttrib, NUM_VERTEX_COMPONENTS, GL_FLOAT, GL_FALSE, (NUM_VERTEX_COMPONENTS + NUM_TEX_COMPONENTS) * sizeof(GLfloat), 0);
glEnableVertexAttribArray(shader->  );
glVertexAttribPointer(shader->texAttrib, NUM_TEX_COMPONENTS, GL_FLOAT, GL_FALSE, (NUM_TEX_COMPONENTS + NUM_VERTEX_COMPONENTS) * sizeof(GLfloat), (void*)(NUM_VERTEX_COMPONENTS * sizeof(GLfloat)));
glUniformMatrix4fv(shader->matrixLocation, 1, GL_FALSE, m_transformationMatrix);
glUniform1i(glGetAttribLocation(shader->getShaderProgram(), "textureY"), 0);
glUniform1i(glGetAttribLocation(shader->getShaderProgram(), "textureUV"), 1);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

glDeleteTextures(2, &textures[0]);
\$\endgroup\$
3
  • \$\begingroup\$ When you say the UV is embedded into one texture, you mean the RG channels of one texture contain the UV data, while the Y data is in a different texture? It seems like that should change only the lines where you declare and sample from the textures, not the conversion routine. Where did you run into trouble adapting this code for your needs? \$\endgroup\$
    – DMGregory
    Jan 27, 2022 at 11:42
  • \$\begingroup\$ @DMGregory Yes you are right, I mean the RG Channels of one texture contains the UV Data and One texture contains the Y. Can you help with the lines that sample the textures ? \$\endgroup\$ Jan 27, 2022 at 11:43
  • \$\begingroup\$ @DMGregory I posted the client code \$\endgroup\$ Jan 27, 2022 at 11:45

1 Answer 1

0
\$\begingroup\$

Just delete one unused sampler2D, sample both red and green channels from the chroma texture, and unpack them to your u and v variables.

const char* pFragmentShaderSource = "\
    precision highp float;\
    uniform sampler2D lumaTexture;\
    uniform sampler2D chromaTexture;\
    varying vec2 gsvTexCoordLuma;\
    varying vec2 gsvTexCoordChroma;\
    \
    void main()\
    {\
        float y = texture2D(lumaTexture, gsvTexCoordLuma).r;\
        float2 chroma = texture2D(chromaTexture, gsvTexCoordChroma).rg;\
        float u = chroma.r - 0.5;\
        float v = chroma.g - 0.5;\
        vec3 rgb;\
        rgb.r = y + (1.403 * v);\
        rgb.g = y - (0.344 * u) - (0.714 * v);\
        rgb.b = y + (1.770 * u);\
        gl_FragColor = vec4(rgb, 1.0);\
    }";
\$\endgroup\$
2
  • \$\begingroup\$ Should I keep GL_LUMINANCE ? in the client code ? \$\endgroup\$ Jan 27, 2022 at 11:55
  • \$\begingroup\$ or it should be GL_RGB ? \$\endgroup\$ Jan 27, 2022 at 12:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .