Compare commits

..

2 Commits

Author SHA1 Message Date
10e37cc33f Clean 2026-03-06 09:06:15 +07:00
0f8dae0943 Render triangle 2026-03-06 09:05:46 +07:00
4 changed files with 92 additions and 34 deletions

View File

@ -8,4 +8,5 @@
org.lwjgl/lwjgl-assimp {:mvn/version "3.3.3"}
org.lwjgl/lwjgl-assimp$natives-linux {:mvn/version "3.3.3"}
org.joml/joml {:mvn/version "1.10.7"}}
:paths ["src"]}
:paths ["src"]
:aliases {:dev {:jvm-opts ["-Djdk.attach.allowAttachSelf=true"]}}}

View File

@ -1,10 +1,10 @@
#version 330
in vec3 color;
uniform vec4 uColor;
out vec4 fragment;
void main()
{
fragment = vec4(color, 1.0);
fragment = uColor;
}

View File

@ -1,14 +1,8 @@
#version 330
uniform mat4 MVP;
in vec3 vCol;
in vec2 vPos;
out vec3 color;
in vec3 vPos;
void main()
{
gl_Position = MVP * vec4(vPos, 0.0, 1.0);
color = vCol;
gl_Position = vec4(vPos, 1.0);
}

View File

@ -1,11 +1,27 @@
(ns nol.core
(:import [org.lwjgl.assimp Assimp AIScene AIMesh AIVector3D AIFace]
[org.lwjgl.glfw GLFW GLFWKeyCallbackI GLFWErrorCallbackI]
[org.lwjgl.opengl GL GL45 GL33 GL20 GL15 GL11 GL30]
[org.lwjgl.system MemoryStack MemoryUtil]
(:require [clojure.math])
(:import [org.lwjgl.assimp Assimp AIFace AIMaterial AIMesh AIScene AIVector3D]
[org.lwjgl.glfw GLFW GLFWErrorCallbackI GLFWKeyCallbackI]
[org.lwjgl.opengl GL GL11 GL15 GL20 GL33 GL30 GL45]
[org.lwjgl.system MemoryUtil MemoryStack]
[org.joml Matrix4f]
[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 fragment-shader-text (slurp "shaders/base.frag"))
@ -27,15 +43,13 @@
(throw (RuntimeException. (str "Program link error: " (GL20/glGetProgramInfoLog program)))))
program))
(def state (atom {:last-time (GLFW/glfwGetTime)}))
(defn load-model [path]
(Assimp/aiImportFile path (bit-or Assimp/aiProcess_Triangulate
Assimp/aiProcess_FlipUVs)))
(def vertices (float-array [0.0 0.5 0.0
-0.5 0.5 0.0
0.5 -0.5 0.0]))
(def vertices (float-array [0.0 1.0 0.0
-1.0 -1.0 0.0
1.0 -1.0 0.0]))
(defn- update-loop [window stack data]
(let [w-buf (.mallocInt stack 1)
@ -43,14 +57,19 @@
_ (GLFW/glfwGetFramebufferSize window w-buf h-buf)
w (.get w-buf 0)
h (.get h-buf 0)
current-time (GLFW/glfwGetTime)]
t (GLFW/glfwGetTime)]
(GL11/glViewport 0 0 w h)
(GL11/glClear GL11/GL_COLOR_BUFFER_BIT)
(swap! state assoc :last-time current-time)
(swap! state assoc :last-time t)
(GLFW/glfwSwapBuffers window)))
(defn stop! []
(with-gl
(GLFW/glfwSetWindowShouldClose
(:window @state) true)))
(defn -main []
(when-not (GLFW/glfwInit)
(throw (RuntimeException. "Failed to init GLFW")))
@ -59,37 +78,81 @@
(GLFW/glfwWindowHint GLFW/GLFW_CONTEXT_VERSION_MINOR 5)
(GLFW/glfwWindowHint GLFW/GLFW_OPENGL_PROFILE GLFW/GLFW_OPENGL_CORE_PROFILE)
(let [window (GLFW/glfwCreateWindow 960 592 "NOL" MemoryUtil/NULL MemoryUtil/NULL)]
(let [window (GLFW/glfwCreateWindow 960 300 #_592 "NOL" MemoryUtil/NULL MemoryUtil/NULL)]
(when (= window MemoryUtil/NULL)
(GLFW/glfwTerminate)
(throw (RuntimeException. "Failed to create window")))
(GLFW/glfwMakeContextCurrent window)
(GL/createCapabilities)
(GLFW/glfwSwapInterval 1)
(swap! state assoc :window window :should-close false)
(GLFW/glfwSetKeyCallback window
(reify GLFWKeyCallbackI
(invoke [_ win key scancode action mods]
(when (and (= key GLFW/GLFW_KEY_ESCAPE) (= action GLFW/GLFW_PRESS))
(GLFW/glfwSetWindowShouldClose win true)))))
(swap! state assoc :should-close true)))))
(loop []
(when-not (GLFW/glfwWindowShouldClose window)
(GLFW/glfwPollEvents)
(let [stack (MemoryStack/stackPush)]
(try
(update-loop window stack)
(finally
(MemoryStack/stackPop))))
(recur)))
(let []
(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 {})
(finally
(MemoryStack/stackPop))))
(recur))))
(GLFW/glfwDestroyWindow window)
(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
(-main)
(start!)
(stop!)
(def ^AIScene scene (load-model "assets/model.glb"))
(.mNumMeshes scene) ;; 54
(.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))
:-)