PDA

View Full Version : Tessellation shader pass-through : Nothing displayed



rXpSwiss
12-08-2014, 09:51 AM
Hello,

I am trying to set a pass-through tessellation shader and then build on top of that while learning.
From what I found/read I need to do in the TE shader everything that was done in the vertex shader and the TC shader just has to send the data forward. The vertex shader just sends the vertices coordinate, normal, tangent to the TC shader.

So for now, I pass the data do the computing in the TE shader that was done in the vertex shader and the fragment will just color everything in red. No texture is applied, I really just want to see something, which is not the case. I only have a black screen.

I did change the draw command from triangles to patches and set the GL_PATCHES_VERTICES to 3. I also want to say that the vertex/fragment shader works fine with or without texture.

In that spirit :
Vertex Shader :

#version 430 core
in vec4 vertCoord;
in vec3 vertNormal;
in vec3 texCoord;
in vec4 tangent;
out vec2 f_texcoord;
out vec4 vPosition;


void main()
{
vPosition = vertCoord;
f_texcoord = vec2(texCoord);
}

TC shader :

#version 430 core

layout (vertices=3) out;

in vec4 vPosition[];
in vec3 normal[];
in vec4 tangent[];
out vec4 tcPosition[];
out vec3 tcNormal[];
out vec4 tcTangent[];

void main(void) {
tcPosition[gl_InvocationID]=vPosition[gl_InvocationID];
tcNormal[gl_InvocationID]=normal[gl_InvocationID];
tcTangent[gl_InvocationID]=tangent[gl_InvocationID];
if(gl_InvocationID==0){
gl_TessLevelOuter[0] = 1.0;
gl_TessLevelOuter[1] = 1.0;
gl_TessLevelOuter[2] = 1.0;
gl_TessLevelInner[0] = 1.0;
gl_TessLevelInner[1] = 1.0;
}
}

TE shader :

#version 430 core

layout(triangles,equal_spacing,ccw) in;

in vec4 tcPosition[];
in vec3 tcNormal[];
in vec4 tcTangent[];
uniform mat4 invTransp;
uniform mat4 mvp;//MVP
uniform mat4 m;
uniform mat4 mv;
uniform mat4 invView;
out mat3 tangenteSpace;
out vec4 position;// position of the vertex in world space
out vec3 varyingNormalDirection;

void main(void) {
vec3 p = gl_TessCoord.xyz;

vec4 vertCoord = vec4(normalize(tcPosition[0]*p.x + tcPosition[1]*p.y + tcPosition[2]*p.z).xyz,1.0);
vec3 vertNormal = normalize(tcNormal[0]*p.x + tcNormal[1]*p.y + tcNormal[2]*p.z);
vec4 tangent = vec4(normalize(tcTangent[0]*p.x + tcTangent[1]*p.y + tcTangent[2]*p.z).xyzw);

//comnpute tangent space
tangenteSpace[0] = normalize(tangent.xyz);
tangenteSpace[2] = normalize(vertNormal);
tangenteSpace[1] = normalize(cross(tangenteSpace[0],tangenteSpace[2])*tangent.w);
tangenteSpace = transpose(tangenteSpace);

//for no bump map
varyingNormalDirection = normalize(mat3(invTransp)*vertNormal);

//position in world space
position = m * vertCoord;
//f_texcoord = vec2(texCoord);

gl_Position = mvp*vertCoord;
}

What could be so wrong that nothing is displayed but no error either ?

rXp :)

Alfonse Reinheart
12-08-2014, 12:49 PM
I don't believe that there was no error, because I can one. So odds are that your error testing code doesn't work correctly. Here's one problem:



//Vertex Shader
out vec2 f_texcoord;
out vec4 vPosition;

//TCS
in vec4 vPosition[];
in vec3 normal[];
in vec4 tangent[];


Only one of the input values from your TCS is actually provided by your VS. If you were using linked programs, the linker should have failed with an error. If you were using separate programs, then your pipeline should have been invalid and your rendering should have given you an error.

rXpSwiss
12-10-2014, 03:21 AM
On every example that I found (web or book) the vertex shader only returns one value but since the TCS get several vertices, it will get an array of them.
What am I not getting ?

Link :
https://developer.nvidia.com/content/opengl-sdk-simple-tessellation-shader

Alfonse Reinheart
12-10-2014, 05:38 AM
since the TCS get several vertices, it will get an array of them.
What am I not getting ?

I don't know. Are you asking about your specific code, or are you asking about Tessellation (https://www.opengl.org/wiki/Tessellation) and TCS's (https://www.opengl.org/wiki/Tessellation_Control_Shader) in general? Because the problem in your specific code is not about the array issue. It's about having a mis-matched interface. Fix that problem first, then we can deal with the rest.

rXpSwiss
12-10-2014, 06:07 AM
Okey, but I can't find what is wrong. Where is the miss-match ? And what am I doing wrong when I check for errors ?

Error checking :


GLint glVerifyStatus(GLint toVerify, GLuint whatToCheck, char* what){
GLint status = GL_FALSE;
glGetProgramiv(toVerify, whatToCheck, &status);
if (GL_FALSE == status) {
std::cerr << "Failed to :" << "\"" << what << "\"" << std::endl;
GLint logLen;
glGetProgramiv(toVerify, GL_INFO_LOG_LENGTH,
&logLen);
if (logLen > 0)
{
char * log = (char *)malloc(logLen);
GLsizei written;
glGetProgramInfoLog(toVerify, logLen,
&written, log);
std::cerr << "Log :" << log << std::endl;
free(log);
}
}
return status;
}

Linked program :

//---------------------------- SHADERS
GLint vertShader = createShader("shaders/basic.vert.glsl", GL_VERTEX_SHADER);
GLint tcShader = createShader("shaders/basic.tcs.glsl", GL_TESS_CONTROL_SHADER);
GLint teShader = createShader("shaders/basic.tes.glsl", GL_TESS_EVALUATION_SHADER);
GLint fragShader = createShader("shaders/basic.frag.glsl", GL_FRAGMENT_SHADER);

programHandle = glCreateProgram();
if (0 == programHandle)
{
fprintf(stderr, "Error creating program object.\n");
exit(1);
}
glAttachShader(programHandle, vertShader);
glAttachShader(programHandle, tcShader);
glAttachShader(programHandle, teShader);
glAttachShader(programHandle, fragShader);

glLinkProgram(programHandle);
if (glVerifyStatus(programHandle, GL_VALIDATE_STATUS, "validate program") == GL_TRUE && glVerifyStatus(programHandle, GL_LINK_STATUS, "link program") == GL_TRUE)
glUseProgram(programHandle);
else
exit(0);


Edit : I am sorry ! I found a mistake in the createShader that didn't display the errors... I will get back to you after this.

Alfonse Reinheart
12-10-2014, 06:53 AM
Where is the miss-match ?

I can't tell you any more clearly than by copying the output and input variables that don't match. Which I did in my first post.

Also, it's not a good idea to prefix your own functions with "gl". It makes it difficult to tell the difference between the real OpenGL functions in your code and the code that belongs to you.

rXpSwiss
12-10-2014, 07:26 AM
I can't tell you any more clearly than by copying the output and input variables that don't match. Which I did in my first post.

Also, it's not a good idea to prefix your own functions with "gl". It makes it difficult to tell the difference between the real OpenGL functions in your code and the code that belongs to you.

Yes you can't, I was really blind ! I'm sorry I guess I was on that for way too long and I just couldn't see anything anymore.
I matched the input/ouput and now I see something. It is not great at all but it is there.