IOviSpot
IOviSpot

Reputation: 368

Why can I not use multiple "in" variables in GLSL?

Consider my shader program.

const char* vert_shader_script =

"#version 330 core\n                                    \n\
                                                        \n\
layout(location = 0) in vec3 vertex_pos;                \n\
layout(location = 1) in vec2 texture_uv;                \n\
                                                        \n\
uniform mat4 M, V, P;                                   \n\
                                                        \n\
out vec2 uv;                                            \n\
                                                        \n\
void main() {                                           \n\
                                                        \n\
    gl_Position = P * V * M * vec4(vertex_pos, 1.0);    \n\
    uv = texture_uv;                                    \n\
}\n";

const char* frag_shader_script =

"#version 330 core                                                                  \n\
                                                                                    \n\
uniform sampler2D texture0;                                                         \n\
uniform vec4 override_color;                                                        \n\
uniform vec2 player_pos;                                                            \n\
                                                                                    \n\
in vec2 uv;                                                                         \n\
in int gl_VertexID; // This causes it!                                                              \n\
                                                                                    \n\
out vec4 out_col;                                                                   \n\
                                                                                    \n\
void main() {                                                                       \n\
                                                                                    \n\
    vec4 tex_color = texture2D(texture0, uv);                                       \n\
    float alpha = 1.0;                                                              \n\
                                                                                    \n\
    if (tex_color.r == 1.0 && tex_color.g == 0.0 && tex_color.b == 1.0)             \n\
        alpha = 0.0;                                                                \n\
    else {                                                                          \n\
                                                                                    \n\
        if (override_color.a > 0.0)                                                 \n\
            tex_color = override_color;                                             \n\
        else {                                                                      \n\
                                                                                    \n\
            tex_color.r = max(tex_color.r - 0.9, 0.1);                              \n\
            tex_color.g = max(tex_color.g - 0.9, 0.1);                              \n\
            tex_color.b = max(tex_color.b - 0.9, 0.1);                              \n\
        }                                                                           \n\
    }                                                                               \n\
                                                                                    \n\
    out_col = vec4(tex_color.r, tex_color.g, tex_color.b, alpha);                   \n\
}\n";

Everything works fine until I've added the in int gl_VertexID in the fragment shader. Nothing but the background color gets drawn. Not only does it happen when I use gl_VertexID, but even when I'm trying to add my own in variable below uv, it happens. I am trying to pass vertex_pos from the vertex shader to the fragment shader by creating a new out pos in the vertex shader, create in pos in the fragment shader then change it in the vertex shader before it gets sent to the fragment shader. But, the problem occurs immediately after adding another in variable inside of the fragment shader.

Am I only allowed to use one at a time? Is something else happening here, like a missing gl function in my C++ code? The only things I'm using before and upon rendering at the moment is:

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glDepthFunc(GL_LESS);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);

Even without them except the first one, the problem still occurs.

EDIT: There are no error/warning messages in the logs of both vertex and fragment shaders.


UPDATE: I've relocated the gl_VertexID from the fragment shader to the vertex shader and solved any possible problems I may get int the future. However, I've noticed when my current issue actually occurs, but do not know why.

Consider the updated shaders as such:

// Vertex Shader
...
in int gl_VertexID;
out int vert_id;

void main() {

    ...
    vert_id = gl_VertexID;
}

// Fragment Shader
...
in int vert_id;

void main() {

    ...
    if (vert_id == 0) {

        // Empty statement for testing purposes.
    }
    else {

        // This statement is empty as well.
    }

    ...
    // Draw normally. Apply regular data to the out_color vector. Nothing else has been changed nor prevents the code from reaching the declaration. But doesn't it really?
}

The issue lies within assigment of the vert_id variable. If I were to keep everything except the vert_id = gl_VertexID from the vertex shader's main function, the issue would not occur but as soon as I give the vert_id any value, it does not draw anything besides the background color. This likely occurs when I am doing checking in the fragment shader, mainly if (vert_id == N), because upon removing that instead of the assignment in the vertex shader, the issue does not persist. What am I doing wrong here? There are still no errors reported in the logs.

Upvotes: 1

Views: 622

Answers (2)

derhass
derhass

Reputation: 45322

There is no interpolation support for integral types. So if you want to forward integral values to the fragment shader, you must use the flat interpolation qualifier:

VS:

flat out int vert_id;

FS:

flat in int vert_id;

it does not draw anything besides the background color

That's because your shaders are failing to compile or link. You should query the Shader and Program info logs, and actually read them.

Upvotes: 0

Nicol Bolas
Nicol Bolas

Reputation: 473192

All identifiers starting with gl_ are reserved for the GLSL specification. You don't get to reinvent them. You can redeclare some of them, but only if they already exist in some form in that shader stage.

To whit:

until I've added the in int gl_VertexID in the fragment shader

gl_VertexID is a built-in variable that defines which vertex index a particular input vertex comes from. Since fragment shaders process fragments, not vertices, this variable is not available in an FS (a fragment is generated by primitives, which can be built from multiple vertices. So you wouldn't know which vertex to get the index from). If you want to pass some kind of identifier to an FS, you're going to have to make your VS provide that data.

Upvotes: 7

Related Questions