《GPU編程與CG語言之陽春白雪下里巴人》- 第五章(CG 數(shù)據(jù)類型)

第05章 CG 數(shù)據(jù)類型

書讀的越多而不加思考未巫,你就會(huì)覺得你知道得很多;而當(dāng)你讀書而思考得越多的時(shí)候,你就會(huì)越清楚地看到,你知道得很少笤虫。
                                   ------ 伏爾泰

本章將著重介紹 Cg 語言中預(yù)定義的內(nèi)置(built in)的、或稱為基本(primitive)的數(shù)據(jù)類型祖凫。然后介紹可以用來聲明對(duì)象的各種類型琼蚯,主要是數(shù)組和結(jié)構(gòu)類型。學(xué)習(xí)本章時(shí)惠况,需要體會(huì)內(nèi)置向量類型和數(shù)組類型的區(qū)別遭庶。

5.1 基本數(shù)據(jù)類型

Cg 支持 7 種基本的數(shù)據(jù)類型:

  1. float, 32 位浮點(diǎn)數(shù)據(jù),一個(gè)符號(hào)位稠屠。浮點(diǎn)數(shù)據(jù)類型被所有的 Profiles 支持(但是 DirectX8 Pixel Profiles 在一些操作中降低了浮點(diǎn)數(shù)的精度和范圍)峦睡;
  2. half,16 位浮點(diǎn)數(shù)據(jù)权埠;
  3. int榨了,32 位整形數(shù)據(jù),有些 Profile 會(huì)將 int 類型作為 float 類型使用攘蔽;
  4. fixed阻逮,12 位定點(diǎn)數(shù),被所有的 fragment Profiles 所支持秩彤;
  5. bool叔扼,布爾數(shù)據(jù),通常用于 if 和條件操作符(?:), 布爾數(shù)據(jù)類型被所有的 Profiles 支持漫雷;
  6. sampler, 紋理對(duì)象的句柄(the handle to a texture object)瓜富,分為 6 類:sampler,sampler1D降盹,sampler2D与柑,sampler3D,samplerCUBE 和 samplerRECT。DirectX Profiles 不支持 samplerRECT 類型价捧,除此之外這些類型被所有的 Pixel Profiles 和 NV40 vertex program profile 所支持(CgUsersManual 30 頁)丑念。由此可見,在不遠(yuǎn)的未來结蟋,頂點(diǎn)程序也將廣泛支持紋理操作脯倚;
  7. string,字符類型嵌屎,該類型不被當(dāng)前存在 Profiles 所支持推正,實(shí)際上也沒有必要在 Cg 程序中用到字符類型,但是泥可以通過 Cg Runtime API 聲明該類型變量宝惰,并賦值植榕;因此,該類型變量可以保存 Cg 文件的信息尼夺。
      前 6 種類型會(huì)經(jīng)常用到尊残,事實(shí)上在 Wikipedia 有關(guān) Cg 語言的闡述中只列舉了前 6 種類型,而并沒有提到 string 數(shù)據(jù)類型淤堵。除了上面的基本數(shù)據(jù)類型外夜郁,Cg 還提供了內(nèi)置的向量數(shù)據(jù)(built-in vector data types),內(nèi)置的向量數(shù)據(jù)類型基于基礎(chǔ)數(shù)據(jù)類型粘勒。例如:float4竞端,表示 float 類型的 4 元向量; bool4庙睡,表示 bool 類型 4 元向量事富。
      注意:向量最長(zhǎng)不能超過 4 元,即在 Cg 程序中可以聲明 float1乘陪、float2统台、float3、float4 類型的數(shù)組變量啡邑,但是不能聲明超過 4 元的向量贱勃,例如:
  float5 array; // 編譯報(bào)錯(cuò)

向量初始化方式一般為:

  float5 array = float4(1.0, 2.0, 3.0, 4.0);

較長(zhǎng)的向量還可以通過較短的向量進(jìn)行構(gòu)建:

  float2 a = float2(1.0, 2.0);
  float4 b = float4(a, 0.0, 0.0, 0.0);

此外,Cg 還提供矩陣數(shù)據(jù)類型谤逼,不過最大的維數(shù)不能超過 4 * 4 階贵扰。例如:

  float1x1 matrix1;  // 等價(jià)于 float matirx1; x 是字符流部,并不是乘號(hào)戚绕;
  float2x3 matrix2; // 表示2 * 3 階矩陣枝冀,包含了 6 個(gè) float 類型數(shù)據(jù)舞丛;
  float4x3 matrix3耘子; // 表示4 * 2 階矩陣,包含了 8 個(gè) float 類型數(shù)據(jù)球切;
  float4x4 matrix4谷誓; // 表示4 * 4 階矩陣,這是最大的維數(shù)吨凑;

矩陣的初始化方式為:

  float2x3 matrix5 = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0};

注意:Cg 中向量捍歪、矩陣與數(shù)組是完全不同,向量和矩陣是內(nèi)置的數(shù)據(jù)類型(矩陣基于向量)怀骤,而數(shù)組則是一種數(shù)據(jù)結(jié)構(gòu)费封,不是內(nèi)置數(shù)據(jù)類型焕妙!這一點(diǎn)和 C\C++ 中不太一樣蒋伦,在 C\C++ 中,這三者同屬于數(shù)據(jù)結(jié)構(gòu)焚鹊,數(shù)組可以構(gòu)建向量和矩陣痕届。下一節(jié)中將詳細(xì)闡述 Cg 中的數(shù)組類型。

5.2 數(shù)組類型

“General-purpose arrays can only be used ad uniform parameters to a vertex program. The intent is to allow an application to pass arrays of skinning matrices and arrays of light parameters to a vertex program”(文獻(xiàn)【3】的 Array 章節(jié))末患。
  在著色程序中研叫,數(shù)組通常的使用目的是:作為從外部應(yīng)用程序傳入大量參數(shù)到 Cg 的頂點(diǎn)程序中的形參接口,例如與皮膚形變相關(guān)的矩陣數(shù)組璧针,或者光照參數(shù)數(shù)組等嚷炉。
  簡(jiǎn)而言之,數(shù)組數(shù)據(jù)類型在 Cg 程序中的作用是:作為函數(shù)的形參探橱,用于大量數(shù)據(jù)的傳遞申屹。
  Cg 中聲明數(shù)組變量的方式和 C 語言類似,例如:

  float a[10];  // 聲明了一個(gè)數(shù)組隧膏,包含 10 個(gè) float 類型數(shù)據(jù)哗讥;
  float4 b[10];  // 聲明了一個(gè)數(shù)組,包含 10 個(gè) float4 類型數(shù)據(jù)胞枕;

對(duì)數(shù)組進(jìn)行初始化的方式為:

  float a[4] = {1.0, 2.0, 3.0, 4.0};  // 初始化一個(gè)數(shù)組杆煞;

要獲取數(shù)組長(zhǎng)度,可以調(diào)用“.legth”腐泻,例如:

  float a[10];  // 聲明一個(gè)數(shù)組决乎;
  int length = a.length;  // 獲取數(shù)組的長(zhǎng)度;

聲明多維數(shù)組以及初始化的方式如下所示:

  float b[2][3] = {{0.0, 0.0, 0.0}, {1.0, 1.0, 1.0}}派桩;

對(duì)多維數(shù)組取長(zhǎng)度的方式為:

  int length1 = b.length瑞驱; // length1 值為 2
  int length2 = b[0].length; // length2 值為 3

數(shù)組和矩陣有些類似窄坦,但是并不是相同唤反。例如 4 * 4 階數(shù)組的聲明方式為: float M[4][4]; 4 階矩陣的聲明方式為: float4x4 M凳寺。前者是一個(gè)數(shù)據(jù)結(jié)構(gòu),包含 16 個(gè) float 類型數(shù)據(jù)彤侍,后者是一個(gè) 4 階矩陣數(shù)據(jù)肠缨。float4x4 M[4],表示一個(gè)數(shù)組盏阶,包含 4 個(gè) 4 階矩陣數(shù)據(jù)晒奕。
  進(jìn)行數(shù)組變量聲明時(shí),一定要指定數(shù)組長(zhǎng)度名斟,除非是作為函數(shù)參數(shù)而聲明的形參數(shù)組脑慧。并且在當(dāng)前的 profiles 中,數(shù)組的長(zhǎng)度和所引用的數(shù)組元素的地址必須在編譯時(shí)就知道砰盐。
  “Unsized arrays may only be declared as function parameters-key may not be declared as variables. Furthermore, in all current profiles, the actual array length and address calculations implied by array indexing must be known at compile time”(文獻(xiàn)【3】)闷袒。
  由于形參數(shù)組的概念與函數(shù)的概念緊密結(jié)合,所以將在第 8 章的 8.1 函數(shù)章節(jié)進(jìn)行統(tǒng)一闡述岩梳。

5.3 結(jié)構(gòu)類型

Cg 語言支持結(jié)構(gòu)體(structure)囊骤,實(shí)際上 Cg 中的結(jié)構(gòu)體的聲明、使用和 C++ 非常類似(只是類似冀值,不是相同)也物。一個(gè)結(jié)構(gòu)體相當(dāng)于一種數(shù)據(jù)類型,可以定義該類型的變量列疗。引入結(jié)構(gòu)體機(jī)制滑蚯,賦予了 Cg 語言一絲面向?qū)ο蟮纳省_€記得 C++ 中抵栈,結(jié)構(gòu)體與類的區(qū)別嗎告材?沒有區(qū)別,除了默認(rèn)訪問屬性在結(jié)構(gòu)體中為 public竭讳,類中為 private创葡,所以結(jié)構(gòu)體與類是非常近似的,由此可以看出 shader 語言的發(fā)展趨勢(shì)還是向著具有面向?qū)ο筇匦缘母呒?jí)語言绢慢。不過目前的 Cg 語言中的結(jié)構(gòu)體以展現(xiàn)“封裝”功能為主灿渴,并不支持集成機(jī)制。
  結(jié)構(gòu)體的聲明以關(guān)鍵字 struct 開始胰舆,然后緊跟結(jié)構(gòu)體的名字骚露,接下來是一個(gè)大括號(hào),并以分號(hào)結(jié)尾(不要忘了分號(hào))缚窿。大括號(hào)中是結(jié)構(gòu)體的定義棘幸,分為兩大類:成員變量和成員函數(shù)。例如倦零,定義一個(gè)名為 myAdd 的結(jié)構(gòu)體误续,包含一個(gè)成員變量吨悍,和一個(gè)執(zhí)行相加功能的成員函數(shù),然后聲明一個(gè)該結(jié)構(gòu)體類型的變量蹋嵌,代碼為:

  struct myAdd
  {
    float val;
    float add(float x) 
    {
       return val + x;
    }
  };
  myAdds;

使用符號(hào)“.”引用結(jié)構(gòu)體中的成員變量和成員函數(shù)育瓜。例如:

  float a = s.value;
  float b = s.add(a)栽烂;

注意:在當(dāng)前的所有的 profile 版本下躏仇,如果結(jié)構(gòu)體的一個(gè)成員函數(shù)使用了成員變量,則該成員變量要聲明在前腺办。此外焰手,成員函數(shù)是否可以重載依賴于使用的 Profile 版本。(文獻(xiàn)【3】 的 structures and Member functions 章節(jié))
  一般來說怀喉,Cg 的源代碼都會(huì)在文件首部定義二個(gè)結(jié)構(gòu)體书妻,分別用于定義輸入和輸出的類型,這個(gè)二個(gè)結(jié)構(gòu)體定義與普通的 C 結(jié)構(gòu)定義不同磺送,除了定義結(jié)構(gòu)體成員的數(shù)據(jù)類型外驻子,還定義了該成員的綁定語義類型(Binding Semantics)灿意,所謂綁定語義類型是為了與宿主環(huán)境進(jìn)行數(shù)據(jù)交換的時(shí)候識(shí)別不同數(shù)據(jù)類型的估灿。目前 Cg 支持的綁定語義類型包括 POSTION (位置),COLOR(顏色)缤剧,NORMAL(法向量)馅袁,Texcoord(紋理坐標(biāo))等類型。
  當(dāng)頂點(diǎn)著色程序向片段著色程序傳遞的數(shù)據(jù)類型較多的情況下荒辕,使用結(jié)構(gòu)體可以大大的方便代碼的編寫和維護(hù)汗销。總而言之抵窒,使用結(jié)構(gòu)體是一個(gè)好習(xí)慣弛针,高智商的孩子都使用(感覺是不是很囧 哈哈哈 O(∩_∩)O哈哈~)。

5.4 接口(Interfaces)類型

Cg 語言提供接口類型李皇,實(shí)際上削茁,我本人很少見到使用接口類型的著色程序,原因在于掉房,Cg 語言中的接口類型還不夠完善茧跋,不能被擴(kuò)展和包含。此外卓囚,目前的 GPU 編程大多是針對(duì)獨(dú)立的算法進(jìn)行編碼瘾杭,規(guī)模較小,使用接口類型沒有太大的優(yōu)勢(shì)哪亿。所以這里對(duì)該類型并不多做說明粥烁。有興趣的讀者可以參閱文獻(xiàn)【3】的 Interfaces 章節(jié)贤笆。

5.5 類型轉(zhuǎn)換

Cg 中的類型轉(zhuǎn)換和 C 語言的類型轉(zhuǎn)換很類似。C 語言中類型轉(zhuǎn)換可以是強(qiáng)制類型轉(zhuǎn)換讨阻,也可以是隱式類型轉(zhuǎn)換苏潜,如果是后者,則數(shù)據(jù)類型從低精度向高精度轉(zhuǎn)換变勇。在 Cg 語言中也是如此恤左。例如:

  float a = 1.0;
  half b = 2.0搀绣;
  float c = a + b飞袋; // 等價(jià)于 float c = a + (float)b;

當(dāng)有類型變量和無類型常量數(shù)據(jù)進(jìn)行運(yùn)算時(shí),該常量數(shù)據(jù)不做類型轉(zhuǎn)換链患,舉例如下:

  float a = 1.0巧鸭;
  float b = a + 2.0;// 2.0 為無類型常量數(shù)據(jù)麻捻,編譯時(shí)作為 float 類型;

Cg 語言中對(duì)于常量數(shù)據(jù)可以加上類型后綴纲仍,表示該數(shù)據(jù)的類型,例如:

  float a = 1.0贸毕;
  float b = a + 2.0h郑叠;// 2.0h 為half類型常量數(shù)據(jù);

運(yùn)算是需要做類型轉(zhuǎn)換常量的類型后綴(type suffix)有 3 種:

  f : 表示 float明棍;
  h : 表示 half乡革;
  x : 表示 fixed;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末摊腋,一起剝皮案震驚了整個(gè)濱河市沸版,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌兴蒸,老刑警劉巖视粮,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異橙凳,居然都是意外死亡蕾殴,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門痕惋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來区宇,“玉大人,你說我怎么就攤上這事值戳∫楣龋” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵堕虹,是天一觀的道長(zhǎng)卧晓。 經(jīng)常有香客問我芬首,道長(zhǎng),這世上最難降的妖魔是什么逼裆? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任郁稍,我火速辦了婚禮,結(jié)果婚禮上胜宇,老公的妹妹穿的比我還像新娘耀怜。我一直安慰自己,他們只是感情好桐愉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布财破。 她就那樣靜靜地躺著,像睡著了一般从诲。 火紅的嫁衣襯著肌膚如雪左痢。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天系洛,我揣著相機(jī)與錄音俊性,去河邊找鬼。 笑死描扯,一個(gè)胖子當(dāng)著我的面吹牛定页,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播荆烈,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼拯勉,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼竟趾!你這毒婦竟也來了憔购?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤岔帽,失蹤者是張志新(化名)和其女友劉穎玫鸟,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體犀勒,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡屎飘,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了贾费。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钦购。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖褂萧,靈堂內(nèi)的尸體忽然破棺而出押桃,到底是詐尸還是另有隱情,我是刑警寧澤导犹,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布唱凯,位于F島的核電站羡忘,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏磕昼。R本人自食惡果不足惜卷雕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望票从。 院中可真熱鬧漫雕,春花似錦、人聲如沸峰鄙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽先馆。三九已至发框,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間煤墙,已是汗流浹背梅惯。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留仿野,地道東北人铣减。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像脚作,于是被迫代替她去往敵國(guó)和親葫哗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容