赋值
表达式赋值到具体类型对象时,将表达式转换为该类型的对象,表达式的结果值被复制到该对象中。
赋值表达式(=,*=等)和C中定义的一致
一个赋值表达式在赋值后,有给予左值的值,但却不等同于左值。赋值表达式的类型是左值的类型,除非左值有一个修饰符。在这种情况下,赋值表达式的值是其对应的未修饰版本的值类型。更新左值产生的边界效应将发生在先前和接下来的指令序列之间。
一个动态类型的赋值表达式,只有在表达式类型是兼容类型时,才有可能实现。在到下一次赋值之前,该对象都将使用赋值表达式的值类型
标量转为向量
如果一个二元操作发生在向量和标量之间,标量会自动通过类型晋升为一个和另一个向量同样长度的向量,并将标量的值赋值到这个新向量中的每一个元素中。三元操作符?:同样支持。此时,这个规则先发生在第二和第三操作数,然后在将该结果和第一操作数上使用该规则。
命名空间
和C一样,有两种命名空间,每种有多个作用域
标签命名空间,有结构标签组成
即每个使用tag方式定义的结构,其内部形成一个命名空间,比如
struct {...}
一般命名空间的组成
- typedef 名称(这个名称可以是是结构声明时自动使用typedef定义的结构名)
- 变量
- 函数名
常量缓存
常量缓存是用来在Cg中定义一个uniform的块,一个常量缓存使用uniform关键字定义
uniform{…}:BUFFER[[N]]
N代表单位数量,可选。每一个定义在块内的对象,在缓存中都有唯一的空间
数组和下标
数组声明除了可以选则的使用packed以外,和C中的声明一样。数组在cg中是第一类类型,因此函数或是程序的数组参数必须使用数组语法声明,而不是指针语法。同样的,数组类型对象的赋值是一个数组copy,而不是一个指针copy
[1]长度的数组代表的是数组,其类型是不同于对应的非数组类型的。(意思就是int[1]和int不是一个类型)
由于Cg语言目前不支持指针,数组的存储顺序只有在应用传递参数到顶点或是栅格化的程序时才是可见的。因此,目前编译器可以在它认为的合适的地方自由分配临时的数组变量
声明和使用数组的数组和C中的风格一样,二维数组的声明如下
float A[4][4]
同时,下述的语句为true
数组索引为A[行][列]
数组可以使用如下的构造函数
float4x4 A = { { A[0][0], A[0][1], A[0][2], A[0][3] },
{ A[1][0], A[1][1], A[1][2], A[1][3] },
{ A[2][0], A[2][1], A[2][2], A[2][3] },
{ A[3][0], A[3][1], A[3][2], A[3][3] } };
A[0]等同于float4(A[0][0], A[0][1], A[0][2], A[0][3])
支持包含数组的结构
无长度数组
对象可以被声明为一个无长度的数组,使用一个不带有长度的[],并不带有初始化。如果一个的声明使用一个带有初始化的无长度数组语法,实际上相当于声明了一个有长度的数组类型。无长度数组是动态类型,可以接收任何长度的数组赋值给他们
最小数组需求
Profiles必须对某些类型的数组提供部分支持。所有的profiles都被设计为部分局部支持向量和矩阵。对向量profile,它被设计为支持光源的状态数组(由光源的数量来索引),并通过uniform的参数来传递。蒙皮矩阵的数组也作为uniform参数传递
Profile必须支持向量和矩阵的下标,复制,长度请求和语法糖访问。然后,在运行时计算下标索引并不要求支持。
顶点Profiles必须对作为一个uniform参数传递给程序,或者一个传递给程序的uniform结构中包含的非packed数组支持如下的操作。同样,当数组是间接的传递的uniform参数(只该数组,或是结构中包含的数组,通过一系列函数的输入参数传递),也必须满足这些要求。
以下三种操作必须支持
- 右值下标是运行时计算的,或是编译时产生的值
- 当对应的函数形参是输入参数时,将整个数组作为参数传递给函数
- 可以使用.length后缀来请求数组长度
以下操作时明确不支持的
- 左值下标索引
- 复制
- 其他比如乘法,加法,比较等操作
注意,当一个uniform数组作为右值并被使用下标索引时,其结果是一个表达式,而这个表达式不再被认为i是uniform的程序参数。因此,当这整个表达式结果是数组时,他接下去的使用必须按照标准的数组使用方式
这些规则不限于数值类型的数组,当数组作为程序的一个uniform参数时,包括结构数组,矩阵数组,和向量数组都遵循这些规则。最大的数组长度决定于可用的寄存器。在这种情况下编译器可以发出错误消息。然后,profile必须支持float arr[8], float4 arr[8], and float4x4 arr[4][4].的长度
栅格化profile不需要支持仁恒长度的数组的任何操作。只需要支持向量和矩阵。