qt5_qml_Opengl_shader 第三弹-----------------------纹理贴图(YUV)
来源:互联网 发布:php开启伪静态 编辑:程序博客网 时间:2024/05/18 03:39
Opengl_under_qml第三弹----------------------纹理贴图(YUV)
本文接上文
Opengl_under_qml第三弹----------------------纹理贴图(YUV)
主要通过程序将yuv数据送给shader,通过gpu来转成rgb进而渲染。
与上文主要不同的地方还是paint函数,为了容易看懂,没有将其写成多个函数的形式,也没有加测试代码,
voidSquircleRenderer::paint()
{
//initializeGLFunctions();
initializeOpenGLFunctions();
if(!m_program){
m_program=newQOpenGLShaderProgram();
m_program->addShaderFromSourceCode(QOpenGLShader::Vertex,
"attributehighpvec4vertexIn;"
"attributehighpvec2textureIn;"
"varyingvec2textureOut;"
"voidmain(void){"
"gl_Position=vertexIn;"
"textureOut=textureIn;}");
m_program->addShaderFromSourceCode(QOpenGLShader::Fragment,
"varyingvec2textureOut;"
"uniformsampler2Dtex_y;"
"uniformsampler2Dtex_u;"
"uniformsampler2Dtex_v;"
"voidmain(void){"
"vec3yuv;"
"vec3rgb;"
"yuv.x=texture2D(tex_y,textureOut).r;"
"yuv.y=texture2D(tex_u,textureOut).r-0.5;"
"yuv.z=texture2D(tex_v,textureOut).r-0.5;"
"rgb=mat3(1, 1, 1,"
"0, -0.39465, 2.03211,"
"1.13983,-0.58060, 0)*yuv;"
"gl_FragColor=vec4(rgb,1);}");
m_program->bindAttributeLocation("vertexIn",ATTRIB_VERTEX);
m_program->bindAttributeLocation("textureIn",ATTRIB_TEXTURE);
m_program->link();
}
m_program->bind();
staticconstGLfloatvertexVertices[]={
-1.0f,-1.0f,
1.0f,-1.0f,
-1.0f, 1.0f,
1.0f, 1.0f,
};
m_program->setAttributeArray(ATTRIB_VERTEX,GL_FLOAT,vertexVertices,2);
m_program->enableAttributeArray(ATTRIB_VERTEX);
staticconstGLfloattextureVertices[]={
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
};
m_program->setAttributeArray(ATTRIB_TEXTURE,GL_FLOAT,textureVertices,2);
m_program->enableAttributeArray(ATTRIB_TEXTURE);
GLuintTextureID0=m_program->uniformLocation("tex_y");
GLuintTextureID1=m_program->uniformLocation("tex_u");
GLuintTextureID2=m_program->uniformLocation("tex_v");
GLuintytexture,utexture,vtexture;
glGenTextures(1,&ytexture);
glBindTexture(GL_TEXTURE_2D,ytexture);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,(GLfloat)GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,(GLfloat)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);
glGenTextures(1,&utexture);
glBindTexture(GL_TEXTURE_2D,utexture);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,(GLfloat)GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,(GLfloat)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);
glGenTextures(1,&vtexture);
glBindTexture(GL_TEXTURE_2D,vtexture);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,(GLfloat)GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,(GLfloat)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);
FILE*fp;
if((fp=fopen("D:/testyuv.yuv","rb"))==NULL)
{
printf("cantopenthefile");
exit(0);
}
unsignedchardata[size];
fread(data,1,size,fp);
unsignedchar*y=data,*u=y+Pitch,*v=u+(Pitch>>2);//iePITCH*HEIGHT16*1/4
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,ytexture);
glTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE,MAIN_TEXTURE_WIDTH,MAIN_TEXTURE_HEIGHT,0,GL_LUMINANCE,GL_UNSIGNED_BYTE,y);
m_program->setUniformValue(TextureID0,0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,utexture);
glTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE,MAIN_TEXTURE_WIDTH/2,MAIN_TEXTURE_HEIGHT/2,0,GL_LUMINANCE,GL_UNSIGNED_BYTE,u);
m_program->setUniformValue(TextureID1,1);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D,vtexture);
glTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE,MAIN_TEXTURE_WIDTH/2,MAIN_TEXTURE_HEIGHT/2,0,GL_LUMINANCE,GL_UNSIGNED_BYTE,v);
m_program->setUniformValue(TextureID2,2);
glViewport(0,0,m_viewportSize.width(),m_viewportSize.height());
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_TRIANGLE_STRIP,0,4);
glDisable(GL_DEPTH_TEST);
m_program->disableAttributeArray(ATTRIB_VERTEX);
m_program->disableAttributeArray(ATTRIB_VERTEX);
fclose(fp);
m_program->release();
}
先看shader的代码:
首先Vsh:
attributehighpvec4vertexIn;
attributehighpvec2textureIn;
varyingvec2textureOut;
voidmain(void){
gl_Position=vertexIn;
textureOut=textureIn;
定义了两个attribute变量,一个作为顶点着色器的坐标vertexIn,另一个textureIn用于传给fsh的textureOut变量来进行纹理绘制,这里跟上一篇略有不同,原因是我参考的例子不同,应该使按照上一篇只定义一个坐标变量就行了,这里不再修改了。
然后是Fsh。
varyingvec2textureOut;
uniformsampler2Dtex_y;"
uniformsampler2Dtex_u;"
uniformsampler2Dtex_v;"
voidmain(void){"
vec3yuv;"
vec3rgb;"
yuv.x=texture2D(tex_y,textureOut).r;
yuv.y=texture2D(tex_u,textureOut).r-0.5;
yuv.z=texture2D(tex_v,textureOut).r-0.5;
rgb=mat3(1, 1, 1,
0, -0.39465, 2.03211,
1.13983,-0.58060, 0)*yuv;
gl_FragColor=vec4(rgb,1);}
textureOut是从vsh传递过来的用于绘制纹理的坐标变量,tex_y,tex_u,tex_v是定义的是纹理变量(sampler2D),然后把值给yuv,然后通过一个矩阵的乘法,得到rgb数据,这里和普通的yuv-转rgb是一样的,只不过是放在gpu转换。
具体的顶点坐标传值在上一篇文章里介绍了,这里就不在说了。主要说纹理的生成,(其实部分也是和上一篇文章是一样的,都是把buffer data传给sample2d纹理变量,这里把所有的东西(包括读取数据)写到一个流程里了)
GLuintytexture,utexture,vtexture;//定义纹理id
glGenTextures(1,&ytexture); //生成纹理
glBindTexture(GL_TEXTURE_2D,ytexture);//绑定纹理
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,(GLfloat)GL_LINEAR);//设置纹理参数
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,(GLfloat)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);
然后是读取文件操作:
//读取文件到fp
FILE*fp;
fp=fopen("D:/testyuv.yuv","rb")
//从fp读取数据到data,大小是size,个数是1
unsignedchardata[size];
fread(data,1,size,fp);
定义指针指向data数据
unsignedchar*y=data,*u=y+Pitch,*v=u+(Pitch>>2);//iePITCH*HEIGHT16*1/4
这里的对yuv数据加以说明,一帧分辨率为Pitch=imagewidth*imageheight的yuv数据,总共的数据量有3*Pitch/2个字节,其中y数据占Pitch个字节,所以程序里有:“*u = y + Pitch”,然后u数据,占Pitch/4个字节,所以程序里:”*v = u + (Pitch >> 2)”,意思就是PITCH*HEIGHT16*1/4,最后v数据占Pitch/4个字节,
这里需要说明的是,文件一旦打开,及执行完
FILE*fp;
fp=fopen("D:/testyuv.yuv","rb")
第一次fread(data,1,size,fp);就是读取第一帧,在没有执行fclose的前提下,再执行一次fclose,那么就会读取的是下一帧,这个根文件操作有关,具体的就不知道了。
然后是纹理绑定数据
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,ytexture);
glTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE,MAIN_TEXTURE_WIDTH,MAIN_TEXTURE_HEIGHT,0,GL_LUMINANCE,GL_UNSIGNED_BYTE,y);
m_program->setUniformValue(TextureID0,0);
跟上一篇文章是一样的,只不过glTexImage2D变量不一样,上一篇是rgb三阶数据绑定到一个纹理变量中,所以第二个变量是GL_RGB,这里一次只绑定一阶数据,所以第二个变量设置成GL_LUMINANCE
还有要注意的是大小,对于y数据是MAIN_TEXTURE_WIDTH,MAIN_TEXTURE_HEIGHT,但是对于u和v数据就是MAIN_TEXTURE_WIDTH,MAIN_TEXTURE_HEIGHT/2,原因上边已经讲过了。
最后就是老一套绘图,
glViewport(0,0,m_viewportSize.width(),m_viewportSize.height());
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_TRIANGLE_STRIP,0,4);
glDisable(GL_DEPTH_TEST);
代码:http://download.csdn.net/detail/u010423298/8699493
- qt5_qml_Opengl_shader 第三弹-----------------------纹理贴图(YUV)
- qt5_qml_Opengl_shader 第四弹----------------------纹理贴图(YUV视频循环播放)
- qt5_qml_Opengl_shader 第二弹----------------------纹理贴图(RGB)
- opengl纹理贴图(续)
- 纹理贴图
- 纹理贴图
- 纹理贴图
- 纹理贴图
- 纹理贴图
- 纹理贴图
- 纹理贴图
- 纹理贴图
- OpenGL(十二) 纹理映射(贴图)
- 【GLSL教程】(八)纹理贴图
- 【GLSL教程】(八)纹理贴图
- 【GLSL教程】(八)纹理贴图
- 【GLSL教程】(八)纹理贴图
- 【GLSL教程】(八)纹理贴图
- 字符串统计
- The constructor XMLOutputter(Format) is undefined
- 2015年大一下第8周项目1-存储班长信息的学生类(2)访问权限为private
- 正确编写概要设计说明书
- 配置OpenCV产生flann\logger.h(66): error C4996: 'fopen': This function or variable may be unsafe问题
- qt5_qml_Opengl_shader 第三弹-----------------------纹理贴图(YUV)
- [Script]Backordered Problematic delivery detail
- C#三层结构
- JavaMail的发送邮件
- The connection to adb is down, and a severe error has occured.问题解决方法小结
- java中的for each循环
- 安装oracle数据库后遇到数据入库为乱码的问题-由于oracle编码和系统编码不同导致
- OM System Parameter: Reservation Time Fence
- 积跬步至千里——算法强化训练(2)全排列和组合数