在单个OpenGL程序中附加多个相同类型的着色器?

时间:2012-02-06 22:24:00

标签: opengl

在阅读OpenGL规范时,我注意到它提到你可以在一个程序中包含多个相同类型的着色器(即多个GL_VERTEX_SHADER附带glAttachShader)。特别是在OpenGL 4.2,§2.11.3,程序对象:“相同类型的多个着色器对象可以附加到单个程序对象......”。

OpenGL管道程序和子程序可能适用于此处,但这是在存在之前定义的(实际上它可以追溯到2.1规范,§2.15.2)所以我正在寻找这个想法的前GL4示例。当我做一些简单的测试时,我发现包含多个void main()会导致链接错误。有人知道使用它的实用示例吗?

2 个答案:

答案 0 :(得分:27)

您可以将常用功能放在单独的着色器中。然后只编译一次,并在多个程序中链接。

类似于编译cpp文件一次以获取静态或共享库的方式类似。然后将此库链接到多个可执行程序,从而节省编译时间。

假设你有复杂的照明功能:

vec3 ComputeLighting(vec3 position, vec3 eyeDir)
{
    // ...
    return vec3(...);
}

然后,对于要使用此功能的每个着色器,请执行以下操作:

vec3 ComputeLighting(vec3 position, vec3 eyeDir);

void main()
{
    vec3 light = ComputeLighting(arg1, arg2);
    gl_FragColor = ...;
}

然后分别编译常用着色器和主着色器。但是只编译一次普通着色器。

答案 1 :(得分:7)

  

我发现包含多个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; 
}

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);
}