OpenGL Shader变量传递

时间:2016-02-15 16:50:23

标签: c opengl shader

我阅读了许多文章和帖子,内容涉及从顶点着色器阶段向片段着色器传递矢量和矩阵等值。但我还是不确定这个: 如果你在顶点着色器中有一些out vars(我称之为vtxs),而片段着色器(frgs)中有一些vars,那么OpenGl如何关联它们以便它们引用相同的值(我忽略了这一事实:传递给frgs的值是插值的)?我必须按照某种顺序写下来吗?如果我写的话,OpenGl如何解释这些变量:

vtxs:

out float x;
out vec4 mvp;

frgs:

in vec4 mvp;
in float x;
in double newvar;

注意:我改变了var类型,并且在frgs中有1个以上的var,然后在vtxs中有vars。

我看到布局列表中的位置规范是一种分配...地址的方法吗? ...到一个变量,但我有一个古老的上网本不支持这样一个变量装饰。

并作为提示:你知道某种调试着色器吗?我的意思是,在cpu程序中你可以添加一些printfs,但我没有在glsl中看到这样的函数...

总而言之,这是我的问题:

  1. 你用布局指定了什么(location = ...)有关着色器的后果是什么?

  2. 各种着色器阶段之间的值匹配/关联如何工作?有没有" location ="?

  3. 调试glsl着色器

2 个答案:

答案 0 :(得分:3)

默认情况下,输入和输出在接口之间按名称匹配。对于顶点着色器输入,默认的“自动”索引分配是arbitrary,因为它可能在实现之间有所不同。

layout限定符允许显式指定输入\输出的存储类型和位置。由于顶点输入的自动分配是任意的,您应该使用GLSL中的layout位置或函数glBindAttribLocation​来保证苹果是苹果和橘子橙。

因此layout规范在顶点着色器中非常常见。但它可以在任何界面之间使用。例如,如果您没有为vec4float使用相同的名称,那么您就完成了

<强> vtxs:

layout(location = 0) out float x;
layout(location = 1) out vec4 mvp;

<强> frgs:

layout(location = 0) in float y;
layout(location = 1) in vec4 pvm;

现在,界面中没有的任何输入都会破坏管道。如果您使用新变量

in double newvar;

然后glLinkProgram将失败。

<强>调试: 第一个调试步骤是检查状态着色器编译和链接。失败时,您可以使用glGetShaderInfoLog检索错误。

//compilation
glCompileShader(shader);
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if(!success)
{
    GLchar infoLog[512];
    glGetShaderInfoLog(shader, 512, NULL, infoLog);
}

//program
glLinkProgram(shaderProgram);
GLint success;
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if(!success)
{
    GLchar infoLog[512];
    glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
}

你也可以

答案 1 :(得分:1)

默认情况下,阶段之间的变量按名称匹配。

对于位置,您可以在概念上将阶段之间传递的数据视为vec4的数组。然后location是我们用来传递该变量的数组的索引。

大于vec4的类型会获得多个连续位置。对于较新的opengl版本(或ARB_enhanced_layouts),这些也是一个组件布局限定符,用于在该vec4数组中更紧密地打包值。

我不确定在按名称和位置进行匹配时如何分配位置。