抄“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

Cg(c for graphic)语言的数据类(转)的更多相关文章

  1. SQL语言学习-数据定义语言

    Sql语言至今已经有6个版本.SQL查询语言包括了所有对数据的操作命令,这些操作可分为四类:数据定义语言(DDL).数据操纵语言(DML).数据控制语言(DCL)和嵌入式SQL语言. 数据定义语言(D ...

  2. Kotlin——最详细的数据类、密封类详解

    在前面几个章节章节中,详细的讲解了Koltin中的接口类(Interface).枚举类(Enmu),还不甚了解的可以查看我的上一篇文章Kotlin--接口类.枚举类详解.当然,在Koltin中,除了接 ...

  3. Python Cookbook(第3版)中文版:15.19 从C语言中读取类文件对象

    15.19 从C语言中读取类文件对象¶ 问题¶ 你要写C扩展来读取来自任何Python类文件对象中的数据(比如普通文件.StringIO对象等). 解决方案¶ 要读取一个类文件对象的数据,你需要重复调 ...

  4. R语言——实验5-聚类分析

    针对课件中的例子自己实现k-means算法 调用R语言自带kmeans()对给定数据集表示的文档进行聚类. 给定数据集: a)         数据代表的是文本信息. b)        第一行代表词 ...

  5. SQL语言分为五大类

    SQL语言分为五大类:DDL(数据定义语言) - Create.Alter.Drop 这些语句自动提交,无需用Commit提交.DQL(数据查询语言) - Select 查询语句不存在提交问题.DML ...

  6. 浅谈C语言的数据存储(一)

    作者:冯老师,华清远见嵌入式学院讲师. 程序由指令和数据组成,C语言程序亦是如此.开发者在编写程序的时候往往需要根据不同数据的特点以及程序需求来选择不同的数据存储方式,那么在C语言中数据的存储分为哪些 ...

  7. 代码的坏味道(16)——纯稚的数据类(Data Class)

    坏味道--纯稚的数据类(Data Class) 特征 纯稚的数据类(Data Class) 指的是只包含字段和访问它们的getter和setter函数的类.这些仅仅是供其他类使用的数据容器.这些类不包 ...

  8. R语言进行数据预处理wranging

    R语言进行数据预处理wranging li_volleyball 2016年3月22日 data wrangling with R packages:tidyr dplyr Ground rules ...

  9. Java数据类型和MySql数据类型对应一览

    类型名称 显示长度 数据库类型 JAVA类型 JDBC类型索引(int) 描述             VARCHAR L+N VARCHAR java.lang.String 12   CHAR N ...

随机推荐

  1. bsp开发之驱动开发

    驱动程序是可以管理虚拟设备或者物理设备,协议,服务等得软件模块,操作系统仅仅有通过驱动程序才干訪问硬件.针对windows ce开发设备驱动.就是通过platform builder创建一个新的平台, ...

  2. 使用maven创建项目和cannot change version web module 3.0

    近期下载了最新的Eclipse mars.2, 这个eclipse自带了maven插件,于是就用maven尝试创建一个java web项目. 第一步,例如以下图所看到的选择 Maven Project ...

  3. 键值对集合Dictionary<K,V>根据索引提取数据

    Dictionary<K,V>中ToList方法返回 List<KeyValuePair<K,V>>定义可设置检索的键/值对

  4. C语言语句

    /*Console.Write("你能跑得过豹子吗,请输入 能/不能:"); string a = Console.ReadLine();//接收所输入的字符串内容, if (a= ...

  5. sql server 关于表中只增标识问题 C# 实现自动化打开和关闭可执行文件(或 关闭停止与系统交互的可执行文件) ajaxfileupload插件上传图片功能,用MVC和aspx做后台各写了一个案例 将小写阿拉伯数字转换成大写的汉字, C# WinForm 中英文实现, 国际化实现的简单方法 ASP.NET Core 2 学习笔记(六)ASP.NET Core 2 学习笔记(三)

    sql server 关于表中只增标识问题   由于我们系统时间用的过长,数据量大,设计是采用自增ID 我们插入数据的时候把ID也写进去,我们可以采用 关闭和开启自增标识 没有关闭的时候 ,提示一下错 ...

  6. 混合minxins

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. spring中Bean创建

    Spring中bean的加载过程: 1.获取配置文件资源 2.对获取的xml资源进行一定的处理检验 3.处理包装资源 4.解析处理包装过后的资源 5.加载提取bean并注册(添加到beanDefini ...

  8. Unity自己主动打包工具

    最開始有写打包工具的想法,是由于看到<啪啪三国>王伟峰分享的一张图,他们有一个专门的"工具程序猿"开发各种工具. (ps:说起来这个王伟峰和他的创始团队成员,曾经跟我是 ...

  9. kbmMemTable关于内存表的使用,以及各种三层框架的评价

    关于内存表的使用(kbmMemTable) 关于内存表的使用说明一. Delphi使用内存表1.1 Delphi创建内存表步骤:1. 创建一个Ttable实例.2. 设置一个DataBaseName为 ...

  10. RTC脚本模型课堂 - ShowMessage(Star5的博客)

    ShowMessage对delphi开发人员而言,是个非常熟悉的玩意,常常需要在软件上做一些合适的提醒,以达到更好的用户体验.今天我们来介绍一下网站里的提示框,也就是JavaSciprt中的alert ...