Skip to content

Instantly share code, notes, and snippets.

@scottdw
Created August 5, 2013 06:29

Revisions

  1. scottdw created this gist Aug 5, 2013.
    85 changes: 85 additions & 0 deletions gl.clj
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,85 @@
    (ns scottdw.mmgr.gl
    (:import [javax.media.opengl DebugGL3 GL GL2 GL3 GLAutoDrawable GLCapabilities GLEventListener GLProfile]
    [com.jogamp.newt NewtFactory]
    [com.jogamp.newt.event WindowAdapter WindowEvent]
    [com.jogamp.newt.opengl GLWindow])
    (:require [clojure.java.io :as io]
    [taoensso.timbre :as timbre :refer (trace debug error)]))

    (defn create-shader [^GL3 gl resource type]
    (let [source (slurp (io/resource resource))
    shader (.glCreateShader gl type)
    ^Strings s-holder (into-array String [source])
    ^ints i-holder (into-array Integer/TYPE [(count source)])]
    (if (zero? shader)
    (error (str "Shader not created: " resource))
    (do
    (doto gl
    (.glShaderSource shader 1 s-holder i-holder 0)
    (.glCompileShader shader)
    (.glGetShaderiv shader GL3/GL_COMPILE_STATUS i-holder 0))
    (if-not (zero? (aget i-holder 0))
    (do
    (trace (str resource ": compiled."))
    shader)
    (error
    (do
    (.glGetShaderiv gl shader GL3/GL_INFO_LOG_LENGTH i-holder 0)
    (let [log-length (aget i-holder 0)
    ^bytes ba (make-array Byte/TYPE log-length)]
    (.glGetShaderInfoLog gl shader log-length nil 0 ba 0)
    (str "Error compiling: " resource ": " (String. ba 0 (dec log-length)))))))))))

    (defn init [^GL3 gl3 shaders gl-state]
    (doseq [[k {:keys [resource type]}] shaders]
    (if-let [s (create-shader gl3 resource type)]
    (swap! gl-state update-in [:shaders] assoc k s))))

    (defn display [^GL3 gl3])

    (defn dispose [^GL3 gl3 gl-state]
    (doseq [[k s] (:shaders @gl-state)]
    (.glDeleteShader gl3 s)
    (swap! gl-state update-in [:shaders] dissoc k)))

    (defn reshape [^GL3 gl3 w h]
    (.glViewport gl3 0 0 w h))

    (defn gl-info [^GLCapabilities caps ^GL gl]
    (trace (str "GL info: " \newline
    "GLCapabilities: " caps \newline
    "GL class: " (-> gl .getClass .getName) \newline
    "GL_VENDOR: " (.glGetString gl GL/GL_VENDOR) \newline
    "GL_RENDERER: " (.glGetString gl GL/GL_RENDERER) \newline
    "GL_VERSION: " (.glGetString gl GL/GL_VERSION) \newline
    "GL_SHADING_LANGUAGE_VERSION" (.glGetString gl GL3/GL_SHADING_LANGUAGE_VERSION))))

    (let [shaders {:simple-vertex {:resource "shaders/simple.vshader" :type GL3/GL_VERTEX_SHADER}
    :simple-fragment {:resource "shaders/simple.fshader" :type GL3/GL_FRAGMENT_SHADER}}
    gl3 (fn [^GLAutoDrawable drawable]
    (-> drawable .getGL .getGL3))]
    (defn create-gl-event-listener [gl-state debug]
    (reify GLEventListener
    (init [this drawable]
    (when debug
    (.setGL drawable (DebugGL3. (gl3 drawable))))
    (init (gl3 drawable) shaders gl-state))
    (display [this drawable]
    (display (gl3 drawable)))
    (dispose [this drawable]
    (dispose (gl3 drawable) gl-state))
    (reshape [this drawable x y w h]
    (reshape (gl3 drawable) w h)))))

    (defn create-window
    ([] (create-window (atom {}) false))
    ([gl-state debug]
    (let [caps (doto (-> GLProfile/GL3 GLProfile/get GLCapabilities.)
    (.setBackgroundOpaque true))
    dpy (NewtFactory/createDisplay nil)
    screen (NewtFactory/createScreen dpy 0)]
    (doto (GLWindow/create screen caps)
    (.setSize 512 512)
    (.setTitle "NEWT Window Test")
    (.addGLEventListener (create-gl-event-listener gl-state debug))
    (.setVisible true)))))