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:
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.