Cg(c for graphic)語言的數據類型

 抄“GPU Programming And Cg Language Primer 1rd Edition” 中文名“GPU編程與CG語言之陽春白雪下里巴人”


    本章將着重介紹Cg語言中預定義的內置(built in)的、或稱爲基本(primitive)的數據類型。然後介紹可以用來聲明對象的各類類型,主要是數組和結構類型。學習本章時,需要體會內置向量類型和數組類型的區別。


5.1 基本數據類型


    Cg支持7種基本的數據類型:


1.    float,32位浮點數據,一個符號位。浮點數據類型被所有的profile支持(但是DirectX8 pixel profiles在一些操作中降低了浮點數的精度和範圍);


2.    half,16爲浮點數據;


3.    int,32位整形數據,有些profile會將int類型作爲float類型使用;


4.    fixed,12位定點數,被所有的fragment profiles所支持;


5.    bool,布爾數據,通常用於if和條件操作符(?:),布爾數據類型被所有的profiles支持;


6.    sampler*,紋理對象的句柄(the handle to a texture object),分爲6類:sampler, sampler1D, sampler2D, sampler3D, samplerCUBE,和samplerRECT。DirectX profiles不支持samplerRECT類型,除此之外這些類型被所有的pixel profiles和    NV40 vertex program profile所支持(CgUsersManual 30頁)。由此可見,在不遠的未來,頂點程序也將廣泛支持紋理操作;


7.    string,字符類型,該類型不被當前存在的profile所支持,實際上也沒有必要在Cg程序中用到字符類型,但是你可以通過Cg runtime API聲明該類型變量,並賦值;因此,該類型變量可以保存Cg文件的信息。


    前6種類型會經常用到,事實上在Wikipedia有關Cg語言的闡述中只列舉了前6種類型,而並沒有提到string數據類型。除了上面的基本數據類型外,Cg還提供了內置的向量數據類型(built-in vector data types),內置的向量數據類型基於基礎數據類型。例如:float4,表示float類型的4元向量;bool4,表示bool類型4元向量。


    注意:向量最長不能超過4元,即在Cg程序中可以聲明float1、float2、float3、float4類型的數組變量,但是不能聲明超過4元的向量,例如:
 

float5 array ;// 編譯報錯


向量初始化方式一般爲:
 

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


較長的向量還可以通過較短的向量進行構建:
 

float2 a = float2(1.0, 1.0);

float4 b = float4(a, 0.0, 0.0);

 


此外,Cg還提供矩陣數據類型,不過最大的維數不能超過4*4階。例如:
 

float1x1 matrix1; // 等價於 float matirx1; x 是字符,並不是乘號!

float2x3 matrix2; // 表示2*3 階矩陣,包含6 float 類型數據

float4x2 matrix3;// 表示 4*2 階矩陣,包含 8 float 類型數據

float4x4 matrix4 ;// 表示4*4 階矩陣,這是最大的維數

 


矩陣的初始化方式爲:
 

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

 


    注意:Cg中向量、矩陣與數組是完全不同,向量和矩陣是內置的數據類型(矩陣基於向量),而數組則是一種數據結構,不是內置數據類型!這一點和C/C++中不太一樣,在C/C++中,這三者同屬於數據結構,數組可以構建向量和矩陣。下一節中將詳細闡述Cg中的數組類型。


5.2 數組類型


    “General-purpose arrays can only be used as 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”(文獻【3】的Array章節)。


    在着色程序中,數組通常的使用目的是:作爲從外部應用程序傳入大量參數到Cg的頂點程序中的形參接口,例如與皮膚形變相關的矩陣數組,或者光照參數數組等。


    簡而言之,數組數據類型在Cg程序中的作用是:作爲函數的形參,用於大量數據的轉遞。
Cg中聲明數組變量的方式和C語言類似:例如:
 

float a[10]; // 聲明瞭一個數組,包含10 float 類型數據

float4 b[10]; // 聲明瞭一個數組,包含10 float4 類型向量數據

 


對數組進行初始化的方式爲:
 

float a[4] = {1.0, 2.0, 3.0, 4.0}; // 初始化一個數組

 


要獲取數組長度,可以調用“.length”,例如:
 

float a[10];          // 聲明一個數組

int length = a.length; // 獲取數組長度

 


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

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

 


對多維數組取長度的方式爲:
 

int length1 = b.length;   // length1 值爲2

int length2 = b[0].length; // length2 值爲3

 


    數組和矩陣有些類似,但是並不是相同。 例如4*4階數組的的聲明方式爲:float M[4][4];4階矩陣的聲明方式爲:float4x4 M。前者是一個數據結構,包含16個float類型數據,後者是一個4階矩陣數據。float4x4 M[4],表示一個數組,包含4個4階矩陣數據。


    進行數組變量聲明時,一定要指定數組長度,除非是作爲函數參數而聲明的形參數組。並且在當前的profiles中,數組的長度和所引用的數組元素的地址必須在編譯時就知道。


    “Unsized arrays may only be declared as function parameters-they 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”(文獻【3】)。


    由於形參數組的概念與函數的概念緊密結合,所以將在第8章的8.1函數章節中進行統一闡述。


5.3 結構類型


    Cg語言支持結構體(structure),實際上Cg中的結構體的聲明、使用和C++非常類似(只是類似,不是相同)。一個結構體相當於一種數據類型,可以定義該類型的變量。引入結構體機制,賦予了Cg語言一絲面向對象的色彩。還記得C++中,結構體與類的區別嗎?沒有區別,除了默認訪問屬性在結構體中爲public,類中爲private,所以結構體與類是非常近似的,由此可以看出shader 語言的發展趨勢還是向着具有面向對象特性的高級語言。不過目前的Cg語言中的結構體以展現“封裝”功能爲主,並不支持繼承機制。


    結構體的聲明以關鍵字struct開始,然後緊跟結構體的名字,接下來是一個大括號,並以分號結尾(不要忘了分號)。大括號中是結構體的定義,分爲兩大類:成員變量和成員函數。例如,定義一個名爲myAdd的結構體,包含一個成員變量,和一個執行相加功能的成員函數,然後聲明一個該結構體類型的變量,代碼爲:
 

struct myAdd

{

      float val;

      float add(float x)

   {

        return val + x;

    }

};

myAdd s;

 


使用符號“ ”引用結構體中的成員變量和成員函數。例如:

 

float a = s.value;

float b = s.add(a);


 
    注意:在當前的所有的profile版本下,如果結構體的一個成員函數使用了成員變量,則該成員變量要聲明在前。此外,成員函數是否可以重載依賴於使用的profile版本。(文獻[3] 的structures and Member functions章節)


    一般來說,Cg的源代碼都會在文件首部定義二個結構體,分別用於定義輸人和輸出的類型,這二個結構體定義與普通的C結構定義不同,除了定義結構體成員的數據類型外,還定義了該成員的綁定語義類型( Binding Semantics),所謂綁定語義類型是爲了與宿主環境進行數據交換的時候識別不同數據類型的。目前Cg支持的綁定語義類型包括POSTION位置),COLOR(顏色),NORMAL(法向量),Texcoord(紋理座標)等類型。


    當頂點着色程序向片段着色程序傳遞的數據類型較多的情況下,使用結構體可以大大的方便代碼的編寫和維護。總而言之,使用結構體是一個好習慣,高智商的孩子都使用。


5.4 接口(Interfaces)類型


    Cg語言提供接口類型,實際上,我本人很少見到使用接口類型的着色程序,原因在於,Cg語言中的接口類型還不完善,不能被擴展和包含。此外,目前的GPU編程大多隻是針對獨立的算法進行編碼,規模較小,使用接口類型沒有太大的優勢。所以這裏對該類型並不多做說明。有興趣的讀者可以參閱文獻【3】的Interfaces章節。


5.5 類型轉換


    Cg中的類型轉換和C語言中的類型轉換很類似。C語言中類型轉換可以是強制類型轉換,也可以是隱式轉換,如果是後者,則數據類型從低精度向高精度轉換。在Cg語言中也是如此。例如:
 

float a = 1.0;

half b = 2.0 ;

float c = a+b ; // 等價於 float c = a + (float)b;

 


    當有類型變量和無類型常量數據進行運算時,該常量數據不做類型轉換,舉例如下:
 

float a = 1.0;

float b = a + 2.0; //2.0 爲無類型常量數據,編譯時作爲 float 類型

 


    Cg語言中對於常量數據可以加上類型後綴,表示該數據的類型,例如:

 

float a = 1.0;

float b = a + 2.0h; //2.0h half 類型常量數據,運算是需要做類型轉換

 


     常量的類型後綴(type suffix)有3種:
    f :表示float;
    h:  表示 half;
    x:  表示fixed


發佈了6 篇原創文章 · 獲贊 7 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章