Hey,
as stated in the topic title, I’m trying to render cubic Bézier curves using a tessellation shader, but can’t identify the problem(s) that are causing nothing at all to be drawn (or at least, seen) on the screen. Also, on my Radeon HD 5770, the program segfaults on glDrawArrays.
Basically, the thing I’m trying to accomplish here is to give the program four control points and draw a curve with different tessellation levels based on the zoom level.
Here’s the basic OpenGL initialization code I’m using:
#define WIN_W 1280
#define WIN_H 960
glClearColor(0.0, 0.0, 0.0, 1.0);
glEnable(GL_DEPTH_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glViewport(0, 0, WIN_W, WIN_H);
glPatchParameteri(GL_PATCH_VERTICES, 4);
<shader loading code> // this shouldn't be the problem here, since it works on a lot of other projects.
// incl. glBindAttribLocation(programID, 0, "Position_VS_in")
float patch_buffer[4 * 2] = { 0.0, 0.0, 0.2, 1.0, 0.8, 1.0, 1.0, 0.0 };
#define ATTRIB_POSITION 0
glGenVertexArrays(1, &VAOid);
glBindVertexArray(VAOid);
glEnableVertexAttribArray(ATTRIB_POSITION);
glGenBuffers(1, &VBOid);
glBindBuffer(GL_ARRAY_BUFFER, VBOid);
glBufferData(GL_ARRAY_BUFFER, 8*sizeof(float), patch_buffer, GL_DYNAMIC_DRAW);
glVertexAttribPointer(ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), 0);
glBindVertexArray(0);
glDisableVertexAttribArray(ATTRIB_POSITION);
The shaders:
// VERTEX SHADER
#version 400
layout(location = 0) in vec2 Position_VS_in;
out vec3 vPos;
void main() {
vPos = vec3(Position_VS_in, 0.0);
}
// TESSELLATION CONTROL SHADER
#version 400
layout(vertices = 4) out; // 4 points per patch
in vec3 vPos[];
out vec3 tcPos[];
void main() {
tcPos[gl_InvocationID] = vPos[gl_InvocationID];
if(gl_InvocationID == 0) { // levels only need to be set once per patch
gl_TessLevelOuter[0] = 1; // we're only tessellating one line
gl_TessLevelOuter[1] = 100; // tessellate the line into 100 segments
}
}
// TESSELLATION CONTROL SHADER
#version 400
vec3 bezier2(vec3 a, vec3 b, float t) {
return mix(a, b, t);
}
vec3 bezier3(vec3 a, vec3 b, vec3 c, float t) {
return mix(bezier2(a, b, t), bezier2(b, c, t), t);
}
vec3 bezier4(vec3 a, vec3 b, vec3 c, vec3, d, float t) {
return mix(bezier3(a, b, c, t), bezier3(b, c, d, t), t);
}
layout(isolines) in;
in vec3 tcPos[];
uniform mat4 uMVP;
void main() {
float t = gl_TessCoord.x;
vec3 ePos = bezier4(tcPos[0], tcPos[1], tcPos[2], tcPos[3], t);
gl_Position = uMVP * vec4(ePos, 1);
}
// FRAGMENT SHADER
#version 400
out vec4 frag_color;
void main() {
frag_color = vec4(1.0, 1.0, 1.0, 1.0);
}
Drawing code:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(wave_shader->getProgramHandle());
mat4 mvp = mat4::proj_ortho(0.0, WIN_W, WIN_H, 0.0, -1.0, 1.0) * mat4::scale(100, 100, 100);
wave_shader->update_uniform_mat4("uMVP", mvp);
glBindVertexArray(VAOid);
glDrawArrays(GL_PATCHES, 0, 4);
// later: SwapBuffers
I’m not absolutely sure about the TCS/TES part, but at least mathematically speaking, it seems fine as far as I can tell.
Haven’t been able to figure out what the problem is. Any pointers on this will be much appreciated!
Thanks.