[SOLVED] The Tesselation Shaders

Started by Estraven, September 09, 2010, 19:47:16

Previous topic - Next topic

Estraven

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

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"));
			glCompileShader(vsHandle);
			System.out.println("VS compilation Status : " + (glGetShader(vsHandle, GL_COMPILE_STATUS)==GL11.GL_FALSE? "FALSE" : "TRUE"));
			EGL_ShaderManager.printLogInfo(vsHandle);
			if(EGL_ShaderManager.checkGLErrors("Error while loading VS"))	System.exit(0);

			glShaderSource(tcsHandle, EGL_ShaderManager.getProgramCode(TCSpath,"TCS"));
			glCompileShader(tcsHandle);
			System.out.println("TCS compilation Status : " + (glGetShader(tcsHandle, GL_COMPILE_STATUS)==GL11.GL_FALSE? "FALSE" : "TRUE"));
			EGL_ShaderManager.printLogInfo(tcsHandle);
			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"));
			glCompileShader(tesHandle);
			System.out.println("TES compilation Status : " + (glGetShader(tesHandle, GL_COMPILE_STATUS)==GL11.GL_FALSE? "FALSE" : "TRUE"));
			EGL_ShaderManager.printLogInfo(tesHandle);
			if(EGL_ShaderManager.checkGLErrors("Error while loading TES"))	System.exit(0);

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

			if(EGL_ShaderManager.checkGLErrors("Error while loading GS"))	System.exit(0);
			
			glShaderSource(fsHandle, EGL_ShaderManager.getProgramCode(FSpath,"FS"));
			glCompileShader(fsHandle);
			System.out.println("FS compilation Status : " + (glGetShader(fsHandle, GL_COMPILE_STATUS)==GL11.GL_FALSE? "FALSE" : "TRUE"));
			EGL_ShaderManager.printLogInfo(fsHandle);

			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);
			
			glValidateProgram(ProgramHandle);
			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);

			glLinkProgram(ProgramHandle);

			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"));

			glUseProgram(ProgramHandle);
			
			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 :

glGetProgram(ProgramHandle,GL40.GL_TESS_CONTROL_OUTPUT_VERTICES);


returns GL_INVALID_OPERATION

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.

Estraven

spasi

Try to print out the program info log after glLinkProgram (use glGetProgramInfoLog). It might explain why the linking failed.

Estraven

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.

Estraven



Estraven

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 ?

Thanks,

Estraven

Estraven

Hey, I finally figured it out.

There was a spec revision of GLSL 4.00 in which this appeared this :
Quote
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
undefined.


The example I used defines the Tessellator Control Shader code as :
    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 !

    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 :)

Estraven