图像处理之基础---用Shader实现的YUV到RGB转换:使用3重纹理实现 .

     

上一篇中,我是用一个RGB格式的纹理来存储每一帧的画面,其中纹理为m_FrameWidth * m_FrameHeight大小,这样,在内存中,就必须要先对YUV的数据进行排序,然后才能当做RGB的数据格式传给纹理内存。我们发现对一个很大帧的图片进行数据重新排序会花费很多时间,为了减少这个时间,当然可以用汇编语言来进行这个排序的操作。然而,有一种更好的方法。

      我们发现在上一次所用到的YUV420数据格式是一种平面格式,他的数据排列十分有规律,这里,考虑用3重纹理来实现他的转换。

    先定义3个纹理,格式都为GL_LUMINANCE格式,其中一个纹理的大小为m_FrameWidth * m_FrameHeight,这是用来存放Y数据的,另两个纹理的大小为(m_FrameWidth / 2) * (m_FrameHeight / 2),分别用来存放U和V数据。好啦,我们可以直接使用内存拷贝memcpy()函数分别将YUV的数据拷出来,再生成纹理。

    那么frame shader中的程序就要改成:

  1. uniform sampler2D yTexture;
  2. uniform sampler2D uTexture;
  3. uniform sampler2D vTexture;
  4. void main()
  5. {
  6.     float yuv0 = (texture2D(yTexture,gl_TexCoord[0].st)).r;
  7.     float yuv1 = (texture2D(uTexture,gl_TexCoord[0].st)).r;
  8.     float yuv2 = (texture2D(vTexture,gl_TexCoord[0].st)).r;
  9.     vec4 color;
  10.     
  11.     color.r = yuv0 + 1.4022 * yuv2 - 0.7011;
  12.     color.r = (color.r < 0.0) ? 0.0 : ((color.r > 1.0) ? 1.0 : color.r);
  13.     color.g = yuv0 - 0.3456 * yuv1 - 0.7145 * yuv2 + 0.53005;
  14.     color.g = (color.g < 0.0) ? 0.0 : ((color.g > 1.0) ? 1.0 : color.g);
  15.     color.b = yuv0 + 1.771 * yuv1 - 0.8855;
  16.     color.b = (color.b < 0.0) ? 0.0 : ((color.b > 1.0) ? 1.0 : color.b);
  17.     gl_FragColor = color;
  18. }

    其中需要注意的两点是:

    1: uniform的值是要在每次绘制前调用的。

 

  1.     m_loc=glGetUniformLocation(m_Program,"yTexture");
  2.     glUniform1i(m_loc,0);  /* Bind Utex to texture unit 1 */
  3.     m_loc=glGetUniformLocation(m_Program,"uTexture");
  4.     glUniform1i(m_loc,1);  /* Bind Utex to texture unit 1 */
  5.     m_loc=glGetUniformLocation(m_Program,"vTexture");
  6.     glUniform1i(m_loc,2);  /* Bind Utex to texture unit 1 */

    m_Program就是shader的程序。

    2:在使用shader和多重纹理之前,都要进行初始化:glewInit();

  1.     int m = m_FrameWidth * m_FrameHeight;
  2.     int l = (m_FrameWidth / 2) * (m_FrameHeight / 2);
  3.     unsigned char * pyuv = m_y;
  4.     unsigned char * ptemp = cTemp[0];
  5.     __asm
  6.     {
  7.         mov ecx, m
  8.         mov ebx, ptemp
  9.         mov edx, pyuv
  10. label_y:
  11.         mov al, [ebx]
  12.         mov [edx], al
  13.         add ebx, 1
  14.         add edx, 1
  15.         dec ecx
  16.         jnz label_y
  17.     }
  18.     
  19.     pyuv = m_u;
  20.     ptemp = cTemp[1];
  21.     __asm
  22.     {
  23.         mov ecx, l
  24.         mov ebx, ptemp
  25.         mov edx, pyuv
  26. label_u:
  27.         mov ah, [ebx]
  28.         mov [edx], ah
  29.         add ebx, 1
  30.         add edx, 1
  31.         dec ecx
  32.         jnz label_u
  33.     }
  34.     pyuv = m_v;
  35.     ptemp = cTemp[2];
  36.     __asm
  37.     {
  38.         mov ecx, l
  39.         mov ebx, ptemp
  40.         mov edx, pyuv
  41. label_v:
  42.         mov al, [ebx]
  43.         mov [edx], al
  44.         add ebx, 1
  45.         add edx, 1
  46.         dec ecx
  47.         jnz label_v
  48.     }
posted @ 2014-10-22 02:27  midu  阅读(1426)  评论(0编辑  收藏  举报