管道程序中着色器之间的输入/输出变量

时间:2012-01-20 09:27:59

标签: opengl opengl-3

我目前正在使用3个不同的着色器(顶点,几何和片段),每个着色器属于不同的程序,所有这些都在一个程序管道中收集。

问题在于Geometry和Fragment将其变量归零,也就是说,它们不包含先前由管道中的前一个着色器写入的值。

每个着色器

glCreateShader(...)
glShadersource(...)
glCompileShader(...)
glGetShaderiv(*shd,GL_COMPILE_STATUS,&status)
每个程序

program[index] = glCreateProgram()
glAttachShader(program[index],s[...])
glProgramParameteri(program[index],GL_PROGRAM_SEPARABLE,GL_TRUE)
glLinkProgram(program[index])
glGetProgramiv(program[index],GL_LINK_STATUS,&status)

然后:

glGenProgramPipelines(1,&pipeline_object)

在gl draw中:

glBindProgramPipeline(pipeline_object)
glUseProgramStages(pipeline_object,GL_VERTEX_SHADER_BIT,program[MY_VERTEX_PROGRAM])
and again for the geometry and fragment programs

顶点着色器:

#version 330

//modelview and projection mat(s) skipped
...

//interface to geometry shader
out vec3 my_vec;
out float my_float;

void main() {
    my_vec = vec3(1,2,3);
    my_float = 12.3;
    gl_Position = <whatever>
}

几何着色器:

#version 330

//input/output layouts skipped
...

//interface from vertex shader
in vec3 my_vec[];
in float my_float[];
//interface to fragment shader
out vec3 my_vec_fs;
out float my_float_fs;

void main() {
    int i;
    for(i=0;i<3;i++) {
        my_vec_fs = my_vec[i];
        my_float_fs = my_float[i];
        EmitVertex();
    }
    EndPrimitive();
}

片段着色器:

#version 330

//interface from geometry
in vec3 my_vec_fs;
in float my_float_fs;

void main() {
    here my_vec_fs and my_float_fs come all zeroed
}

我是否错过了在程序管道中不同阶段之间写/读的一些关键步骤?

更新:

我尝试使用布局位置限定符,以确保每个人都在同一个向量上“讨论”,因为GLSL规范声明:

  

layout-qualifier-id location =整数常量   只接受一个论点。例如,vec4 normal中的layout(location = 3);将确定将着色器输入法线分配给向量位置编号3.对于顶点着色器输入,该位置指定从中获取输入值的通用顶点属性的编号。对于所有其他着色器类型的输入,该位置指定一个向量编号,该编号可用于匹配前一个着色器阶段的输出,即使该着色器位于不同的程序对象中。

但添加

layout(location = 3) out vec3 my_vec;

无法编译

所以我尝试通过glBindAttribLocation()做同样的事情,我得到没有错误,但行为仍未改变

更新2

如果我添加    “#extension GL_ARB_separate_shader_objects:enable”

然后我可以使用layout(location = n)in / out var; 然后就可以了。

找到:

GLSL 330: Vertex shaders cannot have output layout qualifiers
GLSL 420: All shaders allow location output layout qualifiers on output variable declarations

这很有趣..如果你声明#version 330你就不能使用布局输出限定符,即使你启用扩展名也是如此。 ..但扩展名再次声明:

  

此ARB扩展扩展了GLSL语言对布局限定符的使用,以提供跨阶段接口。

现在我想知道为什么它不能使用glBindAttribLocation()或仅使用普通名称匹配+ ARB扩展启用!

1 个答案:

答案 0 :(得分:0)

在至少一个实现中(我认为是webgl和旧的chrome)我发现了glBindAttribLocation()的错误我认为问题是,你必须按数字顺序绑定顶点属性。事实证明使用它没有用。我不得不切换到getAttribLocation()才能让它发挥作用。