《GPU编程与CG语言之阳春白雪下里巴人》- 第五章(CG 数据类型)

第05章 CG 数据类型

书读的越多而不加思考,你就会觉得你知道得很多;而当你读书而思考得越多的时候,你就会越清楚地看到,你知道得很少。
                                   ------ 伏尔泰

本章将着重介绍 Cg 语言中预定义的内置(built in)的、或称为基本(primitive)的数据类型。然后介绍可以用来声明对象的各种类型,主要是数组和结构类型。学习本章时,需要体会内置向量类型和数组类型的区别。

5.1 基本数据类型

Cg 支持 7 种基本的数据类型:

  1. float, 32 位浮点数据,一个符号位。浮点数据类型被所有的 Profiles 支持(但是 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,字符类型,该类型不被当前存在 Profiles 所支持,实际上也没有必要在 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; // 编译报错

向量初始化方式一般为:

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

较长的向量还可以通过较短的向量进行构建:

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

此外,Cg 还提供矩阵数据类型,不过最大的维数不能超过 4 * 4 阶。例如:

  float1x1 matrix1;  // 等价于 float matirx1; x 是字符,并不是乘号;
  float2x3 matrix2; // 表示2 * 3 阶矩阵,包含了 6 个 float 类型数据;
  float4x3 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 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”(文献【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};  // 初始化一个数组;

要获取数组长度,可以调用“.legth”,例如:

  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-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”(文献【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;
    }
  };
  myAdds;

使用符号“.”引用结构体中的成员变量和成员函数。例如:

  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(纹理坐标)等类型。
  当顶点着色程序向片段着色程序传递的数据类型较多的情况下,使用结构体可以大大的方便代码的编写和维护。总而言之,使用结构体是一个好习惯,高智商的孩子都使用(感觉是不是很囧 哈哈哈 O(∩_∩)O哈哈~)。

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;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354

推荐阅读更多精彩内容