上一篇中我們提到先在iOS端將NV12先轉(zhuǎn)換成YUV褒繁,再傳入Unity中轉(zhuǎn)換成RGB,由于在iOS端轉(zhuǎn)換過程是在CPU中進行的馍忽,效率較慢棒坏,一幀圖像數(shù)據(jù)大概消耗20ms左右。因為Unity的shader轉(zhuǎn)換是在GPU中進行舵匾,效率高俊抵,所以考慮將這一步驟也挪到Unity中進行。
需要更改的有兩個步驟:
- 將數(shù)據(jù)拷貝到顯存
// 將數(shù)據(jù)拷貝到顯存
glBindTexture(GL_TEXTURE_2D, tex[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pData0);
glBindTexture(GL_TEXTURE_2D, tex[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w/2, h/2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, pData1);
注意GL_LUMINANCE_ALPHA參數(shù)坐梯,我們先來看看百度對于glTexImage2D方法的介紹徽诲。
這是一個OpenGL函數(shù)(以下敘述以OpenGL ES2.0為例)。
函數(shù)原型:
GL_APICALL void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLenum internalformat,
GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels);
參數(shù)說明:
target 指定目標紋理,這個值必須是GL_TEXTURE_2D谎替。
level 執(zhí)行細節(jié)級別偷溺。0是最基本的圖像級別,n表示第N級貼圖細化級別钱贯。
internalformat 指定紋理中的顏色組件挫掏。可選的值有GL_ALPHA,GL_RGB,GL_RGBA,GL_LUMINANCE, GL_LUMINANCE_ALPHA 等幾種秩命。
width 指定紋理圖像的寬度尉共,必須是2的n次方。紋理圖片至少要支持64個材質(zhì)元素的寬度
height 指定紋理圖像的高度弃锐,必須是2的m次方袄友。紋理圖片至少要支持64個材質(zhì)元素的高度
border 指定邊框的寬度。必須為0霹菊。
format 像素數(shù)據(jù)的顏色格式, 不需要和internalformatt取值必須相同剧蚣。可選的值參考internalformat旋廷。
type 指定像素數(shù)據(jù)的數(shù)據(jù)類型鸠按。可以使用的值有GL_UNSIGNED_BYTE,GL_UNSIGNED_SHORT_5_6_5,GL_UNSIGNED_SHORT_4_4_4_4,GL_UNSIGNED_SHORT_5_5_5_1饶碘。
pixels 指定內(nèi)存中指向圖像數(shù)據(jù)的指針
internalformat 指定紋理中的顏色組件目尖。因為在上一篇中我們每個數(shù)據(jù)只包含Y、U熊镣、V中的一個方向的分量卑雁,所以我們使用GL_ALPHA募书,同理在shader中取值時也是通過alpha通道取值绪囱。這一次NV12格式的數(shù)據(jù)UV方向分量在一起,所以我們使用GL_LUMINANCE_ALPHA莹捡,灰度值和Alpha值鬼吵,將U、V分別存入RGB和A中篮赢。
- 使用shader將NV12轉(zhuǎn)換為RGB
fixed4 yuv;
yuv.x = tex2D(_MainTexU, i.uv).a;
yuv.y = tex2D(_MainTexUV, i.uv).rgb - 0.5;
yuv.z = tex2D(_MainTexUV, i.uv).a - 0.5;
c.r = yuv.x + 1.403*yuv.z;
c.g = yuv.x - 0.344*yuv.y - 0.714*yuv.z;
c.b = yuv.x + 1.770*yuv.y;
注意在取值時從rgb通道取出U方向分量齿椅,alpha通道取出V方向分量。