[TOC]
OpenGL ES著色語言雖然是基于C/C++基本語法的語言豪嚎,但是其與C/C++相比較還是有很大不同的。例如谈火,該語言不支持雙精度浮點型(double)侈询、字節(jié)型(byte)、短整型(short)糯耍、長整型(long)扔字,并且取消了C中的聯(lián)合體(union)及枚舉類型(enum)等特性囊嘉。
1. 數(shù)據類型概述
與C語言類似,著色語言中有許多內建的原生數(shù)據類型以及構建數(shù)據類型革为,如浮點型(float)扭粱、布爾型(bool)、有符號整型(int)震檩、無符號整型(uint)琢蛤、矩陣型(matrix)以及向量型(vec2、vec3等)等抛虏〔┢洌總體來說,這些數(shù)據類型可以分為標量迂猴、向量慕淡、矩陣、采樣器错忱、結構體以及數(shù)組等幾類
-
標量
OpenGL ES3著色語言支持的標量類型有bool儡率、int、uint與float
聲明無符號整型(uint)字面常量時以清,需要在數(shù)字之后添加后綴u或U儿普,否則該字面常量的類型為有符號整型
-
向量
OpenGL ES著色語言中,向量可以看作是用同樣類型的標量組成的掷倔,其基本類型也分為bool眉孩、int、uint及float 四種勒葱。每個向量可以由2個浪汪、3個或者4個相同的標量組成.
向 量 類 型 | 說 明 |
---|---|
vec2 | 包含了2個浮點數(shù)的向量 |
bvec2 | 包含了2個布爾數(shù)的向量 |
vec3 | 包含了3個浮點數(shù)的向量 |
bvec3 | 包含了3個布爾數(shù)的向量 |
vec4 | 包含了4個浮點數(shù)的向量 |
bvec4 | 包含了4個布爾數(shù)的向量 |
ivec2 | 包含了2個整數(shù)的向量 |
uvec2 | 包含了2個無符號整數(shù)的向量 |
ivec3 | 包含了3個整數(shù)的向量 |
uvec3 | 包含了3個無符號整數(shù)的向量 |
ivec4 | 包含了4個整數(shù)的向量 |
uvec4 | 包含了4個無符號整數(shù)的向量 |
若向量是4維的,當看作顏色使用時凛虽,則可以使用的分量名為:r死遭、g、b凯旋、a呀潭;
若向量是4維的,當看作位置使用時至非,則可以使用的分量名為:x钠署、y、z荒椭、w谐鼎;
若向量是4維的,當看作紋理坐標使用時趣惠,則可以使用的分量名為:s狸棍、t身害、p、q隔缀;
訪問向量中的各個分量不但可以采用“.”加上不同的分量名题造,還可以將向量看作一個數(shù)組傍菇,用下標來進行訪問
aColor.r=0.6; //給向量aColor的紅色通道分量賦值
aColor.g=0.8; //給向量aColor的綠色通道分量賦值
aPosition.x=67.2; //給向量aPosition的X分量賦值
aPosition.z=48.3; //給向量aPosition的Z分量賦值
aTexCoor.s=0.65; //給向量aTexCoor的s分量賦值
aTexCoor.t=0.34; //給向量aTexCoor的t分量賦值
aColor[0]=0.6; //給向量aColor的紅色通道分量賦值
aPosition[2]=48.3; //給向量aPosition的z軸分量賦值
aTexCoor[1]=0.34; //給向量aTexCoor的t分量賦值
-
矩陣
矩陣按尺寸分為2×2矩陣猾瘸、2×3矩陣和2×4矩陣、3×2矩陣丢习、3×3矩陣和3×4矩陣以及4×2矩陣牵触、4×3矩陣和4×4矩陣,其中矩陣類型的第一個數(shù)字表示矩陣的列數(shù)咐低,第二個數(shù)字表示矩陣的行數(shù)揽思,具體情況如表4-2所列。
矩 陣 類 型 | 說 明 |
---|---|
mat2 | 2×2的浮點數(shù)矩陣 |
mat2×2 | 2×2的浮點數(shù)矩陣 |
mat3 | 3×3的浮點數(shù)矩陣 |
mat2×3 | 2×3的浮點數(shù)矩陣 |
mat4 | 4×4的浮點數(shù)矩陣 |
mat2×4 | 2×4的浮點數(shù)矩陣 |
mat3×2 | 3×2的浮點數(shù)矩陣 |
mat4×2 | 4×2的浮點數(shù)矩陣 |
mat3×3 | 3×3的浮點數(shù)矩陣 |
mat4×3 | 4×3的浮點數(shù)矩陣 |
mat3×4 | 3×4的浮點數(shù)矩陣 |
mat4×4 | 4×4的浮點數(shù)矩陣 |
OpenGL ES著色語言中见擦,矩陣是按列順序組織的钉汗,也就是一個矩陣可以看作由幾個列向量組成。例如鲤屡,mat3就可以看作由3個vec3組成损痰。另外,mat2與mat2×2酒来、mat3與mat3×3以及mat4與mat4×4是3組兩兩完全相同的類型卢未,只是其類型的名稱不同而已。
-
采樣器
采樣器是著色語言中不同于C語言的一種特殊的基本數(shù)據類型堰汉,其專門用來進行紋理采樣的相關操作辽社。一般情況下,一個采樣器變量代表一幅或一套紋理貼圖翘鸭。
采樣器類型 | 說 明 |
---|---|
sampler2D | 用于訪問浮點型的二維紋理 |
isampler3D | 用于訪問整型的三維紋理 |
sampler3D | 用于訪問浮點型的三維紋理 |
isamplerCube | 用于訪問整型的立方貼圖紋理 |
samplerCube | 用于訪問浮點型的立方貼圖紋理 |
isampler2DArray | 用于訪問整型的2D紋理數(shù)組 |
samplerCubeShadow | 用于訪問浮點型的立方陰影紋理 |
usampler2D | 用于訪問無符號整型的二維紋理 |
sampler2DShadow | 用于訪問浮點型的二維陰影紋理 |
usampler3D | 用于訪問無符號整型的三維紋理 |
sampler2DArray | 用于訪問浮點型的2D紋理數(shù)組 |
usamplerCube | 用于訪問無符號整型的立方貼圖紋理 |
sampler2DArrayShadow | 用于訪問浮點型的2D陰影紋理數(shù)組 |
usampler2DArray | 用于訪問無符號整型的2D紋理數(shù)組 |
isampler2D | 用于訪問整型的二維紋理 |
需要注意的是滴铅,與前面介紹的幾類變量不同,采樣器變量不能在著色器中進行初始化就乓。一般情況下采樣器變量都用uniform限定符來修飾汉匙,從宿主語言(如C++、Java)接收傳遞進著色器的值档址。此外盹兢,采樣器變量也可以用作函數(shù)的參數(shù),但是作為函數(shù)參數(shù)時不可以使用out或inout修飾符來修飾守伸。
-
結構體
OpenGL ES著色語言還提供了類似于C語言中的用戶自定義結構體绎秒,同樣也是使用struct關鍵字進行聲明,基本用法與C語言基本類似尼摹,不在此贅述了见芹。
-
數(shù)組
在著色語言中剂娄,開發(fā)人員可以聲明任何類型的數(shù)組。聲明數(shù)組的方式主要有兩種玄呛,具體如下所列阅懦。
(1). 在聲明數(shù)組的同時,指定數(shù)組的大信锹痢:
vec3 position[20]; //聲明了一個包含20個vec3的數(shù)組耳胎,索引從0開始
(2). 在聲明數(shù)組并初始化的同時,可以不指定數(shù)組的大小惕它,不支持動態(tài)長度數(shù)組
float x[]=float[2](1.0,2.0); //數(shù)組的長度為2
float y[]=float[](1.0,2.0,3.0); //數(shù)組的長度為3
OpenGL ES 3.0的著色語言只支持一維數(shù)組的使用怕午,不支持二維以及更多維數(shù)組的使用。
2. 運算符
運 算 符 | 說 明 |
---|---|
() | 括號分組 |
[ ] | 數(shù)組下標 |
() | 函數(shù)調用和構造函數(shù)結構 |
. | 用于成員選擇與混合 |
++ -- | 自加1與自減1后綴 |
++ -- | 自加1與自減1 前綴 |
+ - ~ ! | 一元運算符 |
* / % | 乘法淹魄、除法和取余 |
+ - | 加法與減法 |
<< >> | 逐位左移和右移 |
< > <= >= | 關系運算符 |
== != | 等于以及不等于 |
& | 逐位與 |
^ | 逐位異或 |
| | 逐位或 |
&& | 邏輯與 |
^^ | 邏輯異或 |
|| | 邏輯或 |
?: | 選擇 |
= += -= *= /= | 賦值運算符 |
%= <<= >>= &= ^=∮粝А|= | 賦值運算符 |
, | 按順序排列 |
-
OpenGLES運算符的特殊操作
某些OpenGLES的運算符有不同于c語言的操作,下面簡單介紹下甲锡。
- 通過運算符“.”進行混合選擇操作
在運算符“.”之后列出一個向量中需要的各個分量的名稱兆蕉,就可以選擇并重新排列這些分量。下面的代碼片段說明了這個問題缤沦。
vec4 color= vec4(0.7,0.1,0.5,1.0); //聲明一個vec4類型的向量color
vec3 temp=color.agb; //相當于獲取到一個向量(1.0,0.1,0.5)賦值給temp
vec4 tempL=color.aabb; //相當于獲取到一個向量(1.0,1.0,0.5,0.5)賦值給tempL
vec3 tempLL; //聲明了一個3維向量tempLL
tempLL.grb=color.aab; //對向量tempLL的3個分量賦值
一次出現(xiàn)的各部分的分量名稱必須是來自同一名稱組虎韵。3個名稱組分別為:xyzw、rgba疚俱、stpq
3. 構造函數(shù)
-
矩陣的構造函數(shù)
矩陣的構造函數(shù)共有3種基本形式劝术。
- 如果矩陣的構造函數(shù)內只有一個標量值,那么矩陣的對角線上的分量都等于該值呆奕,其余值為0养晋。
- 矩陣可以由許多向量構造而成。比如說梁钾,一個mat2矩陣可以由兩個vec2構成绳泉。
- 矩陣還可以由大量的標量值構成,矩陣的分量由左向右依次被賦值姆泻。
vec2 d=vec2(1.0,2.0); //d的分量值分別為1.0零酪、2.0
mat2 e=mat2(d,d); //e的第一列和第二列均為1.0、2.0
mat3 f=mat3(e); //將矩陣e放到矩陣f的左上角拇勃,右下角剩余對角線元素的值為1四苇,其余為0
mat4x2 g=mat4x2(d,d,d,d); //聲明一個mat4*2矩陣
mat2x3 h=mat2x3(g); //將矩陣g左上角的2*2個元素值賦值給h中的對應元素,h矩陣的最后一行為0,0
mat3 myMat3 = mat3(1.0, 0.0, 0.0, //矩陣myMat3第一列的值
0.0, 1.0, 0.0, //矩陣myMat3第二列的值
0.0, 1.0, 1.0); //矩陣myMat3第三列的值
OpenGL ES中矩陣元素的存儲順序以列為主方咆,即矩陣由列向量組成月腋。因此,當使用矩陣的構造函數(shù)時,矩陣的元素將會按照矩陣的列的順序依次被參數(shù)賦值榆骚。這一點從上述代碼片段的第5行有所體現(xiàn)
其他數(shù)據類型的構造函數(shù)和C語言一樣片拍,不再贅述。
類型轉換
OpenGL ES著色語言沒有提供類型的自動提升功能妓肢,并且對類型匹配的要求十分嚴格捌省。賦值表達式中的兩個操作數(shù)類型必須完全相同,另外調用函數(shù)時的形參以及實參的類型也必須完全相同碉钠。
同時OpenGL ES著色語言也沒有提供數(shù)據類型的強制轉換功能纲缓,只能使用構造函數(shù)來完成類型轉換。
float f=1.0; //聲明一個浮點數(shù)f并賦值
bool b=bool(f); //將浮點數(shù)轉換成布爾類型放钦,該構造函數(shù)將非0的數(shù)字轉為true色徘,0轉為false
float f1=float(b); //將布爾值轉變?yōu)楦↑c數(shù),true轉換為1.0操禀,false轉換為0.0
int c=int(f1); //將浮點數(shù)轉換成有符號或者無符號整型,直接去掉小數(shù)部分
存儲限定符
這些限定符中大部分只能用來修飾全局變量横腿,主要的如下所列颓屑。
限 定 符 | 說 明 |
---|---|
const | 用于聲明常量 |
in/centroid in | 一般用于聲明著色器的輸入變量,如頂點著色器中用來接收頂點位置耿焊、顏色等數(shù)據的變量揪惦,centroid in變量與插值類型有關 |
out/centroid out | 一般用來聲明著色器的輸出變量,如從頂點著色器向片元著色器傳遞的頂點位置等數(shù)據的變量罗侯,centroid out變量與插值類型有關 |
uniform | 一般用于對同一組頂點組成的單個3D物體中所有頂點都相同的量器腋,如當前的光源位置 |
限定符在使用時應該放在變量類型之前,且使用in钩杰、uniform以及out限定符修飾的變量必須為全局變量纫塌。同時要注意的是,著色語言中沒有默認限定符的概念讲弄,因此如果有需要措左,必須為全局變量明確指定需要的限定符。