声明及声明修饰符
Cg程序有一系列的声明构成,每个声明由一个或多个函数或变量构成。每个声明,有零个或多个声明修饰符,类型,一个或多个声明组成。一些修饰符和标准C一样,一些是Cg中特有的
const
变量被定义成常量的话,在程序中,就不能再对该变量赋值,除非const和uniform,varying一起使用。const修饰的变量,需要在声明时给予一个初始值
extern
extern表明声明仅仅是声明,而非定义。在程序中一定有一个地方存在一个非extern的对应的声明
in
只在声明参数,或是使用varying修饰符时使用。将参数,或是varying作为函数或是程序的输入值。函数参数如果没有in,out,或者inout的话,隐式的默认为in
inline
只在函数定义时有用,告诉编译器始终对该函数采取内联调用
inout
只在声明为参数和varying时使用,将参数或是varying声明为函数或是程序的输入输出值
static
只在声明全局变量时使用,static将使变量对程序而言成为私有的,外部不可见,不能和uniform,varying一起使用
out
只在声明参数和varying时使用,将变量或varying定义为函数或是程序的输出值
uniform
用于全局变量和程序的入口函数的参数,用来定义constant buffers(常量缓存)。如果用于一个非入口函数的参数,它将被忽略。这样做的目的是为了使一个函数既能作为入口函数,又能作为非入口函数。uniform的变量可以像非uniform的变量那样读写。uniform修饰符通过向外部语言提供一个机制,来提供变量的初始值是如何指定和保存的信息。
这段话的意思,结合前一篇文章中的说明,就是说uniform修饰的变量,其初始值不是由cg程序内部指定,而是由外部程序指定的。并且一旦指定后,在GPU的并发调用中,这段程序即使被多次调用,这个初始值还是不变的,直到外部程序改变了这个值。
即便初始值不变,但在这段cg程序执行内,这个uniform变量就和一般的变量读写没有区别了注:这个外部程序是指当前编译后,并执行的入口函数及其调用程序以外的不相关的程序。比如说我们编译了一段cg代码,其中有一个入口函数,和N个被调用函数,那么我们编译的另一段cg代码,或者我们使用c等语言编写的调用这段cg程序的代码,就是外部程序
varying
只用于程序的顶层main函数的参数,或是全局变量。如果用于非顶层函数,将被忽略
profile name
任何profile的名字,或是通配符可以在任何函数的声明之前指定。限定了函数只在对应的profile中可见
uniform和varying
uniform和varying修饰符,指定了一段Cg程序和外部程序之间的数据传递的方式。典型的,一个uniform变量或是参数的初始值被存储与不同的硬件寄存器类中来表示一个varing变量。进一步的,外部机制指定的uniform的变量或是参数的初始值的方式不同与对varying变量或是参数的初始值。使用uniform修饰的参数通常看成是永久状态,而varying看成是流状态数据,每条流记录都有一个新的值
非静态的全局变量默认是uniform的,顶层函数的参数,默认是varying
老实说,原文的这一段关于uniform和varying的说明很晦涩,结合先前提到的对uniform的解释,我目前理解这段内容表述的是(有可能过几天我理解深入了,就会重新写,哈哈,表扔我鸡蛋)
uniform可以保证在不同的代码执行中,数据的初始值是保持不变的。如果要使这个值变化,那只有将初值值保存在不同的硬件寄存器中。那么,这种情况可能出现在这段cg代码正运行于不同的渲染阶段。不同的渲染阶段,其使用的硬件不同,因此这时对该值进行的值才会不同。而varying则相反,即时在同一渲染阶段,随着输入的数据不同,值就发生变化。
每个声明在其声明点到封闭块的结尾是可见的,或是如果其在块外部,则到该段编译对象结尾是可见的。在有命名的范围(比如结构,接口)中的声明,如果使用显示的范围修饰符可以在其范围外可见,这个和C++类似