├── .editorconfig ├── .gitignore ├── .npmrc ├── .prettierignore ├── .prettierrc.cjs ├── LICENSE ├── README.md ├── asc.d.ts ├── package.json ├── scripts └── build.js ├── server.js ├── src ├── ASWebGLue.d.ts ├── ASWebGLue.js ├── ASWebGLue2.d.ts ├── ASWebGLue2.js ├── WebGL.ts ├── examples │ ├── AnimationTexture │ │ ├── README.md │ │ ├── index.html │ │ ├── kaijunicorn.json │ │ ├── kaijunicorn.png │ │ ├── kaijunicorn.tps │ │ ├── kaijunicorn1.png │ │ ├── kaijunicorn2.png │ │ ├── kaijunicorn3.png │ │ └── texture_animation.ts │ ├── ColorTriangle │ │ ├── README.md │ │ ├── color_triangle.ts │ │ └── index.html │ ├── ColorTriangleRotate │ │ ├── README.md │ │ ├── color_triangle_rotate.ts │ │ └── index.html │ ├── Cube │ │ ├── README.md │ │ ├── cube.ts │ │ └── index.html │ ├── HelloWorldTriangle │ │ ├── README.md │ │ ├── index.html │ │ └── triangle.ts │ ├── InstancedSprites │ │ ├── README.md │ │ ├── index.html │ │ ├── instanced_sprites.ts │ │ ├── kaijunicorn-mini.png │ │ ├── kaijunicorn-sheet.png │ │ └── kaijunicorn.png │ ├── Lines │ │ ├── index.html │ │ └── render_lines.ts │ ├── Material │ │ ├── Robot.ts │ │ ├── index.html │ │ ├── obj_mat.ts │ │ └── robot_temp.asc │ ├── MousePoint │ │ ├── README.md │ │ ├── index.html │ │ └── mouse_point.ts │ ├── NormalModel │ │ ├── LunarMap.png │ │ ├── LunarMapOG.png │ │ ├── LunarNormalMap.png │ │ ├── Moon_Sphere.ts │ │ ├── index.html │ │ ├── moon.blend │ │ ├── moon.blend1 │ │ ├── moon.mtl │ │ ├── moon.obj │ │ ├── obj_norm.ts │ │ └── reminder.txt │ ├── Obj │ │ ├── README.md │ │ ├── Suzanne.ts │ │ ├── index.html │ │ ├── monkey.mtl │ │ ├── monkey.obj │ │ ├── monkey.zip │ │ ├── obj.ts │ │ ├── obj.zip │ │ └── teapot.obj.txt │ ├── Quad │ │ ├── README.md │ │ ├── index.html │ │ └── quad.ts │ ├── QuadFollowMouse │ │ ├── README.md │ │ ├── index.html │ │ └── quad_follow_mouse.ts │ ├── README.md │ ├── RobotTex.psd │ ├── RobotTexPixel.png │ ├── RobotTexPixel.psd │ ├── RobotTexPixel_n.png │ ├── SimpleLighting │ │ ├── README.md │ │ ├── index.html │ │ └── simple_lighting.ts │ ├── SpriteLighting │ │ ├── README.md │ │ ├── SpaceShip.png │ │ ├── SpaceShipN.png │ │ ├── index.html │ │ └── sprite_lighting.ts │ ├── TextureModel │ │ ├── RobotTex.ts │ │ ├── RobotTexPixel.png │ │ ├── index.html │ │ └── obj_tex.ts │ ├── TextureQuad │ │ ├── README.md │ │ ├── index.html │ │ ├── kaijunicorn.png │ │ └── texture_quad.ts │ ├── WarpSpeed │ │ ├── README.md │ │ ├── index.html │ │ └── warp_speed.ts │ ├── commented.mtl │ ├── commented.obj │ ├── icosphere.png │ ├── monkey.mtl │ ├── monkey.obj │ ├── robot.blend │ ├── robot.blend1 │ ├── robot.mtl │ ├── robot.obj │ ├── robot_texture.blend │ ├── robot_texture.blend1 │ ├── robot_texture.mtl │ ├── robot_texture.obj │ ├── robots.blend │ ├── spaceship.blend │ ├── spaceship.blend1 │ ├── spaceship.dae │ ├── spaceship.mtl │ ├── spaceship.obj │ ├── spaceship.x3d │ ├── spaceship_uv.jpg │ ├── spaceship_uv.png │ └── spaceship_uv.psd └── performance-test │ ├── Readme.md │ ├── objTest.js │ └── objTest.ts └── tsconfig.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | charset = utf-8 8 | indent_style = space 9 | indent_size = 2 10 | end_of_line = lf 11 | insert_final_newline = true 12 | trim_trailing_whitespace = true 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | dist 4 | package-lock.json 5 | *.wasm 6 | *.wat 7 | images 8 | src/extended 9 | src/old 10 | hidden 11 | *.sh -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | .vscode/ -------------------------------------------------------------------------------- /.prettierrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | tabWidth: 2, 3 | useTabs: false, 4 | semi: true, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | bracketSpacing: false, 8 | printWidth: 120, 9 | arrowParens: 'avoid', 10 | }; 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Rick Battagline 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ASWebGLue (Assemblyscript WebGL Bindings) 2 | 3 | ASWebGLue is a set of javascript bindings for AssemblyScript/WebGL. Currently it is being ported into typescript for 4 | better assembly script compatibility. The primary goal of this project is to provide high level access to WebGL 5 | for AssemblyScript projects. The glue adds the webgl exports to your asc program. 6 | 7 | Tutorials available on [Wasm Book](https://wasmbook.com) 8 | 9 | ## Using 10 | 11 | There are two files in this project to use in your project. These files are `ASWebGLue.js` which contains the JavaScript glue code and `WebGL.ts` that contains the AssemblyScript bindings. There are several examples in the `/src/examples` directory. A version of aswebglue is available on npm, but I didn't create it, so I am not sure how up to date it is. 12 | 13 | There are two main files to be concerned with. One. `WebGL.ts` exposes the webgl bindings to your assembly script code. The compiler will pull this into to make sure everything is happy within typescript. The other file is the `ASWebGLuejs` which is used to initiates the loader used by WebAssembly. This file also provides an initialization function which will attach the webgl bindings to your instatiated WebGL AssemblyScript program. The js file contains all of the high level WebGL functions which are contained in your browsers `lib.dom.js`. 14 | 15 | Here is a simple example from **HelloTriangle** 16 | 17 | ### JavaScript 18 | ```javascript 19 | import { initASWebGLue, ASWebGLReady } from '../../ASWebGLue.js'; 20 | const wasm_file = 'triangle.wasm'; 21 | var exports; 22 | var w = window.innerWidth * 0.99; 23 | var h = window.innerHeight * 0.99; 24 | var cnvs = document.getElementById("cnvs"); 25 | if (w > h) { 26 | cnvs.width = h; 27 | cnvs.height = h; 28 | } 29 | else { 30 | cnvs.width = w; 31 | cnvs.height = w; 32 | } 33 | 34 | function renderFrame() { 35 | // call the displayLoop function in the WASM module 36 | exports.displayLoop(); 37 | 38 | // requestAnimationFrame calls renderFrame the next time a frame is rendered 39 | requestAnimationFrame(renderFrame); 40 | 41 | } 42 | 43 | const memory = new WebAssembly.Memory({ initial: 100 }); // linear memory 44 | 45 | var importObject = { 46 | env: { 47 | memory: memory, 48 | seed: Date.now, 49 | } 50 | }; 51 | 52 | initASWebGLue(importObject); 53 | 54 | (async () => { 55 | // use WebAssembly.instantiateStreaming in combination with 56 | // fetch instead of WebAssembly.instantiate and fs.readFileSync 57 | let obj = await WebAssembly.instantiateStreaming( 58 | fetch(wasm_file), 59 | importObject); 60 | console.log(obj); 61 | exports = obj.instance.exports; 62 | console.log(exports); 63 | ASWebGLReady(obj, importObject); 64 | requestAnimationFrame(renderFrame); 65 | })(); 66 | ``` 67 | 68 | ### AssemblyScript 69 | ```typescript 70 | import { 71 | WebGLRenderingContext, WebGLShader, WebGLProgram, WebGLBuffer, GLint, 72 | } from '../../webgl' 73 | 74 | const VERTEX_SHADER_CODE: string = /*glsl*/ `#version 300 es 75 | precision highp float; 76 | 77 | in vec2 position; 78 | 79 | void main() { 80 | gl_Position = vec4( position, 0.0, 1.0 ); 81 | } 82 | `; 83 | 84 | const FRAGMENT_SHADER_CODE: string = /*glsl*/ `#version 300 es 85 | precision highp float; 86 | out vec4 color; 87 | 88 | void main() { 89 | color = vec4( 1.0, 0.0, 0.0, 1.0 ); 90 | } 91 | `; 92 | 93 | // initialize webgl 94 | var gl = new WebGLRenderingContext('cnvs', 'webgl2'); 95 | 96 | let vertex_shader: WebGLShader = gl.createShader(gl.VERTEX_SHADER); 97 | gl.shaderSource(vertex_shader, VERTEX_SHADER_CODE); 98 | gl.compileShader(vertex_shader); 99 | 100 | let fragment_shader: WebGLShader = gl.createShader(gl.FRAGMENT_SHADER); 101 | gl.shaderSource(fragment_shader, FRAGMENT_SHADER_CODE); 102 | gl.compileShader(fragment_shader); 103 | 104 | let program: WebGLProgram = gl.createProgram(); 105 | 106 | gl.attachShader(program, vertex_shader); 107 | gl.attachShader(program, fragment_shader); 108 | 109 | gl.linkProgram(program); 110 | 111 | gl.useProgram(program); 112 | 113 | let buffer: WebGLBuffer = gl.createBuffer(); 114 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 115 | 116 | let position_al: GLint = gl.getAttribLocation(program, 'position'); 117 | gl.enableVertexAttribArray(position_al); 118 | 119 | let triangle_data: StaticArray = [0.0, 0.5, 120 | -0.5, -0.5, 121 | 0.5, -0.5,]; 122 | 123 | export function displayLoop(): void { 124 | // R G B A 125 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 126 | gl.clear(gl.COLOR_BUFFER_BIT); 127 | 128 | gl.bufferData(gl.ARRAY_BUFFER, triangle_data, gl.STATIC_DRAW); 129 | 130 | // attribute | dimensions | data_type | normalize | stride | offset 131 | gl.vertexAttribPointer(position_al, 2, gl.FLOAT, false, 0, 0); 132 | 133 | // mode | first vertex | count 134 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, 3); 135 | } 136 | 137 | ``` 138 | 139 | ## Contact me (Rick Battagline) 140 | 141 | If you have any questions, please feel free to contact me (Rick) on 142 |

143 | Twitter: https://twitter.com/battagline @battagline
144 | LinkedIn: https://www.linkedin.com/in/battagline
145 | AssemblyScript Discord: https://discord.gg/mNPWbVT4
146 | [WebAssembly Book](https://wasmbook.com) 147 | -------------------------------------------------------------------------------- /asc.d.ts: -------------------------------------------------------------------------------- 1 | // type externref = number; 2 | // type bool = any; 3 | // type i8 = any; 4 | // type i16 = any; 5 | // type i32 = any; 6 | // type i64 = any; 7 | // type f32 = any; 8 | // type f64 = any; 9 | // type u8 = any; 10 | // type u16 = any; 11 | // type u32 = any; 12 | // type u64 = any; 13 | // type usize = any; 14 | // declare class StaticArray { 15 | // constructor(x: number) 16 | // } 17 | 18 | // declare function assert(isTrueish: Text, message?: string): Text; 19 | // declare function instantiate(...args: any[]): T; 20 | // declare function store(size: usize, offset: usize): T; 21 | // declare function changetype(value: any): T; 22 | // declare function idof(): u32; 23 | // declare function nameof(value?: T): string; 24 | 25 | // declare namespace Mathf { 26 | // const E: number; 27 | // const LN2: number; 28 | // const LN10: number; 29 | // const LOG2E: number; 30 | // const LOG10E: number; 31 | // const PI: number; 32 | // const SQRT1_2: number; 33 | // const SQRT2: number; 34 | 35 | // function abs(x: number): number; 36 | // function acos(x: number): number; 37 | // function acosh(x: number): number; 38 | // function asin(x: number): number; 39 | // function asinh(x: number): number; 40 | // function atan(x: number): number; 41 | // function atan2(x: number): number; 42 | // function atanh(x: number): number; 43 | // function cbrt(x: number): number; 44 | // function ceil(x: number): number; 45 | // function clz32(x: number): number; 46 | // function cos(x: number): number; 47 | // function cosh(x: number): number; 48 | // function exp(x: number): number; 49 | // function expm1(x: number): number; 50 | // function floor(x: number): number; 51 | // function fround(x: number): number; 52 | // function hypot(value1: number, value2: number): number; 53 | // function imul(a: number, b: number): number; 54 | // function log(x: number): number; 55 | // function log10(x: number): number; 56 | // function log1p(x: number): number; 57 | // function log2(x: number): number; 58 | // function max(v1: number, v2: number): number; 59 | // function min(v1: number, v2: number): number; 60 | // function pow(base: number, exponent: number): number; 61 | // function random(): number; 62 | // function round(x: number): number; 63 | // function sign(x: number): number; 64 | // function signbit(x: number): bool; 65 | // function sin(x: number): number; 66 | // function sinh(x: number): number; 67 | // function sqrt(x: number): number; 68 | // function tan(x: number): number; 69 | // function tanh(x: number): number; 70 | // function trunc(x: number): number; 71 | // } 72 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aswebglue", 3 | "version": "0.1.1", 4 | "ascMain": "src/WebGL.ts", 5 | "type": "module", 6 | "main": "src/ASWebGLue.js", 7 | "types": "src/ASWebGLue.d.ts", 8 | "repository": { 9 | "type": "git", 10 | "url": "https://github.com/battlelinegames/ASWebGLue" 11 | }, 12 | "scripts": { 13 | "clean": "rimraf dist", 14 | "prebuild": "npm run clean", 15 | "build": "npm run build:examples", 16 | "build:examples": "node ./scripts/build.js --mode dev", 17 | "start": "live-server --verbose ./", 18 | "release:patch": "npm version patch --message 'v%s' && npm publish && git push --follow-tags", 19 | "release:minor": "npm version minor --message 'v%s' && npm publish && git push --follow-tags", 20 | "release:major": "npm version major --message 'v%s' && npm publish && git push --follow-tags" 21 | }, 22 | "devDependencies": { 23 | "@assemblyscript/loader": "^0.17.14", 24 | "assemblyscript": "^0.17.7", 25 | "benchmark": "^2.1.4", 26 | "child-process": "^1.0.2", 27 | "connect": "^3.7.0", 28 | "imagemin": "^7.0.1", 29 | "imagemin-pngquant": "^9.0.1", 30 | "live-server": "^1.2.1", 31 | "make-dir-cli": "^2.0.0", 32 | "node-minify": "^3.6.0", 33 | "rimraf": "^3.0.2", 34 | "serve-static": "^1.14.1" 35 | }, 36 | "author": "Rick Battagline ", 37 | "license": "MIT", 38 | "dependencies": {} 39 | } 40 | -------------------------------------------------------------------------------- /scripts/build.js: -------------------------------------------------------------------------------- 1 | import {exec as _exec} from 'child_process'; 2 | import fs from 'fs'; 3 | import path from 'path'; 4 | import min from 'node-minify'; 5 | import imagemin from 'imagemin'; 6 | import imageminPngQuant from 'imagemin-pngquant'; 7 | import {exit} from 'process'; 8 | import {promisify} from 'util'; 9 | 10 | const {readdir, copyFile, lstat, mkdir} = fs.promises; 11 | const exec = promisify(_exec); 12 | 13 | // Currently AS projects consume libs' AS code directly, so no need to build 14 | // webgl.wasm into a Wasm module. Maybe later we'll have dynamic and static 15 | // linking, in which case maybe we'd want to ship webgl.wasm too. 16 | /* 17 | const ASWebGLueWasm = './src/webgl.ts'; 18 | const ASWebGLueWasmOut = './dist/webgl.wasm'; 19 | let ascRun = `asc ${ASWebGLueWasm} --runtime stub -O3 --importMemory -o ${ASWebGLueWasmOut}`; 20 | exec(ascRun); 21 | */ 22 | 23 | const distDir = './dist'; 24 | 25 | if (!fs.existsSync(distDir)) await mkdir(distDir, 0o744); 26 | 27 | await copyFile('./src/ASWebGLue.js', './dist/ASWebGLue.js'); 28 | await copyFile('./src/ASWebGLue.d.ts', './dist/ASWebGLue.d.ts'); 29 | 30 | const exampleDirectory = './src/examples/'; 31 | 32 | // TODO Grab this option from the `--mode` CLI option. 33 | const MODE = 'dev'; 34 | 35 | // In dev mode, we will output wasm files into the same folders as the example 36 | // source code. This makes it easy to serve the files, and to make quick 37 | // changes to the HTML files and refresh the browser without having to re-build 38 | // all examples again. 39 | const distDirectory = MODE === 'dev' ? './src/examples/' : './dist/examples/'; 40 | 41 | // TODO Spread `asc` processes across threads using a huristic so we don't 42 | // overload the computer and crash. (Previously this script tried to run `asc` 43 | // on every example in parallel, which would crash if there wasn't enough 44 | // resources). Probably easier to use Gulp task runner for this, so it can 45 | // include watch mode that re-builds only a particular example that is modified 46 | // isntead of re-building everything. 47 | // 48 | // For now, it builds everything, one at a time. 49 | 50 | const files = await readdir(exampleDirectory); 51 | 52 | for (const file of files) { 53 | const stats = await lstat(path.resolve(exampleDirectory, file)); 54 | if (!stats.isDirectory()) continue; 55 | 56 | let subDir = file; 57 | 58 | const exampleFiles = await readdir(exampleDirectory + file); 59 | 60 | for (const exampleFile of exampleFiles) { 61 | if (exampleFile.indexOf('.ts') >= 0) { 62 | let fi = `${exampleDirectory}${subDir}/${exampleFile}`; 63 | let fo = `${distDirectory}${subDir}/${exampleFile.replace('.ts', '.wasm')}`; 64 | let ascRun = `asc ${fi} --runtime stub -O3 --importMemory -o ${fo}`; 65 | 66 | console.log(ascRun); 67 | 68 | try { 69 | await exec(ascRun); 70 | } catch (err) { 71 | console.error('ERROR:\n', err.stderr); 72 | exit(1); 73 | } 74 | } else if (exampleFile.indexOf('.html') >= 0) { 75 | // We only minify the HTML files and output them into the dist/ dir when building for prod. 76 | if (MODE === 'prod') { 77 | console.log(`minify ${subDir}/${exampleFile}`); 78 | 79 | await new Promise((resolve, reject) => { 80 | min.minify({ 81 | compressor: 'html-minifier', 82 | input: `${exampleDirectory}${subDir}/${exampleFile}`, 83 | output: `${distDirectory}${subDir}/${exampleFile}`, 84 | callback(err, min) { 85 | if (err) reject(err); 86 | else resolve(); 87 | }, 88 | }); 89 | }); 90 | } 91 | } else if (exampleFile.indexOf('.png') >= 0) { 92 | // We only compress the images and output them into the dist/ dir when building for prod. 93 | if (MODE === 'prod') { 94 | let fi = `${exampleDirectory}${subDir}/${exampleFile}`; 95 | let fo = `${distDirectory}${subDir}`; 96 | 97 | await imagemin([fi], { 98 | destination: fo, 99 | plugins: [ 100 | imageminPngQuant({ 101 | quality: [0.6, 0.8], 102 | }), 103 | ], 104 | }); 105 | } 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | import connect from 'connect'; 2 | import { dirname } from 'path'; 3 | import serveStatic from 'serve-static'; 4 | console.log(dirname('.') + "/") 5 | connect().use(serveStatic(dirname('.') + "/")).listen(8080, function () { 6 | console.log('Server running on 8080...'); 7 | }); 8 | 9 | -------------------------------------------------------------------------------- /src/ASWebGLue.d.ts: -------------------------------------------------------------------------------- 1 | export declare function print(str: string): void 2 | export declare function ASWebGLReady(wasm_obj: object, importObject: object): void 3 | export declare function initASWebGLue(importObject: object): void -------------------------------------------------------------------------------- /src/ASWebGLue2.d.ts: -------------------------------------------------------------------------------- 1 | export declare function print(str: string): void; 2 | export declare function ASWebGLReady(wasm_obj: object, importObject: object): void; 3 | export declare function initASWebGLue(importObject: object): void; 4 | -------------------------------------------------------------------------------- /src/examples/AnimationTexture/README.md: -------------------------------------------------------------------------------- 1 | # Animation Texture 2 | 3 | This example is an animated sprite. 4 | -------------------------------------------------------------------------------- /src/examples/AnimationTexture/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Animation Texture Example 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 | 72 | 73 | -------------------------------------------------------------------------------- /src/examples/AnimationTexture/kaijunicorn.json: -------------------------------------------------------------------------------- 1 | {"frames": { 2 | 3 | "kaijunicorn1.png": 4 | { 5 | "frame": {"x":1,"y":1,"w":42,"h":64}, 6 | "rotated": false, 7 | "trimmed": true, 8 | "spriteSourceSize": {"x":3,"y":0,"w":42,"h":64}, 9 | "sourceSize": {"w":48,"h":64} 10 | }, 11 | "kaijunicorn2.png": 12 | { 13 | "frame": {"x":1,"y":133,"w":40,"h":64}, 14 | "rotated": false, 15 | "trimmed": true, 16 | "spriteSourceSize": {"x":5,"y":0,"w":40,"h":64}, 17 | "sourceSize": {"w":48,"h":64} 18 | }, 19 | "kaijunicorn3.png": 20 | { 21 | "frame": {"x":1,"y":67,"w":41,"h":64}, 22 | "rotated": false, 23 | "trimmed": true, 24 | "spriteSourceSize": {"x":5,"y":0,"w":41,"h":64}, 25 | "sourceSize": {"w":48,"h":64} 26 | }}, 27 | "meta": { 28 | "app": "https://www.codeandweb.com/texturepacker", 29 | "version": "1.0", 30 | "image": "kaijunicorn.png", 31 | "format": "RGBA8888", 32 | "size": {"w":44,"h":198}, 33 | "scale": "1", 34 | "smartupdate": "$TexturePacker:SmartUpdate:6e386e05493c1963607c61a7919b90cd:a86b0a5e232f296e9763f0871df228fb:0ddf5b54490cc1c036def6a03cfb8e4e$" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/examples/AnimationTexture/kaijunicorn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/AnimationTexture/kaijunicorn.png -------------------------------------------------------------------------------- /src/examples/AnimationTexture/kaijunicorn.tps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | fileFormatVersion 5 | 4 6 | texturePackerVersion 7 | 5.4.0 8 | autoSDSettings 9 | 10 | 11 | scale 12 | 1 13 | extension 14 | 15 | spriteFilter 16 | 17 | acceptFractionalValues 18 | 19 | maxTextureSize 20 | 21 | width 22 | -1 23 | height 24 | -1 25 | 26 | 27 | 28 | allowRotation 29 | 30 | shapeDebug 31 | 32 | dpi 33 | 72 34 | dataFormat 35 | json 36 | textureFileName 37 | kaijunicorn.png 38 | flipPVR 39 | 40 | pvrCompressionQuality 41 | PVR_QUALITY_NORMAL 42 | atfCompressData 43 | 44 | mipMapMinSize 45 | 32768 46 | etc1CompressionQuality 47 | ETC1_QUALITY_LOW_PERCEPTUAL 48 | etc2CompressionQuality 49 | ETC2_QUALITY_LOW_PERCEPTUAL 50 | dxtCompressionMode 51 | DXT_PERCEPTUAL 52 | jxrColorFormat 53 | JXR_YUV444 54 | jxrTrimFlexBits 55 | 0 56 | jxrCompressionLevel 57 | 0 58 | ditherType 59 | PngQuantLow 60 | backgroundColor 61 | 0 62 | libGdx 63 | 64 | filtering 65 | 66 | x 67 | Linear 68 | y 69 | Linear 70 | 71 | 72 | shapePadding 73 | 0 74 | jpgQuality 75 | 80 76 | pngOptimizationLevel 77 | 1 78 | webpQualityLevel 79 | 101 80 | textureSubPath 81 | 82 | atfFormats 83 | 84 | textureFormat 85 | png8 86 | borderPadding 87 | 0 88 | maxTextureSize 89 | 90 | width 91 | 2048 92 | height 93 | 2048 94 | 95 | fixedTextureSize 96 | 97 | width 98 | -1 99 | height 100 | -1 101 | 102 | algorithmSettings 103 | 104 | algorithm 105 | MaxRects 106 | freeSizeMode 107 | Best 108 | sizeConstraints 109 | AnySize 110 | forceSquared 111 | 112 | maxRects 113 | 114 | heuristic 115 | Best 116 | 117 | basic 118 | 119 | sortBy 120 | Best 121 | order 122 | Ascending 123 | 124 | polygon 125 | 126 | alignToGrid 127 | 1 128 | 129 | 130 | dataFileNames 131 | 132 | data 133 | 134 | name 135 | kaijunicorn.json 136 | 137 | 138 | multiPack 139 | 140 | forceIdenticalLayout 141 | 142 | outputFormat 143 | RGBA8888 144 | alphaHandling 145 | ClearTransparentPixels 146 | contentProtection 147 | 148 | key 149 | 150 | 151 | autoAliasEnabled 152 | 153 | trimSpriteNames 154 | 155 | prependSmartFolderName 156 | 157 | autodetectAnimations 158 | 159 | globalSpriteSettings 160 | 161 | scale 162 | 1 163 | scaleMode 164 | Smooth 165 | extrude 166 | 1 167 | trimThreshold 168 | 1 169 | trimMargin 170 | 1 171 | trimMode 172 | Trim 173 | tracerTolerance 174 | 200 175 | heuristicMask 176 | 177 | defaultPivotPoint 178 | 0.5,0.5 179 | writePivotPoints 180 | 181 | 182 | individualSpriteSettings 183 | 184 | kaijunicorn1.png 185 | kaijunicorn2.png 186 | kaijunicorn3.png 187 | 188 | pivotPoint 189 | 0.5,0.5 190 | spriteScale 191 | 1 192 | scale9Enabled 193 | 194 | scale9Borders 195 | 12,16,24,32 196 | scale9Paddings 197 | 12,16,24,32 198 | scale9FromFile 199 | 200 | 201 | 202 | fileList 203 | 204 | kaijunicorn1.png 205 | kaijunicorn2.png 206 | kaijunicorn3.png 207 | 208 | ignoreFileList 209 | 210 | replaceList 211 | 212 | ignoredWarnings 213 | 214 | commonDivisorX 215 | 1 216 | commonDivisorY 217 | 1 218 | packNormalMaps 219 | 220 | autodetectNormalMaps 221 | 222 | normalMapFilter 223 | 224 | normalMapSuffix 225 | 226 | normalMapSheetFileName 227 | 228 | exporterProperties 229 | 230 | 231 | 232 | -------------------------------------------------------------------------------- /src/examples/AnimationTexture/kaijunicorn1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/AnimationTexture/kaijunicorn1.png -------------------------------------------------------------------------------- /src/examples/AnimationTexture/kaijunicorn2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/AnimationTexture/kaijunicorn2.png -------------------------------------------------------------------------------- /src/examples/AnimationTexture/kaijunicorn3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/AnimationTexture/kaijunicorn3.png -------------------------------------------------------------------------------- /src/examples/AnimationTexture/texture_animation.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Rick Battagline / https://embed.com/wasm 3 | */ 4 | 5 | import {WebGLRenderingContext} from '../../WebGL'; 6 | 7 | const VERTEX_SHADER_CODE: string = `#version 300 es 8 | precision highp float; 9 | 10 | in vec2 position; 11 | in vec2 tex_coord; 12 | 13 | out vec2 tc; 14 | 15 | void main() { 16 | gl_Position = vec4(position, 0.0, 1.0); 17 | tc = tex_coord; 18 | } 19 | `; 20 | // THIS IS THE FRAGMENT SHADER 21 | const FRAGMENT_SHADER_CODE: string = `#version 300 es 22 | precision highp float; 23 | 24 | in vec2 tc; 25 | 26 | uniform sampler2D sampler; 27 | 28 | out vec4 color; 29 | 30 | void main() { 31 | color = texture( sampler, tc ); 32 | } 33 | `; 34 | 35 | // initialize webgl 36 | var gl = new WebGLRenderingContext('cnvs', 'webgl2'); 37 | 38 | // ImageData, createImage, imageReady, 39 | var image_id = gl.createImage('kaijunicorn.png'); 40 | var image_ready: bool = false; 41 | 42 | let vertex_shader = gl.createShader(gl.VERTEX_SHADER); 43 | gl.shaderSource(vertex_shader, VERTEX_SHADER_CODE); 44 | gl.compileShader(vertex_shader); 45 | 46 | let fragment_shader = gl.createShader(gl.FRAGMENT_SHADER); 47 | gl.shaderSource(fragment_shader, FRAGMENT_SHADER_CODE); 48 | gl.compileShader(fragment_shader); 49 | 50 | let program = gl.createProgram(); 51 | 52 | gl.attachShader(program, vertex_shader); 53 | gl.attachShader(program, fragment_shader); 54 | 55 | gl.linkProgram(program); 56 | 57 | gl.useProgram(program); 58 | 59 | let buffer = gl.createBuffer(); 60 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 61 | 62 | let position_al = gl.getAttribLocation(program, 'position'); 63 | gl.enableVertexAttribArray(position_al); 64 | 65 | let tex_coord_al = gl.getAttribLocation(program, 'tex_coord'); 66 | gl.enableVertexAttribArray(tex_coord_al); 67 | 68 | gl.enable(gl.BLEND); 69 | gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); 70 | 71 | let frame_num = 0; 72 | // frame 44 x 198 73 | // prettier-ignore 74 | let frame_1: StaticArray = [ 75 | // x y u v 76 | -0.15, -0.2, 0.0, 0.01, 77 | -0.15, 0.2, 0.0, 0.33, 78 | 0.15, -0.2, 0.95, 0.01, 79 | 0.15, 0.2, 0.95, 0.33, 80 | ]; 81 | 82 | // prettier-ignore 83 | let frame_2: StaticArray = [ 84 | -0.15, -0.2, 0.0, 0.33, 85 | -0.15, 0.2, 0.0, 0.66, 86 | 0.15, -0.2, 0.95, 0.33, 87 | 0.15, 0.2, 0.95, 0.66, 88 | ]; 89 | 90 | // prettier-ignore 91 | let frame_3: StaticArray = [ 92 | -0.15, -0.2, 0.0, 0.66, 93 | -0.15, 0.2, 0.0, 0.999, 94 | 0.15, -0.2, 0.95, 0.66, 95 | 0.15, 0.2, 0.95, 0.999, 96 | ]; 97 | 98 | let texture = gl.createTexture(); 99 | let sampler = gl.getUniformLocation(program, 'sampler'); 100 | let time_left: i32 = 100; 101 | 102 | export function displayLoop(delta: i32): void { 103 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 104 | gl.clear(gl.COLOR_BUFFER_BIT); 105 | 106 | if (image_ready == false) { 107 | if (gl.imageReady(image_id) == false) { 108 | return; 109 | } 110 | 111 | gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); 112 | gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, +true); 113 | gl.activeTexture(gl.TEXTURE0); 114 | gl.bindTexture(gl.TEXTURE_2D, texture); 115 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 116 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 117 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image_id); 118 | 119 | gl.uniform1i(sampler, 0); 120 | image_ready = true; 121 | } 122 | 123 | if (time_left <= 0) { 124 | if (frame_num == 3) { 125 | frame_num = 0; 126 | } else { 127 | frame_num++; 128 | } 129 | time_left = 100; 130 | } else { 131 | time_left -= delta; 132 | } 133 | 134 | if (frame_num == 0) { 135 | gl.bufferData(gl.ARRAY_BUFFER, frame_3, gl.STATIC_DRAW); 136 | } else if (frame_num == 1) { 137 | gl.bufferData(gl.ARRAY_BUFFER, frame_2, gl.STATIC_DRAW); 138 | } else if (frame_num == 2) { 139 | gl.bufferData(gl.ARRAY_BUFFER, frame_3, gl.STATIC_DRAW); 140 | } else { 141 | gl.bufferData(gl.ARRAY_BUFFER, frame_1, gl.STATIC_DRAW); 142 | } 143 | 144 | //vertexAttribPointer attribute | dimensions | data type | normalize | stride bytes | offset bytes 145 | gl.vertexAttribPointer(position_al, 2, gl.FLOAT, +false, 16, 0); 146 | gl.vertexAttribPointer(tex_coord_al, 2, gl.FLOAT, +false, 16, 8); 147 | 148 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, frame_1.length / 4); 149 | } 150 | -------------------------------------------------------------------------------- /src/examples/ColorTriangle/README.md: -------------------------------------------------------------------------------- 1 | # Color Triangle 2 | 3 | This example adds a color value to the *Hello World Triangle* example. -------------------------------------------------------------------------------- /src/examples/ColorTriangle/color_triangle.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Rick Battagline / https://embed.com/wasm 3 | */ 4 | 5 | import {WebGLRenderingContext} from '../../WebGL'; 6 | 7 | const VERTEX_SHADER_CODE: string = `#version 300 es 8 | precision highp float; 9 | 10 | layout(location = 0) in vec2 position; 11 | layout(location = 1) in vec3 color; 12 | out vec4 c; 13 | 14 | void main() { 15 | gl_Position = vec4( position, 0.0, 1.0 ); 16 | c = vec4(color, 1.0); 17 | } 18 | `; 19 | // THIS IS THE FRAGMENT SHADER 20 | const FRAGMENT_SHADER_CODE: string = `#version 300 es 21 | precision highp float; 22 | in vec4 c; 23 | out vec4 color; 24 | 25 | void main() { 26 | color = c; 27 | } 28 | `; 29 | 30 | // initialize webgl 31 | var gl = new WebGLRenderingContext('cnvs', 'webgl2'); 32 | 33 | let vertex_shader = gl.createShader(gl.VERTEX_SHADER); 34 | gl.shaderSource(vertex_shader, VERTEX_SHADER_CODE); 35 | gl.compileShader(vertex_shader); 36 | 37 | let fragment_shader = gl.createShader(gl.FRAGMENT_SHADER); 38 | gl.shaderSource(fragment_shader, FRAGMENT_SHADER_CODE); 39 | gl.compileShader(fragment_shader); 40 | 41 | let program = gl.createProgram(); 42 | 43 | gl.attachShader(program, vertex_shader); 44 | gl.attachShader(program, fragment_shader); 45 | 46 | gl.linkProgram(program); 47 | 48 | gl.useProgram(program); 49 | 50 | let buffer = gl.createBuffer(); 51 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 52 | 53 | let position_al = gl.getAttribLocation(program, 'position'); 54 | 55 | let color_al = gl.getAttribLocation(program, 'color'); 56 | 57 | // prettier-ignore 58 | let line_data: StaticArray = [ 59 | // X Y R G B 60 | 0.0, 0.5, 1.0, 0.0, 0.0, 61 | -0.5, -0.5, 0.0, 1.0, 0.0, 62 | 0.5, -0.5, 0.0, 0.0, 1.0, 63 | ]; 64 | 65 | gl.enableVertexAttribArray(position_al); 66 | gl.enableVertexAttribArray(color_al); 67 | 68 | export function displayLoop(delta: i32): void { 69 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 70 | gl.clear(gl.COLOR_BUFFER_BIT); 71 | 72 | gl.bufferData(gl.ARRAY_BUFFER, line_data, gl.STATIC_DRAW); 73 | 74 | //vertexAttribPointer attribute | dimensions | data type | normalize | stride bytes | offset bytes 75 | gl.vertexAttribPointer(position_al, 2, gl.FLOAT, +false, 20, 0); 76 | gl.vertexAttribPointer(color_al, 3, gl.FLOAT, +false, 20, 8); 77 | 78 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, line_data.length / 5); 79 | } 80 | -------------------------------------------------------------------------------- /src/examples/ColorTriangle/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Color Triangle Demo 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 | 72 | 73 | -------------------------------------------------------------------------------- /src/examples/ColorTriangleRotate/README.md: -------------------------------------------------------------------------------- 1 | # Rotating color triangle 2 | 3 | This takes the color triangle example and rotates it around the z-axis with a new rotate function: 4 | 5 | ``` 6 | function rotate(theta: f32): void { //u32 { 7 | 8 | for (var coord_i: i32 = 0; coord_i < line_data.length; coord_i += 5) { 9 | let x: f32 = line_data[coord_i]; 10 | let y: f32 = line_data[coord_i + 1]; 11 | 12 | let x1: f32 = x * Mathf.cos(theta) - y * Mathf.sin(theta); 13 | 14 | let y1: f32 = y * Mathf.cos(theta) + x * Mathf.sin(theta); 15 | 16 | line_data[coord_i] = x1; 17 | line_data[coord_i + 1] = y1; 18 | } 19 | return; 20 | } 21 | ``` -------------------------------------------------------------------------------- /src/examples/ColorTriangleRotate/color_triangle_rotate.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Rick Battagline / https://embed.com/wasm 3 | */ 4 | 5 | import {WebGLRenderingContext} from '../../WebGL'; 6 | 7 | const VERTEX_SHADER_CODE: string = `#version 300 es 8 | precision highp float; 9 | 10 | layout(location = 0) in vec2 position; 11 | layout(location = 1) in vec3 color; 12 | out vec4 c; 13 | 14 | void main() { 15 | gl_Position = vec4( position, 0.0, 1.0 ); 16 | c = vec4(color, 1.0); 17 | } 18 | `; 19 | // THIS IS THE FRAGMENT SHADER 20 | const FRAGMENT_SHADER_CODE: string = `#version 300 es 21 | precision highp float; 22 | in vec4 c; 23 | out vec4 color; 24 | 25 | void main() { 26 | color = c; 27 | } 28 | `; 29 | 30 | // initialize webgl 31 | var gl = new WebGLRenderingContext('cnvs', 'webgl2'); 32 | 33 | let vertex_shader = gl.createShader(gl.VERTEX_SHADER); 34 | gl.shaderSource(vertex_shader, VERTEX_SHADER_CODE); 35 | gl.compileShader(vertex_shader); 36 | 37 | let fragment_shader = gl.createShader(gl.FRAGMENT_SHADER); 38 | gl.shaderSource(fragment_shader, FRAGMENT_SHADER_CODE); 39 | gl.compileShader(fragment_shader); 40 | 41 | let program = gl.createProgram(); 42 | 43 | gl.attachShader(program, vertex_shader); 44 | gl.attachShader(program, fragment_shader); 45 | 46 | gl.linkProgram(program); 47 | 48 | gl.useProgram(program); 49 | 50 | let buffer = gl.createBuffer(); 51 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 52 | 53 | let position_al = gl.getAttribLocation(program, 'position'); 54 | 55 | let color_al = gl.getAttribLocation(program, 'color'); 56 | 57 | // prettier-ignore 58 | let line_data: StaticArray = [ 59 | // X Y R G B 60 | 0.0, 0.5, 1.0, 0.0, 0.0, 61 | -0.55, -0.5, 0.0, 1.0, 0.0, 62 | 0.55, -0.5, 0.0, 0.0, 1.0, 63 | ]; 64 | 65 | gl.enableVertexAttribArray(position_al); 66 | gl.enableVertexAttribArray(color_al); 67 | 68 | function rotate(theta: f32): void { 69 | for (var coord_i: i32 = 0; coord_i < line_data.length; coord_i += 5) { 70 | let x: f32 = line_data[coord_i]; 71 | let y: f32 = line_data[coord_i + 1]; 72 | 73 | let x1: f32 = x * Mathf.cos(theta) - y * Mathf.sin(theta); 74 | 75 | let y1: f32 = y * Mathf.cos(theta) + x * Mathf.sin(theta); 76 | 77 | line_data[coord_i] = x1; 78 | line_data[coord_i + 1] = y1; 79 | } 80 | return; 81 | } 82 | export function displayLoop(delta: i32): void { 83 | let r: f32 = delta / 10000.0; 84 | rotate(r); 85 | 86 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 87 | gl.clear(gl.COLOR_BUFFER_BIT); 88 | 89 | gl.bufferData(gl.ARRAY_BUFFER, line_data, gl.DYNAMIC_DRAW); 90 | 91 | //vertexAttribPointer attribute | dimensions | data type | normalize | stride bytes | offset bytes 92 | gl.vertexAttribPointer(position_al, 2, gl.FLOAT, +false, 20, 0); 93 | gl.vertexAttribPointer(color_al, 3, gl.FLOAT, +false, 20, 8); 94 | 95 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, line_data.length / 5); 96 | } 97 | -------------------------------------------------------------------------------- /src/examples/ColorTriangleRotate/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Color Triangle with Rotation 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 | 72 | 73 | -------------------------------------------------------------------------------- /src/examples/Cube/README.md: -------------------------------------------------------------------------------- 1 | # Cube 2 | 3 | This example renderes a multicolor spinning cube. There is no lighting on this cube, so the faces had to each be a different color to make it obvious that you are looking at a cube. -------------------------------------------------------------------------------- /src/examples/Cube/cube.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Rick Battagline / https://embed.com/wasm 3 | */ 4 | 5 | import {WebGLRenderingContext, WebGLShader, WebGLProgram} from '../../WebGL'; 6 | 7 | const VERTEX_SHADER_CODE: string = `#version 300 es 8 | precision highp float; 9 | 10 | in vec3 position; 11 | in vec3 color; 12 | out vec4 c; 13 | 14 | void main() { 15 | mat4 mRotateTranslate = mat4( 16 | 1.0, 0.0, 0.0, 0.0, // column 1 17 | 0.0, cos(-0.2),-sin(-0.2), -0.2, // column 2 18 | 0.0, sin(-0.0), cos(-0.2), 0.0, // column 3 19 | 0.0, 0.0, 0.0, 1.0 // column 4 20 | ); 21 | 22 | gl_Position = vec4( position, 1.0 ) * mRotateTranslate; 23 | c = vec4(color, 1.0); 24 | } 25 | `; 26 | 27 | // THIS IS THE FRAGMENT SHADER 28 | const FRAGMENT_SHADER_CODE: string = `#version 300 es 29 | precision highp float; 30 | in vec4 c; 31 | out vec4 color; 32 | 33 | void main() { 34 | color = c; 35 | } 36 | `; 37 | 38 | // initialize webgl 39 | var gl = new WebGLRenderingContext('cnvs', 'webgl2'); 40 | 41 | let vertex_shader: WebGLShader = gl.createShader(gl.VERTEX_SHADER); 42 | gl.shaderSource(vertex_shader, VERTEX_SHADER_CODE); 43 | gl.compileShader(vertex_shader); 44 | 45 | let fragment_shader: WebGLShader = gl.createShader(gl.FRAGMENT_SHADER); 46 | gl.shaderSource(fragment_shader, FRAGMENT_SHADER_CODE); 47 | gl.compileShader(fragment_shader); 48 | 49 | let program: WebGLProgram = gl.createProgram(); 50 | 51 | gl.attachShader(program, vertex_shader); 52 | gl.attachShader(program, fragment_shader); 53 | 54 | gl.linkProgram(program); 55 | 56 | gl.useProgram(program); 57 | 58 | let buffer = gl.createBuffer(); 59 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 60 | 61 | let position_al = gl.getAttribLocation(program, 'position'); 62 | gl.enableVertexAttribArray(position_al); 63 | 64 | let color_al = gl.getAttribLocation(program, 'color'); 65 | gl.enableVertexAttribArray(color_al); 66 | 67 | gl.enable(gl.DEPTH_TEST); 68 | 69 | // prettier-ignore 70 | let cube_data: StaticArray> = [ 71 | // front face 72 | // X Y Z R G B 73 | [ 74 | -0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 75 | -0.5, 0.5, 0.5, 1.0, 0.0, 0.0, 76 | 0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 77 | 0.5, 0.5, 0.5, 1.0, 0.0, 0.0, 78 | ], 79 | // back face 80 | [ 81 | -0.5, -0.5, -0.5, 0.0, 1.0, 0.0, 82 | -0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 83 | 0.5, -0.5, -0.5, 0.0, 1.0, 0.0, 84 | 0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 85 | ], 86 | // left face 87 | [ 88 | -0.5, -0.5, -0.5, 0.0, 0.0, 1.0, 89 | -0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 90 | -0.5, 0.5, -0.5, 0.0, 0.0, 1.0, 91 | -0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 92 | ], 93 | // right face 94 | [ 95 | 0.5, -0.5, -0.5, 1.0, 0.7, 0.0, 96 | 0.5, -0.5, 0.5, 1.0, 0.7, 0.0, 97 | 0.5, 0.5, -0.5, 1.0, 0.7, 0.0, 98 | 0.5, 0.5, 0.5, 1.0, 0.7, 0.0, 99 | ], 100 | // top face 101 | [ 102 | -0.5, 0.5, -0.5, 1.0, 0.0, 0.7, 103 | -0.5, 0.5, 0.5, 1.0, 0.0, 0.7, 104 | 0.5, 0.5, -0.5, 1.0, 0.0, 0.7, 105 | 0.5, 0.5, 0.5, 1.0, 0.0, 0.7, 106 | ], 107 | // bottom face 108 | [ 109 | -0.5, -0.5, -0.5, 0.0, 1.0, 0.7, 110 | -0.5, -0.5, 0.5, 0.0, 1.0, 0.7, 111 | 0.5, -0.5, -0.5, 0.0, 1.0, 0.7, 112 | 0.5, -0.5, 0.5, 0.0, 1.0, 0.7, 113 | ] 114 | ]; 115 | 116 | function rotate(theta: f32): void { 117 | for (var i: i32 = 0; i < cube_data.length; i++) { 118 | for (var coord_i: i32 = 0; coord_i < cube_data[i].length; coord_i += 6) { 119 | let x: f32 = cube_data[i][coord_i]; 120 | let z: f32 = cube_data[i][coord_i + 2]; 121 | 122 | let x1: f32 = x * Mathf.cos(theta) - z * Mathf.sin(theta); 123 | 124 | let z1: f32 = z * Mathf.cos(theta) + x * Mathf.sin(theta); 125 | 126 | cube_data[i][coord_i] = x1; 127 | cube_data[i][coord_i + 2] = z1; 128 | } 129 | } 130 | return; 131 | } 132 | 133 | export function displayLoop(delta: i32): void { 134 | let r: f32 = delta / 10000.0; 135 | rotate(r); 136 | 137 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 138 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 139 | 140 | for (var i: i32 = 0; i < 6; i++) { 141 | gl.bufferData(gl.ARRAY_BUFFER, cube_data[i], gl.DYNAMIC_DRAW); 142 | // dimensions | data_type | normalize | stride | offset 143 | gl.vertexAttribPointer(position_al, 3, gl.FLOAT, +false, 24, 0); 144 | gl.vertexAttribPointer(color_al, 3, gl.FLOAT, +false, 24, 12); 145 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/examples/Cube/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Cube Example 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 | 72 | 73 | -------------------------------------------------------------------------------- /src/examples/HelloWorldTriangle/README.md: -------------------------------------------------------------------------------- 1 | #Hello World Triangle 2 | 3 | The triangle is the most basic of graphical programs. When I have read a books on OpenGL / WebGL / DirectX, they always begin with a program that draws a simple triangle. 4 | 5 | ``` 6 | asc triangle.asc --extension asc --runtime stub --importMemory -o triangle.wasm 7 | ``` -------------------------------------------------------------------------------- /src/examples/HelloWorldTriangle/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Hello World Triangle Example 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 | 65 | 66 | -------------------------------------------------------------------------------- /src/examples/HelloWorldTriangle/triangle.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Rick Battagline / https://embed.com/wasm 3 | */ 4 | 5 | import {WebGLRenderingContext, WebGLShader, WebGLProgram, WebGLBuffer, GLint} from '../../WebGL'; 6 | 7 | const VERTEX_SHADER_CODE: string = /*glsl*/ `#version 300 es 8 | precision highp float; 9 | 10 | in vec2 position; 11 | 12 | void main() { 13 | gl_Position = vec4( position, 0.0, 1.0 ); 14 | } 15 | `; 16 | 17 | const FRAGMENT_SHADER_CODE: string = /*glsl*/ `#version 300 es 18 | precision highp float; 19 | out vec4 color; 20 | 21 | void main() { 22 | color = vec4( 1.0, 0.0, 0.0, 1.0 ); 23 | } 24 | `; 25 | 26 | // initialize webgl 27 | var gl = new WebGLRenderingContext('cnvs', 'webgl2'); 28 | 29 | let vertex_shader: WebGLShader = gl.createShader(gl.VERTEX_SHADER); 30 | gl.shaderSource(vertex_shader, VERTEX_SHADER_CODE); 31 | gl.compileShader(vertex_shader); 32 | 33 | let fragment_shader: WebGLShader = gl.createShader(gl.FRAGMENT_SHADER); 34 | gl.shaderSource(fragment_shader, FRAGMENT_SHADER_CODE); 35 | gl.compileShader(fragment_shader); 36 | 37 | let program: WebGLProgram = gl.createProgram(); 38 | 39 | gl.attachShader(program, vertex_shader); 40 | gl.attachShader(program, fragment_shader); 41 | 42 | gl.linkProgram(program); 43 | 44 | gl.useProgram(program); 45 | 46 | let buffer: WebGLBuffer = gl.createBuffer(); 47 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 48 | 49 | let position_al: GLint = gl.getAttribLocation(program, 'position'); 50 | gl.enableVertexAttribArray(position_al); 51 | 52 | // prettier-ignore 53 | let triangle_data: StaticArray = [ 54 | 0.0, 0.5, 55 | -0.5, -0.5, 56 | 0.5, -0.5, 57 | ]; 58 | 59 | export function displayLoop(): void { 60 | // R G B A 61 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 62 | gl.clear(gl.COLOR_BUFFER_BIT); 63 | 64 | gl.bufferData(gl.ARRAY_BUFFER, triangle_data, gl.STATIC_DRAW); 65 | 66 | // attribute | dimensions | data_type | normalize | stride | offset 67 | gl.vertexAttribPointer(position_al, 2, gl.FLOAT, +false, 0, 0); 68 | 69 | // mode | first vertex | count 70 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, 3); 71 | } 72 | -------------------------------------------------------------------------------- /src/examples/InstancedSprites/README.md: -------------------------------------------------------------------------------- 1 | # Instanced Sprites 2 | 3 | # Instanced Sprites 4 | 5 | This demo uses instanced rendering to render 500,000 sprites at once. -------------------------------------------------------------------------------- /src/examples/InstancedSprites/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Instanced Sprites Example 8 | 9 | 10 | 11 |
12 | sprites: fps: 0 13 |
14 |
15 | 16 |
17 | 18 | 87 | 88 | -------------------------------------------------------------------------------- /src/examples/InstancedSprites/instanced_sprites.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Rick Battagline / https://embed.com 3 | */ 4 | 5 | // prettier-ignore 6 | import { 7 | FRAGMENT_SHADER, VERTEX_SHADER, ARRAY_BUFFER, DYNAMIC_DRAW, 8 | STATIC_DRAW, FLOAT, FALSE, COLOR_BUFFER_BIT, TRIANGLES, 9 | UNPACK_FLIP_Y_WEBGL, UNPACK_PREMULTIPLY_ALPHA_WEBGL, 10 | SRC_ALPHA, ONE_MINUS_SRC_ALPHA, DEPTH_TEST, BLEND, STENCIL_TEST, 11 | TEXTURE0, TEXTURE_2D, TEXTURE_MAG_FILTER, NEAREST, 12 | TEXTURE_MIN_FILTER, RGBA, UNSIGNED_BYTE, CULL_FACE, 13 | clearColor, clear, imageReady, pixelStorei, 14 | uniform1i, drawArraysInstanced, createImage, 15 | bindTexture, texParameteri, texImage2D, 16 | blendFunc, disable, enable, activeTexture, 17 | createShader, bindBuffer, getAttribLocation, 18 | vertexAttribPointer, vertexAttribDivisor, 19 | bindVertexArray, enableVertexAttribArray, 20 | createBuffer, bufferData, createVertexArray, 21 | shaderSource, compileShader, createProgram, 22 | attachShader, linkProgram, useProgram, 23 | createTexture, getUniformLocation, viewport, 24 | createContextFromCanvas, WebGLRenderingContextId, 25 | WebGLShader, ImageData, WebGLUniformLocation, 26 | WebGLBuffer, GLint, WebGLProgram, WebGLTexture, WebGLVertexArrayObject, 27 | } from "../../WebGL"; 28 | 29 | const VERTEX_SHADER_CODE: string = /*glsl*/ `#version 300 es 30 | precision mediump float; 31 | layout (location = 0) in vec2 objPosition; 32 | layout (location = 1) in vec2 position; 33 | layout (location = 2) in vec2 tex_coord; 34 | 35 | out vec2 tc; 36 | 37 | // 1. 0.0, 0.0 to 0.5, 0.5 38 | // 2. 0.5, 0.0 to 1.0, 0.5 39 | // 3. 0.0, 0.5 to 0.5, 1.0 40 | // 4. 0.5, 0.5 to 1.0, 1.0 41 | const float u_start[4] = float[4](0.0, 0.5, 0.0, 0.5); 42 | const float v_start[4] = float[4](0.0, 0.0, 0.5, 0.5); 43 | 44 | void main() { 45 | 46 | gl_Position = vec4(position+objPosition, 0.0, 1.0); 47 | // gl_InstanceID 48 | int instance_sprite = gl_InstanceID & 3; 49 | tc.x = tex_coord.x * 0.5 + u_start[instance_sprite]; 50 | tc.y = tex_coord.y * 0.5 + v_start[instance_sprite]; 51 | } 52 | `; /* end vertex shader */ 53 | 54 | const FRAGMENT_SHADER_CODE: string = /*glsl*/ `#version 300 es 55 | precision mediump float; 56 | in vec2 tc; 57 | 58 | uniform sampler2D sampler; 59 | 60 | out vec4 color; 61 | 62 | void main() { 63 | color = texture( sampler, tc ); 64 | } 65 | `; /* end fragment shader */ 66 | 67 | // initialize webgl 68 | const kaijunicornMax: i32 = 1_000_000; 69 | var kaijunicornCount: i32 = 0; 70 | 71 | var gl: WebGLRenderingContextId = createContextFromCanvas('cnvs', 'webgl2'); 72 | 73 | var image_id: ImageData = createImage('kaijunicorn-sheet.png'); 74 | var image_ready: bool = false; 75 | 76 | let vertex_shader: WebGLShader = createShader(gl, VERTEX_SHADER); 77 | shaderSource(gl, vertex_shader, VERTEX_SHADER_CODE); 78 | compileShader(gl, vertex_shader); 79 | 80 | let fragment_shader: WebGLShader = createShader(gl, FRAGMENT_SHADER); 81 | shaderSource(gl, fragment_shader, FRAGMENT_SHADER_CODE); 82 | compileShader(gl, fragment_shader); 83 | 84 | let program: WebGLProgram = createProgram(gl); 85 | 86 | attachShader(gl, program, vertex_shader); 87 | attachShader(gl, program, fragment_shader); 88 | 89 | linkProgram(gl, program); 90 | 91 | useProgram(gl, program); 92 | 93 | let buffer: WebGLBuffer = createBuffer(gl); 94 | bindBuffer(gl, ARRAY_BUFFER, buffer); 95 | 96 | let position_al: GLint = getAttribLocation(gl, program, 'position'); 97 | let obj_position_al: GLint = getAttribLocation(gl, program, 'objPosition'); 98 | let tex_coord_al: GLint = getAttribLocation(gl, program, 'tex_coord'); 99 | 100 | // prettier-ignore 101 | let quad_data: StaticArray = [ 102 | // x y u v 103 | -0.05, 0.05, 0.0, 1.0, 104 | -0.05, -0.05, 0.0, 0.0, 105 | 0.05, -0.05, 1.0, 0.0, 106 | 107 | -0.05, 0.05, 0.0, 1.0, 108 | 0.05, -0.05, 1.0, 0.0, 109 | 0.05, 0.05, 1.0, 1.0, 110 | ]; 111 | 112 | let translation: StaticArray = new StaticArray(kaijunicornMax * 2); 113 | 114 | class Kaijunicorn { 115 | static COUNT: i32 = 0; 116 | public index: i32 = 0; 117 | public dx: f32; 118 | public dy: f32; 119 | 120 | @inline set x(val: f32) { 121 | unchecked(translation[this.index << 1] = val); 122 | } 123 | 124 | @inline get x(): f32 { 125 | return unchecked(translation[this.index << 1]); 126 | } 127 | 128 | @inline set y(val: f32) { 129 | unchecked(translation[(this.index << 1) + 1] = val); 130 | } 131 | 132 | @inline get y(): f32 { 133 | return unchecked(translation[(this.index << 1) + 1]); 134 | } 135 | 136 | constructor() { 137 | this.index = Kaijunicorn.COUNT++; 138 | 139 | this.dx = Mathf.random() / 50.0 - 0.01; 140 | this.dy = Mathf.random() / 50.0 - 0.01; 141 | } 142 | 143 | @inline Move(): void { 144 | this.x += this.dx; 145 | this.y += this.dy; 146 | 147 | this.x %= 1.1; 148 | this.y %= 1.1; 149 | } 150 | } 151 | 152 | var KaijunicornArray: StaticArray = new StaticArray(kaijunicornMax); 153 | 154 | for (var i: i32 = 0; i < kaijunicornMax; i++) { 155 | KaijunicornArray[i] = new Kaijunicorn(); 156 | } 157 | 158 | let texture: WebGLTexture = createTexture(gl); 159 | let sampler: WebGLUniformLocation = getUniformLocation(gl, program, 'sampler'); 160 | 161 | var quadVAO: WebGLVertexArrayObject; 162 | var quadVBO: WebGLBuffer; 163 | var instanceVBO: WebGLBuffer; 164 | 165 | export function init(): void { 166 | viewport(gl, 0, 0, 640, 640); 167 | instanceVBO = createBuffer(gl); 168 | 169 | bindBuffer(gl, ARRAY_BUFFER, instanceVBO); 170 | bufferData(gl, ARRAY_BUFFER, translation, DYNAMIC_DRAW); 171 | 172 | quadVAO = createVertexArray(gl); 173 | quadVBO = createBuffer(gl); 174 | 175 | bindVertexArray(gl, quadVAO); 176 | bindBuffer(gl, ARRAY_BUFFER, quadVBO); 177 | bufferData(gl, ARRAY_BUFFER, quad_data, STATIC_DRAW); 178 | 179 | enableVertexAttribArray(gl, position_al); 180 | vertexAttribPointer(gl, position_al, 2, FLOAT, FALSE, 16, 0); 181 | 182 | enableVertexAttribArray(gl, tex_coord_al); 183 | vertexAttribPointer(gl, tex_coord_al, 2, FLOAT, FALSE, 16, 8); 184 | 185 | bindBuffer(gl, ARRAY_BUFFER, instanceVBO); 186 | 187 | enableVertexAttribArray(gl, obj_position_al); 188 | vertexAttribPointer(gl, obj_position_al, 2, FLOAT, FALSE, 0, 0); 189 | 190 | bindBuffer(gl, ARRAY_BUFFER, 0); 191 | 192 | vertexAttribDivisor(gl, 1, 1); 193 | } 194 | 195 | export function displayLoop(delta: i32): void { 196 | clearColor(gl, 0.0, 0.0, 0.0, 1.0); 197 | clear(gl, COLOR_BUFFER_BIT); 198 | 199 | if (image_ready == false) { 200 | if (imageReady(image_id) == false) { 201 | return; 202 | } 203 | 204 | pixelStorei(gl, UNPACK_FLIP_Y_WEBGL, 1); 205 | pixelStorei(gl, UNPACK_PREMULTIPLY_ALPHA_WEBGL, /*true*/1); 206 | blendFunc(gl, SRC_ALPHA, ONE_MINUS_SRC_ALPHA); 207 | disable(gl, DEPTH_TEST); 208 | enable(gl, BLEND); 209 | enable(gl, CULL_FACE); 210 | 211 | activeTexture(gl, TEXTURE0); 212 | bindTexture(gl, TEXTURE_2D, texture); 213 | texParameteri(gl, TEXTURE_2D, TEXTURE_MIN_FILTER, NEAREST); 214 | texParameteri(gl, TEXTURE_2D, TEXTURE_MAG_FILTER, NEAREST); 215 | texImage2D(gl, TEXTURE_2D, 0, RGBA, RGBA, UNSIGNED_BYTE, image_id); 216 | 217 | uniform1i(gl, sampler, 0); 218 | image_ready = true; 219 | } 220 | 221 | if (kaijunicornCount < kaijunicornMax) { 222 | kaijunicornCount += 500; 223 | } 224 | 225 | for (var i: i32 = 0; i < kaijunicornCount; i++) { 226 | KaijunicornArray[i].Move(); 227 | } 228 | 229 | bindBuffer(gl, ARRAY_BUFFER, instanceVBO); 230 | bufferData(gl, ARRAY_BUFFER, translation, DYNAMIC_DRAW); 231 | 232 | bindVertexArray(gl, quadVAO); 233 | drawArraysInstanced(gl, TRIANGLES, 0, 6, kaijunicornCount); 234 | } 235 | -------------------------------------------------------------------------------- /src/examples/InstancedSprites/kaijunicorn-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/InstancedSprites/kaijunicorn-mini.png -------------------------------------------------------------------------------- /src/examples/InstancedSprites/kaijunicorn-sheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/InstancedSprites/kaijunicorn-sheet.png -------------------------------------------------------------------------------- /src/examples/InstancedSprites/kaijunicorn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/InstancedSprites/kaijunicorn.png -------------------------------------------------------------------------------- /src/examples/Lines/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | WebGL Line Drawing Example 9 | 10 | 11 | 12 |
13 | 14 |
15 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/examples/Lines/render_lines.ts: -------------------------------------------------------------------------------- 1 | import {WebGLRenderingContext, WebGLShader, WebGLProgram, WebGLBuffer, GLint, WebGLUniformLocation} from '../../WebGL'; 2 | 3 | const V_COLOR_LINE_SHADER: string = /*glsl*/ `#version 300 es 4 | precision highp float; 5 | 6 | uniform vec4 u_color; 7 | 8 | in vec2 position; 9 | out vec4 c; 10 | 11 | void main() { 12 | gl_Position = vec4( position, 0.0, 1.0 ); 13 | c = u_color/255.0; 14 | } 15 | `; 16 | 17 | // THIS IS THE FRAGMENT SHADER 18 | const F_SHADER: string = /*glsl*/ `#version 300 es 19 | precision highp float; 20 | 21 | in vec4 c; 22 | out vec4 color; 23 | 24 | void main() { 25 | color = c; 26 | } 27 | `; 28 | 29 | var theta: f32 = 0.0; 30 | 31 | var loop_color: StaticArray> = [ 32 | [0.0, 255.0, 0.0, 255.0], // default layer color 33 | [255.0, 255.0, 0.0, 255.0], // cockpit layer color 34 | [0.0, 255.0, 0.0, 255.0], // wings layer color 35 | [0.0, 255.0, 0.0, 255.0], // wings2 layer color 36 | [255.0, 0.0, 0.0, 255.0], // engine layer color 37 | [0.0, 255.0, 0.0, 255.0], // recoloration layer color 38 | ]; 39 | 40 | var program_id: i32 = -1; 41 | var default_layer: StaticArray = [-0.1, 0.4, -0.2, 0, 0, -0.3, 0.2, 0, 0.1, 0.4, 0.2, 0.3, 0, 0.9, -0.2, 0.3]; 42 | 43 | var cockpit_layer: StaticArray = [-0.1, 0.1, 0, 0.6, 0.1, 0.1]; 44 | 45 | var wings_layer: StaticArray = [0.7, 0.2, 0.2, 0, 0, -0.3]; 46 | 47 | var wings2_layer: StaticArray = [0, -0.3, -0.2, 0, -0.7, 0.2]; 48 | 49 | var engine_layer: StaticArray = [-0.1, -0.2, -0.1, -0.3, 0.1, -0.3, 0.1, -0.2, 0, -0.6]; 50 | 51 | var recoloration_layer: StaticArray = [0.2, 0, 0, -0.3, -0.2, 0, 0, -0.3]; 52 | 53 | var layer_array: StaticArray> = [ 54 | default_layer, 55 | cockpit_layer, 56 | wings_layer, 57 | wings2_layer, 58 | engine_layer, 59 | recoloration_layer, 60 | ]; 61 | 62 | var color_line_program: WebGLProgram; 63 | var gl: WebGLRenderingContext; 64 | 65 | export function init(): void { 66 | gl = new WebGLRenderingContext('cnvs', 'webgl2'); 67 | let color_line_vertex_shader: WebGLShader = gl.createShader(gl.VERTEX_SHADER); 68 | gl.shaderSource(color_line_vertex_shader, V_COLOR_LINE_SHADER); 69 | gl.compileShader(color_line_vertex_shader); 70 | 71 | let fragment_shader: WebGLShader = gl.createShader(gl.FRAGMENT_SHADER); 72 | gl.shaderSource(fragment_shader, F_SHADER); 73 | gl.compileShader(fragment_shader); 74 | 75 | color_line_program = gl.createProgram(); 76 | 77 | gl.attachShader(color_line_program, color_line_vertex_shader); 78 | gl.attachShader(color_line_program, fragment_shader); 79 | 80 | gl.linkProgram(color_line_program); 81 | 82 | gl.useProgram(color_line_program); 83 | // could use mutable import 84 | // let color_location: WebGLUniformLocation = getUniformLocation(gl, color_line_program, "u_color"); 85 | } 86 | /*Array*/ 87 | function drawLines(line_data: StaticArray, color_data: StaticArray): void { 88 | let buffer: WebGLBuffer = gl.createBuffer(); 89 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 90 | store(changetype(line_data) - 8, idof>()); 91 | gl.bufferData(gl.ARRAY_BUFFER, line_data, gl.STATIC_DRAW); 92 | 93 | let position_al: GLint = gl.getAttribLocation(color_line_program, 'position'); 94 | gl.enableVertexAttribArray(position_al); 95 | 96 | let color_location: WebGLUniformLocation = gl.getUniformLocation(color_line_program, 'u_color'); 97 | store(changetype(color_data) - 8, idof>()); 98 | gl.uniform4fv(color_location, color_data); 99 | 100 | const dimensions: i32 = 2; 101 | const data_type: i32 = gl.FLOAT; 102 | const normalize: i32 = +false; 103 | const stride: i32 = 0; 104 | const offset: i32 = 0; 105 | 106 | gl.vertexAttribPointer(position_al, dimensions, data_type, normalize, stride, offset); 107 | 108 | gl.drawArrays(gl.LINE_LOOP, 0, line_data.length / 2); 109 | } 110 | 111 | export function animation_frame(): void { 112 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 113 | gl.clear(gl.COLOR_BUFFER_BIT); 114 | 115 | theta += 0.01; 116 | if (theta >= 6.28318) { 117 | theta = 0.0; 118 | } 119 | 120 | animation(0.001); 121 | 122 | for (var i: i32 = 0; i < layer_array.length; i++) { 123 | let loop_size: i32 = layer_array[i].length; 124 | 125 | let layer: StaticArray = layer_array[i]; //, 126 | let color: StaticArray = loop_color[i]; 127 | 128 | drawLines(layer, color); 129 | } 130 | } 131 | 132 | export function animation(theta: f32): void { 133 | for (var ship_i: i32 = 0; ship_i < layer_array.length; ship_i++) { 134 | const layer = layer_array[ship_i]; 135 | const ship_loop_size = layer.length; 136 | 137 | for (var coord_i: i32 = 0; coord_i < ship_loop_size; coord_i += 2) { 138 | let x: f32 = layer[coord_i]; 139 | let y: f32 = layer[coord_i + 1]; 140 | 141 | let x1: f32 = x * Math.cos(theta) - y * Math.sin(theta); 142 | 143 | let y1: f32 = y * Math.cos(theta) + x * Math.sin(theta); 144 | 145 | layer[coord_i] = x1; 146 | layer[coord_i + 1] = y1; 147 | } 148 | } 149 | return; 150 | } 151 | -------------------------------------------------------------------------------- /src/examples/Material/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Wavefront Object converted to AssemblyScript 8 | 9 | 10 | 11 |
fps:
12 |
13 | 14 |
15 | 16 | 85 | 86 | -------------------------------------------------------------------------------- /src/examples/Material/obj_mat.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Rick Battagline / https://embed.com/wasm 3 | */ 4 | 5 | import {WebGLRenderingContext, WebGLShader, WebGLProgram, WebGLBuffer, GLint, WebGLUniformLocation} from '../../WebGL'; 6 | 7 | import {objArray, matArray, groupArray, VertGroup} from './Robot'; 8 | 9 | const VERTEX_SHADER_CODE: string = `#version 300 es 10 | precision mediump float; 11 | 12 | in vec3 position; 13 | in vec3 normal; 14 | uniform vec3 diffuse; 15 | out vec4 c; 16 | 17 | void main() { 18 | const vec3 light = vec3(0.25, 2.0, -0.5); 19 | float d = clamp( dot( normal, light ), 0.0, 1.0); 20 | vec4 pos = vec4( position, 1.0 ); 21 | 22 | mat4 mRotateTranslate = mat4( 23 | 1.0, 0.0, 0.0, 0.0, // column 1 24 | 0.0, cos(-0.2),-sin(-0.2), -0.2, // column 2 25 | 0.0, sin(-0.0), cos(-0.2), 0.0, // column 3 26 | 0.0, 0.0, 0.0, 1.0 // column 4 27 | ); 28 | 29 | gl_Position = pos * mRotateTranslate; 30 | c = vec4( d + diffuse.r, 31 | d + diffuse.g, 32 | d + diffuse.b, 1.0); 33 | } 34 | `; 35 | 36 | // THIS IS THE FRAGMENT SHADER 37 | const FRAGMENT_SHADER_CODE: string = `#version 300 es 38 | precision highp float; 39 | in vec4 c; 40 | out vec4 color; 41 | 42 | void main() { 43 | color = c; 44 | } 45 | `; 46 | 47 | // initialize webgl 48 | var gl = new WebGLRenderingContext('cnvs', 'webgl2'); 49 | 50 | let vertex_shader: WebGLShader = gl.createShader(gl.VERTEX_SHADER); 51 | gl.shaderSource(vertex_shader, VERTEX_SHADER_CODE); 52 | gl.compileShader(vertex_shader); 53 | 54 | let fragment_shader: WebGLShader = gl.createShader(gl.FRAGMENT_SHADER); 55 | gl.shaderSource(fragment_shader, FRAGMENT_SHADER_CODE); 56 | gl.compileShader(fragment_shader); 57 | 58 | let program: WebGLProgram = gl.createProgram(); 59 | 60 | gl.attachShader(program, vertex_shader); 61 | gl.attachShader(program, fragment_shader); 62 | 63 | gl.linkProgram(program); 64 | 65 | gl.useProgram(program); 66 | 67 | let buffer: WebGLBuffer = gl.createBuffer(); 68 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 69 | 70 | let position_al: GLint = gl.getAttribLocation(program, 'position'); 71 | gl.enableVertexAttribArray(position_al); 72 | 73 | let normal_al: GLint = gl.getAttribLocation(program, 'normal'); 74 | gl.enableVertexAttribArray(normal_al); 75 | 76 | let diffuse: WebGLUniformLocation = gl.getUniformLocation(program, 'diffuse'); 77 | 78 | //diffuse 79 | gl.enable(gl.DEPTH_TEST); 80 | 81 | function rotate(theta: f32): void { 82 | for (var obj_i: i32 = 0; obj_i < objArray.length; obj_i++) { 83 | for (var coord_i: i32 = 0; coord_i < objArray[obj_i].length; coord_i += 8) { 84 | let x: f32 = objArray[obj_i][coord_i]; 85 | let z: f32 = objArray[obj_i][coord_i + 2]; 86 | 87 | let nx: f32 = objArray[obj_i][coord_i + 5]; 88 | let nz: f32 = objArray[obj_i][coord_i + 7]; 89 | 90 | let x1: f32 = x * Mathf.cos(theta) - z * Mathf.sin(theta); 91 | let z1: f32 = z * Mathf.cos(theta) + x * Mathf.sin(theta); 92 | 93 | let nx1: f32 = nx * Mathf.cos(theta) - nz * Mathf.sin(theta); 94 | let nz1: f32 = nz * Mathf.cos(theta) + nx * Mathf.sin(theta); 95 | 96 | objArray[obj_i][coord_i] = x1; 97 | objArray[obj_i][coord_i + 2] = z1; 98 | 99 | objArray[obj_i][coord_i + 5] = nx1; 100 | objArray[obj_i][coord_i + 7] = nz1; 101 | } 102 | } 103 | 104 | return; 105 | } 106 | 107 | var vGroup: VertGroup; 108 | export function displayLoop(delta: i32): void { 109 | let r: f32 = delta / 10000.0; 110 | rotate(r); 111 | 112 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 113 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 114 | 115 | for (var g_i: i32 = 0; g_i < groupArray.length; g_i++) { 116 | vGroup = groupArray[g_i]; 117 | gl.bufferData(gl.ARRAY_BUFFER, objArray[vGroup.obj_index], gl.DYNAMIC_DRAW); 118 | let diffuse_r: f32 = matArray[vGroup.mat_index][4]; 119 | let diffuse_g: f32 = matArray[vGroup.mat_index][5]; 120 | let diffuse_b: f32 = matArray[vGroup.mat_index][6]; 121 | gl.uniform3f(diffuse, diffuse_r, diffuse_g, diffuse_b); 122 | 123 | // dimensions | data_type | normalize | stride | offset 124 | gl.vertexAttribPointer(position_al, 3, gl.FLOAT, +false, 32, 0); 125 | // vertexAttribPointer(gl, tex_uv_al, 2, FLOAT, false, 32, 12); 126 | gl.vertexAttribPointer(normal_al, 3, gl.FLOAT, +false, 32, 20); 127 | gl.drawArrays(gl.TRIANGLES, vGroup.start_face, vGroup.length); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/examples/MousePoint/README.md: -------------------------------------------------------------------------------- 1 | # Mouse Point 2 | 3 | This example renders points that fade away as the mouse moves away from them. It does this with a point class and an array of those points. The point gets activated and the alpha value is set to full opacity. 4 | The point then fades out by altering the alpha value as it moves. The active point data is copied into the array buffer to be rendered on the canvas. -------------------------------------------------------------------------------- /src/examples/MousePoint/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Mouse Point Example 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 | 84 | 85 | -------------------------------------------------------------------------------- /src/examples/MousePoint/mouse_point.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Rick Battagline / https://embed.com 3 | */ 4 | 5 | import {WebGLRenderingContext, WebGLShader, WebGLProgram, WebGLBuffer, GLint, WebGLUniformLocation} from '../../WebGL'; 6 | 7 | // SRC_ALPHA 8 | // ONE_MINUS_SRC_ALPHA 9 | // prettier-ignore 10 | let point_data: StaticArray = [ 11 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 12 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 13 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 14 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 15 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 16 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 17 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 18 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 19 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 20 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 21 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 22 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 23 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 24 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 25 | ]; 26 | 27 | class Point { 28 | public x: f32 = 0.0; 29 | public y: f32 = 0.0; 30 | public alpha: f32 = 1.0; 31 | public visible: bool = false; 32 | public index: i32 = 0; 33 | 34 | constructor(index: i32) { 35 | this.index = index; 36 | } 37 | 38 | public activate(x: f32, y: f32): void { 39 | this.x = x; 40 | this.y = y; 41 | this.visible = true; 42 | this.alpha = 1.0; 43 | } 44 | 45 | public move(): void { 46 | this.alpha -= second_delta * 2; 47 | 48 | if (this.alpha < 0.0) { 49 | this.visible = false; 50 | this.alpha = 0.0; 51 | } 52 | 53 | point_data[this.index * 3] = this.x; 54 | point_data[this.index * 3 + 1] = this.y; 55 | point_data[this.index * 3 + 2] = this.alpha; 56 | } 57 | } 58 | 59 | const VERTEX_SHADER_CODE: string = `#version 300 es 60 | precision highp float; 61 | 62 | layout(location = 0) in vec2 position; 63 | layout(location = 1) in float alpha; 64 | out vec4 c; 65 | 66 | void main() { 67 | gl_Position = vec4( position.x, position.y, 0.0, 1.0 ); 68 | gl_PointSize = 8.0; 69 | float a = clamp(alpha, 0.0, 1.0); 70 | c = vec4(1.0,1.0,0.0,a); 71 | 72 | } 73 | `; 74 | // THIS IS THE FRAGMENT SHADER 75 | const FRAGMENT_SHADER_CODE: string = `#version 300 es 76 | precision highp float; 77 | in vec4 c; 78 | out vec4 color; 79 | 80 | void main() { 81 | color = c; 82 | } 83 | `; 84 | 85 | // initialize webgl 86 | var second_delta: f32 = 0.0; 87 | var gl = new WebGLRenderingContext('cnvs', 'webgl2'); 88 | 89 | let vertex_shader: WebGLShader = gl.createShader(gl.VERTEX_SHADER); 90 | gl.shaderSource(vertex_shader, VERTEX_SHADER_CODE); 91 | gl.compileShader(vertex_shader); 92 | 93 | let fragment_shader: WebGLShader = gl.createShader(gl.FRAGMENT_SHADER); 94 | gl.shaderSource(fragment_shader, FRAGMENT_SHADER_CODE); 95 | gl.compileShader(fragment_shader); 96 | 97 | let program: WebGLProgram = gl.createProgram(); 98 | 99 | gl.attachShader(program, vertex_shader); 100 | gl.attachShader(program, fragment_shader); 101 | 102 | gl.linkProgram(program); 103 | 104 | gl.useProgram(program); 105 | 106 | let buffer: WebGLBuffer = gl.createBuffer(); 107 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 108 | 109 | let position_al: GLint = gl.getAttribLocation(program, 'position'); 110 | gl.enableVertexAttribArray(position_al); 111 | let alpha_al: GLint = gl.getAttribLocation(program, 'alpha'); 112 | gl.enableVertexAttribArray(alpha_al); 113 | 114 | gl.enable(gl.BLEND); 115 | gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); 116 | 117 | let point_index: i32 = 0; 118 | 119 | // prettier-ignore 120 | let point_list: StaticArray = [ 121 | new Point(0), new Point(1), new Point(2), new Point(3), new Point(4), 122 | new Point(5), new Point(6), new Point(7), new Point(8), new Point(9), 123 | new Point(10), new Point(11), new Point(12), new Point(13), new Point(14), 124 | new Point(15), new Point(16), new Point(17), new Point(18), new Point(19), 125 | new Point(20), new Point(21), new Point(22), new Point(23), new Point(24), 126 | new Point(25), new Point(26), new Point(27), new Point(28), new Point(29), 127 | new Point(30), new Point(31), new Point(32), new Point(33), new Point(34), 128 | new Point(35), new Point(36), new Point(37), new Point(38), new Point(39), 129 | new Point(40), new Point(41), new Point(42), new Point(43), new Point(44), 130 | new Point(45), new Point(46), new Point(47), new Point(48), new Point(49), 131 | new Point(50), new Point(51), new Point(52), new Point(53), new Point(54), 132 | new Point(55), new Point(56), new Point(57), new Point(58), new Point(59), 133 | new Point(60), new Point(61), new Point(62), new Point(63), new Point(64), 134 | new Point(65), new Point(66), new Point(67), new Point(68), new Point(69), 135 | ]; 136 | 137 | var prev_x: f32 = 0.0; 138 | var prev_y: f32 = 0.0; 139 | 140 | export function displayLoop(delta: i32, mouse_x: f32, mouse_y: f32): void { 141 | second_delta = delta / 1000.0; 142 | for (let i: i32 = 0; i < point_list.length; i++) { 143 | point_list[i].move(); 144 | } 145 | 146 | if (prev_x != mouse_x || prev_y != mouse_y) { 147 | point_index++; 148 | if (point_index >= point_list.length) { 149 | point_index = 0; 150 | } 151 | point_list[point_index].activate(mouse_x, mouse_y); 152 | prev_x = mouse_x; 153 | prev_y = mouse_y; 154 | } 155 | 156 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 157 | gl.clear(gl.COLOR_BUFFER_BIT); 158 | 159 | gl.bufferData(gl.ARRAY_BUFFER, point_data, gl.DYNAMIC_DRAW); 160 | 161 | //vertexAttribPointer attribute | dimensions | data type | normalize | stride bytes | offset bytes 162 | gl.vertexAttribPointer(position_al, 2, gl.FLOAT, +false, 12, 0); 163 | gl.vertexAttribPointer(alpha_al, 1, gl.FLOAT, +false, 12, 8); 164 | 165 | gl.drawArrays(gl.POINTS, 0, point_list.length); 166 | } 167 | -------------------------------------------------------------------------------- /src/examples/NormalModel/LunarMap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/NormalModel/LunarMap.png -------------------------------------------------------------------------------- /src/examples/NormalModel/LunarMapOG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/NormalModel/LunarMapOG.png -------------------------------------------------------------------------------- /src/examples/NormalModel/LunarNormalMap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/NormalModel/LunarNormalMap.png -------------------------------------------------------------------------------- /src/examples/NormalModel/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Normal Mapped Wavefront Object converted to AssemblyScript 8 | 9 | 10 | 11 |
fps:
12 |
13 | 14 |
15 | 16 | 85 | 86 | -------------------------------------------------------------------------------- /src/examples/NormalModel/moon.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/NormalModel/moon.blend -------------------------------------------------------------------------------- /src/examples/NormalModel/moon.blend1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/NormalModel/moon.blend1 -------------------------------------------------------------------------------- /src/examples/NormalModel/moon.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'moon.blend' 2 | # Material Count: 1 3 | 4 | newmtl Material.001 5 | Ns 225.000000 6 | Ka 1.000000 1.000000 1.000000 7 | Kd 0.800000 0.800000 0.800000 8 | Ks 0.500000 0.500000 0.500000 9 | Ke 0.000000 0.000000 0.000000 10 | Ni 1.450000 11 | d 1.000000 12 | illum 2 13 | map_Bump LunarNormalMap.png 14 | map_Kd LunarMap.png 15 | -------------------------------------------------------------------------------- /src/examples/NormalModel/obj_norm.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Rick Battagline / https://embed.com/wasm 3 | */ 4 | 5 | import { 6 | WebGLRenderingContext, 7 | WebGLShader, 8 | WebGLProgram, 9 | ImageData, 10 | WebGLBuffer, 11 | GLint, 12 | WebGLUniformLocation, 13 | WebGLTexture, 14 | } from '../../WebGL'; 15 | 16 | import {objArray, groupArray, VertGroup, matMapArray} from './Moon_Sphere'; 17 | 18 | // OG CODE 19 | const VERTEX_SHADER_CODE: string = `#version 300 es 20 | precision highp float; 21 | 22 | in vec3 position; 23 | in vec3 normal; 24 | in vec2 tex_uv; 25 | 26 | out vec3 cam_dir; 27 | out vec3 light_dir; 28 | out vec2 tc; 29 | out vec3 norm; 30 | 31 | void main() { 32 | // rotate z axis 33 | 34 | mat4 mRotateTranslate = mat4( 35 | 1.0, 0.0, 0.0, 0.0, // column 1 36 | 0.0, cos(-0.2),-sin(-0.2), -0.2, // column 2 37 | 0.0, sin(-0.0), cos(-0.2), 0.0, // column 3 38 | 0.0, 0.0, 0.0, 1.0 // column 4 39 | ); 40 | 41 | vec3 up = vec3(0.0, -1.0, 0.0); 42 | vec3 light_pos = vec3( 0.0, -0.7, 0.5 ); 43 | float d = dot( up, normal ); 44 | 45 | vec3 tan = cross( up, normal ); 46 | vec3 bitan = cross( normal, tan ); 47 | 48 | vec3 l; 49 | l.x = dot( tan, light_pos ); 50 | l.y = dot( bitan, light_pos ); 51 | l.z = dot( normal, light_pos ); 52 | 53 | light_dir = l; //normalize(l); 54 | 55 | vec3 camera; 56 | camera.x = dot( tan, position ); 57 | camera.y = dot( bitan, position ); 58 | camera.z = dot( normal, position ); 59 | 60 | cam_dir = normalize(camera); 61 | tc = tex_uv; 62 | norm = normal; 63 | 64 | gl_Position = vec4(position, 1.0); 65 | }`; 66 | 67 | // this shader is super kludgy 68 | const FRAGMENT_SHADER_CODE: string = `#version 300 es 69 | precision highp float; 70 | uniform sampler2D normalMap; 71 | uniform sampler2D sampler; 72 | 73 | in vec3 cam_dir; 74 | in vec3 light_dir; 75 | in vec2 tc; 76 | in vec3 norm; 77 | 78 | out vec4 color; 79 | void main (void) 80 | { 81 | vec3 l = normalize(light_dir); 82 | vec3 e = normalize(-cam_dir); 83 | vec3 n = 2.0 * texture(normalMap, tc).rgb - 1.0; 84 | 85 | float kd = clamp(dot(l, n + norm - vec3(0.0, 0.0, 1.0)), 0.1, 1.0); 86 | 87 | vec3 tex_color = texture(sampler, tc).rgb; 88 | vec3 c = kd * tex_color; 89 | 90 | color = vec4( c, 1.0 ); 91 | }`; 92 | 93 | // initialize webgl 94 | var gl = new WebGLRenderingContext('cnvs', 'webgl2'); 95 | 96 | let vertex_shader: WebGLShader = gl.createShader(gl.VERTEX_SHADER); 97 | gl.shaderSource(vertex_shader, VERTEX_SHADER_CODE); 98 | gl.compileShader(vertex_shader); 99 | 100 | let fragment_shader: WebGLShader = gl.createShader(gl.FRAGMENT_SHADER); 101 | gl.shaderSource(fragment_shader, FRAGMENT_SHADER_CODE); 102 | gl.compileShader(fragment_shader); 103 | 104 | let program: WebGLProgram = gl.createProgram(); 105 | 106 | gl.attachShader(program, vertex_shader); 107 | gl.attachShader(program, fragment_shader); 108 | 109 | gl.linkProgram(program); 110 | 111 | gl.useProgram(program); 112 | 113 | let buffer: WebGLBuffer = gl.createBuffer(); 114 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 115 | 116 | let position_al: GLint = gl.getAttribLocation(program, 'position'); 117 | gl.enableVertexAttribArray(position_al); 118 | 119 | let tex_uv_al: GLint = gl.getAttribLocation(program, 'tex_uv'); 120 | gl.enableVertexAttribArray(tex_uv_al); 121 | 122 | let normal_al: GLint = gl.getAttribLocation(program, 'normal'); 123 | gl.enableVertexAttribArray(normal_al); 124 | 125 | let texture: WebGLTexture = gl.createTexture(); 126 | let sampler: WebGLUniformLocation = gl.getUniformLocation(program, 'sampler'); 127 | 128 | let texture_n: WebGLTexture = gl.createTexture(); 129 | let tex_norm: WebGLUniformLocation = gl.getUniformLocation(program, 'normalMap'); 130 | 131 | var image_id: ImageData = gl.createImage(matMapArray[0].diffuse); 132 | var norm_image_id: ImageData = gl.createImage(matMapArray[0].bump); 133 | 134 | var image_ready: bool = false; 135 | 136 | //diffuse 137 | gl.enable(gl.DEPTH_TEST); 138 | 139 | function rotate(theta: f32): void { 140 | for (var obj_i: i32 = 0; obj_i < objArray.length; obj_i++) { 141 | for (var coord_i: i32 = 0; coord_i < objArray[obj_i].length; coord_i += 8) { 142 | let x: f32 = objArray[obj_i][coord_i]; 143 | let z: f32 = objArray[obj_i][coord_i + 2]; 144 | 145 | let nx: f32 = objArray[obj_i][coord_i + 5]; 146 | let nz: f32 = objArray[obj_i][coord_i + 7]; 147 | 148 | let x1: f32 = x * Mathf.cos(theta) + z * Mathf.sin(theta); 149 | let z1: f32 = z * Mathf.cos(theta) - x * Mathf.sin(theta); 150 | 151 | let nx1: f32 = nx * Mathf.cos(theta) + nz * Mathf.sin(theta); 152 | let nz1: f32 = nz * Mathf.cos(theta) - nx * Mathf.sin(theta); 153 | 154 | objArray[obj_i][coord_i] = x1; 155 | objArray[obj_i][coord_i + 2] = z1; 156 | 157 | objArray[obj_i][coord_i + 5] = nx1; 158 | objArray[obj_i][coord_i + 7] = nz1; 159 | } 160 | } 161 | 162 | return; 163 | } 164 | 165 | var vGroup: VertGroup; 166 | export function displayLoop(delta: i32): void { 167 | let r: f32 = delta / 10000.0; 168 | rotate(r); 169 | 170 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 171 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 172 | 173 | if (image_ready == false) { 174 | if (gl.imageReady(image_id) == false || gl.imageReady(norm_image_id) == false) { 175 | return; 176 | } 177 | 178 | gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); 179 | gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, +true); 180 | gl.activeTexture(gl.TEXTURE0); 181 | gl.bindTexture(gl.TEXTURE_2D, texture); 182 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 183 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 184 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image_id); 185 | 186 | gl.activeTexture(gl.TEXTURE1); 187 | gl.bindTexture(gl.TEXTURE_2D, texture_n); 188 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 189 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 190 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, norm_image_id); 191 | 192 | gl.uniform1i(sampler, 0); 193 | image_ready = true; 194 | } 195 | 196 | for (var g_i: i32 = 0; g_i < groupArray.length; g_i++) { 197 | vGroup = groupArray[g_i]; 198 | gl.bufferData(gl.ARRAY_BUFFER, objArray[vGroup.obj_index], gl.DYNAMIC_DRAW); 199 | 200 | // dimensions | data_type | normalize | stride | offset 201 | gl.vertexAttribPointer(position_al, 3, gl.FLOAT, +false, 32, 0); 202 | gl.vertexAttribPointer(tex_uv_al, 2, gl.FLOAT, +false, 32, 12); 203 | gl.vertexAttribPointer(normal_al, 3, gl.FLOAT, +false, 32, 20); 204 | gl.drawArrays(gl.TRIANGLES, vGroup.start_face, vGroup.length); 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /src/examples/NormalModel/reminder.txt: -------------------------------------------------------------------------------- 1 | When you're exporting from Blender, don't forget to triangulate faces. -------------------------------------------------------------------------------- /src/examples/Obj/README.md: -------------------------------------------------------------------------------- 1 | # Using Wavefront .obj files 2 | 3 | This program has a second .ts file that includes the model data for the Blender3D demo monkey (named Suzanne). This model data was created using the npm module I created called [obj2asc](https://www.npmjs.com/package/obj2asc). 4 | 5 | The obj2asc CLI converts a Wavefront .obj file to an AssemblyScript .asc file. If you use it, and you are using the .ts extension for AssemblyScript, you will need to change the .asc file extension to .ts, or copy and paste the data into an existing .ts file. You can install obj2asc using npm: 6 | ``` 7 | npm i obj2asc -g 8 | ``` -------------------------------------------------------------------------------- /src/examples/Obj/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Wavefront Object converted to AssemblyScript 8 | 9 | 10 | 11 |
fps:
12 |
13 | 14 |
15 | 16 | 85 | 86 | -------------------------------------------------------------------------------- /src/examples/Obj/monkey.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'None' 2 | # Material Count: 1 3 | 4 | newmtl None 5 | Ns 500 6 | Ka 0.8 0.8 0.8 7 | Kd 0.8 0.8 0.8 8 | Ks 0.8 0.8 0.8 9 | d 1 10 | illum 2 11 | -------------------------------------------------------------------------------- /src/examples/Obj/monkey.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/Obj/monkey.zip -------------------------------------------------------------------------------- /src/examples/Obj/obj.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Rick Battagline / https://embed.com 3 | */ 4 | 5 | import { 6 | WebGLRenderingContext, 7 | WebGLShader, 8 | WebGLProgram, 9 | ImageData, 10 | WebGLBuffer, 11 | GLint, 12 | WebGLUniformLocation, 13 | } from '../../WebGL'; 14 | 15 | import {Suzanne_data} from './Suzanne'; 16 | 17 | const VERTEX_SHADER_CODE: string = `#version 300 es 18 | precision mediump float; 19 | 20 | in vec3 position; 21 | in vec3 normal; 22 | out vec4 c; 23 | 24 | void main() { 25 | const vec3 light = vec3(0.25, 2.0, -0.5); 26 | float d = clamp( dot( normal, light ), 0.0, 1.0); 27 | vec4 pos = vec4( position, 1.0 ); 28 | 29 | mat4 mRotateTranslate = mat4( 30 | 1.0, 0.0, 0.0, 0.0, // column 1 31 | 0.0, cos(-0.2),-sin(-0.2), -0.2, // column 2 32 | 0.0, sin(-0.0), cos(-0.2), 0.0, // column 3 33 | 0.0, 0.0, 0.0, 1.0 // column 4 34 | ); 35 | 36 | gl_Position = pos * mRotateTranslate; 37 | c = vec4(max(d, 0.2), max(d, 0.2), max(d, 0.25), 1.0); 38 | } 39 | `; 40 | 41 | // THIS IS THE FRAGMENT SHADER 42 | const FRAGMENT_SHADER_CODE: string = `#version 300 es 43 | precision highp float; 44 | in vec4 c; 45 | out vec4 color; 46 | 47 | void main() { 48 | color = c; 49 | } 50 | `; 51 | 52 | // initialize webgl 53 | var gl = new WebGLRenderingContext('cnvs', 'webgl2'); 54 | 55 | let vertex_shader: WebGLShader = gl.createShader(gl.VERTEX_SHADER); 56 | gl.shaderSource(vertex_shader, VERTEX_SHADER_CODE); 57 | gl.compileShader(vertex_shader); 58 | 59 | let fragment_shader: WebGLShader = gl.createShader(gl.FRAGMENT_SHADER); 60 | gl.shaderSource(fragment_shader, FRAGMENT_SHADER_CODE); 61 | gl.compileShader(fragment_shader); 62 | 63 | let program: WebGLProgram = gl.createProgram(); 64 | 65 | gl.attachShader(program, vertex_shader); 66 | gl.attachShader(program, fragment_shader); 67 | 68 | gl.linkProgram(program); 69 | 70 | gl.useProgram(program); 71 | 72 | let buffer: WebGLBuffer = gl.createBuffer(); 73 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 74 | 75 | let position_al: GLint = gl.getAttribLocation(program, 'position'); 76 | gl.enableVertexAttribArray(position_al); 77 | 78 | let normal_al: GLint = gl.getAttribLocation(program, 'normal'); 79 | gl.enableVertexAttribArray(normal_al); 80 | 81 | gl.enable(gl.DEPTH_TEST); 82 | 83 | // I'M DUPLICATING A LOT OF VERTICES HERE. 84 | // INDEXES WOULD BE BETTER 85 | 86 | function rotate(theta: f32): void { 87 | for (var coord_i: i32 = 0; coord_i < Suzanne_data.length; coord_i += 6) { 88 | let x: f32 = Suzanne_data[coord_i]; 89 | let z: f32 = Suzanne_data[coord_i + 2]; 90 | 91 | let nx: f32 = Suzanne_data[coord_i + 3]; 92 | let nz: f32 = Suzanne_data[coord_i + 5]; 93 | 94 | let x1: f32 = x * Mathf.cos(theta) - z * Mathf.sin(theta); 95 | let z1: f32 = z * Mathf.cos(theta) + x * Mathf.sin(theta); 96 | 97 | let nx1: f32 = nx * Mathf.cos(theta) - nz * Mathf.sin(theta); 98 | let nz1: f32 = nz * Mathf.cos(theta) + nx * Mathf.sin(theta); 99 | 100 | Suzanne_data[coord_i] = x1; 101 | Suzanne_data[coord_i + 2] = z1; 102 | 103 | Suzanne_data[coord_i + 3] = nx1; 104 | Suzanne_data[coord_i + 5] = nz1; 105 | } 106 | 107 | return; 108 | } 109 | 110 | export function displayLoop(delta: i32): void { 111 | let r: f32 = delta / 10000.0; 112 | rotate(r); 113 | 114 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 115 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 116 | 117 | gl.bufferData(gl.ARRAY_BUFFER, Suzanne_data, gl.DYNAMIC_DRAW); 118 | // dimensions | data_type | normalize | stride | offset 119 | gl.vertexAttribPointer(position_al, 3, gl.FLOAT, +false, 24, 0); 120 | gl.vertexAttribPointer(normal_al, 3, gl.FLOAT, +false, 24, 12); 121 | gl.drawArrays(gl.TRIANGLES, 0, Suzanne_data.length / 6); 122 | } 123 | -------------------------------------------------------------------------------- /src/examples/Obj/obj.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/Obj/obj.zip -------------------------------------------------------------------------------- /src/examples/Quad/README.md: -------------------------------------------------------------------------------- 1 | # Drawing a quad 2 | 3 | Drawing a quad isn't much different than drawing a triangle. Quads are used for sprites and billboards in a lot of games, and are rectangles. The main difference between this and the triangle rendering app is that the quad_data static array variable has eight floats in stead of six, because there are four x, y coordinate pairs: 4 | ``` 5 | let quad_data: StaticArray = [-0.5, -0.5, 6 | -0.5, 0.5, 7 | 0.5, -0.5, 8 | 0.5, 0.5,]; 9 | ``` -------------------------------------------------------------------------------- /src/examples/Quad/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Quad Drawing Example 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 | 73 | 74 | -------------------------------------------------------------------------------- /src/examples/Quad/quad.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Rick Battagline / https://embed.com 3 | */ 4 | 5 | import {WebGLRenderingContext, WebGLShader, WebGLProgram, WebGLBuffer, GLint} from '../../WebGL'; 6 | 7 | const VERTEX_SHADER_CODE: string = `#version 300 es 8 | precision highp float; 9 | 10 | in vec2 position; 11 | 12 | void main() { 13 | gl_Position = vec4( position, 0.0, 1.0 ); 14 | } 15 | `; 16 | // THIS IS THE FRAGMENT SHADER 17 | const FRAGMENT_SHADER_CODE: string = `#version 300 es 18 | precision highp float; 19 | out vec4 color; 20 | 21 | void main() { 22 | color = vec4( 0.5, 0.2, 1.0, 1.0 ); 23 | } 24 | `; 25 | 26 | // initialize webgl 27 | var gl: WebGLRenderingContext = new WebGLRenderingContext('cnvs', 'webgl2'); 28 | 29 | let vertex_shader: WebGLShader = gl.createShader(gl.VERTEX_SHADER); 30 | gl.shaderSource(vertex_shader, VERTEX_SHADER_CODE); 31 | gl.compileShader(vertex_shader); 32 | 33 | let fragment_shader: WebGLShader = gl.createShader(gl.FRAGMENT_SHADER); 34 | gl.shaderSource(fragment_shader, FRAGMENT_SHADER_CODE); 35 | gl.compileShader(fragment_shader); 36 | 37 | let program: WebGLProgram = gl.createProgram(); 38 | 39 | gl.attachShader(program, vertex_shader); 40 | gl.attachShader(program, fragment_shader); 41 | 42 | gl.linkProgram(program); 43 | 44 | gl.useProgram(program); 45 | 46 | let buffer: WebGLBuffer = gl.createBuffer(); 47 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 48 | 49 | let position_al: GLint = gl.getAttribLocation(program, 'position'); 50 | gl.enableVertexAttribArray(position_al); 51 | 52 | // prettier-ignore 53 | let quad_data: StaticArray = [ 54 | -0.5, -0.5, 55 | -0.5, 0.5, 56 | 0.5, -0.5, 57 | 0.5, 0.5 58 | ]; 59 | 60 | export function displayLoop(delta: i32): void { 61 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 62 | gl.clear(gl.COLOR_BUFFER_BIT); 63 | 64 | gl.bufferData(gl.ARRAY_BUFFER, quad_data, gl.STATIC_DRAW); 65 | 66 | const dimensions: i32 = 2; 67 | const data_type: i32 = gl.FLOAT; 68 | const normalize: i32 = +false; 69 | const stride: i32 = 0; 70 | const offset: i32 = 0; 71 | 72 | gl.vertexAttribPointer(position_al, dimensions, data_type, normalize, stride, offset); 73 | 74 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, quad_data.length / 2); 75 | } 76 | -------------------------------------------------------------------------------- /src/examples/QuadFollowMouse/README.md: -------------------------------------------------------------------------------- 1 | # Quad Follow Mouse 2 | 3 | This is a simple *follow the mouse* demo that makes a WebGL quad follow the mouse cursor around the canvas. 4 | 5 | 6 | ## Vertex Shader 7 | The `uniform vec2 quad_pos` is a uniform variable with the x and y coordinates of the mouse relative to the canvas. This value will be combined with the quad vector data to have your quad follow your mouse cursor. 8 | 9 | ``` 10 | precision highp float; 11 | 12 | uniform vec2 quad_pos; 13 | in vec2 position; 14 | 15 | void main() { 16 | vec2 pos = position + quad_pos; 17 | gl_Position = vec4( pos, 0.0, 1.0 ); 18 | } 19 | ``` 20 | 21 | ## Fragment Shader 22 | 23 | In the fragment shader code I hardcoded the color I'm passing out of the shader to a purple shade; 24 | 25 | ``` 26 | precision highp float; 27 | out vec4 color; 28 | 29 | void main() { 30 | color = vec4( 0.5, 0.2, 1.0, 1.0 ); 31 | } 32 | ``` 33 | 34 | ## moveMouse function 35 | 36 | The `moveMouse` function replaces the `displayLoop` function in most of the examples. The `moveMouse` passes in the mouse x and y positions relative to the canvas. In addition to buffering the data, the `quad_pos` uniform must be set: 37 | 38 | ``` 39 | uniform2f(gl, quad_pos, mouse_x, mouse_y); 40 | ``` -------------------------------------------------------------------------------- /src/examples/QuadFollowMouse/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Quad Following The Mouse Example 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 | 66 | 67 | -------------------------------------------------------------------------------- /src/examples/QuadFollowMouse/quad_follow_mouse.ts: -------------------------------------------------------------------------------- 1 | import {WebGLRenderingContext, WebGLShader, WebGLProgram, WebGLBuffer, WebGLUniformLocation} from '../../WebGL'; 2 | 3 | const VERTEX_SHADER_CODE: string = `#version 300 es 4 | precision highp float; 5 | 6 | uniform vec2 quad_pos; 7 | in vec2 position; 8 | 9 | void main() { 10 | vec2 pos = position + quad_pos; 11 | gl_Position = vec4( pos, 0.0, 1.0 ); 12 | } 13 | `; 14 | // THIS IS THE FRAGMENT SHADER 15 | const FRAGMENT_SHADER_CODE: string = `#version 300 es 16 | precision highp float; 17 | out vec4 color; 18 | 19 | void main() { 20 | color = vec4( 0.5, 0.2, 1.0, 1.0 ); 21 | } 22 | `; 23 | 24 | // initialize webgl 25 | var gl: WebGLRenderingContext = new WebGLRenderingContext('cnvs', 'webgl2'); 26 | 27 | let vertex_shader: WebGLShader = gl.createShader(gl.VERTEX_SHADER); 28 | gl.shaderSource(vertex_shader, VERTEX_SHADER_CODE); 29 | gl.compileShader(vertex_shader); 30 | 31 | let fragment_shader: WebGLShader = gl.createShader(gl.FRAGMENT_SHADER); 32 | gl.shaderSource(fragment_shader, FRAGMENT_SHADER_CODE); 33 | gl.compileShader(fragment_shader); 34 | 35 | let program: WebGLProgram = gl.createProgram(); 36 | 37 | gl.attachShader(program, vertex_shader); 38 | gl.attachShader(program, fragment_shader); 39 | 40 | gl.linkProgram(program); 41 | 42 | gl.useProgram(program); 43 | 44 | let buffer: WebGLBuffer = gl.createBuffer(); 45 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 46 | 47 | let position_al = gl.getAttribLocation(program, 'position'); 48 | gl.enableVertexAttribArray(position_al); 49 | 50 | // prettier-ignore 51 | let quad_data: StaticArray = [ 52 | -0.2, -0.2, 53 | -0.2, 0.2, 54 | 0.2, -0.2, 55 | 0.2, 0.2 56 | ]; 57 | 58 | let quad_pos: WebGLUniformLocation = gl.getUniformLocation(program, 'quad_pos'); 59 | 60 | export function moveMouse(mouse_x: f32, mouse_y: f32): void { 61 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 62 | gl.clear(gl.COLOR_BUFFER_BIT); 63 | 64 | gl.bufferData(gl.ARRAY_BUFFER, quad_data, gl.STATIC_DRAW); 65 | 66 | const dimensions: i32 = 2; 67 | const data_type: i32 = gl.FLOAT; 68 | const normalize: i32 = +false; 69 | const stride: i32 = 0; 70 | const offset: i32 = 0; 71 | 72 | gl.vertexAttribPointer(position_al, dimensions, data_type, normalize, stride, offset); 73 | gl.uniform2f(quad_pos, mouse_x, mouse_y); 74 | 75 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, quad_data.length / 2); 76 | } 77 | -------------------------------------------------------------------------------- /src/examples/README.md: -------------------------------------------------------------------------------- 1 | #AssemblyScript WebGL Binding Examples 2 | 3 | I am creating a series of AssemblyScript WebGL tutorials to show examples of using the AssemblyScript bindings and glue code for WebGL. 4 | 5 | These can also be used as a series of small tutorials. You should do them in the following order 6 | 7 | 1. Hello World Triangle 8 | 2. Color Triangle 9 | -------------------------------------------------------------------------------- /src/examples/RobotTex.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/RobotTex.psd -------------------------------------------------------------------------------- /src/examples/RobotTexPixel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/RobotTexPixel.png -------------------------------------------------------------------------------- /src/examples/RobotTexPixel.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/RobotTexPixel.psd -------------------------------------------------------------------------------- /src/examples/RobotTexPixel_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/RobotTexPixel_n.png -------------------------------------------------------------------------------- /src/examples/SimpleLighting/README.md: -------------------------------------------------------------------------------- 1 | #Hello World Triangle 2 | 3 | The triangle is the most basic of graphical programs. When I have read a books on OpenGL / WebGL / DirectX, they always begin with a program that draws a simple triangle. 4 | 5 | ``` 6 | asc triangle.asc --extension asc --runtime stub --importMemory -o triangle.wasm 7 | ``` -------------------------------------------------------------------------------- /src/examples/SimpleLighting/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Simple Lighting Model Example 8 | 9 | 10 | 11 |
fps:
12 |
13 | 14 |
15 | 16 | 85 | 86 | -------------------------------------------------------------------------------- /src/examples/SimpleLighting/simple_lighting.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Rick Battagline / https://embed.com 3 | */ 4 | 5 | import {WebGLRenderingContext, WebGLShader, WebGLBuffer, GLint, WebGLProgram} from '../../WebGL'; 6 | 7 | const VERTEX_SHADER_CODE: string = `#version 300 es 8 | precision mediump float; 9 | 10 | in vec3 position; 11 | in vec3 normal; 12 | out vec4 c; 13 | 14 | void main() { 15 | const vec3 light = vec3(0.25, 2.0, -0.5); 16 | float d = clamp( dot( normal, light ), 0.0, 1.0); 17 | vec4 pos = vec4( position, 1.0 ); 18 | 19 | mat4 mRotateTranslate = mat4( 20 | 1.0, 0.0, 0.0, 0.0, // column 1 21 | 0.0, cos(-0.2),-sin(-0.2), -0.2, // column 2 22 | 0.0, sin(-0.0), cos(-0.2), 0.0, // column 3 23 | 0.0, 0.0, 0.0, 1.0 // column 4 24 | ); 25 | 26 | gl_Position = pos * mRotateTranslate; 27 | c = vec4(max(d, 0.2), max(d, 0.2), max(d, 0.3), 1.0); 28 | } 29 | `; 30 | 31 | // THIS IS THE FRAGMENT SHADER 32 | const FRAGMENT_SHADER_CODE: string = `#version 300 es 33 | precision highp float; 34 | in vec4 c; 35 | out vec4 color; 36 | 37 | void main() { 38 | color = c; 39 | } 40 | `; 41 | 42 | // initialize webgl 43 | var gl: WebGLRenderingContext = new WebGLRenderingContext('cnvs', 'webgl2'); 44 | 45 | let vertex_shader: WebGLShader = gl.createShader(gl.VERTEX_SHADER); 46 | gl.shaderSource(vertex_shader, VERTEX_SHADER_CODE); 47 | gl.compileShader(vertex_shader); 48 | 49 | let fragment_shader: WebGLShader = gl.createShader(gl.FRAGMENT_SHADER); 50 | gl.shaderSource(fragment_shader, FRAGMENT_SHADER_CODE); 51 | gl.compileShader(fragment_shader); 52 | 53 | let program: WebGLProgram = gl.createProgram(); 54 | 55 | gl.attachShader(program, vertex_shader); 56 | gl.attachShader(program, fragment_shader); 57 | 58 | gl.linkProgram(program); 59 | 60 | gl.useProgram(program); 61 | 62 | let buffer: WebGLBuffer = gl.createBuffer(); 63 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 64 | 65 | let position_al: GLint = gl.getAttribLocation(program, 'position'); 66 | gl.enableVertexAttribArray(position_al); 67 | 68 | let normal_al: GLint = gl.getAttribLocation(program, 'normal'); 69 | gl.enableVertexAttribArray(normal_al); 70 | 71 | gl.enable(gl.DEPTH_TEST); 72 | 73 | // I'M DUPLICATING A LOT OF VERTICES HERE. 74 | // INDEXES WOULD BE BETTER 75 | // prettier-ignore 76 | let cube_data: StaticArray = [ 77 | // X Y Z NX NY NZ 78 | // Front 79 | -0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 80 | 0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 81 | -0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 82 | 83 | 0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 84 | -0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 85 | 0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 86 | // X Y Z NX NY NZ 87 | // Top 88 | -0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 89 | 0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 90 | -0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 91 | 92 | 0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 93 | -0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 94 | 0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 95 | // X Y Z NX NY NZ 96 | // Back 97 | -0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 98 | 0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 99 | -0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 100 | 101 | 0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 102 | -0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 103 | 0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 104 | // X Y Z NX NY NZ 105 | // Right 106 | 0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 107 | 0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 108 | 0.5, 0.5, -0.5, 1.0, 0.0, 0.0, 109 | 110 | 0.5, 0.5, 0.5, 1.0, 0.0, 0.0, 111 | 0.5, 0.5, -0.5, 1.0, 0.0, 0.0, 112 | 0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 113 | // Bottom 114 | -0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 115 | 0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 116 | -0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 117 | 118 | 0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 119 | -0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 120 | 0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 121 | 122 | // X Y Z NX NY NZ 123 | // Left 124 | -0.5, -0.5, -0.5, -1.0, 0.0, 0.0, 125 | -0.5, -0.5, 0.5, -1.0, 0.0, 0.0, 126 | -0.5, 0.5, -0.5, -1.0, 0.0, 0.0, 127 | 128 | -0.5, 0.5, 0.5, -1.0, 0.0, 0.0, 129 | -0.5, 0.5, -0.5, -1.0, 0.0, 0.0, 130 | -0.5, -0.5, 0.5, -1.0, 0.0, 0.0, 131 | ]; 132 | 133 | function rotate(theta: f32): void { 134 | for (var coord_i: i32 = 0; coord_i < cube_data.length; coord_i += 6) { 135 | let x: f32 = cube_data[coord_i]; 136 | let z: f32 = cube_data[coord_i + 2]; 137 | 138 | let nx: f32 = cube_data[coord_i + 3]; 139 | let nz: f32 = cube_data[coord_i + 5]; 140 | 141 | let x1: f32 = x * Mathf.cos(theta) - z * Mathf.sin(theta); 142 | let z1: f32 = z * Mathf.cos(theta) + x * Mathf.sin(theta); 143 | 144 | let nx1: f32 = nx * Mathf.cos(theta) - nz * Mathf.sin(theta); 145 | let nz1: f32 = nz * Mathf.cos(theta) + nx * Mathf.sin(theta); 146 | 147 | cube_data[coord_i] = x1; 148 | cube_data[coord_i + 2] = z1; 149 | 150 | cube_data[coord_i + 3] = nx1; 151 | cube_data[coord_i + 5] = nz1; 152 | } 153 | 154 | return; 155 | } 156 | 157 | export function displayLoop(delta: i32): void { 158 | let r: f32 = delta / 10000.0; 159 | rotate(r); 160 | 161 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 162 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 163 | 164 | gl.bufferData(gl.ARRAY_BUFFER, cube_data, gl.DYNAMIC_DRAW); 165 | // dimensions | data_type | normalize | stride | offset 166 | gl.vertexAttribPointer(position_al, 3, gl.FLOAT, +false, 24, 0); 167 | gl.vertexAttribPointer(normal_al, 3, gl.FLOAT, +false, 24, 12); 168 | gl.drawArrays(gl.TRIANGLES, 0, cube_data.length / 6); 169 | } 170 | -------------------------------------------------------------------------------- /src/examples/SpriteLighting/README.md: -------------------------------------------------------------------------------- 1 | # Sprite Lighting 2 | 3 | This is an example of simple 2D sprite lighting. There are two shaders, because I wanted to render the location of the light source as a point. 4 | 5 | -------------------------------------------------------------------------------- /src/examples/SpriteLighting/SpaceShip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/SpriteLighting/SpaceShip.png -------------------------------------------------------------------------------- /src/examples/SpriteLighting/SpaceShipN.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/SpriteLighting/SpaceShipN.png -------------------------------------------------------------------------------- /src/examples/SpriteLighting/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Sprite Lighting Example 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 | 72 | 73 | -------------------------------------------------------------------------------- /src/examples/SpriteLighting/sprite_lighting.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Rick Battagline / https://embed.com 3 | */ 4 | 5 | import { 6 | WebGLRenderingContext, 7 | WebGLShader, 8 | ImageData, 9 | WebGLUniformLocation, 10 | WebGLBuffer, 11 | GLint, 12 | WebGLProgram, 13 | WebGLTexture, 14 | } from '../../WebGL'; 15 | 16 | const VS_POINT_CODE: string = `#version 300 es 17 | in vec2 position; 18 | 19 | void main() { 20 | gl_Position = vec4(position, 0.0, 1.0); 21 | gl_PointSize = 16.0; 22 | } 23 | `; 24 | 25 | const FS_POINT_CODE: string = `#version 300 es 26 | precision highp float; 27 | out vec4 color; 28 | 29 | void main() { 30 | color = vec4(1.0, 1.0, 1.0, 1.0);; 31 | } 32 | `; 33 | 34 | const VERTEX_SHADER_CODE: string = `#version 300 es 35 | precision highp float; 36 | 37 | in vec2 position; 38 | in vec2 tex_coord; 39 | 40 | out vec2 tc; 41 | 42 | void main() { 43 | gl_Position = vec4(position, 0.0, 1.0); 44 | tc = tex_coord; 45 | } 46 | `; 47 | 48 | const FRAGMENT_SHADER_CODE: string = `#version 300 es 49 | precision highp float; 50 | 51 | in vec2 tc; 52 | 53 | uniform sampler2D sampler; 54 | uniform sampler2D normal_map; 55 | uniform vec3 light_source; 56 | 57 | out vec4 color; 58 | 59 | void main() { 60 | vec3 NormalMap = texture( normal_map, tc ).xyz; 61 | vec3 norm; 62 | norm.xyz = NormalMap.rgb * 2.0 - 1.0; 63 | 64 | vec3 N = normalize(norm); 65 | vec3 L = normalize(light_source); 66 | 67 | float norm_light = clamp(dot( N, L ), 0.5, 2.0); 68 | 69 | color = texture( sampler, tc ); 70 | color.rgb *= norm_light; // / 3.0; 71 | } 72 | `; 73 | 74 | // light source 75 | var light_x: f32 = 0.5; 76 | var light_y: f32 = 0.0; 77 | var light_z: f32 = 0.5; 78 | 79 | // initialize webgl 80 | var gl: WebGLRenderingContext = new WebGLRenderingContext('cnvs', 'webgl2'); 81 | 82 | // ImageData, createImage, imageReady, 83 | var image_id: ImageData = gl.createImage('SpaceShip.png'); 84 | var normal_image_id: ImageData = gl.createImage('SpaceShipN.png'); 85 | var image_ready: bool = false; 86 | 87 | let vertex_shader: WebGLShader = gl.createShader(gl.VERTEX_SHADER); 88 | gl.shaderSource(vertex_shader, VERTEX_SHADER_CODE); 89 | gl.compileShader(vertex_shader); 90 | 91 | let fragment_shader: WebGLShader = gl.createShader(gl.FRAGMENT_SHADER); 92 | gl.shaderSource(fragment_shader, FRAGMENT_SHADER_CODE); 93 | gl.compileShader(fragment_shader); 94 | 95 | let program: WebGLProgram = gl.createProgram(); 96 | 97 | gl.attachShader(program, vertex_shader); 98 | gl.attachShader(program, fragment_shader); 99 | 100 | gl.linkProgram(program); 101 | 102 | gl.useProgram(program); 103 | 104 | let buffer: WebGLBuffer = gl.createBuffer(); 105 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 106 | 107 | let position_al: GLint = gl.getAttribLocation(program, 'position'); 108 | gl.enableVertexAttribArray(position_al); 109 | 110 | let tex_coord_al: GLint = gl.getAttribLocation(program, 'tex_coord'); 111 | gl.enableVertexAttribArray(tex_coord_al); 112 | 113 | gl.enable(gl.BLEND); 114 | gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); 115 | 116 | let vertex_shader2: WebGLShader = gl.createShader(gl.VERTEX_SHADER); 117 | gl.shaderSource(vertex_shader2, VS_POINT_CODE); 118 | gl.compileShader(vertex_shader2); 119 | 120 | let fragment_shader2: WebGLShader = gl.createShader(gl.FRAGMENT_SHADER); 121 | gl.shaderSource(fragment_shader2, FS_POINT_CODE); 122 | gl.compileShader(fragment_shader2); 123 | 124 | let program2: WebGLProgram = gl.createProgram(); 125 | 126 | gl.attachShader(program2, vertex_shader2); 127 | gl.attachShader(program2, fragment_shader2); 128 | 129 | gl.linkProgram(program2); 130 | 131 | gl.useProgram(program2); 132 | 133 | let buffer2: WebGLBuffer = gl.createBuffer(); 134 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer2); 135 | 136 | let position2_al: GLint = gl.getAttribLocation(program2, 'position'); 137 | gl.enableVertexAttribArray(position2_al); 138 | 139 | // prettier-ignore 140 | let quad_data: StaticArray = [ 141 | // x y u v 142 | -0.15, -0.15, 0.0, 0.0, 143 | -0.15, 0.15, 0.0, 0.99, 144 | 0.15, -0.15, 0.95, 0.0, 145 | 0.15, 0.15, 0.95, 0.99,]; 146 | 147 | let light_point: StaticArray = [0.0, 0.0]; 148 | 149 | let texture: WebGLTexture = gl.createTexture(); 150 | let normal_texture: WebGLTexture = gl.createTexture(); 151 | let sampler: WebGLUniformLocation = gl.getUniformLocation(program, 'sampler'); 152 | let normal_map: WebGLUniformLocation = gl.getUniformLocation(program, 'normal_map'); 153 | let light_source: WebGLUniformLocation = gl.getUniformLocation(program, 'light_source'); 154 | 155 | function rotateLight(theta: f32): void { 156 | let x: f32 = light_x; 157 | let y: f32 = light_y; 158 | 159 | light_x = x * Mathf.cos(theta) - y * Mathf.sin(theta); 160 | light_y = y * Mathf.cos(theta) + x * Mathf.sin(theta); 161 | 162 | light_point[0] = light_x; 163 | light_point[1] = light_y; 164 | return; 165 | } 166 | 167 | export function displayLoop(delta: i32): void { 168 | let r: f32 = delta / 1000.0; 169 | rotateLight(r); 170 | 171 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 172 | gl.clear(gl.COLOR_BUFFER_BIT); 173 | 174 | if (image_ready == false) { 175 | if (gl.imageReady(image_id) == false || gl.imageReady(normal_image_id) == false) { 176 | return; 177 | } 178 | gl.useProgram(program); 179 | 180 | gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); 181 | gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, +true); 182 | gl.activeTexture(gl.TEXTURE0); 183 | gl.bindTexture(gl.TEXTURE_2D, texture); 184 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 185 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 186 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image_id); 187 | 188 | gl.uniform1i(sampler, 0); 189 | 190 | gl.activeTexture(gl.TEXTURE1); 191 | gl.bindTexture(gl.TEXTURE_2D, normal_texture); 192 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 193 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 194 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, normal_image_id); 195 | 196 | gl.uniform1i(normal_map, 1); 197 | image_ready = true; 198 | } 199 | gl.useProgram(program); 200 | 201 | gl.uniform3f(light_source, light_x, light_y, light_z); 202 | gl.bufferData(gl.ARRAY_BUFFER, quad_data, gl.STATIC_DRAW); 203 | 204 | //vertexAttribPointer attribute | dimensions | data type | normalize | stride bytes | offset bytes 205 | gl.vertexAttribPointer(position_al, 2, gl.FLOAT, +false, 16, 0); 206 | gl.vertexAttribPointer(tex_coord_al, 2, gl.FLOAT, +false, 16, 8); 207 | 208 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, quad_data.length / 4); 209 | 210 | gl.useProgram(program2); 211 | gl.bufferData(gl.ARRAY_BUFFER, light_point, gl.STATIC_DRAW); 212 | gl.vertexAttribPointer(position2_al, 2, gl.FLOAT, +false, 8, 0); 213 | gl.drawArrays(gl.POINTS, 0, 1); 214 | } 215 | -------------------------------------------------------------------------------- /src/examples/TextureModel/RobotTexPixel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/TextureModel/RobotTexPixel.png -------------------------------------------------------------------------------- /src/examples/TextureModel/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Textured Wavefront Object converted to AssemblyScript 8 | 9 | 10 | 11 |
fps:
12 |
13 | 14 |
15 | 16 | 85 | 86 | -------------------------------------------------------------------------------- /src/examples/TextureModel/obj_tex.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Rick Battagline / https://embed.com/wasm 3 | */ 4 | 5 | import { 6 | WebGLRenderingContext, 7 | WebGLShader, 8 | ImageData, 9 | WebGLUniformLocation, 10 | WebGLBuffer, 11 | GLint, 12 | WebGLProgram, 13 | WebGLTexture, 14 | } from '../../WebGL'; 15 | 16 | import {objArray, matArray, groupArray, VertGroup, matMapArray, MaterialMap} from './RobotTex'; 17 | 18 | const VERTEX_SHADER_CODE: string = `#version 300 es 19 | precision mediump float; 20 | 21 | in vec3 position; 22 | in vec2 tex_uv; 23 | in vec3 normal; 24 | uniform vec3 diffuse; 25 | 26 | out vec2 tc; 27 | out vec4 c; 28 | 29 | void main() { 30 | const vec3 light = vec3(0.25, 2.0, -0.5); 31 | float d = clamp( dot( normal, light ), 0.0, 1.0); 32 | vec4 pos = vec4( position, 1.0 ); 33 | 34 | mat4 mRotateTranslate = mat4( 35 | 1.0, 0.0, 0.0, 0.0, // column 1 36 | 0.0, cos(-0.2),-sin(-0.2), -0.2, // column 2 37 | 0.0, sin(-0.0), cos(-0.2), 0.0, // column 3 38 | 0.0, 0.0, 0.0, 1.0 // column 4 39 | ); 40 | 41 | gl_Position = pos * mRotateTranslate; 42 | tc = tex_uv; 43 | c = vec4( d + diffuse.r, 44 | d + diffuse.g, 45 | d + diffuse.b, 1.0); 46 | } 47 | `; 48 | 49 | // THIS IS THE FRAGMENT SHADER 50 | const FRAGMENT_SHADER_CODE: string = `#version 300 es 51 | precision highp float; 52 | in vec4 c; 53 | in vec2 tc; 54 | out vec4 color; 55 | uniform sampler2D sampler; 56 | 57 | void main() { 58 | color = texture( sampler, tc ) * c; 59 | } 60 | `; 61 | 62 | // initialize webgl 63 | var gl: WebGLRenderingContext = new WebGLRenderingContext('cnvs', 'webgl2'); 64 | 65 | let vertex_shader: WebGLShader = gl.createShader(gl.VERTEX_SHADER); 66 | gl.shaderSource(vertex_shader, VERTEX_SHADER_CODE); 67 | gl.compileShader(vertex_shader); 68 | 69 | let fragment_shader: WebGLShader = gl.createShader(gl.FRAGMENT_SHADER); 70 | gl.shaderSource(fragment_shader, FRAGMENT_SHADER_CODE); 71 | gl.compileShader(fragment_shader); 72 | 73 | let program: WebGLProgram = gl.createProgram(); 74 | 75 | gl.attachShader(program, vertex_shader); 76 | gl.attachShader(program, fragment_shader); 77 | 78 | gl.linkProgram(program); 79 | 80 | gl.useProgram(program); 81 | 82 | let buffer: WebGLBuffer = gl.createBuffer(); 83 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 84 | 85 | let position_al: GLint = gl.getAttribLocation(program, 'position'); 86 | gl.enableVertexAttribArray(position_al); 87 | 88 | let tex_uv_al: GLint = gl.getAttribLocation(program, 'tex_uv'); 89 | gl.enableVertexAttribArray(tex_uv_al); 90 | 91 | let normal_al: GLint = gl.getAttribLocation(program, 'normal'); 92 | gl.enableVertexAttribArray(normal_al); 93 | 94 | let diffuse: WebGLUniformLocation = gl.getUniformLocation(program, 'diffuse'); 95 | 96 | let texture: WebGLTexture = gl.createTexture(); 97 | let sampler: WebGLUniformLocation = gl.getUniformLocation(program, 'sampler'); 98 | 99 | var image_id: ImageData = gl.createImage(matMapArray[0].diffuse); 100 | var image_ready: bool = false; 101 | 102 | //diffuse 103 | gl.enable(gl.DEPTH_TEST); 104 | 105 | function rotate(theta: f32): void { 106 | //u32 { 107 | for (var obj_i: i32 = 0; obj_i < objArray.length; obj_i++) { 108 | for (var coord_i: i32 = 0; coord_i < objArray[obj_i].length; coord_i += 8) { 109 | let x: f32 = objArray[obj_i][coord_i]; 110 | let z: f32 = objArray[obj_i][coord_i + 2]; 111 | 112 | let nx: f32 = objArray[obj_i][coord_i + 5]; 113 | let nz: f32 = objArray[obj_i][coord_i + 7]; 114 | 115 | let x1: f32 = x * Mathf.cos(theta) - z * Mathf.sin(theta); 116 | let z1: f32 = z * Mathf.cos(theta) + x * Mathf.sin(theta); 117 | 118 | let nx1: f32 = nx * Mathf.cos(theta) - nz * Mathf.sin(theta); 119 | let nz1: f32 = nz * Mathf.cos(theta) + nx * Mathf.sin(theta); 120 | 121 | objArray[obj_i][coord_i] = x1; 122 | objArray[obj_i][coord_i + 2] = z1; 123 | 124 | objArray[obj_i][coord_i + 5] = nx1; 125 | objArray[obj_i][coord_i + 7] = nz1; 126 | } 127 | } 128 | 129 | return; 130 | } 131 | 132 | var vGroup: VertGroup; 133 | export function displayLoop(delta: i32): void { 134 | let r: f32 = delta / 10000.0; 135 | rotate(r); 136 | 137 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 138 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 139 | 140 | if (image_ready == false) { 141 | if (gl.imageReady(image_id) == false) { 142 | return; 143 | } 144 | 145 | gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); 146 | gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, +true); 147 | gl.activeTexture(gl.TEXTURE0); 148 | gl.bindTexture(gl.TEXTURE_2D, texture); 149 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 150 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 151 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image_id); 152 | 153 | gl.uniform1i(sampler, 0); 154 | image_ready = true; 155 | } 156 | 157 | for (var g_i: i32 = 0; g_i < groupArray.length; g_i++) { 158 | vGroup = groupArray[g_i]; 159 | gl.bufferData(gl.ARRAY_BUFFER, objArray[vGroup.obj_index], gl.DYNAMIC_DRAW); 160 | let diffuse_r: f32 = matArray[vGroup.mat_index][4]; 161 | let diffuse_g: f32 = matArray[vGroup.mat_index][5]; 162 | let diffuse_b: f32 = matArray[vGroup.mat_index][6]; 163 | gl.uniform3f(diffuse, diffuse_r, diffuse_g, diffuse_b); 164 | 165 | // dimensions | data_type | normalize | stride | offset 166 | gl.vertexAttribPointer(position_al, 3, gl.FLOAT, +false, 32, 0); 167 | gl.vertexAttribPointer(tex_uv_al, 2, gl.FLOAT, +false, 32, 12); 168 | gl.vertexAttribPointer(normal_al, 3, gl.FLOAT, +false, 32, 20); 169 | gl.drawArrays(gl.TRIANGLES, vGroup.start_face, vGroup.length); 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /src/examples/TextureQuad/README.md: -------------------------------------------------------------------------------- 1 | # Textured Quad 2 | 3 | Drawing sprites in WebGL is usually done by texturing a quad. In this demo, I draw a sprite using WebGL by texturing a quad (rectangle). 4 | 5 | ## The Vertex Shader 6 | 7 | The vertex shader is pretty striaght forward. I'm passing in 2D coordinates so the coordinates must be transformed in a vec4 by adding a z and w value to the end of the position object before passing it on to gl_Position. The UV coordinates are passed on from the vertex shader to the fragment shader without modification. 8 | 9 | Here's the code for the vertex shader: 10 | ``` 11 | precision highp float; 12 | 13 | in vec2 position; 14 | in vec2 tex_coord; 15 | 16 | out vec2 tc; 17 | 18 | void main() { 19 | gl_Position = vec4(position, 0.0, 1.0); 20 | tc = tex_coord; 21 | } 22 | ``` 23 | ## The Fragment Shader 24 | 25 | The fragment shader uses the uv coordinates to get the pixel value from the sampler2D passed in as a uniform. The output color is set to the value retrieved from the sampler with a call to the texture function. 26 | 27 | Here's the fragment shader code: 28 | ``` 29 | precision highp float; 30 | 31 | in vec2 position; 32 | in vec2 tex_coord; 33 | 34 | out vec2 tc; 35 | 36 | void main() { 37 | gl_Position = vec4(position, 0.0, 1.0); 38 | tc = tex_coord; 39 | } 40 | ``` 41 | ## Creating the ImageData object 42 | 43 | When the Wasm module loads, I have to load an image. I do so with the following call: 44 | 45 | ``` 46 | var image_id: ImageData = createImage('kaijunicorn.png'); 47 | var image_ready: bool = false; 48 | ``` 49 | 50 | The second line creates an image_ready boolean. I'm going to set this flag when the image is ready so I don't need to make a call to the JavaScript from within the display_loop once the image is ready to render. 51 | 52 | ## The Quad Data 53 | 54 | I use a StaticArray where I put the quad's x and y data. On each line I put the data for a single vertex, which is four f32 values for the x, y, u and v values. Here's the quad_data: 55 | 56 | ``` 57 | let quad_data: StaticArray = [ 58 | // x y u v 59 | -0.15, -0.2, 0.0, 0.0, 60 | -0.15, 0.2, 0.0, 0.99, 61 | 0.15, -0.2, 0.95, 0.0, 62 | 0.15, 0.2, 0.95, 0.99,]; 63 | ``` 64 | 65 | ## The displayLoop function 66 | 67 | in the displayLoop, I need to check the image_ready flag each time through the loop. If the image is not ready yet, I need to call the imageReady function: 68 | 69 | ``` 70 | export function displayLoop(): void { 71 | clearColor(gl, 0.0, 0.0, 0.0, 1.0); 72 | clear(gl, COLOR_BUFFER_BIT); 73 | 74 | if (image_ready == false) { 75 | if (imageReady(image_id) == false) { 76 | return; 77 | } 78 | ``` 79 | 80 | There are several WebGL functions that need to be called to set up WebGL to render texture data. It then sets the image_ready flat to true: 81 | 82 | ``` 83 | pixelStorei(gl, UNPACK_FLIP_Y_WEBGL, 1); 84 | pixelStorei(gl, UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); 85 | activeTexture(gl, TEXTURE0); 86 | bindTexture(gl, TEXTURE_2D, texture); 87 | texParameteri(gl, TEXTURE_2D, TEXTURE_MIN_FILTER, NEAREST); 88 | texParameteri(gl, TEXTURE_2D, TEXTURE_MAG_FILTER, NEAREST); 89 | texImage2D(gl, TEXTURE_2D, 0, RGB, RGB, UNSIGNED_BYTE, image_id); 90 | 91 | uniform1i(gl, sampler, 0); 92 | image_ready = true; 93 | } 94 | ``` 95 | 96 | I buffer the quad's vertex data: 97 | ``` 98 | bufferData(gl, ARRAY_BUFFER, quad_data, STATIC_DRAW); 99 | ``` 100 | 101 | I bind the array buffer to the vertex attributes for the position and uv data: 102 | ``` 103 | // attribute | dimensions | data type | normalize | stride bytes | offset bytes 104 | vertexAttribPointer(gl, position_al, 2, FLOAT, false, 16, 0); 105 | vertexAttribPointer(gl, tex_coord_al, 2, FLOAT, false, 16, 8); 106 | 107 | ``` 108 | 109 | 110 | Finally I draw the arrays: 111 | ``` 112 | drawArrays(gl, TRIANGLE_STRIP, 0, quad_data.length / 4); 113 | 114 | ``` 115 | 116 | -------------------------------------------------------------------------------- /src/examples/TextureQuad/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Textured Quad Example 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 | 72 | 73 | -------------------------------------------------------------------------------- /src/examples/TextureQuad/kaijunicorn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/TextureQuad/kaijunicorn.png -------------------------------------------------------------------------------- /src/examples/TextureQuad/texture_quad.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Rick Battagline / https://embed.com 3 | */ 4 | 5 | import { 6 | WebGLRenderingContext, 7 | WebGLShader, 8 | ImageData, 9 | WebGLUniformLocation, 10 | WebGLBuffer, 11 | GLint, 12 | WebGLProgram, 13 | WebGLTexture, 14 | } from '../../WebGL'; 15 | 16 | const VERTEX_SHADER_CODE: string = `#version 300 es 17 | precision highp float; 18 | 19 | in vec2 position; 20 | in vec2 tex_coord; 21 | 22 | out vec2 tc; 23 | 24 | void main() { 25 | gl_Position = vec4(position, 0.0, 1.0); 26 | tc = tex_coord; 27 | } 28 | `; 29 | // THIS IS THE FRAGMENT SHADER 30 | const FRAGMENT_SHADER_CODE: string = `#version 300 es 31 | precision highp float; 32 | 33 | in vec2 tc; 34 | 35 | uniform sampler2D sampler; 36 | 37 | out vec4 color; 38 | 39 | void main() { 40 | color = texture( sampler, tc ); 41 | } 42 | `; 43 | 44 | // initialize webgl 45 | var gl: WebGLRenderingContext = new WebGLRenderingContext('cnvs', 'webgl2'); 46 | 47 | // ImageData, createImage, imageReady, 48 | var image_id: ImageData = gl.createImage('kaijunicorn.png'); 49 | var image_ready: bool = false; 50 | 51 | let vertex_shader: WebGLShader = gl.createShader(gl.VERTEX_SHADER); 52 | gl.shaderSource(vertex_shader, VERTEX_SHADER_CODE); 53 | gl.compileShader(vertex_shader); 54 | 55 | let fragment_shader: WebGLShader = gl.createShader(gl.FRAGMENT_SHADER); 56 | gl.shaderSource(fragment_shader, FRAGMENT_SHADER_CODE); 57 | gl.compileShader(fragment_shader); 58 | 59 | let program: WebGLProgram = gl.createProgram(); 60 | 61 | gl.attachShader(program, vertex_shader); 62 | gl.attachShader(program, fragment_shader); 63 | 64 | gl.linkProgram(program); 65 | 66 | gl.useProgram(program); 67 | 68 | let buffer: WebGLBuffer = gl.createBuffer(); 69 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 70 | 71 | let position_al: GLint = gl.getAttribLocation(program, 'position'); 72 | gl.enableVertexAttribArray(position_al); 73 | 74 | let tex_coord_al: GLint = gl.getAttribLocation(program, 'tex_coord'); 75 | gl.enableVertexAttribArray(tex_coord_al); 76 | 77 | gl.enable(gl.BLEND); 78 | gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); 79 | 80 | let quad_data: StaticArray = [ 81 | // x y u v 82 | -0.15, 83 | -0.2, 84 | 0.0, 85 | 0.0, 86 | -0.15, 87 | 0.2, 88 | 0.0, 89 | 0.99, 90 | 0.15, 91 | -0.2, 92 | 0.95, 93 | 0.0, 94 | 0.15, 95 | 0.2, 96 | 0.95, 97 | 0.99, 98 | ]; 99 | 100 | let texture: WebGLTexture = gl.createTexture(); 101 | let sampler: WebGLUniformLocation = gl.getUniformLocation(program, 'sampler'); 102 | 103 | export function displayLoop(): void { 104 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 105 | gl.clear(gl.COLOR_BUFFER_BIT); 106 | 107 | if (image_ready == false) { 108 | if (gl.imageReady(image_id) == false) { 109 | return; 110 | } 111 | 112 | gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); 113 | gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, +true); 114 | gl.activeTexture(gl.TEXTURE0); 115 | gl.bindTexture(gl.TEXTURE_2D, texture); 116 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 117 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 118 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image_id); 119 | 120 | gl.uniform1i(sampler, 0); 121 | image_ready = true; 122 | } 123 | 124 | gl.bufferData(gl.ARRAY_BUFFER, quad_data, gl.STATIC_DRAW); 125 | 126 | //vertexAttribPointer attribute | dimensions | data type | normalize | stride bytes | offset bytes 127 | gl.vertexAttribPointer(position_al, 2, gl.FLOAT, +false, 16, 0); 128 | gl.vertexAttribPointer(tex_coord_al, 2, gl.FLOAT, +false, 16, 8); 129 | 130 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, quad_data.length / 4); 131 | } 132 | -------------------------------------------------------------------------------- /src/examples/WarpSpeed/README.md: -------------------------------------------------------------------------------- 1 | # Simple Lighting Model 2 | 3 | This is a simple lighting model for cube. With each call of the displayLoop function I rotate the cube and render it. 4 | 5 | ## Vertex Shader 6 | 7 | The vertex shader has a fixed light position hardcoded into the shader. The face lighting is calculated with a simple dot product. I have a hardcoded rotation matrix that I use to tilt the cube when I render it. The dot product value is used for the red, green and blue components of the color value passed to the fragment shader. The red and green component has a minimum ambient lighting value of 0.2, and the blue has a minimum value of 0.3. This gives the cube shadows a slight blue tint. 8 | 9 | Here's the vertex shader code: 10 | ``` 11 | precision mediump float; 12 | 13 | in vec3 position; 14 | in vec3 normal; 15 | out vec4 c; 16 | 17 | void main() { 18 | const vec3 light = vec3(0.25, 2.0, -0.5); 19 | float d = clamp( dot( normal, light ), 0.0, 1.0); 20 | vec4 pos = vec4( position, 1.0 ); 21 | 22 | mat4 mRotateTranslate = mat4( 23 | 1.0, 0.0, 0.0, 0.0, // column 1 24 | 0.0, cos(-0.2),-sin(-0.2), -0.2, // column 2 25 | 0.0, sin(-0.0), cos(-0.2), 0.0, // column 3 26 | 0.0, 0.0, 0.0, 1.0 // column 4 27 | ); 28 | 29 | gl_Position = pos * mRotateTranslate; 30 | c = vec4(max(d, 0.2), max(d, 0.2), max(d, 0.3), 1.0); 31 | } 32 | ``` 33 | ## Fragment Shader 34 | 35 | The fragment shader simply outputs the color value coming in from the vertex shader: 36 | 37 | ``` 38 | precision highp float; 39 | in vec4 c; 40 | out vec4 color; 41 | 42 | void main() { 43 | color = c; 44 | } 45 | ``` 46 | 47 | ## The Cube 48 | 49 | The cube vertex data is hardcoded into a StaticArray with each vertex having x,y,z vertex values and x,y,z normal values: 50 | 51 | ``` 52 | let cube_data: StaticArray = [ 53 | // X Y Z NX NY NZ 54 | // Front 55 | -0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 56 | 0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 57 | -0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 58 | 59 | 0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 60 | -0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 61 | 0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 62 | // X Y Z NX NY NZ 63 | // Top 64 | -0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 65 | 0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 66 | -0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 67 | 68 | 0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 69 | -0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 70 | 0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 71 | // X Y Z NX NY NZ 72 | // Back 73 | -0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 74 | 0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 75 | -0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 76 | 77 | 0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 78 | -0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 79 | 0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 80 | // X Y Z NX NY NZ 81 | // Right 82 | 0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 83 | 0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 84 | 0.5, 0.5, -0.5, 1.0, 0.0, 0.0, 85 | 86 | 0.5, 0.5, 0.5, 1.0, 0.0, 0.0, 87 | 0.5, 0.5, -0.5, 1.0, 0.0, 0.0, 88 | 0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 89 | // Bottom 90 | -0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 91 | 0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 92 | -0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 93 | 94 | 0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 95 | -0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 96 | 0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 97 | 98 | // X Y Z NX NY NZ 99 | // Left 100 | -0.5, -0.5, -0.5, -1.0, 0.0, 0.0, 101 | -0.5, -0.5, 0.5, -1.0, 0.0, 0.0, 102 | -0.5, 0.5, -0.5, -1.0, 0.0, 0.0, 103 | 104 | -0.5, 0.5, 0.5, -1.0, 0.0, 0.0, 105 | -0.5, 0.5, -0.5, -1.0, 0.0, 0.0, 106 | -0.5, -0.5, 0.5, -1.0, 0.0, 0.0, 107 | ]; 108 | ``` 109 | 110 | ## rotate function 111 | 112 | The rotate function is called once per frame and rotates the cube data based on the time delta between the current frame and the previous frame: 113 | 114 | ``` 115 | function rotate(theta: f32): void { //u32 { 116 | for (var coord_i: i32 = 0; coord_i < cube_data.length; coord_i += 6) { 117 | let x: f32 = cube_data[coord_i]; 118 | let z: f32 = cube_data[coord_i + 2]; 119 | 120 | let nx: f32 = cube_data[coord_i + 3]; 121 | let nz: f32 = cube_data[coord_i + 5]; 122 | 123 | let x1: f32 = x * Mathf.cos(theta) - z * Mathf.sin(theta); 124 | let z1: f32 = z * Mathf.cos(theta) + x * Mathf.sin(theta); 125 | 126 | let nx1: f32 = nx * Mathf.cos(theta) - nz * Mathf.sin(theta); 127 | let nz1: f32 = nz * Mathf.cos(theta) + nx * Mathf.sin(theta); 128 | 129 | cube_data[coord_i] = x1; 130 | cube_data[coord_i + 2] = z1; 131 | 132 | cube_data[coord_i + 3] = nx1; 133 | cube_data[coord_i + 5] = nz1; 134 | } 135 | 136 | return; 137 | } 138 | ``` 139 | 140 | ## displayLoop function 141 | 142 | The displayLoop is passed the time delta between the previous frame render and this one. I divide the delta value by 10000.0 because that amount of rotation per second felt right for this demo: 143 | ``` 144 | let r: f32 = delta / 10000.0; 145 | rotate(r); 146 | ``` 147 | 148 | Everything else is pretty standard for a display loop, clearing the canvas: 149 | 150 | ``` 151 | clearColor(gl, 0.0, 0.0, 0.0, 1.0); 152 | clear(gl, COLOR_BUFFER_BIT | DEPTH_BUFFER_BIT); 153 | ``` 154 | 155 | Buffering the cube data: 156 | 157 | ``` 158 | bufferData(gl, ARRAY_BUFFER, cube_data, DYNAMIC_DRAW); 159 | ``` 160 | 161 | Binding the vertex data to the vertex attributes in the shader: 162 | 163 | ``` 164 | vertexAttribPointer(gl, position_al, 3, FLOAT, false, 24, 0); 165 | vertexAttribPointer(gl, normal_al, 3, FLOAT, false, 24, 12); 166 | ``` 167 | 168 | Finally, drawing the array: 169 | ``` 170 | drawArrays(gl, TRIANGLES, 0, cube_data.length / 6); 171 | ``` 172 | 173 | 174 | 175 | 176 | 177 | -------------------------------------------------------------------------------- /src/examples/WarpSpeed/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Starfield Point Rendering Demo 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 | 72 | 73 | -------------------------------------------------------------------------------- /src/examples/WarpSpeed/warp_speed.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Rick Battagline / https://embed.com 3 | */ 4 | 5 | import {WebGLRenderingContext, WebGLShader, WebGLBuffer, GLint, WebGLProgram} from '../../WebGL'; 6 | 7 | class Point { 8 | public x: f32 = 0.0; 9 | public y: f32 = 0.0; 10 | public dx: f32 = 0.0; 11 | public dy: f32 = 0.0; 12 | 13 | constructor() { 14 | this.reset(); 15 | } 16 | 17 | public reset(): void { 18 | this.x = 0; 19 | this.y = 0; 20 | 21 | do { 22 | this.dx = Mathf.random() * 0.1 - 0.05; 23 | this.dy = Mathf.random() * 0.1 - 0.05; 24 | } while (Mathf.abs(this.dx) + Mathf.abs(this.dy) < 0.02); 25 | } 26 | 27 | public move(): void { 28 | if (this.x > 1.0 || this.x < -1.0 || this.y > 1.0 || this.y < -1.0) { 29 | this.reset(); 30 | } 31 | this.x += this.dx; 32 | this.y += this.dy; 33 | } 34 | } 35 | 36 | const VERTEX_SHADER_CODE: string = `#version 300 es 37 | precision highp float; 38 | 39 | in vec2 position; 40 | out vec4 c; 41 | 42 | void main() { 43 | gl_Position = vec4( position, 0.0, 1.0 ); 44 | float total = clamp(abs(position.x) + abs(position.y) + 0.4, 0.01, 1.0); 45 | gl_PointSize = total * 8.0; 46 | c = vec4(total, total, total, 1.0); 47 | 48 | } 49 | `; 50 | // THIS IS THE FRAGMENT SHADER 51 | const FRAGMENT_SHADER_CODE: string = `#version 300 es 52 | precision highp float; 53 | in vec4 c; 54 | out vec4 color; 55 | 56 | void main() { 57 | color = c; 58 | } 59 | `; 60 | 61 | // initialize webgl 62 | var gl: WebGLRenderingContext = new WebGLRenderingContext('cnvs', 'webgl2'); 63 | 64 | let vertex_shader: WebGLShader = gl.createShader(gl.VERTEX_SHADER); 65 | gl.shaderSource(vertex_shader, VERTEX_SHADER_CODE); 66 | gl.compileShader(vertex_shader); 67 | 68 | let fragment_shader: WebGLShader = gl.createShader(gl.FRAGMENT_SHADER); 69 | gl.shaderSource(fragment_shader, FRAGMENT_SHADER_CODE); 70 | gl.compileShader(fragment_shader); 71 | 72 | let program: WebGLProgram = gl.createProgram(); 73 | 74 | gl.attachShader(program, vertex_shader); 75 | gl.attachShader(program, fragment_shader); 76 | 77 | gl.linkProgram(program); 78 | 79 | gl.useProgram(program); 80 | 81 | let buffer: WebGLBuffer = gl.createBuffer(); 82 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 83 | 84 | let position_al: GLint = gl.getAttribLocation(program, 'position'); 85 | gl.enableVertexAttribArray(position_al); 86 | 87 | // prettier-ignore 88 | let point_list: StaticArray = [ 89 | new Point(), new Point(), new Point(), new Point(), new Point(), 90 | new Point(), new Point(), new Point(), new Point(), new Point(), 91 | new Point(), new Point(), new Point(), new Point(), new Point(), 92 | new Point(), new Point(), new Point(), new Point(), new Point(), 93 | new Point(), new Point(), new Point(), new Point(), new Point(), 94 | new Point(), new Point(), new Point(), new Point(), new Point(), 95 | new Point(), new Point(), new Point(), new Point(), new Point(), 96 | new Point(), new Point(), new Point(), new Point(), new Point(), 97 | new Point(), new Point(), new Point(), new Point(), new Point(), 98 | new Point(), new Point(), new Point(), new Point(), new Point(), 99 | new Point(), new Point(), new Point(), new Point(), new Point(), 100 | new Point(), new Point(), new Point(), new Point(), new Point(), 101 | new Point(), new Point(), new Point(), new Point(), new Point(), 102 | new Point(), new Point(), new Point(), new Point(), new Point(), 103 | new Point(), new Point(), new Point(), new Point(), new Point(), 104 | new Point(), new Point(), new Point(), new Point(), new Point(), 105 | new Point(), new Point(), new Point(), new Point(), new Point(), 106 | new Point(), new Point(), new Point(), new Point(), new Point(), 107 | new Point(), new Point(), new Point(), new Point(), new Point(), 108 | new Point(), new Point(), new Point(), new Point(), new Point(), 109 | new Point(), new Point(), new Point(), new Point(), new Point(), 110 | new Point(), new Point(), new Point(), new Point(), new Point(), 111 | new Point(), new Point(), new Point(), new Point(), new Point(), 112 | new Point(), new Point(), new Point(), new Point(), new Point(), 113 | new Point(), new Point(), new Point(), new Point(), new Point(), 114 | new Point(), new Point(), new Point(), new Point(), new Point(), 115 | new Point(), new Point(), new Point(), new Point(), new Point(), 116 | new Point(), new Point(), new Point(), new Point(), new Point(), 117 | new Point(), new Point(), new Point(), new Point(), new Point(), 118 | new Point(), new Point(), new Point(), new Point(), new Point(), 119 | new Point(), new Point(), new Point(), new Point(), new Point(), 120 | new Point(), new Point(), new Point(), new Point(), new Point(), 121 | new Point(), new Point(), new Point(), new Point(), new Point(), 122 | new Point(), new Point(), new Point(), new Point(), new Point(), 123 | new Point(), new Point(), new Point(), new Point(), new Point(), 124 | new Point(), new Point(), new Point(), new Point(), new Point(), 125 | new Point(), new Point(), new Point(), new Point(), new Point(), 126 | new Point(), new Point(), new Point(), new Point(), new Point(), 127 | new Point(), new Point(), new Point(), new Point(), new Point(), 128 | new Point(), new Point(), new Point(), new Point(), new Point(), 129 | new Point(), new Point(), new Point(), new Point(), new Point(), 130 | new Point(), new Point(), new Point(), new Point(), new Point(), 131 | new Point(), new Point(), new Point(), new Point(), new Point(), 132 | new Point(), new Point(), new Point(), new Point(), new Point(), 133 | new Point(), new Point(), new Point(), new Point(), new Point(), 134 | ]; 135 | 136 | // prettier-ignore 137 | let point_data: StaticArray = [ 138 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 139 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 140 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 141 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 142 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 143 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 144 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 145 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 146 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 147 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 148 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 149 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 150 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 151 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 152 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 153 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 154 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 155 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 156 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 157 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 158 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 159 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 160 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 161 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 162 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 163 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 164 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 165 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 166 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 167 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 168 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 169 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 170 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 171 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 172 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 173 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 174 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 175 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 176 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 177 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 178 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 179 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 180 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 181 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 182 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 183 | ]; 184 | 185 | export function displayLoop(delta: i32): void { 186 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 187 | gl.clear(gl.COLOR_BUFFER_BIT); 188 | 189 | for (let i: i32 = 0; i < point_list.length; i++) { 190 | point_list[i].move(); 191 | point_data[i * 2] = point_list[i].x; 192 | point_data[i * 2 + 1] = point_list[i].y; 193 | } 194 | 195 | gl.bufferData(gl.ARRAY_BUFFER, point_data, gl.STATIC_DRAW); 196 | 197 | const dimensions: i32 = 2; 198 | const data_type: i32 = gl.FLOAT; 199 | const normalize: i32 = +false; 200 | const stride: i32 = 0; 201 | const offset: i32 = 0; 202 | 203 | gl.vertexAttribPointer(position_al, dimensions, data_type, normalize, stride, offset); 204 | 205 | gl.drawArrays(gl.POINTS, 0, point_list.length); 206 | } 207 | -------------------------------------------------------------------------------- /src/examples/commented.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'robot.blend' 2 | # Material Count: 3 3 | 4 | # http://paulbourke.net/dataformats/mtl/ 5 | # http://paulbourke.net/dataformats/obj/ 6 | 7 | newmtl Material 8 | # Ns Specular Exponent 9 | Ns 323.999994 10 | # Ka Ambient Reflectivity 11 | Ka 1.000000 1.000000 1.000000 12 | # Kd Diffuse Reflectivity 13 | Kd 0.800000 0.314507 0.070683 14 | # Ks Specular Reflectivity 15 | Ks 0.500000 0.500000 0.500000 16 | # Ke Emission 17 | Ke 0.000000 0.000000 0.000000 18 | # Ni Optical Density 19 | Ni 1.450000 20 | # d dissolve factor 21 | d 1.000000 22 | # illum illumination model 23 | # Illumination Properties that are turned on in the 24 | # model Property Editor 25 | # 0 Color on and Ambient off 26 | # 1 Color on and Ambient on 27 | # 2 Highlight on 28 | # 3 Reflection on and Ray trace on 29 | # 4 Transparency: Glass on 30 | # Reflection: Ray trace on 31 | # 5 Reflection: Fresnel on and Ray trace on 32 | # 6 Transparency: Refraction on 33 | # Reflection: Fresnel off and Ray trace on 34 | # 7 Transparency: Refraction on 35 | # Reflection: Fresnel on and Ray trace on 36 | # 8 Reflection on and Ray trace off 37 | # 9 Transparency: Glass on 38 | # Reflection: Ray trace off 39 | # 10 Casts shadows onto invisible surfaces 40 | 41 | illum 2 42 | 43 | 44 | newmtl Material.001 45 | Ns 225.000000 46 | Ka 1.000000 1.000000 1.000000 47 | Kd 1.000000 0.000000 0.000000 48 | Ks 0.500000 0.500000 0.500000 49 | Ke 0.000000 0.000000 0.000000 50 | Ni 1.450000 51 | d 1.000000 52 | illum 2 53 | 54 | newmtl Material.002 55 | Ns 225.000000 56 | Ka 1.000000 1.000000 1.000000 57 | Kd 0.000000 0.000000 1.000000 58 | Ks 0.500000 0.500000 0.500000 59 | Ke 0.000000 0.000000 0.000000 60 | Ni 1.450000 61 | d 1.000000 62 | illum 2 63 | -------------------------------------------------------------------------------- /src/examples/commented.obj: -------------------------------------------------------------------------------- 1 | # Blender v2.90.1 OBJ File: 'robot.blend' 2 | # www.blender.org (created by) 3 | # mtlib material file 4 | mtllib robot.mtl 5 | # o object name 6 | o Cube 7 | # v vertex position data 8 | v 1.000000 1.000000 -1.000000 9 | v 1.000000 -1.000000 -1.000000 10 | v 1.000000 1.000000 1.000000 11 | v 1.000000 -1.000000 1.000000 12 | v -1.000000 1.000000 -1.000000 13 | v -1.000000 -1.000000 -1.000000 14 | v -1.000000 1.000000 1.000000 15 | v -1.000000 -1.000000 1.000000 16 | v 0.396396 3.195775 0.396396 17 | v -0.396396 3.195775 0.396396 18 | v 0.396396 3.195775 -0.396396 19 | v -0.396396 3.195775 -0.396396 20 | v 0.707780 4.659433 0.707780 21 | v -0.707780 4.659433 0.707780 22 | v 0.707780 4.659433 -0.707780 23 | v -0.707780 4.659433 -0.707780 24 | v 0.707780 5.747853 0.707780 25 | v -0.707780 5.747853 0.707780 26 | v 0.707780 5.747853 -0.707780 27 | v -0.707780 5.747853 -0.707780 28 | v 0.363607 6.039236 0.363607 29 | v -0.363607 6.039236 0.363607 30 | v 0.363607 6.039236 -0.363607 31 | v -0.363607 6.039236 -0.363607 32 | v 0.363607 6.228965 0.363607 33 | v -0.363607 6.228965 0.363607 34 | v 0.363607 6.228965 -0.363607 35 | v -0.363607 6.228965 -0.363607 36 | v 0.527745 6.437937 0.527745 37 | v -0.527745 6.437937 0.527745 38 | v 0.527745 6.437937 -0.527745 39 | v -0.527745 6.437937 -0.527745 40 | v 0.581972 7.220059 0.581972 41 | v -0.581972 7.220059 0.581972 42 | v 0.581972 7.220059 -0.581972 43 | v -0.581972 7.220059 -0.581972 44 | v 0.285750 7.649150 0.285750 45 | v -0.285750 7.649150 0.285750 46 | v 0.285750 7.649150 -0.285750 47 | v -0.285750 7.649150 -0.285750 48 | v 0.980918 4.891058 -0.406536 49 | v 0.980918 4.891058 0.406536 50 | v 0.980918 5.516228 -0.406536 51 | v 0.980918 5.516228 0.406536 52 | v -0.980918 4.891058 0.406536 53 | v -0.980918 4.891058 -0.406536 54 | v -0.980918 5.516228 0.406536 55 | v -0.980918 5.516228 -0.406536 56 | v -1.280918 4.891058 0.406536 57 | v -1.280918 4.891058 -0.406536 58 | v -1.280918 5.516228 0.406536 59 | v -1.280918 5.516228 -0.406536 60 | v 1.280918 4.891058 -0.406536 61 | v 1.280918 4.891058 0.406536 62 | v 1.280918 5.516228 -0.406536 63 | v 1.280918 5.516228 0.406536 64 | v 1.039887 4.005651 -0.246717 65 | v 1.039887 4.005651 0.246717 66 | v -1.039887 4.005651 0.246717 67 | v -1.039887 4.005651 -0.246717 68 | v -1.221950 4.005651 0.246717 69 | v -1.221950 4.005651 -0.246717 70 | v 1.221950 4.005651 -0.246717 71 | v 1.221950 4.005651 0.246717 72 | v 0.980918 3.537906 -0.406536 73 | v 0.980918 3.356243 0.406536 74 | v -0.980918 3.356243 0.406536 75 | v -0.980918 3.537906 -0.406536 76 | v -1.280918 3.356243 0.406536 77 | v -1.280918 3.537906 -0.406536 78 | v 1.280918 3.537906 -0.406536 79 | v 1.280918 3.356243 0.406536 80 | v 0.980918 2.342852 -0.795716 81 | v 0.980918 2.342852 -0.481741 82 | v -0.980918 2.342852 -0.481741 83 | v -0.980918 2.342852 -0.795716 84 | v -1.280918 2.342852 -0.481741 85 | v -1.280918 2.342852 -0.795716 86 | v 1.280918 2.342852 -0.795716 87 | v 1.280918 2.342852 -0.481741 88 | v 0.980918 2.075831 -1.046264 89 | v 0.980918 1.921174 -0.773021 90 | v -0.980918 1.921174 -0.773021 91 | v -0.980918 2.075831 -1.046264 92 | v -1.280918 1.921174 -0.773021 93 | v -1.280918 2.075831 -1.046264 94 | v 1.280918 2.075831 -1.046264 95 | v 1.280918 1.921174 -0.773021 96 | v 1.055918 1.868141 -1.073623 97 | v 1.055918 1.790813 -0.937002 98 | v -1.055918 1.790813 -0.937002 99 | v -1.055918 1.868141 -1.073623 100 | v -1.205918 1.790813 -0.937002 101 | v -1.205918 1.868141 -1.073623 102 | v 1.205918 1.868141 -1.073623 103 | v 1.205918 1.790813 -0.937002 104 | 105 | # vt vertex texture data 106 | vt 0.625000 0.500000 107 | vt 0.625000 0.250000 108 | vt 0.625000 0.250000 109 | vt 0.625000 0.500000 110 | vt 0.375000 0.750000 111 | vt 0.625000 0.750000 112 | vt 0.625000 1.000000 113 | vt 0.375000 1.000000 114 | vt 0.375000 0.000000 115 | vt 0.625000 0.000000 116 | vt 0.375000 0.250000 117 | vt 0.125000 0.500000 118 | vt 0.375000 0.500000 119 | vt 0.125000 0.750000 120 | vt 0.625000 0.750000 121 | vt 0.625000 1.000000 122 | vt 0.625000 0.000000 123 | vt 0.625000 0.500000 124 | vt 0.625000 0.250000 125 | vt 0.625000 0.250000 126 | vt 0.625000 0.500000 127 | vt 0.625000 0.000000 128 | vt 0.625000 0.000000 129 | vt 0.625000 0.250000 130 | vt 0.625000 0.750000 131 | vt 0.625000 0.750000 132 | vt 0.625000 0.750000 133 | vt 0.625000 0.750000 134 | vt 0.625000 0.250000 135 | vt 0.625000 0.250000 136 | vt 0.625000 1.000000 137 | vt 0.625000 1.000000 138 | vt 0.625000 1.000000 139 | vt 0.625000 0.750000 140 | vt 0.625000 0.750000 141 | vt 0.625000 1.000000 142 | vt 0.625000 0.500000 143 | vt 0.625000 0.500000 144 | vt 0.625000 0.250000 145 | vt 0.625000 0.250000 146 | vt 0.625000 0.500000 147 | vt 0.625000 0.000000 148 | vt 0.625000 0.750000 149 | vt 0.625000 0.000000 150 | vt 0.625000 1.000000 151 | vt 0.625000 0.500000 152 | vt 0.625000 0.250000 153 | vt 0.625000 0.250000 154 | vt 0.625000 0.500000 155 | vt 0.625000 0.750000 156 | vt 0.625000 1.000000 157 | vt 0.875000 0.500000 158 | vt 0.875000 0.750000 159 | vt 0.625000 0.750000 160 | vt 0.625000 0.000000 161 | vt 0.625000 0.000000 162 | vt 0.625000 1.000000 163 | vt 0.625000 0.500000 164 | vt 0.625000 0.500000 165 | vt 0.625000 0.500000 166 | vt 0.625000 0.500000 167 | vt 0.625000 1.000000 168 | vt 0.625000 1.000000 169 | vt 0.625000 1.000000 170 | vt 0.625000 1.000000 171 | vt 0.625000 0.000000 172 | vt 0.625000 0.000000 173 | vt 0.625000 0.000000 174 | vt 0.625000 0.250000 175 | vt 0.625000 0.000000 176 | vt 0.625000 0.000000 177 | vt 0.625000 0.250000 178 | vt 0.625000 0.500000 179 | vt 0.625000 0.750000 180 | vt 0.625000 0.750000 181 | vt 0.625000 0.750000 182 | vt 0.625000 0.750000 183 | vt 0.625000 0.500000 184 | vt 0.625000 1.000000 185 | vt 0.625000 1.000000 186 | vt 0.625000 1.000000 187 | vt 0.625000 1.000000 188 | vt 0.625000 0.750000 189 | vt 0.625000 0.500000 190 | vt 0.625000 0.250000 191 | vt 0.625000 0.000000 192 | vt 0.625000 0.250000 193 | vt 0.625000 0.000000 194 | vt 0.625000 0.750000 195 | vt 0.625000 0.750000 196 | vt 0.625000 0.750000 197 | vt 0.625000 0.500000 198 | vt 0.625000 0.500000 199 | vt 0.625000 0.000000 200 | vt 0.625000 0.250000 201 | vt 0.625000 0.250000 202 | vt 0.625000 0.000000 203 | vt 0.625000 0.250000 204 | vt 0.625000 0.250000 205 | vt 0.625000 0.250000 206 | vt 0.625000 0.250000 207 | vt 0.625000 0.500000 208 | vt 0.625000 0.500000 209 | vt 0.625000 0.500000 210 | vt 0.625000 1.000000 211 | vt 0.625000 1.000000 212 | vt 0.625000 0.000000 213 | vt 0.625000 0.000000 214 | vt 0.625000 0.500000 215 | vt 0.625000 0.500000 216 | vt 0.625000 0.000000 217 | vt 0.625000 0.000000 218 | vt 0.625000 0.250000 219 | vt 0.625000 0.000000 220 | vt 0.625000 0.750000 221 | vt 0.625000 0.750000 222 | vt 0.625000 1.000000 223 | vt 0.625000 1.000000 224 | vt 0.625000 0.000000 225 | vt 0.625000 0.250000 226 | vt 0.625000 0.750000 227 | vt 0.625000 0.750000 228 | vt 0.625000 1.000000 229 | vt 0.625000 1.000000 230 | 231 | # vn vertex normal data 232 | vn 0.0000 0.2651 -0.9642 233 | vn 0.0000 0.0000 1.0000 234 | vn -1.0000 0.0000 0.0000 235 | vn 0.0000 -1.0000 0.0000 236 | vn 1.0000 0.0000 0.0000 237 | vn 0.0000 0.0000 -1.0000 238 | vn 0.0000 0.2651 0.9642 239 | vn -0.9642 0.2651 0.0000 240 | vn 0.9642 0.2651 0.0000 241 | vn -0.6461 0.7632 0.0000 242 | vn 0.7408 0.0000 0.6717 243 | vn -0.7408 0.0000 -0.6717 244 | vn 0.0000 0.7632 0.6461 245 | vn 0.0000 0.7632 -0.6461 246 | vn 0.6461 0.7632 0.0000 247 | vn 0.0000 -0.6177 -0.7864 248 | vn 0.7864 -0.6177 0.0000 249 | vn -0.7864 -0.6177 0.0000 250 | vn 0.0000 -0.6177 0.7864 251 | vn 0.0000 0.5681 -0.8229 252 | vn 0.0000 -0.0692 0.9976 253 | vn 0.0000 1.0000 0.0000 254 | vn 0.8229 0.5681 0.0000 255 | vn -0.8229 0.5681 0.0000 256 | vn 0.0000 0.5681 0.8229 257 | vn 0.6468 -0.7627 0.0000 258 | vn 0.7408 0.0000 -0.6717 259 | vn 0.6468 0.7627 0.0000 260 | vn -0.6468 0.7627 0.0000 261 | vn -0.7408 0.0000 0.6717 262 | vn -0.6468 -0.7627 0.0000 263 | vn -0.9978 -0.0665 0.0000 264 | vn 0.9978 -0.0665 0.0000 265 | vn 0.0000 0.2390 0.9710 266 | vn 0.9944 0.1050 0.0146 267 | vn 0.0000 -0.1776 -0.9841 268 | vn 0.0000 -0.1776 0.9841 269 | vn 0.0000 -0.6592 0.7520 270 | vn 0.0000 0.3233 -0.9463 271 | vn -0.9944 0.1050 0.0146 272 | vn 0.0000 0.6843 -0.7292 273 | vn 0.0000 0.3097 -0.9508 274 | vn 0.0000 0.1306 -0.9914 275 | vn 0.9329 -0.3135 -0.1774 276 | vn 0.0000 -0.5684 0.8228 277 | vn 0.0000 -0.8703 -0.4926 278 | vn -0.9329 -0.3135 -0.1774 279 | vn 0.0000 -0.7828 0.6223 280 | vn -0.9976 -0.0692 0.0000 281 | vn 0.0000 -0.0692 -0.9976 282 | vn 0.9976 -0.0692 0.0000 283 | vn -0.9781 -0.2081 0.0000 284 | vn 0.0000 -0.2081 0.9781 285 | vn 0.0000 -0.2081 -0.9781 286 | vn 0.9781 -0.2081 0.0000 287 | 288 | # set current material to Material 289 | usemtl Material 290 | # I can't figure out what s is 291 | s off 292 | 293 | # face vertex indexes 294 | f 1/1/1 5/2/1 12/3/1 11/4/1 295 | f 4/5/2 3/6/2 7/7/2 8/8/2 296 | f 8/9/3 7/10/3 5/2/3 6/11/3 297 | f 6/12/4 2/13/4 4/5/4 8/14/4 298 | f 2/13/5 1/1/5 3/6/5 4/5/5 299 | f 6/11/6 5/2/6 1/1/6 2/13/6 300 | f 7/7/7 3/6/7 9/15/7 10/16/7 301 | f 5/2/8 7/10/8 10/17/8 12/3/8 302 | f 3/6/9 1/1/9 11/4/9 9/15/9 303 | f 15/18/6 16/19/6 20/20/6 19/21/6 304 | f 20/20/10 18/22/10 22/23/10 24/24/10 305 | f 17/25/11 13/26/11 42/27/11 44/28/11 306 | f 20/20/12 16/19/12 46/29/12 48/30/12 307 | f 14/31/2 13/26/2 17/25/2 18/32/2 308 | f 22/33/2 21/34/2 25/35/2 26/36/2 309 | f 18/32/13 17/25/13 21/34/13 22/33/13 310 | f 19/21/14 20/20/14 24/24/14 23/37/14 311 | f 17/25/15 19/21/15 23/37/15 21/34/15 312 | f 27/38/16 28/39/16 32/40/16 31/41/16 313 | f 23/37/6 24/24/6 28/39/6 27/38/6 314 | f 21/34/5 23/37/5 27/38/5 25/35/5 315 | f 24/24/3 22/23/3 26/42/3 28/39/3 316 | f 25/35/17 27/38/17 31/41/17 29/43/17 317 | f 28/39/18 26/42/18 30/44/18 32/40/18 318 | f 26/36/19 25/35/19 29/43/19 30/45/19 319 | f 35/46/20 36/47/20 40/48/20 39/49/20 320 | f 30/45/21 29/43/21 33/50/21 34/51/21 321 | f 39/49/22 40/52/22 38/53/22 37/54/22 322 | f 33/50/23 35/46/23 39/49/23 37/54/23 323 | f 36/47/24 34/55/24 38/56/24 40/48/24 324 | f 34/51/25 33/50/25 37/54/25 38/57/25 325 | f 41/58/6 43/59/6 55/60/6 53/61/6 326 | f 13/26/26 15/18/26 41/58/26 42/27/26 327 | f 15/18/27 19/21/27 43/59/27 41/58/27 328 | f 19/21/28 17/25/28 44/28/28 43/59/28 329 | f 45/62/2 47/63/2 51/64/2 49/65/2 330 | f 18/22/29 20/20/29 48/30/29 47/66/29 331 | f 14/31/30 18/32/30 47/63/30 45/62/30 332 | f 16/19/31 14/67/31 45/68/31 46/29/31 333 | f 50/69/3 49/70/3 51/71/3 52/72/3 334 | f 47/66/22 48/30/22 52/72/22 51/71/22 335 | f 48/30/6 46/29/6 50/69/6 52/72/6 336 | f 42/27/32 41/58/32 57/73/32 58/74/32 337 | f 54/75/5 53/61/5 55/60/5 56/76/5 338 | f 53/61/33 54/75/33 64/77/33 63/78/33 339 | f 44/28/2 42/27/2 54/75/2 56/76/2 340 | f 43/59/22 44/28/22 56/76/22 55/60/22 341 | f 59/79/34 61/80/34 69/81/34 67/82/34 342 | f 63/78/35 64/77/35 72/83/35 71/84/35 343 | f 41/58/36 53/61/36 63/78/36 57/73/36 344 | f 49/70/32 50/69/32 62/85/32 61/86/32 345 | f 50/69/36 46/29/36 60/87/36 62/85/36 346 | f 45/62/37 49/65/37 61/80/37 59/79/37 347 | f 54/75/37 42/27/37 58/74/37 64/77/37 348 | f 46/29/33 45/68/33 59/88/33 60/87/33 349 | f 72/83/38 66/89/38 74/90/38 80/91/38 350 | f 66/89/3 65/92/3 73/93/3 74/90/3 351 | f 60/87/35 59/88/35 67/94/35 68/95/35 352 | f 57/73/39 63/78/39 71/84/39 65/92/39 353 | f 62/85/39 60/87/39 68/95/39 70/96/39 354 | f 61/86/40 62/85/40 70/96/40 69/97/40 355 | f 58/74/40 57/73/40 65/92/40 66/89/40 356 | f 64/77/34 58/74/34 66/89/34 72/83/34 357 | f 78/98/41 76/99/41 84/100/41 86/101/41 358 | f 73/93/41 79/102/41 87/103/41 81/104/41 359 | f 71/84/5 72/83/5 80/91/5 79/102/5 360 | f 67/82/38 69/81/38 77/105/38 75/106/38 361 | f 68/95/5 67/94/5 75/107/5 76/99/5 362 | f 65/92/42 71/84/42 79/102/42 73/93/42 363 | f 70/96/42 68/95/42 76/99/42 78/98/42 364 | f 69/97/3 70/96/3 78/98/3 77/108/3 365 | f 81/104/43 87/103/43 95/109/43 89/110/43 366 | f 84/100/44 83/111/44 91/112/44 92/113/44 367 | f 77/108/3 78/98/3 86/101/3 85/114/3 368 | f 74/90/3 73/93/3 81/104/3 82/115/3 369 | f 80/91/45 74/90/45 82/115/45 88/116/45 370 | f 79/102/5 80/91/5 88/116/5 87/103/5 371 | f 75/106/45 77/105/45 85/117/45 83/118/45 372 | f 76/99/5 75/107/5 83/111/5 84/100/5 373 | f 92/113/46 91/112/46 93/119/46 94/120/46 374 | f 90/121/46 89/110/46 95/109/46 96/122/46 375 | f 86/101/43 84/100/43 92/113/43 94/120/43 376 | f 85/114/47 86/101/47 94/120/47 93/119/47 377 | f 82/115/47 81/104/47 89/110/47 90/121/47 378 | f 88/116/48 82/115/48 90/121/48 96/122/48 379 | f 87/103/44 88/116/44 96/122/44 95/109/44 380 | f 83/118/48 85/117/48 93/123/48 91/124/48 381 | 382 | # second material 383 | usemtl Material.001 384 | f 32/40/49 30/44/49 34/55/49 36/47/49 385 | f 31/41/50 32/40/50 36/47/50 35/46/50 386 | f 29/43/51 31/41/51 35/46/51 33/50/51 387 | 388 | # third material 389 | usemtl Material.002 390 | f 12/3/52 10/17/52 14/67/52 16/19/52 391 | f 10/16/53 9/15/53 13/26/53 14/31/53 392 | f 11/4/54 12/3/54 16/19/54 15/18/54 393 | f 9/15/55 11/4/55 15/18/55 13/26/55 394 | -------------------------------------------------------------------------------- /src/examples/icosphere.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/icosphere.png -------------------------------------------------------------------------------- /src/examples/monkey.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'None' 2 | # Material Count: 1 3 | 4 | newmtl None 5 | Ns 500 6 | Ka 0.8 0.8 0.8 7 | Kd 0.8 0.8 0.8 8 | Ks 0.8 0.8 0.8 9 | d 1 10 | illum 2 11 | -------------------------------------------------------------------------------- /src/examples/robot.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/robot.blend -------------------------------------------------------------------------------- /src/examples/robot.blend1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/robot.blend1 -------------------------------------------------------------------------------- /src/examples/robot.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'robot.blend' 2 | # Material Count: 3 3 | 4 | newmtl Material 5 | # Ns Specular Exponent 6 | Ns 323.999994 7 | # Ka Ambient Reflectivity 8 | Ka 1.000000 1.000000 1.000000 9 | # Kd Diffuse Reflectivity 10 | Kd 0.800000 0.314507 0.070683 11 | # Ks Specular Reflectivity 12 | Ks 0.500000 0.500000 0.500000 13 | # Ke Emission 14 | Ke 0.000000 0.000000 0.000000 15 | # Ni Optical Density 16 | Ni 1.450000 17 | # d dissolve factor 18 | d 1.000000 19 | # illum illumination model 20 | # Illumination Properties that are turned on in the 21 | # model Property Editor 22 | # 0 Color on and Ambient off 23 | # 1 Color on and Ambient on 24 | # 2 Highlight on 25 | # 3 Reflection on and Ray trace on 26 | # 4 Transparency: Glass on 27 | # Reflection: Ray trace on 28 | # 5 Reflection: Fresnel on and Ray trace on 29 | # 6 Transparency: Refraction on 30 | # Reflection: Fresnel off and Ray trace on 31 | # 7 Transparency: Refraction on 32 | # Reflection: Fresnel on and Ray trace on 33 | # 8 Reflection on and Ray trace off 34 | # 9 Transparency: Glass on 35 | # Reflection: Ray trace off 36 | # 10 Casts shadows onto invisible surfaces 37 | 38 | illum 2 39 | 40 | 41 | newmtl Material.001 42 | Ns 225.000000 43 | Ka 1.000000 1.000000 1.000000 44 | Kd 1.000000 0.000000 0.000000 45 | Ks 0.500000 0.500000 0.500000 46 | Ke 0.000000 0.000000 0.000000 47 | Ni 1.450000 48 | d 1.000000 49 | illum 2 50 | 51 | newmtl Material.002 52 | Ns 225.000000 53 | Ka 1.000000 1.000000 1.000000 54 | Kd 0.000000 0.000000 1.000000 55 | Ks 0.500000 0.500000 0.500000 56 | Ke 0.000000 0.000000 0.000000 57 | Ni 1.450000 58 | d 1.000000 59 | illum 2 60 | -------------------------------------------------------------------------------- /src/examples/robot.obj: -------------------------------------------------------------------------------- 1 | # Blender v2.90.1 OBJ File: 'robot.blend' 2 | # www.blender.org 3 | mtllib robot.mtl 4 | o Cube 5 | v 1.000000 1.000000 -1.000000 6 | v 1.000000 -1.000000 -1.000000 7 | v 1.000000 1.000000 1.000000 8 | v 1.000000 -1.000000 1.000000 9 | v -1.000000 1.000000 -1.000000 10 | v -1.000000 -1.000000 -1.000000 11 | v -1.000000 1.000000 1.000000 12 | v -1.000000 -1.000000 1.000000 13 | v 0.396396 3.195775 0.396396 14 | v -0.396396 3.195775 0.396396 15 | v 0.396396 3.195775 -0.396396 16 | v -0.396396 3.195775 -0.396396 17 | v 0.707780 4.659433 0.707780 18 | v -0.707780 4.659433 0.707780 19 | v 0.707780 4.659433 -0.707780 20 | v -0.707780 4.659433 -0.707780 21 | v 0.707780 5.747853 0.707780 22 | v -0.707780 5.747853 0.707780 23 | v 0.707780 5.747853 -0.707780 24 | v -0.707780 5.747853 -0.707780 25 | v 0.363607 6.039236 0.363607 26 | v -0.363607 6.039236 0.363607 27 | v 0.363607 6.039236 -0.363607 28 | v -0.363607 6.039236 -0.363607 29 | v 0.363607 6.228965 0.363607 30 | v -0.363607 6.228965 0.363607 31 | v 0.363607 6.228965 -0.363607 32 | v -0.363607 6.228965 -0.363607 33 | v 0.527745 6.437937 0.527745 34 | v -0.527745 6.437937 0.527745 35 | v 0.527745 6.437937 -0.527745 36 | v -0.527745 6.437937 -0.527745 37 | v 0.581972 7.220059 0.581972 38 | v -0.581972 7.220059 0.581972 39 | v 0.581972 7.220059 -0.581972 40 | v -0.581972 7.220059 -0.581972 41 | v 0.285750 7.649150 0.285750 42 | v -0.285750 7.649150 0.285750 43 | v 0.285750 7.649150 -0.285750 44 | v -0.285750 7.649150 -0.285750 45 | v 0.980918 4.891058 -0.406536 46 | v 0.980918 4.891058 0.406536 47 | v 0.980918 5.516228 -0.406536 48 | v 0.980918 5.516228 0.406536 49 | v -0.980918 4.891058 0.406536 50 | v -0.980918 4.891058 -0.406536 51 | v -0.980918 5.516228 0.406536 52 | v -0.980918 5.516228 -0.406536 53 | v -1.280918 4.891058 0.406536 54 | v -1.280918 4.891058 -0.406536 55 | v -1.280918 5.516228 0.406536 56 | v -1.280918 5.516228 -0.406536 57 | v 1.280918 4.891058 -0.406536 58 | v 1.280918 4.891058 0.406536 59 | v 1.280918 5.516228 -0.406536 60 | v 1.280918 5.516228 0.406536 61 | v 1.039887 4.005651 -0.246717 62 | v 1.039887 4.005651 0.246717 63 | v -1.039887 4.005651 0.246717 64 | v -1.039887 4.005651 -0.246717 65 | v -1.221950 4.005651 0.246717 66 | v -1.221950 4.005651 -0.246717 67 | v 1.221950 4.005651 -0.246717 68 | v 1.221950 4.005651 0.246717 69 | v 0.980918 3.537906 -0.406536 70 | v 0.980918 3.356243 0.406536 71 | v -0.980918 3.356243 0.406536 72 | v -0.980918 3.537906 -0.406536 73 | v -1.280918 3.356243 0.406536 74 | v -1.280918 3.537906 -0.406536 75 | v 1.280918 3.537906 -0.406536 76 | v 1.280918 3.356243 0.406536 77 | v 0.980918 2.342852 -0.795716 78 | v 0.980918 2.342852 -0.481741 79 | v -0.980918 2.342852 -0.481741 80 | v -0.980918 2.342852 -0.795716 81 | v -1.280918 2.342852 -0.481741 82 | v -1.280918 2.342852 -0.795716 83 | v 1.280918 2.342852 -0.795716 84 | v 1.280918 2.342852 -0.481741 85 | v 0.980918 2.075831 -1.046264 86 | v 0.980918 1.921174 -0.773021 87 | v -0.980918 1.921174 -0.773021 88 | v -0.980918 2.075831 -1.046264 89 | v -1.280918 1.921174 -0.773021 90 | v -1.280918 2.075831 -1.046264 91 | v 1.280918 2.075831 -1.046264 92 | v 1.280918 1.921174 -0.773021 93 | v 1.055918 1.868141 -1.073623 94 | v 1.055918 1.790813 -0.937002 95 | v -1.055918 1.790813 -0.937002 96 | v -1.055918 1.868141 -1.073623 97 | v -1.205918 1.790813 -0.937002 98 | v -1.205918 1.868141 -1.073623 99 | v 1.205918 1.868141 -1.073623 100 | v 1.205918 1.790813 -0.937002 101 | vt 0.625000 0.500000 102 | vt 0.625000 0.250000 103 | vt 0.625000 0.250000 104 | vt 0.625000 0.500000 105 | vt 0.375000 0.750000 106 | vt 0.625000 0.750000 107 | vt 0.625000 1.000000 108 | vt 0.375000 1.000000 109 | vt 0.375000 0.000000 110 | vt 0.625000 0.000000 111 | vt 0.375000 0.250000 112 | vt 0.125000 0.500000 113 | vt 0.375000 0.500000 114 | vt 0.125000 0.750000 115 | vt 0.625000 0.750000 116 | vt 0.625000 1.000000 117 | vt 0.625000 0.000000 118 | vt 0.625000 0.500000 119 | vt 0.625000 0.250000 120 | vt 0.625000 0.250000 121 | vt 0.625000 0.500000 122 | vt 0.625000 0.000000 123 | vt 0.625000 0.000000 124 | vt 0.625000 0.250000 125 | vt 0.625000 0.750000 126 | vt 0.625000 0.750000 127 | vt 0.625000 0.750000 128 | vt 0.625000 0.750000 129 | vt 0.625000 0.250000 130 | vt 0.625000 0.250000 131 | vt 0.625000 1.000000 132 | vt 0.625000 1.000000 133 | vt 0.625000 1.000000 134 | vt 0.625000 0.750000 135 | vt 0.625000 0.750000 136 | vt 0.625000 1.000000 137 | vt 0.625000 0.500000 138 | vt 0.625000 0.500000 139 | vt 0.625000 0.250000 140 | vt 0.625000 0.250000 141 | vt 0.625000 0.500000 142 | vt 0.625000 0.000000 143 | vt 0.625000 0.750000 144 | vt 0.625000 0.000000 145 | vt 0.625000 1.000000 146 | vt 0.625000 0.500000 147 | vt 0.625000 0.250000 148 | vt 0.625000 0.250000 149 | vt 0.625000 0.500000 150 | vt 0.625000 0.750000 151 | vt 0.625000 1.000000 152 | vt 0.875000 0.500000 153 | vt 0.875000 0.750000 154 | vt 0.625000 0.750000 155 | vt 0.625000 0.000000 156 | vt 0.625000 0.000000 157 | vt 0.625000 1.000000 158 | vt 0.625000 0.500000 159 | vt 0.625000 0.500000 160 | vt 0.625000 0.500000 161 | vt 0.625000 0.500000 162 | vt 0.625000 1.000000 163 | vt 0.625000 1.000000 164 | vt 0.625000 1.000000 165 | vt 0.625000 1.000000 166 | vt 0.625000 0.000000 167 | vt 0.625000 0.000000 168 | vt 0.625000 0.000000 169 | vt 0.625000 0.250000 170 | vt 0.625000 0.000000 171 | vt 0.625000 0.000000 172 | vt 0.625000 0.250000 173 | vt 0.625000 0.500000 174 | vt 0.625000 0.750000 175 | vt 0.625000 0.750000 176 | vt 0.625000 0.750000 177 | vt 0.625000 0.750000 178 | vt 0.625000 0.500000 179 | vt 0.625000 1.000000 180 | vt 0.625000 1.000000 181 | vt 0.625000 1.000000 182 | vt 0.625000 1.000000 183 | vt 0.625000 0.750000 184 | vt 0.625000 0.500000 185 | vt 0.625000 0.250000 186 | vt 0.625000 0.000000 187 | vt 0.625000 0.250000 188 | vt 0.625000 0.000000 189 | vt 0.625000 0.750000 190 | vt 0.625000 0.750000 191 | vt 0.625000 0.750000 192 | vt 0.625000 0.500000 193 | vt 0.625000 0.500000 194 | vt 0.625000 0.000000 195 | vt 0.625000 0.250000 196 | vt 0.625000 0.250000 197 | vt 0.625000 0.000000 198 | vt 0.625000 0.250000 199 | vt 0.625000 0.250000 200 | vt 0.625000 0.250000 201 | vt 0.625000 0.250000 202 | vt 0.625000 0.500000 203 | vt 0.625000 0.500000 204 | vt 0.625000 0.500000 205 | vt 0.625000 1.000000 206 | vt 0.625000 1.000000 207 | vt 0.625000 0.000000 208 | vt 0.625000 0.000000 209 | vt 0.625000 0.500000 210 | vt 0.625000 0.500000 211 | vt 0.625000 0.000000 212 | vt 0.625000 0.000000 213 | vt 0.625000 0.250000 214 | vt 0.625000 0.000000 215 | vt 0.625000 0.750000 216 | vt 0.625000 0.750000 217 | vt 0.625000 1.000000 218 | vt 0.625000 1.000000 219 | vt 0.625000 0.000000 220 | vt 0.625000 0.250000 221 | vt 0.625000 0.750000 222 | vt 0.625000 0.750000 223 | vt 0.625000 1.000000 224 | vt 0.625000 1.000000 225 | vn 0.0000 0.2651 -0.9642 226 | vn 0.0000 0.0000 1.0000 227 | vn -1.0000 0.0000 0.0000 228 | vn 0.0000 -1.0000 0.0000 229 | vn 1.0000 0.0000 0.0000 230 | vn 0.0000 0.0000 -1.0000 231 | vn 0.0000 0.2651 0.9642 232 | vn -0.9642 0.2651 0.0000 233 | vn 0.9642 0.2651 0.0000 234 | vn -0.6461 0.7632 0.0000 235 | vn 0.7408 0.0000 0.6717 236 | vn -0.7408 0.0000 -0.6717 237 | vn 0.0000 0.7632 0.6461 238 | vn 0.0000 0.7632 -0.6461 239 | vn 0.6461 0.7632 0.0000 240 | vn 0.0000 -0.6177 -0.7864 241 | vn 0.7864 -0.6177 0.0000 242 | vn -0.7864 -0.6177 0.0000 243 | vn 0.0000 -0.6177 0.7864 244 | vn 0.0000 0.5681 -0.8229 245 | vn 0.0000 -0.0692 0.9976 246 | vn 0.0000 1.0000 0.0000 247 | vn 0.8229 0.5681 0.0000 248 | vn -0.8229 0.5681 0.0000 249 | vn 0.0000 0.5681 0.8229 250 | vn 0.6468 -0.7627 0.0000 251 | vn 0.7408 0.0000 -0.6717 252 | vn 0.6468 0.7627 0.0000 253 | vn -0.6468 0.7627 0.0000 254 | vn -0.7408 0.0000 0.6717 255 | vn -0.6468 -0.7627 0.0000 256 | vn -0.9978 -0.0665 0.0000 257 | vn 0.9978 -0.0665 0.0000 258 | vn 0.0000 0.2390 0.9710 259 | vn 0.9944 0.1050 0.0146 260 | vn 0.0000 -0.1776 -0.9841 261 | vn 0.0000 -0.1776 0.9841 262 | vn 0.0000 -0.6592 0.7520 263 | vn 0.0000 0.3233 -0.9463 264 | vn -0.9944 0.1050 0.0146 265 | vn 0.0000 0.6843 -0.7292 266 | vn 0.0000 0.3097 -0.9508 267 | vn 0.0000 0.1306 -0.9914 268 | vn 0.9329 -0.3135 -0.1774 269 | vn 0.0000 -0.5684 0.8228 270 | vn 0.0000 -0.8703 -0.4926 271 | vn -0.9329 -0.3135 -0.1774 272 | vn 0.0000 -0.7828 0.6223 273 | vn -0.9976 -0.0692 0.0000 274 | vn 0.0000 -0.0692 -0.9976 275 | vn 0.9976 -0.0692 0.0000 276 | vn -0.9781 -0.2081 0.0000 277 | vn 0.0000 -0.2081 0.9781 278 | vn 0.0000 -0.2081 -0.9781 279 | vn 0.9781 -0.2081 0.0000 280 | usemtl Material 281 | s off 282 | f 1/1/1 5/2/1 12/3/1 11/4/1 283 | f 4/5/2 3/6/2 7/7/2 8/8/2 284 | f 8/9/3 7/10/3 5/2/3 6/11/3 285 | f 6/12/4 2/13/4 4/5/4 8/14/4 286 | f 2/13/5 1/1/5 3/6/5 4/5/5 287 | f 6/11/6 5/2/6 1/1/6 2/13/6 288 | f 7/7/7 3/6/7 9/15/7 10/16/7 289 | f 5/2/8 7/10/8 10/17/8 12/3/8 290 | f 3/6/9 1/1/9 11/4/9 9/15/9 291 | f 15/18/6 16/19/6 20/20/6 19/21/6 292 | f 20/20/10 18/22/10 22/23/10 24/24/10 293 | f 17/25/11 13/26/11 42/27/11 44/28/11 294 | f 20/20/12 16/19/12 46/29/12 48/30/12 295 | f 14/31/2 13/26/2 17/25/2 18/32/2 296 | f 22/33/2 21/34/2 25/35/2 26/36/2 297 | f 18/32/13 17/25/13 21/34/13 22/33/13 298 | f 19/21/14 20/20/14 24/24/14 23/37/14 299 | f 17/25/15 19/21/15 23/37/15 21/34/15 300 | f 27/38/16 28/39/16 32/40/16 31/41/16 301 | f 23/37/6 24/24/6 28/39/6 27/38/6 302 | f 21/34/5 23/37/5 27/38/5 25/35/5 303 | f 24/24/3 22/23/3 26/42/3 28/39/3 304 | f 25/35/17 27/38/17 31/41/17 29/43/17 305 | f 28/39/18 26/42/18 30/44/18 32/40/18 306 | f 26/36/19 25/35/19 29/43/19 30/45/19 307 | f 35/46/20 36/47/20 40/48/20 39/49/20 308 | f 30/45/21 29/43/21 33/50/21 34/51/21 309 | f 39/49/22 40/52/22 38/53/22 37/54/22 310 | f 33/50/23 35/46/23 39/49/23 37/54/23 311 | f 36/47/24 34/55/24 38/56/24 40/48/24 312 | f 34/51/25 33/50/25 37/54/25 38/57/25 313 | f 41/58/6 43/59/6 55/60/6 53/61/6 314 | f 13/26/26 15/18/26 41/58/26 42/27/26 315 | f 15/18/27 19/21/27 43/59/27 41/58/27 316 | f 19/21/28 17/25/28 44/28/28 43/59/28 317 | f 45/62/2 47/63/2 51/64/2 49/65/2 318 | f 18/22/29 20/20/29 48/30/29 47/66/29 319 | f 14/31/30 18/32/30 47/63/30 45/62/30 320 | f 16/19/31 14/67/31 45/68/31 46/29/31 321 | f 50/69/3 49/70/3 51/71/3 52/72/3 322 | f 47/66/22 48/30/22 52/72/22 51/71/22 323 | f 48/30/6 46/29/6 50/69/6 52/72/6 324 | f 42/27/32 41/58/32 57/73/32 58/74/32 325 | f 54/75/5 53/61/5 55/60/5 56/76/5 326 | f 53/61/33 54/75/33 64/77/33 63/78/33 327 | f 44/28/2 42/27/2 54/75/2 56/76/2 328 | f 43/59/22 44/28/22 56/76/22 55/60/22 329 | f 59/79/34 61/80/34 69/81/34 67/82/34 330 | f 63/78/35 64/77/35 72/83/35 71/84/35 331 | f 41/58/36 53/61/36 63/78/36 57/73/36 332 | f 49/70/32 50/69/32 62/85/32 61/86/32 333 | f 50/69/36 46/29/36 60/87/36 62/85/36 334 | f 45/62/37 49/65/37 61/80/37 59/79/37 335 | f 54/75/37 42/27/37 58/74/37 64/77/37 336 | f 46/29/33 45/68/33 59/88/33 60/87/33 337 | f 72/83/38 66/89/38 74/90/38 80/91/38 338 | f 66/89/3 65/92/3 73/93/3 74/90/3 339 | f 60/87/35 59/88/35 67/94/35 68/95/35 340 | f 57/73/39 63/78/39 71/84/39 65/92/39 341 | f 62/85/39 60/87/39 68/95/39 70/96/39 342 | f 61/86/40 62/85/40 70/96/40 69/97/40 343 | f 58/74/40 57/73/40 65/92/40 66/89/40 344 | f 64/77/34 58/74/34 66/89/34 72/83/34 345 | f 78/98/41 76/99/41 84/100/41 86/101/41 346 | f 73/93/41 79/102/41 87/103/41 81/104/41 347 | f 71/84/5 72/83/5 80/91/5 79/102/5 348 | f 67/82/38 69/81/38 77/105/38 75/106/38 349 | f 68/95/5 67/94/5 75/107/5 76/99/5 350 | f 65/92/42 71/84/42 79/102/42 73/93/42 351 | f 70/96/42 68/95/42 76/99/42 78/98/42 352 | f 69/97/3 70/96/3 78/98/3 77/108/3 353 | f 81/104/43 87/103/43 95/109/43 89/110/43 354 | f 84/100/44 83/111/44 91/112/44 92/113/44 355 | f 77/108/3 78/98/3 86/101/3 85/114/3 356 | f 74/90/3 73/93/3 81/104/3 82/115/3 357 | f 80/91/45 74/90/45 82/115/45 88/116/45 358 | f 79/102/5 80/91/5 88/116/5 87/103/5 359 | f 75/106/45 77/105/45 85/117/45 83/118/45 360 | f 76/99/5 75/107/5 83/111/5 84/100/5 361 | f 92/113/46 91/112/46 93/119/46 94/120/46 362 | f 90/121/46 89/110/46 95/109/46 96/122/46 363 | f 86/101/43 84/100/43 92/113/43 94/120/43 364 | f 85/114/47 86/101/47 94/120/47 93/119/47 365 | f 82/115/47 81/104/47 89/110/47 90/121/47 366 | f 88/116/48 82/115/48 90/121/48 96/122/48 367 | f 87/103/44 88/116/44 96/122/44 95/109/44 368 | f 83/118/48 85/117/48 93/123/48 91/124/48 369 | usemtl Material.001 370 | f 32/40/49 30/44/49 34/55/49 36/47/49 371 | f 31/41/50 32/40/50 36/47/50 35/46/50 372 | f 29/43/51 31/41/51 35/46/51 33/50/51 373 | usemtl Material.002 374 | f 12/3/52 10/17/52 14/67/52 16/19/52 375 | f 10/16/53 9/15/53 13/26/53 14/31/53 376 | f 11/4/54 12/3/54 16/19/54 15/18/54 377 | f 9/15/55 11/4/55 15/18/55 13/26/55 378 | -------------------------------------------------------------------------------- /src/examples/robot_texture.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/robot_texture.blend -------------------------------------------------------------------------------- /src/examples/robot_texture.blend1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/robot_texture.blend1 -------------------------------------------------------------------------------- /src/examples/robot_texture.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'robot_texture.blend' 2 | # Material Count: 1 3 | 4 | newmtl Material.003 5 | Ns 900.000000 6 | Ka 1.000000 1.000000 1.000000 7 | Kd 0.800000 0.800000 0.800000 8 | Ks 0.500000 0.500000 0.500000 9 | Ke 0.000000 0.000000 0.000000 10 | Ni 1.450000 11 | d 1.000000 12 | illum 2 13 | map_Bump RobotTexPixel_n.png 14 | map_Kd RobotTexPixel.png 15 | -------------------------------------------------------------------------------- /src/examples/robots.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/robots.blend -------------------------------------------------------------------------------- /src/examples/spaceship.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/spaceship.blend -------------------------------------------------------------------------------- /src/examples/spaceship.blend1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/spaceship.blend1 -------------------------------------------------------------------------------- /src/examples/spaceship.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'spaceship.blend' 2 | # Material Count: 1 3 | 4 | newmtl Material 5 | Ns 323.999994 6 | Ka 1.000000 1.000000 1.000000 7 | Kd 0.800000 0.800000 0.800000 8 | Ks 0.500000 0.500000 0.500000 9 | Ke 0.000000 0.000000 0.000000 10 | Ni 1.450000 11 | d 1.000000 12 | illum 2 13 | map_Kd spaceship_uv.psd 14 | -------------------------------------------------------------------------------- /src/examples/spaceship.x3d: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 18 | 23 | 28 | 29 | 30 | 31 | 39 | 40 | 44 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 58 | 65 | 66 | 71 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /src/examples/spaceship_uv.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/spaceship_uv.jpg -------------------------------------------------------------------------------- /src/examples/spaceship_uv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/spaceship_uv.png -------------------------------------------------------------------------------- /src/examples/spaceship_uv.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlelinegames/ASWebGLue/29459205d7e5c1285a2274821e0f87164c592d18/src/examples/spaceship_uv.psd -------------------------------------------------------------------------------- /src/performance-test/Readme.md: -------------------------------------------------------------------------------- 1 | # Performance tests 2 | 3 | I made this folder to test some performance hyptheses. 4 | 5 | ## objTest.ts 6 | 7 | This test was based on a conversation I had with @decode on the AssemblyScript Discord: 8 | https://discord.gg/mNPWbVT4 9 | 10 | The calls to the WebGLContext object require a `global.get` and `load` Wasm call, where 11 | using the direct calls only need a `global.get` call. @decode believed that this would 12 | be a negligible performance cost, and as always, he was correct. When I wrote this test 13 | I had the following outout: 14 | ``` 15 | ============ FASTEST ============ 16 | #1 Direct call test 177 exec/sec 17 | #2 Object inline test 161 exec/sec 18 | #3 Object call test 161 exec/sec 19 | ============ SLOWEST ============ 20 | ``` 21 | Each exec is really 1 Million calls. When you disassemble the code to WAT, the difference 22 | is the single load call. There is a performance difference, but it is quite small. -------------------------------------------------------------------------------- /src/performance-test/objTest.js: -------------------------------------------------------------------------------- 1 | // import benchmark.js 2 | var Benchmark = require('benchmark'); 3 | var suite = new Benchmark.Suite(); 4 | 5 | // use fs to read the pow2_test.wasm module into a byte array 6 | const fs = require('fs'); 7 | const bytes = fs.readFileSync('./objTest.wasm'); 8 | const colors = require('colors'); // allow console logs with color 9 | 10 | // Variables for the WebAssembly functions 11 | var inline_object_test; 12 | var call_object_test; 13 | var direct_test; 14 | 15 | console.log(` 16 | ================= RUNNING BENCHMARK ================= 17 | `.rainbow); 18 | 19 | function init_benchmark() { 20 | // adds the callbacks for the benchmarks 21 | suite.add('#1 '.yellow + 'Direct call test', direct_test); 22 | suite.add('#2 '.yellow + 'Object inline test', inline_object_test); 23 | suite.add('#3 '.yellow + 'Object call test', call_object_test); 24 | // add listeners 25 | suite.on('cycle', function (event) { 26 | console.log(String(event.target)); 27 | }); 28 | 29 | suite.on('complete', function () { 30 | // when the benchmark has finished, log the fastest and slowest functions 31 | let fast_string = ('Fastest is ' + 32 | this.filter('fastest').map('name')); 33 | let slow_string = ('Slowest is ' + 34 | this.filter('slowest').map('name')); 35 | console.log(` 36 | ------------------------------------------------------------ 37 | ${fast_string.green} 38 | ${slow_string.red} 39 | ------------------------------------------------------------ 40 | `); 41 | 42 | // create an array of all successful runs and sort fast to slow 43 | var arr = this.filter('successful'); 44 | arr.sort(function (a, b) { 45 | return a.stats.mean - b.stats.mean; 46 | }); 47 | 48 | console.log(` 49 | 50 | `); 51 | console.log("============ FASTEST ============".green); 52 | while (obj = arr.shift()) { 53 | let extension = ''; 54 | let count = Math.ceil(1 / obj.stats.mean); 55 | 56 | if (count > 1000) { 57 | count /= 1000; 58 | extension = 'K'.green.bold; 59 | } 60 | 61 | if (count > 1000) { 62 | count /= 1000; 63 | extension = 'M'.green.bold; 64 | } 65 | 66 | count = Math.ceil(count); 67 | let count_string = count.toString().yellow + extension; 68 | console.log( 69 | `${obj.name.padEnd(45, ' ')} ${count_string} exec/sec` 70 | ); 71 | } 72 | console.log("============ SLOWEST ============".red); 73 | }); 74 | // run async 75 | suite.run({ 'async': false }); 76 | } 77 | var importObject = { 78 | objTest: { 79 | passInt: (i) => { 80 | } 81 | }, 82 | env: { 83 | abort: () => { }, 84 | } 85 | }; 86 | 87 | (async () => { 88 | const obj = await WebAssembly.instantiate(new Uint8Array(bytes), importObject); 89 | 90 | inline_object_test = obj.instance.exports.inline_object_test; 91 | call_object_test = obj.instance.exports.call_object_test; 92 | direct_test = obj.instance.exports.direct_test; 93 | init_benchmark(); 94 | })(); 95 | -------------------------------------------------------------------------------- /src/performance-test/objTest.ts: -------------------------------------------------------------------------------- 1 | /* 2 | This test was based on a conversation I had with @decode on the AssemblyScript Discord: 3 | https://discord.gg/mNPWbVT4 4 | 5 | The calls to the WebGLContext object require a global.get and load Wasm call, where 6 | using the direct calls only need a global.get call. @decode believed that this would 7 | be a negligible performance cost, and as always, he was correct. When I wrote this test 8 | I had the following outout: 9 | 10 | ============ FASTEST ============ 11 | #1 Direct call test 177 exec/sec 12 | #2 Object inline test 161 exec/sec 13 | #3 Object call test 161 exec/sec 14 | ============ SLOWEST ============ 15 | 16 | Each exec is really 1 Million calls. When you disassemble the code to WAT, the difference 17 | is the single load call. There is a performance difference, but it is quite small. 18 | */ 19 | export declare function passInt(i: i32): void; 20 | @final @unmanaged 21 | class ObjTest { 22 | obj_id: i32 = 1; 23 | @inline constructor(obj_id: i32) { 24 | this.obj_id = obj_id; 25 | } 26 | 27 | @inline inlinePassInt(): void { 28 | passInt(this.obj_id); 29 | } 30 | 31 | callPassInt(): void { 32 | passInt(this.obj_id); 33 | } 34 | 35 | } 36 | var obj = new ObjTest(123); 37 | 38 | export function inline_object_test(): void { 39 | for (var i: i32 = 0; i < 1_000_000; i++) { 40 | obj.inlinePassInt(); 41 | } 42 | } 43 | 44 | export function call_object_test(): void { 45 | for (var i: i32 = 0; i < 1_000_000; i++) { 46 | obj.callPassInt(); 47 | } 48 | } 49 | 50 | const id: i32 = 123; 51 | 52 | export function direct_test(): void { 53 | for (var i: i32 = 0; i < 1_000_000; i++) { 54 | passInt(id); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "assemblyscript/std/assembly.json", 3 | "include": ["./src/**/*.ts"], 4 | "lib": ["asc.d.ts"], 5 | "compilerOptions": { 6 | // "target": "es2020", 7 | // "module": "esnext" 8 | } 9 | } 10 | --------------------------------------------------------------------------------