JOGL and GLSL

Hi everybody!

I have worked quite a while with JOGL and Cg now and I now tried to look into OpenGL Shading Laguage. I found a few tutorials, wrote some shaders using a shader-designer-software and started porting some C-code to Java/JOGL to have the shaders running there.
Now after doing all this I get nothing at all. I implemented an output for the InfoLog and get the following output:


Vertex info
-----------
(0) : error C3001: no program defined
1 lines, 1 errors.
Fragment info
-------------
(0) : error C3001: no program defined
1 lines, 1 errors.

If I try and compile the shaders with the cgc-compiler and the option “-oglsl” everythings works fine. I get no errors.

The shaders are:


      public String[] getVertexShader() {

            String[] result = new String[8];
            result[0] = new String("varying vec3 v;");
            result[1] = new String("varying vec3 n;");
            result[2] = new String("void main() {");
            result[3] = new String("v = vec3(gl_ModelViewMatrix * gl_Vertex);");
            result[4] = new String("n = normalize(gl_NormalMatrix * gl_Normal);");
            result[5] = new String("gl_TexCoord[0] = gl_MultiTexCoord0;");
            result[6] = new String("gl_TexCoord[1] = gl_MultiTexCoord0;");
            result[7] = new String("gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; }");
            return result;

      }

      public String[] getFragmentShader() {

            String[] result = new String[14];
            result[0] = new String("varying vec3 v;");
            result[1] = new String("varying vec3 n;");
            result[2] = new String("uniform sampler2D TextureUnit0;");
            result[3] = new String("void main() {");
            result[4] = new String("vec4 ambient, diffuse, specular;");
            result[5] = new String("for (int l = 0; l < gl_MaxLights; l++) {");
            result[6] = new String("vec3 l = normalize(gl_LightSource[l].position.xyz - v);");
            result[7] = new String("vec3 e = normalize(-v);");
            result[8] = new String("vec3 r = normalize(-reflect(l, n));");
            result[9] = new String("ambient += gl_FrontLightProduct[l].ambient * gl_FrontMaterial.ambient;");
            result[10] = new String("diffuse += gl_FrontLightProduct[l].diffuse * max(dot(n, l), 0.0);");
            result[11] = new String("specular += gl_FrontLightProduct[l].specular * pow(max(dot(r, e), 0.0), gl_FrontMaterial.shininess); }");
            result[12] = new String("gl_FragColor = ambient + diffuse;");
            result[13] = new String("gl_FragColor += specular; }");
            return result;

      }

The code to initi GLSL and load the programs looks like this:

      protected void initGLSL(GLDrawable glDraw) {

            GL gl = glDraw.getGL();

            this.vertexShaderHandle = gl.glCreateShaderObjectARB(GL.GL_VERTEX_SHADER_ARB);
            this.fragmentShaderHandle = gl.glCreateShaderObjectARB(GL.GL_FRAGMENT_SHADER_ARB);

            FirstGLSLshader shaderSource = new FirstGLSLshader();

            int[] emptyIntArray = null;
            gl.glShaderSourceARB(this.vertexShaderHandle, 1, shaderSource.getVertexShader(), emptyIntArray);
            gl.glShaderSourceARB(this.fragmentShaderHandle, 1, shaderSource.getFragmentShader(), emptyIntArray);

            gl.glCompileShaderARB(this.vertexShaderHandle);
            int[] resultVertex = new int[1];
            gl.glGetObjectParameterivARB(this.vertexShaderHandle, GL.GL_OBJECT_COMPILE_STATUS_ARB, resultVertex);
            this.printInfoLog(glDraw, this.vertexShaderHandle);

            gl.glCompileShaderARB(this.fragmentShaderHandle);
            int[] resultFragment = new int[1];
            gl.glGetObjectParameterivARB(this.fragmentShaderHandle, GL.GL_OBJECT_COMPILE_STATUS_ARB, resultFragment);
            this.printInfoLog(glDraw, this.fragmentShaderHandle);

            if (resultVertex[0] == 0 || resultFragment[0] == 0) {

                  if (VERBOSE) System.err.println("Unable to initialize OGSL");
                  System.exit(-1);

            }

            this.OGSLProgram = gl.glCreateProgramObjectARB();
            gl.glAttachObjectARB(this.OGSLProgram, this.vertexShaderHandle);
            gl.glAttachObjectARB(this.OGSLProgram, this.fragmentShaderHandle);

            gl.glLinkProgramARB(this.OGSLProgram);
            int[] programLinked = new int[1];
            gl.glGetObjectParameterivARB(this.fragmentShaderHandle, GL.GL_OBJECT_COMPILE_STATUS_ARB, programLinked);
            this.printInfoLog(glDraw, this.OGSLProgram);

            if (programLinked[0] == 0) {

                  if (VERBOSE) System.err.println("Unable to link Program");
                  System.exit(-1);

            }

            gl.glUseProgramObjectARB(this.OGSLProgram);

            this.checkGLErrors(glDraw);

      }

I’m not quite sure where the problem is. Is there a need to specify the entry-point-function-names? I though that wouldn’t be necessary if they are both “main”.
The cgc-compiler I used for testing the code is from the new Cg-Toolkit 1.3 Beta 2. Hardware is a nVidia Quadro FX 3400 with drivers 65.62 (Dell Performance-Driver).

Anybody got an idea? Any help is appreciated.

Greetz…

…Hoschi_S

You must add a GLEventListener to your GLDrawable and make your OpenGL function calls from within the GLEventListener’s init() or display() methods.

Thanks for your answer but that’s surely not the problem. I posted only parts from a bigger project. I have a baseclass that organizes most things needed and calls some overridable functions. Then I derive that class and have with little more than twenty lines a complete new JOGL-App. I added a boolean-switch USE_GLSL in the baseclass and a

if (USE_GLSL) initGLSL(glDrawable);

in the init()-Method invoked through the GLEventListener.
I also have a little scene with activated Lighting and two Lightsources in this special case to see an effect from the perPixel-Lighting from the Shaders. The system works fine, the scene is drawn but the Shaders won’t work which is somewhat clear when they don’t compile. I just don’t have any idea why they don’t compile. Am I doing something wrong with the String-Array containing the shader-codes? I just ported c-code for that part and haven’t found any GLSL-examples using JOGL up 'till now…

Ok, I found the problem. A stupid mistake, as always :frowning:
By porting from c/c++ one should think not only about different behavior using pointers but also about different behavior with Strings being not null-terminated.
Thus the calls to

glShaderSourceARB

have to be made differently: Passing a “NULL” for the last parameter and a 1 for the numStrings-Parameter is valid if the strings are null-terminated c-strings in an array terminated by an empty string. That is not the case with java, so changing the old call


            int[] emptyIntArray = null;
            gl.glShaderSourceARB(this.vertexShaderHandle, 1, shaderSource.getVertexShader(), emptyIntArray);


to:


            String[] vertexShader = shaderSource.getVertexShader();
            int[] vertexLength = new int[vertexShader.length];
            for (int v = 0; v < vertexLength.length; v++)
                  vertexLength[v] = vertexShader[v].length();
            gl.glShaderSourceARB(this.vertexShaderHandle, vertexShader.length, vertexShader, vertexLength);


solved the problem. The shaders are now compiled (Of course the same had to be done to the fragmentShader call…). ;D

If I am successfull in the further work on the project I might set up a tutorial about the use og GLSL and JOGL. Let’s see how it turns out.

cheers…

…Hoschi_S

I look forward to the tutorial! :smiley:

The contents of the individual Strings being passed from Java to C are null-terminated, but I think there is a bug in the GlueGen-generated code where if you attempt to pass null as an element in the String[] that the native code will crash. Did you see this behavior? Do you have a test case illustrating the behavior that should work? If so, please file a bug with the JOGL Issue Tracker on http://jogl.dev.java.net/.

Ken, just want to confirm that we see that behaviour pop up in a number of different places. For example, passing a null value for the Buffer object or a Buffer object allocated to length of zero to one of the gl*Pointer() methods.

Please, file a bug with a test case. We can’t fix problems we don’t know about. Thanks. When in doubt, file a bug (after checking for duplicates, of course).

Hm, I never ran into that sort of problem before. Since I found an immediate workaround I also threw away the old code-version (didn’t even checked it into CVS :slight_smile:
What I can say is that there was no crash nor even an exception when running into the String[]. The program kept going with fixed-function-behavior and terminated correct without any further errors when exited by hand later.
I’ll keep the problem in mind and will see if it will show up anywhere else in the project.

By the way: As we speak of shader-programming, are there any plans to alter JOGL soon to match the new Cg-Tookit v1.3? I know it’s only Beta but it works nice and stable for me at the moment using profiles vp40 and fp40 and the parameter-sharing and texture-binding-control is a valuable add-on. Tell me if you need help. I would be interested in working on it since I want to use the features :wink:

Greetz…

…Hoschi_S

If you want to take a crack at upgrading the Cg headers JOGL points at to the new Cg beta, please go ahead. I am sure there will be a significant number of issues as the Cg APIs seem to be a quickly moving target. I think we’ll probably wait to upgrade the JOGL workspace until the new Cg is finalized, but until then we could probably check in your changes under a branch.