Thursday, March 1, 2012

LibGDX Triangle Example in Clojure

I started messing around with LibGDX with Clojure and came up with this translation of LibGDX's  example MyFirstTriangle.

There might be a bug in Clojure 1.3 with short arrays (?). While
float-array [0.5 0.5 0.5]
works,
short-array [0 1 2]
does not (exception).

(ns gdx1
  (:import (com.badlogic.gdx ApplicationListener Gdx)
           (com.badlogic.gdx.graphics GL10 Mesh VertexAttribute)
           (com.badlogic.gdx.backends.lwjgl LwjglApplication)))

(defn app-listener []
  (let [vertices (float-array [-0.5 -0.5 0 0.5 -0.5 0 0 0.5 0])
        triangles (into-array Short/TYPE [0 1 2])
        attrs (into-array VertexAttribute
         [(VertexAttribute.
           com.badlogic.gdx.graphics.VertexAttributes$Usage/Position
           3 "a_position")])
        mesh (ref nil)]
    (proxy [ApplicationListener] []
    (resize [w h] )
    (create []
      (let [m (doto (Mesh. true 3 3 attrs)
                (.setVertices vertices)
                (.setIndices triangles))]
      (dosync ( ref-set mesh m))))
    (render []
      (doto (Gdx/gl)
        (.glClear GL10/GL_COLOR_BUFFER_BIT))
     (doto @mesh
       (.render GL10/GL_TRIANGLES 0 3)))
    (pause [] )
    (resume [] )
    (dispose [] ))))

(defn App []
  (LwjglApplication. (app-listener) "My Game" 480 320 false))
This works fine in the repl. For Android, we would need to generate real classes, like so:
(ns net.thomas.android.MyFirstTriangle
  (:gen-class
   :extends com.badlogic.gdx.backends.android.AndroidApplication
   :exposes-methods {onCreate superOnCreate})
  (:import (android.os Bundle)
           (net.thomas.android Gdx1)
           (com.badlogic.gdx Gdx)
           (com.badlogic.gdx.backends.android AndroidApplication)))

(defn -onCreate [this bundle]
  (.superOnCreate this bundle)
  (.initialize this (Gdx1.) false))
and
(ns net.thomas.android.Gdx1
  (:gen-class
   :implements [com.badlogic.gdx.ApplicationListener]
  (:import (com.badlogic.gdx ApplicationListener Gdx)
           (com.badlogic.gdx.graphics GL10 Mesh VertexAttribute)))

(def vertices (float-array [-0.5 -0.5 0 0.5 -0.5 0 0 0.5 0]))
(def triangles (into-array Short/TYPE [0 1 2]))
(def mesh (ref nil))

(defn -resize [_ w h] )

(defn -create [_]
  (let [attrs (into-array VertexAttribute
                          [(VertexAttribute.
                            com.badlogic.gdx.graphics.VertexAttributes$Usage/Position
                            3 "a_position")])
        m (doto (Mesh. true 3 3 attrs)
            (.setVertices vertices)
            (.setIndices triangles))]
    (dosync (ref-set mesh m))))

(defn -render [_]
  (doto (Gdx/gl)
    (.glClear GL10/GL_COLOR_BUFFER_BIT))
  (doto @mesh
    (.render GL10/GL_TRIANGLES 0 3)))

(defn -pause [_] )
(defn -resume [_] )
(defn -dispose [_] )