GLSL program fails to link without errors

Hi all,

I’m trying to use a Geometry shader.
My OpenGL program is compossed by this 3 shaders:

//#shader vertex
#version 330 core
layout(location=0) in vec4 position;
layout(location=1) in float type;

uniform vec4 u_colors[4];
out vec4 fragmentColor;
uniform mat4 u_view;
uniform mat4 u_model;
uniform mat4 u_proj;
void main() {
    gl_Position = u_proj * u_view * u_model * position;
    fragmentColor = u_colors[int(type)];

//#shader fragment
#version 330 core
in vec4 fragmentColor;
out vec4 color;
void main() {
    color = fragmentColor;

//#shader geometry
#version 330
layout (lines) in;
layout (line_strip, max_vertices = 2) out;
in vec4 vFragColorVs[2];
out vec4 vFragColor;
void main(void) {
     int i;
     for ( i=0; i < gl_in.length(); i++) {
          vFragColor = vFragColorVs[i];
          gl_Position = gl_in[i].gl_Position;

When I try to compile it there are no compilation errors.
Thats the code that I use to link:


    GLint isLinked = 0;
    glGetProgramiv(rendererID, GL_LINK_STATUS, &isLinked);
    if (isLinked == GL_FALSE)
        int length;
        std::string log;
        glGetProgramiv(rendererID, GL_INFO_LOG_LENGTH, &length);
        log.reserve(static_cast<unsigned long>(length));
        glGetProgramInfoLog(rendererID, length, &length, &log[0]);

        // The program is useless now. So delete it.
        std::cerr << "cannot Link: " << log << std::endl;
        throw std::runtime_error("cannot link opengl program");

The output is only cannot link: without a log message.
The program without the Geometry shader links and works well.

Where is the mistake?

I believe what you’re doing with trying to reading the link log into a std::string isn’t portable.

Try this: Shader_Compilation#Error_handling. That is, read it into a vector of chars, or into a raw char array.

string::reserve() only reserves space; the length will still be zero. Use e.g.

log.assign(length, '\0');

to enlarge the string. Or just create the string at the appropriate size:

std::string log(length, '\0');

Note that a vector has essentially the same issue; vector::reserve() will only reserve space, it won’t change the length.

The fragmentColor is the issue. You need to pass the colour from the vertex shader, to the geom shader, and out to the fragment shader. e.g.

// in vertex shader:
out vec4 gs_fragmentColor;

// in geom shader:
in vec4 gs_fragmentColor[];
out vec4 fs_fragmentColor;

// in frag shader:
in vec4 fs_fragmentColor;

Currently you’re assuming fragmentColor will go directly from the vertex shader to the fragment shader (it won’t!), and the vFragColorVs/vFragColor vars in your geom shader don’t match the vertex/fragment shader inputs/outputs.

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