2011-11-11 98 views
57

我想离开OpenGL的灯光,做我自己的。 我希望我的着色器允许可变数量的灯光。GLSL/C++:制服阵列?

我们可以声明制服的GLSL着色器的阵列? 如果是这样,我们将如何设置这些制服的价值?

+4

谁想要一个可变数目的灯,才使阵列体面的能力,并保持有多少灯是当前活动的计数。 GLSL不允许变量大小的数组(所有数组大小必须是常数,硬编码值)。 – Miles

回答

71

是的,这是可能的。你声明的统一数组类似于你在C中的做法,例如

uniform float v[10]; 

然后你就可以使用glUniform{1,2,3,4}{f,i}v

GLfloat v[10] = {...}; 
glUniform1fv(glGetUniformLocation(program, "v"), 10, v); 
+2

1,2,3,4是指什么?这是否意味着我只能将数组的值设置为最多四位成员? – Miles

+0

这是'glUniform1fv'的一个非常聪明/扭曲的用法。有人会认为,glUniform1fv'的'第二个参数是只是一种形式,它应该始终作为1 – bobobobo

+0

因此从技术上讲,你可以设置一个统一的'vec4'使用'glUniform1fv(uniformId,4,V);其中' 'v'是一个由4个浮点数组成的数组。 – bobobobo

7

是的,它可以声明在GLSL着色器制服的阵列设置它们的值。只是谷歌“glsl统一阵列”的一些例子(编辑:或见datenwolf的例子)。然而,有多少制服可以发送到不同的显卡(至少在较老的显示卡上有限制,我不确定目前的显示卡(尽管我想还是会有的))。

如果你决定走下来制服的路线,我会建议使用统一的缓冲器。根据http://www.opengl.org/wiki/Uniform_Buffer_Object,“统一缓冲区绑定之间的切换通常比切换程序中的几十个制服更快”。

如果你有大量的灯光和参数,你也可以发送数据为float缓冲区。

+6

统一缓冲区对象仅在GL版本3.1以后才可用。自2.0版以来,需要ARB_Uniform_Buffer_Object扩展。 –

+54

谷歌搜索“glsl uniform array”现在返回此页面作为第一个结果!我们现在干什么? – mlvljr

+1

您可以在运行时查询OpenGL以获得最大数量的具有'Glint结果的制服; glGetIntegerv(GL_MAX_UNIFORM_LOCATIONS,0,&result);' – rwols