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
(:require-macros [app.main.style :as stl])
(:require-macros [app.util.gl.macros :refer [slurp]])
(:require
[app.common.math :as math]
[app.util.gl :as gl]
[cuerdas.core :as str]
[rumext.v2 :as mf]))
(:require-macros [app.main.style :as stl])
(:require-macros [app.util.gl.macros :refer [slurp]])
(:require
[app.common.math :as math]
[app.util.gl :as gl]
[cuerdas.core :as str]
[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-fragment-shader (slurp "src/app/util/gl/shaders/default.f.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 shaders (js/Map.))
(def programs (js/Map.))
#_(def textures (js/Map.))
#_(def framebuffers (js/Map.))
#_(def shaders (js/Map.))
(def programs (js/Map.))
#_(def textures (js/Map.))
#_(def framebuffers (js/Map.))
(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 parse-color-hex
[color opacity]
(let [r (str/slice color 1 3)
g (str/slice color 3 5)
b (str/slice color 5 7)]
#js [(/ (js/parseInt r 16) 255.0)
(/ (js/parseInt g 16) 255.0)
(/ (js/parseInt b 16) 255.0)
opacity]))
(defn resize-canvas
[canvas]
(let [width (math/floor (.-clientWidth canvas))
height (math/floor (.-clientHeight canvas))]
(resize-canvas-to canvas width height)))
(defn parse-color
[color opacity]
(cond
(str/starts-with? color "#")
(parse-color-hex color opacity)
(defn prepare-gl
[gl]
(let [default-program (gl/create-program-from-sources gl default-vertex-shader default-fragment-shader)]
(.set programs "default" default-program)))
:else
#js [0.0 0.0 0.0 1.0]))
(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
[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))
(.viewport gl 0 0 (.-width (.-canvas gl)) (.-height (.-canvas gl)))
(.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]
(do
(.uniform4f gl (.getUniformLocation gl (.get programs "default") "u_color") 1.0 0.0 0.0 1.0)
(.uniform2f gl (.getUniformLocation gl (.get programs "default") "u_size") (:width object) (:height object))
(.uniform2f gl (.getUniformLocation gl (.get programs "default") "u_position") (:x object) (:y object))
(let [selrect (:selrect object)
x (:x selrect)
y (:y selrect)
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))))
(mf/defc canvas
"A canvas element with a WebGL context."
{::mf/wrap-props false}
[props]
(js/console.log props)
(js/console.log "default-shaders" default-vertex-shader default-fragment-shader)
(let [objects (unchecked-get props "objects")
vbox (unchecked-get props "vbox")
canvas-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]
(let [canvas (mf/ref-val canvas-ref)]
@@ -77,8 +103,7 @@
(mf/set-ref-val! gl-ref gl)
(resize-canvas canvas)
(prepare-gl gl)
(render-gl gl objects vbox)
(js/console.log "gl" gl)))))
(render-gl gl objects vbox)))))
[:canvas {:class (stl/css :canvas)
:ref canvas-ref}]))

View File

@@ -2,19 +2,19 @@
precision highp float;
uniform vec2 u_screenSize;
uniform vec4 u_vbox;
uniform vec2 u_position;
uniform vec2 u_size;
// out vec2 v_texCoord;
vec2 get_base_position(int id) {
vec2 get_vertex_position(int id) {
if(id == 0) {
return vec2(-1.0f, -1.0f);
return vec2(0.0f, 0.0f);
} else if(id == 1) {
return vec2(1.0f, -1.0f);
return vec2(1.0f, 0.0f);
} else if(id == 2) {
return vec2(-1.0f, 1.0f);
return vec2(0.0f, 1.0f);
} else if(id == 3) {
return vec2(1.0f, 1.0f);
} 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() {
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);
}