GLSL Example(s) in Jogl

Can anyone point me to (or supply!) an example of GLSL shaders in JOGL please?

Thanks in advance!

Here is a small example for JOGL 1.1.1. I hope this is enough to get you started.

I’m actually currently working on a blog-post about mandelbrot and JOGL (vs. pure Java) for my blog: http://blog.nobel-joergensen.com/
The blog post should be ready in about a week :slight_smile:

Kind regards,

Morten


import com.sun.opengl.util.Animator;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;
import javax.swing.;
import java.awt.
;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;

public class SimpleShaderExample extends GLCanvas implements GLEventListener {

private boolean updateUniformVars = true;
private int vertexShaderProgram;
private int fragmentShaderProgram;
private int shaderprogram;
private final Animator animator = new Animator(this);
private float x = -2;
private float y = -2;
private float height = 4;
private float width = 4;
private int iterations = 255;

public SimpleShaderExample() {
	addGLEventListener(this);
    animator.start();
}

public void init(GLAutoDrawable drawable) {
    GL gl = drawable.getGL();

    // Enable VSync
    gl.setSwapInterval(1);
	gl.glShadeModel(GL.GL_FLAT);
	try {
		attachShaders(gl);
	} catch (Exception e) {
		e.printStackTrace();
	}
}

private String[] loadShaderSrc(String name){
	StringBuilder sb = new StringBuilder();
	try{
		InputStream is = getClass().getResourceAsStream(name);
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		String line;
		while ((line = br.readLine())!=null){
			sb.append(line);
			sb.append('\n');
		}
		is.close();
	}
	catch (Exception e){
		e.printStackTrace();
	}
	System.out.println("Shader is "+sb.toString());
	return new String[]{sb.toString()};
}

private void attachShaders(GL gl) throws Exception {
	vertexShaderProgram = gl.glCreateShader(GL.GL_VERTEX_SHADER);
	fragmentShaderProgram = gl.glCreateShader(GL.GL_FRAGMENT_SHADER);

	String[] vsrc = new String[]{"uniform float mandel_x;\n" +
			"uniform float mandel_y;\n" +
			"uniform float mandel_width;\n" +
			"uniform float mandel_height; \n" +
			"uniform float mandel_iterations;\n" +
			"\n" +
			"void main()\n" +
			"{\n" +
			"\tgl_TexCoord[0] = gl_MultiTexCoord0;\n" +
			"\tgl_Position = ftransform();\n" +
			"}"};
	gl.glShaderSource(vertexShaderProgram, 1, vsrc, null, 0);
	gl.glCompileShader(vertexShaderProgram);

	String[] fsrc = new String[]{"uniform float mandel_x;\n" +
			"uniform float mandel_y;\n" +
			"uniform float mandel_width;\n" +
			"uniform float mandel_height; \n" +
			"uniform float mandel_iterations;\n" +
			"\n" +
			"float calculateMandelbrotIterations(float x, float y) {\n" +
			"\tfloat xx = 0.0;\n" +
			"    float yy = 0.0;\n" +
			"    float iter = 0.0;\n" +
			"    while (xx * xx + yy * yy <= 4.0 && iter<mandel_iterations) {\n" +
			"        float temp = xx*xx - yy*yy + x;\n" +
			"        yy = 2.0*xx*yy + y;\n" +
			"\n" +
			"        xx = temp;\n" +
			"\n" +
			"        iter ++;\n" +
			"    }\n" +
			"    return iter;\n" +
			"}\n" +
			"\n" +
			"vec4 getColor(float iterations) {\n" +
			"\tfloat oneThirdMandelIterations = mandel_iterations/3.0;\n" +
			"\tfloat green = iterations/oneThirdMandelIterations;\n" +
			"\tfloat blue = (iterations-1.3*oneThirdMandelIterations)/oneThirdMandelIterations;\n" +
			"\tfloat red = (iterations-2.2*oneThirdMandelIterations)/oneThirdMandelIterations;\n" +
			"\treturn vec4(red,green,blue,1.0);\n" +
			"}\n" +
			"\n" +
			"void main()\n" +
			"{\n" +
			"\tfloat x = mandel_x+gl_TexCoord[0].x*mandel_width;\n" +
			"\tfloat y = mandel_y+gl_TexCoord[0].y*mandel_height;\n" +
			"\tfloat iterations = calculateMandelbrotIterations(x,y);\n" +
			"\tgl_FragColor = getColor(iterations);\n" +
			"}"};
	gl.glShaderSource(fragmentShaderProgram, 1, fsrc, null, 0);
	gl.glCompileShader(fragmentShaderProgram);

	shaderprogram = gl.glCreateProgram();
	gl.glAttachShader(shaderprogram, vertexShaderProgram);
	gl.glAttachShader(shaderprogram, fragmentShaderProgram);
	gl.glLinkProgram(shaderprogram);
	gl.glValidateProgram(shaderprogram);
	IntBuffer intBuffer = IntBuffer.allocate(1);
	gl.glGetProgramiv(shaderprogram, GL.GL_LINK_STATUS,intBuffer);
	if (intBuffer.get(0)!=1){
		gl.glGetProgramiv(shaderprogram, GL.GL_INFO_LOG_LENGTH,intBuffer);
		int size = intBuffer.get(0);
		System.err.println("Program link error: ");
		if (size>0){
			ByteBuffer byteBuffer = ByteBuffer.allocate(size);
			gl.glGetProgramInfoLog(shaderprogram, size, intBuffer, byteBuffer);
			for (byte b:byteBuffer.array()){
				System.err.print((char)b);
			}
		} else {
			System.out.println("Unknown");
		}
		System.exit(1);
	}
	gl.glUseProgram(shaderprogram);
}

public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
    GL gl = drawable.getGL();
    GLU glu = new GLU();

    if (height <= 0) { // avoid a divide by zero error!

        height = 1;
    }
    final float h = (float) width / (float) height;
    gl.glViewport(0, 0, width, height);
    gl.glMatrixMode(GL.GL_PROJECTION);
    gl.glLoadIdentity();
    glu.gluOrtho2D(0, 1, 0, 1);
    gl.glMatrixMode(GL.GL_MODELVIEW);
    gl.glLoadIdentity();
}



public void display(GLAutoDrawable drawable) {
    GL gl = drawable.getGL();

	if (updateUniformVars){
		updateUniformVars(gl);
	}

    // Reset the current matrix to the "identity"
    gl.glLoadIdentity();

    // Draw A Quad
    gl.glBegin(GL.GL_QUADS);
	{
		gl.glTexCoord2f(0.0f, 1.0f);
		gl.glVertex3f(0.0f, 1.0f, 1.0f);  // Top Left
		gl.glTexCoord2f(1.0f, 1.0f);
		gl.glVertex3f(1.0f, 1.0f, 1.0f);   // Top Right
		gl.glTexCoord2f(1.0f, 0.0f);
		gl.glVertex3f(1.0f, 0.0f, 1.0f);  // Bottom Right
		gl.glTexCoord2f(0.0f, 0.0f);
		gl.glVertex3f(0.0f, 0.0f, 1.0f); // Bottom Left
	}
	// Done Drawing The Quad
    gl.glEnd();

    // Flush all drawing operations to the graphics card
    gl.glFlush();
}

private void updateUniformVars(GL gl) {
	int mandel_x = gl.glGetUniformLocation(shaderprogram, "mandel_x");
	int mandel_y = gl.glGetUniformLocation(shaderprogram, "mandel_y");
	int mandel_width = gl.glGetUniformLocation(shaderprogram, "mandel_width");
	int mandel_height = gl.glGetUniformLocation(shaderprogram, "mandel_height");
	int mandel_iterations = gl.glGetUniformLocation(shaderprogram, "mandel_iterations");
	assert(mandel_x!=-1);
	assert(mandel_y!=-1);
	assert(mandel_width!=-1);
	assert(mandel_height!=-1);
	assert(mandel_iterations!=-1);

	gl.glUniform1f(mandel_x, x);
	gl.glUniform1f(mandel_y, y);
	gl.glUniform1f(mandel_width, width);
	gl.glUniform1f(mandel_height, height);
	gl.glUniform1f(mandel_iterations, iterations);

}

public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
}

public static void main(String[] args) {
	SwingUtilities.invokeLater(new Runnable() {
		public void run() {
			JFrame jf = new JFrame();
			jf.setSize(800,800);
			jf.getContentPane().setLayout(new BorderLayout());
			jf.getContentPane().add(new SimpleShaderExample(), BorderLayout.CENTER);
			jf.setVisible(true);
		}
	});

}

}

Thank you so much! :slight_smile:

I have now finished my blog post (or at least the first part) - with a few improvements in the GLSL code. You can find it here:

Kind regards,
Morten

Thanks. I advise you to have a look at JOCL/JOGL 2 examples that Mickael Bien wrote, some of them deal with Mandelbrot, it might be interesting for you.