I've recently been trying to test OpenGL in Clojure with the lwjgl library. I started off with this code:
(ns test.core
(:import [org.lwjgl.opengl Display DisplayMode GL11]))
(defn init-window
[width height title]
(Display/setDisplayMode (DisplayMode. width height))
(Display/setTitle title)
(Display/create))
(defn update
[]
(GL11/glClearColor 0 0 0 0)
(GL11/glClear GL11/GL_COLOR_BUFFER_BIT))
(defn run
[]
(init-window 800 600 "test")
(while (not (Display/isCloseRequested))
(update)
(Display/update))
(Display/destroy))
(defn -main
[& args]
(.start (Thread. run)))
This worked well as in emacs, with the nREPL plugin, I could start it and while it was running change something (eg the call to glClearColor
).
I decided to split this into two seperate files, so I could reuse the init-window
function :
(ns copengl.core
(:import [org.lwjgl.opengl Display DisplayMode GL11]))
(defn init-window
[width height title]
(Display/setDisplayMode (DisplayMode. width height))
(Display/setTitle title)
(Display/create))
(defn mainloop
[{:keys [update-fn]}]
(while (not (Display/isCloseRequested))
(update-fn)
(Display/update))
(Display/destroy))
(defn run
[data]
(init-window (:width data) (:height data) (:title data))
(mainloop data))
(defn start
[data]
(.start (Thread. (partial run data))))
and then in a seperate file
(ns test.core
(:import [org.lwjgl.opengl Display DisplayMode GL11])
(:require [copengl.core :as starter]))
(def -main
[& args]
(starter/start {:width 800 :height 600 :title "Test" :update-fn update})
This, however, does not let me change while running. I have to close the window then execute -main
again to see the change.
So far I have tried putting these last two excerpts of code into just one file which also did not work. However, if I change the call from update-fn
to the name of my update function (update
) when they were in the same file I could change things while it was running.
I'm guessing this is because when I create the map with the update function in it passes the actual function and so if I redefine update
by using the nREPL plugin to evaluate it there is no effect because the mainloop
function is using the function - not looking up the symbol update
and using that.
Is there a way to have the code split between two files whilst still being able to change the code while running?