This commit is contained in:
Aitor 2023-12-18 13:18:32 +01:00
parent 4690945f59
commit 189e6b31d0
2 changed files with 84 additions and 52 deletions

View File

@ -1,74 +1,100 @@
(ns app.main.ui.workspace.viewport.gl (ns app.main.ui.workspace.viewport.gl
(:require-macros [app.main.style :as stl]) (:require-macros [app.main.style :as stl])
(:require-macros [app.util.gl.macros :refer [slurp]]) (:require-macros [app.util.gl.macros :refer [slurp]])
(:require (:require
[app.common.math :as math] [app.common.math :as math]
[app.util.gl :as gl] [app.util.gl :as gl]
[cuerdas.core :as str] [cuerdas.core :as str]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
(def CANVAS_CONTEXT_ID "webgl2") (def CANVAS_CONTEXT_ID "webgl2")
(def default-vertex-shader (slurp "src/app/util/gl/shaders/default.v.glsl")) (def default-vertex-shader (slurp "src/app/util/gl/shaders/default.v.glsl"))
(def default-fragment-shader (slurp "src/app/util/gl/shaders/default.f.glsl")) (def default-fragment-shader (slurp "src/app/util/gl/shaders/default.f.glsl"))
#_(def shaders (js/Map.)) #_(def shaders (js/Map.))
(def programs (js/Map.)) (def programs (js/Map.))
#_(def textures (js/Map.)) #_(def textures (js/Map.))
#_(def framebuffers (js/Map.)) #_(def framebuffers (js/Map.))
(defn resize-canvas-to (defn parse-color-hex
[canvas width height] [color opacity]
(let [resized-width (not= (.-width canvas) width) (let [r (str/slice color 1 3)
resized-height (not= (.-height canvas) height) g (str/slice color 3 5)
resized (or resized-width resized-height)] b (str/slice color 5 7)]
(when resized-width #js [(/ (js/parseInt r 16) 255.0)
(set! (.-width canvas) width)) (/ (js/parseInt g 16) 255.0)
(when resized-height (/ (js/parseInt b 16) 255.0)
(set! (.-height canvas) height)) opacity]))
resized))
(defn resize-canvas (defn parse-color
[canvas] [color opacity]
(let [width (math/floor (.-clientWidth canvas)) (cond
height (math/floor (.-clientHeight canvas))] (str/starts-with? color "#")
(resize-canvas-to canvas width height))) (parse-color-hex color opacity)
(defn prepare-gl :else
[gl] #js [0.0 0.0 0.0 1.0]))
(let [default-program (gl/create-program-from-sources gl default-vertex-shader default-fragment-shader)]
(.set programs "default" default-program))) (defn resize-canvas-to
[canvas width height]
(let [resized-width (not= (.-width canvas) width)
resized-height (not= (.-height canvas) height)
resized (or resized-width resized-height)]
(when resized-width
(set! (.-width canvas) width))
(when resized-height
(set! (.-height canvas) height))
resized))
(defn resize-canvas
[canvas]
(let [width (math/floor (.-clientWidth canvas))
height (math/floor (.-clientHeight canvas))]
(resize-canvas-to canvas width height)))
(defn prepare-gl
[gl]
(let [default-program (gl/create-program-from-sources gl default-vertex-shader default-fragment-shader)]
(.set programs "default" default-program)))
(defn render-gl (defn render-gl
[gl objects vbox] [gl objects vbox]
(.clearColor gl 0.0 0.0 0.0 0.0) (.clearColor gl 1.0 0.0 1.0 0.5)
(.clear gl (.-COLOR_BUFFER_BIT gl)) (.clear gl (.-COLOR_BUFFER_BIT gl))
(.viewport gl 0 0 (.-width (.-canvas gl)) (.-height (.-canvas gl))) (.viewport gl 0 0 (.-width (.-canvas gl)) (.-height (.-canvas gl)))
(.useProgram gl (.get programs "default")) (.useProgram gl (.get programs "default"))
(.uniform2f gl (.getUniformLocation gl (.get programs "default") "u_screenSize") (.-width (.-canvas gl)) (.-height (.-canvas gl))) (println "---------------> vbox" (:x vbox) (:width vbox) (:y vbox) (:height vbox))
(.uniform4f gl (.getUniformLocation gl (.get programs "default") "u_vbox") (:x vbox) (:y vbox) (:width vbox) (:height vbox))
(println "objects vals" (vals objects))
(doseq [[_ object] objects] (doseq [[_ object] objects]
(do (let [selrect (:selrect object)
(.uniform4f gl (.getUniformLocation gl (.get programs "default") "u_color") 1.0 0.0 0.0 1.0) x (:x selrect)
(.uniform2f gl (.getUniformLocation gl (.get programs "default") "u_size") (:width object) (:height object)) y (:y selrect)
(.uniform2f gl (.getUniformLocation gl (.get programs "default") "u_position") (:x object) (:y object)) width (:width selrect)
height (:height selrect )
fill (first (:fills object))]
(js/console.log "fill" fill)
(.uniform4fv gl (.getUniformLocation gl (.get programs "default") "u_color") (parse-color (:fill-color fill) (:fill-opacity fill)))
(.uniform2f gl (.getUniformLocation gl (.get programs "default") "u_size") width height)
(.uniform2f gl (.getUniformLocation gl (.get programs "default") "u_position") x y)
(.drawArrays gl (.-TRIANGLE_STRIP gl) 0 4)))) (.drawArrays gl (.-TRIANGLE_STRIP gl) 0 4))))
(mf/defc canvas (mf/defc canvas
"A canvas element with a WebGL context." "A canvas element with a WebGL context."
{::mf/wrap-props false} {::mf/wrap-props false}
[props] [props]
(js/console.log props)
(js/console.log "default-shaders" default-vertex-shader default-fragment-shader)
(let [objects (unchecked-get props "objects") (let [objects (unchecked-get props "objects")
vbox (unchecked-get props "vbox") vbox (unchecked-get props "vbox")
canvas-ref (mf/use-ref nil) canvas-ref (mf/use-ref nil)
gl-ref (mf/use-ref nil)] gl-ref (mf/use-ref nil)]
(println "---------------> vbox" (:x vbox) (:width vbox) (:y vbox) (:height vbox)) (mf/with-effect [objects vbox]
(let [gl (mf/ref-val gl-ref)]
(when (some? gl)
(render-gl gl objects vbox))))
(mf/with-effect [canvas-ref] (mf/with-effect [canvas-ref]
(let [canvas (mf/ref-val canvas-ref)] (let [canvas (mf/ref-val canvas-ref)]
@ -77,8 +103,7 @@
(mf/set-ref-val! gl-ref gl) (mf/set-ref-val! gl-ref gl)
(resize-canvas canvas) (resize-canvas canvas)
(prepare-gl gl) (prepare-gl gl)
(render-gl gl objects vbox) (render-gl gl objects vbox)))))
(js/console.log "gl" gl)))))
[:canvas {:class (stl/css :canvas) [:canvas {:class (stl/css :canvas)
:ref canvas-ref}])) :ref canvas-ref}]))

View File

@ -2,19 +2,19 @@
precision highp float; precision highp float;
uniform vec2 u_screenSize; uniform vec4 u_vbox;
uniform vec2 u_position; uniform vec2 u_position;
uniform vec2 u_size; uniform vec2 u_size;
// out vec2 v_texCoord; // out vec2 v_texCoord;
vec2 get_base_position(int id) { vec2 get_vertex_position(int id) {
if(id == 0) { if(id == 0) {
return vec2(-1.0f, -1.0f); return vec2(0.0f, 0.0f);
} else if(id == 1) { } else if(id == 1) {
return vec2(1.0f, -1.0f); return vec2(1.0f, 0.0f);
} else if(id == 2) { } else if(id == 2) {
return vec2(-1.0f, 1.0f); return vec2(0.0f, 1.0f);
} else if(id == 3) { } else if(id == 3) {
return vec2(1.0f, 1.0f); return vec2(1.0f, 1.0f);
} else { } else {
@ -38,7 +38,14 @@ vec2 get_tex_position(int id) {
} }
*/ */
vec2 from(vec2 v, vec2 min, vec2 max) {
return (v - min) / (max - min);
}
void main() { void main() {
gl_Position = vec4((get_base_position(gl_VertexID) * u_size + u_position) / u_screenSize, 0.0f, 1.0f); vec2 vertex = get_vertex_position(gl_VertexID);
vec2 position = vertex * from(u_size, vec2(0), u_vbox.zw) + from(u_position, u_vbox.xy, u_vbox.xy + u_vbox.zw); // 0,1
gl_Position = vec4(mix(vec2(-1.0, 1.0), vec2(1.0, -1.0), position), 0.0f, 1.0f);
// gl_Position = vec4(((get_base_position(gl_VertexID) * u_size + u_position) / u_vbox.zw), 0.0f, 1.0f);
// v_texCoord = get_tex_position(gl_VertexID); // v_texCoord = get_tex_position(gl_VertexID);
} }