From ef02f6177138b9b420fc03d9eedf1e7313d53a1e Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Sat, 7 Mar 2026 08:26:40 +0700 Subject: [PATCH] Extract and render mesh --- src/nol/core.clj | 64 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/src/nol/core.clj b/src/nol/core.clj index 73ec298..f335f69 100644 --- a/src/nol/core.clj +++ b/src/nol/core.clj @@ -43,10 +43,6 @@ (throw (RuntimeException. (str "Program link error: " (GL20/glGetProgramInfoLog program))))) program)) -(defn load-model [path] - (Assimp/aiImportFile path (bit-or Assimp/aiProcess_Triangulate - Assimp/aiProcess_FlipUVs))) - (def vertices (float-array [0.0 1.0 0.0 -1.0 -1.0 0.0 1.0 -1.0 0.0])) @@ -62,6 +58,18 @@ (GL11/glClear GL11/GL_COLOR_BUFFER_BIT) (swap! state assoc :last-time t) + (do + (GL20/glUseProgram program) + + (let [color-loc (GL20/glGetUniformLocation program "uColor")] + (GL20/glUniform4f color-loc 1.0 0.5 0.2 1.0)) + + (doseq [m meshes] + (GL30/glBindVertexArray (:vao m)) + (GL11/glDrawElements GL11/GL_TRIANGLES (:indices-count m) GL11/GL_UNSIGNED_INT 0)) + + (GL30/glBindVertexArray 0) + (GL20/glUseProgram 0)) (GLFW/glfwSwapBuffers window))) @@ -78,7 +86,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 300 #_592 "NOL" MemoryUtil/NULL MemoryUtil/NULL)] + (let [window (GLFW/glfwCreateWindow 1900 #_300 1100 "NOL" MemoryUtil/NULL MemoryUtil/NULL)] (when (= window MemoryUtil/NULL) (GLFW/glfwTerminate) (throw (RuntimeException. "Failed to create window"))) @@ -126,12 +134,54 @@ (.setDaemon true) (.start)))) +(defn extract-mesh [^AIScene scene idx] + (let [meshes (.mMeshes scene)] + (let [mesh (AIMesh/create (.get meshes idx)) + verts (.mVertices mesh) + n (.mNumVertices mesh) + vert-arr (float-array (* 3 n)) + faces (.mFaces mesh) + nf (.mNumFaces mesh) + idx-arr (int-array (* 3 nf))] + (dotimes [i n] + (let [v (.get verts i)] + (aset vert-arr (+ (* i 3) 0) (.x v)) + (aset vert-arr (+ (* i 3) 1) (.y v)) + (aset vert-arr (+ (* i 3) 2) (.z v)))) + (dotimes [i nf] + (let [face (.get faces i) + idxs (.mIndices face)] + (aset idx-arr (+ (* i 3) 0) (.get idxs 0)) + (aset idx-arr (+ (* i 3) 1) (.get idxs 1)) + (aset idx-arr (+ (* i 3) 2) (.get idxs 2)))) + {:verts vert-arr :indices idx-arr :mat-idx (.mMaterialIndex mesh)}))) + +(defn load-model [path] + (let [flags (bit-or Assimp/aiProcess_Triangulate + Assimp/aiProcess_FlipUVs)] + (Assimp/aiImportFile path flags))) + (comment (start!) (stop!) (def ^AIScene scene (load-model "assets/model.glb")) - (.mNumMeshes scene) ;; 54 - (.mNumMaterials scene) ;; 17 + + (def meshes (with-gl + (doall + (for [i (range (.mNumMeshes scene))] + (let [mesh (extract-mesh scene i) + vbo (GL45/glCreateBuffers) + ebo (GL45/glCreateBuffers) + vao (GL45/glCreateVertexArrays)] + (GL45/glNamedBufferStorage vbo (:verts mesh) GL45/GL_DYNAMIC_STORAGE_BIT) + (GL45/glNamedBufferStorage ebo (:indices mesh) GL45/GL_DYNAMIC_STORAGE_BIT) + (GL45/glVertexArrayElementBuffer vao ebo) + (GL45/glVertexArrayVertexBuffer vao 0 vbo 0 (* 3 Float/BYTES)) + (GL45/glVertexArrayAttribFormat vao 0 3 GL11/GL_FLOAT false 0) + (GL45/glVertexArrayAttribBinding vao 0 0) + (GL45/glEnableVertexArrayAttrib vao 0) + {:vbo vbo :vao vao :ebo ebo + :indices-count (alength (:indices mesh))}))))) (with-gl (GL11/glClearColor 0.392 0.584 0.929 1.0))