From bcf01abdbed1cc9448487d7c5f04879c368e07da Mon Sep 17 00:00:00 2001 From: Aitor Date: Mon, 18 Dec 2023 10:08:42 +0100 Subject: [PATCH] wip --- .../src/app/main/ui/workspace/viewport.cljs | 6 ++ .../app/main/ui/workspace/viewport/gl.cljs | 26 +++++ .../app/main/ui/workspace/viewport/gl.scss | 13 +++ frontend/src/app/util/gl.cljs | 99 +++++++++++++++++++ 4 files changed, 144 insertions(+) create mode 100644 frontend/src/app/main/ui/workspace/viewport/gl.cljs create mode 100644 frontend/src/app/main/ui/workspace/viewport/gl.scss create mode 100644 frontend/src/app/util/gl.cljs diff --git a/frontend/src/app/main/ui/workspace/viewport.cljs b/frontend/src/app/main/ui/workspace/viewport.cljs index 5d679fe36b..6bc48fd144 100644 --- a/frontend/src/app/main/ui/workspace/viewport.cljs +++ b/frontend/src/app/main/ui/workspace/viewport.cljs @@ -28,6 +28,7 @@ [app.main.ui.workspace.viewport.debug :as wvd] [app.main.ui.workspace.viewport.drawarea :as drawarea] [app.main.ui.workspace.viewport.frame-grid :as frame-grid] + [app.main.ui.workspace.viewport.gl :as gl] [app.main.ui.workspace.viewport.gradients :as gradients] [app.main.ui.workspace.viewport.grid-layout-editor :as grid-layout] [app.main.ui.workspace.viewport.guides :as guides] @@ -131,6 +132,8 @@ [viewport-ref on-viewport-ref] (create-viewport-ref) + canvas-ref (mf/use-ref nil) + ;; VARS disable-paste (mf/use-var false) in-viewport? (mf/use-var false) @@ -346,6 +349,9 @@ :objects base-objects :active-frames @active-frames}]]]] + ;; IT's MAGIC! + [gl/canvas {:objects base-objects}] + [:svg.viewport-controls {:xmlns "http://www.w3.org/2000/svg" :xmlnsXlink "http://www.w3.org/1999/xlink" diff --git a/frontend/src/app/main/ui/workspace/viewport/gl.cljs b/frontend/src/app/main/ui/workspace/viewport/gl.cljs new file mode 100644 index 0000000000..6a00a64098 --- /dev/null +++ b/frontend/src/app/main/ui/workspace/viewport/gl.cljs @@ -0,0 +1,26 @@ +(ns app.main.ui.workspace.viewport.gl + (:require-macros [app.main.style :as stl]) + (:require + [rumext.v2 :as mf])) + +(def CANVAS_CONTEXT_ID "webgl2") + +(mf/defc canvas + "A canvas element with a WebGL context." + {::mf/wrap-props false} + [props] + (js/console.log props) + (let [canvas-ref (mf/use-ref nil) + gl-ref (mf/use-ref nil)] + (mf/with-effect [canvas-ref] + (let [canvas (mf/ref-val canvas-ref)] + (when (some? canvas) + (let [gl (.getContext canvas CANVAS_CONTEXT_ID)] + (.clearColor gl 1.0 0.0 1.0 0.5) + (.clear gl (.-COLOR_BUFFER_BIT gl)) + (mf/set-ref-val! gl-ref gl) + (js/console.log "gl" gl))))) + + [:canvas {:class (stl/css :canvas) + :ref canvas-ref}])) + diff --git a/frontend/src/app/main/ui/workspace/viewport/gl.scss b/frontend/src/app/main/ui/workspace/viewport/gl.scss new file mode 100644 index 0000000000..393e5c9fbd --- /dev/null +++ b/frontend/src/app/main/ui/workspace/viewport/gl.scss @@ -0,0 +1,13 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// +// Copyright (c) KALEIDOS INC + +@import "refactor/common-refactor.scss"; + +.canvas { + position: absolute; + width: 100%; + height: 100%; +} diff --git a/frontend/src/app/util/gl.cljs b/frontend/src/app/util/gl.cljs new file mode 100644 index 0000000000..193c2637c9 --- /dev/null +++ b/frontend/src/app/util/gl.cljs @@ -0,0 +1,99 @@ +(ns app.util.gl) + +;; +;; Shaders +;; +(defn create-shader + "Creates a shader of the given type with the given source" + [gl type source] + (let [shader (.createShader gl type)] + (.shaderSource gl shader source) + (.compileShader gl shader) + (when-not (.getShaderParameter gl shader (.COMPILE_STATUS gl)) + (throw (js/Error. (.getShaderInfoLog gl shader)))))) + +(defn create-vertex-shader + "Creates a vertex shader with the given source" + [gl source] + (create-shader gl (.VERTEX_SHADER gl) source)) + +(defn create-fragment-shader + "Creates a fragment shader with the given source" + [gl source] + (create-shader gl (.FRAGMENT_SHADER gl) source)) + +;; +;; Programs +;; +(defn create-program + "Creates a program with the given vertex and fragment shaders" + [gl vertex-shader fragment-shader] + (let [program (.createProgram gl)] + (.attachShader gl program vertex-shader) + (.attachShader gl program fragment-shader) + (.linkProgram gl program) + (when-not (.getProgramParameter gl program (.LINK_STATUS gl)) + (throw (js/Error. (.getProgramInfoLog gl program)))) + program)) + +(defn create-program-from-sources + "Creates a program with the given vertex and fragment shader sources" + [gl vertex-source fragment-source] + (let [vertex-shader (create-vertex-shader gl vertex-source) + fragment-shader (create-fragment-shader gl fragment-source)] + (create-program gl vertex-shader fragment-shader))) + +(defn get-program-active-factory + "Returns a map of active uniform and attribute names to their locations" + [parameter get-active-name get-location-name] + (fn [gl program] + (let [count (.getProgramParameter gl program parameter) + get-active (dm/get gl get-active-name) + get-location (dm/get gl get-location-name)] + (into {} (for [index (range count)] + (let [info (.get-active gl program index) + name (.-name info) + location (.get-location gl program name)] + [name #js {:name name :info info :location location}])))))) + +(def get-program-uniforms (get-program-active-factory (.ACTIVE_UNIFORMS js/WebGLRenderingContext) "getActiveUniform" "getUniformLocation")) +(def get-program-attributes (get-program-active-factory (.ACTIVE_ATTRIBUTES js/WebGLRenderingContext) "getActiveAttrib" "getAttribLocation")) + +(defn get-program-actives + "Returns a map of uniform names to uniform locations for the given program" + [gl program] + (let [uniforms (get-program-uniforms gl program) + attributes (get-program-attributes gl program)] + #js { :uniforms uniforms :attributes attributes })) + +;; +;; Buffers +;; +(defn create-buffer-from-data + [gl data target usage] + (let [buffer (.createBuffer gl)] + (.bindBuffer gl target buffer) + (.bufferData gl target data usage) + (.bindBuffer gl target nil) + buffer)) + +;; +;; Framebuffers +;; +(defn create-framebuffer + [gl] + (let [framebuffer (.createFramebuffer gl)] + (.bindFramebuffer gl framebuffer) + (.bindFramebuffer gl nil) + framebuffer)) + +;; +;; Renderbuffers +;; +(defn create-renderbuffer + [gl] + (let [renderbuffer (.createRenderbuffer gl)] + (.bindRenderbuffer gl renderbuffer) + (.bindRenderbuffer gl nil) + renderbuffer)) +