After much struggling I finally got a simple OpenGL example working in Clojure!
Here’s a port of the JOGL example in Wikipedia to Clojure:
;This is a Clojure port of the JOGL example in Wikipedia;Author: Curran Kelleher;License: Public Domain;dependencies: jogl.jar, gluegen-rt.jar
;for the REPL (use C-x C-e):(comment;these are the default paths of the jars in Ubuntu(add-classpath "file:/usr/share/java/jogl.jar")(add-classpath "file:/usr/share/java/gluegen-rt.jar"))
(import '(java.awt Frame) '(java.awt.event WindowListener WindowAdapter KeyListener KeyEvent) '(javax.media.opengl GLCanvas GLEventListener GL GLAutoDrawable) '(javax.media.opengl.glu GLU) '(com.sun.opengl.util Animator))(def rotateT 0)(def glu (new GLU))(def canvas (new GLCanvas))(def frame (new Frame "Jogl 3D Shape/Rotation"))(def animator (new Animator canvas))(defn exit "Stops animation and closes the OpenGL frame." [](.stop animator)(.dispose frame))
(.addGLEventListenercanvas(proxy [GLEventListener] [] (display [#^GLAutoDrawable drawable] (doto (.getGL drawable) (.glClear (. GL GL_COLOR_BUFFER_BIT)) (.glClear (. GL GL_DEPTH_BUFFER_BIT)) (.glLoadIdentity) (.glTranslatef 0 0 -5)
(.glRotatef rotateT 1 0 0) (.glRotatef rotateT 0 1 0) (.glRotatef rotateT 0 0 1) (.glRotatef rotateT 0 1 0)
(.glBegin (. GL GL_TRIANGLES))
; Front (.glColor3f 0 1 1) (.glVertex3f 0 1 0) (.glColor3f 0 0 1) (.glVertex3f -1 -1 1) (.glColor3f 0 0 0) (.glVertex3f 1 -1 1)
; Right Side Facing Front (.glColor3f 0 1 1) (.glVertex3f 0 1 0) (.glColor3f 0 0 1) (.glVertex3f 1 -1 1) (.glColor3f 0 0 0) (.glVertex3f 0 -1 -1)
; Left Side Facing Front (.glColor3f 0 1 1) (.glVertex3f 0 1 0) (.glColor3f 0 0 1) (.glVertex3f 0 -1 -1) (.glColor3f 0 0 0) (.glVertex3f -1 -1 1)
;Bottom (.glColor3f 0 0 0) (.glVertex3f -1 -1 1) (.glColor3f 0.1 0.1 0.1) (.glVertex3f 1 -1 1) (.glColor3f 0.2 0.2 0.2) (.glVertex3f 0 -1 -1)
(.glEnd)) (def rotateT (+ 0.2 rotateT)))
(displayChanged [drawable m d])
(init [#^GLAutoDrawable drawable] (doto (.getGL drawable) (.glShadeModel (. GL GL_SMOOTH)) (.glClearColor 0 0 0 0) (.glClearDepth 1) (.glEnable (. GL GL_DEPTH_TEST)) (.glDepthFunc (. GL GL_LEQUAL)) (.glHint (. GL GL_PERSPECTIVE_CORRECTION_HINT) (. GL GL_NICEST))) (.addKeyListener drawable (proxy [KeyListener] [] (keyPressed [e] (when (= (.getKeyCode e) (. KeyEvent VK_ESCAPE)) (exit))))))
(reshape [#^GLAutoDrawable drawable x y w h] (when (> h 0) (let [gl (.getGL drawable)] (.glMatrixMode gl (. GL GL_PROJECTION)) (.glLoadIdentity gl) (.gluPerspective glu 50 (/ w h) 1 1000) (.glMatrixMode gl (. GL GL_MODELVIEW)) (.glLoadIdentity gl))))))
(doto frame(.add canvas)(.setSize 640 480)(.setUndecorated true)(.setExtendedState (. Frame MAXIMIZED_BOTH))(.addWindowListener (proxy [WindowAdapter] [] (windowClosing [e] (exit))))(.setVisible true))(.start animator)(.requestFocus canvas)
Here’s a shell script that will run it:
#!/bin/shjava -cp $CLOJURE_EXT/clojure.jar:/usr/share/java/jogl.jar:/usr/share/java/gluegen-rt.jar clojure.main joglExample.clj
The libraries can be installed in Ubuntu with
sudo apt-get install libjogl-java
Here’s the refactored Java example from Wikipedia:
import javax.media.opengl.GL;import javax.media.opengl.GLEventListener;import javax.media.opengl.GLAutoDrawable;import javax.media.opengl.glu.GLU;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import javax.media.opengl.GLCanvas;import java.awt.Frame;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import com.sun.opengl.util.Animator;
public class joglExample implements GLEventListener, KeyListener { float rotateT = 0.0f; static GLU glu = new GLU(); static GLCanvas canvas = new GLCanvas(); static Frame frame = new Frame("Jogl 3D Shape/Rotation"); static Animator animator = new Animator(canvas); public void display(GLAutoDrawable gLDrawable) { final GL gl = gLDrawable.getGL(); gl.glClear(GL.GL_COLOR_BUFFER_BIT); gl.glClear(GL.GL_DEPTH_BUFFER_BIT); gl.glLoadIdentity(); gl.glTranslatef(0.0f, 0.0f, -5.0f);
gl.glRotatef(rotateT, 1.0f, 0.0f, 0.0f); gl.glRotatef(rotateT, 0.0f, 1.0f, 0.0f); gl.glRotatef(rotateT, 0.0f, 0.0f, 1.0f); gl.glRotatef(rotateT, 0.0f, 1.0f, 0.0f);
gl.glBegin(GL.GL_TRIANGLES);
// Front gl.glColor3f(0.0f, 1.0f, 1.0f); gl.glVertex3f(0.0f, 1.0f, 0.0f); gl.glColor3f(0.0f, 0.0f, 1.0f); gl.glVertex3f(-1.0f, -1.0f, 1.0f); gl.glColor3f(0.0f, 0.0f, 0.0f); gl.glVertex3f(1.0f, -1.0f, 1.0f);
// Right Side Facing Front gl.glColor3f(0.0f, 1.0f, 1.0f); gl.glVertex3f(0.0f, 1.0f, 0.0f); gl.glColor3f(0.0f, 0.0f, 1.0f); gl.glVertex3f(1.0f, -1.0f, 1.0f); gl.glColor3f(0.0f, 0.0f, 0.0f); gl.glVertex3f(0.0f, -1.0f, -1.0f);
// Left Side Facing Front gl.glColor3f(0.0f, 1.0f, 1.0f); gl.glVertex3f(0.0f, 1.0f, 0.0f); gl.glColor3f(0.0f, 0.0f, 1.0f); gl.glVertex3f(0.0f, -1.0f, -1.0f); gl.glColor3f(0.0f, 0.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, 1.0f);
// Bottom gl.glColor3f(0.0f, 0.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, 1.0f); gl.glColor3f(0.1f, 0.1f, 0.1f); gl.glVertex3f(1.0f, -1.0f, 1.0f); gl.glColor3f(0.2f, 0.2f, 0.2f); gl.glVertex3f(0.0f, -1.0f, -1.0f);
gl.glEnd();
rotateT += 0.2f; }
public void displayChanged(GLAutoDrawable gLDrawable, boolean modeChanged, boolean deviceChanged) { }
public void init(GLAutoDrawable gLDrawable) { GL gl = gLDrawable.getGL(); gl.glShadeModel(GL.GL_SMOOTH); gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); gl.glClearDepth(1.0f); gl.glEnable(GL.GL_DEPTH_TEST); gl.glDepthFunc(GL.GL_LEQUAL); gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST); gLDrawable.addKeyListener(this); }
public void reshape(GLAutoDrawable gLDrawable, int x, int y, int width, int height) { GL gl = gLDrawable.getGL(); if(height <= 0) { height = 1; } float h = (float)width / (float)height; gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); glu.gluPerspective(50.0f, h, 1.0, 1000.0); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); }
public void keyPressed(KeyEvent e) { if(e.getKeyCode() == KeyEvent.VK_ESCAPE) { exit(); } }
public void keyReleased(KeyEvent e) { }
public void keyTyped(KeyEvent e) { }
public static void exit(){ animator.stop(); frame.dispose(); System.exit(0); }
public static void main(String[] args) { canvas.addGLEventListener(new joglExample()); frame.add(canvas); frame.setSize(640, 480); frame.setUndecorated(true); frame.setExtendedState(Frame.MAXIMIZED_BOTH); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { exit(); } }); frame.setVisible(true); animator.start(); canvas.requestFocus(); }}
Here’s a shell script that will run it:
#!/bin/shjavac -cp /usr/share/java/jogl.jar:/usr/share/java/gluegen-rt.jar joglExample.javajava -cp ./:/usr/share/java/jogl.jar:/usr/share/java/gluegen-rt.jar joglExample
Enjoy!