0

由于 OpenGL 中不推荐使用通用顶点属性,因此我尝试仅使用自定义属性重写我的顶点着色器。而且我没有为我工作。这是顶点着色器:

attribute vec3 aPosition;
attribute vec3 aNormal;

varying   vec4 vColor;

vec4 calculateLight(vec4 normal) {
    // ...
}

void main(void) {
    gl_Position = uProjectionMatrix * uWorldViewMatrix * vec4(aPosition, 1);
    vec4 rotatedNormal = normalize(uWorldViewMatrix * vec4(aNormal, 0));
    vColor = calculateLight(rotatedNormal);
}

这在 OpenGL ES 2.0 中完美运行。但是,当我尝试将它与 OpenGL 一起使用时,我看到了黑屏。如果我更改aNormal为通用,gl_Normal一切正常(请注意,aPosition在两种情况下都可以正常工作,我不必使用gl_Vertex)。

我究竟做错了什么?

我使用 RenderMonkey 来测试着色器,并在其中使用适当的属性名称(aPosition 和 aNormal)设置流映射。也许它与属性索引有关,因为我将它们全部设置为0? 此外,这是 RenderMonkey 文档中关于在“流映射”中设置自定义属性名称的内容:

“属性名称”字段显示可在着色器编辑器中用于引用该流的默认名称。在 OpenGL ES 效果中,应使用更改后的名称来引用流;但是,在 DirectX 或 OpenGL 效果中,新名称对着色器编辑器没有影响

我想知道这个问题是否特定于 RenderMonkey 或 OpenGL 本身?为什么aPosition仍然有效呢?

4

1 回答 1

1

属性索引应该是唯一的。在链接程序glBindAttribLocation 之前可以告诉 OpenGL 使用特定的索引。无论哪种方式,正常的方法是使用glGetAttribLocation. 听起来 RenderMonkey 让您选择,在这种情况下您是否尝试过将它们分开?

我之前已经看到固定函数渲染交叉到顶点属性,glVertexPointer如果它未绑定,则可以最终绑定到第一个属性(我不知道这是否可以重现)。

在尝试属性和固定函数名称时,我还看到了一些奇怪的事情。不调用glBindAttribLocation,我编译以下着色器:

attribute vec4 a;
attribute vec4 b;
void main()
{
    gl_Position = gl_Vertex + vec4(gl_Normal, 0) + a + b;
}

我得到以下位置(通过glGetActiveAttrib):

a: 1
b: 3
gl_Vertex: -1
gl_Normal: -1

在实验时,似乎使用了gl_Vertex占用索引0gl_Normal占用索引2(即使没有报告)。aPosition我想知道你是否在and之间添加了一个填充属性aNormal(不要忘记在输出中使用它,否则它会被编译掉)让它工作。

在这种情况下,位置数据可能只是最后绑定到位置零。但是,黑屏aNormal指向什么都没有绑定(在这种情况下,它将始终是{0, 0, 0})。这有点不太一致 - 如果法线绑定到与您期望某些颜色的位置相同的数据,如果不是正确的颜色,因为法线将具有位置数据。

允许应用程序将多个用户定义的属性变量绑定到同一个通用顶点属性索引。这称为别名,仅当在可执行程序中只有一个别名属性处于活动状态,或者没有通过着色器的路径消耗一组别名到同一位置的属性中的一个以上属性时,才允许使用别名。

我的感觉是,RenderMonkey 只使用glVertexPointer/glNormalPointer而不是属性,尽管您说两个索引都为零,但我本来可以将法线和位置绑定到法线或位置数据。

在 DirectX 或 OpenGL 效果中,新名称在着色器编辑器中没有影响

也许这意味着“命名流”在非 ES OpenGL 版本中根本不可用?

这是不相关的,但在最近的 OpenGL-GLSL 版本中,#version需要一个数字并且属性使用关键字in

于 2014-01-29T09:24:38.450 回答