shaders in a JOGL applet

I’m playing around with a JOGL applet. Everything seems to be working well, but adding shaders causes a GL_INVALID_OPERATION after glUseProgram. I’m using the “hello world” style shaders, so they seem to be too simple to cause problems. I seem to be getting a 4 for the glsl program, which seems high since there is only one, but I don’t think that should be an issue either. Can anyone spot the problem with my code or give me a reason why shaders don’t work in JOGL applets?

Binding my shader class gives me this trace:


Exception in thread "AWT-EventQueue-2" javax.media.opengl.GLException: glGetError() returned the following error codes after a call to glUseProgram(): GL_INVALID_OPERATION 
	at javax.media.opengl.DebugGL.checkGLGetError(DebugGL.java:12715)
	at javax.media.opengl.DebugGL.glUseProgram(DebugGL.java:9774)
	at javax.media.opengl.DebugGL.glUseProgram(DebugGL.java:9773)
	at javax.media.opengl.DebugGL.glUseProgram(DebugGL.java:9773)
	at javax.media.opengl.DebugGL.glUseProgram(DebugGL.java:9773)
	at javax.media.opengl.DebugGL.glUseProgram(DebugGL.java:9773)
	at javax.media.opengl.DebugGL.glUseProgram(DebugGL.java:9773)
	at javax.media.opengl.DebugGL.glUseProgram(DebugGL.java:9773)
	at javax.media.opengl.DebugGL.glUseProgram(DebugGL.java:9773)
	at javax.media.opengl.DebugGL.glUseProgram(DebugGL.java:9773)
	at javax.media.opengl.DebugGL.glUseProgram(DebugGL.java:9773)
	at base.shader.ShaderProgram.bind(ShaderProgram.java:71)
...

I’ve even tried not attaching either shader to the program. Here’s my shader code that handles the setup:


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import javax.media.opengl.DebugGL;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;

public abstract class ShaderProgram {
    public void validate(GLAutoDrawable drawable) {
        // adapted from David Cornette's code (http://www.davidcornette.com/glsl/)
        drawable.setGL(new DebugGL(drawable.getGL()));
        GL gl = drawable.getGL();
        
        int v = gl.glCreateShader(GL.GL_VERTEX_SHADER);
        int f = gl.glCreateShader(GL.GL_FRAGMENT_SHADER);
        String line;

        try {
            BufferedReader brv = new BufferedReader(new InputStreamReader(vert_url.openStream()));
            String[] vsrc = new String[1];
            while ((line=brv.readLine()) != null) {
                System.out.println(line);
                vsrc[0] += line + "\n";
            }
            gl.glShaderSource(v, 1, vsrc, (int[])null, 0);
            gl.glCompileShader(v);
        } catch (FileNotFoundException e) {
            System.err.println("File not found: " + e.getMessage());
        } catch (IOException e) {
            System.err.println("IO error: " + e.getMessage());
        }
        
        try {
            BufferedReader brf = new BufferedReader(new InputStreamReader(frag_url.openStream()));
            String[] fsrc = new String[1];
            while ((line=brf.readLine()) != null) {
                fsrc[0] += line + "\n";
                System.out.println(line);
            }
            gl.glShaderSource(f, 1, fsrc, (int[])null, 0);
            gl.glCompileShader(f);
        } catch (FileNotFoundException e) {
            System.err.println("File not found: " + e.getMessage());
        } catch (IOException e) {
            System.err.println("IO error: " + e.getMessage());
        }

        program = gl.glCreateProgram();
        program = gl.glCreateProgram();
        /*
        gl.glAttachShader(program, v);
        gl.glAttachShader(program, f);
         */
        gl.glLinkProgram(program);
        gl.glValidateProgram(program);
                
        valid = true;
    }
    
    public void bind(GLAutoDrawable drawable) {
        drawable.setGL(new DebugGL(drawable.getGL()));
        GL gl = drawable.getGL();
        
        if (!valid)
            validate(drawable);
        System.out.println(program);
        gl.glUseProgram(program);       
    }
    
    public void release(GLAutoDrawable drawable) {
        drawable.setGL(new DebugGL(drawable.getGL()));
        GL gl = drawable.getGL();
        
        gl.glUseProgram(0); 
    }

    int program;
    boolean valid = false;
    
    URL vert_url;
    URL frag_url;

}


does it work as regular application?

this looks a bit bugy. you are creating two program handles but you don’t attach anything to them.

You should also check if your program compiled successfully.


    private void checkProgram(GL gl) {
                
        int[] buffer = new int[1];
        
        // check link status
        gl.glGetObjectParameterivARB(handle, GL.GL_OBJECT_LINK_STATUS_ARB, buffer, 0);
        if(buffer[0] == GL.GL_FALSE) // 1 or 0
            getLog().warning("error linking program");
        
        // validate program
        gl.glValidateProgramARB(handle);
        gl.glGetObjectParameterivARB(handle, GL.GL_OBJECT_VALIDATE_STATUS_ARB, buffer, 0);
        if(buffer[0] == GL.GL_FALSE)
            getLog().warning("program validation reports error");
        
        // dump log
        gl.glGetObjectParameterivARB(handle, GL.GL_OBJECT_INFO_LOG_LENGTH_ARB, buffer, 0);
        byte[] log = new byte[buffer[0]];
        gl.glGetInfoLogARB(handle, buffer[0], buffer, 0, log, 0);
        
        if(log[0] != 0) // 0 if empty
            getLog().warning("linker info log:\n"+new String(log));
    }

    private void checkShader(GL gl) throws GLSLCompileException {
        
        boolean error = false;
        
        // check compile state
        int[] buffer = new int[1];
        gl.glGetObjectParameterivARB(handle, GL.GL_OBJECT_COMPILE_STATUS_ARB, buffer, 0);
        if(buffer[0] == GL.GL_FALSE) {
//            getLog().warning("error compiling shader:\n"+getName());
            error = true;
        }
        
        // log info log
        gl.glGetObjectParameterivARB(handle, GL.GL_OBJECT_INFO_LOG_LENGTH_ARB, buffer, 0);
        byte[] log = new byte[buffer[0]];
        gl.glGetInfoLogARB(handle, buffer[0], buffer, 0, log, 0);
        
        if(log[0] != 0 && !error)  {// 0 if empty
            error = throwExceptionOnCompilerWarning; // TODO setup exception level
//            getLog().warning("compiler info log:\n"+new String(log, 0, log.length-1));
        }
        
        if(error)
            throw new GLSLCompileException(shaderNames, new String(log, 0, log.length-1).split("\n"));
    }