由于在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效果中,改变了 name应该用于引用流;但是,在DirectX或OpenGL效果中, 新名称在着色器编辑器中没有任何影响
我想知道此问题是否特定于RenderMonkey或OpenGL本身?为什么aPosition
仍然适用?
答案 0 :(得分:1)
属性索引应该是唯一的。在链接程序之前,可以通过glBindAttribLocation
告诉OpenGL使用特定索引。无论哪种方式,通常的方法是使用glGetAttribLocation
查询索引。听起来像RenderMonkey让你选择,在这种情况下你是否尝试将它们分开?
我之前看到固定函数渲染交叉到顶点属性,其中glVertexPointer
可以在第一个属性未绑定时结束第一个属性(我不知道这是否可以再现)。 / p>
在尝试使用属性和固定函数名称时,我也看到了一些奇怪的东西。不调用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
占用索引0
而gl_Normal
占用索引2
(即使未报告)。我想知道你是否在aPosition
和aNormal
之间输入了一个填充属性(不要忘记在输出中使用它或者它会被编译掉)使它工作。
在这种情况下,位置数据可能最后简单地绑定到零位置。但是,aNormal
的黑屏表示没有任何约束(在这种情况下,它始终为{0, 0, 0}
)。这有点不那么一致 - 如果法线与你期望某种颜色的位置相同的数据,如果不是正确的颜色,则法线会有位置数据。
允许应用程序绑定多个用户定义的属性 变量到相同的通用顶点属性索引。这就是所谓的 别名,仅在其中一个别名属性时才允许使用 在可执行程序中处于活动状态,或者如果没有通过着色器的路径 消耗了一组属性的多个属性 同一地点。
我的感觉是,RenderMonkey只使用glVertexPointer
/ glNormalPointer
而不是属性,我会将正常和位置绑定到正常或位置数据,因为你说两个索引是零。
在DirectX或OpenGL效果中,新名称在着色器编辑器中没有任何影响
也许这意味着“命名流”在非ES OpenGL版本中根本不可用?
这是不相关的,但在最近的OpenGL-GLSL版本中,需要#version
个数字,属性使用关键字in
。