Extract scene hiearchy and matrices, render recursively
This commit is contained in:
parent
fccb0ef878
commit
beed54fd18
109
src/nol/core.clj
109
src/nol/core.clj
@ -3,7 +3,7 @@
|
|||||||
[clojure.math])
|
[clojure.math])
|
||||||
(:import
|
(:import
|
||||||
[java.nio FloatBuffer IntBuffer]
|
[java.nio FloatBuffer IntBuffer]
|
||||||
[org.lwjgl.assimp AIColor4D AIMaterial AIMesh AIScene AIString AITexture Assimp]
|
[org.lwjgl.assimp AIColor4D AIMaterial AIMatrix4x4 AIMesh AINode AIScene AIString AITexture Assimp]
|
||||||
[org.lwjgl.glfw GLFW GLFWKeyCallbackI]
|
[org.lwjgl.glfw GLFW GLFWKeyCallbackI]
|
||||||
[org.lwjgl.opengl GL GL11 GL20 GL30 GL45]
|
[org.lwjgl.opengl GL GL11 GL20 GL30 GL45]
|
||||||
[org.lwjgl.stb STBImage]
|
[org.lwjgl.stb STBImage]
|
||||||
@ -44,10 +44,55 @@
|
|||||||
(throw (RuntimeException. (str "Program link error: " (GL20/glGetProgramInfoLog program)))))
|
(throw (RuntimeException. (str "Program link error: " (GL20/glGetProgramInfoLog program)))))
|
||||||
program))
|
program))
|
||||||
|
|
||||||
(def loaded-scenes (atom []))
|
(defn ai-matrix->matrix4f [^AIMatrix4x4 m]
|
||||||
(def uploaded-scenes (atom []))
|
(Matrix4f. (.a1 m) (.a2 m) (.a3 m) (.a4 m)
|
||||||
|
(.b1 m) (.b2 m) (.b3 m) (.b4 m)
|
||||||
|
(.c1 m) (.c2 m) (.c3 m) (.c4 m)
|
||||||
|
(.d1 m) (.d2 m) (.d3 m) (.d4 m)))
|
||||||
|
|
||||||
|
(defn matrix4f->vectors [^Matrix4f m]
|
||||||
|
[(vector (.m00 m) (.m01 m) (.m02 m) (.m03 m))
|
||||||
|
(vector (.m10 m) (.m11 m) (.m12 m) (.m13 m))
|
||||||
|
(vector (.m20 m) (.m21 m) (.m22 m) (.m23 m))
|
||||||
|
(vector (.m30 m) (.m31 m) (.m32 m) (.m33 m))])
|
||||||
|
|
||||||
|
(defn node-matrix4f [^AINode c]
|
||||||
|
(-> c
|
||||||
|
(.mTransformation)
|
||||||
|
(ai-matrix->matrix4f)))
|
||||||
|
|
||||||
|
(defn node-matrix [^AINode c]
|
||||||
|
(-> c
|
||||||
|
(.mTransformation)
|
||||||
|
(ai-matrix->matrix4f)
|
||||||
|
(matrix4f->vectors)))
|
||||||
|
|
||||||
|
(def loaded-scene (atom nil))
|
||||||
|
(def uploaded-scene (atom nil))
|
||||||
(def shaders (atom nil))
|
(def shaders (atom nil))
|
||||||
|
|
||||||
|
(defn render-scene [scene node mtx]
|
||||||
|
(when-let [mesh-indices (seq (:meshes node))]
|
||||||
|
(let [{:keys [gl-meshes gl-textures]} scene
|
||||||
|
{:keys [program uniforms]} @shaders]
|
||||||
|
(doseq [idx mesh-indices
|
||||||
|
:let [gl-mesh (nth gl-meshes idx)
|
||||||
|
mesh (:mesh gl-mesh)
|
||||||
|
[r g b a] (:color mesh)
|
||||||
|
tex-idx (:texture-idx mesh)]]
|
||||||
|
(GL20/glUniform4f (:color uniforms) r g b a)
|
||||||
|
(GL20/glUniformMatrix4fv (:mm uniforms) false mtx #_(:transform node))
|
||||||
|
(GL30/glBindVertexArray (:vao gl-mesh))
|
||||||
|
(when tex-idx
|
||||||
|
(let [tex-id (:gl-id (nth gl-textures tex-idx))]
|
||||||
|
(GL45/glActiveTexture GL45/GL_TEXTURE0)
|
||||||
|
(GL11/glBindTexture GL11/GL_TEXTURE_2D tex-id)
|
||||||
|
(GL20/glUniform1i (:tex uniforms) 0)))
|
||||||
|
(GL11/glDrawElements GL11/GL_TRIANGLES (:indices-count gl-mesh) GL11/GL_UNSIGNED_INT 0))))
|
||||||
|
(when-let [children (seq (:children node))]
|
||||||
|
(doseq [child children]
|
||||||
|
(render-scene scene child mtx))))
|
||||||
|
|
||||||
(defn- update-loop [window stack data]
|
(defn- update-loop [window stack data]
|
||||||
(let [w-buf (.mallocInt stack 1)
|
(let [w-buf (.mallocInt stack 1)
|
||||||
h-buf (.mallocInt stack 1)
|
h-buf (.mallocInt stack 1)
|
||||||
@ -57,31 +102,20 @@
|
|||||||
t (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)
|
||||||
|
(GL11/glClear (bit-or GL11/GL_COLOR_BUFFER_BIT GL11/GL_DEPTH_BUFFER_BIT))
|
||||||
|
|
||||||
;; (swap! state assoc :last-time t)
|
;; (swap! state assoc :last-time t)
|
||||||
(try
|
(try
|
||||||
(when (and (seq @uploaded-scenes) @shaders)
|
(when (and @uploaded-scene @shaders)
|
||||||
(doseq [scene @uploaded-scenes
|
(let [scene @uploaded-scene
|
||||||
:let [{:keys [meshes gl-meshes gl-textures]} scene
|
{:keys [program uniforms]} @shaders]
|
||||||
{:keys [program uniforms]} @shaders]]
|
|
||||||
(GL20/glUseProgram program)
|
(GL20/glUseProgram program)
|
||||||
(doseq [m gl-meshes
|
(let [buf (.mallocFloat stack 16)
|
||||||
:let [[r g b a] (:color (:mesh m))
|
m (Matrix4f.)]
|
||||||
tex-idx (:texture-idx (:mesh m))]]
|
(.get m buf)
|
||||||
(GL20/glUniform4f (:color uniforms) r g b a)
|
(GL20/glUniformMatrix4fv (:mv uniforms) false buf)
|
||||||
(let [buf (.mallocFloat stack 16)
|
(GL20/glUniformMatrix4fv (:mp uniforms) false buf)
|
||||||
m (Matrix4f.)]
|
(render-scene scene (:hiearchy scene) buf))))
|
||||||
(.get m buf)
|
|
||||||
(GL20/glUniformMatrix4fv (:mm uniforms) false buf)
|
|
||||||
(GL20/glUniformMatrix4fv (:mv uniforms) false buf)
|
|
||||||
(GL20/glUniformMatrix4fv (:mp uniforms) false buf))
|
|
||||||
(GL30/glBindVertexArray (:vao m))
|
|
||||||
(when tex-idx
|
|
||||||
(let [tex-id (:gl-id (nth gl-textures tex-idx))]
|
|
||||||
(GL45/glActiveTexture GL45/GL_TEXTURE0)
|
|
||||||
(GL11/glBindTexture GL11/GL_TEXTURE_2D tex-id)
|
|
||||||
(GL20/glUniform1i (:tex uniforms) 0)))
|
|
||||||
(GL11/glDrawElements GL11/GL_TRIANGLES (:indices-count m) GL11/GL_UNSIGNED_INT 0))))
|
|
||||||
(catch Exception e
|
(catch Exception e
|
||||||
(println "Update Loop GL thread error:" e)))
|
(println "Update Loop GL thread error:" e)))
|
||||||
|
|
||||||
@ -91,7 +125,7 @@
|
|||||||
(GLFW/glfwSwapBuffers window)))
|
(GLFW/glfwSwapBuffers window)))
|
||||||
|
|
||||||
(defn stop! []
|
(defn stop! []
|
||||||
(reset! uploaded-scenes [])
|
(reset! uploaded-scene nil)
|
||||||
(reset! shaders nil)
|
(reset! shaders nil)
|
||||||
(with-gl
|
(with-gl
|
||||||
(GLFW/glfwSetWindowShouldClose
|
(GLFW/glfwSetWindowShouldClose
|
||||||
@ -105,7 +139,7 @@
|
|||||||
(GLFW/glfwWindowHint GLFW/GLFW_CONTEXT_VERSION_MINOR 5)
|
(GLFW/glfwWindowHint GLFW/GLFW_CONTEXT_VERSION_MINOR 5)
|
||||||
(GLFW/glfwWindowHint GLFW/GLFW_OPENGL_PROFILE GLFW/GLFW_OPENGL_CORE_PROFILE)
|
(GLFW/glfwWindowHint GLFW/GLFW_OPENGL_PROFILE GLFW/GLFW_OPENGL_CORE_PROFILE)
|
||||||
|
|
||||||
(let [window (GLFW/glfwCreateWindow 960 #_1900 300 #_1100 "NOL" MemoryUtil/NULL MemoryUtil/NULL)]
|
(let [window (GLFW/glfwCreateWindow 960 300 #_#_1900 1100 "NOL" MemoryUtil/NULL MemoryUtil/NULL)]
|
||||||
(when (= window MemoryUtil/NULL)
|
(when (= window MemoryUtil/NULL)
|
||||||
(GLFW/glfwTerminate)
|
(GLFW/glfwTerminate)
|
||||||
(throw (RuntimeException. "Failed to create window")))
|
(throw (RuntimeException. "Failed to create window")))
|
||||||
@ -199,6 +233,14 @@
|
|||||||
Assimp/aiProcess_FlipUVs)]
|
Assimp/aiProcess_FlipUVs)]
|
||||||
(Assimp/aiImportFile path flags)))
|
(Assimp/aiImportFile path flags)))
|
||||||
|
|
||||||
|
(defn traverse [^AINode node]
|
||||||
|
{:node node
|
||||||
|
:meshes (let [buf (.mMeshes node)]
|
||||||
|
(mapv #(.get buf %) (range (.mNumMeshes node))))
|
||||||
|
:transform (node-matrix4f node)
|
||||||
|
:children (mapv #(traverse (AINode/create ^long (.get (.mChildren node) %)))
|
||||||
|
(range (.mNumChildren node)))})
|
||||||
|
|
||||||
(defn load-scene [path]
|
(defn load-scene [path]
|
||||||
(let [scene (load-model path)
|
(let [scene (load-model path)
|
||||||
meshes (doall
|
meshes (doall
|
||||||
@ -213,8 +255,10 @@
|
|||||||
h (int-array 1)
|
h (int-array 1)
|
||||||
channels (int-array 1)]
|
channels (int-array 1)]
|
||||||
{:data (STBImage/stbi_load_from_memory buf w h channels 4)
|
{:data (STBImage/stbi_load_from_memory buf w h channels 4)
|
||||||
:w (aget w 0) :h (aget h 0)}))))]
|
:w (aget w 0) :h (aget h 0)}))))
|
||||||
{:scene scene :meshes meshes :textures textures}))
|
hiearchy (traverse (.mRootNode scene))]
|
||||||
|
(Assimp/aiReleaseImport scene)
|
||||||
|
{:meshes meshes :textures textures :hiearchy hiearchy}))
|
||||||
|
|
||||||
(defn upload-scene! [scene]
|
(defn upload-scene! [scene]
|
||||||
(let [gl-meshes
|
(let [gl-meshes
|
||||||
@ -264,16 +308,17 @@
|
|||||||
:mv (GL20/glGetUniformLocation program "uView")
|
:mv (GL20/glGetUniformLocation program "uView")
|
||||||
:mp (GL20/glGetUniformLocation program "uProjection")}}))
|
:mp (GL20/glGetUniformLocation program "uProjection")}}))
|
||||||
|
|
||||||
|
(reset! loaded-scene (load-scene "assets/model.glb"))
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(start!)
|
(start!)
|
||||||
(stop!)
|
(stop!)
|
||||||
|
|
||||||
(@loaded-scenes)
|
(reset! uploaded-scene (with-gl (upload-scene! @loaded-scene)))
|
||||||
|
|
||||||
(swap! loaded-scenes conj (load-scene "assets/model.glb"))
|
|
||||||
(swap! uploaded-scenes conj (with-gl (upload-scene! (first @loaded-scenes))))
|
|
||||||
(reset! shaders (with-gl (load-shaders! "shaders/base.vert" "shaders/base.frag")))
|
(reset! shaders (with-gl (load-shaders! "shaders/base.vert" "shaders/base.frag")))
|
||||||
|
|
||||||
|
(with-gl
|
||||||
|
(GL11/glClear (bit-or GL11/GL_COLOR_BUFFER_BIT GL11/GL_DEPTH_BUFFER_BIT)))
|
||||||
(with-gl
|
(with-gl
|
||||||
(GL11/glClearColor 0.392 0.584 0.929 1.0))
|
(GL11/glClearColor 0.392 0.584 0.929 1.0))
|
||||||
(with-gl
|
(with-gl
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user