|
|
Glsl 7.3
链接与运行shader
每个Shader会被独立的编译,为了组成一个完整的程序,需要将它们链接到一起。所以,我们用glCreateProgramObjectARB(void)
函数返回一个空GLhandleARB,作为将来要用的program对象。你可以指定哪些shader对象要被链接到这个program对象上去。同时,gl还要检查将要链接的各个shader是否能够"捆绑"在一起,比如vs fs之间的兼容性。当program对象里的部分shader不再被我们需要时,可以它们从program对象里剔除。
怎样链接呢?用这个函数:
void?glAttachObjectARB(GLhandleARB?program,GLhandleARB shader)
参数非常简单明了,一个是先前编译成功返回的shader对象的handle,另一个是刚生成的那个program对象的handle。
需要注意的是,program对象仅仅只是个装载shader对象的容器,这意味着,无论是否shaders里有代码,是否代码已经被编译,而同一个shader"粘"上多个program对象也是允许的。
我们当然希望program对象有效,可以被使用,所以,所有想到链接成program的shader都必然已经被正确的编译。Linker将标记所有uniform的位置,解析各个独立shader的引用情况,与检查vs fs的兼容性。使用函数void?glLinkProgramARB(GLhandleARB?program)
根据shaders的属性,如果是fs被链接,它将被自动在p上运行,fs亦然。
最好不要忘记使用glGetObjectParameterARB函数检查在program对象上,链接操作是否顺利完成。如果成功,首完所有用户自定的uniform值将被初始化为零,主程序中声明的每个uniform都需要先获得在shader里同名uniform的地址,即glUniform之前要先运行glGetUniformLocation。用户自定的attribute变量会有同样的操作。
如果program只有vs,那么vs将替代传统顶点处理管线,但fs依然是传统的那一套。同理,若只有fS,则传统顶点处理管线将被启用。
链接出错有几个原因:
attribute数目过多
uniform数目过多
Vs fs找不到main入口
varying变量没有同时在Vsfs里声明
引用的函数名或变量名有误
shader间被共享的全局变量被重复声明或有不同的初始化值
有shader对象没有编译成功
链接操作会覆盖上一次操作的记录。而且glLinkProgramARB函数在没有执行完之前不会返回。 记得用void?glUseProgramObjectARB(GLhandleARB?program)查询链接是否成功。如果重新链接一个正在使用中的program,那么新program将更新旧的program,更新状态机(如果链接成功)
补:一切正常之后,我们就可以用glUseProgramARB进行激动人心的可编程渲染了。我们知道,OpenGL的工作方式是状态机,当glUseProgram调用后,所有在函数调用之后的场景都是用Shader渲染的。如果我们不希望用shader渲染一些东西,那么在你的渲染场景的函数间调用glUseProgram(0)。
如何在一个渲染周期中使用多program呢?很简单 glUseProgram(p1)
Xxxcc//draw something
glUseProgram(p2)
Xxxcc//draw something
但这种方式很少用,大多数情况都是用单program实现渲染操作。
|
|