Extract scene hiearchy and matrices, render recursively
This commit is contained in:
parent
fccb0ef878
commit
beed54fd18
101
src/nol/core.clj
101
src/nol/core.clj
@ -3,7 +3,7 @@
|
||||
[clojure.math])
|
||||
(:import
|
||||
[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.opengl GL GL11 GL20 GL30 GL45]
|
||||
[org.lwjgl.stb STBImage]
|
||||
@ -44,10 +44,55 @@
|
||||
(throw (RuntimeException. (str "Program link error: " (GL20/glGetProgramInfoLog program)))))
|
||||
program))
|
||||
|
||||
(def loaded-scenes (atom []))
|
||||
(def uploaded-scenes (atom []))
|
||||
(defn ai-matrix->matrix4f [^AIMatrix4x4 m]
|
||||
(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))
|
||||
|
||||
(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]
|
||||
(let [w-buf (.mallocInt stack 1)
|
||||
h-buf (.mallocInt stack 1)
|
||||
@ -57,31 +102,20 @@
|
||||
t (GLFW/glfwGetTime)]
|
||||
(GL11/glViewport 0 0 w h)
|
||||
(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)
|
||||
(try
|
||||
(when (and (seq @uploaded-scenes) @shaders)
|
||||
(doseq [scene @uploaded-scenes
|
||||
:let [{:keys [meshes gl-meshes gl-textures]} scene
|
||||
{:keys [program uniforms]} @shaders]]
|
||||
(when (and @uploaded-scene @shaders)
|
||||
(let [scene @uploaded-scene
|
||||
{:keys [program uniforms]} @shaders]
|
||||
(GL20/glUseProgram program)
|
||||
(doseq [m gl-meshes
|
||||
:let [[r g b a] (:color (:mesh m))
|
||||
tex-idx (:texture-idx (:mesh m))]]
|
||||
(GL20/glUniform4f (:color uniforms) r g b a)
|
||||
(let [buf (.mallocFloat stack 16)
|
||||
m (Matrix4f.)]
|
||||
(.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))))
|
||||
(GL20/glUniformMatrix4fv (:mp uniforms) false buf)
|
||||
(render-scene scene (:hiearchy scene) buf))))
|
||||
(catch Exception e
|
||||
(println "Update Loop GL thread error:" e)))
|
||||
|
||||
@ -91,7 +125,7 @@
|
||||
(GLFW/glfwSwapBuffers window)))
|
||||
|
||||
(defn stop! []
|
||||
(reset! uploaded-scenes [])
|
||||
(reset! uploaded-scene nil)
|
||||
(reset! shaders nil)
|
||||
(with-gl
|
||||
(GLFW/glfwSetWindowShouldClose
|
||||
@ -105,7 +139,7 @@
|
||||
(GLFW/glfwWindowHint GLFW/GLFW_CONTEXT_VERSION_MINOR 5)
|
||||
(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)
|
||||
(GLFW/glfwTerminate)
|
||||
(throw (RuntimeException. "Failed to create window")))
|
||||
@ -199,6 +233,14 @@
|
||||
Assimp/aiProcess_FlipUVs)]
|
||||
(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]
|
||||
(let [scene (load-model path)
|
||||
meshes (doall
|
||||
@ -213,8 +255,10 @@
|
||||
h (int-array 1)
|
||||
channels (int-array 1)]
|
||||
{:data (STBImage/stbi_load_from_memory buf w h channels 4)
|
||||
:w (aget w 0) :h (aget h 0)}))))]
|
||||
{:scene scene :meshes meshes :textures textures}))
|
||||
:w (aget w 0) :h (aget h 0)}))))
|
||||
hiearchy (traverse (.mRootNode scene))]
|
||||
(Assimp/aiReleaseImport scene)
|
||||
{:meshes meshes :textures textures :hiearchy hiearchy}))
|
||||
|
||||
(defn upload-scene! [scene]
|
||||
(let [gl-meshes
|
||||
@ -264,16 +308,17 @@
|
||||
:mv (GL20/glGetUniformLocation program "uView")
|
||||
:mp (GL20/glGetUniformLocation program "uProjection")}}))
|
||||
|
||||
(reset! loaded-scene (load-scene "assets/model.glb"))
|
||||
|
||||
(comment
|
||||
(start!)
|
||||
(stop!)
|
||||
|
||||
(@loaded-scenes)
|
||||
|
||||
(swap! loaded-scenes conj (load-scene "assets/model.glb"))
|
||||
(swap! uploaded-scenes conj (with-gl (upload-scene! (first @loaded-scenes))))
|
||||
(reset! uploaded-scene (with-gl (upload-scene! @loaded-scene)))
|
||||
(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
|
||||
(GL11/glClearColor 0.392 0.584 0.929 1.0))
|
||||
(with-gl
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user