Reputation: 3
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
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