Render triangle
This commit is contained in:
parent
b3c1fc5edf
commit
0f8dae0943
3
deps.edn
3
deps.edn
@ -8,4 +8,5 @@
|
|||||||
org.lwjgl/lwjgl-assimp {:mvn/version "3.3.3"}
|
org.lwjgl/lwjgl-assimp {:mvn/version "3.3.3"}
|
||||||
org.lwjgl/lwjgl-assimp$natives-linux {:mvn/version "3.3.3"}
|
org.lwjgl/lwjgl-assimp$natives-linux {:mvn/version "3.3.3"}
|
||||||
org.joml/joml {:mvn/version "1.10.7"}}
|
org.joml/joml {:mvn/version "1.10.7"}}
|
||||||
:paths ["src"]}
|
:paths ["src"]
|
||||||
|
:aliases {:dev {:jvm-opts ["-Djdk.attach.allowAttachSelf=true"]}}}
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
in vec3 color;
|
uniform vec4 uColor;
|
||||||
|
|
||||||
out vec4 fragment;
|
out vec4 fragment;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
fragment = vec4(color, 1.0);
|
fragment = uColor;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,14 +1,8 @@
|
|||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
uniform mat4 MVP;
|
in vec3 vPos;
|
||||||
|
|
||||||
in vec3 vCol;
|
|
||||||
in vec2 vPos;
|
|
||||||
|
|
||||||
out vec3 color;
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = MVP * vec4(vPos, 0.0, 1.0);
|
gl_Position = vec4(vPos, 1.0);
|
||||||
color = vCol;
|
|
||||||
}
|
}
|
||||||
|
|||||||
125
src/nol/core.clj
125
src/nol/core.clj
@ -1,4 +1,5 @@
|
|||||||
(ns nol.core
|
(ns nol.core
|
||||||
|
(:require [clojure.math])
|
||||||
(:import [org.lwjgl.assimp Assimp AIScene AIMesh AIVector3D AIFace]
|
(:import [org.lwjgl.assimp Assimp AIScene AIMesh AIVector3D AIFace]
|
||||||
[org.lwjgl.glfw GLFW GLFWKeyCallbackI GLFWErrorCallbackI]
|
[org.lwjgl.glfw GLFW GLFWKeyCallbackI GLFWErrorCallbackI]
|
||||||
[org.lwjgl.opengl GL GL45 GL33 GL20 GL15 GL11 GL30]
|
[org.lwjgl.opengl GL GL45 GL33 GL20 GL15 GL11 GL30]
|
||||||
@ -6,6 +7,21 @@
|
|||||||
[org.joml Matrix4f]
|
[org.joml Matrix4f]
|
||||||
[java.nio FloatBuffer]))
|
[java.nio FloatBuffer]))
|
||||||
|
|
||||||
|
(def render-queue (java.util.concurrent.LinkedBlockingQueue.))
|
||||||
|
|
||||||
|
(def state (atom {:last-time (GLFW/glfwGetTime) :window nil}))
|
||||||
|
|
||||||
|
(def gl-thread (atom nil))
|
||||||
|
|
||||||
|
(defmacro with-gl [& body]
|
||||||
|
`(let [result# (promise)]
|
||||||
|
(.put render-queue #(deliver result# (try (do ~@body)
|
||||||
|
(catch Exception e# e#))))
|
||||||
|
(let [r# (deref result#)]
|
||||||
|
(if (instance? Exception r#)
|
||||||
|
(throw r#)
|
||||||
|
r#))))
|
||||||
|
|
||||||
(def vertex-shader-text (slurp "shaders/base.vert"))
|
(def vertex-shader-text (slurp "shaders/base.vert"))
|
||||||
|
|
||||||
(def fragment-shader-text (slurp "shaders/base.frag"))
|
(def fragment-shader-text (slurp "shaders/base.frag"))
|
||||||
@ -27,15 +43,13 @@
|
|||||||
(throw (RuntimeException. (str "Program link error: " (GL20/glGetProgramInfoLog program)))))
|
(throw (RuntimeException. (str "Program link error: " (GL20/glGetProgramInfoLog program)))))
|
||||||
program))
|
program))
|
||||||
|
|
||||||
(def state (atom {:last-time (GLFW/glfwGetTime)}))
|
|
||||||
|
|
||||||
(defn load-model [path]
|
(defn load-model [path]
|
||||||
(Assimp/aiImportFile path (bit-or Assimp/aiProcess_Triangulate
|
(Assimp/aiImportFile path (bit-or Assimp/aiProcess_Triangulate
|
||||||
Assimp/aiProcess_FlipUVs)))
|
Assimp/aiProcess_FlipUVs)))
|
||||||
|
|
||||||
(def vertices (float-array [0.0 0.5 0.0
|
(def vertices (float-array [0.0 1.0 0.0
|
||||||
-0.5 0.5 0.0
|
-1.0 -1.0 0.0
|
||||||
0.5 -0.5 0.0]))
|
1.0 -1.0 0.0]))
|
||||||
|
|
||||||
(defn- update-loop [window stack data]
|
(defn- update-loop [window stack data]
|
||||||
(let [w-buf (.mallocInt stack 1)
|
(let [w-buf (.mallocInt stack 1)
|
||||||
@ -43,14 +57,31 @@
|
|||||||
_ (GLFW/glfwGetFramebufferSize window w-buf h-buf)
|
_ (GLFW/glfwGetFramebufferSize window w-buf h-buf)
|
||||||
w (.get w-buf 0)
|
w (.get w-buf 0)
|
||||||
h (.get h-buf 0)
|
h (.get h-buf 0)
|
||||||
current-time (GLFW/glfwGetTime)]
|
t (GLFW/glfwGetTime)]
|
||||||
(GL11/glViewport 0 0 w h)
|
(GL11/glViewport 0 0 w h)
|
||||||
(GL11/glClear GL11/GL_COLOR_BUFFER_BIT)
|
(GL11/glClear GL11/GL_COLOR_BUFFER_BIT)
|
||||||
|
|
||||||
(swap! state assoc :last-time current-time)
|
(swap! state assoc :last-time t)
|
||||||
|
|
||||||
|
(GL45/glUseProgram (:program data))
|
||||||
|
(let [loc (GL45/glGetUniformLocation (:program data) "uColor")
|
||||||
|
t (* t 2)]
|
||||||
|
(GL45/glUniform4f loc
|
||||||
|
(* 0.5 (+ 1.0 (clojure.math/sin t)))
|
||||||
|
(* 0.5 (+ 1.0 (clojure.math/sin (+ t 2.094))))
|
||||||
|
(* 0.5 (+ 1.0 (clojure.math/sin (+ t 4.189))))
|
||||||
|
1.0))
|
||||||
|
(GL45/glBindVertexArray (:vao data))
|
||||||
|
(GL45/glDrawArrays GL45/GL_TRIANGLES 0 3)
|
||||||
|
|
||||||
(GLFW/glfwSwapBuffers window)))
|
(GLFW/glfwSwapBuffers window)))
|
||||||
|
|
||||||
|
(defn stop! []
|
||||||
|
;; signal the window to close
|
||||||
|
(with-gl
|
||||||
|
(GLFW/glfwSetWindowShouldClose
|
||||||
|
(:window @state) true)))
|
||||||
|
|
||||||
(defn -main []
|
(defn -main []
|
||||||
(when-not (GLFW/glfwInit)
|
(when-not (GLFW/glfwInit)
|
||||||
(throw (RuntimeException. "Failed to init GLFW")))
|
(throw (RuntimeException. "Failed to init GLFW")))
|
||||||
@ -64,32 +95,90 @@
|
|||||||
(GLFW/glfwTerminate)
|
(GLFW/glfwTerminate)
|
||||||
(throw (RuntimeException. "Failed to create window")))
|
(throw (RuntimeException. "Failed to create window")))
|
||||||
|
|
||||||
|
|
||||||
(GLFW/glfwMakeContextCurrent window)
|
(GLFW/glfwMakeContextCurrent window)
|
||||||
(GL/createCapabilities)
|
(GL/createCapabilities)
|
||||||
(GLFW/glfwSwapInterval 1)
|
(GLFW/glfwSwapInterval 1)
|
||||||
|
|
||||||
|
(swap! state assoc :window window :should-close false)
|
||||||
|
|
||||||
(GLFW/glfwSetKeyCallback window
|
(GLFW/glfwSetKeyCallback window
|
||||||
(reify GLFWKeyCallbackI
|
(reify GLFWKeyCallbackI
|
||||||
(invoke [_ win key scancode action mods]
|
(invoke [_ win key scancode action mods]
|
||||||
(when (and (= key GLFW/GLFW_KEY_ESCAPE) (= action GLFW/GLFW_PRESS))
|
(when (and (= key GLFW/GLFW_KEY_ESCAPE) (= action GLFW/GLFW_PRESS))
|
||||||
(GLFW/glfwSetWindowShouldClose win true)))))
|
(swap! state assoc :should-close true)))))
|
||||||
|
|
||||||
(loop []
|
(let [vbo (GL45/glCreateBuffers)
|
||||||
(when-not (GLFW/glfwWindowShouldClose window)
|
vao (GL45/glCreateVertexArrays)
|
||||||
(GLFW/glfwPollEvents)
|
data (try
|
||||||
(let [stack (MemoryStack/stackPush)]
|
(let [vert (compile-shader GL20/GL_VERTEX_SHADER vertex-shader-text)
|
||||||
(try
|
frag (compile-shader GL20/GL_FRAGMENT_SHADER fragment-shader-text)
|
||||||
(update-loop window stack)
|
program (link-program vert frag)]
|
||||||
(finally
|
(GL45/glNamedBufferStorage vbo vertices GL45/GL_DYNAMIC_STORAGE_BIT)
|
||||||
(MemoryStack/stackPop))))
|
(GL45/glVertexArrayVertexBuffer vao 0 vbo 0 12)
|
||||||
(recur)))
|
(GL45/glEnableVertexArrayAttrib vao 0)
|
||||||
|
(GL45/glVertexArrayAttribFormat vao 0 3 GL45/GL_FLOAT false 0)
|
||||||
|
(GL45/glVertexArrayAttribBinding vao 0 0)
|
||||||
|
{:vbo vbo :vao vao :program program})
|
||||||
|
(catch Exception e
|
||||||
|
(println "Setup error:" (.getMessage e))
|
||||||
|
nil))]
|
||||||
|
(swap! state merge data)
|
||||||
|
(loop []
|
||||||
|
(while (not (.isEmpty render-queue))
|
||||||
|
((.take render-queue)))
|
||||||
|
(when-not (or (:should-close @state)
|
||||||
|
(GLFW/glfwWindowShouldClose window))
|
||||||
|
(GLFW/glfwPollEvents)
|
||||||
|
(let [stack (MemoryStack/stackPush)]
|
||||||
|
(try
|
||||||
|
(update-loop window stack data)
|
||||||
|
(finally
|
||||||
|
(MemoryStack/stackPop))))
|
||||||
|
(recur))))
|
||||||
|
|
||||||
(GLFW/glfwDestroyWindow window)
|
(GLFW/glfwDestroyWindow window)
|
||||||
(GLFW/glfwTerminate)))
|
(GLFW/glfwTerminate)))
|
||||||
|
|
||||||
|
(defn start! []
|
||||||
|
(when (and @gl-thread (.isAlive @gl-thread))
|
||||||
|
(throw (RuntimeException. "Already running")))
|
||||||
|
(reset! gl-thread
|
||||||
|
(doto (Thread. (fn []
|
||||||
|
(try
|
||||||
|
(-main)
|
||||||
|
(catch Exception e
|
||||||
|
(println "GL thread error:" e)))))
|
||||||
|
(.setName "opengl-thread")
|
||||||
|
(.setDaemon true)
|
||||||
|
(.start))))
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(-main)
|
(start!)
|
||||||
|
(stop!)
|
||||||
(def ^AIScene scene (load-model "assets/model.glb"))
|
(def ^AIScene scene (load-model "assets/model.glb"))
|
||||||
(.mNumMeshes scene) ;; 54
|
(.mNumMeshes scene) ;; 54
|
||||||
(.mNumMaterials scene) ;; 17
|
(.mNumMaterials scene) ;; 17
|
||||||
|
(with-gl
|
||||||
|
(GL11/glClearColor 0.392 0.584 0.929 1.0))
|
||||||
|
|
||||||
|
(with-gl
|
||||||
|
(GL45/glNamedBufferSubData (:vbo @state) 0 ^floats (float-array [ 0.0 0.5 0.0
|
||||||
|
-0.5 -0.5 0.0
|
||||||
|
0.5 -0.5 0.0])))
|
||||||
|
(with-gl
|
||||||
|
(GL45/glNamedBufferSubData (:vbo @state) 0 ^floats (float-array [ 0.0 1.0 0.0
|
||||||
|
-1.0 -1.0 0.0
|
||||||
|
1.0 -1.0 0.0])))
|
||||||
|
|
||||||
|
(def program (with-gl (let [vert (compile-shader GL20/GL_VERTEX_SHADER vertex-shader-text)
|
||||||
|
frag (compile-shader GL20/GL_FRAGMENT_SHADER fragment-shader-text)]
|
||||||
|
(link-program vert frag))))
|
||||||
|
|
||||||
|
(with-gl (GL45/glVertexArrayVertexBuffer vao 0 vbo 0 12))
|
||||||
|
|
||||||
|
(with-gl (GL45/glEnableVertexArrayAttrib vao 0)
|
||||||
|
(GL45/glVertexArrayAttribFormat vao 0 3 GL45/GL_FLOAT false 0)
|
||||||
|
(GL45/glVertexArrayAttribBinding vao 0 0))
|
||||||
|
|
||||||
:-)
|
:-)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user