今天在做glsl渲染yuv圖像時,因為對glActiveTexture和glBindTexture的不熟,遇到了麻煩。經(jīng)過試驗,有了新的理解,并基于此理解解決了問題。
之前用到紋理,都是傳GL_RGB或者GL_RGBA類型的數(shù)據(jù)進去的,只需要使用一張紋理,完全不用設置glActiveTexture的,所以對glActiveTexture的理解很淺
渲染yuv就不同了。
ffmpeg解碼出來的yuv一般是以yuv420p的格式,分別存放在AVFrame->data二維數(shù)組中。其中
data[0] => y
data[1] => u
data[2] => v
這樣格式的數(shù)據(jù),需要使用三張紋理,分別傳輸?shù)斤@卡中。
glBindTexture
我的理解是,glBindTexture(GL_TEXTURE_2D, tex_id) 有以下幾個涵義:
- 表示 tex_id是一個二維紋理,設置過一次后,tex_id的類型就不可變了
-
opengl采用狀態(tài)機的設計,glBindTexture告訴opengl說,我選擇tex_id作為當前紋理,后續(xù)對紋理的操作都將作用在此紋理上。
glActiveTexture
我們已經(jīng)通過·glGenTextures在顯卡上開辟了一張紋理, 然后使用glBindTexture將該紋理選為當前操作目標, 接著也調(diào)用了glTexParameter`函數(shù)族設置了紋理的屬性
那么問題來了,紋理是怎么和glsl上的sampler2D關聯(lián)起來的?
假如
假如是自己來設計,會怎么設計:
將
glGenTextures生成的tex_id賦值給sampler2D變量就好了
實際上
我也不理解為什么。實際上opengl在這塊關聯(lián)上繞了下路。
紋理與sampler2D變量的關聯(lián)是通過索引來關聯(lián)的。
我們可以給sampler2D變量賦int值。
GLuint tex_loc = glGetUniformLocation(program, "tex");
glUniform1i(tex_loc, 1);
然后
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, tex_id);
將紋理與GL_TEXTURE1關聯(lián)起來。
tex_id與GL_TEXTUR1關聯(lián)
GL_TEXTURE1又與值為1的sampler2D變量關聯(lián)
所以tex_id 就這樣間接地與sampler2D變量關聯(lián)了
Q&A
平時使用單張紋理怎么不需要glActiveTexture?
sampler2D默認值為0,紋理也默認與GL_TEXTURE0關聯(lián)。