user3706588
user3706588

Reputation: 3

JOGL, opengl 4.3, passing color vector from geometry shader, to fragment shader

I am using a book called Opengl SuperBible 6th edition. I am using JOGL 2.5.1 API. Everytihing was working fine, until I created geometry shader (exercise on page 37). When I try to pass color vector from geometry shader to fragment shader, the Java virtual machine crashes. I have also implemented GLSL error check at shader creation and it shows nothing. I really want to know what is the catch here. here is my code from vertex shader to fragment shader. Funny thing is the program crashes only when i send color from geometry shader to fragment shader. If i set color manualy in fragment shader the program works.

VERTEX SHADER:

#version 430 core

layout (location = 0) in vec4 offset;
layout (location = 1) in vec4 color;

out vec4 vs_color;

void main(void){
    const vec4 vertices[3] = vec4[3](vec4( 0.25, -0.25, 0.5, 1.0),
                  vec4(-0.25, -0.25, 0.5, 1.0),
                  vec4( 0.25, 0.25, 0.5, 1.0));


     gl_Position = vertices[gl_VertexID] + offset;

     vs_color = color;
}

TESSELATION CONTROL SHADER:

#version 430 core

layout (vertices = 3) out;

in vec4 vs_color[];

out vec4 tsc_color[];

void main(void){

    if (gl_InvocationID == 0){
        gl_TessLevelInner[0] = 5.0;
        gl_TessLevelOuter[0] = 5.0;
        gl_TessLevelOuter[1] = 5.0;
        gl_TessLevelOuter[2] = 5.0;
                         }
        gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;

        tsc_color[0] = vs_color[0];
}

TESSELATION EVALUATION SHADER:

#version 430 core

layout (triangles, equal_spacing, cw) in;

in vec4 tsc_color[];

out vec4 tse_color[];

void main(void){
    gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position +
    gl_TessCoord.y * gl_in[1].gl_Position +
    gl_TessCoord.z * gl_in[2].gl_Position);

    tse_color[0] = tsc_color[0];
}

GEOMETRY SHADER:

#version 430 core

layout (triangles) in;
layout (points, max_vertices = 3) out;

in vec4 tse_color[];

out vec4 geo_color;

void main(void){
    int i;
    for (i = 0; i < gl_in.length(); i++)
    {
    gl_Position = gl_in[i].gl_Position;
    EmitVertex();
    }

    geo_color = tse_color[0];
}

FRAGMENT SHADER:

#version 430 core

in vec4 geo_color;

out vec4 color;

void main(void){    
//color = vec4(0.0f, 0.8f, 1.0f, 1.0f); for manual setting
    color = geo_color;
}

THE ERROR THAT OCCURES:

glLinkProgram(<int> 0x6)GLDebugEvent[ id 0x7d1
    type Error
    severity High: dangerous undefined behavior
    source GLSL or extension compiler
    msg glLinkProgram failed to link a GLSL program with the following program info log: 'Vertex shader(s) failed to link, tessellation control shader(s) failed to link, tessellation evaluation shader(s) failed to link, geometry shader(s) failed to link, fragment shader(s) failed to link.
Vertex link error: INVALID_OPERATION.
ERROR: error(#275) Symbol "tse_color" is defined with 2 different types between two stages
tessellation control link error: INVALID_OPERATION.
ERROR: error(#275) Symbol "tse_color" is defined with 2 different types between two stages
tessellation evaluation link error: INVALID_OPERATION.
ERROR: error(#275) Symbol "tse_color" is defined with 2 different types between two stages
geometry link error: INVALID_OPERATION.
ERROR: error(#275) Symbol "tse_color" is defined with 2 different types between two stages
fragment link error: INVALID_OPERATION.
ERROR: error(#275) Symbol "tse_color" is defined with 2 different types between two stages
'
    when 1401907851402
    source 4.4 (Core profile, arb, debug, ES2 compat, ES3 compat, FBO, hardware) - 4.4.12874 Core Profile/Debug Context 14.100.0.0 - hash 0x14e08f00]

Upvotes: 0

Views: 827

Answers (1)

Andon M. Coleman
Andon M. Coleman

Reputation: 43319

Tessellation Evaluation Shaders only output 1 vertex. I do not know why you have declared out vec4 tse_color[];, but that is a mistake.

// out vec4 tse_color[];        // WRONG
out vec4 tse_color;             // * Fixed

[...]

// tse_color[0] = tsc_color[0]; // WRONG
tse_color = tsc_color[0];       // * Fixed

Finally, you are only outputting color to a single vertex for every invocation of your control shader, when you should be outputting multiple. To pass your per-vertex color through the control shader, you need the following:

tsc_color [gl_InvocationID] = vs_color [gl_InvocationID];

Now, here is where things get strange... you are only referencing the first color in your patch for each evaluated vertex. I think what you actually want is an input/output variable qualified with patch storage. That will allow you to create exactly 1 instance of the variable shared across all invocations, sort of like a provoking vertex only for tessellation.

Upvotes: 1

Related Questions