hey, although i have some experience with modern opengl, i haven’t dealt with GS and instancing much.
what i’m trying to achieve is to render to 3-dimensional FBO using glDrawElementsInstanced and gl_InstanceID;
and i’ve encountered a problem writing geometry shader for that purpose. if i have basic passthrought geometry shader - everything is fine, objects do render(tested it with normal rendering, without 3d-texture FBO). but if anywhere in the code i mention gl_InstanceID - all glGetUniformLocation and glGetAttribLocation calls for that program fail with GL_INVALID_OPERATION(it’s “program has not been successfully linked”, because i do check with glIsProgram and it returns “true”). however i am calling glGetError after glLinkProgram and it returns 0. and compile logs are empty. if i write something intentionally erroneous inside GS like “asdasfas” - i get proper compile log with error. but if i use gl_InstanceID - it just silently fails.
example of failing code:
#version 330
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
void main() {
gl_Layer = gl_InstanceID; //if i remove that line - it works
for(int i = 0; i < 3; i++) {
gl_Position = gl_in[i].gl_Position;
EmitVertex();
}
EndPrimitive();
}
Edit: ok, i found out i didn’t check GL_LINK_STATUS after linking, only glGetError. and it, indeed, fails to link. but i have no idea why yet.
According to the GLSL Spec, there is no built-in gl_InstanceID in the geometry language. I guess you need to pass it from the vertex shader - should yield a compile-time error, however. Does that make sense? Obviously it did to the ARB.
ok, that was quite idiotic. my application didn’t output glGetProgramInfoLog to log-file because there was no detected OpenGL error at the stage of linking. it actually says “0(5) : error C5052: gl_InstanceID is not accessible in this profile”. i am using WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB. does it require forward compatibility? i haven’t seen it mentioned anywhere.
that is puzzling… why does it say it’s not “accessible”?
i found line “gl_Layer = gl_InstanceID;” here . but he was probably writing it like that to make it shorter. because, indeed, GLSL documentation only defines gl_InstanceID for vertex processing stage.
if i do it like that:
in VS:
out int instanceID;
void main(void)
{
...
instanceID = gl_InstanceID;
}
GS:
#version 330
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
in int instanceID[3];
void main(void) {
for(int i = 0; i < 3; i++) {
gl_Layer = instanceID[i];
gl_Position = gl_in[i].gl_Position;
EmitVertex();
}
EndPrimitive();
}
it doesn’t complain. so, i guess, it’s solved. unless i screwed up somewhere else. it’s going to take some time until i will be abl to actually test it with rendering to 3d-texture.
Well, it doesn’t actually make sense to not include gl_InstanceID in the geometry language. The ID will not change across primitives as it is associated with a draw call. Sure, you can pass it down the pipeline yourself but it could very well be a built-in. On the other hand, you could simply set the instance ID yourself using a plain old uniform which you increment (or calculate otherwise) for every instanced draw call. However the purpose of the built-in is probably to make the latter variant unnecessary.
yes, writing lines “in int instanceID[3];” and “gl_Layer = instanceID[0];” made me cringe a little bit. i presume it says it’s not accessible in this profile for GS, because they plan to make it available in future versions.