我想离开OpenGL的灯,自己做。我希望我的着色器允许可变数量的灯光。
我们可以在GLSL着色器中声明统一数组吗?如果是这样,我们将如何设置这些制服的值?
Answers:
是的,这是可能的。您可以声明与C中类似的统一数组,例如
uniform float v[10];
然后您可以使用 glUniform{1,2,3,4}{f,i}v
GLfloat v[10] = {...};
glUniform1fv(glGetUniformLocation(program, "v"), 10, v);
glUniform1fv
。有人会认为的第二个参数glUniform1fv
仅仅是一种形式,应该始终将其用作
vec4
使用glUniform1fv( uniformId, 4, v ) ;
where设置v
4个float数组来设置统一。
i
不透明色除外1i
)。如果您说1f
,则制服必须为1个浮点数。否则,GL_INVALID_OPERATION
随之而来。
{1234}
函数中的@ MilesRufat-LatreglUniform
讲述了统一变量的类型。1f表示单个浮点数,2i表示ivec2,依此类推。这不应与count
函数采用的第二个参数(即数组大小)相混淆。因此,要上传到uniform vec2 vecs[5];
,这将会是glUniform2fv(loc, 5, data);
。
是的,可以在GLSL着色器中声明一个统一数组。只是谷歌“ GLSL统一数组”的一些例子(编辑:或参见datenwolf的例子)。但是,可以发送多少张制服到不同的图形卡上有一些限制(至少在较旧的显卡上,我不确定当前的显卡(尽管我想还会有))。
如果您确实决定沿制服路线走,我建议您使用制服缓冲区。根据http://www.opengl.org/wiki/Uniform_Buffer_Object的说法,“在统一缓冲区绑定之间切换通常比在程序中切换数十个统一制服要快”。
如果您有大量的灯光和参数,则还可以将数据作为浮点缓冲区发送。
Glint result; glGetIntegerv(GL_MAX_UNIFORM_LOCATIONS, 0, &result);