├── .editorconfig ├── .gitignore ├── .jsbeautifyrc ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── FUNDING.yml ├── LICENSE ├── README.md ├── build └── config.gypi ├── docs ├── css │ ├── docs.css │ ├── docs.css.map │ ├── docs.min.css │ ├── docs.min.css.map │ ├── vendors.css │ ├── vendors.min.css │ └── vendors.min.css.map ├── img │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── browserconfig.xml │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── mstile-150x150.png │ ├── safari-pinned-tab.svg │ └── site.webmanifest ├── index.html ├── js │ ├── docs.js │ ├── docs.min.js │ ├── docs.min.js.map │ ├── vendors.js │ ├── vendors.min.js │ └── vendors.min.js.map └── playgrounds │ ├── animation.glsl │ ├── blend.glsl │ ├── boolean.glsl │ ├── buffers.glsl │ ├── camera.glsl │ ├── colors.glsl │ ├── coords.glsl │ ├── drawing.glsl │ ├── easing.glsl │ ├── fields.glsl │ ├── lib.glsl │ ├── main.glsl │ ├── shapes.glsl │ ├── tile.glsl │ ├── trails.glsl │ └── units.glsl ├── glsl.configuration.json ├── gulpfile-config.json ├── gulpfile.js ├── out ├── extension.js ├── extension.js.map ├── glsl │ ├── color.provider.js │ ├── color.provider.js.map │ ├── common.js │ ├── common.js.map │ ├── editor.js │ ├── editor.js.map │ ├── export.js │ ├── export.js.map │ ├── format.provider.js │ ├── format.provider.js.map │ ├── options.js │ ├── options.js.map │ ├── panel.js │ └── panel.js.map └── test │ ├── runTest.js │ ├── runTest.js.map │ └── suite │ ├── extension.test.js │ ├── extension.test.js.map │ ├── index.js │ └── index.js.map ├── package-lock.json ├── package.json ├── resources ├── css │ ├── app.css │ ├── app.css.map │ ├── app.min.css │ ├── app.min.css.map │ ├── vendors.css │ ├── vendors.min.css │ └── vendors.min.css.map ├── export │ ├── LICENSE │ ├── css │ │ └── glsl-canvas.css │ ├── img │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ └── favicon.ico │ └── package.json ├── fonts │ ├── fonts │ │ ├── glslcanvas.eot │ │ ├── glslcanvas.svg │ │ ├── glslcanvas.ttf │ │ └── glslcanvas.woff │ ├── icons-reference.html │ └── styles.css ├── img │ └── icon.png ├── js │ ├── app.js │ ├── app.min.js │ ├── app.min.js.map │ ├── vendors.js │ ├── vendors.min.js │ └── vendors.min.js.map └── model │ └── duck-toy.obj ├── snippets └── glsl.json ├── src ├── app │ ├── app.js │ ├── app.scss │ └── services │ │ ├── camera │ │ └── camera.service.js │ │ ├── capture │ │ ├── capture.service.js │ │ └── ccapture.service.js │ │ ├── gui │ │ ├── gui.scss │ │ └── gui.service.js │ │ ├── trails │ │ └── trails.service.js │ │ ├── vars.scss │ │ └── vector │ │ └── vector.js ├── docs │ ├── docs.js │ └── docs.scss ├── extension.ts ├── glsl │ ├── color.provider.ts │ ├── common.ts │ ├── editor.ts │ ├── export.ts │ ├── format.provider.ts │ ├── options.ts │ └── panel.ts ├── icon.png ├── icon.psd ├── previews │ ├── 01-main.gif │ ├── 01-mode.gif │ ├── 02-picker.gif │ ├── 03-camera.gif │ ├── 04-trails.gif │ ├── 05-uniforms.gif │ ├── 06-buffers.gif │ ├── 07-export.gif │ └── 08-format.gif ├── snippets │ ├── animation.glsl │ ├── colors.glsl │ ├── coords.glsl │ ├── drawing.glsl │ ├── ease │ │ ├── back │ │ │ ├── in.glsl │ │ │ ├── inOut.glsl │ │ │ └── out.glsl │ │ ├── bounce │ │ │ ├── in.glsl │ │ │ ├── inOut.glsl │ │ │ └── out.glsl │ │ ├── circular │ │ │ ├── in.glsl │ │ │ ├── inOut.glsl │ │ │ └── out.glsl │ │ ├── cubic │ │ │ ├── in.glsl │ │ │ ├── inOut.glsl │ │ │ └── out.glsl │ │ ├── elastic │ │ │ ├── in.glsl │ │ │ ├── inOut.glsl │ │ │ └── out.glsl │ │ ├── expo │ │ │ ├── in.glsl │ │ │ ├── inOut.glsl │ │ │ └── out.glsl │ │ ├── quad │ │ │ ├── in.glsl │ │ │ ├── inOut.glsl │ │ │ └── out.glsl │ │ ├── quart │ │ │ ├── in.glsl │ │ │ ├── inOut.glsl │ │ │ └── out.glsl │ │ ├── quint │ │ │ ├── in.glsl │ │ │ ├── inOut.glsl │ │ │ └── out.glsl │ │ └── sine │ │ │ ├── in.glsl │ │ │ ├── inOut.glsl │ │ │ └── out.glsl │ ├── main.glsl │ ├── math │ │ ├── 2d │ │ │ └── transform.glsl │ │ └── 3d │ │ │ └── transform.glsl │ ├── modifiers │ │ ├── blend.glsl │ │ ├── boolean.glsl │ │ └── tile.glsl │ ├── object.glsl │ ├── shapes │ │ └── 2d │ │ │ ├── arc.glsl │ │ │ ├── circle.glsl │ │ │ ├── grid.glsl │ │ │ ├── hex.glsl │ │ │ ├── line.glsl │ │ │ ├── pie.glsl │ │ │ ├── plot.glsl │ │ │ ├── poly.glsl │ │ │ ├── rect.glsl │ │ │ ├── roundrect.glsl │ │ │ ├── segment.glsl │ │ │ ├── spiral.glsl │ │ │ └── star.glsl │ ├── snippets.md │ └── units.glsl └── test │ ├── runTest.ts │ └── suite │ ├── extension.test.ts │ └── index.ts ├── tsconfig.json ├── tslint.json └── vsc-extension-quickstart.md /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = tab 7 | indent_size = 4 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.json] 12 | indent_style = space 13 | indent_size = 2 14 | 15 | [*.md] 16 | max_line_length = off 17 | trim_trailing_whitespace = false 18 | 19 | # The indent size used in the `package.json` file cannot be changed 20 | # https://github.com/npm/npm/pull/3180#issuecomment-16336516 21 | [{*.yml,*.yaml,package.json,package-lock.json}] 22 | indent_style = space 23 | indent_size = 2 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.psd 2 | 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # Bower dependency directory (https://bower.io/) 29 | bower_components 30 | 31 | # node-waf configuration 32 | .lock-wscript 33 | 34 | # Compiled binary addons (http://nodejs.org/api/addons.html) 35 | build/Release 36 | 37 | # Dependency directories 38 | node_modules/ 39 | jspm_packages/ 40 | 41 | # Typescript v1 declaration files 42 | typings/ 43 | 44 | # Optional npm cache directory 45 | .npm 46 | 47 | # Optional eslint cache 48 | .eslintcache 49 | 50 | # Optional REPL history 51 | .node_repl_history 52 | 53 | # Output of 'npm pack' 54 | *.tgz 55 | 56 | # Yarn Integrity file 57 | .yarn-integrity 58 | 59 | # dotenv environment variables file 60 | .env 61 | 62 | _README.md 63 | # *.vsix 64 | *.psd 65 | snippets/glsl-example.json 66 | gulp3/ 67 | 68 | .DS_Store 69 | src/preview.jpg 70 | -------------------------------------------------------------------------------- /.jsbeautifyrc: -------------------------------------------------------------------------------- 1 | { 2 | "indent_with_tabs": true, 3 | "max_preserve_newlines": 2, 4 | "preserve_newlines": true, 5 | "keep_array_indentation": true, 6 | "break_chained_methods": false, 7 | "wrap_line_length": 0, 8 | "end_with_newline": true, 9 | "brace_style": "collapse,preserve-inline", 10 | "unformatted": [] 11 | } 12 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | { 3 | "version": "0.2.0", 4 | "configurations": [ 5 | { 6 | "name": "Run Extension", 7 | "type": "extensionHost", 8 | "request": "launch", 9 | "runtimeExecutable": "${execPath}", 10 | "args": [ 11 | "--extensionDevelopmentPath=${workspaceRoot}" 12 | ], 13 | "stopOnEntry": false, 14 | "sourceMaps": true, 15 | "outFiles": [ 16 | "${workspaceFolder}/out/**/*.js" 17 | ], 18 | "preLaunchTask": "npm: watch" 19 | }, 20 | { 21 | "name": "Run Extension Tests", 22 | "type": "extensionHost", 23 | "request": "launch", 24 | "runtimeExecutable": "${execPath}", 25 | "args": [ 26 | "--extensionDevelopmentPath=${workspaceFolder}", 27 | "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" 28 | ], 29 | "outFiles": [ 30 | "${workspaceFolder}/out/test/**/*.js" 31 | ], 32 | "preLaunchTask": "npm: watch" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false // set this to true to hide the "out" folder with the compiled JS files 5 | }, 6 | "search.exclude": { 7 | "out": true // set this to false to include "out" folder in search results 8 | } 9 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "watch", 9 | "problemMatcher": "$tsc-watch", 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "never" 13 | }, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | #node_modules/** 2 | .vscode/** 3 | .vscode-test/** 4 | bower_components/** 5 | docs/** 6 | out/test/** 7 | out/**/*.map 8 | src/** 9 | .gitignore 10 | .jsbeautifyrc 11 | bower.json 12 | bundleconfig.json 13 | compilerconfig.json 14 | tsconfig.json 15 | tslint.json 16 | gulpfile.js 17 | gulpfile.config.json 18 | **/*.ts 19 | **/tsconfig.json 20 | !file.ts 21 | vsc-extension-quickstart.md 22 | *.vsix 23 | *.psd 24 | *.zip 25 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to the "vscode-glsl-canvas" extension will be documented in this file. 3 | 4 | --- 5 | 6 | ## [0.2.15] - 2022-02-05 7 | ### Added 8 | - Video recording options, recordDuration, recordWidth, recordHeight, recordMethod MediaRecorder or CCapture. 9 | ### Fixed 10 | - WebGL2 VERTEX shader definition updating GlslCanvas. 11 | 12 | --- 13 | 14 | ## [0.2.14] - 2021-09-19 15 | ### Fixed 16 | - dat.gui style. 17 | 18 | --- 19 | 20 | ## [0.2.13] - 2021-05-22 21 | ### Fixed 22 | - u_camera uniform & buffers. 23 | 24 | --- 25 | 26 | ## [0.2.12] - 2021-04-04 27 | ### Added 28 | - Nested includes with relative paths. 29 | ### Fixed 30 | - Formatter. Loading resources. 31 | 32 | --- 33 | 34 | ## [0.2.11] - 2020-04-27 35 | ### Added 36 | - Mesh support with modes: flat, box, sphere, torus, mesh. 37 | - File .obj loader/parser. 38 | - VERTEX macro. 39 | 40 | --- 41 | 42 | ## [0.2.10] - 2020-03-29 43 | ### Added 44 | - WebGL extensions option support. 45 | - Inizialization protocol error. 46 | 47 | --- 48 | 49 | ## [0.2.8] - 2020-01-01 50 | ### Added 51 | - Texture querystring options. 52 | 53 | --- 54 | 55 | ## [0.2.7] - 2019-10-13 56 | ### Added 57 | - WebGL2 support. 58 | - Including dependent files with #include macro. 59 | ### Fixed 60 | - Non-compact formatter extra spaces. 61 | 62 | --- 63 | 64 | ## [0.2.6] - 2019-02-16 65 | ### Fixed 66 | - u_mouse on retina display. 67 | 68 | --- 69 | 70 | ## [0.2.4] - 2019-02-09 71 | ### Added 72 | - WebGL code exporter functionality. 73 | - Glsl code formatting functionality. 74 | 75 | --- 76 | 77 | ## [0.2.2] - 2019-01-28 78 | ### Fixed 79 | - Inizialization error. 80 | 81 | --- 82 | 83 | ## [0.2.0] - 2019-01-27 84 | ### Added 85 | - Editor color picker. 86 | - `glsl-canvas` refactor. 87 | ### Fixed 88 | - Custom uniforms values. 89 | - Layout reordering issue. 90 | 91 | --- 92 | 93 | ## [0.1.92] - 2018-12-02 94 | ### Added 95 | - Support for local textures. 96 | - Missing WebGL error message. 97 | 98 | --- 99 | 100 | ## [0.1.91] - 2018-06-29 101 | ### Added 102 | - More control/options over refreshing the glslCanvas. 103 | ### Fixed 104 | - Rendering loop updating GlslCanvas. 105 | 106 | --- 107 | 108 | ## [0.1.9] - 2018-06-16 109 | ### Added 110 | - Multiple buffers functionality and playground. 111 | - Mouse orbit control and playground. 112 | - Change detection timeout configuration option. 113 | 114 | --- 115 | 116 | ## [0.1.7] - 2018-03-15 117 | ### Fixed 118 | - sArc and easeInOut snippets methods. 119 | 120 | --- 121 | 122 | ## [0.1.6] - 2018-03-13 123 | ### Added 124 | - Documented snippets library with playgrounds. 125 | - Mouse trail uniforms. 126 | - Texture repeating feature. 127 | 128 | --- 129 | 130 | ## [0.1.5] - 2018-02-17 131 | ### Added 132 | - Gui for changing custom uniforms at runtime. 133 | - Fixed dependancy from other extension. 134 | 135 | --- 136 | 137 | ## [0.1.3] - 2018-02-11 138 | ### Added 139 | - Play / pause functionality. 140 | - Record button that exports to ```.webm``` video. 141 | - Activable performance monitor. 142 | - Better handling of active ```.glsl``` editor. 143 | - Improved inline error message. 144 | - Minor snippets functionality. 145 | - Fixed resizing issue. 146 | 147 | --- 148 | 149 | ## [0.1.1] - 2018-02-03 150 | ### Added 151 | - Initial release of glsl-canvas for vscode. 152 | 153 | --- 154 | 155 | Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. 156 | -------------------------------------------------------------------------------- /FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [vscode-glsl-canvas] 2 | patreon: lzampetti 3 | custom: ["https://www.paypal.me/circledev/5"] 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Luca Zampetti 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /build/config.gypi: -------------------------------------------------------------------------------- 1 | # Do not edit. File was generated by node-gyp's "configure" step 2 | { 3 | "target_defaults": { 4 | "cflags": [], 5 | "default_configuration": "Release", 6 | "defines": [], 7 | "include_dirs": [], 8 | "libraries": [] 9 | }, 10 | "variables": { 11 | "asan": 0, 12 | "build_v8_with_gn": "false", 13 | "coverage": "false", 14 | "debug_nghttp2": "false", 15 | "enable_lto": "false", 16 | "force_dynamic_crt": 0, 17 | "host_arch": "x64", 18 | "icu_data_in": "../../deps/icu-small/source/data/in/icudt62l.dat", 19 | "icu_endianness": "l", 20 | "icu_gyp_path": "tools/icu/icu-generic.gyp", 21 | "icu_locales": "en,root", 22 | "icu_path": "deps/icu-small", 23 | "icu_small": "true", 24 | "icu_ver_major": "62", 25 | "llvm_version": "0", 26 | "node_byteorder": "little", 27 | "node_debug_lib": "false", 28 | "node_enable_d8": "false", 29 | "node_enable_v8_vtunejit": "false", 30 | "node_install_npm": "true", 31 | "node_module_version": 64, 32 | "node_no_browser_globals": "false", 33 | "node_prefix": "/usr/local", 34 | "node_release_urlbase": "https://nodejs.org/download/release/", 35 | "node_shared": "false", 36 | "node_shared_cares": "false", 37 | "node_shared_http_parser": "false", 38 | "node_shared_libuv": "false", 39 | "node_shared_nghttp2": "false", 40 | "node_shared_openssl": "false", 41 | "node_shared_zlib": "false", 42 | "node_tag": "", 43 | "node_target_type": "executable", 44 | "node_use_bundled_v8": "true", 45 | "node_use_dtrace": "true", 46 | "node_use_etw": "false", 47 | "node_use_openssl": "true", 48 | "node_use_pch": "false", 49 | "node_use_perfctr": "false", 50 | "node_use_v8_platform": "true", 51 | "node_with_ltcg": "false", 52 | "node_without_node_options": "false", 53 | "openssl_fips": "", 54 | "openssl_no_asm": 0, 55 | "shlib_suffix": "64.dylib", 56 | "target_arch": "x64", 57 | "v8_enable_gdbjit": 0, 58 | "v8_enable_i18n_support": 1, 59 | "v8_enable_inspector": 1, 60 | "v8_no_strict_aliasing": 1, 61 | "v8_optimized_debug": 0, 62 | "v8_promise_internal_field_count": 1, 63 | "v8_random_seed": 0, 64 | "v8_trace_maps": 0, 65 | "v8_typed_array_max_size_in_heap": 0, 66 | "v8_use_snapshot": "true", 67 | "want_separate_host_toolset": 0, 68 | "xcode_version": "7.0", 69 | "nodedir": "/Users/lucazampetti/.node-gyp/10.11.0", 70 | "standalone_static_library": 1 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /docs/css/docs.css: -------------------------------------------------------------------------------- 1 | body { 2 | height: 100%; 3 | margin: 0; 4 | background: #171717; } 5 | 6 | .editor { 7 | display: block; 8 | height: 100%; } 9 | 10 | .CodeMirror { 11 | font-size: 13px !important; 12 | font-family: Cousine, Monaco, 'Courier New', monospace !important; 13 | min-height: 100vh; } 14 | .CodeMirror.cm-s-monokai { 15 | background: #171717; 16 | color: #d4d4d4; } 17 | .CodeMirror.cm-s-monokai .CodeMirror-gutters { 18 | background: #171717; } 19 | .CodeMirror.cm-s-monokai span.cm-atom, .CodeMirror.cm-s-monokai span.cm-number { 20 | color: #b5cea8; } 21 | .CodeMirror.cm-s-monokai span.cm-keyword { 22 | color: #9f7ec0; } 23 | .CodeMirror.cm-s-monokai span.cm-comment { 24 | color: #44864e; } 25 | .CodeMirror.cm-s-monokai span.cm-variable-3 { 26 | color: #569cd6; } 27 | .CodeMirror.cm-s-monokai span.cm-variable { 28 | color: #dcd98a; } 29 | 30 | .CodeMirror-scroll { 31 | overflow: auto !important; } 32 | 33 | .CodeMirror-linenumber.CodeMirror-gutter-elt { 34 | color: #5a5a5a; } 35 | 36 | .btn { 37 | display: none; 38 | position: fixed; 39 | bottom: 20px; 40 | right: 20px; 41 | z-index: 100; 42 | padding: 8px; 43 | border-radius: 5px; 44 | text-decoration: none; 45 | font-family: Arial, Helvetica, sans-serif; 46 | font-size: 14px; 47 | background: #272727; 48 | color: white; } 49 | 50 | @media screen and (min-width: 960px) { 51 | body { 52 | padding: 20px; } 53 | .CodeMirror { 54 | min-height: calc(100vh - 40px); } 55 | .btn { 56 | display: block; } } 57 | -------------------------------------------------------------------------------- /docs/css/docs.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["src/docs/docs.scss"],"names":[],"mappings":"AAAA;EACC,YAAY;EACZ,SAAS;EACT,mBAAmB,EAAA;;AAGpB;EACC,cAAc;EACd,YAAY,EAAA;;AAGb;EACC,0BAA0B;EAC1B,iEAAiE;EACjE,iBAAiB,EAAA;EAHlB;IAKE,mBAAmB;IACnB,cAAc,EAAA;IANhB;MAQG,mBAAmB,EAAA;IARtB;MAaI,cAAc,EAAA;IAblB;MAgBI,cAAc,EAAA;IAhBlB;MAmBI,cAAc,EAAA;IAnBlB;MAsBI,cAAc,EAAA;IAtBlB;MAyBI,cAAc,EAAA;;AAMlB;EACC,yBAAyB,EAAA;;AAG1B;EACC,cAAc,EAAA;;AAGf;EACC,aAAa;EACV,eAAe;EACf,YAAY;EACZ,WAAW;EACX,YAAY;EACZ,YAAY;EACZ,kBAAkB;EAClB,qBAAqB;EACrB,yCAAyC;EAC5C,eAAe;EACf,mBAAmB;EAChB,YAAY,EAAA;;AAGhB;EACC;IACC,aAAa,EAAA;EAGd;IACC,8BAA8B,EAAA;EAG/B;IACC,cAAc,EAAA,EACd","file":"docs/css/docs.css","sourcesContent":["body {\n\theight: 100%;\n\tmargin: 0;\n\tbackground: #171717;\n}\n\n.editor {\n\tdisplay: block;\n\theight: 100%;\n}\n\n.CodeMirror {\n\tfont-size: 13px !important;\n\tfont-family: Cousine, Monaco, 'Courier New', monospace !important;\n\tmin-height: 100vh;\n\t&.cm-s-monokai {\n\t\tbackground: #171717;\n\t\tcolor: #d4d4d4;\n\t\t.CodeMirror-gutters {\n\t\t\tbackground: #171717;\n\t\t}\n\t\tspan {\n\t\t\t&.cm-atom,\n\t\t\t&.cm-number {\n\t\t\t\tcolor: #b5cea8;\n\t\t\t}\n\t\t\t&.cm-keyword {\n\t\t\t\tcolor: #9f7ec0;\n\t\t\t}\n\t\t\t&.cm-comment {\n\t\t\t\tcolor: #44864e;\n\t\t\t}\n\t\t\t&.cm-variable-3 {\n\t\t\t\tcolor: #569cd6;\n\t\t\t}\n\t\t\t&.cm-variable {\n\t\t\t\tcolor: #dcd98a;\n\t\t\t}\n\t\t}\n\t}\n}\n\n.CodeMirror-scroll {\n\toverflow: auto !important;\n}\n\n.CodeMirror-linenumber.CodeMirror-gutter-elt {\n\tcolor: #5a5a5a;\n}\n\n.btn {\n\tdisplay: none;\n position: fixed;\n bottom: 20px;\n right: 20px;\n z-index: 100;\n padding: 8px;\n border-radius: 5px;\n text-decoration: none;\n font-family: Arial, Helvetica, sans-serif;\n\tfont-size: 14px;\n\tbackground: #272727;\n color: white;\n}\n\n@media screen and (min-width: 960px) {\n\tbody {\n\t\tpadding: 20px;\n\t}\n\n\t.CodeMirror {\n\t\tmin-height: calc(100vh - 40px);\n\t}\n\n\t.btn {\n\t\tdisplay: block;\n\t}\n}\n"]} -------------------------------------------------------------------------------- /docs/css/docs.min.css: -------------------------------------------------------------------------------- 1 | body{height:100%;margin:0;background:#171717}.editor{display:block;height:100%}.CodeMirror{font-size:13px!important;font-family:Cousine,Monaco,Courier New,monospace!important;min-height:100vh}.CodeMirror.cm-s-monokai{background:#171717;color:#d4d4d4}.CodeMirror.cm-s-monokai .CodeMirror-gutters{background:#171717}.CodeMirror.cm-s-monokai span.cm-atom,.CodeMirror.cm-s-monokai span.cm-number{color:#b5cea8}.CodeMirror.cm-s-monokai span.cm-keyword{color:#9f7ec0}.CodeMirror.cm-s-monokai span.cm-comment{color:#44864e}.CodeMirror.cm-s-monokai span.cm-variable-3{color:#569cd6}.CodeMirror.cm-s-monokai span.cm-variable{color:#dcd98a}.CodeMirror-scroll{overflow:auto!important}.CodeMirror-linenumber.CodeMirror-gutter-elt{color:#5a5a5a}.btn{display:none;position:fixed;bottom:20px;right:20px;z-index:100;padding:8px;border-radius:5px;text-decoration:none;font-family:Arial,Helvetica,sans-serif;font-size:14px;background:#272727;color:#fff}@media screen and (min-width:960px){body{padding:20px}.CodeMirror{min-height:calc(100vh - 40px)}.btn{display:block}} 2 | /*# sourceMappingURL=docs.min.css.map */ -------------------------------------------------------------------------------- /docs/css/docs.min.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["src/docs/docs.scss"],"names":[],"mappings":"AAAA,KACC,WAAY,CACZ,QAAS,CACT,kBAAmB,CAGpB,QACC,aAAc,CACd,WAAY,CAGb,YACC,wBAA0B,CAC1B,0DAAiE,CACjE,gBAAiB,CAHlB,yBAKE,kBAAmB,CACnB,aAAc,CANhB,6CAQG,kBAAmB,CARtB,8EAaI,aAAc,CAblB,yCAgBI,aAAc,CAhBlB,yCAmBI,aAAc,CAnBlB,4CAsBI,aAAc,CAtBlB,0CAyBI,aAAc,CAMlB,mBACC,uBAAyB,CAG1B,6CACC,aAAc,CAGf,KACC,YAAa,CACV,cAAe,CACf,WAAY,CACZ,UAAW,CACX,WAAY,CACZ,WAAY,CACZ,iBAAkB,CAClB,oBAAqB,CACrB,sCAAyC,CAC5C,cAAe,CACf,kBAAmB,CAChB,UAAY,CAGhB,oCACC,KACC,YAAa,CAGd,YACC,6BAA8B,CAG/B,KACC,aAAc,CACd","file":"docs/css/docs.min.css","sourcesContent":["body {\n\theight: 100%;\n\tmargin: 0;\n\tbackground: #171717;\n}\n\n.editor {\n\tdisplay: block;\n\theight: 100%;\n}\n\n.CodeMirror {\n\tfont-size: 13px !important;\n\tfont-family: Cousine, Monaco, 'Courier New', monospace !important;\n\tmin-height: 100vh;\n\t&.cm-s-monokai {\n\t\tbackground: #171717;\n\t\tcolor: #d4d4d4;\n\t\t.CodeMirror-gutters {\n\t\t\tbackground: #171717;\n\t\t}\n\t\tspan {\n\t\t\t&.cm-atom,\n\t\t\t&.cm-number {\n\t\t\t\tcolor: #b5cea8;\n\t\t\t}\n\t\t\t&.cm-keyword {\n\t\t\t\tcolor: #9f7ec0;\n\t\t\t}\n\t\t\t&.cm-comment {\n\t\t\t\tcolor: #44864e;\n\t\t\t}\n\t\t\t&.cm-variable-3 {\n\t\t\t\tcolor: #569cd6;\n\t\t\t}\n\t\t\t&.cm-variable {\n\t\t\t\tcolor: #dcd98a;\n\t\t\t}\n\t\t}\n\t}\n}\n\n.CodeMirror-scroll {\n\toverflow: auto !important;\n}\n\n.CodeMirror-linenumber.CodeMirror-gutter-elt {\n\tcolor: #5a5a5a;\n}\n\n.btn {\n\tdisplay: none;\n position: fixed;\n bottom: 20px;\n right: 20px;\n z-index: 100;\n padding: 8px;\n border-radius: 5px;\n text-decoration: none;\n font-family: Arial, Helvetica, sans-serif;\n\tfont-size: 14px;\n\tbackground: #272727;\n color: white;\n}\n\n@media screen and (min-width: 960px) {\n\tbody {\n\t\tpadding: 20px;\n\t}\n\n\t.CodeMirror {\n\t\tmin-height: calc(100vh - 40px);\n\t}\n\n\t.btn {\n\t\tdisplay: block;\n\t}\n}\n"]} -------------------------------------------------------------------------------- /docs/img/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/docs/img/android-chrome-192x192.png -------------------------------------------------------------------------------- /docs/img/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/docs/img/android-chrome-512x512.png -------------------------------------------------------------------------------- /docs/img/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/docs/img/apple-touch-icon.png -------------------------------------------------------------------------------- /docs/img/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #603cba 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /docs/img/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/docs/img/favicon-16x16.png -------------------------------------------------------------------------------- /docs/img/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/docs/img/favicon-32x32.png -------------------------------------------------------------------------------- /docs/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/docs/img/favicon.ico -------------------------------------------------------------------------------- /docs/img/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/docs/img/mstile-150x150.png -------------------------------------------------------------------------------- /docs/img/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.11, written by Peter Selinger 2001-2013 9 | 10 | 12 | 60 | 62 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /docs/img/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "short_name": "", 4 | "icons": [ 5 | { 6 | "src": "/img/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "/img/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "theme_color": "#ffffff", 17 | "background_color": "#ffffff", 18 | "display": "standalone" 19 | } 20 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | vscode-glsl-canvas playground 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | vscode-glsl-canvas 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /docs/js/docs.min.js: -------------------------------------------------------------------------------- 1 | !function(){"use strict";var t=function(){function t(t,n,e){this.x=t||0,this.y=n||0,this.z=e||0}return t.prototype={negative:function(){return new t(-this.x,-this.y,-this.z)},add:function(n){return n instanceof t?new t(this.x+n.x,this.y+n.y,this.z+n.z):new t(this.x+n,this.y+n,this.z+n)},subtract:function(n){return n instanceof t?new t(this.x-n.x,this.y-n.y,this.z-n.z):new t(this.x-n,this.y-n,this.z-n)},multiply:function(n){return n instanceof t?new t(this.x*n.x,this.y*n.y,this.z*n.z):new t(this.x*n,this.y*n,this.z*n)},divide:function(n){return n instanceof t?new t(this.x/n.x,this.y/n.y,this.z/n.z):new t(this.x/n,this.y/n,this.z/n)},equals:function(t){return this.x===t.x&&this.y===t.y&&this.z===t.z},dot:function(t){return this.x*t.x+this.y*t.y+this.z*t.z},cross:function(n){return new t(this.y*n.z-this.z*n.y,this.z*n.x-this.x*n.z,this.x*n.y-this.y*n.x)},length:function(){return Math.sqrt(this.dot(this))},unit:function(){return this.divide(this.length())},min:function(){return Math.min(Math.min(this.x,this.y),this.z)},max:function(){return Math.max(Math.max(this.x,this.y),this.z)},toAngles:function(){return{theta:Math.atan2(this.z,this.x),phi:Math.asin(this.y/this.length())}},angleTo:function(t){return Math.acos(this.dot(t)/(this.length()*t.length()))},toArray:function(t){return[this.x,this.y,this.z].slice(0,t||3)},clone:function(){return new t(this.x,this.y,this.z)},init:function(t,n,e){return this.x=t,this.y=n,this.z=e,this}},t.negative=function(t,n){return n.x=-t.x,n.y=-t.y,n.z=-t.z,n},t.add=function(n,e,i){return e instanceof t?(i.x=n.x+e.x,i.y=n.y+e.y,i.z=n.z+e.z):(i.x=n.x+e,i.y=n.y+e,i.z=n.z+e),i},t.subtract=function(n,e,i){return e instanceof t?(i.x=n.x-e.x,i.y=n.y-e.y,i.z=n.z-e.z):(i.x=n.x-e,i.y=n.y-e,i.z=n.z-e),i},t.multiply=function(n,e,i){return e instanceof t?(i.x=n.x*e.x,i.y=n.y*e.y,i.z=n.z*e.z):(i.x=n.x*e,i.y=n.y*e,i.z=n.z*e),i},t.divide=function(n,e,i){return e instanceof t?(i.x=n.x/e.x,i.y=n.y/e.y,i.z=n.z/e.z):(i.x=n.x/e,i.y=n.y/e,i.z=n.z/e),i},t.cross=function(t,n,e){return e.x=t.y*n.z-t.z*n.y,e.y=t.z*n.x-t.x*n.z,e.z=t.x*n.y-t.y*n.x,e},t.unit=function(t,n){var e=t.length();return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n},t.fromAngles=function(n,e){return new t(Math.cos(n)*Math.cos(e),Math.sin(e),Math.sin(n)*Math.cos(e))},t.randomDirection=function(){return t.fromAngles(Math.random()*Math.PI*2,Math.asin(2*Math.random()-1))},t.min=function(n,e){return new t(Math.min(n.x,e.x),Math.min(n.y,e.y),Math.min(n.z,e.z))},t.max=function(n,e){return new t(Math.max(n.x,e.x),Math.max(n.y,e.y),Math.max(n.z,e.z))},t.lerp=function(t,n,e){return n.subtract(t).multiply(e).add(t)},t.fromArray=function(n){return new t(n[0],n[1],n[2])},t.angleBetween=function(t,n){return t.angleTo(n)},t}();window.Vector=t}(),function(){"use strict";var t=function(){var t=Math.PI/180;function n(n,e,i){var r=this;r.theta=(n||45)*t,r.phi=(e||45)*t,r.radius=i||1}return n.prototype={down:function(t,n){this.mouse={x:t,y:n}},move:function(n,e){var i=this,r=i.mouse;if(r){var a=180*(n-r.x)*t,o=180*(r.y-e)*t;r.x=n,r.y=e,i.theta+=a,i.phi+=o}},up:function(t,n){this.mouse=null},wheel:function(t){this.radius=Math.max(.01,this.radius+.02*t)},render:function(t){var e=n.toVector(this),i=new Float32Array([e.x,e.y,e.z]);this.update(t,"3fv","vec3","u_camera",i)},update:function(t,n,e,i,r){try{var a=t.uniforms[i]=t.uniforms[i]||{};a.name=i,a.value=r,a.type=e,a.method="uniform"+n,a.location=t.gl.getUniformLocation(t.program,i),t.gl[a.method].apply(t.gl,[a.location].concat(a.value))}catch(t){console.log("CameraService.update.error",t)}}},n.fromVector=function(t){var e=t.length(),i=Math.acos(t.y/e),r=Math.atan(t.x/t.z);return new n(i,r,e)},n.toVector=function(t){var n=Math.sin(t.phi)*t.radius,e=n*Math.sin(t.theta),i=Math.cos(t.phi)*t.radius,r=n*Math.cos(t.theta);return new Vector(e,i,r)},n}();window.CameraService=t}(),function(){"use strict";var t=function(){function t(){var t=this;t.mouse=new Float32Array([0,0]),t.history=[],t.trails=new Array(10).fill(null).map((function(){return new Float32Array([0,0])}))}t.prototype={render:function(t){var n=this,e=n.trails,i=n.history,r=n.mouse,a=0,o=e.length,s=i.length?i[0]:r;for(;a0?e[a-1]:s,h=e[a],c=1/(5+a);h[0]+=(u[0]-h[0])*c,h[1]+=(u[1]-h[1])*c,n.update(t,"2fv","vec2","u_trails["+a+"]",h),a++}i.length&&i.shift()},move:function(t,n){var e=this.mouse;e[0]=t,e[1]=n,this.push()},push:function(t,e,i){var r,a,o,s=null,u=0;i||(i={});var h=function(){u=!1===i.leading?0:n(),s=null,o=t.apply(r,a),s||(r=a=null)};return function(){var c=n();u||!1!==i.leading||(u=c);var f=e-(c-u);return r=this,a=arguments,f<=0||f>e?(s&&(clearTimeout(s),s=null),u=c,o=t.apply(r,a),s||(r=a=null)):s||!1===i.trailing||(s=setTimeout(h,f)),o}}((function(){this.history.push(new Float32Array(this.mouse))}),1e3/60),update:function(t,n,e,i,r){try{var a=t.uniforms[i]=t.uniforms[i]||{};a.name=i,a.value=r,a.type=e,a.method="uniform"+n,a.location=t.gl.getUniformLocation(t.program,i),t.gl[a.method].apply(t.gl,[a.location].concat(a.value))}catch(t){console.log("TrailsService.update.error",t)}}};var n=Date.now||function(){return(new Date).getTime()};return t}();window.TrailsService=t}(),function(){"use strict";var t,n=new CameraService,e=new TrailsService;function i(t,n){var e=new XMLHttpRequest;e.open("GET",t,!0),e.addEventListener("load",(function(){n(e.responseText)})),e.send()}t="",i("playgrounds/lib.glsl",(function(r){t=r,i("playgrounds/"+(function(t){if(""==t)return{};for(var n={},e=0;e parseFloat(c)); 17 | const isColor = (components.length === 1 || components.length === l) && components.reduce((f, c) => { 18 | return f && c >= 0.0 && c <= 1.0; 19 | }, true); 20 | if (isColor) { 21 | if (components.length === 1) { 22 | while (components.length < l) { 23 | components.push(components[0]); 24 | } 25 | } 26 | if (components.length === 3) { 27 | components.push(1.0); 28 | } 29 | if (components.length === 4) { 30 | const color = new vscode.ColorInformation(new vscode.Range(document.positionAt(match.index), document.positionAt(match.index + match[0].length)), new vscode.Color(components[0], components[1], components[2], components[3])); 31 | colors.push(color); 32 | } 33 | } 34 | } 35 | return Promise.resolve(colors); 36 | } 37 | provideColorPresentations(color, context, token) { 38 | if (context.document.getText(context.range).indexOf('vec3') === 0) { 39 | return Promise.resolve([new vscode.ColorPresentation(`vec3(${GlslColorProvider.trim(color.red)}, ${GlslColorProvider.trim(color.green)}, ${GlslColorProvider.trim(color.blue)})`)]); 40 | } 41 | else { 42 | return Promise.resolve([new vscode.ColorPresentation(`vec4(${GlslColorProvider.trim(color.red)}, ${GlslColorProvider.trim(color.green)}, ${GlslColorProvider.trim(color.blue)}, ${GlslColorProvider.trim(color.alpha)})`)]); 43 | } 44 | } 45 | } 46 | exports.default = GlslColorProvider; 47 | //# sourceMappingURL=color.provider.js.map -------------------------------------------------------------------------------- /out/glsl/color.provider.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"color.provider.js","sourceRoot":"","sources":["../../src/glsl/color.provider.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /out/glsl/common.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const vscode = require("vscode"); 4 | const LANGUAGES = ['glsl', 'cpp', 'c']; 5 | function isGlslLanguage(languageId) { 6 | return LANGUAGES.indexOf(languageId) !== -1; 7 | } 8 | exports.isGlslLanguage = isGlslLanguage; 9 | let lastGlslEditor = null; 10 | function currentGlslEditor() { 11 | const editor = vscode.window.activeTextEditor; 12 | // console.log('Common.currentGlslEditor', editor ? editor.document : null); 13 | if (editor && isGlslLanguage(editor.document.languageId)) { 14 | lastGlslEditor = editor; 15 | } 16 | // Just return the last valid editor we've seen 17 | return lastGlslEditor; 18 | } 19 | exports.currentGlslEditor = currentGlslEditor; 20 | function currentGlslDocument() { 21 | const editor = currentGlslEditor(); 22 | return editor ? editor.document : null; 23 | } 24 | exports.currentGlslDocument = currentGlslDocument; 25 | //# sourceMappingURL=common.js.map -------------------------------------------------------------------------------- /out/glsl/common.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/glsl/common.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,iCAAiC;AAEjC,MAAM,SAAS,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;AAEvC,SAAgB,cAAc,CAAC,UAAkB;IAC7C,OAAO,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;AAChD,CAAC;AAFD,wCAEC;AAED,IAAI,cAAc,GAA6B,IAAI,CAAC;AAEpD,SAAgB,iBAAiB;IAC7B,MAAM,MAAM,GAAsB,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC;IACpE,4EAA4E;IACzE,IAAI,MAAM,IAAI,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE;QAC5D,cAAc,GAAG,MAAM,CAAC;KACxB;IACD,+CAA+C;IAC/C,OAAO,cAAc,CAAC;AACvB,CAAC;AARD,8CAQC;AAED,SAAgB,mBAAmB;IAC/B,MAAM,MAAM,GAAsB,iBAAiB,EAAE,CAAC;IACtD,OAAO,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3C,CAAC;AAHD,kDAGC"} -------------------------------------------------------------------------------- /out/glsl/editor.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const fs = require("fs"); 4 | const path = require("path"); 5 | const vscode = require("vscode"); 6 | exports.DefaultFragment = ` 7 | #extension GL_OES_standard_derivatives : enable 8 | 9 | #ifdef GL_ES 10 | precision mediump float; 11 | #endif 12 | 13 | varying vec4 v_position; 14 | varying vec4 v_normal; 15 | varying vec2 v_texcoord; 16 | varying vec4 v_color; 17 | 18 | uniform mat4 u_projectionMatrix; 19 | uniform mat4 u_modelViewMatrix; 20 | uniform mat4 u_normalMatrix; 21 | uniform vec2 u_resolution; 22 | uniform float u_time; 23 | 24 | #if defined(VERTEX) 25 | 26 | // attribute vec4 a_position; // myfolder/myfile.obj 27 | attribute vec4 a_position; 28 | attribute vec4 a_normal; 29 | attribute vec2 a_texcoord; 30 | attribute vec4 a_color; 31 | 32 | void main(void) { 33 | v_position = u_projectionMatrix * u_modelViewMatrix * a_position; 34 | v_normal = u_normalMatrix * a_normal; 35 | v_texcoord = a_texcoord; 36 | v_color = a_color; 37 | gl_Position = v_position; 38 | } 39 | 40 | #else // fragment shader 41 | 42 | uniform vec2 u_mouse; 43 | uniform vec2 u_pos; 44 | // uniform sampler2D u_texture; // https://cdn.jsdelivr.net/gh/actarian/plausible-brdf-shader/textures/mars/4096x2048/diffuse.jpg?repeat=true 45 | // uniform vec2 u_textureResolution; 46 | 47 | float checker(vec2 uv, float repeats) { 48 | float cx = floor(repeats * uv.x); 49 | float cy = floor(repeats * uv.y); 50 | float result = mod(cx + cy, 2.0); 51 | return sign(result); 52 | } 53 | 54 | void main() { 55 | vec2 p = v_texcoord; 56 | 57 | vec3 ambient = vec3(0.4); 58 | vec3 direction = vec3(0.0, 1.0, 1.0); 59 | vec3 lightColor = vec3(1.0); 60 | float incidence = max(dot(v_normal.xyz, direction), - 1.0); 61 | vec3 light = clamp(ambient + lightColor * incidence, 0.0, 1.0); 62 | 63 | vec3 color = (0.2 * checker(p, 8.0) + v_normal.rgb); 64 | gl_FragColor = vec4(color * light, 1.0); 65 | } 66 | 67 | #endif 68 | `; 69 | const DefaultFragment_old = /* glsl */ ` 70 | #ifdef GL_ES 71 | precision mediump float; 72 | #endif 73 | 74 | uniform vec2 u_resolution; 75 | uniform vec2 u_mouse; 76 | uniform float u_time; 77 | 78 | #define PI_TWO 1.570796326794897 79 | #define PI 3.141592653589793 80 | #define TWO_PI 6.283185307179586 81 | 82 | vec2 coord(in vec2 p) { 83 | p = p / u_resolution.xy; 84 | // correct aspect ratio 85 | if (u_resolution.x > u_resolution.y) { 86 | p.x *= u_resolution.x / u_resolution.y; 87 | p.x += (u_resolution.y - u_resolution.x) / u_resolution.y / 2.0; 88 | } else { 89 | p.y *= u_resolution.y / u_resolution.x; 90 | p.y += (u_resolution.x - u_resolution.y) / u_resolution.x / 2.0; 91 | } 92 | // centering 93 | p -= 0.5; 94 | p *= vec2(-1.0, 1.0); 95 | return p; 96 | } 97 | #define rx 1.0 / min(u_resolution.x, u_resolution.y) 98 | #define uv gl_FragCoord.xy / u_resolution.xy 99 | #define st coord(gl_FragCoord.xy) 100 | #define mx coord(u_mouse) 101 | 102 | void main() { 103 | vec3 color = vec3( 104 | abs(cos(st.x + mx.x)), 105 | abs(sin(st.y + mx.y)), 106 | abs(sin(u_time)) 107 | ); 108 | gl_FragColor = vec4(color, 1.0); 109 | } 110 | `; 111 | class GlslEditor { 112 | static create() { 113 | return new Promise((resolve, reject) => { 114 | /* 115 | if (!vscode.workspace.rootPath) { 116 | return vscode.window.showErrorMessage('No project currently open!'); 117 | } 118 | */ 119 | const folder = vscode.workspace.rootPath || ''; 120 | // console.log('GlslEditor.onCreateShader', folder); 121 | let newFile = vscode.Uri.parse('untitled:' + path.join(folder, 'untitled.glsl')); 122 | let i = 1; 123 | while (fs.existsSync(newFile.fsPath)) { 124 | newFile = vscode.Uri.parse('untitled:' + path.join(folder, 'untitled' + i + '.glsl')); 125 | i++; 126 | } 127 | vscode.workspace.openTextDocument(newFile).then(document => { 128 | // console.log('GlslEditor.document', document); 129 | const edit = new vscode.WorkspaceEdit(); 130 | edit.insert(newFile, new vscode.Position(0, 0), exports.DefaultFragment); 131 | return vscode.workspace.applyEdit(edit).then(success => { 132 | if (success) { 133 | vscode.window.showTextDocument(document, vscode.ViewColumn.One).then(success => { 134 | resolve(document); 135 | }, error => { 136 | reject(error); 137 | }); 138 | } 139 | else { 140 | reject('Error!'); 141 | } 142 | }, error => { 143 | console.log('GlslEditor.onCreateShader.applyEdit', error); 144 | reject(error); 145 | }); 146 | }, error => { 147 | console.log('GlslEditor.onCreateShader.openTextDocument', error); 148 | reject(error); 149 | }); 150 | }); 151 | } 152 | } 153 | exports.default = GlslEditor; 154 | //# sourceMappingURL=editor.js.map -------------------------------------------------------------------------------- /out/glsl/editor.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"editor.js","sourceRoot":"","sources":["../../src/glsl/editor.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,yBAAyB;AACzB,6BAA6B;AAC7B,iCAAiC;AAEpB,QAAA,eAAe,GAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8DxC,CAAC;AAEF,MAAM,mBAAmB,GAAG,UAAU,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyCrC,CAAC;AAEF,MAAqB,UAAU;IAE9B,MAAM,CAAC,MAAM;QACZ,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACtC;;;;cAIE;YACF,MAAM,MAAM,GAAW,MAAM,CAAC,SAAS,CAAC,QAAQ,IAAI,EAAE,CAAC;YACvD,oDAAoD;YACpD,IAAI,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;YACjF,IAAI,CAAC,GAAG,CAAC,CAAC;YACV,OAAO,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;gBACrC,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;gBACtF,CAAC,EAAE,CAAC;aACJ;YACD,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,IAAI,CAC9C,QAAQ,CAAC,EAAE;gBACV,gDAAgD;gBAChD,MAAM,IAAI,GAAG,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;gBACxC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,uBAAe,CAAC,CAAC;gBACjE,OAAO,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAC3C,OAAO,CAAC,EAAE;oBACT,IAAI,OAAO,EAAE;wBACZ,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,CACnE,OAAO,CAAC,EAAE;4BACT,OAAO,CAAC,QAAQ,CAAC,CAAC;wBACnB,CAAC,EACD,KAAK,CAAC,EAAE;4BACP,MAAM,CAAC,KAAK,CAAC,CAAC;wBACf,CAAC,CACD,CAAC;qBACF;yBAAM;wBACN,MAAM,CAAC,QAAQ,CAAC,CAAC;qBACjB;gBACF,CAAC,EACD,KAAK,CAAC,EAAE;oBACP,OAAO,CAAC,GAAG,CAAC,qCAAqC,EAAE,KAAK,CAAC,CAAC;oBAC1D,MAAM,CAAC,KAAK,CAAC,CAAC;gBACf,CAAC,CAAC,CAAC;YACL,CAAC,EACD,KAAK,CAAC,EAAE;gBACP,OAAO,CAAC,GAAG,CAAC,4CAA4C,EAAE,KAAK,CAAC,CAAC;gBACjE,MAAM,CAAC,KAAK,CAAC,CAAC;YACf,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACJ,CAAC;CAED;AAjDD,6BAiDC"} -------------------------------------------------------------------------------- /out/glsl/format.provider.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const vscode = require("vscode"); 4 | class GlslFormatProvider { 5 | // alt + shift + F = format 6 | // alt + shift + C = compact 7 | // Author: Name 8 | provideDocumentFormattingEdits(document, options, token) { 9 | const range = new vscode.Range(document.lineAt(0).range.start, document.lineAt(document.lineCount - 1).range.end); 10 | return this.provideDocumentRangeFormattingEdits(document, range, options, token); 11 | } 12 | provideDocumentRangeFormattingEdits(document, range, options, token) { 13 | const config = vscode.workspace.getConfiguration('glsl-canvas'); 14 | // console.log('GlslFormatProvider.config', config); 15 | const format = config['useFormatter']; 16 | const compact = config['useCompactFormatter']; 17 | if (format) { 18 | let text = document.getText(range); 19 | const tab = options.insertSpaces ? new Array(options.tabSize).fill(' ').join('') : '\t'; 20 | const comments = text.match(/(\/\/.*$)|(\/\*[\s\S]*\*\/)|(#include\s*".*")|(#include\s*'.*')/gm); 21 | const splitByComments = /\/\/.*$|\/\*[\s\S]*\*\/|#include\s*".*"|#include\s*'.*'/gm; 22 | const splitted = text.split(splitByComments).map(s => { 23 | if (compact) { 24 | // remove double spaces 25 | s = s.replace(/[^\S\n]+/gm, ' '); 26 | // trim 27 | // s = s.replace(/^[^\S\n]+|[^\S\n]+$/gm, ''); 28 | /* 29 | // remove start of line space 30 | s = s.replace(/^[^\S\n]+/gm, ''); 31 | // remove end of line space 32 | s = s.replace(/[^\S\n]+$/gm, ''); 33 | */ 34 | // remove extra new line 35 | s = s.replace(/\n\s*\n\s*\n/g, '\n\n'); 36 | // remove space 37 | s = s.replace(/[^\S\n]*(\B)[^\S\n]*/g, '$1'); 38 | // zero 39 | s = s.replace(/(\d)\.0*(\D)/g, '$1.$2'); 40 | s = s.replace(/(\D)0*\.(\d)/g, '$1.$2'); 41 | } 42 | else { 43 | // parentesis 44 | s = s.replace(/[^\S\n]*([\(\)\[\]])[^\S\n]*/g, '$1'); 45 | // s = s.replace(/(?\<\!\?\:]+)[^\S\n)]*([^\+\-])/g, '$1 $2 $3'); 48 | // s = s.replace(/([^\(\[])[^\S\n\()]*([\*\+\-\/\=/>/<]+)[^\S\n]*([^\+\-])/g, '$1 $2 $3'); 49 | s = s.replace(/([\,\;])[^\S\n]*/g, '$1 '); 50 | s = s.replace(/[^\S\n]*([/{])/g, ' $1'); 51 | // zero 52 | s = s.replace(/(\B)\.(\d)/g, '$10.$2'); 53 | s = s.replace(/(\d)\.(\B)/g, '$1.0$2'); 54 | // remove double spaces 55 | s = s.replace(/[^\S\n]+/gm, ' '); 56 | // special 57 | s = s.replace(/(if|return)[^\S\n]*([\(\[])/g, '$1 $2'); 58 | // trim 59 | // s = s.replace(/^[^\S\n]+|[^\S\n]+$/gm, ''); 60 | /* 61 | // remove start of line space 62 | s = s.replace(/^[^\S\n]+/gm, ''); 63 | // remove end of line space 64 | s = s.replace(/[^\S\n]+$/gm, ''); 65 | */ 66 | // remove extra new line 67 | s = s.replace(/\n\s*\n\s*\n/g, '\n\n'); 68 | // #pragma 69 | s = s.replace(/[^\S\r\n]*#pragma(.+?)\s*:\s*(\S+)[^\S\r\n]*/g, '#pragma$1:$2'); 70 | } 71 | return s; 72 | }); 73 | text = ''; 74 | while (splitted.length) { 75 | text += splitted.shift() + (comments ? (comments.shift() || '') : ''); 76 | } 77 | // indent blocks 78 | const lines = text.split('\n'); 79 | let i = 0; 80 | text = lines.map(l => { 81 | l = l.trim(); 82 | let a = (l.match(/^[^\{]*\}/g) || []).length; 83 | let b = (l.match(/^[^\(]*\)/g) || []).length; 84 | let c = (l.match(/^[^\[]*\]/g) || []).length; 85 | i -= (a + b + c); 86 | if (i > 0) { 87 | l = new Array(i).fill(tab).join('') + l; 88 | } 89 | a = (l.match(/\{(?!.*\})/g) || []).length; 90 | b = (l.match(/\((?!.*\))/g) || []).length; 91 | c = (l.match(/\[(?!.*\])/g) || []).length; 92 | i += (a + b + c); 93 | return l; 94 | }).join('\n'); 95 | return [vscode.TextEdit.replace(range, text)]; 96 | } 97 | else { 98 | return undefined; 99 | } 100 | } 101 | } 102 | exports.default = GlslFormatProvider; 103 | //# sourceMappingURL=format.provider.js.map -------------------------------------------------------------------------------- /out/glsl/format.provider.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"format.provider.js","sourceRoot":"","sources":["../../src/glsl/format.provider.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /out/glsl/options.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const path = require("path"); 4 | const vscode = require("vscode"); 5 | const common_1 = require("./common"); 6 | exports.WORKPATH_SCHEME = 'vscode-webview-resource:'; // 'vscode-webview-resource': 7 | class GlslOptions { 8 | constructor(webview = null, extensionPath = null) { 9 | const document = common_1.currentGlslDocument(); 10 | const config = vscode.workspace.getConfiguration('glsl-canvas'); 11 | const uri = document ? document.uri : null; 12 | const workspaceFolder = this.getWorkspaceFolder_(); 13 | const textures = Object.assign({}, config['textures'] || {}); 14 | this.uri = uri; 15 | this.workspaceFolder = workspaceFolder; 16 | this.fragment = document ? document.getText() : ''; 17 | this.vertex = ''; 18 | this.textures = textures; 19 | this.uniforms = config['uniforms'] || {}; 20 | this.timeout = config['timeout'] || 0; 21 | this.extensions = config['extensions'] || []; 22 | this.antialias = config['antialias'] || false; 23 | this.doubleSided = config['doubleSided'] || false; 24 | this.refreshOnChange = config['refreshOnChange'] || false; 25 | this.refreshOnSave = config['refreshOnSave'] || false; 26 | this.recordMethod = config['recordMethod'] || 'MediaRecorder'; 27 | // tslint:disable-next-line: triple-equals 28 | this.recordDuration = config['recordDuration'] != null ? config['recordDuration'] : 10; 29 | // tslint:disable-next-line: triple-equals 30 | this.recordWidth = config['recordWidth'] != null ? config['recordWidth'] : 1024; 31 | // tslint:disable-next-line: triple-equals 32 | this.recordHeight = config['recordHeight'] != null ? config['recordHeight'] : 1024; 33 | if (webview !== null && extensionPath !== null) { 34 | const workpath = this.getWorkpath_(webview, extensionPath, workspaceFolder, uri); 35 | const folder = this.getFolder_(extensionPath, workspaceFolder, uri); 36 | const resources = this.getResources_(webview, extensionPath); 37 | Object.keys(textures).forEach(key => { 38 | let texture = textures[key]; 39 | if (texture.indexOf('http') === -1) { 40 | if (workspaceFolder) { 41 | texture = path.join(workspaceFolder, texture); 42 | texture = path.relative(folder, texture); 43 | } 44 | else { 45 | texture = path.join(folder, texture); 46 | } 47 | } 48 | textures[key] = texture; 49 | }); 50 | this.workpath = workpath; 51 | this.folder = folder; 52 | this.resources = resources; 53 | } 54 | // console.log('GlslOptions', this); 55 | } 56 | serialize() { 57 | return JSON.stringify(this); 58 | } 59 | getWorkspaceFolder_() { 60 | return vscode.workspace && vscode.workspace.workspaceFolders ? vscode.workspace.workspaceFolders[0].uri.path : null; 61 | } 62 | getWorkpath_(webview, extensionPath, workspaceFolder, uri) { 63 | let url; 64 | const folder = uri ? path.dirname(uri.path) : workspaceFolder; 65 | if (folder) { 66 | uri = webview.asWebviewUri(vscode.Uri.file(folder)); 67 | } 68 | else { 69 | uri = vscode.Uri.file(path.join(extensionPath, 'resources')); 70 | } 71 | url = uri.scheme + '://' + uri.authority + uri.path; 72 | // console.log('GlslOptions.getWorkpath', url); 73 | return url; 74 | } 75 | getFolder_(extensionPath, workspaceFolder, uri) { 76 | let url; 77 | const folder = uri ? path.dirname(uri.path) : workspaceFolder; 78 | if (folder) { 79 | url = folder; 80 | } 81 | else { 82 | url = path.join(extensionPath, 'resources'); 83 | } 84 | // console.log('GlslOptions.getFolder', url); 85 | return url; 86 | } 87 | getResources_(webview, extensionPath) { 88 | const filePath = vscode.Uri.file(path.join(extensionPath, 'resources')); 89 | const uri = webview.asWebviewUri(filePath); 90 | const url = uri.scheme + '://' + uri.authority + uri.path; 91 | // console.log('GlslOptions.getResources', url); 92 | return url; 93 | } 94 | } 95 | exports.default = GlslOptions; 96 | //# sourceMappingURL=options.js.map -------------------------------------------------------------------------------- /out/glsl/options.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/glsl/options.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,6BAA6B;AAC7B,iCAAiC;AACjC,qCAA+C;AAElC,QAAA,eAAe,GAAW,0BAA0B,CAAC,CAAC,6BAA6B;AAEhG,MAAqB,WAAW;IAuB/B,YAAY,UAA0B,IAAI,EAAE,gBAAwB,IAAI;QACvE,MAAM,QAAQ,GAAwB,4BAAmB,EAAE,CAAC;QAC5D,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;QAChE,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3C,MAAM,eAAe,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACnD,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7D,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;QACvC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnD,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QACzC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;QAC7C,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC;QAC9C,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC;QAClD,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,iBAAiB,CAAC,IAAI,KAAK,CAAC;QAC1D,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,eAAe,CAAC,IAAI,KAAK,CAAC;QACtD,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,eAAe,CAAC;QAC9D,0CAA0C;QAC1C,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,gBAAgB,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACvF,0CAA0C;QAC1C,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAChF,0CAA0C;QAC1C,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACnF,IAAI,OAAO,KAAK,IAAI,IAAI,aAAa,KAAK,IAAI,EAAE;YAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,GAAG,CAAC,CAAC;YACjF,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,eAAe,EAAE,GAAG,CAAC,CAAC;YACpE,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;YAC7D,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;gBACnC,IAAI,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;gBAC5B,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE;oBACnC,IAAI,eAAe,EAAE;wBACpB,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;wBAC9C,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;qBACzC;yBAAM;wBACN,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;qBACrC;iBACD;gBACD,QAAQ,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC;YACzB,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;YACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;YACrB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;SAC3B;QACD,oCAAoC;IACrC,CAAC;IAEM,SAAS;QACf,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAEO,mBAAmB;QAC1B,OAAO,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACrH,CAAC;IAEO,YAAY,CAAC,OAAuB,EAAE,aAAqB,EAAE,eAAuB,EAAE,GAAgB;QAC7G,IAAI,GAAW,CAAC;QAChB,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC;QAC9D,IAAI,MAAM,EAAE;YACX,GAAG,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;SACpD;aAAM;YACN,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC,CAAC;SAC7D;QACD,GAAG,GAAG,GAAG,CAAC,MAAM,GAAG,KAAK,GAAG,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC;QACpD,+CAA+C;QAC/C,OAAO,GAAG,CAAC;IACZ,CAAC;IAEO,UAAU,CAAC,aAAqB,EAAE,eAAuB,EAAE,GAAgB;QAClF,IAAI,GAAW,CAAC;QAChB,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC;QAC9D,IAAI,MAAM,EAAE;YACX,GAAG,GAAG,MAAM,CAAC;SACb;aAAM;YACN,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;SAC5C;QACD,6CAA6C;QAC7C,OAAO,GAAG,CAAC;IACZ,CAAC;IAEO,aAAa,CAAC,OAAuB,EAAE,aAAqB;QACnE,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAC/B,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CACrC,CAAC;QACF,MAAM,GAAG,GAAe,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QACvD,MAAM,GAAG,GAAW,GAAG,CAAC,MAAM,GAAG,KAAK,GAAG,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC;QAClE,gDAAgD;QAChD,OAAO,GAAG,CAAC;IACZ,CAAC;CACD;AAjHD,8BAiHC"} -------------------------------------------------------------------------------- /out/glsl/panel.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"panel.js","sourceRoot":"","sources":["../../src/glsl/panel.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /out/test/runTest.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | Object.defineProperty(exports, "__esModule", { value: true }); 12 | const path = require("path"); 13 | const vscode_test_1 = require("vscode-test"); 14 | function main() { 15 | return __awaiter(this, void 0, void 0, function* () { 16 | try { 17 | // The folder containing the Extension Manifest package.json 18 | // Passed to `--extensionDevelopmentPath` 19 | const extensionDevelopmentPath = path.resolve(__dirname, '../../'); 20 | // The path to the extension test script 21 | // Passed to --extensionTestsPath 22 | const extensionTestsPath = path.resolve(__dirname, './suite/index'); 23 | // Download VS Code, unzip it and run the integration test 24 | yield vscode_test_1.runTests({ extensionDevelopmentPath, extensionTestsPath }); 25 | } 26 | catch (err) { 27 | console.error('Failed to run tests'); 28 | process.exit(1); 29 | } 30 | }); 31 | } 32 | main(); 33 | //# sourceMappingURL=runTest.js.map -------------------------------------------------------------------------------- /out/test/runTest.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"runTest.js","sourceRoot":"","sources":["../../src/test/runTest.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,6BAA6B;AAC7B,6CAAuC;AAEvC,SAAe,IAAI;;QAClB,IAAI;YACH,4DAA4D;YAC5D,yCAAyC;YACzC,MAAM,wBAAwB,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YAEnE,wCAAwC;YACxC,iCAAiC;YACjC,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;YAEpE,0DAA0D;YAC1D,MAAM,sBAAQ,CAAC,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,CAAC,CAAC;SACjE;QAAC,OAAO,GAAG,EAAE;YACb,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;YACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;SAChB;IACF,CAAC;CAAA;AAED,IAAI,EAAE,CAAC"} -------------------------------------------------------------------------------- /out/test/suite/extension.test.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const assert = require("assert"); 4 | // You can import and use all API from the 'vscode' module 5 | // as well as import your extension to test it 6 | const vscode = require("vscode"); 7 | // import * as myExtension from '../../extension'; 8 | suite('Extension Test Suite', () => { 9 | vscode.window.showInformationMessage('Start all tests.'); 10 | test('Sample test', () => { 11 | assert.equal([1, 2, 3].indexOf(5), -1); 12 | assert.equal([1, 2, 3].indexOf(0), -1); 13 | }); 14 | }); 15 | //# sourceMappingURL=extension.test.js.map -------------------------------------------------------------------------------- /out/test/suite/extension.test.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"extension.test.js","sourceRoot":"","sources":["../../../src/test/suite/extension.test.ts"],"names":[],"mappings":";;AAAA,iCAAiC;AACjC,0DAA0D;AAC1D,8CAA8C;AAC9C,iCAAiC;AAEjC,kDAAkD;AAElD,KAAK,CAAC,sBAAsB,EAAE,GAAG,EAAE;IAClC,MAAM,CAAC,MAAM,CAAC,sBAAsB,CAAC,kBAAkB,CAAC,CAAC;IAEzD,IAAI,CAAC,aAAa,EAAE,GAAG,EAAE;QACxB,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACvC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC"} -------------------------------------------------------------------------------- /out/test/suite/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const glob = require("glob"); 4 | const Mocha = require("mocha"); 5 | const path = require("path"); 6 | function run() { 7 | // Create the mocha test 8 | const mocha = new Mocha({ 9 | ui: 'tdd' 10 | }); 11 | mocha.useColors(true); 12 | const testsRoot = path.resolve(__dirname, '..'); 13 | return new Promise((c, e) => { 14 | glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { 15 | if (err) { 16 | return e(err); 17 | } 18 | // Add files to the test suite 19 | files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); 20 | try { 21 | // Run the mocha test 22 | mocha.run(failures => { 23 | if (failures > 0) { 24 | e(new Error(`${failures} tests failed.`)); 25 | } 26 | else { 27 | c(); 28 | } 29 | }); 30 | } 31 | catch (err) { 32 | console.error(err); 33 | e(err); 34 | } 35 | }); 36 | }); 37 | } 38 | exports.run = run; 39 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /out/test/suite/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/test/suite/index.ts"],"names":[],"mappings":";;AAAA,6BAA6B;AAC7B,+BAA+B;AAC/B,6BAA6B;AAE7B,SAAgB,GAAG;IAClB,wBAAwB;IACxB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC;QACvB,EAAE,EAAE,KAAK;KACT,CAAC,CAAC;IACH,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAEtB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAEhD,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC3B,IAAI,CAAC,eAAe,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;YACxD,IAAI,GAAG,EAAE;gBACR,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC;aACd;YAED,8BAA8B;YAC9B,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAE9D,IAAI;gBACH,qBAAqB;gBACrB,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;oBACpB,IAAI,QAAQ,GAAG,CAAC,EAAE;wBACjB,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,QAAQ,gBAAgB,CAAC,CAAC,CAAC;qBAC1C;yBAAM;wBACN,CAAC,EAAE,CAAC;qBACJ;gBACF,CAAC,CAAC,CAAC;aACH;YAAC,OAAO,GAAG,EAAE;gBACb,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACnB,CAAC,CAAC,GAAG,CAAC,CAAC;aACP;QACF,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC;AAjCD,kBAiCC"} -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "glsl-canvas", 3 | "displayName": "glsl-canvas", 4 | "description": "Live WebGL preview of GLSL shaders", 5 | "version": "0.2.15", 6 | "author": "Luca Zampetti ", 7 | "publisher": "circledev", 8 | "license": "MIT", 9 | "engines": { 10 | "vscode": "^1.38.0" 11 | }, 12 | "categories": [ 13 | "Snippets", 14 | "Other" 15 | ], 16 | "activationEvents": [ 17 | "onCommand:glsl-canvas.showGlslCanvas", 18 | "onWebviewPanel:glslCanvas", 19 | "onLanguage:glsl" 20 | ], 21 | "main": "./out/extension", 22 | "bugs": { 23 | "url": "https://github.com/actarian/vscode-glsl-canvas/issues" 24 | }, 25 | "homepage": "https://github.com/actarian/vscode-glsl-canvas/blob/master/README.md", 26 | "contributes": { 27 | "configuration": { 28 | "properties": { 29 | "glsl-canvas.textures": { 30 | "type": "object", 31 | "description": "The texture channels (u_texture_0, u_texture_1, ...) using http:// or file:// protocol." 32 | }, 33 | "glsl-canvas.uniforms": { 34 | "type": "object", 35 | "description": "Custom uniforms values." 36 | }, 37 | "glsl-canvas.extensions": { 38 | "type": "array", 39 | "description": "An array of extensions to enable in the webgl context, like EXT_shader_texture_lod." 40 | }, 41 | "glsl-canvas.doubleSided": { 42 | "type": "boolean", 43 | "description": "Enables/Disables doubleSided rendering." 44 | }, 45 | "glsl-canvas.antialias": { 46 | "type": "boolean", 47 | "description": "Enables/Disables antialias in webgl context." 48 | }, 49 | "glsl-canvas.timeout": { 50 | "type": "number", 51 | "default": 0, 52 | "description": "Wait time in milliseconds before updating the canvas after a change in the source code. Set 0 to update immediately." 53 | }, 54 | "glsl-canvas.refreshOnSave": { 55 | "type": "boolean", 56 | "default": true, 57 | "description": "Enables/Disables refreshing the glslCanvas when saving the document." 58 | }, 59 | "glsl-canvas.refreshOnChange": { 60 | "type": "boolean", 61 | "default": true, 62 | "description": "Enables/Disables refreshing the glslCanvas when changing the document." 63 | }, 64 | "glsl-canvas.installOnExport": { 65 | "type": "boolean", 66 | "default": true, 67 | "description": "Enables/Disables installing Npm packages on export. Requires Npm." 68 | }, 69 | "glsl-canvas.useFormatter": { 70 | "type": "boolean", 71 | "default": true, 72 | "description": "Enables/Disables code formatter." 73 | }, 74 | "glsl-canvas.useCompactFormatter": { 75 | "type": "boolean", 76 | "default": true, 77 | "description": "Enables/Disables compact formatter." 78 | }, 79 | "glsl-canvas.recordMethod": { 80 | "type": "string", 81 | "default": "MediaRecorder", 82 | "enum": [ 83 | "MediaRecorder", 84 | "CCapture" 85 | ], 86 | "enumDescriptions": [ 87 | "Use MediaRecorder api for standard quality webm video capture.", 88 | "Use CCapture for high quality webm video capture (slower)." 89 | ] 90 | }, 91 | "glsl-canvas.recordDuration": { 92 | "type": "number", 93 | "default": 0, 94 | "description": "Recording duration in seconds. Set 0 for manual control." 95 | }, 96 | "glsl-canvas.recordWidth": { 97 | "type": "number", 98 | "default": 1024, 99 | "description": "Recording canvas width in pixels. Set 0 to adapt." 100 | }, 101 | "glsl-canvas.recordHeight": { 102 | "type": "number", 103 | "default": 1024, 104 | "description": "Recording canvas height in pixels. Set 0 to adapt." 105 | } 106 | } 107 | }, 108 | "commands": [ 109 | { 110 | "command": "glsl-canvas.showGlslCanvas", 111 | "title": "Show glslCanvas" 112 | } 113 | ], 114 | "snippets": [ 115 | { 116 | "language": "glsl", 117 | "path": "./snippets/glsl.json" 118 | } 119 | ], 120 | "languages": [ 121 | { 122 | "id": "glsl", 123 | "aliases": [ 124 | "GLSL", 125 | "OpenGL Shading Language", 126 | "glsl" 127 | ], 128 | "extensions": [ 129 | ".vs", 130 | ".fs", 131 | ".gs", 132 | ".comp", 133 | ".vert", 134 | ".tesc", 135 | ".tese", 136 | ".frag", 137 | ".geom", 138 | ".glsl", 139 | ".glslv", 140 | ".glslf", 141 | ".glslg" 142 | ], 143 | "configuration": "./glsl.configuration.json" 144 | } 145 | ] 146 | }, 147 | "scripts": { 148 | "vscode:prepublish": "npm run compile", 149 | "compile": "tsc -p ./", 150 | "lint": "eslint . --ext .ts,.tsx", 151 | "watch": "tsc -w -p ./", 152 | "pretest": "npm run compile", 153 | "test": "node ./out/test/runTest.js" 154 | }, 155 | "keywords": [ 156 | "shader", 157 | "glsl" 158 | ], 159 | "icon": "resources/img/icon.png", 160 | "repository": { 161 | "type": "git", 162 | "url": "git://github.com/actarian/vscode-glsl-canvas.git" 163 | }, 164 | "dependencies": { 165 | "ccapture.js": "1.1.0", 166 | "dat.gui": "0.7.7", 167 | "glsl-canvas-js": "0.2.8", 168 | "glslEditor": "0.0.22", 169 | "natives": "~1.1.6", 170 | "spawn-command-with-kill": "~1.0.2", 171 | "stats.js": "0.17.0" 172 | }, 173 | "devDependencies": { 174 | "gulpfile-config": "1.0.0-alpha.14", 175 | "@types/mocha": "7.0.2", 176 | "@types/node": "13.9.5", 177 | "@types/vscode": "1.38.0", 178 | "@typescript-eslint/eslint-plugin": "4.16.0", 179 | "@typescript-eslint/parser": "4.16.0", 180 | "eslint": "6.8.0", 181 | "mocha": "7.1.2", 182 | "typescript": "3.8.3", 183 | "vscode-test": "1.3.0" 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /resources/css/vendors.css: -------------------------------------------------------------------------------- 1 | .dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear;border:0;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button.close-top{position:relative}.dg.main .close-button.close-bottom{position:absolute}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-y:visible}.dg.a.has-save>ul.close-top{margin-top:0}.dg.a.has-save>ul.close-bottom{margin-top:27px}.dg.a.has-save>ul.closed{margin-top:0}.dg.a .save-row{top:0;z-index:1002}.dg.a .save-row.close-top{position:relative}.dg.a .save-row.close-bottom{position:fixed}.dg li{-webkit-transition:height .1s ease-out;-o-transition:height .1s ease-out;-moz-transition:height .1s ease-out;transition:height .1s ease-out;-webkit-transition:overflow .1s linear;-o-transition:overflow .1s linear;-moz-transition:overflow .1s linear;transition:overflow .1s linear}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li>*{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px;overflow:hidden}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .c{float:left;width:60%;position:relative}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:7px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .cr.color{overflow:visible}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.color{border-left:3px solid}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2FA1D6}.dg .cr.number input[type=text]{color:#2FA1D6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2FA1D6;max-width:100%}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda} 2 | -------------------------------------------------------------------------------- /resources/css/vendors.min.css: -------------------------------------------------------------------------------- 1 | .dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1!important}.dg.main .close-button.drag,.dg.main:hover .close-button{opacity:1}.dg.main .close-button{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear;border:0;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button.close-top{position:relative}.dg.main .close-button.close-bottom{position:absolute}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-y:visible}.dg.a.has-save>ul.close-top{margin-top:0}.dg.a.has-save>ul.close-bottom{margin-top:27px}.dg.a.has-save>ul.closed{margin-top:0}.dg.a .save-row{top:0;z-index:1002}.dg.a .save-row.close-top{position:relative}.dg.a .save-row.close-bottom{position:fixed}.dg li{-webkit-transition:height .1s ease-out;-o-transition:height .1s ease-out;-moz-transition:height .1s ease-out;transition:height .1s ease-out;-webkit-transition:overflow .1s linear;-o-transition:overflow .1s linear;-moz-transition:overflow .1s linear;transition:overflow .1s linear}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid transparent}.dg li.title{margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li>*{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px;overflow:hidden}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .c{float:left;width:60%;position:relative}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:7px}.dg .c select{margin-top:5px}.dg .cr.boolean,.dg .cr.boolean *,.dg .cr.function,.dg .cr.function *,.dg .cr.function .property-name{cursor:pointer}.dg .cr.color{overflow:visible}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco,monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px Lucida Grande,sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid hsla(0,0%,100%,.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.color{border-left:3px solid}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2fa1d6}.dg .cr.number input[type=text]{color:#2fa1d6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.boolean:hover,.dg .cr.function:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2fa1d6;max-width:100%}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda} 2 | /*# sourceMappingURL=vendors.min.css.map */ -------------------------------------------------------------------------------- /resources/export/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2019 Luca Zampetti lzampetti@gmail.com https://github.com/actarian/glsl-canvas 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /resources/export/css/glsl-canvas.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | width: 100%; 3 | height: 100%; 4 | } 5 | 6 | body { 7 | display: flex; 8 | margin: 0; 9 | background: #111; 10 | overflow: hidden; 11 | } 12 | 13 | .glsl-canvas{ 14 | width: 100%; 15 | height: 100%; 16 | } 17 | -------------------------------------------------------------------------------- /resources/export/img/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/resources/export/img/favicon-16x16.png -------------------------------------------------------------------------------- /resources/export/img/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/resources/export/img/favicon-32x32.png -------------------------------------------------------------------------------- /resources/export/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/resources/export/img/favicon.ico -------------------------------------------------------------------------------- /resources/export/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "glsl-canvas-preview", 3 | "version": "0.2.15", 4 | "author": "Luca Zampetti ", 5 | "license": "MIT", 6 | "scripts": { 7 | "postinstall": "npm run start", 8 | "start": "sirv --port 8080 --host --cors --single --dev" 9 | }, 10 | "dependencies": { 11 | "glsl-canvas-js": "0.2.8", 12 | "stats.js": "0.17.0" 13 | }, 14 | "devDependencies": { 15 | "sirv-cli": "1.0.11" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /resources/fonts/fonts/glslcanvas.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/resources/fonts/fonts/glslcanvas.eot -------------------------------------------------------------------------------- /resources/fonts/fonts/glslcanvas.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by Fontastic.me 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /resources/fonts/fonts/glslcanvas.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/resources/fonts/fonts/glslcanvas.ttf -------------------------------------------------------------------------------- /resources/fonts/fonts/glslcanvas.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/resources/fonts/fonts/glslcanvas.woff -------------------------------------------------------------------------------- /resources/fonts/styles.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | @font-face { 4 | font-family: "glslcanvas"; 5 | src:url("fonts/glslcanvas.eot"); 6 | src:url("fonts/glslcanvas.eot?#iefix") format("embedded-opentype"), 7 | url("fonts/glslcanvas.woff") format("woff"), 8 | url("fonts/glslcanvas.ttf") format("truetype"), 9 | url("fonts/glslcanvas.svg#glslcanvas") format("svg"); 10 | font-weight: normal; 11 | font-style: normal; 12 | 13 | } 14 | 15 | [data-icon]:before { 16 | font-family: "glslcanvas" !important; 17 | content: attr(data-icon); 18 | font-style: normal !important; 19 | font-weight: normal !important; 20 | font-variant: normal !important; 21 | text-transform: none !important; 22 | speak: none; 23 | line-height: 1; 24 | -webkit-font-smoothing: antialiased; 25 | -moz-osx-font-smoothing: grayscale; 26 | } 27 | 28 | [class^="icon-"]:before, 29 | [class*=" icon-"]:before { 30 | font-family: "glslcanvas" !important; 31 | font-style: normal !important; 32 | font-weight: normal !important; 33 | font-variant: normal !important; 34 | text-transform: none !important; 35 | speak: none; 36 | line-height: 1; 37 | -webkit-font-smoothing: antialiased; 38 | -moz-osx-font-smoothing: grayscale; 39 | } 40 | 41 | .icon-pause:before { 42 | content: "\61"; 43 | } 44 | .icon-play:before { 45 | content: "\62"; 46 | } 47 | .icon-record:before { 48 | content: "\63"; 49 | } 50 | .icon-stop:before { 51 | content: "\64"; 52 | } 53 | .icon-stats:before { 54 | content: "\65"; 55 | } 56 | .icon-export:before { 57 | content: "\6c"; 58 | } 59 | .icon-flat:before { 60 | content: "\66"; 61 | } 62 | .icon-box:before { 63 | content: "\67"; 64 | } 65 | .icon-sphere:before { 66 | content: "\68"; 67 | } 68 | .icon-torus:before { 69 | content: "\69"; 70 | } 71 | .icon-mesh:before { 72 | content: "\6a"; 73 | } 74 | -------------------------------------------------------------------------------- /resources/img/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/resources/img/icon.png -------------------------------------------------------------------------------- /src/app/services/camera/camera.service.js: -------------------------------------------------------------------------------- 1 | /* global window, console, Vector */ 2 | 3 | (function () { 4 | 'use strict'; 5 | 6 | var CameraService = function () { 7 | 8 | var PI = Math.PI; 9 | var RAD = PI / 180; 10 | 11 | function CameraService(theta, phi, radius) { 12 | var service = this; 13 | service.theta = (theta || 45) * RAD; 14 | service.phi = (phi || 45) * RAD; 15 | service.radius = radius || 1.0; 16 | } 17 | 18 | CameraService.prototype = { 19 | down: down, 20 | move: move, 21 | up: up, 22 | wheel: wheel, 23 | render: render, 24 | update: update, 25 | }; 26 | 27 | CameraService.fromVector = fromVector; 28 | CameraService.toVector = toVector; 29 | 30 | // publics 31 | 32 | function down(x, y) { 33 | var service = this; 34 | service.mouse = { 35 | x: x, 36 | y: y, 37 | }; 38 | } 39 | 40 | function move(x, y) { 41 | var service = this, 42 | mouse = service.mouse; 43 | if (mouse) { 44 | var theta = (x - mouse.x) * 180 * RAD; 45 | var phi = (mouse.y - y) * 180 * RAD; 46 | mouse.x = x; 47 | mouse.y = y; 48 | service.theta += theta; 49 | service.phi += phi; 50 | } 51 | } 52 | 53 | function up(x, y) { 54 | var service = this; 55 | service.mouse = null; 56 | } 57 | 58 | function wheel(d) { 59 | var service = this; 60 | service.radius = Math.max(0.01, service.radius + d * 0.02); 61 | } 62 | 63 | function render(glsl) { 64 | var service = this; 65 | var vector = CameraService.toVector(service); 66 | var array = new Float32Array([vector.x, vector.y, vector.z]); 67 | service.update(glsl, '3fv', 'vec3', 'u_camera', array); 68 | } 69 | 70 | function update(glsl, method, type, name, value) { 71 | try { 72 | var u = glsl.uniforms[name] = glsl.uniforms[name] || {}; 73 | u.name = name; 74 | u.value = value; 75 | u.type = type; 76 | u.method = 'uniform' + method; 77 | u.location = glsl.gl.getUniformLocation(glsl.program, name); 78 | glsl.gl[u.method].apply(glsl.gl, [u.location].concat(u.value)); 79 | } catch (e) { 80 | console.log('CameraService.update.error', e); 81 | } 82 | } 83 | 84 | // statics 85 | 86 | function fromVector(vector) { 87 | var radius = vector.length(); 88 | var theta = Math.acos(vector.y / radius); //theta 89 | var phi = Math.atan(vector.x / vector.z); //phi 90 | return new CameraService(theta, phi, radius); 91 | } 92 | 93 | function toVector(camera) { 94 | var spr = Math.sin(camera.phi) * camera.radius; 95 | var x = spr * Math.sin(camera.theta); 96 | var y = Math.cos(camera.phi) * camera.radius; 97 | var z = spr * Math.cos(camera.theta); 98 | return new Vector(x, y, z); 99 | } 100 | 101 | return CameraService; 102 | 103 | }(); 104 | 105 | window.CameraService = CameraService; 106 | 107 | }()); 108 | -------------------------------------------------------------------------------- /src/app/services/capture/capture.service.js: -------------------------------------------------------------------------------- 1 | /* global window, document, console, GlslCanvas */ 2 | /* 3 | Author: Brett Camper (@professorlemeza) 4 | URL: https://github.com/tangrams/tangram/blob/master/src/utils/media_capture.js 5 | */ 6 | 7 | (function () { 8 | 'use strict'; 9 | 10 | function CaptureService() {} 11 | 12 | CaptureService.prototype = { 13 | set: set, 14 | snapshot: snapshot, 15 | snapshotRender: snapshotRender, 16 | record: record, 17 | stop: stop, 18 | }; 19 | 20 | function set(canvas) { 21 | var service = this; 22 | service.canvas = canvas; 23 | } 24 | 25 | /* 26 | var mimeTypes = [ 27 | 'video/webm\;codecs=h264', 28 | 'video/webm\;codecs=vp8', 29 | 'video/webm\;codecs=daala', 30 | 'video/webm', 31 | 'audio/webm\;codecs=opus', 32 | 'audio/webm', 33 | 'video/mpeg', 34 | ]; 35 | var options = { 36 | videoBitsPerSecond: 2500000, 37 | audioBitsPerSecond: 128000, 38 | mimeType: 'video/webm', 39 | extension: '.webm', 40 | }; 41 | // MediaRecorder.isTypeSupported(mimeTypes[0]) 42 | */ 43 | 44 | function record() { 45 | var service = this; 46 | if (typeof window.MediaRecorder !== 'function' || !service.canvas || typeof service.canvas.captureStream !== 'function') { 47 | console.log('warn: Video capture (Canvas.captureStream and/or MediaRecorder APIs) not supported by browser'); 48 | return false; 49 | } else if (service.capture) { 50 | console.log('warn: Video capture already in progress, call Scene.stopVideoCapture() first'); 51 | return false; 52 | } 53 | try { 54 | var capture = {}; 55 | var chunks = []; 56 | var stream = service.canvas.captureStream(30); 57 | var options = { 58 | mimeType: 'video/webm; codecs=vp9', // 'video/webm', // 'video/webm\;codecs=h264' 59 | audioBitsPerSecond: 0, 60 | videoBitsPerSecond: 1048576 * 10, 61 | }; 62 | var recorder = new MediaRecorder(stream, options); 63 | // console.log('videoBitsPerSecond', recorder.videoBitsPerSecond); 64 | recorder.ondataavailable = function (event) { 65 | if (event.data.size > 0) { 66 | chunks.push(event.data); 67 | } 68 | // Stopped recording? Create the final capture file blob 69 | if (capture.resolve) { 70 | var blob = new Blob(chunks, { 71 | type: options.mimeType, 72 | }); 73 | if (stream) { 74 | var tracks = stream.getTracks() || []; 75 | tracks.forEach(function (track) { 76 | track.stop(); 77 | stream.removeTrack(track); 78 | }); 79 | } 80 | stream = null; 81 | service.recorder = null; 82 | service.capture = null; 83 | capture.resolve({ 84 | blob: blob, 85 | extension: '.webm', 86 | }); 87 | } 88 | }; 89 | service.capture = capture; 90 | service.recorder = recorder; 91 | recorder.start(); 92 | } catch (error) { 93 | service.capture = null; 94 | service.recorder = null; 95 | console.log('error: Scene video capture failed', error); 96 | return false; 97 | } 98 | return true; 99 | } 100 | 101 | function stop() { 102 | var service = this; 103 | if (!service.capture) { 104 | console.log('warn: No scene video capture in progress, call Scene.startVideoCapture() first'); 105 | return Promise.resolve({}); 106 | } 107 | service.capture.promise = new Promise(function (resolve, reject) { 108 | service.capture.resolve = resolve; 109 | service.capture.reject = reject; 110 | }); 111 | service.recorder.stop(); 112 | return service.capture.promise; 113 | } 114 | 115 | function snapshot() { 116 | var service = this; 117 | if (service.queue) { 118 | return service.queue.promise; 119 | } 120 | service.queue = {}; 121 | service.queue.promise = new Promise(function (resolve, reject) { 122 | service.queue.resolve = resolve; 123 | service.queue.reject = reject; 124 | }); 125 | return service.queue.promise; 126 | } 127 | 128 | function snapshotRender() { 129 | var service = this; 130 | if (service.queue) { 131 | // Get data URL, convert to blob 132 | // Strip host/mimetype/etc., convert base64 to binary without UTF-8 mangling 133 | // Adapted from: https://gist.github.com/unconed/4370822 134 | var url = service.canvas.toDataURL('image/png'); 135 | var bytes = atob(url.slice(22)); 136 | var buffer = new Uint8Array(bytes.length); 137 | for (var i = 0; i < bytes.length; ++i) { 138 | buffer[i] = bytes.charCodeAt(i); 139 | } 140 | var blob = new Blob([buffer], { 141 | type: 'image/png', 142 | }); 143 | service.queue.resolve({ 144 | blob: blob, 145 | extension: '.png', 146 | }); 147 | service.queue = null; 148 | } 149 | } 150 | 151 | window.CaptureService = CaptureService; 152 | }()); 153 | -------------------------------------------------------------------------------- /src/app/services/capture/ccapture.service.js: -------------------------------------------------------------------------------- 1 | /* global window, document, console, GlslCanvas */ 2 | /* 3 | Author: Brett Camper (@professorlemeza) 4 | URL: https://github.com/tangrams/tangram/blob/master/src/utils/media_capture.js 5 | */ 6 | 7 | (function () { 8 | 'use strict'; 9 | 10 | function CCaptureService() { 11 | this.capturer = new CCapture({ 12 | format: 'webm', 13 | quality: 90, 14 | framerate: 60, 15 | // motionBlurFrames: 3, 16 | // timeLimit: window.options.recordDuration !== 0 ? window.options.recordDuration : null, 17 | }); 18 | } 19 | 20 | CCaptureService.prototype = { 21 | set: set, 22 | snapshot: snapshot, 23 | snapshotRender: snapshotRender, 24 | record: record, 25 | stop: stop, 26 | }; 27 | 28 | function set(canvas) { 29 | var service = this; 30 | service.canvas = canvas; 31 | } 32 | 33 | function record() { 34 | var service = this; 35 | var capturer = service.capturer; 36 | capturer.start(); 37 | return true; 38 | } 39 | 40 | function stop() { 41 | var service = this; 42 | var capturer = service.capturer; 43 | return new Promise(function (resolve, reject) { 44 | capturer.stop(); 45 | capturer.save(function(blob) { 46 | resolve({ 47 | blob: blob, 48 | extension: '.webm', 49 | }); 50 | }); 51 | }); 52 | } 53 | 54 | function snapshot() { 55 | var service = this; 56 | return null; 57 | } 58 | 59 | function snapshotRender() { 60 | var service = this; 61 | var capturer = service.capturer; 62 | capturer.capture(service.canvas); 63 | } 64 | 65 | window.CCaptureService = CCaptureService; 66 | }()); 67 | -------------------------------------------------------------------------------- /src/app/services/gui/gui.scss: -------------------------------------------------------------------------------- 1 | @import "../vars"; 2 | $boolean: #45c4b0; 3 | $function: #dccd7d; 4 | $number: #569cd6; 5 | $string: #c3886f; 6 | 7 | /* 8 | var(--vscode-editor-background) 9 | var(--vscode-editor-foreground) 10 | var(--vscode-editor-lineHighlightBorder) 11 | var(--vscode-editor-lineHighlightBackground) 12 | */ 13 | 14 | .dg { 15 | &.ac { 16 | height: auto; 17 | right: 0; 18 | left: auto; 19 | position: absolute; 20 | transform: translateX(15px); 21 | cursor: pointer; 22 | -webkit-user-select: none; 23 | user-select: none; 24 | } 25 | &.main { 26 | &.taller-than-window { 27 | .close-button { 28 | border-top-color: var(--vscode-editor-background); 29 | } 30 | } 31 | .close-button { 32 | background-color: var(--vscode-editor-background); 33 | &:hover { 34 | background-color: var(--vscode-editor-lineHighlightBorder); 35 | } 36 | } 37 | } 38 | &.a { 39 | margin-right: 15px; 40 | } 41 | li.folder { 42 | border-left-color: $value; 43 | } 44 | .property-name { 45 | width: 40%; 46 | } 47 | .c { 48 | width: 60%; 49 | .slider:hover .slider-fg { 50 | background: $value; 51 | } 52 | } 53 | &.dialogue { 54 | background-color: var(--vscode-editor-background); 55 | width: 460px; 56 | padding: 15px; 57 | font-size: 13px; 58 | line-height: 15px; 59 | } 60 | } 61 | 62 | .dg { 63 | color: $text; 64 | font: 11px inherit; 65 | text-shadow: none; 66 | &.main { 67 | &::-webkit-scrollbar { 68 | background: var(--vscode-editor-background); 69 | } 70 | &::-webkit-scrollbar-thumb { 71 | background: var(--vscode-editor-lineHighlightBorder); 72 | } 73 | } 74 | li { 75 | &:not(.folder) { 76 | background: var(--vscode-editor-background); 77 | // border-bottom-color: rgba(255, 255, 255, 0.2); 78 | border-bottom-color: var(--vscode-editorIndentGuide-background); 79 | } 80 | &.save-row { 81 | background: $value; 82 | .button { 83 | &:hover { 84 | background-color: darken($foreground, 5%); 85 | box-shadow: none; 86 | } 87 | } 88 | } 89 | &.title { 90 | background: #000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat; 91 | // border-bottom-color: rgba(255, 255, 255, 0.2); 92 | border-bottom-color: var(--vscode-editorIndentGuide-background); 93 | } 94 | } 95 | .closed li.title { 96 | background-image: url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==); 97 | } 98 | .c { 99 | input[type=text] { 100 | background: var(--vscode-editor-background); 101 | &:hover { 102 | background: var(--vscode-editor-lineHighlightBorder); 103 | } 104 | &:focus { 105 | background: var(--vscode-editorLineNumber-foreground); 106 | color: $text; 107 | } 108 | } 109 | .slider { 110 | background: var(--vscode-editor-background); 111 | &:hover { 112 | background: var(--vscode-editor-lineHighlightBorder); 113 | } 114 | } 115 | } 116 | .cr { 117 | &.boolean { 118 | border-left-color: mix($background, $boolean, 80%); 119 | .c { 120 | .slider-fg { 121 | background: $boolean; 122 | } 123 | .slider:hover { 124 | .slider-fg { 125 | background: lighten($boolean, 5%); 126 | } 127 | } 128 | } 129 | } 130 | &.function { 131 | border-left-color: mix($background, $function, 80%); 132 | .c { 133 | .slider-fg { 134 | background: $function; 135 | } 136 | .slider:hover { 137 | .slider-fg { 138 | background: lighten($function, 5%); 139 | } 140 | } 141 | } 142 | } 143 | &.number { 144 | border-left-color: mix($background, $number, 80%); 145 | input[type=text] { 146 | color: $number; 147 | } 148 | .c { 149 | .slider-fg { 150 | background: $number; 151 | } 152 | .slider:hover { 153 | .slider-fg { 154 | background: lighten($number, 5%); 155 | } 156 | } 157 | } 158 | } 159 | &.string { 160 | border-left-color: mix($background, $string, 80%); 161 | input[type=text] { 162 | color: $string; 163 | } 164 | .c { 165 | .slider-fg { 166 | background: $string; 167 | } 168 | .slider:hover { 169 | .slider-fg { 170 | background: lighten($string, 5%); 171 | } 172 | } 173 | } 174 | } 175 | &.function:hover, 176 | &.boolean:hover { 177 | background: var(--vscode-editor-background); 178 | } 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /src/app/services/trails/trails.service.js: -------------------------------------------------------------------------------- 1 | /* global window, document, console */ 2 | 3 | (function () { 4 | 'use strict'; 5 | 6 | var TrailsService = function () { 7 | 8 | function TrailsService() { 9 | var service = this; 10 | service.mouse = new Float32Array([0.0, 0.0]); 11 | service.history = []; 12 | service.trails = new Array(10).fill(null).map(function () { 13 | return new Float32Array([0.0, 0.0]); 14 | }); 15 | } 16 | 17 | TrailsService.prototype = { 18 | render: render, 19 | move: move, 20 | push: throttle(_push, 1000 / 60), 21 | update: update, 22 | }; 23 | 24 | // statics 25 | 26 | var getNow = Date.now || function () { 27 | return new Date().getTime(); 28 | }; 29 | 30 | function throttle(func, wait, options) { 31 | // Returns a function, that, when invoked, will only be triggered at most once 32 | // during a given window of time. Normally, the throttled function will run 33 | // as much as it can, without ever going more than once per `wait` duration; 34 | // but if you'd like to disable the execution on the leading edge, pass 35 | // `{leading: false}`. To disable execution on the trailing edge, ditto. 36 | var context, args, result; 37 | var timeout = null; 38 | var previous = 0; 39 | if (!options) options = {}; 40 | var later = function () { 41 | previous = options.leading === false ? 0 : getNow(); 42 | timeout = null; 43 | result = func.apply(context, args); 44 | if (!timeout) context = args = null; 45 | }; 46 | return function () { 47 | var now = getNow(); 48 | if (!previous && options.leading === false) previous = now; 49 | var remaining = wait - (now - previous); 50 | context = this; 51 | args = arguments; 52 | if (remaining <= 0 || remaining > wait) { 53 | if (timeout) { 54 | clearTimeout(timeout); 55 | timeout = null; 56 | } 57 | previous = now; 58 | result = func.apply(context, args); 59 | if (!timeout) context = args = null; 60 | } else if (!timeout && options.trailing !== false) { 61 | timeout = setTimeout(later, remaining); 62 | } 63 | return result; 64 | }; 65 | } 66 | 67 | // publics 68 | 69 | var ti = 0; 70 | 71 | function render(glsl) { 72 | var service = this; 73 | var trails = service.trails, 74 | history = service.history, 75 | mouse = service.mouse; 76 | 77 | var i = 0, 78 | t = trails.length; 79 | var tx = history.length ? history[0] : mouse; 80 | while (i < t) { 81 | var e = (i > 0 ? trails[i - 1] : tx); 82 | var v = trails[i]; 83 | var friction = 1.0 / (5.0 + i); 84 | v[0] += (e[0] - v[0]) * friction; 85 | v[1] += (e[1] - v[1]) * friction; 86 | service.update(glsl, '2fv', 'vec2', 'u_trails[' + i + ']', v); 87 | i++; 88 | } 89 | if (history.length) { 90 | history.shift(); 91 | } 92 | } 93 | 94 | function move(x, y) { 95 | var service = this, 96 | mouse = service.mouse; 97 | mouse[0] = x; 98 | mouse[1] = y; 99 | service.push(); 100 | } 101 | 102 | function _push() { 103 | var service = this; 104 | service.history.push(new Float32Array(service.mouse)); 105 | } 106 | 107 | function update(glsl, method, type, name, value) { 108 | try { 109 | var u = glsl.uniforms[name] = glsl.uniforms[name] || {}; 110 | u.name = name; 111 | u.value = value; 112 | u.type = type; 113 | u.method = 'uniform' + method; 114 | u.location = glsl.gl.getUniformLocation(glsl.program, name); 115 | glsl.gl[u.method].apply(glsl.gl, [u.location].concat(u.value)); 116 | } catch (e) { 117 | console.log('TrailsService.update.error', e); 118 | } 119 | } 120 | 121 | return TrailsService; 122 | }(); 123 | 124 | window.TrailsService = TrailsService; 125 | 126 | }()); 127 | -------------------------------------------------------------------------------- /src/app/services/vars.scss: -------------------------------------------------------------------------------- 1 | // vars 2 | $background: #1e1e1e; 3 | $foreground: #333333; 4 | $errors: #252526; 5 | $error: #e54646; 6 | $warning: #cc6633; 7 | $line: #4ec9b0; 8 | $value: #569cd0; 9 | $text: #d4d4d4; 10 | $tools: #000000; // #333333; 11 | $record: #e54646; 12 | $create: #007acc; 13 | -------------------------------------------------------------------------------- /src/app/services/vector/vector.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | var Vector = function () { 5 | 6 | function Vector(x, y, z) { 7 | this.x = x || 0; 8 | this.y = y || 0; 9 | this.z = z || 0; 10 | } 11 | 12 | // Instance Methods 13 | // The methods add(), subtract(), multiply(), and divide() can all take either a vector or a number as an argument. 14 | 15 | Vector.prototype = { 16 | negative: function () { 17 | return new Vector(-this.x, -this.y, -this.z); 18 | }, 19 | add: function (v) { 20 | if (v instanceof Vector) return new Vector(this.x + v.x, this.y + v.y, this.z + v.z); 21 | else return new Vector(this.x + v, this.y + v, this.z + v); 22 | }, 23 | subtract: function (v) { 24 | if (v instanceof Vector) return new Vector(this.x - v.x, this.y - v.y, this.z - v.z); 25 | else return new Vector(this.x - v, this.y - v, this.z - v); 26 | }, 27 | multiply: function (v) { 28 | if (v instanceof Vector) return new Vector(this.x * v.x, this.y * v.y, this.z * v.z); 29 | else return new Vector(this.x * v, this.y * v, this.z * v); 30 | }, 31 | divide: function (v) { 32 | if (v instanceof Vector) return new Vector(this.x / v.x, this.y / v.y, this.z / v.z); 33 | else return new Vector(this.x / v, this.y / v, this.z / v); 34 | }, 35 | equals: function (v) { 36 | return this.x === v.x && this.y === v.y && this.z === v.z; 37 | }, 38 | dot: function (v) { 39 | return this.x * v.x + this.y * v.y + this.z * v.z; 40 | }, 41 | cross: function (v) { 42 | return new Vector( 43 | this.y * v.z - this.z * v.y, 44 | this.z * v.x - this.x * v.z, 45 | this.x * v.y - this.y * v.x 46 | ); 47 | }, 48 | length: function () { 49 | return Math.sqrt(this.dot(this)); 50 | }, 51 | unit: function () { 52 | return this.divide(this.length()); 53 | }, 54 | min: function () { 55 | return Math.min(Math.min(this.x, this.y), this.z); 56 | }, 57 | max: function () { 58 | return Math.max(Math.max(this.x, this.y), this.z); 59 | }, 60 | toAngles: function () { 61 | return { 62 | theta: Math.atan2(this.z, this.x), 63 | phi: Math.asin(this.y / this.length()) 64 | }; 65 | }, 66 | angleTo: function (a) { 67 | return Math.acos(this.dot(a) / (this.length() * a.length())); 68 | }, 69 | toArray: function (n) { 70 | return [this.x, this.y, this.z].slice(0, n || 3); 71 | }, 72 | clone: function () { 73 | return new Vector(this.x, this.y, this.z); 74 | }, 75 | init: function (x, y, z) { 76 | this.x = x; 77 | this.y = y; 78 | this.z = z; 79 | return this; 80 | } 81 | }; 82 | 83 | // Static Methods 84 | // Vector.randomDirection() returns a vector with a length of 1 and a statistically uniform direction. Vector.lerp() performs linear interpolation between two vectors. 85 | 86 | Vector.negative = function (a, b) { 87 | b.x = -a.x; 88 | b.y = -a.y; 89 | b.z = -a.z; 90 | return b; 91 | }; 92 | Vector.add = function (a, b, c) { 93 | if (b instanceof Vector) { 94 | c.x = a.x + b.x; 95 | c.y = a.y + b.y; 96 | c.z = a.z + b.z; 97 | } else { 98 | c.x = a.x + b; 99 | c.y = a.y + b; 100 | c.z = a.z + b; 101 | } 102 | return c; 103 | }; 104 | Vector.subtract = function (a, b, c) { 105 | if (b instanceof Vector) { 106 | c.x = a.x - b.x; 107 | c.y = a.y - b.y; 108 | c.z = a.z - b.z; 109 | } else { 110 | c.x = a.x - b; 111 | c.y = a.y - b; 112 | c.z = a.z - b; 113 | } 114 | return c; 115 | }; 116 | Vector.multiply = function (a, b, c) { 117 | if (b instanceof Vector) { 118 | c.x = a.x * b.x; 119 | c.y = a.y * b.y; 120 | c.z = a.z * b.z; 121 | } else { 122 | c.x = a.x * b; 123 | c.y = a.y * b; 124 | c.z = a.z * b; 125 | } 126 | return c; 127 | }; 128 | Vector.divide = function (a, b, c) { 129 | if (b instanceof Vector) { 130 | c.x = a.x / b.x; 131 | c.y = a.y / b.y; 132 | c.z = a.z / b.z; 133 | } else { 134 | c.x = a.x / b; 135 | c.y = a.y / b; 136 | c.z = a.z / b; 137 | } 138 | return c; 139 | }; 140 | Vector.cross = function (a, b, c) { 141 | c.x = a.y * b.z - a.z * b.y; 142 | c.y = a.z * b.x - a.x * b.z; 143 | c.z = a.x * b.y - a.y * b.x; 144 | return c; 145 | }; 146 | Vector.unit = function (a, b) { 147 | var length = a.length(); 148 | b.x = a.x / length; 149 | b.y = a.y / length; 150 | b.z = a.z / length; 151 | return b; 152 | }; 153 | Vector.fromAngles = function (theta, phi) { 154 | return new Vector(Math.cos(theta) * Math.cos(phi), Math.sin(phi), Math.sin(theta) * Math.cos(phi)); 155 | }; 156 | Vector.randomDirection = function () { 157 | return Vector.fromAngles(Math.random() * Math.PI * 2, Math.asin(Math.random() * 2 - 1)); 158 | }; 159 | Vector.min = function (a, b) { 160 | return new Vector(Math.min(a.x, b.x), Math.min(a.y, b.y), Math.min(a.z, b.z)); 161 | }; 162 | Vector.max = function (a, b) { 163 | return new Vector(Math.max(a.x, b.x), Math.max(a.y, b.y), Math.max(a.z, b.z)); 164 | }; 165 | Vector.lerp = function (a, b, fraction) { 166 | return b.subtract(a).multiply(fraction).add(a); 167 | }; 168 | Vector.fromArray = function (a) { 169 | return new Vector(a[0], a[1], a[2]); 170 | }; 171 | Vector.angleBetween = function (a, b) { 172 | return a.angleTo(b); 173 | }; 174 | 175 | return Vector; 176 | }(); 177 | 178 | window.Vector = Vector; 179 | 180 | }()); -------------------------------------------------------------------------------- /src/docs/docs.js: -------------------------------------------------------------------------------- 1 | /* global window, document, console, GlslEditor, CameraService, TrailsService */ 2 | 3 | (function () { 4 | 'use strict'; 5 | 6 | var camera = new CameraService(); 7 | 8 | var trails = new TrailsService(); 9 | 10 | init(); 11 | 12 | function init() { 13 | var frag_header = ''; 14 | getResource("playgrounds/lib.glsl", function (data) { 15 | frag_header = data; 16 | var qso = getQuerystring(); 17 | var resource = qso.glsl || 'main'; 18 | getResource('playgrounds/' + resource + '.glsl', function (data) { 19 | var editorNode = document.querySelector('.editor'); 20 | editorNode.innerHTML = data; 21 | var editor = new GlslEditor(editorNode, { 22 | canvas_size: 400, 23 | canvas_draggable: true, 24 | fileDrops: false, 25 | frag_header: frag_header, 26 | menu: false, 27 | multipleBuffers: false, 28 | theme: 'monokai', 29 | watchHash: false, 30 | }); 31 | // console.log('editor', editor); 32 | var glsl = editor.shader.canvas; 33 | glsl.on('render', function () { 34 | trails.render(glsl); 35 | camera.render(glsl); 36 | glsl.forceRender = true; 37 | }); 38 | glsl.on('load', function () { 39 | glsl.uniformTexture('u_texture_0', 'https://rawgit.com/actarian/plausible-brdf-shader/master/textures/noise/cloud-1.png', { 40 | filtering: 'mipmap', 41 | repeat: true, 42 | }); 43 | }); 44 | 45 | function onDown(e) { 46 | var min = Math.min(glsl.canvas.offsetWidth, glsl.canvas.offsetHeight); 47 | camera.down(e.x / min, e.y / min); 48 | } 49 | 50 | function onMove(e) { 51 | var min = Math.min(glsl.canvas.offsetWidth, glsl.canvas.offsetHeight); 52 | camera.move(e.x / min, e.y / min); 53 | trails.move(e.x, glsl.canvas.offsetHeight - e.y); 54 | } 55 | 56 | function onUp(e) { 57 | var min = Math.min(glsl.canvas.offsetWidth, glsl.canvas.offsetHeight); 58 | camera.up(e.x / min, e.y / min); 59 | } 60 | 61 | function onWheel(e) { 62 | camera.wheel(e.wheelDelta / Math.abs(e.wheelDelta)); 63 | } 64 | 65 | glsl.canvas.addEventListener('mousedown', onDown); 66 | glsl.canvas.addEventListener('mousemove', onMove); 67 | window.addEventListener('mouseup', onUp); 68 | window.addEventListener('mousewheel', onWheel); 69 | 70 | glsl.canvas.addEventListener('mousemove', function onMove(e) { 71 | trails.move(e.x - editor.shader.el.offsetLeft, editor.shader.el.offsetTop + editor.shader.el.offsetHeight - e.y); 72 | }); 73 | }); 74 | // var nodes = document.querySelectorAll('code'); 75 | // forEach(nodes, function (i, node) { }); 76 | }); 77 | } 78 | 79 | function forEach(array, callback, scope) { 80 | for (var i = 0; i < array.length; i++) { 81 | callback.call(scope, i, array[i]); // passes back stuff we need 82 | } 83 | } 84 | 85 | function getResource(url, callback) { 86 | var request = new XMLHttpRequest(); 87 | request.open('GET', url, true); 88 | request.addEventListener('load', function () { 89 | callback(request.responseText); 90 | }); 91 | request.send(); 92 | } 93 | 94 | function getQuerystring() { 95 | var q = (function (list) { 96 | if (list == '') return {}; 97 | var dict = {}; 98 | for (var i = 0; i < list.length; ++i) { 99 | var kv = list[i].split('=', 2); 100 | if (kv.length == 1) { 101 | dict[kv[0]] = ''; 102 | } else { 103 | dict[kv[0]] = decodeURIComponent(kv[1].replace(/\+/g, ' ')); 104 | } 105 | } 106 | return dict; 107 | })(window.location.search.substr(1).split('&')); 108 | return q; 109 | } 110 | 111 | }()); -------------------------------------------------------------------------------- /src/docs/docs.scss: -------------------------------------------------------------------------------- 1 | body { 2 | height: 100%; 3 | margin: 0; 4 | background: #171717; 5 | } 6 | 7 | .editor { 8 | display: block; 9 | height: 100%; 10 | } 11 | 12 | .CodeMirror { 13 | font-size: 13px !important; 14 | font-family: Cousine, Monaco, 'Courier New', monospace !important; 15 | min-height: 100vh; 16 | &.cm-s-monokai { 17 | background: #171717; 18 | color: #d4d4d4; 19 | .CodeMirror-gutters { 20 | background: #171717; 21 | } 22 | span { 23 | &.cm-atom, 24 | &.cm-number { 25 | color: #b5cea8; 26 | } 27 | &.cm-keyword { 28 | color: #9f7ec0; 29 | } 30 | &.cm-comment { 31 | color: #44864e; 32 | } 33 | &.cm-variable-3 { 34 | color: #569cd6; 35 | } 36 | &.cm-variable { 37 | color: #dcd98a; 38 | } 39 | } 40 | } 41 | } 42 | 43 | .CodeMirror-scroll { 44 | overflow: auto !important; 45 | } 46 | 47 | .CodeMirror-linenumber.CodeMirror-gutter-elt { 48 | color: #5a5a5a; 49 | } 50 | 51 | .btn { 52 | display: none; 53 | position: fixed; 54 | bottom: 20px; 55 | right: 20px; 56 | z-index: 100; 57 | padding: 8px; 58 | border-radius: 5px; 59 | text-decoration: none; 60 | font-family: Arial, Helvetica, sans-serif; 61 | font-size: 14px; 62 | background: #272727; 63 | color: white; 64 | } 65 | 66 | @media screen and (min-width: 960px) { 67 | body { 68 | padding: 20px; 69 | } 70 | 71 | .CodeMirror { 72 | min-height: calc(100vh - 40px); 73 | } 74 | 75 | .btn { 76 | display: block; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/glsl/color.provider.ts: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | import * as vscode from 'vscode'; 5 | 6 | export default class GlslColorProvider implements vscode.DocumentColorProvider { 7 | 8 | static trim(n: number): string { 9 | const c = n.toFixed(4).replace(/(0*$)/, ''); 10 | return c + (c.lastIndexOf('.') === c.length - 1 ? '0' : ''); 11 | // return n.toFixed(7).replace(/(? { 15 | const regexp = /vec[3|4]\s*\(([0-9|.|,|\s]*)\)/gm; 16 | const colors = []; 17 | let match; 18 | while ((match = regexp.exec(document.getText())) !== null) { 19 | const l = match[0].indexOf('vec3') === 0 ? 3 : 4; 20 | const components = match[1].split(',').map((c: string) => parseFloat(c)); 21 | const isColor = (components.length === 1 || components.length === l) && components.reduce((f: boolean, c: number) => { 22 | return f && c >= 0.0 && c <= 1.0; 23 | }, true); 24 | if (isColor) { 25 | if (components.length === 1) { 26 | while (components.length < l) { 27 | components.push(components[0]); 28 | } 29 | } 30 | if (components.length === 3) { 31 | components.push(1.0); 32 | } 33 | if (components.length === 4) { 34 | const color = new vscode.ColorInformation( 35 | new vscode.Range( 36 | document.positionAt(match.index), 37 | document.positionAt(match.index + match[0].length) 38 | ), 39 | new vscode.Color(components[0], components[1], components[2], components[3]), 40 | ); 41 | colors.push(color); 42 | } 43 | } 44 | } 45 | return Promise.resolve(colors); 46 | } 47 | 48 | public provideColorPresentations(color: vscode.Color, context: { document: vscode.TextDocument, range: vscode.Range }, token: vscode.CancellationToken): Thenable { 49 | if (context.document.getText(context.range).indexOf('vec3') === 0) { 50 | return Promise.resolve([new vscode.ColorPresentation(`vec3(${GlslColorProvider.trim(color.red)}, ${GlslColorProvider.trim(color.green)}, ${GlslColorProvider.trim(color.blue)})`)]); 51 | } else { 52 | return Promise.resolve([new vscode.ColorPresentation(`vec4(${GlslColorProvider.trim(color.red)}, ${GlslColorProvider.trim(color.green)}, ${GlslColorProvider.trim(color.blue)}, ${GlslColorProvider.trim(color.alpha)})`)]); 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/glsl/common.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import * as vscode from 'vscode'; 4 | 5 | const LANGUAGES = ['glsl', 'cpp', 'c']; 6 | 7 | export function isGlslLanguage(languageId: string): boolean { 8 | return LANGUAGES.indexOf(languageId) !== -1; 9 | } 10 | 11 | let lastGlslEditor: null | vscode.TextEditor = null; 12 | 13 | export function currentGlslEditor(): vscode.TextEditor | null { 14 | const editor: vscode.TextEditor = vscode.window.activeTextEditor; 15 | // console.log('Common.currentGlslEditor', editor ? editor.document : null); 16 | if (editor && isGlslLanguage(editor.document.languageId)) { 17 | lastGlslEditor = editor; 18 | } 19 | // Just return the last valid editor we've seen 20 | return lastGlslEditor; 21 | } 22 | 23 | export function currentGlslDocument(): vscode.TextDocument { 24 | const editor: vscode.TextEditor = currentGlslEditor(); 25 | return editor ? editor.document : null; 26 | } 27 | -------------------------------------------------------------------------------- /src/glsl/editor.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import * as fs from 'fs'; 4 | import * as path from 'path'; 5 | import * as vscode from 'vscode'; 6 | 7 | export const DefaultFragment = /* glsl */` 8 | #extension GL_OES_standard_derivatives : enable 9 | 10 | #ifdef GL_ES 11 | precision mediump float; 12 | #endif 13 | 14 | varying vec4 v_position; 15 | varying vec4 v_normal; 16 | varying vec2 v_texcoord; 17 | varying vec4 v_color; 18 | 19 | uniform mat4 u_projectionMatrix; 20 | uniform mat4 u_modelViewMatrix; 21 | uniform mat4 u_normalMatrix; 22 | uniform vec2 u_resolution; 23 | uniform float u_time; 24 | 25 | #if defined(VERTEX) 26 | 27 | // attribute vec4 a_position; // myfolder/myfile.obj 28 | attribute vec4 a_position; 29 | attribute vec4 a_normal; 30 | attribute vec2 a_texcoord; 31 | attribute vec4 a_color; 32 | 33 | void main(void) { 34 | v_position = u_projectionMatrix * u_modelViewMatrix * a_position; 35 | v_normal = u_normalMatrix * a_normal; 36 | v_texcoord = a_texcoord; 37 | v_color = a_color; 38 | gl_Position = v_position; 39 | } 40 | 41 | #else // fragment shader 42 | 43 | uniform vec2 u_mouse; 44 | uniform vec2 u_pos; 45 | // uniform sampler2D u_texture; // https://cdn.jsdelivr.net/gh/actarian/plausible-brdf-shader/textures/mars/4096x2048/diffuse.jpg?repeat=true 46 | // uniform vec2 u_textureResolution; 47 | 48 | float checker(vec2 uv, float repeats) { 49 | float cx = floor(repeats * uv.x); 50 | float cy = floor(repeats * uv.y); 51 | float result = mod(cx + cy, 2.0); 52 | return sign(result); 53 | } 54 | 55 | void main() { 56 | vec2 p = v_texcoord; 57 | 58 | vec3 ambient = vec3(0.4); 59 | vec3 direction = vec3(0.0, 1.0, 1.0); 60 | vec3 lightColor = vec3(1.0); 61 | float incidence = max(dot(v_normal.xyz, direction), - 1.0); 62 | vec3 light = clamp(ambient + lightColor * incidence, 0.0, 1.0); 63 | 64 | vec3 color = (0.2 * checker(p, 8.0) + v_normal.rgb); 65 | gl_FragColor = vec4(color * light, 1.0); 66 | } 67 | 68 | #endif 69 | `; 70 | 71 | const DefaultFragment_old = /* glsl */` 72 | #ifdef GL_ES 73 | precision mediump float; 74 | #endif 75 | 76 | uniform vec2 u_resolution; 77 | uniform vec2 u_mouse; 78 | uniform float u_time; 79 | 80 | #define PI_TWO 1.570796326794897 81 | #define PI 3.141592653589793 82 | #define TWO_PI 6.283185307179586 83 | 84 | vec2 coord(in vec2 p) { 85 | p = p / u_resolution.xy; 86 | // correct aspect ratio 87 | if (u_resolution.x > u_resolution.y) { 88 | p.x *= u_resolution.x / u_resolution.y; 89 | p.x += (u_resolution.y - u_resolution.x) / u_resolution.y / 2.0; 90 | } else { 91 | p.y *= u_resolution.y / u_resolution.x; 92 | p.y += (u_resolution.x - u_resolution.y) / u_resolution.x / 2.0; 93 | } 94 | // centering 95 | p -= 0.5; 96 | p *= vec2(-1.0, 1.0); 97 | return p; 98 | } 99 | #define rx 1.0 / min(u_resolution.x, u_resolution.y) 100 | #define uv gl_FragCoord.xy / u_resolution.xy 101 | #define st coord(gl_FragCoord.xy) 102 | #define mx coord(u_mouse) 103 | 104 | void main() { 105 | vec3 color = vec3( 106 | abs(cos(st.x + mx.x)), 107 | abs(sin(st.y + mx.y)), 108 | abs(sin(u_time)) 109 | ); 110 | gl_FragColor = vec4(color, 1.0); 111 | } 112 | `; 113 | 114 | export default class GlslEditor { 115 | 116 | static create(): Promise { 117 | return new Promise((resolve, reject) => { 118 | /* 119 | if (!vscode.workspace.rootPath) { 120 | return vscode.window.showErrorMessage('No project currently open!'); 121 | } 122 | */ 123 | const folder: string = vscode.workspace.rootPath || ''; 124 | // console.log('GlslEditor.onCreateShader', folder); 125 | let newFile = vscode.Uri.parse('untitled:' + path.join(folder, 'untitled.glsl')); 126 | let i = 1; 127 | while (fs.existsSync(newFile.fsPath)) { 128 | newFile = vscode.Uri.parse('untitled:' + path.join(folder, 'untitled' + i + '.glsl')); 129 | i++; 130 | } 131 | vscode.workspace.openTextDocument(newFile).then( 132 | document => { 133 | // console.log('GlslEditor.document', document); 134 | const edit = new vscode.WorkspaceEdit(); 135 | edit.insert(newFile, new vscode.Position(0, 0), DefaultFragment); 136 | return vscode.workspace.applyEdit(edit).then( 137 | success => { 138 | if (success) { 139 | vscode.window.showTextDocument(document, vscode.ViewColumn.One).then( 140 | success => { 141 | resolve(document); 142 | }, 143 | error => { 144 | reject(error); 145 | } 146 | ); 147 | } else { 148 | reject('Error!'); 149 | } 150 | }, 151 | error => { 152 | console.log('GlslEditor.onCreateShader.applyEdit', error); 153 | reject(error); 154 | }); 155 | }, 156 | error => { 157 | console.log('GlslEditor.onCreateShader.openTextDocument', error); 158 | reject(error); 159 | }); 160 | }); 161 | } 162 | 163 | } 164 | -------------------------------------------------------------------------------- /src/glsl/format.provider.ts: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | import * as vscode from 'vscode'; 5 | 6 | export default class GlslFormatProvider implements vscode.DocumentFormattingEditProvider { 7 | 8 | // alt + shift + F = format 9 | // alt + shift + C = compact 10 | // Author: Name 11 | 12 | provideDocumentFormattingEdits(document: vscode.TextDocument, options: vscode.FormattingOptions, token: vscode.CancellationToken): vscode.ProviderResult { 13 | const range = new vscode.Range( 14 | document.lineAt(0).range.start, 15 | document.lineAt(document.lineCount - 1).range.end 16 | ); 17 | return this.provideDocumentRangeFormattingEdits(document, range, options, token); 18 | } 19 | 20 | provideDocumentRangeFormattingEdits(document: vscode.TextDocument, range: vscode.Range, options: vscode.FormattingOptions, token: vscode.CancellationToken): vscode.ProviderResult { 21 | const config = vscode.workspace.getConfiguration('glsl-canvas'); 22 | // console.log('GlslFormatProvider.config', config); 23 | const format = config['useFormatter']; 24 | const compact = config['useCompactFormatter']; 25 | if (format) { 26 | let text = document.getText(range); 27 | const tab = options.insertSpaces ? new Array(options.tabSize).fill(' ').join('') : '\t'; 28 | const comments = text.match(/(\/\/.*$)|(\/\*[\s\S]*\*\/)|(#include\s*".*")|(#include\s*'.*')/gm); 29 | const splitByComments = /\/\/.*$|\/\*[\s\S]*\*\/|#include\s*".*"|#include\s*'.*'/gm; 30 | const splitted = text.split(splitByComments).map(s => { 31 | if (compact) { 32 | // remove double spaces 33 | s = s.replace(/[^\S\n]+/gm, ' '); 34 | // trim 35 | // s = s.replace(/^[^\S\n]+|[^\S\n]+$/gm, ''); 36 | /* 37 | // remove start of line space 38 | s = s.replace(/^[^\S\n]+/gm, ''); 39 | // remove end of line space 40 | s = s.replace(/[^\S\n]+$/gm, ''); 41 | */ 42 | // remove extra new line 43 | s = s.replace(/\n\s*\n\s*\n/g, '\n\n'); 44 | // remove space 45 | s = s.replace(/[^\S\n]*(\B)[^\S\n]*/g, '$1'); 46 | // zero 47 | s = s.replace(/(\d)\.0*(\D)/g, '$1.$2'); 48 | s = s.replace(/(\D)0*\.(\d)/g, '$1.$2'); 49 | } else { 50 | // parentesis 51 | s = s.replace(/[^\S\n]*([\(\)\[\]])[^\S\n]*/g, '$1'); 52 | // s = s.replace(/(?\<\!\?\:]+)[^\S\n)]*([^\+\-])/g, '$1 $2 $3'); 55 | // s = s.replace(/([^\(\[])[^\S\n\()]*([\*\+\-\/\=/>/<]+)[^\S\n]*([^\+\-])/g, '$1 $2 $3'); 56 | s = s.replace(/([\,\;])[^\S\n]*/g, '$1 '); 57 | s = s.replace(/[^\S\n]*([/{])/g, ' $1'); 58 | // zero 59 | s = s.replace(/(\B)\.(\d)/g, '$10.$2'); 60 | s = s.replace(/(\d)\.(\B)/g, '$1.0$2'); 61 | // remove double spaces 62 | s = s.replace(/[^\S\n]+/gm, ' '); 63 | // special 64 | s = s.replace(/(if|return)[^\S\n]*([\(\[])/g, '$1 $2'); 65 | // trim 66 | // s = s.replace(/^[^\S\n]+|[^\S\n]+$/gm, ''); 67 | /* 68 | // remove start of line space 69 | s = s.replace(/^[^\S\n]+/gm, ''); 70 | // remove end of line space 71 | s = s.replace(/[^\S\n]+$/gm, ''); 72 | */ 73 | // remove extra new line 74 | s = s.replace(/\n\s*\n\s*\n/g, '\n\n'); 75 | // #pragma 76 | s = s.replace(/[^\S\r\n]*#pragma(.+?)\s*:\s*(\S+)[^\S\r\n]*/g, '#pragma$1:$2'); 77 | } 78 | return s; 79 | }); 80 | text = ''; 81 | while (splitted.length) { 82 | text += splitted.shift() + (comments ? (comments.shift() || '') : ''); 83 | } 84 | // indent blocks 85 | const lines = text.split('\n'); 86 | let i = 0; 87 | text = lines.map(l => { 88 | l = l.trim(); 89 | let a = (l.match(/^[^\{]*\}/g) || []).length; 90 | let b = (l.match(/^[^\(]*\)/g) || []).length; 91 | let c = (l.match(/^[^\[]*\]/g) || []).length; 92 | i -= (a + b + c); 93 | if (i > 0) { 94 | l = new Array(i).fill(tab).join('') + l; 95 | } 96 | a = (l.match(/\{(?!.*\})/g) || []).length; 97 | b = (l.match(/\((?!.*\))/g) || []).length; 98 | c = (l.match(/\[(?!.*\])/g) || []).length; 99 | i += (a + b + c); 100 | return l; 101 | }).join('\n'); 102 | return [vscode.TextEdit.replace(range, text)]; 103 | } else { 104 | return undefined; 105 | } 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/glsl/options.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import * as path from 'path'; 4 | import * as vscode from 'vscode'; 5 | import { currentGlslDocument } from './common'; 6 | 7 | export const WORKPATH_SCHEME: string = 'vscode-webview-resource:'; // 'vscode-webview-resource': 8 | 9 | export default class GlslOptions { 10 | 11 | public uri: vscode.Uri; 12 | public workspaceFolder: string; 13 | public workpath: string; 14 | public folder: string; 15 | public resources: string; 16 | public fragment: string; 17 | public vertex: string; 18 | public uniforms: object; 19 | public textures: object; 20 | public timeout: number; 21 | public extensions: string[]; 22 | public antialias: boolean; 23 | public doubleSided: boolean; 24 | public refreshOnChange: boolean; 25 | public refreshOnSave: boolean; 26 | public recordMethod: string; 27 | public recordDuration: number; 28 | public recordWidth: number; 29 | public recordHeight: number; 30 | public mode?: 'mesh' | 'torus' | 'spere' | 'box' | 'flat'; 31 | 32 | constructor(webview: vscode.Webview = null, extensionPath: string = null) { 33 | const document: vscode.TextDocument = currentGlslDocument(); 34 | const config = vscode.workspace.getConfiguration('glsl-canvas'); 35 | const uri = document ? document.uri : null; 36 | const workspaceFolder = this.getWorkspaceFolder_(); 37 | const textures = Object.assign({}, config['textures'] || {}); 38 | this.uri = uri; 39 | this.workspaceFolder = workspaceFolder; 40 | this.fragment = document ? document.getText() : ''; 41 | this.vertex = ''; 42 | this.textures = textures; 43 | this.uniforms = config['uniforms'] || {}; 44 | this.timeout = config['timeout'] || 0; 45 | this.extensions = config['extensions'] || []; 46 | this.antialias = config['antialias'] || false; 47 | this.doubleSided = config['doubleSided'] || false; 48 | this.refreshOnChange = config['refreshOnChange'] || false; 49 | this.refreshOnSave = config['refreshOnSave'] || false; 50 | this.recordMethod = config['recordMethod'] || 'MediaRecorder'; 51 | // tslint:disable-next-line: triple-equals 52 | this.recordDuration = config['recordDuration'] != null ? config['recordDuration'] : 10; 53 | // tslint:disable-next-line: triple-equals 54 | this.recordWidth = config['recordWidth'] != null ? config['recordWidth'] : 1024; 55 | // tslint:disable-next-line: triple-equals 56 | this.recordHeight = config['recordHeight'] != null ? config['recordHeight'] : 1024; 57 | if (webview !== null && extensionPath !== null) { 58 | const workpath = this.getWorkpath_(webview, extensionPath, workspaceFolder, uri); 59 | const folder = this.getFolder_(extensionPath, workspaceFolder, uri); 60 | const resources = this.getResources_(webview, extensionPath); 61 | Object.keys(textures).forEach(key => { 62 | let texture = textures[key]; 63 | if (texture.indexOf('http') === -1) { 64 | if (workspaceFolder) { 65 | texture = path.join(workspaceFolder, texture); 66 | texture = path.relative(folder, texture); 67 | } else { 68 | texture = path.join(folder, texture); 69 | } 70 | } 71 | textures[key] = texture; 72 | }); 73 | this.workpath = workpath; 74 | this.folder = folder; 75 | this.resources = resources; 76 | } 77 | // console.log('GlslOptions', this); 78 | } 79 | 80 | public serialize(): string { 81 | return JSON.stringify(this); 82 | } 83 | 84 | private getWorkspaceFolder_(): string { 85 | return vscode.workspace && vscode.workspace.workspaceFolders ? vscode.workspace.workspaceFolders[0].uri.path : null; 86 | } 87 | 88 | private getWorkpath_(webview: vscode.Webview, extensionPath: string, workspaceFolder?:string, uri?: vscode.Uri): string { 89 | let url: string; 90 | const folder = uri ? path.dirname(uri.path) : workspaceFolder; 91 | if (folder) { 92 | uri = webview.asWebviewUri(vscode.Uri.file(folder)); 93 | } else { 94 | uri = vscode.Uri.file(path.join(extensionPath, 'resources')); 95 | } 96 | url = uri.scheme + '://' + uri.authority + uri.path; 97 | // console.log('GlslOptions.getWorkpath', url); 98 | return url; 99 | } 100 | 101 | private getFolder_(extensionPath: string, workspaceFolder?:string, uri?: vscode.Uri): string { 102 | let url: string; 103 | const folder = uri ? path.dirname(uri.path) : workspaceFolder; 104 | if (folder) { 105 | url = folder; 106 | } else { 107 | url = path.join(extensionPath, 'resources'); 108 | } 109 | // console.log('GlslOptions.getFolder', url); 110 | return url; 111 | } 112 | 113 | private getResources_(webview: vscode.Webview, extensionPath: string): string { 114 | const filePath = vscode.Uri.file( 115 | path.join(extensionPath, 'resources') 116 | ); 117 | const uri: vscode.Uri = webview.asWebviewUri(filePath); 118 | const url: string = uri.scheme + '://' + uri.authority + uri.path; 119 | // console.log('GlslOptions.getResources', url); 120 | return url; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/src/icon.png -------------------------------------------------------------------------------- /src/icon.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/src/icon.psd -------------------------------------------------------------------------------- /src/previews/01-main.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/src/previews/01-main.gif -------------------------------------------------------------------------------- /src/previews/01-mode.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/src/previews/01-mode.gif -------------------------------------------------------------------------------- /src/previews/02-picker.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/src/previews/02-picker.gif -------------------------------------------------------------------------------- /src/previews/03-camera.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/src/previews/03-camera.gif -------------------------------------------------------------------------------- /src/previews/04-trails.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/src/previews/04-trails.gif -------------------------------------------------------------------------------- /src/previews/05-uniforms.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/src/previews/05-uniforms.gif -------------------------------------------------------------------------------- /src/previews/06-buffers.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/src/previews/06-buffers.gif -------------------------------------------------------------------------------- /src/previews/07-export.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/src/previews/07-export.gif -------------------------------------------------------------------------------- /src/previews/08-format.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actarian/vscode-glsl-canvas/a4006a873325c58fc71b58ce4375f4e3b48c458d/src/previews/08-format.gif -------------------------------------------------------------------------------- /src/snippets/animation.glsl: -------------------------------------------------------------------------------- 1 | /* Staggered animation */ 2 | struct Animation { float time; float pow; }; 3 | Animation animation = Animation(0.0, 0.0); 4 | void totalTime(in float t, in float offset) { animation.time = mod(u_time + offset, t); } 5 | void totalTime(in float t) { totalTime(t, 0.0); } 6 | bool between(in float duration, in float offset) { 7 | float p = (animation.time - offset) / duration; 8 | animation.pow = p; 9 | animation.time -= (duration + offset); 10 | return (p >= 0.0 && p <= 1.0); 11 | } 12 | bool between(in float duration) { return between(duration, 0.0); } -------------------------------------------------------------------------------- /src/snippets/colors.glsl: -------------------------------------------------------------------------------- 1 | /* Color palette */ 2 | #define BLACK vec3(0.0, 0.0, 0.0) 3 | #define WHITE vec3(1.0, 1.0, 1.0) 4 | #define RED vec3(1.0, 0.0, 0.0) 5 | #define GREEN vec3(0.0, 1.0, 0.0) 6 | #define BLUE vec3(0.0, 0.0, 1.0) 7 | #define YELLOW vec3(1.0, 1.0, 0.0) 8 | #define CYAN vec3(0.0, 1.0, 1.0) 9 | #define MAGENTA vec3(1.0, 0.0, 1.0) 10 | #define ORANGE vec3(1.0, 0.5, 0.0) 11 | #define PURPLE vec3(1.0, 0.0, 0.5) 12 | #define LIME vec3(0.5, 1.0, 0.0) 13 | #define ACQUA vec3(0.0, 1.0, 0.5) 14 | #define VIOLET vec3(0.5, 0.0, 1.0) 15 | #define AZUR vec3(0.0, 0.5, 1.0) -------------------------------------------------------------------------------- /src/snippets/coords.glsl: -------------------------------------------------------------------------------- 1 | /* Coordinate and unit utils */ 2 | vec2 coord(in vec2 p) { 3 | p = p / u_resolution.xy; 4 | // correct aspect ratio 5 | if (u_resolution.x > u_resolution.y) { 6 | p.x *= u_resolution.x / u_resolution.y; 7 | p.x += (u_resolution.y - u_resolution.x) / u_resolution.y / 2.0; 8 | } else { 9 | p.y *= u_resolution.y / u_resolution.x; 10 | p.y += (u_resolution.x - u_resolution.y) / u_resolution.x / 2.0; 11 | } 12 | // centering 13 | p -= 0.5; 14 | p *= vec2(-1.0, 1.0); 15 | return p; 16 | } 17 | #define rx 1.0 / min(u_resolution.x, u_resolution.y) 18 | #define uv gl_FragCoord.xy / u_resolution.xy 19 | #define st coord(gl_FragCoord.xy) 20 | #define mx coord(u_mouse) -------------------------------------------------------------------------------- /src/snippets/drawing.glsl: -------------------------------------------------------------------------------- 1 | /* Signed distance drawing methods */ 2 | float fill(in float d) { return 1.0 - smoothstep(0.0, rx * 2.0, d); } 3 | float stroke(in float d, in float t) { return 1.0 - smoothstep(t - rx * 1.5, t + rx * 1.5, abs(d)); } 4 | vec3 draw(in sampler2D t, in vec2 pos, in vec2 w) { vec2 s = w / 1.0; s.x *= -1.0; return texture2D(t, pos / s + 0.5).rgb; } 5 | /* Field Adapted from https://www.shadertoy.com/view/XsyGRW */ 6 | vec3 field(float d) { 7 | const vec3 c1 = mix(WHITE, YELLOW, 0.4); 8 | const vec3 c2 = mix(WHITE, AZUR, 0.7); 9 | const vec3 c3 = mix(WHITE, ORANGE, 0.9); 10 | const vec3 c4 = BLACK; 11 | float d0 = abs(stroke(mod(d + 0.1, 0.2) - 0.1, 0.004)); 12 | float d1 = abs(stroke(mod(d + 0.025, 0.05) - 0.025, 0.004)); 13 | float d2 = abs(stroke(d, 0.004)); 14 | float f = clamp(d * 0.85, 0.0, 1.0); 15 | vec3 gradient = mix(c1, c2, f); 16 | gradient = mix(gradient, c4, 1.0 - clamp(1.25 - d * 0.25, 0.0, 1.0)); 17 | gradient = mix(gradient, c3, fill(d)); 18 | gradient = mix(gradient, c4, max(d2 * 0.85, max(d0 * 0.25, d1 * 0.06125)) * clamp(1.25 - d, 0.0, 1.0)); 19 | return gradient; 20 | } -------------------------------------------------------------------------------- /src/snippets/ease/back/in.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Back In equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeBackIn(float t) { 4 | float s = 1.70158; 5 | return t * t * ((s + 1.0) * t - s); 6 | } -------------------------------------------------------------------------------- /src/snippets/ease/back/inOut.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Back InOut equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeBackInOut(float t) { 4 | t *= 2.0; float s = 1.70158; 5 | if (t < 1.0) return 0.5 * (t * t * (((s *= (1.525)) + 1.0) * t - s)); 6 | return 0.5 * ((t -= 2.0) * t * (((s *= (1.525)) + 1.0) * t + s) + 2.0); 7 | } -------------------------------------------------------------------------------- /src/snippets/ease/back/out.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Back Out equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeBackOut(float t) { 4 | float s = 1.70158; 5 | return ((t = t - 1.0) * t * ((s + 1.0) * t + s) + 1.0); 6 | } -------------------------------------------------------------------------------- /src/snippets/ease/bounce/in.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Bounce In equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeBounceOut(float t) { 4 | if (t < (1.0 / 2.75)) { 5 | return (7.5625 * t * t); 6 | } else if (t < (2.0 / 2.75)) { 7 | return (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75); 8 | } else if (t < (2.5 / 2.75)) { 9 | return (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375); 10 | } else { 11 | return (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375); 12 | } 13 | } 14 | float easeBounceIn(float t) { 15 | return 1.0 - easeBounceOut(1.0 - t); 16 | } -------------------------------------------------------------------------------- /src/snippets/ease/bounce/inOut.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Bounce InOut equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeBounceOut(float t) { 4 | if (t < (1.0 / 2.75)) { 5 | return (7.5625 * t * t); 6 | } else if (t < (2.0 / 2.75)) { 7 | return (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75); 8 | } else if (t < (2.5 / 2.75)) { 9 | return (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375); 10 | } else { 11 | return (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375); 12 | } 13 | } 14 | float easeBounceIn(float t) { 15 | return 1.0 - easeBounceOut(1.0 - t); 16 | } 17 | float easeBounceInOut(float t) { 18 | if (t < 0.5) return easeBounceIn(t * 2.0) * 0.5; 19 | else return easeBounceOut(t * 2.0 - 1.0) * 0.5 + 0.5; 20 | } -------------------------------------------------------------------------------- /src/snippets/ease/bounce/out.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Bounce Out equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeBounceOut(float t) { 4 | if (t < (1.0 / 2.75)) { 5 | return (7.5625 * t * t); 6 | } else if (t < (2.0 / 2.75)) { 7 | return (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75); 8 | } else if (t < (2.5 / 2.75)) { 9 | return (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375); 10 | } else { 11 | return (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375); 12 | } 13 | } -------------------------------------------------------------------------------- /src/snippets/ease/circular/in.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Circular In equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeCircularIn(float t) { 4 | return -1.0 * (sqrt(1.0 - t * t) - 1.0); 5 | } -------------------------------------------------------------------------------- /src/snippets/ease/circular/inOut.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Circular InOut equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeCircularInOut(float t) { 4 | t = t * 2.0; if ((t) < 1.0) return -0.5 * (sqrt(1.0 - t * t) - 1.0); 5 | return 0.5 * (sqrt(1.0 - (t -= 2.0) * t) + 1.0); 6 | } -------------------------------------------------------------------------------- /src/snippets/ease/circular/out.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Circular Out equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeCircularOut(float t) { 4 | return sqrt(1.0 - (t = t - 1.0) * t); 5 | } -------------------------------------------------------------------------------- /src/snippets/ease/cubic/in.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Cubic In equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeCubicIn(float t) { 4 | return t * t * t; 5 | } -------------------------------------------------------------------------------- /src/snippets/ease/cubic/inOut.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Cubic InOut equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeCubicInOut(float t) { 4 | t = t * 2.0; if (t < 1.0) return 0.5 * t * t * t; 5 | return 0.5 * ((t -= 2.0) * t * t + 2.0); 6 | } -------------------------------------------------------------------------------- /src/snippets/ease/cubic/out.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Cubic Out equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeCubicOut(float t) { 4 | return ((t = t - 1.0) * t * t + 1.0); 5 | } -------------------------------------------------------------------------------- /src/snippets/ease/elastic/in.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Elastic In equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | #define TWO_PI 6.283185307179586 4 | float easeElasticIn(float t) { 5 | if (t == 0.0) { return 0.0; } 6 | if (t == 1.0) { return 1.0; } 7 | float p = 0.3; 8 | float a = 1.0; 9 | float s = p / 4.0; 10 | return -(a * pow(2.0, 10.0 * (t -= 1.0)) * sin((t - s) * TWO_PI / p)); 11 | } -------------------------------------------------------------------------------- /src/snippets/ease/elastic/inOut.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Elastic InOut equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | #define TWO_PI 6.283185307179586 4 | float easeElasticInOut(float t) { 5 | t = t * 2.0; 6 | if (t == 0.0) { return 0.0; } 7 | if ((t / 2.0) == 2.0) { return 1.0; } 8 | float p = (0.3 * 1.5); 9 | float a = 1.0; 10 | float s = p / 4.0; 11 | if (t < 1.0) { 12 | return -0.5 * (a * pow(2.0, 10.0 * (t -= 1.0)) * sin((t - s) * TWO_PI / p)); 13 | } 14 | return a * pow(2.0, -10.0 * (t -= 1.0)) * sin((t - s) * TWO_PI / p) * 0.5 + 1.0; 15 | } -------------------------------------------------------------------------------- /src/snippets/ease/elastic/out.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Elastic Out equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | #define TWO_PI 6.283185307179586 4 | float easeElasticOut(float t) { 5 | if (t == 0.0) { return 0.0; } 6 | if (t == 1.0) { return 1.0; } 7 | float p = 0.3; 8 | float a = 1.0; 9 | float s = p / 4.0; 10 | return (a * pow(2.0, -10.0 * t) * sin((t - s) * TWO_PI / p) + 1.0); 11 | } -------------------------------------------------------------------------------- /src/snippets/ease/expo/in.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Expo In equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeExpoIn(float t) { 4 | return (t == 0.0) ? 0.0 : pow(2.0, 10.0 * (t - 1.0)); 5 | } -------------------------------------------------------------------------------- /src/snippets/ease/expo/inOut.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Expo InOut equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeExpoInOut(float t) { 4 | t = t * 2.0; 5 | if (t == 0.0) return 0.0; 6 | if (t == 1.0) return 1.0; 7 | if (t < 1.0) return 0.5 * pow(2.0, 10.0 * (t - 1.0)); 8 | return 0.5 * (-pow(2.0, -10.0 * --t) + 2.0); 9 | } -------------------------------------------------------------------------------- /src/snippets/ease/expo/out.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Expo Out equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeExpoOut(float t) { 4 | return (t == 1.0) ? 1.0 : (-pow(2.0, -10.0 * t) + 1.0); 5 | } -------------------------------------------------------------------------------- /src/snippets/ease/quad/in.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Quad In equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeQuadIn(float t) { 4 | return t * t; 5 | } -------------------------------------------------------------------------------- /src/snippets/ease/quad/inOut.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Quad InOut equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeQuadInOut(float t) { 4 | t = t * 2.0; if (t < 1.0) return 0.5 * t * t; 5 | return -0.5 * ((--t) * (t - 2.0) - 1.0); 6 | } -------------------------------------------------------------------------------- /src/snippets/ease/quad/out.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Quad Out equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeQuadOut(float t) { 4 | return -1.0 * t * (t - 2.0); 5 | } -------------------------------------------------------------------------------- /src/snippets/ease/quart/in.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Quart In equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeQuartIn(float t) { 4 | return t * t * t * t; 5 | } -------------------------------------------------------------------------------- /src/snippets/ease/quart/inOut.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Quart InOut equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeQuartInOut(float t) { 4 | t = t * 2.0; if (t < 1.0) return 0.5 * t * t * t * t; 5 | return -0.5 * ((t -= 2.0) * t * t * t - 2.0); 6 | } -------------------------------------------------------------------------------- /src/snippets/ease/quart/out.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Quart Out equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeQuartOut(float t) { 4 | return -1.0 * ((t = t - 1.0) * t * t * t - 1.0); 5 | } -------------------------------------------------------------------------------- /src/snippets/ease/quint/in.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Quint In equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeQuintIn(float t) { 4 | return t * t * t * t * t; 5 | } -------------------------------------------------------------------------------- /src/snippets/ease/quint/inOut.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Quint InOut equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeQuintInOut(float t) { 4 | t = t * 2.0; if (t < 1.0) return 0.5 * t * t * t * t * t; 5 | return 0.5 * ((t -= 2.0) * t * t * t * t + 2.0); 6 | } -------------------------------------------------------------------------------- /src/snippets/ease/quint/out.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Quint Out equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | float easeQuintOut(float t) { 4 | return ((t = t - 1.0) * t * t * t * t + 1.0); 5 | } -------------------------------------------------------------------------------- /src/snippets/ease/sine/in.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Sine In equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | #define PI_TWO 1.570796326794897 4 | float easeSineIn(float t) { 5 | return -1.0 * cos(t * PI_TWO) + 1.0; 6 | } -------------------------------------------------------------------------------- /src/snippets/ease/sine/inOut.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Sine InOut equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | #define PI 3.141592653589793 4 | float easeSineInOut(float t) { 5 | return -0.5 * (cos(PI * t * 2.0) - 1.0); 6 | } -------------------------------------------------------------------------------- /src/snippets/ease/sine/out.glsl: -------------------------------------------------------------------------------- 1 | /* Easing Sine Out equation */ 2 | /* Adapted from Robert Penner easing equations */ 3 | #define PI_TWO 1.570796326794897 4 | float easeSineOut(float t) { 5 | return sin(t * PI_TWO); 6 | } -------------------------------------------------------------------------------- /src/snippets/main.glsl: -------------------------------------------------------------------------------- 1 | /* Main function, uniforms & utils */ 2 | #ifdef GL_ES 3 | precision mediump float; 4 | #endif 5 | 6 | uniform vec2 u_resolution; 7 | uniform vec2 u_mouse; 8 | uniform float u_time; 9 | 10 | #define PI_TWO 1.570796326794897 11 | #define PI 3.141592653589793 12 | #define TWO_PI 6.283185307179586 13 | 14 | /* Coordinate and unit utils */ 15 | vec2 coord(in vec2 p) { 16 | p = p / u_resolution.xy; 17 | // correct aspect ratio 18 | if (u_resolution.x > u_resolution.y) { 19 | p.x *= u_resolution.x / u_resolution.y; 20 | p.x += (u_resolution.y - u_resolution.x) / u_resolution.y / 2.0; 21 | } else { 22 | p.y *= u_resolution.y / u_resolution.x; 23 | p.y += (u_resolution.x - u_resolution.y) / u_resolution.x / 2.0; 24 | } 25 | // centering 26 | p -= 0.5; 27 | p *= vec2(-1.0, 1.0); 28 | return p; 29 | } 30 | #define rx 1.0 / min(u_resolution.x, u_resolution.y) 31 | #define uv gl_FragCoord.xy / u_resolution.xy 32 | #define st coord(gl_FragCoord.xy) 33 | #define mx coord(u_mouse) 34 | 35 | void main() { 36 | vec3 color = vec3( 37 | abs(cos(st.x + mx.x)), 38 | abs(sin(st.y + mx.y)), 39 | abs(sin(u_time)) 40 | ); 41 | 42 | gl_FragColor = vec4(color, 1.0); 43 | } -------------------------------------------------------------------------------- /src/snippets/math/2d/transform.glsl: -------------------------------------------------------------------------------- 1 | /* Math 2D Transformations */ 2 | mat2 rotate2d(in float angle){ 3 | return mat2(cos(angle),-sin(angle), sin(angle), cos(angle)); 4 | } 5 | -------------------------------------------------------------------------------- /src/snippets/math/3d/transform.glsl: -------------------------------------------------------------------------------- 1 | /* Math 3D Transformations */ 2 | 3 | const mat4 projection = mat4( 4 | vec4(3.0 / 4.0, 0.0, 0.0, 0.0), 5 | vec4( 0.0, 1.0, 0.0, 0.0), 6 | vec4( 0.0, 0.0, 0.5, 0.5), 7 | vec4( 0.0, 0.0, 0.0, 1.0) 8 | ); 9 | 10 | mat4 scale = mat4( 11 | vec4(4.0 / 3.0, 0.0, 0.0, 0.0), 12 | vec4( 0.0, 1.0, 0.0, 0.0), 13 | vec4( 0.0, 0.0, 1.0, 0.0), 14 | vec4( 0.0, 0.0, 0.0, 1.0) 15 | ); 16 | 17 | mat4 rotation = mat4( 18 | vec4(1.0, 0.0, 0.0, 0.0), 19 | vec4(0.0, cos(u_time), sin(u_time), 0.0), 20 | vec4(0.0, -sin(u_time), cos(u_time), 0.0), 21 | vec4(0.0, 0.0, 0.0, 1.0) 22 | ); 23 | 24 | mat4 rotationAxis(float angle, vec3 axis) { 25 | axis = normalize(axis); 26 | float s = sin(angle); 27 | float c = cos(angle); 28 | float oc = 1.0 - c; 29 | return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, 30 | oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, 31 | oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 32 | 0.0, 0.0, 0.0, 1.0); 33 | } 34 | 35 | vec3 rotateX(vec3 p, float angle) { 36 | mat4 rmy = rotationAxis(angle, vec3(1.0, 0.0, 0.0)); 37 | return (vec4(p, 1.0) * rmy).xyz; 38 | } 39 | 40 | vec3 rotateY_(vec3 p, float angle) { 41 | mat4 rmy = rotationAxis(angle, vec3(0.0, 1.0, 0.0)); 42 | return (vec4(p, 1.0) * rmy).xyz; 43 | } 44 | 45 | vec3 rotateZ(vec3 p, float angle) { 46 | mat4 rmy = rotationAxis(angle, vec3(0.0, 0.0, 1.0)); 47 | return (vec4(p, 1.0) * rmy).xyz; 48 | } 49 | 50 | vec3 rotateY(vec3 p, float angle) { 51 | float c = cos(angle); 52 | float s = sin(angle); 53 | mat4 r = mat4( 54 | vec4(c, 0, s, 0), 55 | vec4(0, 1, 0, 0), 56 | vec4(-s, 0, c, 0), 57 | vec4(0, 0, 0, 1) 58 | ); 59 | return (vec4(p, 1.0) * r).xyz; 60 | } -------------------------------------------------------------------------------- /src/snippets/modifiers/blend.glsl: -------------------------------------------------------------------------------- 1 | /* Blending function */ 2 | /* Smoothmin functions by Inigo Quilez */ 3 | float sBlendExpo(float a, float b, float k) { 4 | float res = exp(-k * a) + exp(-k * b); 5 | return -log(res) / k; 6 | } 7 | float sBlendPoly(float a, float b, float k) { 8 | float h = clamp(0.5 + 0.5 * (b - a) / k, 0.0, 1.0); 9 | return mix(b, a, h) - k * h * (1.0 - h); 10 | } 11 | float sBlendPower(float a, float b, float k) { 12 | a = pow(a, k); b = pow(b, k); 13 | return pow((a * b) / (a + b), 1.0 / k); 14 | } -------------------------------------------------------------------------------- /src/snippets/modifiers/boolean.glsl: -------------------------------------------------------------------------------- 1 | /* Boolean functions */ 2 | float sUnion(float a, float b) { 3 | return min(a, b); 4 | } 5 | float sIntersect(float a, float b) { 6 | return max(a, b); 7 | } 8 | float sDifference(float a, float b) { 9 | return max(a, -b); 10 | } -------------------------------------------------------------------------------- /src/snippets/modifiers/tile.glsl: -------------------------------------------------------------------------------- 1 | /* Tiling function */ 2 | vec2 tile(in vec2 p, vec2 w) { return fract(mod(p + w / 2.0, w)) - (w / 2.0); } 3 | vec2 tile(in vec2 p, float w) { return tile(p, vec2(w)); } -------------------------------------------------------------------------------- /src/snippets/object.glsl: -------------------------------------------------------------------------------- 1 | /* Object struct */ 2 | struct Object { float distance; vec3 color; }; 3 | Object object = Object(0.0, vec3(0.0)); -------------------------------------------------------------------------------- /src/snippets/shapes/2d/arc.glsl: -------------------------------------------------------------------------------- 1 | /* Shape 2D arc */ 2 | float sArc(in vec2 p, in float w, in float s, in float e) { 3 | float a = distance(p, w * 0.5 * vec2(cos(s), sin(s))); 4 | float x = -PI; 5 | p *= mat2(cos(x - s), -sin(x - s), sin(x - s), cos(x - s)); 6 | float b = clamp(atan(p.y, p.x), x, x + e); 7 | b = distance(p, w * 0.5 * vec2(cos(b), sin(b))); 8 | return min(a, b) * 2.0; 9 | } 10 | float arc(in vec2 p, in float w, in float s, in float e, in float t) { 11 | float d = sArc(p, w, s, e); 12 | return stroke(d, t); 13 | } -------------------------------------------------------------------------------- /src/snippets/shapes/2d/circle.glsl: -------------------------------------------------------------------------------- 1 | /* Shape 2D circle */ 2 | float sCircle(in vec2 p, in float w) { 3 | return length(p) * 2.0 - w; 4 | } 5 | float circle(in vec2 p, in float w) { 6 | float d = sCircle(p, w); 7 | return fill(d); 8 | } 9 | float circle(in vec2 p, in float w, float t) { 10 | float d = sCircle(p, w); 11 | return stroke(d, t); 12 | } -------------------------------------------------------------------------------- /src/snippets/shapes/2d/grid.glsl: -------------------------------------------------------------------------------- 1 | /* Shape 2D grid */ 2 | vec2 tile(in vec2 p, vec2 w) { return fract(mod(p + w / 2.0, w)) - (w / 2.0); } 3 | vec2 tile(in vec2 p, float w) { return tile(p, vec2(w)); } 4 | float sLine(in vec2 a, in vec2 b) { 5 | vec2 p = b - a; 6 | float d = abs(dot(normalize(vec2(p.y, -p.x)), a)); 7 | return d * 2.0; 8 | } 9 | float line(in vec2 a, in vec2 b) { 10 | float d = sLine(a, b); 11 | return fill(d); 12 | } 13 | float line(in vec2 a, in vec2 b, in float t) { 14 | float d = sLine(a, b); 15 | return stroke(d, t); 16 | } 17 | float line(in vec2 p, in float a, in float t) { 18 | vec2 b = p + vec2(sin(a), cos(a)); 19 | return line(p, b, t); 20 | } 21 | float sSegment(in vec2 a, in vec2 b) { 22 | vec2 ba = a - b; 23 | float d = clamp(dot(a, ba) / dot(ba, ba), 0.0, 1.0); 24 | return length(a - ba * d) * 2.0; 25 | } 26 | float segment(in vec2 a, in vec2 b, float t) { 27 | float d = sSegment(a, b); 28 | return stroke(d, t); 29 | } 30 | float grid(in vec2 p, in float w) { 31 | vec2 l = tile(p, w); 32 | float d = 0.0; 33 | d += line(l, l + vec2(0.0, 0.1), 0.002); 34 | d += line(l, l + vec2(0.1, 0.0), 0.002); 35 | d *= 0.2; 36 | p = tile(p, vec2(w * 5.0)); 37 | float s = w / 10.0; 38 | float g = 0.0; 39 | g += segment(p + vec2(-s, 0.0), p + vec2(s, 0.0), 0.004); 40 | g += segment(p + vec2(0.0, -s), p + vec2(0.0, s), 0.004); 41 | return d + g; 42 | } -------------------------------------------------------------------------------- /src/snippets/shapes/2d/hex.glsl: -------------------------------------------------------------------------------- 1 | /* Shape 2D hexagon */ 2 | float sHex(in vec2 p, in float w) { 3 | vec2 q = abs(p); 4 | float d = max((q.x * 0.866025 + q.y * 0.5), q.y) - w * 0.5; // * 0.4330125 5 | return d * 2.0; 6 | } 7 | float hex(in vec2 p, in float w) { 8 | float d = sHex(p, w); 9 | return fill(d); 10 | } 11 | float hex(in vec2 p, in float w, in float t) { 12 | float d = sHex(p, w); 13 | return stroke(d, t); 14 | } -------------------------------------------------------------------------------- /src/snippets/shapes/2d/line.glsl: -------------------------------------------------------------------------------- 1 | /* Shape 2D line */ 2 | float sLine(in vec2 a, in vec2 b) { 3 | vec2 p = b - a; 4 | float d = abs(dot(normalize(vec2(p.y, -p.x)), a)); 5 | return d * 2.0; 6 | } 7 | float line(in vec2 a, in vec2 b) { 8 | float d = sLine(a, b); 9 | return fill(d); 10 | } 11 | float line(in vec2 a, in vec2 b, in float t) { 12 | float d = sLine(a, b); 13 | return stroke(d, t); 14 | } 15 | float line(in vec2 p, in float a, in float t) { 16 | vec2 b = p + vec2(sin(a), cos(a)); 17 | return line(p, b, t); 18 | } -------------------------------------------------------------------------------- /src/snippets/shapes/2d/pie.glsl: -------------------------------------------------------------------------------- 1 | /* Shape 2D pie */ 2 | float sPie(in vec2 p, in float w, in float s, in float e) { 3 | s = mod(s, TWO_PI); 4 | e = mod(s + e, TWO_PI); 5 | float a = mod(atan(p.y, p.x), TWO_PI); 6 | a = abs(step(s, a) - step(e, a)); 7 | a = s < e ? a : 1.0 - a; 8 | float d = length(p); 9 | return 1.0 - (a - d * 2.0) - w; 10 | } 11 | float pie(in vec2 p, in float w, in float s, in float e) { 12 | float d = sPie(p, w, s, e); 13 | return fill(d); 14 | } 15 | float pie(in vec2 p, in float w, in float s, in float e, in float t) { 16 | float d = sPie(p, w, s, e); 17 | return stroke(d, t); 18 | } -------------------------------------------------------------------------------- /src/snippets/shapes/2d/plot.glsl: -------------------------------------------------------------------------------- 1 | /* Shape 2D plot */ 2 | float sPlot(vec2 p, float y){ 3 | return p.y + y; 4 | } 5 | float plot(vec2 p, float y, float t) { 6 | float d = sPlot(p, y); 7 | return 1.0 - smoothstep(t / 2.0 - rx, t / 2.0 + rx, abs(d)); 8 | } -------------------------------------------------------------------------------- /src/snippets/shapes/2d/poly.glsl: -------------------------------------------------------------------------------- 1 | /* Shape 2D poly */ 2 | float sPoly(in vec2 p, in float w, in int sides) { 3 | float a = atan(p.x, p.y) + PI; 4 | float r = TWO_PI / float(sides); 5 | float d = cos(floor(0.5 + a / r) * r - a) * length(max(abs(p) * 1.0, 0.0)); 6 | return d * 2.0 - w; 7 | } 8 | float poly(in vec2 p, in float w, in int sides) { 9 | float d = sPoly(p, w, sides); 10 | return fill(d); 11 | } 12 | float poly(in vec2 p, in float w, in int sides, in float t) { 13 | float d = sPoly(p, w, sides); 14 | return stroke(d, t); 15 | } -------------------------------------------------------------------------------- /src/snippets/shapes/2d/rect.glsl: -------------------------------------------------------------------------------- 1 | /* Shape 2D rect */ 2 | float sRect(in vec2 p, in vec2 w) { 3 | float d = max(abs(p.x / w.x), abs(p.y / w.y)) * 2.0; 4 | float m = max(w.x, w.y); 5 | return d * m - m; 6 | } 7 | float rect(in vec2 p, in vec2 w) { 8 | float d = sRect(p, w); 9 | return fill(d); 10 | } 11 | float rect(in vec2 p, in vec2 w, in float t) { 12 | float d = sRect(p, w); 13 | return stroke(d, t); 14 | } -------------------------------------------------------------------------------- /src/snippets/shapes/2d/roundrect.glsl: -------------------------------------------------------------------------------- 1 | /* Shape 2D roundrect */ 2 | float sRoundrect(in vec2 p, in vec2 w, in float corner) { 3 | vec2 d = abs(p) - w * 0.5 + corner; 4 | return (min(max(d.x, d.y), 0.0) + length(max(d, 0.0)) - corner) * 2.0; 5 | } 6 | float roundrect(in vec2 p, in vec2 w, in float corner) { 7 | float d = sRoundrect(p, w, corner); 8 | return fill(d); 9 | } 10 | float roundrect(in vec2 p, in vec2 w, in float corner, in float t) { 11 | float d = sRoundrect(p, w, corner); 12 | return stroke(d, t); 13 | } -------------------------------------------------------------------------------- /src/snippets/shapes/2d/segment.glsl: -------------------------------------------------------------------------------- 1 | /* Shape 2D segment */ 2 | float sSegment(in vec2 a, in vec2 b) { 3 | vec2 ba = a - b; 4 | float d = clamp(dot(a, ba) / dot(ba, ba), 0.0, 1.0); 5 | return length(a - ba * d) * 2.0; 6 | } 7 | float segment(in vec2 a, in vec2 b, float t) { 8 | float d = sSegment(a, b); 9 | return stroke(d, t); 10 | } -------------------------------------------------------------------------------- /src/snippets/shapes/2d/spiral.glsl: -------------------------------------------------------------------------------- 1 | /* Shape 2D spiral */ 2 | /* Spiral function by Patricio Gonzalez Vivo */ 3 | float sSpiral(in vec2 p, in float turns) { 4 | float r = dot(p, p); 5 | float a = atan(p.y, p.x); 6 | float d = abs(sin(fract(log(r) * (turns / 5.0) + a * 0.159))); 7 | return d - 0.5; 8 | } 9 | float spiral(in vec2 p, in float turns) { 10 | float d = sSpiral(p, turns); 11 | return fill(d); 12 | } -------------------------------------------------------------------------------- /src/snippets/shapes/2d/star.glsl: -------------------------------------------------------------------------------- 1 | /* Shape 2D star */ 2 | float sStar(in vec2 p, in float w, in int sides) { 3 | float r = 0.5; float s = max(5.0, float(sides)); float m = 0.5 / s; float x = PI_TWO / s * (2.0 - mod(s, 2.0)); 4 | float segment = (atan(p.y, p.x) - x) / TWO_PI * s; 5 | float a = ((floor(segment) + r) / s + mix(m, -m, step(r, fract(segment)))) * TWO_PI; 6 | float d = abs(dot(vec2(cos(a + x), sin(a + x)), p)) + m; 7 | return (d - rx) * 2.0 - w; 8 | } 9 | float star(in vec2 p, in float w, in int sides) { 10 | float d = sStar(p, w, sides); 11 | return fill(d); 12 | } 13 | float star(in vec2 p, in float w, in int sides, float t) { 14 | float d = sStar(p, w, sides); 15 | return stroke(d, t); 16 | } -------------------------------------------------------------------------------- /src/snippets/units.glsl: -------------------------------------------------------------------------------- 1 | /* Pixel unit conversion function */ 2 | vec2 pos(in float x, in float y) { return st + vec2(x * rx, y * rx); } 3 | vec2 pos(in float x) { return pos(x, x); } 4 | vec2 pos(in vec2 p) { return pos(p.x, p.y); } 5 | float size(in float x) { return x * rx; } 6 | vec2 size(in float x, in float y) { return vec2(x * rx, y * rx); } -------------------------------------------------------------------------------- /src/test/runTest.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | import { runTests } from 'vscode-test'; 3 | 4 | async function main() { 5 | try { 6 | // The folder containing the Extension Manifest package.json 7 | // Passed to `--extensionDevelopmentPath` 8 | const extensionDevelopmentPath = path.resolve(__dirname, '../../'); 9 | 10 | // The path to the extension test script 11 | // Passed to --extensionTestsPath 12 | const extensionTestsPath = path.resolve(__dirname, './suite/index'); 13 | 14 | // Download VS Code, unzip it and run the integration test 15 | await runTests({ extensionDevelopmentPath, extensionTestsPath }); 16 | } catch (err) { 17 | console.error('Failed to run tests'); 18 | process.exit(1); 19 | } 20 | } 21 | 22 | main(); 23 | -------------------------------------------------------------------------------- /src/test/suite/extension.test.ts: -------------------------------------------------------------------------------- 1 | import * as assert from 'assert'; 2 | // You can import and use all API from the 'vscode' module 3 | // as well as import your extension to test it 4 | import * as vscode from 'vscode'; 5 | 6 | // import * as myExtension from '../../extension'; 7 | 8 | suite('Extension Test Suite', () => { 9 | vscode.window.showInformationMessage('Start all tests.'); 10 | 11 | test('Sample test', () => { 12 | assert.equal([1, 2, 3].indexOf(5), -1); 13 | assert.equal([1, 2, 3].indexOf(0), -1); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /src/test/suite/index.ts: -------------------------------------------------------------------------------- 1 | import * as glob from 'glob'; 2 | import * as Mocha from 'mocha'; 3 | import * as path from 'path'; 4 | 5 | export function run(): Promise { 6 | // Create the mocha test 7 | const mocha = new Mocha({ 8 | ui: 'tdd' 9 | }); 10 | mocha.useColors(true); 11 | 12 | const testsRoot = path.resolve(__dirname, '..'); 13 | 14 | return new Promise((c, e) => { 15 | glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { 16 | if (err) { 17 | return e(err); 18 | } 19 | 20 | // Add files to the test suite 21 | files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); 22 | 23 | try { 24 | // Run the mocha test 25 | mocha.run(failures => { 26 | if (failures > 0) { 27 | e(new Error(`${failures} tests failed.`)); 28 | } else { 29 | c(); 30 | } 31 | }); 32 | } catch (err) { 33 | console.error(err); 34 | e(err); 35 | } 36 | }); 37 | }); 38 | } 39 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "outDir": "out", 6 | "lib": [ 7 | "es6" 8 | ], 9 | "sourceMap": true, 10 | "rootDir": "src" 11 | }, 12 | "exclude": [ 13 | "node_modules", 14 | ".vscode-test" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "no-string-throw": true, 4 | "no-unused-expression": true, 5 | "no-duplicate-variable": true, 6 | "curly": true, 7 | "class-name": true, 8 | "semicolon": [ 9 | true, 10 | "always" 11 | ], 12 | "triple-equals": true 13 | }, 14 | "defaultSeverity": "warning" 15 | } -------------------------------------------------------------------------------- /vsc-extension-quickstart.md: -------------------------------------------------------------------------------- 1 | # Welcome to your VS Code Extension 2 | 3 | ## What's in the folder 4 | * This folder contains all of the files necessary for your extension. 5 | * `package.json` - this is the manifest file in which you declare your extension and command. 6 | The sample plugin registers a command and defines its title and command name. With this information 7 | VS Code can show the command in the command palette. It doesn’t yet need to load the plugin. 8 | * `src/extension.ts` - this is the main file where you will provide the implementation of your command. 9 | The file exports one function, `activate`, which is called the very first time your extension is 10 | activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`. 11 | We pass the function containing the implementation of the command as the second parameter to 12 | `registerCommand`. 13 | 14 | ## Get up and running straight away 15 | * Press `F5` to open a new window with your extension loaded. 16 | * Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`. 17 | * Set breakpoints in your code inside `src/extension.ts` to debug your extension. 18 | * Find output from your extension in the debug console. 19 | 20 | ## Make changes 21 | * You can relaunch the extension from the debug toolbar after changing code in `src/extension.ts`. 22 | * You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes. 23 | 24 | ## Explore the API 25 | * You can open the full set of our API when you open the file `node_modules/vscode/vscode.d.ts`. 26 | 27 | ## Run tests 28 | * Open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Launch Tests`. 29 | * Press `F5` to run the tests in a new window with your extension loaded. 30 | * See the output of the test result in the debug console. 31 | * Make changes to `test/extension.test.ts` or create new test files inside the `test` folder. 32 | * By convention, the test runner will only consider files matching the name pattern `**.test.ts`. 33 | * You can create folders inside the `test` folder to structure your tests any way you want. 34 | --------------------------------------------------------------------------------