Hello Guest

[SOLVED] The Tesselation Shaders

  • 4 Replies
[SOLVED] The Tesselation Shaders
« on: September 09, 2010, 19:47:16 »
Hi everyone,

I've just got myself an nVidia GTX 465, cause I want to try OpenGL 4.0.

I've found a great topic with source code in C++, and i'm trying to use it on LWJGL.

However, I can't get this to work as shader loading are not working.

Here is my code :

some info :

checkGLErrors(String message) // Checks glErrors, and if true, display the type of error and the message before returning true;

printLogInfo(int shader) // prints infos logs of the given shader

Code: [Select]
int vsHandle = GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
int tcsHandle = GL20.glCreateShader(GL40.GL_TESS_CONTROL_SHADER);
int tesHandle = GL20.glCreateShader(GL40.GL_TESS_EVALUATION_SHADER);
int gsHandle = GL20.glCreateShader(GL32.GL_GEOMETRY_SHADER);
int fsHandle = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);

if(EGL_ShaderManager.checkGLErrors("Error while creation shaders handles")) System.exit(0);

glShaderSource(vsHandle, EGL_ShaderManager.getProgramCode(VSpath,"VP"));
System.out.println("VS compilation Status : " + (glGetShader(vsHandle, GL_COMPILE_STATUS)==GL11.GL_FALSE? "FALSE" : "TRUE"));
if(EGL_ShaderManager.checkGLErrors("Error while loading VS")) System.exit(0);

glShaderSource(tcsHandle, EGL_ShaderManager.getProgramCode(TCSpath,"TCS"));
System.out.println("TCS compilation Status : " + (glGetShader(tcsHandle, GL_COMPILE_STATUS)==GL11.GL_FALSE? "FALSE" : "TRUE"));
if(EGL_ShaderManager.checkGLErrors("Error while loading TCS")) System.exit(0);
GL40.glPatchParameteri(GL40.GL_PATCH_VERTICES, 3);
if(EGL_ShaderManager.checkGLErrors("Error while spec TCS out")) System.exit(0);

glShaderSource(tesHandle, EGL_ShaderManager.getProgramCode(TESpath,"TES"));
System.out.println("TES compilation Status : " + (glGetShader(tesHandle, GL_COMPILE_STATUS)==GL11.GL_FALSE? "FALSE" : "TRUE"));
if(EGL_ShaderManager.checkGLErrors("Error while loading TES")) System.exit(0);

glShaderSource(gsHandle, EGL_ShaderManager.getProgramCode(GSpath,"GS"));
System.out.println("GS compilation Status : " + (glGetShader(gsHandle, GL_COMPILE_STATUS)==GL11.GL_FALSE? "FALSE" : "TRUE"));

if(EGL_ShaderManager.checkGLErrors("Error while loading GS")) System.exit(0);

glShaderSource(fsHandle, EGL_ShaderManager.getProgramCode(FSpath,"FS"));
System.out.println("FS compilation Status : " + (glGetShader(fsHandle, GL_COMPILE_STATUS)==GL11.GL_FALSE? "FALSE" : "TRUE"));

if(EGL_ShaderManager.checkGLErrors("Error while loading FS")) System.exit(0);

int ProgramHandle = glCreateProgram();
glAttachShader(ProgramHandle, vsHandle);
glAttachShader(ProgramHandle, tcsHandle);
glAttachShader(ProgramHandle, tesHandle);
glAttachShader(ProgramHandle, gsHandle);
glAttachShader(ProgramHandle, fsHandle);

if(EGL_ShaderManager.checkGLErrors("Error after attaching shaders")) System.exit(0);

System.out.println("Validation Status : " + (glGetProgram(ProgramHandle, GL_VALIDATE_STATUS)==GL11.GL_FALSE? "FALSE" : "TRUE"));
if(EGL_ShaderManager.checkGLErrors("Error while validating tesselation Shader")) System.exit(0);


if(EGL_ShaderManager.checkGLErrors("Error while linking tesselation Shader")) System.exit(0);

System.out.println("Number of programs attached  : " + glGetProgram(ProgramHandle, GL_ATTACHED_SHADERS));
if(EGL_ShaderManager.checkGLErrors("Error while retrieving attached program count")) System.exit(0);

System.out.println("Link Status : " + (glGetProgram(ProgramHandle, GL_LINK_STATUS)==GL11.GL_FALSE? "FALSE" : "TRUE"));


if(EGL_ShaderManager.checkGLErrors("Error while binding tesselation Shader"))  System.exit(0);

This code is simply LWJGL adapted from here : http://prideout.net/blog/?p=48

The GLSL source code is exactly the one provided on the topic.

Yet, when executed (and yes, I checked, my GL version is 4.0), GL_LINK_STATUS return GL_FALSE, and thus, glUseProgram(ProgramHandle); returns 'GL_UNVALID_OPERATION'.

However, every compilation status are TRUE.

Another issue :

Code: [Select]

I looked over the OpenGL doc, i've found nothing that could help me.
I really am stuck now. Anyone has an idea ?

Thanks a lot.

« Last Edit: September 11, 2010, 14:35:54 by Estraven »


Offline spasi

  • *****
  • 2256
    • WebHotelier
Re: The Tesselation Shaders
« Reply #1 on: September 10, 2010, 00:47:31 »
Try to print out the program info log after glLinkProgram (use glGetProgramInfoLog). It might explain why the linking failed.

Re: The Tesselation Shaders
« Reply #2 on: September 10, 2010, 05:04:16 »
Hi spasi,

I've tried it already, but to be on the safe side, I checked again, it's empty.

glGetProgramInfoLog(ProgramHandle,65536)) --> Empty string

So are

glGetShaderInfoLog(tcsHandle,65536)); --> Empty string

glGetShaderInfoLog(tesHandle,65536)); --> Empty string

However, I've got a new symptom, if i do not attach the tcsHandle (but attach all four other ones), it links (but the shader cannot be use as it misses one stage)

as soon as the tcsHandle is attached, the link fails.


Re: The Tesselation Shaders
« Reply #3 on: September 10, 2010, 10:10:05 »
Ok, I can't find any reason why this does work. No error message, compilation is ok, it just don't link, apparently for no reason.

Does anybody have a working LWJGL example of tessellation control/evaluation shader that could be provided for source code comparison ?



Re: The Tesselation Shaders
« Reply #4 on: September 11, 2010, 14:34:44 »
Hey, I finally figured it out.

There was a spec revision of GLSL 4.00 in which this appeared this :
Change requirement of indexes of outputs for gl_InvocationID to be the following:  1) the value must     
be gl_InvocationID, 2) the compiler will give an error if it can determine it is not, and 3) if the
compiler does not give an error and the index is not valued as gl_InvocationID, then behavior is

The example I used defines the Tessellator Control Shader code as :
Code: [Select]
    int id = gl_InvocationID;
    tcPosition[id] = vPosition[id];
    if (id == 0) {
        gl_TessLevelInner[0] = TessLevelInner;
        gl_TessLevelOuter[0] = TessLevelOuter;
        gl_TessLevelOuter[1] = TessLevelOuter;
        gl_TessLevelOuter[2] = TessLevelOuter;

But the GLSL compiler consideres that "tcPosition" is not written at "gl_InvocationID".
Which in fact, is the case.
So i changed a single thing !

Code: [Select]
    int id = gl_InvocationID;
    tcPosition[    gl_InvocationID   ] = vPosition[id];
    if (id == 0) {
        gl_TessLevelInner[0] = TessLevelInner;
        gl_TessLevelOuter[0] = TessLevelOuter;
        gl_TessLevelOuter[1] = TessLevelOuter;
        gl_TessLevelOuter[2] = TessLevelOuter;

And now the linking is correct !

I hope it will help someone with a similar issue someday :)


« Last Edit: September 11, 2010, 14:37:13 by Estraven »