Я использую OpenGL в Linux QT для рендеринга видео кадра. Я взял ссылку на шейдер UYVY opengl по этой ссылке, и код RGB, который я использую в opengl, приведен ниже.
Инициализация.
initializeOpenGLFunctions();
glEnable(GL_DEPTH_TEST); //this is already enable in init function
glDisable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
RGB Render
//rendering of rgb
glClear(GL_COLOR_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
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);
if(g_cs_Index == RGB32)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_nVideoW, m_nVideoH, 0, GL_BGRA, GL_UNSIGNED_BYTE, g_buffer); //RGB32 working
}
if(g_cs_Index == RGB24)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, m_nVideoW, m_nVideoH, 0, GL_BGR, GL_UNSIGNED_BYTE, g_buffer); //RGB24 working
}
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(0, 1);
glVertex2f(-1, -1);
glTexCoord2f(1, 1);
glVertex2f(1, -1);
glTexCoord2f(0, 0);
glVertex2f(-1, 1);
glTexCoord2f(1, 0);
glVertex2f(1, 1);
glEnd();
glPopMatrix();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
UYVY Инициализация.
GLhandleARB FSHandle,PHandle;
QOpenGLExtension_ARB_shader_objects* myShader = new QOpenGLExtension_ARB_shader_objects();
const char *FProgram_UYVY_1920_1080=
"uniform sampler2DRect Ytex;\n"
"uniform sampler2DRect UVtex;\n"
"void main(void) {\n"
" float fx, fy, y, u, v, r, g, b;\n"
" fx = gl_TexCoord[0].x;\n"
" fy = 1080.0-gl_TexCoord[0].y;\n"
" y = texture2DRect(Ytex,vec2(fx,fy)).a;\n"
" u = texture2DRect(UVtex,vec2(fx/2.0,fy)).b;\n"
" v = texture2DRect(UVtex,vec2(fx/2.0,fy)).r;\n"
" y=1.164*(y-0.0627);\n"
" u=u-0.5;\n"
" v=v-0.5;\n"
" r = y+1.5958*v;\n"
" g = y-0.39173*u-0.81290*v;\n"
" b = y+2.017*u;\n"
" gl_FragColor=vec4(r, g, b, 1.0);\n"
"}\n";
initializeOpenGLFunctions();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,m_nVideoW,0,m_nVideoH,-1,1);
glViewport(0,0,m_nVideoW,m_nVideoH);
glClearColor(0,0,0,0);
glColor3f(0.0,0.0,0.0);
glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST);
myShader->initializeOpenGLFunctions();
PHandle = myShader->glCreateProgramObjectARB();
FSHandle= myShader->glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
myShader->glShaderSourceARB(FSHandle,1,&FProgram_UYVY_1920_1080,NULL);
myShader->glCompileShaderARB(FSHandle);
myShader->glGetObjectParameterivARB(FSHandle,GL_OBJECT_COMPILE_STATUS_ARB,&i);
myShader->glAttachObjectARB(PHandle,FSHandle);
myShader->glLinkProgramARB(PHandle);
myShader->glUseProgramObjectARB(PHandle);
Код рендеринга UYVY
glClear(0);
g_YV12_render = 2;
glGenTextures(g_YV12_render,array_texture);
glActiveTexture(GL_TEXTURE1);
i=myShader->glGetUniformLocationARB(PHandle,"UVtex");
myShader->glUniform1iARB(i,1); /* Bind Utex to texture unit 1 -YUY2 working*/
glBindTexture(GL_TEXTURE_RECTANGLE_NV, 1);
glEnable(GL_TEXTURE_RECTANGLE_NV);
glTexParameteri(GL_TEXTURE_RECTANGLE_NV,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_NV,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);
glTexImage2D(GL_TEXTURE_RECTANGLE_NV,0,GL_RGBA8, m_nVideoW/2/*(camera->width/2)*/, m_nVideoH/*(camera->height)*/,0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, g_buffer); //UV
glActiveTexture(GL_TEXTURE0);
i=myShader->glGetUniformLocationARB(PHandle,"Ytex");
myShader->glUniform1iARB(i,0); /* Bind Ytex to texture unit 0 -YUY2 Working*/
glBindTexture(GL_TEXTURE_RECTANGLE_NV, 2);//id_y);
glEnable(GL_TEXTURE_RECTANGLE_NV);
glTexParameteri(GL_TEXTURE_RECTANGLE_NV,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_NV,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);
glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_LUMINANCE_ALPHA, m_nVideoW, m_nVideoH, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,g_buffer); //Y
glBegin(GL_QUADS);
glTexCoord2i(0,0);
glVertex2i(0,0);
glTexCoord2i(m_nVideoW,0);
glVertex2i(m_nVideoW,0);
glTexCoord2i(m_nVideoW,m_nVideoH);
glVertex2i(m_nVideoW,m_nVideoH);
glTexCoord2i(0,m_nVideoH);
glVertex2i(0,m_nVideoH);
glEnd();
glDrawArrays(GL_QUADS, 0, 4);
Если я использую эти отрисовки независимо, то это работает, то есть, если я использую только RGB, то отрисовывается нормально, а если используется только UYVY - отрисовывается нормально. Однако, когда я хочу переключиться между UYVY и RGB, тогда RGB не будет отображаться.
Мой вопрос:
1) почему при переходе с UYVY на RGB24 opengl не может отображать RGB24?
Я новичок в области opengl, и у меня не очень хорошее понимание opengl. Я знаю, что существует некоторая проблема, когда я переключаюсь между двумя цветовыми пространствами, это может быть из-за инициализации или очистки какой-либо линии трубопровода. Пожалуйста, можете указать, что не так с кодом выше.