Since generic vertex attributes are deprecated in OpenGL, I tried to rewrite my vertex shader using only custom attributes. And I didn't work for me. Here is the vertex shader:
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);
}
This works perfectly in OpenGL ES 2.0. However, when I try to use it with OpenGL I see black screen. If I change aNormal
to generic gl_Normal
everything works fine aswell (note that aPosition
works fine in both contexts and I don't have to use gl_Vertex
).
What am I doing wrong?
I use RenderMonkey to test shaders, and I've set up stream mapping in it with appropriate attribute names (aPosition and aNormal). Maybe it has something to do with attribute indices, becouse I have all of them set to 0
? Also, here's what RenderMonkey documentation says about setting custom attribute names in "Stream Mapping":
The “Attribute Name” field displays the default name that can be used in the shader editor to refer to that stream. In an OpenGL ES effect, the changed name should be used to reference the stream; however, in a DirectX or OpenGL effect, the new name has no affect in the shader editor
I wonder is this issue specific to RenderMonkey or OpenGL itself? And why aPosition
still works then?
Attribute indices should be unique. It is possible to tell OpenGL to use specific indices via
glBindAttribLocation
before linking the program. Either way the normal way is to query the index withglGetAttribLocation
. It sounds like RenderMonkey lets you choose, in which case have you tried making them separate?I've seen fixed function rendering cross over to vertex attributes before, where
glVertexPointer
can wind up binding to the first attribute if its left unbound (I don't know if this is reproducible any more).I also see some strange things when experimenting with attributes and fixed function names. Without calling
glBindAttribLocation
, I compile the following shader:and I get the following locations (via
glGetActiveAttrib
):When experimenting, it seems the use of
gl_Vertex
takes up index0
andgl_Normal
takes index2
(even if its not reported). I wonder if you throw in a padding attribute betweenaPosition
andaNormal
(don't forget to use it in the output or it'll be compiled away) makes it work.In this case it's possible the position data is simply bound to location zero last. However, the black screen with
aNormal
points to nothing being bound (in which case it will always be{0, 0, 0}
). This is a little less consistent - if the normal was bound to the same data as the position you'd expect some colour, if not correct colour, as the normal would have the position data.My feeling is then that RenderMonkey is using just
glVertexPointer
/glNormalPointer
instead of attributes, which I would have though would bind both normal and position to either the normal or position data since you say both indices are zero.Maybe this means "named streams" are simply not available in the non-ES OpenGL version?
This is unrelated, but in the more recent OpenGL-GLSL versions, a
#version
number is needed and attributes use the keywordin
.