From 7dc8ebf8b201f2eba469e8d8e2fdb2690627bc74 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Fri, 13 Mar 2026 18:55:21 +0700 Subject: [PATCH] Get the child nodes translated and rendering and spinning --- .gitignore | 2 + src/nol/core.clj | 109 +++++++++++++++++++++++++++++++---------------- 2 files changed, 75 insertions(+), 36 deletions(-) diff --git a/.gitignore b/.gitignore index 613c299..03d1617 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ /.cpcache/ /.nrepl-port +/.clj-kondo/ +/.lsp/ diff --git a/src/nol/core.clj b/src/nol/core.clj index e1fc93b..e85bbdf 100644 --- a/src/nol/core.clj +++ b/src/nol/core.clj @@ -44,12 +44,18 @@ (throw (RuntimeException. (str "Program link error: " (GL20/glGetProgramInfoLog program))))) program)) -(defn ai-matrix->matrix4f [^AIMatrix4x4 m] +#_(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 ai-matrix->matrix4f [^AIMatrix4x4 m] + (Matrix4f. (.a1 m) (.b1 m) (.c1 m) (.d1 m) + (.a2 m) (.b2 m) (.c2 m) (.d2 m) + (.a3 m) (.b3 m) (.c3 m) (.d3 m) + (.a4 m) (.b4 m) (.c4 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)) @@ -71,27 +77,31 @@ (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 render-scene [stack scene node mtx] + (let [buf (.mallocFloat stack 16) + model-mtx (Matrix4f.)] + (.mul mtx (:transform node) model-mtx) + (.get model-mtx buf) + (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 buf) + (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 stack scene child model-mtx))))) (defn- update-loop [window stack data] (let [w-buf (.mallocInt stack 1) @@ -110,12 +120,27 @@ (let [scene @uploaded-scene {:keys [program uniforms]} @shaders] (GL20/glUseProgram program) - (let [buf (.mallocFloat stack 16) - m (Matrix4f.)] - (.get m buf) - (GL20/glUniformMatrix4fv (:mv uniforms) false buf) - (GL20/glUniformMatrix4fv (:mp uniforms) false buf) - (render-scene scene (:hiearchy scene) buf)))) + (let [vbuf (.mallocFloat stack 16) + pbuf (.mallocFloat stack 16) + radius 10.0 + cam-x (* radius (Math/sin t)) + cam-z (* radius (Math/cos t)) + vm (-> (Matrix4f.) + (.identity) + (.lookAt (float cam-x) (float 0.0) (float cam-z) + (float 0.0) (float 0.0) (float 0.0) + (float 0.0) (float 1.0) (float 0.0))) + pm (-> (Matrix4f.) + (.identity) + (.perspective (float (Math/toRadians 45)) + (float (/ (float w) (float h))) + (float 0.1) + (float 100.0)))] + (.get vm vbuf) + (.get pm pbuf) + (GL20/glUniformMatrix4fv (:mv uniforms) false vbuf) + (GL20/glUniformMatrix4fv (:mp uniforms) false pbuf) + (render-scene stack scene (:hiearchy scene) (Matrix4f.))))) (catch Exception e (println "Update Loop GL thread error:" e))) @@ -125,11 +150,20 @@ (GLFW/glfwSwapBuffers window))) (defn stop! [] - (reset! uploaded-scene nil) - (reset! shaders nil) (with-gl + (when @uploaded-scene + (doseq [{:keys [vbo vao ebo]} (:gl-meshes @uploaded-scene)] + (GL45/glDeleteBuffers vbo) + (GL45/glDeleteBuffers ebo) + (GL30/glDeleteVertexArrays vao)) + (doseq [{:keys [gl-id]} (:gl-textures @uploaded-scene)] + (GL11/glDeleteTextures gl-id))) + (when @shaders + (GL20/glDeleteProgram (:program @shaders))) (GLFW/glfwSetWindowShouldClose - (:window @state) true))) + (:window @state) true)) + (reset! uploaded-scene nil) + (reset! shaders nil)) (defn -main [] (when-not (GLFW/glfwInit) @@ -147,6 +181,9 @@ (GLFW/glfwMakeContextCurrent window) (GL/createCapabilities) + (GL11/glEnable GL11/GL_DEPTH_TEST) + (GL11/glEnable GL11/GL_CULL_FACE) + (GL11/glCullFace GL11/GL_BACK) (GLFW/glfwSwapInterval 1) (swap! state assoc :window window :should-close false) @@ -188,6 +225,11 @@ (.setDaemon true) (.start)))) +(defn load-model [path] + (let [flags (bit-or Assimp/aiProcess_Triangulate + Assimp/aiProcess_FlipUVs)] + (Assimp/aiImportFile path flags))) + (defn extract-mesh [^AIScene scene idx] (let [meshes (.mMeshes scene)] (let [mesh (AIMesh/create (long (.get meshes idx))) @@ -228,11 +270,6 @@ (parse-long (subs data-path 1))) :color [(.r mat-color) (.g mat-color) (.b mat-color) (.a mat-color)]}))) -(defn load-model [path] - (let [flags (bit-or Assimp/aiProcess_Triangulate - Assimp/aiProcess_FlipUVs)] - (Assimp/aiImportFile path flags))) - (defn traverse [^AINode node] {:node node :meshes (let [buf (.mMeshes node)]