diff --git a/frontend/src/app/main/ui/workspace/viewport/gl.cljs b/frontend/src/app/main/ui/workspace/viewport/gl.cljs index 7cf2a7b6aa..a323ddf0c6 100644 --- a/frontend/src/app/main/ui/workspace/viewport/gl.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/gl.cljs @@ -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}])) diff --git a/frontend/src/app/util/gl/shaders/default.v.glsl b/frontend/src/app/util/gl/shaders/default.v.glsl index 9a876d13c4..c465999ef6 100644 --- a/frontend/src/app/util/gl/shaders/default.v.glsl +++ b/frontend/src/app/util/gl/shaders/default.v.glsl @@ -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); } \ No newline at end of file