Using gl_InstanceID weird issue

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.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.