I am learning tessellation now. Trying to pass the colour via tesselation shaders. Like I found here, the most consistent answer: Passing data through tessellation shaders to the fragment shader
So far consulting also these sources, but did not find the problem in my code yet:
https://www.khronos.org/opengl/wiki/Tessellation_Control_Shader
https://www.khronos.org/opengl/wiki/Tessellation_Evaluation_Shader
As failing to pass for complex shapes, I narrowed problem down to simple basic triangle. Here is the problem. Only the last, third color is taken from the triangle data passed to shaders, see the TessTriangleRainbow::points in the C++ code snippet for tessellated triangle. No matter that I do, the first ad second color is ignored:

Note, exactly the same code and data but not tessellated looks ok:

Vertex shader for tessellated triangle:
#version 430 core layout(location = 0) in vec3 pos; layout(location = 1) in vec3 color; out vec4 vs_color; void main() { gl_Position = vec4(pos, 1.f); vs_color = vec4(color, 1.f); } Tessellation control shader:
#version 430 core layout (vertices = 3) out; in vec4 vs_color []; patch out vec4 patch_color; void main() { gl_TessLevelOuter[0] = 10.0; gl_TessLevelOuter[1] = 10.0; gl_TessLevelOuter[2] = 10.0; gl_TessLevelInner[0] = 5.0; gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position; patch_color = vs_color [gl_InvocationID]; } Tesselation evaluation shader:
#version 430 core layout (triangles, equal_spacing, cw) in; patch in vec4 patch_color; out vec4 tes_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 ); tes_color = patch_color; } Fragment shader for tessellated triangle:
#version 430 core out vec4 color; in vec4 tes_color; void main() { color = tes_color; } Tessellated triangle source:
GLfloat TessTriangleRainbow::points[] = { //x y z r g b -0.5f, -0.5f, 0.0f, 0.0f, 0.f, 1.f, // first xyz vertex + rgb color 0.5f, -0.5f, 0.0f, 1.0f, 0.f, 0.f, // second xyz vertex + rgb color 0.0f, 0.5f, 0.0f, 0.0f, 1.f, 0.f // third xyz vertex + rgb color }; //The base class Tess is tesselation shader aware //It is responsible for compiling linking the shaders TessTriangleRainbow::TessTriangleRainbow() : Tess ("shaders/tesselation/triangleRainbow.tcs", "shaders/tesselation/triangleRainbow.tes", "shaders/tesselation/triangleRainbow.vs", "shaders/tesselation/triangleRainbow.fs") { build(); } void TessTriangleRainbow::build() { glGenVertexArrays(1, &vao); glBindVertexArray(vao); unsigned int vbo; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(points), &points, GL_STATIC_DRAW); //get XYZ values into location 0 on vertex shader glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); //RGBA to location 1 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(1); glBindVertexArray(0); } void TessTriangleRainbow::draw() { glUseProgram(*this); //the inherited overloaded (int) operator returns the program id glPatchParameteri(GL_PATCH_VERTICES, 3); glBindVertexArray(vao); glDrawArrays(GL_PATCHES, 0, 3); } Vertex shader for non tessellated triangle:
#version 430 core layout(location = 0) in vec3 pos; layout(location = 1) in vec3 color; out vec4 vs_color; void main() { gl_Position = vec4(pos, 1.f); vs_color = vec4(color, 1.f); } Fragment shader for non tessellated triangle:
#version 430 core out vec4 color; in vec4 vs_color; void main() { color = vs_color; } Non tessellated triangle source, is almost identical to the tessellated one:
GLfloat TriangleRainbow::points[] = identically the same as tessellated ones //base Shape class builds the program from shaders TriangleRainbow::TriangleRainbow() : Shape ( "shaders/tesselation/triangleRainbow.1.vs", "shaders/tesselation/triangleRainbow.1.fs") { build(); } void TriangleRainbow::build() { ... it is identically the same as the tessellated one } void TriangleRainbow::draw() { glUseProgram(*this); //the inherited overloaded (int) operator returns the program id glBindVertexArray(vao); glDrawArrays(GL_TRIANGLES, 0, 3); } Piece of main function:
TessTriangleRainbow tessTriRainbow; TriangleRainbow triRainbow; ... other shapes if (!tessTriRainbow.program.success) /*report tessellated triangle shader compile errors*/ ... if (!triRainbow.program.success) /*report triangle shader compile errors*/ ... ... glDisable(GL_CULL_FACE); //glEnable(GL_DEPTH_TEST); int currentShape = 0; while (!glfwWindowShouldClose(window)) { processInputs(window); if (keyPressed) { /* change here currentShape to draw*/ ... } glClearColor(0.f, 0.f, 1.f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); switch (currentShape) { case 0: triRainbow.draw(); break; case 1: tessTriRainbow.draw(); break; ...