在阅读OpenGL规范时,我注意到它提到你可以在一个程序中包含多个相同类型的着色器(即多个GL_VERTEX_SHADER附带glAttachShader).特别是在OpenGL 4.2,§2.11.3,程序对象:"相同类型的多个着色器对象可以附加到单个程序对象......".
OpenGL管道程序和子程序可能适用于此处,但这是在存在之前定义的(事实上它可以追溯到2.1规范,§2.15.2),所以我正在寻找这个想法的前GL4示例.当我做一些简单的测试时,我发现包含多个void main()导致链接错误.有人知道一个使用它的实际例子吗?
Mār*_*iko 27
您可以将常用功能放在单独的着色器中.然后只编译一次,并链接到多个程序.
它类似于您只编译一次cpp文件以获取静态或共享库.然后将此库链接到多个可执行程序,从而节省编译时间.
假设你有复杂的照明功能:
vec3 ComputeLighting(vec3 position, vec3 eyeDir)
{
// ...
return vec3(...);
}
Run Code Online (Sandbox Code Playgroud)
然后,对于要使用此功能的每个着色器,请执行以下操作:
vec3 ComputeLighting(vec3 position, vec3 eyeDir);
void main()
{
vec3 light = ComputeLighting(arg1, arg2);
gl_FragColor = ...;
}
Run Code Online (Sandbox Code Playgroud)
然后分别编译常用着色器和主着色器.但是只对常见着色器进行一次编译.
我发现包含多个void main()会导致链接错误
对于每个着色器阶段,必须只有一个主入口函数.
使用它的实际例子(GL4之前)?
您可以在着色器源中声明一个函数而不是定义它,并且在链接时您可以从另一个着色器源提供定义(非常类似于c/c ++链接).
例:
generate_txcoord.glsl:
#version 330
precision highp float;
const vec2 madd = vec2(0.5, 0.5);
vec2 generate_txcoord(vec2 v)
{
return v * madd + madd;
}
Run Code Online (Sandbox Code Playgroud)
vertex.glsl:
#version 330
precision highp float;
in vec2 vxpos;
out vec2 out_txcoord;
vec2 generate_txcoord(vec2 vxpos); // << declared, but not defined
void main()
{
// generate 0..+1 domain txcoords and interpolate them
out_txcoord = generate_txcoord(vxpos);
// interpolate -1..+1 domain vxpos
gl_Position = vec4(vxpos, 0.0, 1.0);
}
Run Code Online (Sandbox Code Playgroud)