我正在尝试使用lwjgl和clojure进行游戏开发。
我的第一步是尝试在REPL的OpenGL屏幕上显示一些东西。在我用莱茵爬虫发动爬虫之后,我到目前为止所做的就是:
(import org.lwjgl.opengl GL11 Display DisplayMode
(Display/setDisplayMode (DisplayMode. 800 600))
(Display/create) ; This shows a black 800x600 window as expected
(GL11/glClearColor 1.0 0.0 0.0 1.0)
(GL11/glClear (bit-or GL11/GL_COLOR_BUFFER_BIT GL11/GL_DEPTH_BUFFER_BIT))
(Display/update)注意,如果做得足够快,这是可行的。但是过了一段时间(即使我只是等待),我开始收到关于当前OpenGL上下文没有绑定到当前线程的错误。
(Display/update)
IllegalStateException No context is current org.lwjgl.opengl.LinuxContextImplementation.swapBuffers (LinuxContextImplementation.java:72)
(GL11/glClear ...)
RuntimeException No OpenGL context found in the current thread. org.lwjgl.opengl.GLContext.getCapabilities (GLContext.java:124)但是也许最有趣的错误发生在我试图调用显示/破坏时。
(Display/destroy)
IllegalStateException From thread Thread[nREPL-worker-4,5,main]: Thread[nREPL-worker-0,5,] already has the context current org.lwjgl.opengl.ContextGL.checkAccess (ContextGL.java:184)这一切看起来就像爬虫在一段时间的不活动之后随机地产生了另一个线程。正如我所读到的,LWJGL只允许您从最初创建它的线程发出OpenGL调用,所以我打赌这是导致这些错误的原因。
但是REPL怎么可能是随机切换线程呢?尤其是如果我什么都没做,只是等着。
发布于 2016-03-23 19:55:43
这是一个已知的问题已经报告了针对nREPL项目 (和关于Clojure Google Group讨论)。nREPL似乎使用线程池来终止空闲线程(可能根据keepalive )。
在它被修复之前,你可以用一个方法来解决这个问题(我承认,这有点尴尬):
(import '(java.util.concurrent Executors))
(def opengl-executor (Executors/newSingleThreadExecutor))
(defmacro with-executor [executor & body]
`(.submit ~executor (fn [] ~@body)))
(on-executor opengl-executor
(println (.getId (Thread/currentThread))))通过使用您自己的执行器,包装在on-executor中的所有代码都将在其线程中执行。newSingleThreadExecutor只创建一个线程,根据文档,只有在当前线程由于异常而失败时才会替换它。当您试图以长时间延迟执行最后一个表达式时,打印的线程ID应该保持不变。
请记住,在停止应用程序时,应该使用shutdown执行程序。
https://stackoverflow.com/questions/36185512
复制相似问题