├── README.md ├── build-js ├── app.js ├── app.js.map ├── core │ ├── math │ │ ├── math-utils.js │ │ ├── math-utils.js.map │ │ ├── matrix.js │ │ ├── matrix.js.map │ │ ├── vector2.js │ │ ├── vector2.js.map │ │ ├── vector4.js │ │ └── vector4.js.map │ ├── raster.js │ ├── raster.js.map │ └── shading │ │ ├── buffer.js │ │ ├── buffer.js.map │ │ ├── color.js │ │ ├── color.js.map │ │ ├── model.js │ │ ├── model.js.map │ │ ├── shader.js │ │ ├── shader.js.map │ │ ├── texture.js │ │ ├── texture.js.map │ │ ├── vertex.js │ │ └── vertex.js.map ├── examples │ ├── draw-box.js │ ├── draw-box.js.map │ ├── draw-mesh.js │ └── draw-mesh.js.map └── web │ ├── input-handler.js │ ├── input-handler.js.map │ ├── webgl-blitter.js │ └── webgl-blitter.js.map ├── index.d.ts ├── main.js ├── package-lock.json ├── package.json ├── res ├── african_head.obj ├── african_head_diffuse.png ├── african_head_nm.png ├── african_head_nm_tangent.png ├── african_head_spec.png ├── diablo3_pose.obj ├── diablo3_pose_diffuse.png ├── diablo3_pose_nm.png ├── diablo3_pose_spec.png └── floor_diffuse.png ├── run.bat ├── run └── index.html ├── src ├── app.ts ├── core │ ├── math │ │ ├── math-utils.ts │ │ ├── matrix.ts │ │ ├── vector2.ts │ │ └── vector4.ts │ ├── raster.ts │ └── shading │ │ ├── buffer.ts │ │ ├── color.ts │ │ ├── model.ts │ │ ├── shader.ts │ │ ├── texture.ts │ │ └── vertex.ts ├── examples │ ├── draw-box.ts │ └── draw-mesh.ts └── web │ ├── input-handler.ts │ └── webgl-blitter.ts ├── tsc.bat └── tsconfig.json /README.md: -------------------------------------------------------------------------------- 1 | 2 | 这是一个使用typescript编写的3D光栅化渲染器,核心渲染代码不超过1000行, 核心部分不会使用任何已有的图形引擎和任何硬件相关的接口。 3 | 4 | 大家可以使用这份代码进行图形学基础的学习, 也可以利用它自己写一些图形效果做一些调试。 5 | 6 | 7 | 目前支持的核心功能有 8 | 9 | * 三角形光栅化 10 | * 透视贴图 11 | * 视锥裁剪 12 | * 边缘剔除 13 | * 深度缓冲 14 | * 纹理双线性插值 15 | * 2x2的MSAA 16 | * 可灵活定制顶点着色/片元着色, 提供接口和vary插值列表 17 | 18 | 例子中支持的非核心功能: 19 | 20 | * obj模型显示/png纹理读取 21 | * 基本光照(blinn-phong) 22 | * 通过鼠标缩放,旋转摄像机 23 | 24 | 后继计划: 25 | 26 | * 支持切线空间的法线纹理 27 | * 阴影 28 | * mipmap 29 | 30 | 31 | 这个是一些渲染截图: 32 | 33 | ![](./docs/head.png) 34 | 35 | 36 | 37 | 38 | 39 | 40 | ##### 一. 运行 41 | 42 | npm install 43 | 44 | run 45 | 46 | 注意 : 运行依赖模块主要是electron + typescript 47 | 48 | ##### 二. 修改ts代码后如何编译 49 | 50 | 执行tsc即可 51 | 52 | 53 | ##### 三. 常见问题 54 | 55 | 1. 为什么使用typescript, 而不是常用的c++? 56 | 57 | typescript更容易上手, 毕竟是学习用途, 不是为了真正商用, 不需要太多考虑性能上的问题。 58 | 59 | 2. 为什么不直接渲染出图片, 而是嵌入到网页上做实时渲染? 60 | 61 | 放到网页上做实时渲染确实更费事(需要把framebuffer当做贴图通过webgl的方式渲染到canvas上), 但是实时渲染可以方便做一些简单的人机交互(比如旋转摄像机) 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /build-js/app.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const webgl_blitter_1 = require("./web/webgl-blitter"); 4 | const raster_1 = require("./core/raster"); 5 | const draw_mesh_1 = require("./examples/draw-mesh"); 6 | class App { 7 | constructor() { 8 | this.showFPSCallback = null; 9 | this.blitter = null; 10 | } 11 | setGL(gl, width, height) { 12 | this.gl = gl; 13 | this.width = width; 14 | this.height = height; 15 | } 16 | run() { 17 | this.renderer = new raster_1.default(this.width, this.height, true); 18 | this.blitter = new webgl_blitter_1.WebGLBlitter(this.gl); 19 | this.example = new draw_mesh_1.default(this.renderer); 20 | let then = 0; 21 | let lastShowFPS = 0; 22 | let loopWrap = (now) => { 23 | now *= 0.001; 24 | const deltaTime = now - then; 25 | if (then > 0 && deltaTime > 0 && this.showFPSCallback != null) { 26 | if (now - lastShowFPS > 0.3) { 27 | const fps = 1 / deltaTime; 28 | this.showFPSCallback(fps); 29 | lastShowFPS = now; 30 | } 31 | } 32 | then = now; 33 | this.loop(); 34 | requestAnimationFrame(loopWrap); 35 | }; 36 | loopWrap(0); 37 | } 38 | setShowFPSCallback(callback) { 39 | this.showFPSCallback = callback; 40 | } 41 | loop() { 42 | this.renderer.clear(); 43 | this.example.draw(); 44 | this.flush(); 45 | } 46 | flush() { 47 | this.blitter.blitPixels(this.renderer.width, this.renderer.height, this.renderer.getFrameBuffer()); 48 | } 49 | } 50 | exports.default = App; 51 | -------------------------------------------------------------------------------- /build-js/app.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":";;AAAA,uDAAkD;AAClD,0CAAkC;AAElC,oDAA2C;AAU3C,MAAqB,GAAG;IAAxB;QAIc,oBAAe,GAAO,IAAI,CAAA;QAI1B,YAAO,GAAgB,IAAI,CAAA;IAkDzC,CAAC;IA/CU,KAAK,CAAC,EAAwB,EAAE,KAAY,EAAE,MAAa;QAC9D,IAAI,CAAC,EAAE,GAAG,EAAE,CAAA;QACZ,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACxB,CAAC;IAEM,GAAG;QACN,IAAI,CAAC,QAAQ,GAAG,IAAI,gBAAM,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QACzD,IAAI,CAAC,OAAO,GAAG,IAAI,4BAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACxC,IAAI,CAAC,OAAO,GAAG,IAAI,mBAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAG1C,IAAI,IAAI,GAAG,CAAC,CAAA;QACZ,IAAI,WAAW,GAAG,CAAC,CAAA;QACnB,IAAI,QAAQ,GAAG,CAAC,GAAU,EAAE,EAAE;YAC1B,GAAG,IAAI,KAAK,CAAA;YACZ,MAAM,SAAS,GAAG,GAAG,GAAG,IAAI,CAAA;YAC5B,IAAI,IAAI,GAAG,CAAC,IAAI,SAAS,GAAG,CAAC,IAAI,IAAI,CAAC,eAAe,IAAI,IAAI,EAAE;gBAC3D,IAAI,GAAG,GAAG,WAAW,GAAG,GAAG,EAAE;oBACzB,MAAM,GAAG,GAAG,CAAC,GAAG,SAAS,CAAA;oBACzB,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAA;oBACzB,WAAW,GAAG,GAAG,CAAA;iBACpB;aAEJ;YACD,IAAI,GAAG,GAAG,CAAA;YACV,IAAI,CAAC,IAAI,EAAE,CAAA;YACX,qBAAqB,CAAC,QAAQ,CAAC,CAAA;QACnC,CAAC,CAAA;QAED,QAAQ,CAAC,CAAC,CAAC,CAAA;IACf,CAAC;IAEM,kBAAkB,CAAC,QAAY;QAClC,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAA;IACnC,CAAC;IAES,IAAI;QACV,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAA;QACrB,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAA;QACnB,IAAI,CAAC,KAAK,EAAE,CAAA;IAChB,CAAC;IAES,KAAK;QACX,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC,CAAA;IACtG,CAAC;CAEJ;AA1DD,sBA0DC"} -------------------------------------------------------------------------------- /build-js/core/math/math-utils.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | class MathUtils { 4 | static getInterpValue2(v1, v2, a, b) { 5 | return v1 * a + v2 * b; 6 | } 7 | static getInterpValue3(v1, v2, v3, a, b, c) { 8 | return v1 * a + v2 * b + v3 * c; 9 | } 10 | static getInterpValue4(v1, v2, v3, v4, a, b, c, d) { 11 | return v1 * a + v2 * b + v3 * c + v4 * d; 12 | } 13 | static clamp(value, min, max) { 14 | if (value < min) { 15 | return min; 16 | } 17 | if (value > max) { 18 | return max; 19 | } 20 | return value; 21 | } 22 | static saturate(value) { 23 | return MathUtils.clamp(value, 0, 1); 24 | } 25 | } 26 | exports.default = MathUtils; 27 | -------------------------------------------------------------------------------- /build-js/core/math/math-utils.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"math-utils.js","sourceRoot":"","sources":["../../../src/core/math/math-utils.ts"],"names":[],"mappings":";;AAEA,MAAqB,SAAS;IAEnB,MAAM,CAAC,eAAe,CAAC,EAAS,EAAE,EAAS,EAAG,CAAQ,EAAE,CAAQ;QACnE,OAAO,EAAE,GAAC,CAAC,GAAG,EAAE,GAAC,CAAC,CAAA;IACtB,CAAC;IAEM,MAAM,CAAC,eAAe,CAAC,EAAS,EAAE,EAAS,EAAE,EAAS,EAAG,CAAQ,EAAE,CAAQ,EAAE,CAAQ;QACxF,OAAO,EAAE,GAAC,CAAC,GAAG,EAAE,GAAC,CAAC,GAAG,EAAE,GAAC,CAAC,CAAA;IAC7B,CAAC;IAEM,MAAM,CAAC,eAAe,CAAC,EAAS,EAAE,EAAS,EAAE,EAAS,EAAE,EAAS,EAAG,CAAQ,EAAE,CAAQ,EAAE,CAAQ,EAAE,CAAQ;QAC7G,OAAO,EAAE,GAAC,CAAC,GAAG,EAAE,GAAC,CAAC,GAAG,EAAE,GAAC,CAAC,GAAG,EAAE,GAAC,CAAC,CAAA;IACpC,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,KAAY,EAAE,GAAU,EAAE,GAAU;QACpD,IAAI,KAAK,GAAG,GAAG,EAAC;YACZ,OAAO,GAAG,CAAA;SACb;QACD,IAAI,KAAK,GAAG,GAAG,EAAC;YACZ,OAAO,GAAG,CAAA;SACb;QACD,OAAO,KAAK,CAAA;IAChB,CAAC;IAEM,MAAM,CAAC,QAAQ,CAAC,KAAY;QAC/B,OAAO,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IACvC,CAAC;CACJ;AA3BD,4BA2BC"} -------------------------------------------------------------------------------- /build-js/core/math/matrix.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.Matrix = void 0; 4 | class Matrix { 5 | constructor() { 6 | this.m = []; 7 | for (let i = 0; i < 4; i++) { 8 | let col = new Float32Array(4); 9 | this.m.push(col); 10 | } 11 | this.identify(); 12 | } 13 | identify() { 14 | this.setValue(0); 15 | this.m[0][0] = this.m[1][1] = this.m[2][2] = this.m[3][3] = 1; 16 | } 17 | multiply(t, dst = null) { 18 | if (dst == null) { 19 | dst = new Matrix(); 20 | } 21 | for (let i = 0; i < 4; i++) { 22 | for (let j = 0; j < 4; j++) { 23 | dst.m[j][i] = 24 | this.m[j][0] * t.m[0][i] 25 | + this.m[j][1] * t.m[1][i] 26 | + this.m[j][2] * t.m[2][i] 27 | + this.m[j][3] * t.m[3][i]; 28 | } 29 | } 30 | return dst; 31 | } 32 | setValue(val) { 33 | for (let i = 0; i < 4; i++) { 34 | for (let j = 0; j < 4; j++) { 35 | this.m[j][i] = val; 36 | } 37 | } 38 | } 39 | setPerspective(fovy, aspect, near, far) { 40 | this.setValue(0); 41 | let n = -near; 42 | let f = -far; 43 | let tn = -Math.tan(fovy / 2); 44 | let nt = 1 / tn; 45 | let nr = nt / aspect; 46 | this.m[0][0] = nr; 47 | this.m[1][1] = nt; 48 | this.m[2][2] = (n + f) / (n - f); 49 | this.m[3][2] = 2 * f * n / (f - n); 50 | this.m[2][3] = 1; 51 | } 52 | setRotateX(angle) { 53 | this.identify(); 54 | let cos = Math.cos(angle), sin = Math.sin(angle); 55 | this.m[1][1] = cos; 56 | this.m[1][2] = sin; 57 | this.m[2][1] = -sin; 58 | this.m[2][2] = cos; 59 | } 60 | setRotateY(angle) { 61 | this.identify(); 62 | let cos = Math.cos(angle), sin = Math.sin(angle); 63 | this.m[0][0] = cos; 64 | this.m[0][2] = -sin; 65 | this.m[2][0] = sin; 66 | this.m[2][2] = cos; 67 | } 68 | setRotateZ(angle) { 69 | this.identify(); 70 | let cos = Math.cos(angle), sin = Math.sin(angle); 71 | this.m[0][0] = cos; 72 | this.m[0][1] = sin; 73 | this.m[1][0] = -sin; 74 | this.m[1][1] = cos; 75 | } 76 | setLookAt(eye, at, up) { 77 | let w = at.sub(eye).normalize().reverse(); 78 | let u = up.cross(w).normalize(); 79 | let v = w.cross(u); 80 | this.setValue(0); 81 | this.m[0][0] = u.x; 82 | this.m[1][0] = u.y; 83 | this.m[2][0] = u.z; 84 | this.m[0][1] = v.x; 85 | this.m[1][1] = v.y; 86 | this.m[2][1] = v.z; 87 | this.m[0][2] = w.x; 88 | this.m[1][2] = w.y; 89 | this.m[2][2] = w.z; 90 | this.m[3][3] = 1; 91 | let tEye = eye.reverse(); 92 | this.m[3][0] = u.dot(tEye); 93 | this.m[3][1] = v.dot(tEye); 94 | this.m[3][2] = w.dot(tEye); 95 | } 96 | } 97 | exports.Matrix = Matrix; 98 | -------------------------------------------------------------------------------- /build-js/core/math/matrix.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"matrix.js","sourceRoot":"","sources":["../../../src/core/math/matrix.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /build-js/core/math/vector2.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.Vector2 = void 0; 4 | const math_utils_1 = require("./math-utils"); 5 | class Vector2 { 6 | constructor(x = 0, y = 0) { 7 | this.x = x; 8 | this.y = y; 9 | } 10 | getLength() { 11 | return Math.sqrt(this.x * this.x + this.y * this.y); 12 | } 13 | static getInterpValue3(v1, v2, v3, a, b, c, dst = null) { 14 | if (dst == null) { 15 | dst = new Vector2(); 16 | } 17 | dst.x = math_utils_1.default.getInterpValue3(v1.x, v2.x, v3.x, a, b, c); 18 | dst.y = math_utils_1.default.getInterpValue3(v1.y, v2.y, v3.y, a, b, c); 19 | return dst; 20 | } 21 | } 22 | exports.Vector2 = Vector2; 23 | -------------------------------------------------------------------------------- /build-js/core/math/vector2.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"vector2.js","sourceRoot":"","sources":["../../../src/core/math/vector2.ts"],"names":[],"mappings":";;;AAAA,6CAAoC;AAEpC,MAAa,OAAO;IAIhB,YAAmB,IAAS,CAAC,EAAE,IAAS,CAAC;QACrC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;QACV,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;IACd,CAAC;IAEM,SAAS;QACZ,OAAO,IAAI,CAAC,IAAI,CAAE,IAAI,CAAC,CAAC,GAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACpD,CAAC;IAEM,MAAM,CAAC,eAAe,CAAC,EAAU,EAAE,EAAU,EAAE,EAAU,EAAE,CAAQ,EAAE,CAAQ,EAAE,CAAQ,EAAE,MAAY,IAAI;QAC5G,IAAI,GAAG,IAAI,IAAI,EAAE;YACb,GAAG,GAAG,IAAI,OAAO,EAAE,CAAA;SACtB;QACD,GAAG,CAAC,CAAC,GAAG,oBAAS,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;QAC5D,GAAG,CAAC,CAAC,GAAG,oBAAS,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;QAC5D,OAAO,GAAG,CAAA;IACd,CAAC;CACJ;AArBD,0BAqBC"} -------------------------------------------------------------------------------- /build-js/core/math/vector4.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.Vector4 = void 0; 4 | const math_utils_1 = require("./math-utils"); 5 | class Vector4 { 6 | constructor(x = 0, y = 0, z = 0, w = 1) { 7 | this.x = x; 8 | this.y = y; 9 | this.z = z; 10 | this.w = w; 11 | } 12 | getLength() { 13 | return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); 14 | } 15 | reverse(dst = null) { 16 | if (dst == null) { 17 | dst = new Vector4(); 18 | } 19 | dst.x = -this.x; 20 | dst.y = -this.y; 21 | dst.z = -this.z; 22 | return dst; 23 | } 24 | add(t, dst = null) { 25 | if (dst == null) { 26 | dst = new Vector4(); 27 | } 28 | dst.x = this.x + t.x; 29 | dst.y = this.y + t.y; 30 | dst.z = this.z + t.z; 31 | dst.w = 1.0; 32 | return dst; 33 | } 34 | sub(t, dst = null) { 35 | if (dst == null) { 36 | dst = new Vector4(); 37 | } 38 | dst.x = this.x - t.x; 39 | dst.y = this.y - t.y; 40 | dst.z = this.z - t.z; 41 | dst.w = 1.0; 42 | return dst; 43 | } 44 | dot(t) { 45 | return this.x * t.x + this.y * t.y + this.z * t.z; 46 | } 47 | cross(t, dst = null) { 48 | if (dst == null) { 49 | dst = new Vector4(); 50 | } 51 | let x = this.y * t.z - this.z * t.y; 52 | let y = this.z * t.x - this.x * t.z; 53 | let z = this.x * t.y - this.y * t.x; 54 | dst.x = x; 55 | dst.y = y; 56 | dst.z = z; 57 | dst.w = 1.0; 58 | return dst; 59 | } 60 | normalize(dst = null) { 61 | if (dst == null) { 62 | dst = new Vector4(); 63 | } 64 | let len = this.getLength(); 65 | if (len > 0) { 66 | dst.x = this.x / len; 67 | dst.y = this.y / len; 68 | dst.z = this.z / len; 69 | } 70 | return dst; 71 | } 72 | transform(matrix, dst = null) { 73 | if (dst == null) { 74 | dst = new Vector4(); 75 | } 76 | let x = this.x, y = this.y, z = this.z, w = this.w; 77 | let m = matrix.m; 78 | dst.x = m[0][0] * x + m[1][0] * y + m[2][0] * z + m[3][0] * w; 79 | dst.y = m[0][1] * x + m[1][1] * y + m[2][1] * z + m[3][1] * w; 80 | dst.z = m[0][2] * x + m[1][2] * y + m[2][2] * z + m[3][2] * w; 81 | dst.w = m[0][3] * x + m[1][3] * y + m[2][3] * z + m[3][3] * w; 82 | return dst; 83 | } 84 | homogenenize() { 85 | if (this.w != 0) { 86 | this.x /= this.w; 87 | this.y /= this.w; 88 | this.z /= this.w; 89 | this.w = 1; 90 | } 91 | } 92 | static getInterpValue3(v1, v2, v3, a, b, c, dst = null) { 93 | if (dst == null) { 94 | dst = new Vector4(); 95 | } 96 | dst.x = math_utils_1.default.getInterpValue3(v1.x, v2.x, v3.x, a, b, c); 97 | dst.y = math_utils_1.default.getInterpValue3(v1.y, v2.y, v3.y, a, b, c); 98 | dst.z = math_utils_1.default.getInterpValue3(v1.z, v2.z, v3.z, a, b, c); 99 | return dst; 100 | } 101 | } 102 | exports.Vector4 = Vector4; 103 | -------------------------------------------------------------------------------- /build-js/core/math/vector4.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"vector4.js","sourceRoot":"","sources":["../../../src/core/math/vector4.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /build-js/core/raster.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const buffer_1 = require("./shading/buffer"); 4 | const matrix_1 = require("./math/matrix"); 5 | const vector4_1 = require("./math/vector4"); 6 | const color_1 = require("./shading/color"); 7 | const math_utils_1 = require("./math/math-utils"); 8 | const vector2_1 = require("./math/vector2"); 9 | class Raster { 10 | constructor(width, height, usingMSAA = true) { 11 | this.buffer = null; 12 | this.backgroundColor = color_1.Color.BLACK.clone(); 13 | this.usingMSAA = true; 14 | this.currentShader = null; 15 | this.camera = { 16 | view: new matrix_1.Matrix(), 17 | projection: new matrix_1.Matrix(), 18 | vp: new matrix_1.Matrix() 19 | }; 20 | this.width = width; 21 | this.height = height; 22 | this.usingMSAA = usingMSAA; 23 | this.buffer = new buffer_1.default(width, height, usingMSAA); 24 | this.setDefaultCamera(); 25 | } 26 | clear() { 27 | this.buffer.clear(this.backgroundColor); 28 | } 29 | drawLine(x0, y0, x1, y1, color) { 30 | if (x0 == x1) { 31 | let dir = y0 < y1 ? 1 : -1; 32 | for (let y = y0; y != y1; y += dir) { 33 | this.setPixel(x0, y, color); 34 | } 35 | this.setPixel(x1, y1, color); 36 | } 37 | else if (y0 == y1) { 38 | let dir = x0 < x1 ? 1 : -1; 39 | for (let x = x0; x != x1; x += dir) { 40 | this.setPixel(x, y0, color); 41 | } 42 | this.setPixel(x1, y1, color); 43 | } 44 | else { 45 | let dx = Math.abs(x1 - x0); 46 | let dy = Math.abs(y1 - y0); 47 | if (dx > dy) { 48 | if (x0 > x1) { 49 | let tx = x0, ty = y0; 50 | x0 = x1, y0 = y1; 51 | x1 = tx, y1 = ty; 52 | } 53 | let dir = y1 > y0 ? 1 : -1; 54 | let y = y0; 55 | let d = (y0 - y1) * (x0 + 1) + (x1 - x0) * (y0 + 0.5 * dir) + x0 * y1 - x1 * y0; 56 | for (let x = x0; x <= x1; x++) { 57 | this.setPixel(x, y, color); 58 | if (d * dir < 0) { 59 | y += dir; 60 | d += (x1 - x0) * dir + (y0 - y1); 61 | } 62 | else { 63 | d += y0 - y1; 64 | } 65 | } 66 | } 67 | else { 68 | if (y0 > y1) { 69 | let tx = x0, ty = y0; 70 | x0 = x1, y0 = y1; 71 | x1 = tx, y1 = ty; 72 | } 73 | let dir = x1 > x0 ? 1 : -1; 74 | let x = x0; 75 | let d = (y0 - y1) * (x0 + 0.5 * dir) + (x1 - x0) * (y0 + 1) + x0 * y1 - x1 * y0; 76 | for (let y = y0; y <= y1; y++) { 77 | this.setPixel(x, y, color); 78 | if (d * dir > 0) { 79 | x += dir; 80 | d += (x1 - x0) + (y0 - y1) * dir; 81 | } 82 | else { 83 | d += x1 - x0; 84 | } 85 | } 86 | } 87 | } 88 | } 89 | barycentricFunc(vs, a, b, x, y) { 90 | return ((vs[a].y - vs[b].y) * x + (vs[b].x - vs[a].x) * y + vs[a].x * vs[b].y - vs[b].x * vs[a].y); 91 | } 92 | getBarycentricInTriangle(x, y, vs, fAlpha, fBelta, fGama, fAlphaTest, fBeltaTest, fGamaTest) { 93 | let belta = this.barycentricFunc(vs, 2, 0, x, y) / fBelta; 94 | let gama = this.barycentricFunc(vs, 0, 1, x, y) / fGama; 95 | let alpha = 1 - belta - gama; 96 | if (alpha >= 0 && belta >= 0 && gama >= 0) { 97 | if ((alpha > 0 || fAlpha * fAlphaTest > 0) 98 | && (belta > 0 || fBelta * fBeltaTest > 0) 99 | && (gama > 0 || fGama * fGamaTest > 0)) { 100 | return [alpha, belta, gama]; 101 | } 102 | } 103 | return null; 104 | } 105 | drawTriangle2D(v0, v1, v2) { 106 | let vs = [v0.context.posScreen, v1.context.posScreen, v2.context.posScreen]; 107 | let x0 = vs[0].x, x1 = vs[1].x, x2 = vs[2].x, y0 = vs[0].y, y1 = vs[1].y, y2 = vs[2].y; 108 | let minX = Math.floor(Math.min(x0, x1, x2)); 109 | let maxX = Math.ceil(Math.max(x0, x1, x2)); 110 | let minY = Math.floor(Math.min(y0, y1, y2)); 111 | let maxY = Math.ceil(Math.max(y0, y1, y2)); 112 | let fBelta = this.barycentricFunc(vs, 2, 0, x1, y1); 113 | let fGama = this.barycentricFunc(vs, 0, 1, x2, y2); 114 | let fAlpha = this.barycentricFunc(vs, 1, 2, x0, y0); 115 | let offScreenPointX = -1, offScreenPointY = -1; 116 | let fAlphaTest = this.barycentricFunc(vs, 1, 2, offScreenPointX, offScreenPointY); 117 | let fGamaTest = this.barycentricFunc(vs, 0, 1, offScreenPointX, offScreenPointY); 118 | let fBeltaTest = this.barycentricFunc(vs, 2, 0, offScreenPointX, offScreenPointY); 119 | for (let x = minX; x <= maxX; x++) { 120 | for (let y = minY; y <= maxY; y++) { 121 | if (!this.usingMSAA) { 122 | this.rasterizePixelInTriangle(x, y, vs, v0, v1, v2, fAlpha, fBelta, fGama, fAlphaTest, fBeltaTest, fGamaTest); 123 | } 124 | else { 125 | this.rasterizePixelInTriangleMSAA(x, y, vs, v0, v1, v2, fAlpha, fBelta, fGama, fAlphaTest, fBeltaTest, fGamaTest); 126 | } 127 | } 128 | } 129 | } 130 | createFragmentInput(x, y, v0, v1, v2, a, b, c) { 131 | let context = { 132 | x: x, 133 | y: y, 134 | color: color_1.Color.WHITE.clone(), 135 | varyingVec2Dict: {}, 136 | varyingVec4Dict: {}, 137 | }; 138 | color_1.Color.getInterpColor(v0.color, v1.color, v2.color, a, b, c, context.color); 139 | for (let k in v0.context.varyingVec2Dict) { 140 | context.varyingVec2Dict[k] = vector2_1.Vector2.getInterpValue3(v0.context.varyingVec2Dict[k], v1.context.varyingVec2Dict[k], v2.context.varyingVec2Dict[k], a, b, c); 141 | } 142 | for (let k in v0.context.varyingVec4Dict) { 143 | context.varyingVec4Dict[k] = vector4_1.Vector4.getInterpValue3(v0.context.varyingVec4Dict[k], v1.context.varyingVec4Dict[k], v2.context.varyingVec4Dict[k], a, b, c); 144 | } 145 | return context; 146 | } 147 | rasterizePixelInTriangle(x, y, vs, v0, v1, v2, fAlpha, fBelta, fGama, fAlphaTest, fBeltaTest, fGamaTest) { 148 | let barycentric = this.getBarycentricInTriangle(x, y, vs, fAlpha, fBelta, fGama, fAlphaTest, fBeltaTest, fGamaTest); 149 | if (barycentric == null) { 150 | return; 151 | } 152 | let rhw = math_utils_1.default.getInterpValue3(v0.context.rhw, v1.context.rhw, v2.context.rhw, barycentric[0], barycentric[1], barycentric[2]); 153 | if (this.buffer.ztest(x, y, rhw)) { 154 | let w = 1 / (rhw != 0 ? rhw : 1); 155 | let a = barycentric[0] * w * v0.context.rhw; 156 | let b = barycentric[1] * w * v1.context.rhw; 157 | let c = barycentric[2] * w * v2.context.rhw; 158 | let input = this.createFragmentInput(x, y, v0, v1, v2, a, b, c); 159 | let finalColor = this.currentShader.fragmentShading(input); 160 | if (finalColor.a > 0) { 161 | this.setPixel(x, y, finalColor); 162 | this.buffer.setZ(x, y, rhw); 163 | } 164 | } 165 | } 166 | rasterizePixelInTriangleMSAA(x, y, vs, v0, v1, v2, fAlpha, fBelta, fGama, fAlphaTest, fBeltaTest, fGamaTest) { 167 | let points = [[x - 0.325, y + 0.125], [x + 0.125, y + 0.325], [x - 0.125, y - 0.325], [x + 0.325, y - 0.125]]; 168 | let testResults = []; 169 | for (let i = 0; i < points.length; i++) { 170 | let p = points[i]; 171 | let px = p[0], py = p[1]; 172 | let barycentric = this.getBarycentricInTriangle(px, py, vs, fAlpha, fBelta, fGama, fAlphaTest, fBeltaTest, fGamaTest); 173 | if (barycentric != null) { 174 | let rhw = math_utils_1.default.getInterpValue3(v0.context.rhw, v1.context.rhw, v2.context.rhw, barycentric[0], barycentric[1], barycentric[2]); 175 | if (this.buffer.ztest(x, y, rhw, i)) { 176 | testResults.push({ 177 | barycentric: barycentric, 178 | index: i, 179 | x: x, 180 | y: y, 181 | rhw: rhw 182 | }); 183 | } 184 | } 185 | } 186 | if (testResults.length > 0) { 187 | let fx = x, fy = y; 188 | let barycentric = this.getBarycentricInTriangle(x, y, vs, fAlpha, fBelta, fGama, fAlphaTest, fBeltaTest, fGamaTest); 189 | if (barycentric == null) { 190 | barycentric = testResults[0].barycentric; 191 | fx = testResults[0].x; 192 | fy = testResults[0].y; 193 | } 194 | let rhw = math_utils_1.default.getInterpValue3(v0.context.rhw, v1.context.rhw, v2.context.rhw, barycentric[0], barycentric[1], barycentric[2]); 195 | let w = 1 / (rhw != 0 ? rhw : 1); 196 | let a = barycentric[0] * w * v0.context.rhw; 197 | let b = barycentric[1] * w * v1.context.rhw; 198 | let c = barycentric[2] * w * v2.context.rhw; 199 | let input = this.createFragmentInput(fx, fy, v0, v1, v2, a, b, c); 200 | let finalColor = this.currentShader.fragmentShading(input); 201 | if (finalColor.a > 0) { 202 | for (let result of testResults) { 203 | let index = result.index; 204 | let rhw = result.rhw; 205 | this.setPixel(x, y, finalColor, index); 206 | this.buffer.setZ(x, y, rhw, index); 207 | } 208 | this.buffer.applyMSAAFilter(x, y); 209 | } 210 | } 211 | } 212 | setBackgroundColor(color) { 213 | this.backgroundColor = color.clone(); 214 | } 215 | setPixel(x, y, color, index = 0) { 216 | if (x < this.width && y < this.height && x >= 0 && y >= 0) { 217 | this.buffer.setColor(x, y, color, index); 218 | } 219 | } 220 | drawTriangle(va) { 221 | if (va.length % 3 != 0) { 222 | return; 223 | } 224 | this.currentShader.setViewProject(this.camera.vp); 225 | for (let vertex of va) { 226 | vertex.context = { 227 | posProject: new vector4_1.Vector4(), 228 | posScreen: new vector4_1.Vector4(), 229 | rhw: 1, 230 | varyingVec2Dict: {}, 231 | varyingVec4Dict: {}, 232 | }; 233 | this.currentShader.vertexShading(vertex); 234 | vertex.context.rhw = 1 / vertex.context.posProject.w; 235 | vertex.context.posProject.homogenenize(); 236 | } 237 | let culling = false; 238 | for (let p of va) { 239 | if (!this.isInsideViewVolumn(p.context.posProject)) { 240 | culling = true; 241 | break; 242 | } 243 | } 244 | if (!culling) { 245 | for (let p of va) { 246 | this.convertToScreenPos(p.context.posProject, p.context.posScreen, this.width, this.height); 247 | } 248 | this.drawTriangle2D(va[0], va[1], va[2]); 249 | } 250 | } 251 | setDefaultCamera() { 252 | let eye = new vector4_1.Vector4(1.5, 0, 3, 1); 253 | let at = new vector4_1.Vector4(0, 0, 0, 1); 254 | let up = new vector4_1.Vector4(0, 1, 0, 1); 255 | let fovy = Math.PI / 2; 256 | let aspect = this.width / this.height; 257 | let near = 1; 258 | let far = 500; 259 | this.setCamera(eye, at, up, fovy, aspect, near, far); 260 | } 261 | setCamera(eye, lookAt, up, fovy, aspect, near, far) { 262 | this.camera.view.setLookAt(eye, lookAt, up); 263 | this.camera.projection.setPerspective(fovy, aspect, near, far); 264 | this.camera.vp = this.camera.view.multiply(this.camera.projection); 265 | } 266 | getFrameBuffer() { 267 | return this.buffer.frameBuffer; 268 | } 269 | setShader(shader) { 270 | this.currentShader = shader; 271 | } 272 | isInsideViewVolumn(v) { 273 | if (v.x < -1 || v.x > 1) { 274 | return false; 275 | } 276 | if (v.y < -1 || v.y > 1) { 277 | return false; 278 | } 279 | if (v.z < -1 || v.z > 1) { 280 | return false; 281 | } 282 | return true; 283 | } 284 | convertToScreenPos(v, dst, width, height) { 285 | dst.x = (v.x + 1) / 2 * width; 286 | dst.y = (v.y + 1) / 2 * height; 287 | dst.z = v.z; 288 | return dst; 289 | } 290 | } 291 | exports.default = Raster; 292 | -------------------------------------------------------------------------------- /build-js/core/raster.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"raster.js","sourceRoot":"","sources":["../../src/core/raster.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /build-js/core/shading/buffer.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const color_1 = require("./color"); 4 | class Buffer { 5 | constructor(width, height, usingMSAA) { 6 | this.usingMSAA = true; 7 | this.zbuf = null; 8 | this.msaaColorBuffer = null; 9 | this.usingMSAA = usingMSAA; 10 | this.width = width; 11 | this.height = height; 12 | this.frameBuffer = new Uint8Array(width * height * 4); 13 | if (!this.usingMSAA) { 14 | this.zbuf = new Float32Array(width * height); 15 | } 16 | else { 17 | this.zbuf = new Float32Array(width * height * 4); 18 | this.msaaColorBuffer = new Uint8Array(width * height * 4 * 4); 19 | } 20 | } 21 | getZPos(x, y, index) { 22 | if (!this.usingMSAA) { 23 | return this.width * y + x; 24 | } 25 | else { 26 | return (this.width * y + x) * 4 + index; 27 | } 28 | } 29 | ztest(x, y, rhw, index = 0) { 30 | let zPos = this.getZPos(x, y, index); 31 | if (isNaN(this.zbuf[zPos]) || this.zbuf[zPos] > rhw) { 32 | return true; 33 | } 34 | return false; 35 | } 36 | setZ(x, y, rhw, index = 0) { 37 | let zPos = this.getZPos(x, y, index); 38 | this.zbuf[zPos] = rhw; 39 | } 40 | setColor(x, y, color, index = 0) { 41 | if (!this.usingMSAA) { 42 | this.setFrameBufferPixel(x, y, color); 43 | } 44 | else { 45 | let pstart = (this.width * y + x) * 4 * 4 + index * 4; 46 | this.msaaColorBuffer[pstart] = color.r; 47 | this.msaaColorBuffer[pstart + 1] = color.g; 48 | this.msaaColorBuffer[pstart + 2] = color.b; 49 | this.msaaColorBuffer[pstart + 3] = color.a; 50 | } 51 | } 52 | setFrameBufferPixel(x, y, color) { 53 | let pstart = (this.width * y + x) * 4; 54 | this.frameBuffer[pstart] = color.r; 55 | this.frameBuffer[pstart + 1] = color.g; 56 | this.frameBuffer[pstart + 2] = color.b; 57 | this.frameBuffer[pstart + 3] = 255; 58 | } 59 | clear(backgroundColor) { 60 | for (let l = 0; l < this.frameBuffer.length; l += 4) { 61 | this.frameBuffer[l] = backgroundColor.r; 62 | this.frameBuffer[l + 1] = backgroundColor.g; 63 | this.frameBuffer[l + 2] = backgroundColor.b; 64 | this.frameBuffer[l + 3] = backgroundColor.a; 65 | } 66 | for (let l = 0; l < this.zbuf.length; l++) { 67 | this.zbuf[l] = NaN; 68 | } 69 | if (this.msaaColorBuffer != null) { 70 | for (let l = 0; l < this.msaaColorBuffer.length; l += 4) { 71 | this.msaaColorBuffer[l] = backgroundColor.r; 72 | this.msaaColorBuffer[l + 1] = backgroundColor.g; 73 | this.msaaColorBuffer[l + 2] = backgroundColor.b; 74 | this.msaaColorBuffer[l + 3] = backgroundColor.a; 75 | } 76 | } 77 | } 78 | applyMSAAFilter(x, y) { 79 | if (this.msaaColorBuffer == null) { 80 | return; 81 | } 82 | let pstart = (this.width * y + x) * 4 * 4; 83 | let color = new color_1.Color(); 84 | for (let i = 0; i < 4; i++) { 85 | let colorStart = pstart + i * 4; 86 | let r = this.msaaColorBuffer[colorStart]; 87 | let g = this.msaaColorBuffer[colorStart + 1]; 88 | let b = this.msaaColorBuffer[colorStart + 2]; 89 | let a = this.msaaColorBuffer[colorStart + 3]; 90 | color.r += 0.25 * r; 91 | color.g += 0.25 * g; 92 | color.b += 0.25 * b; 93 | color.a += 0.25 * a; 94 | } 95 | this.setFrameBufferPixel(x, y, color); 96 | } 97 | } 98 | exports.default = Buffer; 99 | -------------------------------------------------------------------------------- /build-js/core/shading/buffer.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"buffer.js","sourceRoot":"","sources":["../../../src/core/shading/buffer.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /build-js/core/shading/color.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.Color = void 0; 4 | const math_utils_1 = require("../math/math-utils"); 5 | class Color { 6 | constructor(r = 0, g = 0, b = 0, a = 0) { 7 | this.r = r; 8 | this.g = g; 9 | this.b = b; 10 | this.a = a; 11 | } 12 | set(color) { 13 | this.r = color.r; 14 | this.g = color.g; 15 | this.b = color.b; 16 | this.a = color.a; 17 | return this; 18 | } 19 | clone() { 20 | return new Color(this.r, this.g, this.b, this.a); 21 | } 22 | add(value) { 23 | this.r += value; 24 | this.g += value; 25 | this.b += value; 26 | this.a += value; 27 | this.clamp(0, 255); 28 | return this; 29 | } 30 | addRGB(color) { 31 | this.r += color.r; 32 | this.g += color.g; 33 | this.b += color.b; 34 | this.clamp(0, 255); 35 | return this; 36 | } 37 | multiplyRGB(factor) { 38 | this.r *= factor; 39 | this.g *= factor; 40 | this.b *= factor; 41 | this.clamp(0, 255); 42 | return this; 43 | } 44 | clamp(min, max) { 45 | this.r = math_utils_1.default.clamp(this.r, min, max); 46 | this.g = math_utils_1.default.clamp(this.g, min, max); 47 | this.b = math_utils_1.default.clamp(this.b, min, max); 48 | this.a = math_utils_1.default.clamp(this.a, min, max); 49 | } 50 | static getInterpColor(color1, color2, color3, a, b, c, dstColor) { 51 | dstColor.r = math_utils_1.default.getInterpValue3(color1.r, color2.r, color3.r, a, b, c); 52 | dstColor.g = math_utils_1.default.getInterpValue3(color1.g, color2.g, color3.g, a, b, c); 53 | dstColor.b = math_utils_1.default.getInterpValue3(color1.b, color2.b, color3.b, a, b, c); 54 | dstColor.a = math_utils_1.default.getInterpValue3(color1.a, color2.a, color3.a, a, b, c); 55 | } 56 | static getBilinearColor(c1, c2, c3, c4, w1, w2, w3, w4, dstColor) { 57 | dstColor.r = math_utils_1.default.getInterpValue4(c1.r, c2.r, c3.r, c4.r, w1, w2, w3, w4); 58 | dstColor.g = math_utils_1.default.getInterpValue4(c1.g, c2.g, c3.g, c4.g, w1, w2, w3, w4); 59 | dstColor.b = math_utils_1.default.getInterpValue4(c1.b, c2.b, c3.b, c4.b, w1, w2, w3, w4); 60 | dstColor.a = math_utils_1.default.getInterpValue4(c1.a, c2.a, c3.a, c4.a, w1, w2, w3, w4); 61 | } 62 | static multiplyColor(color1, color2, dst) { 63 | dst.r = color1.r * color2.r / 255; 64 | dst.g = color1.g * color2.g / 255; 65 | dst.b = color1.b * color2.b / 255; 66 | dst.a = color1.a * color2.a / 255; 67 | return dst; 68 | } 69 | } 70 | exports.Color = Color; 71 | Color.BLACK = new Color(0, 0, 0, 255); 72 | Color.WHITE = new Color(255, 255, 255, 255); 73 | Color.RED = new Color(255, 0, 0, 255); 74 | Color.BLUE = new Color(0, 0, 255, 255); 75 | Color.GREEN = new Color(0, 255, 255, 255); 76 | Color.YELLOW = new Color(255, 255, 0, 255); 77 | Color.GRAY = new Color(100, 100, 100, 255); 78 | -------------------------------------------------------------------------------- /build-js/core/shading/color.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"color.js","sourceRoot":"","sources":["../../../src/core/shading/color.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /build-js/core/shading/model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const vector2_1 = require("../math/vector2"); 4 | const vector4_1 = require("../math/vector4"); 5 | const color_1 = require("./color"); 6 | const fs = require("fs"); 7 | const path = require("path"); 8 | class Model { 9 | constructor() { 10 | this.triangles = []; 11 | } 12 | createFromFile(file) { 13 | let objContent = fs.readFileSync(path.join(__dirname, "../../../res/" + file), "utf8"); 14 | this.triangles = []; 15 | let lines = objContent.split(/\r\n|\n/); 16 | let vList = []; 17 | let uvList = []; 18 | let normalList = []; 19 | let faceList = []; 20 | for (let line of lines) { 21 | if (line != "") { 22 | if (line.charAt(0) == "#") { 23 | continue; 24 | } 25 | let vals = line.split(/\s+/); 26 | let t = vals[0]; 27 | if (t == "v" && vals.length >= 4) { 28 | vList.push(new vector4_1.Vector4(parseFloat(vals[1]), parseFloat(vals[2]), parseFloat(vals[3]))); 29 | } 30 | else if (t == "vt" && vals.length >= 3) { 31 | uvList.push(new vector2_1.Vector2(parseFloat(vals[1]), parseFloat(vals[2]))); 32 | } 33 | else if (t == "vn" && vals.length >= 4) { 34 | normalList.push(new vector4_1.Vector4(parseFloat(vals[1]), parseFloat(vals[2]), parseFloat(vals[3]))); 35 | } 36 | else if (t == "f" && vals.length >= 4) { 37 | let fvals = [ 38 | vals[1].split("/"), 39 | vals[2].split("/"), 40 | vals[3].split("/"), 41 | ]; 42 | faceList.push(fvals); 43 | } 44 | } 45 | } 46 | for (let f of faceList) { 47 | let v1s = f[0]; 48 | let v2s = f[1]; 49 | let v3s = f[2]; 50 | let v1 = vList[parseInt(v1s[0]) - 1]; 51 | let v2 = vList[parseInt(v2s[0]) - 1]; 52 | let v3 = vList[parseInt(v3s[0]) - 1]; 53 | let uv1 = uvList[parseInt(v1s[1]) - 1]; 54 | let uv2 = uvList[parseInt(v2s[1]) - 1]; 55 | let uv3 = uvList[parseInt(v3s[1]) - 1]; 56 | let n1 = normalList[parseInt(v1s[2]) - 1]; 57 | let n2 = normalList[parseInt(v2s[2]) - 1]; 58 | let n3 = normalList[parseInt(v3s[2]) - 1]; 59 | this.triangles.push([ 60 | { posModel: v1, color: color_1.Color.WHITE, uv: uv1, normal: n1 }, 61 | { posModel: v2, color: color_1.Color.WHITE, uv: uv2, normal: n2 }, 62 | { posModel: v3, color: color_1.Color.WHITE, uv: uv3, normal: n3 }, 63 | ]); 64 | } 65 | } 66 | } 67 | exports.default = Model; 68 | -------------------------------------------------------------------------------- /build-js/core/shading/model.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/core/shading/model.ts"],"names":[],"mappings":";;AAAA,6CAAyC;AACzC,6CAAyC;AACzC,mCAA+B;AAG/B,yBAAyB;AACzB,6BAA6B;AAE7B,MAAqB,KAAK;IAA1B;QACW,cAAS,GAAwB,EAAE,CAAA;IA4D9C,CAAC;IA1DU,cAAc,CAAC,IAAW;QAC7B,IAAI,UAAU,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,GAAG,IAAI,CAAC,EAAE,MAAM,CAAC,CAAA;QACtF,IAAI,CAAC,SAAS,GAAG,EAAE,CAAA;QAEnB,IAAI,KAAK,GAAiB,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QACrD,IAAI,KAAK,GAAiB,EAAE,CAAA;QAC5B,IAAI,MAAM,GAAiB,EAAE,CAAA;QAC7B,IAAI,UAAU,GAAiB,EAAE,CAAA;QACjC,IAAI,QAAQ,GAAa,EAAE,CAAA;QAE3B,KAAK,IAAI,IAAI,IAAI,KAAK,EAAE;YACpB,IAAI,IAAI,IAAI,EAAE,EAAC;gBACX,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,EAAC;oBACtB,SAAQ;iBACX;gBACD,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;gBAC5B,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;gBACf,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,IAAE,CAAC,EAAE;oBAC5B,KAAK,CAAC,IAAI,CAAC,IAAI,iBAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;iBACxF;qBAAM,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,IAAE,CAAC,EAAE;oBACpC,MAAM,CAAC,IAAI,CAAC,IAAI,iBAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAA;iBACtE;qBAAK,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,IAAE,CAAC,EAAE;oBACnC,UAAU,CAAC,IAAI,CAAC,IAAI,iBAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;iBAC7F;qBAAK,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,IAAE,CAAC,EAAE;oBAClC,IAAI,KAAK,GAAG;wBACR,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;wBAClB,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;wBAClB,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;qBACrB,CAAA;oBACD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;iBACvB;aACJ;SACJ;QAED,KAAK,IAAI,CAAC,IAAI,QAAQ,EAAC;YACnB,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;YACd,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;YACd,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;YAEd,IAAI,EAAE,GAAG,KAAK,CAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAE,CAAC,CAAE,CAAA;YACrC,IAAI,EAAE,GAAG,KAAK,CAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAE,CAAC,CAAE,CAAA;YACrC,IAAI,EAAE,GAAG,KAAK,CAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAE,CAAC,CAAE,CAAA;YAErC,IAAI,GAAG,GAAG,MAAM,CAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAE,CAAC,CAAE,CAAA;YACvC,IAAI,GAAG,GAAG,MAAM,CAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAE,CAAC,CAAE,CAAA;YACvC,IAAI,GAAG,GAAG,MAAM,CAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAE,CAAC,CAAE,CAAA;YAEvC,IAAI,EAAE,GAAG,UAAU,CAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAE,CAAC,CAAE,CAAA;YAC1C,IAAI,EAAE,GAAG,UAAU,CAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAE,CAAC,CAAE,CAAA;YAC1C,IAAI,EAAE,GAAG,UAAU,CAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAE,CAAC,CAAE,CAAA;YAE1C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAChB,EAAC,QAAQ,EAAC,EAAE,EAAE,KAAK,EAAC,aAAK,CAAC,KAAK,EAAE,EAAE,EAAC,GAAG,EAAE,MAAM,EAAC,EAAE,EAAC;gBACnD,EAAC,QAAQ,EAAC,EAAE,EAAE,KAAK,EAAC,aAAK,CAAC,KAAK,EAAE,EAAE,EAAC,GAAG,EAAE,MAAM,EAAC,EAAE,EAAC;gBACnD,EAAC,QAAQ,EAAC,EAAE,EAAE,KAAK,EAAC,aAAK,CAAC,KAAK,EAAE,EAAE,EAAC,GAAG,EAAE,MAAM,EAAC,EAAE,EAAC;aACtD,CAAC,CAAA;SACL;IACL,CAAC;CACJ;AA7DD,wBA6DC"} -------------------------------------------------------------------------------- /build-js/core/shading/shader.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.ShaderVarying = void 0; 4 | class ShaderVarying { 5 | } 6 | exports.ShaderVarying = ShaderVarying; 7 | ShaderVarying.NORMAL = "normal"; 8 | ShaderVarying.UV = "uv"; 9 | ShaderVarying.EYE = "eye"; 10 | ShaderVarying.WORLD_POS = "world_pos"; 11 | class Shader { 12 | constructor(program) { 13 | this.program = program; 14 | this.vertexInput = { viewProject: null }; 15 | } 16 | setViewProject(vp) { 17 | this.vertexInput.viewProject = vp; 18 | } 19 | vertexShading(vertex) { 20 | return this.program.vertexShading(vertex, this.vertexInput); 21 | } 22 | fragmentShading(input) { 23 | return this.program.fragmentShading(input); 24 | } 25 | } 26 | exports.default = Shader; 27 | -------------------------------------------------------------------------------- /build-js/core/shading/shader.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"shader.js","sourceRoot":"","sources":["../../../src/core/shading/shader.ts"],"names":[],"mappings":";;;AAuBA,MAAa,aAAa;;AAA1B,sCAMC;AALiB,oBAAM,GAAG,QAAQ,CAAA;AACjB,gBAAE,GAAG,IAAI,CAAA;AACT,iBAAG,GAAG,KAAK,CAAA;AACX,uBAAS,GAAG,WAAW,CAAA;AAIzC,MAAqB,MAAM;IAGvB,YAAmB,OAAsB;QACrC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,WAAW,GAAG,EAAC,WAAW,EAAC,IAAI,EAAC,CAAA;IACzC,CAAC;IAEM,cAAc,CAAC,EAAS;QAC3B,IAAI,CAAC,WAAW,CAAC,WAAW,GAAG,EAAE,CAAA;IACrC,CAAC;IAEM,aAAa,CAAC,MAAa;QAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAA;IAC/D,CAAC;IAEM,eAAe,CAAC,KAAmB;QACtC,OAAO,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,CAAA;IAC9C,CAAC;CACJ;AAnBD,yBAmBC"} -------------------------------------------------------------------------------- /build-js/core/shading/texture.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.TEXTURE_FILTER_MODE = void 0; 4 | const vector4_1 = require("../math/vector4"); 5 | const color_1 = require("./color"); 6 | const fs = require("fs"); 7 | const path = require("path"); 8 | let decode = require('image-decode'); 9 | var TEXTURE_FILTER_MODE; 10 | (function (TEXTURE_FILTER_MODE) { 11 | TEXTURE_FILTER_MODE[TEXTURE_FILTER_MODE["NEAREST"] = 1] = "NEAREST"; 12 | TEXTURE_FILTER_MODE[TEXTURE_FILTER_MODE["BILINEAR"] = 2] = "BILINEAR"; 13 | })(TEXTURE_FILTER_MODE = exports.TEXTURE_FILTER_MODE || (exports.TEXTURE_FILTER_MODE = {})); 14 | class Texture { 15 | constructor(width, height) { 16 | this.data = []; 17 | this.tmp = new color_1.Color(); 18 | this.filterMode = TEXTURE_FILTER_MODE.BILINEAR; 19 | this.width = width; 20 | this.height = height; 21 | } 22 | static createTextureFromFile(file) { 23 | let { data, width, height } = decode(fs.readFileSync(path.join(__dirname, "../../../res/" + file))); 24 | let texture = new Texture(width, height); 25 | for (let y = 0; y < height; y++) { 26 | for (let x = 0; x < width; x++) { 27 | let pos = ((height - y - 1) * width + x) * 4; 28 | let color = new color_1.Color(data[pos], data[pos + 1], data[pos + 2], data[pos + 3]); 29 | texture.setPixel(x, y, color); 30 | } 31 | } 32 | return texture; 33 | } 34 | setPixel(x, y, color) { 35 | let pos = y * this.width + x; 36 | this.data[pos] = color; 37 | } 38 | sample(uv) { 39 | let x = uv.x * (this.width - 1); 40 | let y = uv.y * (this.height - 1); 41 | return this.samplePos(x + 0.5, y + 0.5); 42 | } 43 | sampleAsVector(uv) { 44 | let color = this.sample(uv); 45 | return new vector4_1.Vector4((color.r / 255) * 2 - 1, (color.g / 255) * 2 - 1, (color.b / 255) * 2 - 1, (color.a / 255) * 2 - 1); 46 | } 47 | clamp(value, min, max) { 48 | if (value > max) { 49 | return max; 50 | } 51 | if (value < min) { 52 | return min; 53 | } 54 | return value; 55 | } 56 | getPixel(x, y) { 57 | return this.data[y * this.width + x]; 58 | } 59 | samplePos(x, y) { 60 | if (this.filterMode == TEXTURE_FILTER_MODE.NEAREST) { 61 | x = this.clamp(Math.floor(x), 0, this.width - 1); 62 | y = this.clamp(Math.floor(y), 0, this.height - 1); 63 | let color = this.getPixel(x, y); 64 | this.tmp.a = color.a; 65 | this.tmp.r = color.r; 66 | this.tmp.g = color.g; 67 | this.tmp.b = color.b; 68 | return this.tmp; 69 | } 70 | else if (this.filterMode == TEXTURE_FILTER_MODE.BILINEAR) { 71 | let x1 = this.clamp(Math.floor(x), 0, this.width - 1); 72 | let y1 = this.clamp(Math.floor(y), 0, this.height - 1); 73 | let x2 = this.clamp(Math.floor(x) + 1, 0, this.width - 1); 74 | let y2 = this.clamp(Math.floor(y) + 1, 0, this.height - 1); 75 | let c1 = this.getPixel(x1, y1); 76 | let c2 = this.getPixel(x2, y1); 77 | let c3 = this.getPixel(x1, y2); 78 | let c4 = this.getPixel(x2, y2); 79 | let dx = x - x1; 80 | let dy = y - y1; 81 | let w1 = (1 - dx) * (1 - dy); 82 | let w2 = dx * (1 - dy); 83 | let w3 = (1 - dx) * dy; 84 | let w4 = dx * dy; 85 | color_1.Color.getBilinearColor(c1, c2, c3, c4, w1, w2, w3, w4, this.tmp); 86 | return this.tmp; 87 | } 88 | return color_1.Color.BLACK; 89 | } 90 | } 91 | exports.default = Texture; 92 | -------------------------------------------------------------------------------- /build-js/core/shading/texture.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"texture.js","sourceRoot":"","sources":["../../../src/core/shading/texture.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /build-js/core/shading/vertex.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /build-js/core/shading/vertex.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"vertex.js","sourceRoot":"","sources":["../../../src/core/shading/vertex.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /build-js/examples/draw-box.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const vector4_1 = require("../core/math/vector4"); 4 | const color_1 = require("../core/shading/color"); 5 | const shader_1 = require("../core/shading/shader"); 6 | const texture_1 = require("../core/shading/texture"); 7 | const vector2_1 = require("../core/math/vector2"); 8 | const input_handler_1 = require("../web/input-handler"); 9 | const math_utils_1 = require("../core/math/math-utils"); 10 | const matrix_1 = require("../core/math/matrix"); 11 | class DrawBox { 12 | constructor(renderer) { 13 | this.fovy = Math.PI / 2; 14 | this.eye = new vector4_1.Vector4(1.5, 0, 2.5, 1); 15 | this.texture = this.createTexture(); 16 | this.renderer = renderer; 17 | this.inputHandler = new input_handler_1.default(this); 18 | this.init(); 19 | } 20 | setCamera() { 21 | let at = new vector4_1.Vector4(0, 0, 0, 1); 22 | let up = new vector4_1.Vector4(0, 1, 0, 1); 23 | let aspect = this.renderer.width / this.renderer.height; 24 | let near = 1; 25 | let far = 500; 26 | this.renderer.setCamera(this.eye, at, up, this.fovy, aspect, near, far); 27 | } 28 | init() { 29 | this.setCamera(); 30 | this.renderer.setBackgroundColor(color_1.Color.GRAY); 31 | let texture = this.texture; 32 | let shader = new shader_1.default({ 33 | vertexShading: function (vertex, input) { 34 | vertex.posModel.transform(input.viewProject, vertex.context.posProject); 35 | vertex.context.varyingVec2Dict[shader_1.ShaderVarying.UV] = vertex.uv; 36 | return vertex.context.posProject; 37 | }, 38 | fragmentShading: function (input) { 39 | let tex = texture.sample(input.varyingVec2Dict[shader_1.ShaderVarying.UV]); 40 | return color_1.Color.multiplyColor(tex, input.color, tex); 41 | } 42 | }); 43 | this.renderer.setShader(shader); 44 | } 45 | draw() { 46 | let va = [ 47 | new vector4_1.Vector4(-1, -1, 1), 48 | new vector4_1.Vector4(1, -1, 1), 49 | new vector4_1.Vector4(1, 1, 1), 50 | new vector4_1.Vector4(-1, 1, 1), 51 | new vector4_1.Vector4(-1, -1, -1), 52 | new vector4_1.Vector4(1, -1, -1), 53 | new vector4_1.Vector4(1, 1, -1), 54 | new vector4_1.Vector4(-1, 1, -1), 55 | ]; 56 | let elements = [ 57 | 0, 1, 2, 58 | 2, 3, 0, 59 | 7, 6, 5, 60 | 5, 4, 7, 61 | 0, 4, 5, 62 | 5, 1, 0, 63 | 1, 5, 6, 64 | 6, 2, 1, 65 | 2, 6, 7, 66 | 7, 3, 2, 67 | 3, 7, 4, 68 | 4, 0, 3, 69 | ]; 70 | let uv00 = new vector2_1.Vector2(0, 0); 71 | let uv10 = new vector2_1.Vector2(1, 0); 72 | let uv11 = new vector2_1.Vector2(1, 1); 73 | let uv01 = new vector2_1.Vector2(0, 1); 74 | for (let e = 0; e < elements.length; e += 6) { 75 | this.renderer.drawTriangle([ 76 | { posModel: va[elements[e]], color: color_1.Color.WHITE, uv: uv00 }, 77 | { posModel: va[elements[e + 1]], color: color_1.Color.WHITE, uv: uv10 }, 78 | { posModel: va[elements[e + 2]], color: color_1.Color.WHITE, uv: uv11 }, 79 | ]); 80 | this.renderer.drawTriangle([ 81 | { posModel: va[elements[e + 3]], color: color_1.Color.WHITE, uv: uv11 }, 82 | { posModel: va[elements[e + 4]], color: color_1.Color.WHITE, uv: uv01 }, 83 | { posModel: va[elements[e + 5]], color: color_1.Color.WHITE, uv: uv00 }, 84 | ]); 85 | } 86 | } 87 | createTexture() { 88 | return texture_1.default.createTextureFromFile("floor_diffuse.png"); 89 | } 90 | onWheel(delta) { 91 | this.fovy = math_utils_1.default.clamp(this.fovy + (delta > 0 ? 0.05 : -0.05), Math.PI / 6, Math.PI * 2 / 3); 92 | this.setCamera(); 93 | } 94 | onMove(dx, dy) { 95 | let angleX = -dx / 30 * Math.PI / 180 * 10; 96 | let angleY = -dy / 30 * Math.PI / 180 * 10; 97 | let mat1 = new matrix_1.Matrix(); 98 | mat1.setRotateY(angleX); 99 | let mat2 = new matrix_1.Matrix(); 100 | mat2.setRotateX(angleY); 101 | this.eye.transform(mat1.multiply(mat2), this.eye); 102 | this.setCamera(); 103 | } 104 | } 105 | exports.default = DrawBox; 106 | -------------------------------------------------------------------------------- /build-js/examples/draw-box.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"draw-box.js","sourceRoot":"","sources":["../../src/examples/draw-box.ts"],"names":[],"mappings":";;AAAA,kDAA8C;AAC9C,iDAA4C;AAC5C,mDAA0F;AAC1F,qDAA6C;AAI7C,kDAA8C;AAE9C,wDAA+C;AAC/C,wDAA+C;AAC/C,gDAA4C;AAE5C,MAAqB,OAAO;IAQxB,YAAmB,QAAe;QAJxB,SAAI,GAAU,IAAI,CAAC,EAAE,GAAG,CAAC,CAAA;QACzB,QAAG,GAAW,IAAI,iBAAO,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAA;QAI/C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,aAAa,EAAE,CAAA;QACnC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,YAAY,GAAG,IAAI,uBAAY,CAAC,IAAI,CAAC,CAAA;QAC1C,IAAI,CAAC,IAAI,EAAE,CAAA;IACf,CAAC;IAES,SAAS;QACf,IAAI,EAAE,GAAG,IAAI,iBAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;QAChC,IAAI,EAAE,GAAG,IAAI,iBAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;QAChC,IAAI,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAA;QACvD,IAAI,IAAI,GAAG,CAAC,CAAA;QACZ,IAAI,GAAG,GAAG,GAAG,CAAA;QACb,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,CAAA;IAC3E,CAAC;IAES,IAAI;QACV,IAAI,CAAC,SAAS,EAAE,CAAA;QAEhB,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,aAAK,CAAC,IAAI,CAAC,CAAA;QAC5C,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;QAC1B,IAAI,MAAM,GAAU,IAAI,gBAAM,CAC1B;YACI,aAAa,EAAE,UAAS,MAAa,EAAE,KAAiB;gBACpD,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;gBACvE,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,sBAAa,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,EAAE,CAAA;gBAC5D,OAAO,MAAM,CAAC,OAAO,CAAC,UAAU,CAAA;YACpC,CAAC;YACD,eAAe,EAAE,UAAS,KAAmB;gBACzC,IAAI,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,sBAAa,CAAC,EAAE,CAAC,CAAC,CAAA;gBACjE,OAAO,aAAK,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;YACrD,CAAC;SACJ,CACJ,CAAA;QACD,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;IACnC,CAAC;IAEM,IAAI;QACP,IAAI,EAAE,GAAkB;YACpB,IAAI,iBAAO,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC;YACpB,IAAI,iBAAO,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC;YACnB,IAAI,iBAAO,CAAC,CAAC,EAAC,CAAC,EAAC,CAAC,CAAC;YAClB,IAAI,iBAAO,CAAC,CAAC,CAAC,EAAC,CAAC,EAAC,CAAC,CAAC;YACnB,IAAI,iBAAO,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC;YACrB,IAAI,iBAAO,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC;YACpB,IAAI,iBAAO,CAAC,CAAC,EAAC,CAAC,EAAC,CAAC,CAAC,CAAC;YACnB,IAAI,iBAAO,CAAC,CAAC,CAAC,EAAC,CAAC,EAAC,CAAC,CAAC,CAAC;SACvB,CAAA;QAED,IAAI,QAAQ,GAAG;YACX,CAAC,EAAE,CAAC,EAAE,CAAC;YACP,CAAC,EAAE,CAAC,EAAE,CAAC;YACP,CAAC,EAAE,CAAC,EAAE,CAAC;YACP,CAAC,EAAE,CAAC,EAAE,CAAC;YACP,CAAC,EAAE,CAAC,EAAE,CAAC;YACP,CAAC,EAAE,CAAC,EAAE,CAAC;YACP,CAAC,EAAE,CAAC,EAAE,CAAC;YACP,CAAC,EAAE,CAAC,EAAE,CAAC;YACP,CAAC,EAAE,CAAC,EAAE,CAAC;YACP,CAAC,EAAE,CAAC,EAAE,CAAC;YACP,CAAC,EAAE,CAAC,EAAE,CAAC;YACP,CAAC,EAAE,CAAC,EAAE,CAAC;SACV,CAAA;QAED,IAAI,IAAI,GAAG,IAAI,iBAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QAC5B,IAAI,IAAI,GAAG,IAAI,iBAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QAC5B,IAAI,IAAI,GAAG,IAAI,iBAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QAC5B,IAAI,IAAI,GAAG,IAAI,iBAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QAC5B,KAAK,IAAI,CAAC,GAAC,CAAC,EAAC,CAAC,GAAC,QAAQ,CAAC,MAAM,EAAC,CAAC,IAAE,CAAC,EAAE;YACjC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;gBACvB,EAAC,QAAQ,EAAC,EAAE,CAAE,QAAQ,CAAC,CAAC,CAAC,CAAE,EAAE,KAAK,EAAC,aAAK,CAAC,KAAK,EAAE,EAAE,EAAC,IAAI,EAAC;gBACxD,EAAC,QAAQ,EAAC,EAAE,CAAE,QAAQ,CAAC,CAAC,GAAC,CAAC,CAAC,CAAE,EAAE,KAAK,EAAC,aAAK,CAAC,KAAK,EAAE,EAAE,EAAC,IAAI,EAAC;gBAC1D,EAAC,QAAQ,EAAC,EAAE,CAAE,QAAQ,CAAC,CAAC,GAAC,CAAC,CAAC,CAAE,EAAE,KAAK,EAAC,aAAK,CAAC,KAAK,EAAE,EAAE,EAAC,IAAI,EAAC;aAC7D,CAAC,CAAA;YACF,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;gBACvB,EAAC,QAAQ,EAAC,EAAE,CAAE,QAAQ,CAAC,CAAC,GAAC,CAAC,CAAC,CAAE,EAAE,KAAK,EAAC,aAAK,CAAC,KAAK,EAAE,EAAE,EAAC,IAAI,EAAC;gBAC1D,EAAC,QAAQ,EAAC,EAAE,CAAE,QAAQ,CAAC,CAAC,GAAC,CAAC,CAAC,CAAE,EAAE,KAAK,EAAC,aAAK,CAAC,KAAK,EAAE,EAAE,EAAC,IAAI,EAAC;gBAC1D,EAAC,QAAQ,EAAC,EAAE,CAAE,QAAQ,CAAC,CAAC,GAAC,CAAC,CAAC,CAAE,EAAE,KAAK,EAAC,aAAK,CAAC,KAAK,EAAE,EAAE,EAAC,IAAI,EAAC;aAC7D,CAAC,CAAA;SACL;IACL,CAAC;IAES,aAAa;QACnB,OAAO,iBAAO,CAAC,qBAAqB,CAAC,mBAAmB,CAAC,CAAA;IAC7D,CAAC;IAEM,OAAO,CAAC,KAAY;QACvB,IAAI,CAAC,IAAI,GAAG,oBAAS,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,KAAK,GAAE,CAAC,CAAC,CAAC,CAAA,IAAI,CAAA,CAAC,CAAA,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,GAAC,CAAC,EAAE,IAAI,CAAC,EAAE,GAAC,CAAC,GAAC,CAAC,CAAC,CAAA;QACvF,IAAI,CAAC,SAAS,EAAE,CAAA;IACpB,CAAC;IAEM,MAAM,CAAC,EAAS,EAAE,EAAS;QAC9B,IAAI,MAAM,GAAG,CAAC,EAAE,GAAC,EAAE,GAAG,IAAI,CAAC,EAAE,GAAC,GAAG,GAAC,EAAE,CAAA;QACpC,IAAI,MAAM,GAAG,CAAC,EAAE,GAAC,EAAE,GAAG,IAAI,CAAC,EAAE,GAAC,GAAG,GAAC,EAAE,CAAA;QAEpC,IAAI,IAAI,GAAG,IAAI,eAAM,EAAE,CAAA;QACvB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;QAEvB,IAAI,IAAI,GAAG,IAAI,eAAM,EAAE,CAAA;QACvB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;QACvB,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAA;QAEjD,IAAI,CAAC,SAAS,EAAE,CAAA;IACpB,CAAC;CACJ;AAhHD,0BAgHC"} -------------------------------------------------------------------------------- /build-js/examples/draw-mesh.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const vector4_1 = require("../core/math/vector4"); 4 | const color_1 = require("../core/shading/color"); 5 | const texture_1 = require("../core/shading/texture"); 6 | const shader_1 = require("../core/shading/shader"); 7 | const matrix_1 = require("../core/math/matrix"); 8 | const math_utils_1 = require("../core/math/math-utils"); 9 | const model_1 = require("../core/shading/model"); 10 | const input_handler_1 = require("../web/input-handler"); 11 | class DrawMesh { 12 | constructor(renderer) { 13 | this.fovy = Math.PI / 4; 14 | this.eye = new vector4_1.Vector4(1, 1, 3, 1); 15 | this.modelMatrix = new matrix_1.Matrix(); 16 | this.renderer = renderer; 17 | this.inputHandler = new input_handler_1.default(this); 18 | this.init(); 19 | } 20 | setCamera() { 21 | let at = new vector4_1.Vector4(0, 0, 0, 1); 22 | let up = new vector4_1.Vector4(0, 1, 0, 1); 23 | let aspect = this.renderer.width / this.renderer.height; 24 | let near = 1; 25 | let far = 500; 26 | this.renderer.setCamera(this.eye, at, up, this.fovy, aspect, near, far); 27 | } 28 | init() { 29 | this.setCamera(); 30 | this.renderer.setBackgroundColor(color_1.Color.GRAY); 31 | this.loadObj(); 32 | this.loadTextures(); 33 | let lightDir = (new vector4_1.Vector4(1, 1, 1)).normalize(); 34 | let diffuseTexture = this.diffuseTexture; 35 | let normalTexture = this.normalTexture; 36 | let specTexture = this.specTexture; 37 | let fragColor = new color_1.Color(); 38 | let eye = this.eye; 39 | let modelMatrix = this.modelMatrix; 40 | let shader = new shader_1.default({ 41 | vertexShading: function (vertex, input) { 42 | let posWorld = vertex.posModel.transform(modelMatrix); 43 | vertex.context.posProject = posWorld.transform(input.viewProject); 44 | vertex.context.varyingVec2Dict[shader_1.ShaderVarying.UV] = vertex.uv; 45 | vertex.context.varyingVec4Dict[shader_1.ShaderVarying.WORLD_POS] = posWorld; 46 | return vertex.context.posProject; 47 | }, 48 | fragmentShading: function (input) { 49 | let uv = input.varyingVec2Dict[shader_1.ShaderVarying.UV]; 50 | let diffuseColor = diffuseTexture.sample(uv); 51 | let normal = normalTexture.sampleAsVector(uv); 52 | let specFactor = specTexture.sample(uv).b; 53 | let n = normal.normalize(); 54 | let worldPos = input.varyingVec4Dict[shader_1.ShaderVarying.WORLD_POS]; 55 | let diffuseIntense = math_utils_1.default.saturate(n.dot(lightDir)); 56 | let viewDir = eye.sub(worldPos).normalize(); 57 | let halfDir = lightDir.add(viewDir).normalize(); 58 | let specIntense = Math.pow(Math.max(0, n.dot(halfDir)), 5 * specFactor); 59 | let factor = diffuseIntense + specIntense; 60 | let ambient = 5; 61 | fragColor.set(diffuseColor).multiplyRGB(factor).add(ambient); 62 | fragColor.a = 255; 63 | return fragColor; 64 | } 65 | }); 66 | this.renderer.setShader(shader); 67 | } 68 | loadTextures() { 69 | this.diffuseTexture = texture_1.default.createTextureFromFile("african_head_diffuse.png"); 70 | this.normalTexture = texture_1.default.createTextureFromFile("african_head_nm.png"); 71 | this.specTexture = texture_1.default.createTextureFromFile("african_head_spec.png"); 72 | } 73 | loadObj() { 74 | this.model = new model_1.default(); 75 | this.model.createFromFile("african_head.obj"); 76 | } 77 | draw() { 78 | let triangles = this.model.triangles; 79 | for (let triangle of triangles) { 80 | this.renderer.drawTriangle(triangle); 81 | } 82 | } 83 | onWheel(delta) { 84 | this.fovy = math_utils_1.default.clamp(this.fovy + (delta > 0 ? 0.05 : -0.05), Math.PI / 6, Math.PI * 2 / 3); 85 | this.setCamera(); 86 | } 87 | onMove(dx, dy) { 88 | let angleX = -dx / 30 * Math.PI / 180 * 10; 89 | let angleY = -dy / 30 * Math.PI / 180 * 10; 90 | let mat1 = new matrix_1.Matrix(); 91 | mat1.setRotateY(angleX); 92 | let mat2 = new matrix_1.Matrix(); 93 | mat2.setRotateX(angleY); 94 | this.eye.transform(mat1.multiply(mat2), this.eye); 95 | this.setCamera(); 96 | } 97 | } 98 | exports.default = DrawMesh; 99 | -------------------------------------------------------------------------------- /build-js/examples/draw-mesh.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"draw-mesh.js","sourceRoot":"","sources":["../../src/examples/draw-mesh.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /build-js/web/input-handler.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | class InputHandler { 4 | constructor(example) { 5 | this.isMouseDown = false; 6 | let self = this; 7 | this.example = example; 8 | window.onmousedown = function (e) { 9 | self.onMouseDown(e.clientX, e.clientY); 10 | }; 11 | window.onmousemove = function (e) { 12 | self.onMouseMove(e.clientX, e.clientY); 13 | }; 14 | window.onmouseup = function (e) { 15 | self.onMouseUp(e.clientX, e.clientY); 16 | }; 17 | window.onmousewheel = function (e) { 18 | self.onMouseWheel(e.deltaY); 19 | }; 20 | } 21 | onMouseDown(x, y) { 22 | this.isMouseDown = true; 23 | this.lastMouseX = x; 24 | this.lastMouseY = y; 25 | } 26 | onMouseMove(x, y) { 27 | if (this.isMouseDown) { 28 | let deltaX = x - this.lastMouseX; 29 | let deltaY = y - this.lastMouseY; 30 | this.example.onMove(deltaX, deltaY); 31 | this.lastMouseY = y; 32 | this.lastMouseX = x; 33 | } 34 | } 35 | onMouseUp(x, y) { 36 | this.isMouseDown = false; 37 | } 38 | onMouseWheel(delta) { 39 | if (this.example.onWheel) { 40 | this.example.onWheel(delta); 41 | } 42 | } 43 | } 44 | exports.default = InputHandler; 45 | -------------------------------------------------------------------------------- /build-js/web/input-handler.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"input-handler.js","sourceRoot":"","sources":["../../src/web/input-handler.ts"],"names":[],"mappings":";;AAEA,MAAqB,YAAY;IAK7B,YAAmB,OAAgB;QAHzB,gBAAW,GAAW,KAAK,CAAA;QAIjC,IAAI,IAAI,GAAG,IAAI,CAAA;QACf,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QAGtB,MAAM,CAAC,WAAW,GAAG,UAAS,CAAY;YACtC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAA;QAC1C,CAAC,CAAA;QAED,MAAM,CAAC,WAAW,GAAG,UAAS,CAAY;YACtC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAA;QAC1C,CAAC,CAAA;QAED,MAAM,CAAC,SAAS,GAAG,UAAS,CAAY;YACpC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAA;QACxC,CAAC,CAAA;QAED,MAAM,CAAC,YAAY,GAAG,UAAS,CAAK;YAChC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;QAC/B,CAAC,CAAA;IACL,CAAC;IAES,WAAW,CAAC,CAAQ,EAAE,CAAQ;QACpC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAA;QACvB,IAAI,CAAC,UAAU,GAAG,CAAC,CAAA;QACnB,IAAI,CAAC,UAAU,GAAG,CAAC,CAAA;IACvB,CAAC;IAES,WAAW,CAAC,CAAQ,EAAE,CAAQ;QACpC,IAAI,IAAI,CAAC,WAAW,EAAE;YAClB,IAAI,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,CAAA;YAChC,IAAI,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,CAAA;YAChC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;YACnC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAA;YACnB,IAAI,CAAC,UAAU,GAAG,CAAC,CAAA;SACtB;IAEL,CAAC;IAES,SAAS,CAAC,CAAQ,EAAE,CAAQ;QAClC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAA;IAC5B,CAAC;IAES,YAAY,CAAC,KAAY;QAC/B,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;YACtB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;SAC9B;IACL,CAAC;CAEJ;AAtDD,+BAsDC"} -------------------------------------------------------------------------------- /build-js/web/webgl-blitter.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.WebGLBlitter = void 0; 4 | class WebGLBlitter { 5 | constructor(gl) { 6 | this.gl = gl; 7 | this.initShader(); 8 | this.initTexture(); 9 | this.initGeometry(); 10 | } 11 | initTexture() { 12 | let gl = this.gl; 13 | this.canvasTexture = gl.createTexture(); 14 | gl.bindTexture(gl.TEXTURE_2D, this.canvasTexture); 15 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 16 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 17 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 18 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 19 | gl.bindTexture(gl.TEXTURE_2D, null); 20 | } 21 | initShader() { 22 | let gl = this.gl; 23 | let vertexShaderSource = "attribute vec4 a_Position;" + 24 | "attribute vec2 a_TexCoord;" + 25 | "varying vec2 v_TexCoord;" + 26 | "void main(){" + 27 | "gl_Position = a_Position;" + 28 | "v_TexCoord = a_TexCoord;" + 29 | "}"; 30 | let fragmentShaderSource = "precision mediump float;" + 31 | " uniform sampler2D u_Sampler;" + 32 | " varying vec2 v_TexCoord;" + 33 | " void main(){" + 34 | " gl_FragColor = texture2D(u_Sampler, v_TexCoord);" + 35 | "}"; 36 | var vertShader = gl.createShader(gl.VERTEX_SHADER); 37 | gl.shaderSource(vertShader, vertexShaderSource); 38 | gl.compileShader(vertShader); 39 | var fragShader = gl.createShader(gl.FRAGMENT_SHADER); 40 | gl.shaderSource(fragShader, fragmentShaderSource); 41 | gl.compileShader(fragShader); 42 | this.shaderProgram = gl.createProgram(); 43 | gl.attachShader(this.shaderProgram, vertShader); 44 | gl.attachShader(this.shaderProgram, fragShader); 45 | gl.linkProgram(this.shaderProgram); 46 | this.u_Sampler = gl.getUniformLocation(this.shaderProgram, "u_Sampler"); 47 | } 48 | initGeometry() { 49 | let gl = this.gl; 50 | var vertexs = new Float32Array([ 51 | -1, 1, 0.0, 0.0, 1.0, 52 | -1, -1, 0.0, 0.0, 0.0, 53 | 1, 1, 0.0, 1.0, 1.0, 54 | 1, -1, 0.0, 1.0, 0.0 55 | ]); 56 | this.vertexsBuffer = gl.createBuffer(); 57 | if (this.vertexsBuffer === null) { 58 | console.log("vertexsBuffer is null"); 59 | return false; 60 | } 61 | gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexsBuffer); 62 | gl.bufferData(gl.ARRAY_BUFFER, vertexs, gl.STATIC_DRAW); 63 | let a_Position = gl.getAttribLocation(this.shaderProgram, "a_Position"); 64 | if (a_Position < 0) { 65 | console.log("a_Position < 0"); 66 | return false; 67 | } 68 | let a_TexCoord = gl.getAttribLocation(this.shaderProgram, "a_TexCoord"); 69 | if (a_TexCoord < 0) { 70 | console.log("a_TexCoord < 0"); 71 | return false; 72 | } 73 | gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, vertexs.BYTES_PER_ELEMENT * 5, 0); 74 | gl.enableVertexAttribArray(a_Position); 75 | gl.vertexAttribPointer(a_TexCoord, 2, gl.FLOAT, false, vertexs.BYTES_PER_ELEMENT * 5, vertexs.BYTES_PER_ELEMENT * 3); 76 | gl.enableVertexAttribArray(a_TexCoord); 77 | } 78 | renderCanvas() { 79 | let gl = this.gl; 80 | gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT); 81 | gl.useProgram(this.shaderProgram); 82 | gl.uniform1i(this.u_Sampler, 0); 83 | gl.activeTexture(this.gl.TEXTURE0); 84 | gl.bindTexture(this.gl.TEXTURE_2D, this.canvasTexture); 85 | gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4); 86 | } 87 | blitPixels(width, height, pixels) { 88 | this.gl.bindTexture(this.gl.TEXTURE_2D, this.canvasTexture); 89 | this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, width, height, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, pixels); 90 | this.gl.bindTexture(this.gl.TEXTURE_2D, null); 91 | this.renderCanvas(); 92 | } 93 | } 94 | exports.WebGLBlitter = WebGLBlitter; 95 | -------------------------------------------------------------------------------- /build-js/web/webgl-blitter.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"webgl-blitter.js","sourceRoot":"","sources":["../../src/web/webgl-blitter.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | interface Window { 2 | app: any; 3 | } 4 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | const electron = require('electron') 2 | // Module to control application life. 3 | const app = electron.app 4 | // Module to create native browser window. 5 | const BrowserWindow = electron.BrowserWindow 6 | 7 | const path = require('path') 8 | const url = require('url') 9 | 10 | const {Menu,MenuItem} = require("electron") 11 | 12 | // Keep a global reference of the window object, if you don't, the window will 13 | // be closed automatically when the JavaScript object is garbage collected. 14 | let mainWindow 15 | 16 | function createWindow() { 17 | app.commandLine.appendSwitch('ignore-gpu-blacklist'); 18 | 19 | // Create the browser window. 20 | mainWindow = new BrowserWindow({ 21 | width: 1500, 22 | height: 900, 23 | webPreferences: { 24 | nodeIntegration: true, 25 | webgl: true, 26 | webSecurity: false, 27 | } 28 | }) 29 | 30 | 31 | // and load the index.html of the app. 32 | mainWindow.loadURL(url.format({ 33 | pathname: path.join(__dirname, 'run/index.html'), 34 | protocol: 'file:', 35 | slashes: true 36 | })) 37 | 38 | mainWindow.webContents.on('did-finish-load', async function () { 39 | 40 | 41 | }) 42 | 43 | mainWindow.webContents.on("before-input-event", (event, input) => { 44 | //console.log(input); 45 | }); 46 | // Open the DevTools. 47 | //mainWindow.webContents.openDevTools() 48 | // Emitted when the window is closed. 49 | mainWindow.on('closed', function() { 50 | // Dereference the window object, usually you would store windows 51 | // in an array if your app supports multi windows, this is the time 52 | // when you should delete the corresponding element. 53 | mainWindow = null 54 | }) 55 | 56 | } 57 | 58 | function onresize() { 59 | let size = mainWindow.getSize() 60 | } 61 | 62 | // This method will be called when Electron has finished 63 | // initialization and is ready to create browser windows. 64 | // Some APIs can only be used after this event occurs. 65 | app.on('ready', createWindow) 66 | 67 | // Quit when all windows are closed. 68 | app.on('window-all-closed', function() { 69 | // On OS X it is common for applications and their menu bar 70 | // to stay active until the user quits explicitly with Cmd + Q 71 | if (process.platform !== 'darwin') { 72 | app.quit() 73 | } 74 | }) 75 | // console.log("run", new Date().getTime() ) 76 | 77 | app.on('activate', function() { 78 | // On OS X it's common to re-create a window in the app when the 79 | // dock icon is clicked and there are no other windows open. 80 | 81 | if (mainWindow === null) { 82 | createWindow() 83 | } 84 | }) 85 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "raster-toy", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@electron/get": { 8 | "version": "1.12.2", 9 | "resolved": "https://registry.npm.taobao.org/@electron/get/download/@electron/get-1.12.2.tgz", 10 | "integrity": "sha1-ZEIGavuZvgjO+5ooHktGkrM3ZPM=", 11 | "requires": { 12 | "debug": "^4.1.1", 13 | "env-paths": "^2.2.0", 14 | "fs-extra": "^8.1.0", 15 | "global-agent": "^2.0.2", 16 | "global-tunnel-ng": "^2.7.1", 17 | "got": "^9.6.0", 18 | "progress": "^2.0.3", 19 | "sanitize-filename": "^1.6.2", 20 | "sumchecker": "^3.0.1" 21 | }, 22 | "dependencies": { 23 | "debug": { 24 | "version": "4.3.1", 25 | "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.3.1.tgz?cache=0&sync_timestamp=1607566580543&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.3.1.tgz", 26 | "integrity": "sha1-8NIpxQXgxtjEmsVT0bE9wYP2su4=", 27 | "requires": { 28 | "ms": "2.1.2" 29 | } 30 | }, 31 | "ms": { 32 | "version": "2.1.2", 33 | "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz?cache=0&sync_timestamp=1607433905701&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.1.2.tgz", 34 | "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=" 35 | } 36 | } 37 | }, 38 | "@sindresorhus/is": { 39 | "version": "0.14.0", 40 | "resolved": "https://registry.npm.taobao.org/@sindresorhus/is/download/@sindresorhus/is-0.14.0.tgz?cache=0&sync_timestamp=1602540622325&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40sindresorhus%2Fis%2Fdownload%2F%40sindresorhus%2Fis-0.14.0.tgz", 41 | "integrity": "sha1-n7OjzzEyMoFR81PeRjLgHlIQK+o=" 42 | }, 43 | "@szmarczak/http-timer": { 44 | "version": "1.1.2", 45 | "resolved": "https://registry.npm.taobao.org/@szmarczak/http-timer/download/@szmarczak/http-timer-1.1.2.tgz", 46 | "integrity": "sha1-sWZeLEYaLNkvTBu/UNVFTeDUtCE=", 47 | "requires": { 48 | "defer-to-connect": "^1.0.1" 49 | } 50 | }, 51 | "@types/node": { 52 | "version": "12.19.9", 53 | "resolved": "https://registry.npm.taobao.org/@types/node/download/@types/node-12.19.9.tgz?cache=0&sync_timestamp=1608047832709&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-12.19.9.tgz", 54 | "integrity": "sha1-mQrWh62LJu9tzDSk9pwz1AyVtnk=" 55 | }, 56 | "atob-lite": { 57 | "version": "2.0.0", 58 | "resolved": "https://registry.npm.taobao.org/atob-lite/download/atob-lite-2.0.0.tgz", 59 | "integrity": "sha1-D+9a1G8b16hQLGVyfwNn1e5D1pY=" 60 | }, 61 | "bmp-js": { 62 | "version": "0.1.0", 63 | "resolved": "https://registry.npm.taobao.org/bmp-js/download/bmp-js-0.1.0.tgz", 64 | "integrity": "sha1-4Fpj95amwf8l9Hcex62twUjAcjM=" 65 | }, 66 | "boolean": { 67 | "version": "3.0.2", 68 | "resolved": "https://registry.npm.taobao.org/boolean/download/boolean-3.0.2.tgz", 69 | "integrity": "sha1-3xuqGLaisOcIQEdeHZPsj+dbJXA=" 70 | }, 71 | "buffer-crc32": { 72 | "version": "0.2.13", 73 | "resolved": "https://registry.npm.taobao.org/buffer-crc32/download/buffer-crc32-0.2.13.tgz", 74 | "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" 75 | }, 76 | "buffer-from": { 77 | "version": "1.1.1", 78 | "resolved": "https://registry.npm.taobao.org/buffer-from/download/buffer-from-1.1.1.tgz", 79 | "integrity": "sha1-MnE7wCj3XAL9txDXx7zsHyxgcO8=" 80 | }, 81 | "buffer-to-uint8array": { 82 | "version": "1.1.0", 83 | "resolved": "https://registry.npm.taobao.org/buffer-to-uint8array/download/buffer-to-uint8array-1.1.0.tgz", 84 | "integrity": "sha1-z29BKHwCL0WNp1LDkcGo1TXsX3I=" 85 | }, 86 | "cacheable-request": { 87 | "version": "6.1.0", 88 | "resolved": "https://registry.npm.taobao.org/cacheable-request/download/cacheable-request-6.1.0.tgz", 89 | "integrity": "sha1-IP+4vRYrpL4R6VZ9gj22UQUsqRI=", 90 | "requires": { 91 | "clone-response": "^1.0.2", 92 | "get-stream": "^5.1.0", 93 | "http-cache-semantics": "^4.0.0", 94 | "keyv": "^3.0.0", 95 | "lowercase-keys": "^2.0.0", 96 | "normalize-url": "^4.1.0", 97 | "responselike": "^1.0.2" 98 | }, 99 | "dependencies": { 100 | "get-stream": { 101 | "version": "5.2.0", 102 | "resolved": "https://registry.npm.taobao.org/get-stream/download/get-stream-5.2.0.tgz?cache=0&sync_timestamp=1597056455691&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fget-stream%2Fdownload%2Fget-stream-5.2.0.tgz", 103 | "integrity": "sha1-SWaheV7lrOZecGxLe+txJX1uItM=", 104 | "requires": { 105 | "pump": "^3.0.0" 106 | } 107 | }, 108 | "lowercase-keys": { 109 | "version": "2.0.0", 110 | "resolved": "https://registry.npm.taobao.org/lowercase-keys/download/lowercase-keys-2.0.0.tgz", 111 | "integrity": "sha1-JgPni3tLAAbLyi+8yKMgJVislHk=" 112 | } 113 | } 114 | }, 115 | "clone-response": { 116 | "version": "1.0.2", 117 | "resolved": "https://registry.npm.taobao.org/clone-response/download/clone-response-1.0.2.tgz", 118 | "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", 119 | "requires": { 120 | "mimic-response": "^1.0.0" 121 | } 122 | }, 123 | "concat-stream": { 124 | "version": "1.6.2", 125 | "resolved": "https://registry.npm.taobao.org/concat-stream/download/concat-stream-1.6.2.tgz", 126 | "integrity": "sha1-kEvfGUzTEi/Gdcd/xKw9T/D9GjQ=", 127 | "requires": { 128 | "buffer-from": "^1.0.0", 129 | "inherits": "^2.0.3", 130 | "readable-stream": "^2.2.2", 131 | "typedarray": "^0.0.6" 132 | } 133 | }, 134 | "config-chain": { 135 | "version": "1.1.12", 136 | "resolved": "https://registry.npm.taobao.org/config-chain/download/config-chain-1.1.12.tgz", 137 | "integrity": "sha1-D96NCRIA616AjK8l/mGMAvSOTvo=", 138 | "optional": true, 139 | "requires": { 140 | "ini": "^1.3.4", 141 | "proto-list": "~1.2.1" 142 | } 143 | }, 144 | "core-js": { 145 | "version": "3.8.1", 146 | "resolved": "https://registry.npm.taobao.org/core-js/download/core-js-3.8.1.tgz?cache=0&sync_timestamp=1607215907966&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcore-js%2Fdownload%2Fcore-js-3.8.1.tgz", 147 | "integrity": "sha1-9RUjZorIopTRKFw7nbRAJf2mbUc=", 148 | "optional": true 149 | }, 150 | "core-util-is": { 151 | "version": "1.0.2", 152 | "resolved": "https://registry.npm.taobao.org/core-util-is/download/core-util-is-1.0.2.tgz", 153 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 154 | }, 155 | "debug": { 156 | "version": "2.6.9", 157 | "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1600502826356&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz", 158 | "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", 159 | "requires": { 160 | "ms": "2.0.0" 161 | } 162 | }, 163 | "decompress-response": { 164 | "version": "3.3.0", 165 | "resolved": "https://registry.npm.taobao.org/decompress-response/download/decompress-response-3.3.0.tgz", 166 | "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", 167 | "requires": { 168 | "mimic-response": "^1.0.0" 169 | } 170 | }, 171 | "defer-to-connect": { 172 | "version": "1.1.3", 173 | "resolved": "https://registry.npm.taobao.org/defer-to-connect/download/defer-to-connect-1.1.3.tgz", 174 | "integrity": "sha1-MxrgUMCNz3ifjIOnuB8O2U9KxZE=" 175 | }, 176 | "define-properties": { 177 | "version": "1.1.3", 178 | "resolved": "https://registry.npm.taobao.org/define-properties/download/define-properties-1.1.3.tgz", 179 | "integrity": "sha1-z4jabL7ib+bbcJT2HYcMvYTO6fE=", 180 | "optional": true, 181 | "requires": { 182 | "object-keys": "^1.0.12" 183 | } 184 | }, 185 | "detect-node": { 186 | "version": "2.0.4", 187 | "resolved": "https://registry.npm.taobao.org/detect-node/download/detect-node-2.0.4.tgz", 188 | "integrity": "sha1-AU7o+PZpxcWAI9pkuBecCDooxGw=", 189 | "optional": true 190 | }, 191 | "dtype": { 192 | "version": "2.0.0", 193 | "resolved": "https://registry.npm.taobao.org/dtype/download/dtype-2.0.0.tgz", 194 | "integrity": "sha1-zQUjI84GFETs0uj1dI9popvihDQ=" 195 | }, 196 | "duplexer3": { 197 | "version": "0.1.4", 198 | "resolved": "https://registry.npm.taobao.org/duplexer3/download/duplexer3-0.1.4.tgz", 199 | "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" 200 | }, 201 | "electron": { 202 | "version": "11.1.0", 203 | "resolved": "https://registry.npm.taobao.org/electron/download/electron-11.1.0.tgz", 204 | "integrity": "sha1-jf31edHref7vPj0pN/wCLnISnJA=", 205 | "requires": { 206 | "@electron/get": "^1.0.1", 207 | "@types/node": "^12.0.12", 208 | "extract-zip": "^1.0.3" 209 | } 210 | }, 211 | "encodeurl": { 212 | "version": "1.0.2", 213 | "resolved": "https://registry.npm.taobao.org/encodeurl/download/encodeurl-1.0.2.tgz", 214 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", 215 | "optional": true 216 | }, 217 | "end-of-stream": { 218 | "version": "1.4.4", 219 | "resolved": "https://registry.npm.taobao.org/end-of-stream/download/end-of-stream-1.4.4.tgz", 220 | "integrity": "sha1-WuZKX0UFe682JuwU2gyl5LJDHrA=", 221 | "requires": { 222 | "once": "^1.4.0" 223 | } 224 | }, 225 | "env-paths": { 226 | "version": "2.2.0", 227 | "resolved": "https://registry.npm.taobao.org/env-paths/download/env-paths-2.2.0.tgz", 228 | "integrity": "sha1-zcpVfcAJFSkX1hZuL+vh8DloXkM=" 229 | }, 230 | "es6-error": { 231 | "version": "4.1.1", 232 | "resolved": "https://registry.npm.taobao.org/es6-error/download/es6-error-4.1.1.tgz", 233 | "integrity": "sha1-njr0B0Wd7tR+mpH5uIWoTrBcVh0=", 234 | "optional": true 235 | }, 236 | "extract-zip": { 237 | "version": "1.7.0", 238 | "resolved": "https://registry.npm.taobao.org/extract-zip/download/extract-zip-1.7.0.tgz", 239 | "integrity": "sha1-VWzDrp339FLEk6DPtRzDAneUCSc=", 240 | "requires": { 241 | "concat-stream": "^1.6.2", 242 | "debug": "^2.6.9", 243 | "mkdirp": "^0.5.4", 244 | "yauzl": "^2.10.0" 245 | } 246 | }, 247 | "fd-slicer": { 248 | "version": "1.1.0", 249 | "resolved": "https://registry.npm.taobao.org/fd-slicer/download/fd-slicer-1.1.0.tgz", 250 | "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", 251 | "requires": { 252 | "pend": "~1.2.0" 253 | } 254 | }, 255 | "file-type": { 256 | "version": "10.11.0", 257 | "resolved": "https://registry.npm.taobao.org/file-type/download/file-type-10.11.0.tgz?cache=0&sync_timestamp=1604315099809&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffile-type%2Fdownload%2Ffile-type-10.11.0.tgz", 258 | "integrity": "sha1-KWHQnkZ1ufuaPua2npzSP0P9GJA=" 259 | }, 260 | "flatten-vertex-data": { 261 | "version": "1.0.2", 262 | "resolved": "https://registry.npm.taobao.org/flatten-vertex-data/download/flatten-vertex-data-1.0.2.tgz", 263 | "integrity": "sha1-iJ/WC+pQYAbKM5Ve4RBRdftiAhk=", 264 | "requires": { 265 | "dtype": "^2.0.0" 266 | } 267 | }, 268 | "fs-extra": { 269 | "version": "8.1.0", 270 | "resolved": "https://registry.npm.taobao.org/fs-extra/download/fs-extra-8.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffs-extra%2Fdownload%2Ffs-extra-8.1.0.tgz", 271 | "integrity": "sha1-SdQ8RaiM2Wd2aMt74bRu/bjS4cA=", 272 | "requires": { 273 | "graceful-fs": "^4.2.0", 274 | "jsonfile": "^4.0.0", 275 | "universalify": "^0.1.0" 276 | } 277 | }, 278 | "get-stream": { 279 | "version": "4.1.0", 280 | "resolved": "https://registry.npm.taobao.org/get-stream/download/get-stream-4.1.0.tgz?cache=0&sync_timestamp=1597056455691&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fget-stream%2Fdownload%2Fget-stream-4.1.0.tgz", 281 | "integrity": "sha1-wbJVV189wh1Zv8ec09K0axw6VLU=", 282 | "requires": { 283 | "pump": "^3.0.0" 284 | } 285 | }, 286 | "global-agent": { 287 | "version": "2.1.12", 288 | "resolved": "https://registry.npm.taobao.org/global-agent/download/global-agent-2.1.12.tgz", 289 | "integrity": "sha1-5K44Ercxqegcv4Jfk3fvRQqOQZU=", 290 | "optional": true, 291 | "requires": { 292 | "boolean": "^3.0.1", 293 | "core-js": "^3.6.5", 294 | "es6-error": "^4.1.1", 295 | "matcher": "^3.0.0", 296 | "roarr": "^2.15.3", 297 | "semver": "^7.3.2", 298 | "serialize-error": "^7.0.1" 299 | }, 300 | "dependencies": { 301 | "lru-cache": { 302 | "version": "6.0.0", 303 | "resolved": "https://registry.npm.taobao.org/lru-cache/download/lru-cache-6.0.0.tgz?cache=0&sync_timestamp=1594427573763&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flru-cache%2Fdownload%2Flru-cache-6.0.0.tgz", 304 | "integrity": "sha1-bW/mVw69lqr5D8rR2vo7JWbbOpQ=", 305 | "optional": true, 306 | "requires": { 307 | "yallist": "^4.0.0" 308 | } 309 | }, 310 | "semver": { 311 | "version": "7.3.4", 312 | "resolved": "https://registry.npm.taobao.org/semver/download/semver-7.3.4.tgz?cache=0&sync_timestamp=1606853731020&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-7.3.4.tgz", 313 | "integrity": "sha1-J6qn0uTKdkUvmNOt0JOnLJQ+3Jc=", 314 | "optional": true, 315 | "requires": { 316 | "lru-cache": "^6.0.0" 317 | } 318 | }, 319 | "yallist": { 320 | "version": "4.0.0", 321 | "resolved": "https://registry.npm.taobao.org/yallist/download/yallist-4.0.0.tgz", 322 | "integrity": "sha1-m7knkNnA7/7GO+c1GeEaNQGaOnI=", 323 | "optional": true 324 | } 325 | } 326 | }, 327 | "global-tunnel-ng": { 328 | "version": "2.7.1", 329 | "resolved": "https://registry.npm.taobao.org/global-tunnel-ng/download/global-tunnel-ng-2.7.1.tgz", 330 | "integrity": "sha1-0DtRAt/eOmmRT17n2GdhyjXVfY8=", 331 | "optional": true, 332 | "requires": { 333 | "encodeurl": "^1.0.2", 334 | "lodash": "^4.17.10", 335 | "npm-conf": "^1.1.3", 336 | "tunnel": "^0.0.6" 337 | } 338 | }, 339 | "globalthis": { 340 | "version": "1.0.1", 341 | "resolved": "https://registry.npm.taobao.org/globalthis/download/globalthis-1.0.1.tgz?cache=0&sync_timestamp=1577757335498&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fglobalthis%2Fdownload%2Fglobalthis-1.0.1.tgz", 342 | "integrity": "sha1-QBFvXZwHH56PsAN2VN8as6g7fvk=", 343 | "optional": true, 344 | "requires": { 345 | "define-properties": "^1.1.3" 346 | } 347 | }, 348 | "got": { 349 | "version": "9.6.0", 350 | "resolved": "https://registry.npm.taobao.org/got/download/got-9.6.0.tgz?cache=0&sync_timestamp=1607658569382&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fgot%2Fdownload%2Fgot-9.6.0.tgz", 351 | "integrity": "sha1-7fRefWf5lUVwXeH3u+7rEhdl7YU=", 352 | "requires": { 353 | "@sindresorhus/is": "^0.14.0", 354 | "@szmarczak/http-timer": "^1.1.2", 355 | "cacheable-request": "^6.0.0", 356 | "decompress-response": "^3.3.0", 357 | "duplexer3": "^0.1.4", 358 | "get-stream": "^4.1.0", 359 | "lowercase-keys": "^1.0.1", 360 | "mimic-response": "^1.0.1", 361 | "p-cancelable": "^1.0.0", 362 | "to-readable-stream": "^1.0.0", 363 | "url-parse-lax": "^3.0.0" 364 | } 365 | }, 366 | "graceful-fs": { 367 | "version": "4.2.4", 368 | "resolved": "https://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.2.4.tgz", 369 | "integrity": "sha1-Ila94U02MpWMRl68ltxGfKB6Kfs=" 370 | }, 371 | "http-cache-semantics": { 372 | "version": "4.1.0", 373 | "resolved": "https://registry.npm.taobao.org/http-cache-semantics/download/http-cache-semantics-4.1.0.tgz", 374 | "integrity": "sha1-SekcXL82yblLz81xwj1SSex045A=" 375 | }, 376 | "image-decode": { 377 | "version": "1.2.2", 378 | "resolved": "https://registry.npm.taobao.org/image-decode/download/image-decode-1.2.2.tgz", 379 | "integrity": "sha1-TKdPxTTnEzxQlu1xLYxbzrW6H8Y=", 380 | "requires": { 381 | "bmp-js": "^0.1.0", 382 | "buffer-to-uint8array": "^1.1.0", 383 | "image-type": "^3.0.0", 384 | "jpeg-js": "^0.3.4", 385 | "omggif": "^1.0.9", 386 | "pngjs": "^3.3.3", 387 | "to-array-buffer": "^3.0.0", 388 | "utif": "^2.0.1" 389 | } 390 | }, 391 | "image-type": { 392 | "version": "3.1.0", 393 | "resolved": "https://registry.npm.taobao.org/image-type/download/image-type-3.1.0.tgz", 394 | "integrity": "sha1-kUiUTEDBbWVxdK8r0a8512fCwp8=", 395 | "requires": { 396 | "file-type": "^10.9.0" 397 | } 398 | }, 399 | "inherits": { 400 | "version": "2.0.4", 401 | "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.4.tgz", 402 | "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=" 403 | }, 404 | "ini": { 405 | "version": "1.3.5", 406 | "resolved": "https://registry.npm.taobao.org/ini/download/ini-1.3.5.tgz", 407 | "integrity": "sha1-7uJfVtscnsYIXgwid4CD9Zar+Sc=", 408 | "optional": true 409 | }, 410 | "is-base64": { 411 | "version": "0.1.0", 412 | "resolved": "https://registry.npm.taobao.org/is-base64/download/is-base64-0.1.0.tgz", 413 | "integrity": "sha1-pvIGEMbvSGOlHLoyvAIiVEuTJiI=" 414 | }, 415 | "is-blob": { 416 | "version": "2.1.0", 417 | "resolved": "https://registry.npm.taobao.org/is-blob/download/is-blob-2.1.0.tgz", 418 | "integrity": "sha1-42zYLJBlPx4bkw8RuvnGQhagU4U=" 419 | }, 420 | "isarray": { 421 | "version": "1.0.0", 422 | "resolved": "https://registry.npm.taobao.org/isarray/download/isarray-1.0.0.tgz", 423 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 424 | }, 425 | "jpeg-js": { 426 | "version": "0.3.7", 427 | "resolved": "https://registry.npm.taobao.org/jpeg-js/download/jpeg-js-0.3.7.tgz", 428 | "integrity": "sha1-RxqJ0GARZAWS0xQVhghpAXKxAo0=" 429 | }, 430 | "json-buffer": { 431 | "version": "3.0.0", 432 | "resolved": "https://registry.npm.taobao.org/json-buffer/download/json-buffer-3.0.0.tgz", 433 | "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" 434 | }, 435 | "json-stringify-safe": { 436 | "version": "5.0.1", 437 | "resolved": "https://registry.npm.taobao.org/json-stringify-safe/download/json-stringify-safe-5.0.1.tgz", 438 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", 439 | "optional": true 440 | }, 441 | "jsonfile": { 442 | "version": "4.0.0", 443 | "resolved": "https://registry.npm.taobao.org/jsonfile/download/jsonfile-4.0.0.tgz?cache=0&sync_timestamp=1604161917513&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjsonfile%2Fdownload%2Fjsonfile-4.0.0.tgz", 444 | "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", 445 | "requires": { 446 | "graceful-fs": "^4.1.6" 447 | } 448 | }, 449 | "keyv": { 450 | "version": "3.1.0", 451 | "resolved": "https://registry.npm.taobao.org/keyv/download/keyv-3.1.0.tgz?cache=0&sync_timestamp=1600337519334&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fkeyv%2Fdownload%2Fkeyv-3.1.0.tgz", 452 | "integrity": "sha1-7MIoSG9pmR5J6UdkhaW+Ho/FxNk=", 453 | "requires": { 454 | "json-buffer": "3.0.0" 455 | } 456 | }, 457 | "lodash": { 458 | "version": "4.17.20", 459 | "resolved": "https://registry.npm.taobao.org/lodash/download/lodash-4.17.20.tgz?cache=0&sync_timestamp=1597336053864&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.20.tgz", 460 | "integrity": "sha1-tEqbYpe8tpjxxRo1RaKzs2jVnFI=", 461 | "optional": true 462 | }, 463 | "lowercase-keys": { 464 | "version": "1.0.1", 465 | "resolved": "https://registry.npm.taobao.org/lowercase-keys/download/lowercase-keys-1.0.1.tgz", 466 | "integrity": "sha1-b54wtHCE2XGnyCD/FabFFnt0wm8=" 467 | }, 468 | "matcher": { 469 | "version": "3.0.0", 470 | "resolved": "https://registry.npm.taobao.org/matcher/download/matcher-3.0.0.tgz", 471 | "integrity": "sha1-vZBg9MW3CqgEHMxvgDaHYJlPMMo=", 472 | "optional": true, 473 | "requires": { 474 | "escape-string-regexp": "^4.0.0" 475 | }, 476 | "dependencies": { 477 | "escape-string-regexp": { 478 | "version": "4.0.0", 479 | "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-4.0.0.tgz?cache=0&sync_timestamp=1587627212242&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fescape-string-regexp%2Fdownload%2Fescape-string-regexp-4.0.0.tgz", 480 | "integrity": "sha1-FLqDpdNz49MR5a/KKc9b+tllvzQ=", 481 | "optional": true 482 | } 483 | } 484 | }, 485 | "mimic-response": { 486 | "version": "1.0.1", 487 | "resolved": "https://registry.npm.taobao.org/mimic-response/download/mimic-response-1.0.1.tgz?cache=0&sync_timestamp=1589481326973&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmimic-response%2Fdownload%2Fmimic-response-1.0.1.tgz", 488 | "integrity": "sha1-SSNTiHju9CBjy4o+OweYeBSHqxs=" 489 | }, 490 | "minimist": { 491 | "version": "1.2.5", 492 | "resolved": "https://registry.npm.taobao.org/minimist/download/minimist-1.2.5.tgz", 493 | "integrity": "sha1-Z9ZgFLZqaoqqDAg8X9WN9OTpdgI=" 494 | }, 495 | "mkdirp": { 496 | "version": "0.5.5", 497 | "resolved": "https://registry.npm.taobao.org/mkdirp/download/mkdirp-0.5.5.tgz", 498 | "integrity": "sha1-2Rzv1i0UNsoPQWIOJRKI1CAJne8=", 499 | "requires": { 500 | "minimist": "^1.2.5" 501 | } 502 | }, 503 | "ms": { 504 | "version": "2.0.0", 505 | "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz", 506 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 507 | }, 508 | "normalize-url": { 509 | "version": "4.5.0", 510 | "resolved": "https://registry.npm.taobao.org/normalize-url/download/normalize-url-4.5.0.tgz?cache=0&sync_timestamp=1602432435724&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnormalize-url%2Fdownload%2Fnormalize-url-4.5.0.tgz", 511 | "integrity": "sha1-RTNUCH5sqWlXvY9br3U/WYIUISk=" 512 | }, 513 | "npm-conf": { 514 | "version": "1.1.3", 515 | "resolved": "https://registry.npm.taobao.org/npm-conf/download/npm-conf-1.1.3.tgz", 516 | "integrity": "sha1-JWzEe9DiGMJZxOlVC/QTvCGSr/k=", 517 | "optional": true, 518 | "requires": { 519 | "config-chain": "^1.1.11", 520 | "pify": "^3.0.0" 521 | }, 522 | "dependencies": { 523 | "pify": { 524 | "version": "3.0.0", 525 | "resolved": "https://registry.npm.taobao.org/pify/download/pify-3.0.0.tgz", 526 | "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", 527 | "optional": true 528 | } 529 | } 530 | }, 531 | "object-keys": { 532 | "version": "1.1.1", 533 | "resolved": "https://registry.npm.taobao.org/object-keys/download/object-keys-1.1.1.tgz", 534 | "integrity": "sha1-HEfyct8nfzsdrwYWd9nILiMixg4=", 535 | "optional": true 536 | }, 537 | "omggif": { 538 | "version": "1.0.10", 539 | "resolved": "https://registry.npm.taobao.org/omggif/download/omggif-1.0.10.tgz", 540 | "integrity": "sha1-3ar5DUpC9TLp58s6lezdR/F8exk=" 541 | }, 542 | "once": { 543 | "version": "1.4.0", 544 | "resolved": "https://registry.npm.taobao.org/once/download/once-1.4.0.tgz", 545 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 546 | "requires": { 547 | "wrappy": "1" 548 | } 549 | }, 550 | "p-cancelable": { 551 | "version": "1.1.0", 552 | "resolved": "https://registry.npm.taobao.org/p-cancelable/download/p-cancelable-1.1.0.tgz", 553 | "integrity": "sha1-0HjRWjr0CSIMiG8dmgyi5EGrJsw=" 554 | }, 555 | "pako": { 556 | "version": "1.0.11", 557 | "resolved": "https://registry.npm.taobao.org/pako/download/pako-1.0.11.tgz", 558 | "integrity": "sha1-bJWZ00DVTf05RjgCUqNXBaa5kr8=" 559 | }, 560 | "pend": { 561 | "version": "1.2.0", 562 | "resolved": "https://registry.npm.taobao.org/pend/download/pend-1.2.0.tgz", 563 | "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" 564 | }, 565 | "pngjs": { 566 | "version": "3.4.0", 567 | "resolved": "https://registry.npm.taobao.org/pngjs/download/pngjs-3.4.0.tgz", 568 | "integrity": "sha1-mcp9clll+2VYFOr2XzjxK72/VV8=" 569 | }, 570 | "prepend-http": { 571 | "version": "2.0.0", 572 | "resolved": "https://registry.npm.taobao.org/prepend-http/download/prepend-http-2.0.0.tgz", 573 | "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" 574 | }, 575 | "process-nextick-args": { 576 | "version": "2.0.1", 577 | "resolved": "https://registry.npm.taobao.org/process-nextick-args/download/process-nextick-args-2.0.1.tgz", 578 | "integrity": "sha1-eCDZsWEgzFXKmud5JoCufbptf+I=" 579 | }, 580 | "progress": { 581 | "version": "2.0.3", 582 | "resolved": "https://registry.npm.taobao.org/progress/download/progress-2.0.3.tgz", 583 | "integrity": "sha1-foz42PW48jnBvGi+tOt4Vn1XLvg=" 584 | }, 585 | "proto-list": { 586 | "version": "1.2.4", 587 | "resolved": "https://registry.npm.taobao.org/proto-list/download/proto-list-1.2.4.tgz", 588 | "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", 589 | "optional": true 590 | }, 591 | "pump": { 592 | "version": "3.0.0", 593 | "resolved": "https://registry.npm.taobao.org/pump/download/pump-3.0.0.tgz", 594 | "integrity": "sha1-tKIRaBW94vTh6mAjVOjHVWUQemQ=", 595 | "requires": { 596 | "end-of-stream": "^1.1.0", 597 | "once": "^1.3.1" 598 | } 599 | }, 600 | "readable-stream": { 601 | "version": "2.3.7", 602 | "resolved": "https://registry.npm.taobao.org/readable-stream/download/readable-stream-2.3.7.tgz", 603 | "integrity": "sha1-Hsoc9xGu+BTAT2IlKjamL2yyO1c=", 604 | "requires": { 605 | "core-util-is": "~1.0.0", 606 | "inherits": "~2.0.3", 607 | "isarray": "~1.0.0", 608 | "process-nextick-args": "~2.0.0", 609 | "safe-buffer": "~5.1.1", 610 | "string_decoder": "~1.1.1", 611 | "util-deprecate": "~1.0.1" 612 | } 613 | }, 614 | "responselike": { 615 | "version": "1.0.2", 616 | "resolved": "https://registry.npm.taobao.org/responselike/download/responselike-1.0.2.tgz", 617 | "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", 618 | "requires": { 619 | "lowercase-keys": "^1.0.0" 620 | } 621 | }, 622 | "roarr": { 623 | "version": "2.15.4", 624 | "resolved": "https://registry.npm.taobao.org/roarr/download/roarr-2.15.4.tgz?cache=0&sync_timestamp=1600094664861&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Froarr%2Fdownload%2Froarr-2.15.4.tgz", 625 | "integrity": "sha1-9f55W3uDjM/jXcYI4Cgrnrouev0=", 626 | "optional": true, 627 | "requires": { 628 | "boolean": "^3.0.1", 629 | "detect-node": "^2.0.4", 630 | "globalthis": "^1.0.1", 631 | "json-stringify-safe": "^5.0.1", 632 | "semver-compare": "^1.0.0", 633 | "sprintf-js": "^1.1.2" 634 | } 635 | }, 636 | "safe-buffer": { 637 | "version": "5.1.2", 638 | "resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz", 639 | "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=" 640 | }, 641 | "sanitize-filename": { 642 | "version": "1.6.3", 643 | "resolved": "https://registry.npm.taobao.org/sanitize-filename/download/sanitize-filename-1.6.3.tgz", 644 | "integrity": "sha1-dV69dSBFkxl34wsgJdNA18kJA3g=", 645 | "requires": { 646 | "truncate-utf8-bytes": "^1.0.0" 647 | } 648 | }, 649 | "semver-compare": { 650 | "version": "1.0.0", 651 | "resolved": "https://registry.npm.taobao.org/semver-compare/download/semver-compare-1.0.0.tgz", 652 | "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", 653 | "optional": true 654 | }, 655 | "serialize-error": { 656 | "version": "7.0.1", 657 | "resolved": "https://registry.npm.taobao.org/serialize-error/download/serialize-error-7.0.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fserialize-error%2Fdownload%2Fserialize-error-7.0.1.tgz", 658 | "integrity": "sha1-8TYLBEf2H/tIPsQVfHN/q313jhg=", 659 | "optional": true, 660 | "requires": { 661 | "type-fest": "^0.13.1" 662 | } 663 | }, 664 | "sprintf-js": { 665 | "version": "1.1.2", 666 | "resolved": "https://registry.npm.taobao.org/sprintf-js/download/sprintf-js-1.1.2.tgz", 667 | "integrity": "sha1-2hdlJiv4wPVxdJ8q1sJjACB65nM=", 668 | "optional": true 669 | }, 670 | "string-to-arraybuffer": { 671 | "version": "1.0.2", 672 | "resolved": "https://registry.npm.taobao.org/string-to-arraybuffer/download/string-to-arraybuffer-1.0.2.tgz", 673 | "integrity": "sha1-FhFH+63qAuKLCTUALOxMQPHKfwo=", 674 | "requires": { 675 | "atob-lite": "^2.0.0", 676 | "is-base64": "^0.1.0" 677 | } 678 | }, 679 | "string_decoder": { 680 | "version": "1.1.1", 681 | "resolved": "https://registry.npm.taobao.org/string_decoder/download/string_decoder-1.1.1.tgz", 682 | "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", 683 | "requires": { 684 | "safe-buffer": "~5.1.0" 685 | } 686 | }, 687 | "sumchecker": { 688 | "version": "3.0.1", 689 | "resolved": "https://registry.npm.taobao.org/sumchecker/download/sumchecker-3.0.1.tgz", 690 | "integrity": "sha1-Y3fplnlauwttNI6bPh37JDRajkI=", 691 | "requires": { 692 | "debug": "^4.1.0" 693 | }, 694 | "dependencies": { 695 | "debug": { 696 | "version": "4.3.1", 697 | "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.3.1.tgz?cache=0&sync_timestamp=1607566580543&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.3.1.tgz", 698 | "integrity": "sha1-8NIpxQXgxtjEmsVT0bE9wYP2su4=", 699 | "requires": { 700 | "ms": "2.1.2" 701 | } 702 | }, 703 | "ms": { 704 | "version": "2.1.2", 705 | "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz?cache=0&sync_timestamp=1607433905701&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.1.2.tgz", 706 | "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=" 707 | } 708 | } 709 | }, 710 | "to-array-buffer": { 711 | "version": "3.2.0", 712 | "resolved": "https://registry.npm.taobao.org/to-array-buffer/download/to-array-buffer-3.2.0.tgz", 713 | "integrity": "sha1-y2hN1pGnNow7JJwjSNdSJ/fU27Q=", 714 | "requires": { 715 | "flatten-vertex-data": "^1.0.2", 716 | "is-blob": "^2.0.1", 717 | "string-to-arraybuffer": "^1.0.0" 718 | } 719 | }, 720 | "to-readable-stream": { 721 | "version": "1.0.0", 722 | "resolved": "https://registry.npm.taobao.org/to-readable-stream/download/to-readable-stream-1.0.0.tgz", 723 | "integrity": "sha1-zgqgwvPfat+FLvtASng+d8BHV3E=" 724 | }, 725 | "truncate-utf8-bytes": { 726 | "version": "1.0.2", 727 | "resolved": "https://registry.npm.taobao.org/truncate-utf8-bytes/download/truncate-utf8-bytes-1.0.2.tgz", 728 | "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=", 729 | "requires": { 730 | "utf8-byte-length": "^1.0.1" 731 | } 732 | }, 733 | "tsc": { 734 | "version": "1.20150623.0", 735 | "resolved": "https://registry.npm.taobao.org/tsc/download/tsc-1.20150623.0.tgz", 736 | "integrity": "sha1-Trw8d04WkUjLx2inNCUz8ILHpuU=", 737 | "dev": true 738 | }, 739 | "tunnel": { 740 | "version": "0.0.6", 741 | "resolved": "https://registry.npm.taobao.org/tunnel/download/tunnel-0.0.6.tgz", 742 | "integrity": "sha1-cvExSzSlsZLbASMk3yzFh8pH+Sw=", 743 | "optional": true 744 | }, 745 | "type-fest": { 746 | "version": "0.13.1", 747 | "resolved": "https://registry.npm.taobao.org/type-fest/download/type-fest-0.13.1.tgz?cache=0&sync_timestamp=1606468899313&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftype-fest%2Fdownload%2Ftype-fest-0.13.1.tgz", 748 | "integrity": "sha1-AXLLW86AsL1ULqNI21DH4hg02TQ=", 749 | "optional": true 750 | }, 751 | "typedarray": { 752 | "version": "0.0.6", 753 | "resolved": "https://registry.npm.taobao.org/typedarray/download/typedarray-0.0.6.tgz", 754 | "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" 755 | }, 756 | "typescript": { 757 | "version": "4.1.3", 758 | "resolved": "https://registry.npm.taobao.org/typescript/download/typescript-4.1.3.tgz?cache=0&sync_timestamp=1608446729281&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftypescript%2Fdownload%2Ftypescript-4.1.3.tgz", 759 | "integrity": "sha1-UZ1YK9lMugz4k0x9joRn5HP1O7c=", 760 | "dev": true 761 | }, 762 | "universalify": { 763 | "version": "0.1.2", 764 | "resolved": "https://registry.npm.taobao.org/universalify/download/universalify-0.1.2.tgz?cache=0&sync_timestamp=1603180004159&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Funiversalify%2Fdownload%2Funiversalify-0.1.2.tgz", 765 | "integrity": "sha1-tkb2m+OULavOzJ1mOcgNwQXvqmY=" 766 | }, 767 | "url-parse-lax": { 768 | "version": "3.0.0", 769 | "resolved": "https://registry.npm.taobao.org/url-parse-lax/download/url-parse-lax-3.0.0.tgz", 770 | "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", 771 | "requires": { 772 | "prepend-http": "^2.0.0" 773 | } 774 | }, 775 | "utf8-byte-length": { 776 | "version": "1.0.4", 777 | "resolved": "https://registry.npm.taobao.org/utf8-byte-length/download/utf8-byte-length-1.0.4.tgz", 778 | "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=" 779 | }, 780 | "utif": { 781 | "version": "2.0.1", 782 | "resolved": "https://registry.npm.taobao.org/utif/download/utif-2.0.1.tgz", 783 | "integrity": "sha1-nhWC2bvSABGmWIVI7TJmKY5xF1k=", 784 | "requires": { 785 | "pako": "^1.0.5" 786 | } 787 | }, 788 | "util-deprecate": { 789 | "version": "1.0.2", 790 | "resolved": "https://registry.npm.taobao.org/util-deprecate/download/util-deprecate-1.0.2.tgz", 791 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 792 | }, 793 | "wrappy": { 794 | "version": "1.0.2", 795 | "resolved": "https://registry.npm.taobao.org/wrappy/download/wrappy-1.0.2.tgz", 796 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 797 | }, 798 | "yauzl": { 799 | "version": "2.10.0", 800 | "resolved": "https://registry.npm.taobao.org/yauzl/download/yauzl-2.10.0.tgz", 801 | "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", 802 | "requires": { 803 | "buffer-crc32": "~0.2.3", 804 | "fd-slicer": "~1.1.0" 805 | } 806 | } 807 | } 808 | } 809 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "raster-toy", 3 | "version": "1.0.0", 4 | "main": "main.js", 5 | "scripts": { 6 | "start": "electron ." 7 | }, 8 | "description": "raster-toy", 9 | "author": "laomoi", 10 | "license": "CC0-1.0", 11 | "devDependencies": { 12 | "tsc": "^1.20150623.0", 13 | "typescript": "^4.1.3" 14 | }, 15 | "dependencies": { 16 | "electron": "^11.1.0", 17 | "image-decode": "^1.2.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /res/african_head_diffuse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laomoi/toy-raster/29a79d96d255d858ca1080e8445f993326d5df90/res/african_head_diffuse.png -------------------------------------------------------------------------------- /res/african_head_nm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laomoi/toy-raster/29a79d96d255d858ca1080e8445f993326d5df90/res/african_head_nm.png -------------------------------------------------------------------------------- /res/african_head_nm_tangent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laomoi/toy-raster/29a79d96d255d858ca1080e8445f993326d5df90/res/african_head_nm_tangent.png -------------------------------------------------------------------------------- /res/african_head_spec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laomoi/toy-raster/29a79d96d255d858ca1080e8445f993326d5df90/res/african_head_spec.png -------------------------------------------------------------------------------- /res/diablo3_pose_diffuse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laomoi/toy-raster/29a79d96d255d858ca1080e8445f993326d5df90/res/diablo3_pose_diffuse.png -------------------------------------------------------------------------------- /res/diablo3_pose_nm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laomoi/toy-raster/29a79d96d255d858ca1080e8445f993326d5df90/res/diablo3_pose_nm.png -------------------------------------------------------------------------------- /res/diablo3_pose_spec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laomoi/toy-raster/29a79d96d255d858ca1080e8445f993326d5df90/res/diablo3_pose_spec.png -------------------------------------------------------------------------------- /res/floor_diffuse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laomoi/toy-raster/29a79d96d255d858ca1080e8445f993326d5df90/res/floor_diffuse.png -------------------------------------------------------------------------------- /run.bat: -------------------------------------------------------------------------------- 1 | .\node_modules\.bin\electron .\ 2 | -------------------------------------------------------------------------------- /run/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | toy raster 6 | 7 | 8 | 9 | 10 | 11 | 12 |
fps:
13 | 14 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/app.ts: -------------------------------------------------------------------------------- 1 | import { WebGLBlitter } from "./web/webgl-blitter" 2 | import Raster from "./core/raster" 3 | import DrawBox from "./examples/draw-box" 4 | import DrawMesh from "./examples/draw-mesh" 5 | 6 | 7 | export interface IExample { 8 | draw():void; 9 | onWheel?(delta:number):void; 10 | onMove?(x:number, y:number):void; 11 | } 12 | 13 | 14 | export default class App { 15 | 16 | protected gl:WebGLRenderingContext 17 | 18 | protected showFPSCallback:any = null 19 | 20 | protected width:number 21 | protected height:number 22 | protected blitter:WebGLBlitter = null 23 | protected renderer:Raster 24 | protected example:IExample 25 | public setGL(gl:WebGLRenderingContext, width:number, height:number) { 26 | this.gl = gl 27 | this.width = width 28 | this.height = height 29 | } 30 | 31 | public run() { 32 | this.renderer = new Raster(this.width, this.height, true) 33 | this.blitter = new WebGLBlitter(this.gl) 34 | // this.example = new DrawBox(this.renderer) 35 | this.example = new DrawMesh(this.renderer) 36 | 37 | 38 | let then = 0 39 | let lastShowFPS = 0 40 | let loopWrap = (now:number) => { 41 | now *= 0.001 42 | const deltaTime = now - then 43 | if (then > 0 && deltaTime > 0 && this.showFPSCallback != null) { 44 | if (now - lastShowFPS > 0.3) { 45 | const fps = 1 / deltaTime 46 | this.showFPSCallback(fps) 47 | lastShowFPS = now 48 | } 49 | 50 | } 51 | then = now 52 | this.loop() 53 | requestAnimationFrame(loopWrap) 54 | } 55 | 56 | loopWrap(0) 57 | } 58 | 59 | public setShowFPSCallback(callback:any) { 60 | this.showFPSCallback = callback 61 | } 62 | 63 | protected loop() { 64 | this.renderer.clear() 65 | this.example.draw() 66 | this.flush() 67 | } 68 | 69 | protected flush() { 70 | this.blitter.blitPixels(this.renderer.width, this.renderer.height, this.renderer.getFrameBuffer()) 71 | } 72 | 73 | } -------------------------------------------------------------------------------- /src/core/math/math-utils.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | export default class MathUtils { 4 | 5 | public static getInterpValue2(v1:number, v2:number, a:number, b:number) { 6 | return v1*a + v2*b 7 | } 8 | 9 | public static getInterpValue3(v1:number, v2:number, v3:number, a:number, b:number, c:number) { 10 | return v1*a + v2*b + v3*c 11 | } 12 | 13 | public static getInterpValue4(v1:number, v2:number, v3:number, v4:number, a:number, b:number, c:number, d:number) { 14 | return v1*a + v2*b + v3*c + v4*d 15 | } 16 | 17 | public static clamp(value:number, min:number, max:number) { 18 | if (value < min){ 19 | return min 20 | } 21 | if (value > max){ 22 | return max 23 | } 24 | return value 25 | } 26 | 27 | public static saturate(value:number){ 28 | return MathUtils.clamp(value, 0, 1) 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/core/math/matrix.ts: -------------------------------------------------------------------------------- 1 | import { Vector4 } from "./vector4" 2 | 3 | // 4x4 列向量矩阵 , 右手坐标系 4 | export class Matrix { 5 | public m:Array 6 | constructor() { 7 | this.m = [] 8 | for (let i=0;i<4;i++) { 9 | let col = new Float32Array(4) 10 | this.m.push(col) 11 | } 12 | this.identify() 13 | } 14 | 15 | public identify(){ 16 | this.setValue(0) 17 | this.m[0][0] = this.m[1][1]= this.m[2][2]= this.m[3][3] = 1 18 | } 19 | 20 | public multiply(t:Matrix, dst:Matrix=null):Matrix{ 21 | if (dst == null){ 22 | dst = new Matrix() 23 | } 24 | for (let i=0;i<4;i++) { 25 | for (let j=0;j<4;j++) { 26 | dst.m[j][i] = 27 | this.m[j][0] * t.m[0][i] 28 | + this.m[j][1] * t.m[1][i] 29 | + this.m[j][2] * t.m[2][i] 30 | + this.m[j][3] * t.m[3][i] 31 | } 32 | } 33 | return dst 34 | } 35 | 36 | public setValue(val:number){ 37 | for (let i=0;i<4;i++) { 38 | for (let j=0;j<4;j++) { 39 | this.m[j][i] = val 40 | } 41 | } 42 | } 43 | 44 | //near far should be > 0 45 | public setPerspective(fovy:number, aspect:number, near:number, far:number){ 46 | this.setValue(0) 47 | 48 | let n = -near 49 | let f = -far 50 | let tn = -Math.tan(fovy/2) // t/n, aspect = r/t 51 | let nt = 1 / tn // = n/t 52 | let nr = nt / aspect // = n/r 53 | 54 | this.m[0][0] = nr 55 | this.m[1][1] = nt 56 | this.m[2][2] = (n+f)/(n-f) 57 | this.m[3][2] = 2*f*n/(f-n) 58 | this.m[2][3] = 1 59 | } 60 | 61 | public setRotateX(angle:number){ 62 | this.identify() 63 | let cos = Math.cos(angle), sin=Math.sin(angle) 64 | this.m[1][1] = cos 65 | this.m[1][2] = sin 66 | this.m[2][1] = -sin 67 | this.m[2][2] = cos 68 | } 69 | 70 | public setRotateY(angle:number){ 71 | this.identify() 72 | let cos = Math.cos(angle), sin=Math.sin(angle) 73 | this.m[0][0] = cos 74 | this.m[0][2] = -sin 75 | this.m[2][0] = sin 76 | this.m[2][2] = cos 77 | } 78 | 79 | public setRotateZ(angle:number){ 80 | this.identify() 81 | let cos = Math.cos(angle), sin=Math.sin(angle) 82 | this.m[0][0] = cos 83 | this.m[0][1] = sin 84 | this.m[1][0] = -sin 85 | this.m[1][1] = cos 86 | } 87 | 88 | public setLookAt(eye:Vector4, at:Vector4, up:Vector4) { 89 | //w is reverse of look at direction, wuv is the axises of the camera, 90 | //The equation is from 4th. 7.1 91 | let w = at.sub(eye).normalize().reverse() 92 | let u = up.cross(w).normalize() 93 | let v = w.cross(u) 94 | this.setValue(0) 95 | 96 | this.m[0][0] = u.x 97 | this.m[1][0] = u.y 98 | this.m[2][0] = u.z 99 | 100 | this.m[0][1] = v.x 101 | this.m[1][1] = v.y 102 | this.m[2][1] = v.z 103 | 104 | this.m[0][2] = w.x 105 | this.m[1][2] = w.y 106 | this.m[2][2] = w.z 107 | 108 | this.m[3][3] = 1 109 | 110 | //translate 111 | let tEye = eye.reverse() 112 | this.m[3][0] = u.dot(tEye) 113 | this.m[3][1] = v.dot(tEye) 114 | this.m[3][2] = w.dot(tEye) 115 | } 116 | } -------------------------------------------------------------------------------- /src/core/math/vector2.ts: -------------------------------------------------------------------------------- 1 | import MathUtils from "./math-utils" 2 | 3 | export class Vector2{ 4 | public x:number 5 | public y:number 6 | 7 | public constructor(x:number=0, y:number=0) { 8 | this.x = x 9 | this.y = y 10 | } 11 | 12 | public getLength():number{ 13 | return Math.sqrt( this.x*this.x + this.y*this.y) 14 | } 15 | 16 | public static getInterpValue3(v1:Vector2, v2:Vector2, v3:Vector2, a:number, b:number, c:number, dst:Vector2=null) { 17 | if (dst == null) { 18 | dst = new Vector2() 19 | } 20 | dst.x = MathUtils.getInterpValue3(v1.x, v2.x, v3.x, a, b, c) 21 | dst.y = MathUtils.getInterpValue3(v1.y, v2.y, v3.y, a, b, c) 22 | return dst 23 | } 24 | } -------------------------------------------------------------------------------- /src/core/math/vector4.ts: -------------------------------------------------------------------------------- 1 | import MathUtils from "./math-utils" 2 | import { Matrix } from "./matrix" 3 | 4 | export class Vector4{ 5 | public x:number 6 | public y:number 7 | public z:number 8 | public w:number 9 | public constructor(x:number=0, y:number=0, z:number=0, w:number=1) { 10 | this.x = x 11 | this.y = y 12 | this.z = z 13 | this.w = w 14 | } 15 | public getLength():number{ 16 | return Math.sqrt( this.x*this.x + this.y*this.y + this.z*this.z ) 17 | } 18 | 19 | public reverse(dst:Vector4=null):Vector4{ 20 | if (dst == null) { 21 | dst = new Vector4() 22 | } 23 | dst.x = - this.x 24 | dst.y = - this.y 25 | dst.z = - this.z 26 | return dst 27 | } 28 | 29 | public add(t:Vector4, dst:Vector4=null):Vector4 { 30 | if (dst == null){ 31 | dst = new Vector4() 32 | } 33 | dst.x = this.x + t.x 34 | dst.y = this.y + t.y 35 | dst.z = this.z + t.z 36 | dst.w = 1.0 37 | return dst 38 | } 39 | 40 | public sub(t:Vector4, dst:Vector4=null):Vector4 { 41 | if (dst == null){ 42 | dst = new Vector4() 43 | } 44 | dst.x = this.x - t.x 45 | dst.y = this.y - t.y 46 | dst.z = this.z - t.z 47 | dst.w = 1.0 48 | return dst 49 | } 50 | 51 | public dot(t:Vector4):number { 52 | return this.x * t.x + this.y * t.y + this.z * t.z; 53 | } 54 | 55 | public cross(t:Vector4, dst:Vector4=null):Vector4 { 56 | if (dst == null){ 57 | dst = new Vector4() 58 | } 59 | let x = this.y * t.z - this.z * t.y 60 | let y = this.z * t.x - this.x * t.z 61 | let z = this.x * t.y - this.y * t.x 62 | dst.x = x 63 | dst.y = y 64 | dst.z = z 65 | dst.w = 1.0 66 | return dst 67 | } 68 | 69 | public normalize(dst:Vector4=null):Vector4{ 70 | if (dst == null){ 71 | dst = new Vector4() 72 | } 73 | let len = this.getLength() 74 | if (len > 0) { 75 | dst.x = this.x / len 76 | dst.y = this.y / len 77 | dst.z = this.z / len 78 | } 79 | return dst 80 | } 81 | 82 | public transform(matrix:Matrix, dst:Vector4=null) { 83 | if (dst == null){ 84 | dst = new Vector4() 85 | } 86 | let x = this.x, y = this.y, z = this.z, w = this.w 87 | let m = matrix.m 88 | dst.x = m[0][0]*x + m[1][0]*y + m[2][0]*z + m[3][0]*w 89 | dst.y = m[0][1]*x + m[1][1]*y + m[2][1]*z + m[3][1]*w 90 | dst.z = m[0][2]*x + m[1][2]*y + m[2][2]*z + m[3][2]*w 91 | dst.w = m[0][3]*x + m[1][3]*y + m[2][3]*z + m[3][3]*w 92 | return dst 93 | } 94 | 95 | //齐次坐标归一 96 | public homogenenize(){ 97 | if (this.w != 0) { 98 | this.x /= this.w 99 | this.y /= this.w 100 | this.z /= this.w 101 | this.w = 1 102 | } 103 | } 104 | 105 | public static getInterpValue3(v1:Vector4, v2:Vector4, v3:Vector4, a:number, b:number, c:number, dst:Vector4=null) { 106 | if (dst == null){ 107 | dst = new Vector4() 108 | } 109 | dst.x = MathUtils.getInterpValue3(v1.x, v2.x, v3.x, a, b, c) 110 | dst.y = MathUtils.getInterpValue3(v1.y, v2.y, v3.y, a, b, c) 111 | dst.z = MathUtils.getInterpValue3(v1.z, v2.z, v3.z, a, b, c) 112 | return dst 113 | } 114 | } -------------------------------------------------------------------------------- /src/core/raster.ts: -------------------------------------------------------------------------------- 1 | import Buffer from "./shading/buffer" 2 | import { Matrix } from "./math/matrix" 3 | import { Vector4 } from "./math/vector4" 4 | import { Color } from "./shading/color" 5 | import Shader, { IShaderProgram, FragmentInput } from "./shading/shader" 6 | import { Vertex } from "./shading/vertex" 7 | import MathUtils from "./math/math-utils" 8 | import { Vector2 } from "./math/vector2" 9 | 10 | 11 | export interface Camera { 12 | view: Matrix, 13 | projection:Matrix, 14 | vp:Matrix //projection*view 15 | } 16 | 17 | 18 | export default class Raster { 19 | public width:number 20 | public height:number 21 | // public frameBuffer:Uint8Array = null 22 | protected buffer:Buffer = null 23 | protected backgroundColor:Color = Color.BLACK.clone() 24 | protected usingMSAA:boolean = true //使用2x2 grid的MSAA抗锯齿 25 | protected currentShader:Shader = null 26 | 27 | protected camera:Camera = { 28 | view: new Matrix(), 29 | projection: new Matrix(), 30 | vp: new Matrix() 31 | } 32 | 33 | constructor(width:number, height:number, usingMSAA:boolean=true) { 34 | this.width = width 35 | this.height = height 36 | this.usingMSAA = usingMSAA 37 | 38 | this.buffer = new Buffer(width, height, usingMSAA) 39 | 40 | this.setDefaultCamera() 41 | } 42 | 43 | public clear() { 44 | this.buffer.clear(this.backgroundColor) 45 | } 46 | 47 | public drawLine(x0:number, y0:number, x1:number, y1:number, color:Color){ 48 | if (x0 == x1) { 49 | let dir = y0 < y1 ? 1 : -1 50 | for (let y=y0; y!=y1; y+=dir) { 51 | this.setPixel(x0, y, color) 52 | } 53 | this.setPixel(x1, y1, color) 54 | } else if (y0 == y1) { 55 | let dir = x0 < x1 ? 1 : -1 56 | for (let x=x0; x!=x1; x+=dir) { 57 | this.setPixel(x, y0, color) 58 | } 59 | this.setPixel(x1, y1, color) 60 | } else { 61 | //use mid-point algorithm to draw line, 4th, Setion 8.1 62 | let dx = Math.abs(x1 - x0) 63 | let dy = Math.abs(y1 - y0) 64 | if (dx > dy) { 65 | //more horizontal line 66 | if (x0 > x1) { 67 | let tx = x0, ty = y0 68 | x0 = x1, y0 = y1 69 | x1 = tx, y1 = ty 70 | } 71 | let dir = y1 > y0 ? 1: -1 72 | let y = y0 73 | let d = (y0-y1)*(x0+1) + (x1-x0)*(y0+0.5*dir) + x0*y1 - x1*y0 74 | for (let x=x0;x<=x1;x++) { 75 | this.setPixel(x, y, color) 76 | if (d*dir < 0){ 77 | y += dir 78 | d += (x1-x0)*dir + (y0-y1) 79 | } else { 80 | d += y0 - y1 81 | } 82 | } 83 | } else { 84 | //more vertical line 85 | if (y0 > y1) { 86 | let tx = x0, ty = y0 87 | x0 = x1, y0 = y1 88 | x1 = tx, y1 = ty 89 | } 90 | let dir = x1 > x0 ? 1: -1 91 | let x = x0 92 | let d = (y0-y1)*(x0+0.5*dir) + (x1-x0)*(y0+1) + x0*y1 - x1*y0 93 | for (let y=y0;y<=y1;y++) { 94 | this.setPixel(x, y, color) 95 | if (d*dir > 0){ 96 | x += dir 97 | d += (x1-x0)+ (y0-y1)*dir 98 | } else { 99 | d += x1 - x0 100 | } 101 | } 102 | } 103 | } 104 | } 105 | 106 | protected barycentricFunc(vs:Array, a:number, b:number, x:number, y:number):number{ 107 | return ((vs[a].y - vs[b].y)*x + (vs[b].x - vs[a].x)*y + vs[a].x*vs[b].y - vs[b].x*vs[a].y) 108 | } 109 | 110 | //如果在三角形内,返回[3个重心坐标], 否则返回null 111 | protected getBarycentricInTriangle(x:number, y:number, vs:Array, fAlpha:number, fBelta:number, fGama:number, 112 | fAlphaTest:number, fBeltaTest:number, fGamaTest:number) { 113 | //F(a,b, x,y) = (ya-yb)*x + (xb-xa)*y + xa*yb - xb*ya, 114 | //a,b is [0,1,2], belta= F(2,0,x,y) / F(2, 0, x1,y1) 115 | let belta = this.barycentricFunc(vs, 2, 0, x, y) / fBelta 116 | let gama = this.barycentricFunc(vs, 0, 1, x, y) / fGama 117 | let alpha = 1 - belta - gama 118 | if (alpha>=0 && belta >=0 && gama >=0) { 119 | if ( (alpha > 0 || fAlpha*fAlphaTest > 0) 120 | && (belta > 0 || fBelta*fBeltaTest > 0) 121 | && (gama > 0 || fGama*fGamaTest > 0) 122 | ){ 123 | return [ alpha, belta, gama] 124 | } 125 | } 126 | return null 127 | } 128 | 129 | protected drawTriangle2D(v0:Vertex, v1:Vertex, v2:Vertex) { 130 | //使用重心坐标的算法(barycentric coordinates)对三角形进行光栅化 131 | //使用AABB来优化性能 132 | //对于三角形边(edge case)上的点, 使用的是上的算法, 使用一个Off-screen point(-1, -1) 来判断是否在同一边 133 | let vs = [v0.context.posScreen, v1.context.posScreen, v2.context.posScreen] 134 | let x0 = vs[0].x, x1 = vs[1].x, x2 = vs[2].x, y0 = vs[0].y, y1=vs[1].y, y2=vs[2].y 135 | let minX = Math.floor( Math.min(x0, x1, x2) ) 136 | let maxX = Math.ceil( Math.max(x0, x1, x2) ) 137 | let minY = Math.floor( Math.min(y0, y1, y2) ) 138 | let maxY = Math.ceil( Math.max(y0, y1, y2) ) 139 | let fBelta = this.barycentricFunc(vs, 2, 0, x1, y1) 140 | let fGama = this.barycentricFunc(vs, 0, 1, x2, y2) 141 | let fAlpha = this.barycentricFunc(vs, 1, 2, x0, y0) 142 | 143 | let offScreenPointX = -1, offScreenPointY = -1 144 | let fAlphaTest = this.barycentricFunc(vs, 1, 2, offScreenPointX, offScreenPointY) 145 | let fGamaTest = this.barycentricFunc(vs, 0, 1, offScreenPointX, offScreenPointY) 146 | let fBeltaTest = this.barycentricFunc(vs, 2, 0, offScreenPointX, offScreenPointY) 147 | 148 | for (let x=minX;x<=maxX;x++) { 149 | for (let y=minY;y<=maxY;y++) { 150 | if (!this.usingMSAA) { 151 | this.rasterizePixelInTriangle(x, y, vs, v0, v1, v2, fAlpha, fBelta, fGama, fAlphaTest, fBeltaTest, fGamaTest) 152 | } else { 153 | this.rasterizePixelInTriangleMSAA(x, y, vs, v0, v1, v2, fAlpha, fBelta, fGama, fAlphaTest, fBeltaTest, fGamaTest) 154 | } 155 | } 156 | } 157 | } 158 | 159 | protected createFragmentInput(x:number, y:number, v0:Vertex, v1:Vertex, v2:Vertex, a:number, b:number, c:number) { 160 | let context:FragmentInput = { 161 | x:x, 162 | y:y, 163 | color:Color.WHITE.clone(), 164 | varyingVec2Dict:{}, 165 | varyingVec4Dict:{}, 166 | } 167 | //插值 168 | Color.getInterpColor(v0.color, v1.color, v2.color, a, b, c, context.color) 169 | for (let k in v0.context.varyingVec2Dict) { 170 | context.varyingVec2Dict[k] = Vector2.getInterpValue3(v0.context.varyingVec2Dict[k], 171 | v1.context.varyingVec2Dict[k], v2.context.varyingVec2Dict[k], a, b, c) 172 | } 173 | for (let k in v0.context.varyingVec4Dict) { 174 | context.varyingVec4Dict[k] = Vector4.getInterpValue3(v0.context.varyingVec4Dict[k], 175 | v1.context.varyingVec4Dict[k], v2.context.varyingVec4Dict[k], a, b, c) 176 | } 177 | return context 178 | } 179 | 180 | protected rasterizePixelInTriangle(x:number, y:number, vs:Array, v0:Vertex, v1:Vertex, v2:Vertex, 181 | fAlpha:number, fBelta:number, fGama:number, fAlphaTest:number, fBeltaTest:number, fGamaTest:number) { 182 | let barycentric = this.getBarycentricInTriangle(x, y, vs, fAlpha, fBelta, fGama, fAlphaTest, fBeltaTest, fGamaTest) 183 | if (barycentric == null) { 184 | return 185 | } 186 | let rhw = MathUtils.getInterpValue3(v0.context.rhw, v1.context.rhw, v2.context.rhw, barycentric[0], barycentric[1], barycentric[2]) //1/z 187 | //这里使用rhw=1/w作为深度缓冲的值,非线性的zbuffer在近处有更高的精度 188 | if (this.buffer.ztest(x, y, rhw)) { 189 | let w = 1 / (rhw != 0 ? rhw : 1) 190 | //反推3D空间中的重心坐标 a, b, c 191 | let a = barycentric[0]*w*v0.context.rhw 192 | let b = barycentric[1]*w*v1.context.rhw 193 | let c = barycentric[2]*w*v2.context.rhw 194 | 195 | let input:FragmentInput = this.createFragmentInput(x, y, v0, v1, v2, a, b, c) 196 | let finalColor = this.currentShader.fragmentShading(input) 197 | if (finalColor.a > 0) { 198 | this.setPixel(x, y, finalColor) 199 | this.buffer.setZ(x, y, rhw) 200 | } 201 | } 202 | } 203 | 204 | protected rasterizePixelInTriangleMSAA(x:number, y:number, vs:Array, v0:Vertex, v1:Vertex, v2:Vertex, 205 | fAlpha:number, fBelta:number, fGama:number, fAlphaTest:number, fBeltaTest:number, fGamaTest:number) { 206 | //4个子采样点, 2x2 RGSS GRID 207 | let points = [[x-0.325,y+0.125],[x+0.125, y+0.325],[x-0.125, y-0.325],[x+0.325,y-0.125]] 208 | let testResults:Array<{barycentric:number[],index:number,x:number,y:number,rhw:number}> = [] 209 | for (let i=0;i 0) { 228 | //对像素中心点进行一次frag着色,如果取不到,则使用第一个采样点进行着色 229 | let fx = x, fy = y 230 | let barycentric = this.getBarycentricInTriangle(x, y, vs, fAlpha, fBelta, fGama, fAlphaTest, fBeltaTest, fGamaTest) 231 | if (barycentric == null) { 232 | barycentric = testResults[0].barycentric 233 | fx = testResults[0].x 234 | fy = testResults[0].y 235 | } 236 | let rhw = MathUtils.getInterpValue3(v0.context.rhw, v1.context.rhw, v2.context.rhw, barycentric[0], barycentric[1], barycentric[2]) //1/z 237 | let w = 1 / (rhw != 0 ? rhw : 1) 238 | let a = barycentric[0]*w*v0.context.rhw 239 | let b = barycentric[1]*w*v1.context.rhw 240 | let c = barycentric[2]*w*v2.context.rhw 241 | let input:FragmentInput = this.createFragmentInput(fx, fy, v0, v1, v2, a, b, c) 242 | let finalColor = this.currentShader.fragmentShading(input) 243 | if (finalColor.a > 0) { 244 | for (let result of testResults) { 245 | let index = result.index 246 | let rhw = result.rhw 247 | this.setPixel(x, y, finalColor, index) 248 | this.buffer.setZ(x, y, rhw, index) 249 | } 250 | this.buffer.applyMSAAFilter(x, y) 251 | } 252 | } 253 | } 254 | 255 | 256 | public setBackgroundColor(color:Color) { 257 | this.backgroundColor = color.clone() 258 | } 259 | 260 | public setPixel(x:number, y:number, color:Color, index:number=0) { 261 | if (x < this.width && y < this.height && x>=0 && y>=0) { 262 | this.buffer.setColor(x, y, color, index) 263 | } 264 | } 265 | 266 | public drawTriangle(va:Array){ 267 | if (va.length % 3 != 0){ 268 | return 269 | } 270 | //执行顶点着色器,得到真正的投影坐标,输出到 context, 作为片元着色器的输入 271 | this.currentShader.setViewProject(this.camera.vp) 272 | for (let vertex of va) { 273 | vertex.context = { 274 | posProject: new Vector4(), 275 | posScreen: new Vector4(), 276 | rhw: 1, 277 | varyingVec2Dict: {}, 278 | varyingVec4Dict: {}, 279 | } 280 | this.currentShader.vertexShading(vertex) 281 | vertex.context.rhw = 1/vertex.context.posProject.w //w等同于投影前的视图坐标的z 282 | vertex.context.posProject.homogenenize() 283 | } 284 | 285 | //没做backface culling, 只做了view volumn culling 286 | //三角形细分的clip没做 287 | //计算到屏幕坐标,执行片元着色器 288 | let culling = false 289 | for (let p of va) { 290 | //view volumn culling 291 | if (!this.isInsideViewVolumn(p.context.posProject) ) { 292 | culling = true 293 | break; 294 | } 295 | } 296 | 297 | if (!culling) { 298 | for (let p of va) { 299 | this.convertToScreenPos(p.context.posProject, p.context.posScreen, this.width, this.height) 300 | } 301 | this.drawTriangle2D(va[0], va[1], va[2]) 302 | } 303 | } 304 | 305 | protected setDefaultCamera() { 306 | let eye = new Vector4(1.5, 0, 3, 1) 307 | let at = new Vector4(0, 0, 0, 1) 308 | let up = new Vector4(0, 1, 0, 1) 309 | let fovy = Math.PI / 2 310 | let aspect = this.width / this.height 311 | let near = 1 312 | let far = 500 313 | this.setCamera(eye, at, up, fovy, aspect, near, far) 314 | } 315 | 316 | public setCamera(eye:Vector4, lookAt:Vector4, up:Vector4, fovy:number, aspect:number, near:number, far:number) { 317 | this.camera.view.setLookAt(eye, lookAt, up) 318 | this.camera.projection.setPerspective(fovy, aspect, near, far) 319 | this.camera.vp = this.camera.view.multiply(this.camera.projection) 320 | } 321 | 322 | public getFrameBuffer() { 323 | return this.buffer.frameBuffer 324 | } 325 | 326 | public setShader(shader:Shader){ 327 | this.currentShader = shader 328 | } 329 | 330 | protected isInsideViewVolumn(v:Vector4){ 331 | if (v.x < -1 || v.x > 1){ 332 | return false 333 | } 334 | if (v.y < -1 || v.y > 1){ 335 | return false 336 | } 337 | if (v.z < -1 || v.z > 1){ 338 | return false 339 | } 340 | return true 341 | } 342 | 343 | protected convertToScreenPos(v:Vector4, dst:Vector4, width:number, height:number){ 344 | dst.x = (v.x + 1)/2 * width 345 | dst.y = (v.y + 1)/2 * height 346 | dst.z = v.z 347 | return dst 348 | } 349 | } 350 | 351 | -------------------------------------------------------------------------------- /src/core/shading/buffer.ts: -------------------------------------------------------------------------------- 1 | import { Color } from "./color" 2 | 3 | export default class Buffer { 4 | public usingMSAA:boolean = true 5 | protected width:number 6 | protected height:number 7 | protected zbuf:Float32Array = null 8 | public frameBuffer:Uint8Array 9 | protected msaaColorBuffer:Uint8Array = null 10 | public constructor(width:number, height:number, usingMSAA:boolean) { 11 | this.usingMSAA = usingMSAA 12 | this.width = width 13 | this.height = height 14 | 15 | this.frameBuffer = new Uint8Array(width*height*4) 16 | 17 | if (!this.usingMSAA){ 18 | this.zbuf = new Float32Array(width*height) 19 | } else { 20 | this.zbuf = new Float32Array(width*height*4) 21 | this.msaaColorBuffer = new Uint8Array(width*height*4*4) 22 | } 23 | } 24 | 25 | 26 | protected getZPos(x:number, y:number, index:number) { 27 | if (!this.usingMSAA) { 28 | return this.width * y + x 29 | } else { 30 | return (this.width * y + x)*4 + index 31 | } 32 | } 33 | public ztest(x:number, y:number, rhw:number, index:number=0):boolean{ 34 | let zPos = this.getZPos(x, y, index) 35 | if (isNaN(this.zbuf[zPos]) || this.zbuf[zPos] > rhw) { 36 | return true 37 | } 38 | return false 39 | } 40 | 41 | public setZ(x:number, y:number, rhw:number, index:number=0){ 42 | let zPos = this.getZPos(x, y, index) 43 | this.zbuf[zPos] = rhw 44 | } 45 | 46 | public setColor(x:number, y:number, color:Color, index:number=0){ 47 | if (!this.usingMSAA) { 48 | this.setFrameBufferPixel(x, y, color) 49 | }else { 50 | let pstart = (this.width*y + x)*4*4 + index*4 51 | this.msaaColorBuffer[pstart] = color.r 52 | this.msaaColorBuffer[pstart+1] = color.g 53 | this.msaaColorBuffer[pstart+2] = color.b 54 | this.msaaColorBuffer[pstart+3] = color.a 55 | } 56 | } 57 | 58 | protected setFrameBufferPixel(x:number, y:number, color:Color) { 59 | let pstart = (this.width*y + x)*4 60 | this.frameBuffer[pstart] = color.r 61 | this.frameBuffer[pstart+1] = color.g 62 | this.frameBuffer[pstart+2] = color.b 63 | this.frameBuffer[pstart+3] = 255 64 | //using default blend? 65 | // let a = color.a/255 66 | // this.frameBuffer[pstart] = color.r*a + this.frameBuffer[pstart]*(1-a) 67 | // this.frameBuffer[pstart+1] = color.g*a + this.frameBuffer[pstart+1]*(1-a) 68 | // this.frameBuffer[pstart+2] = color.b*a + this.frameBuffer[pstart+2]*(1-a) 69 | // this.frameBuffer[pstart+3] = 255//color.a 70 | } 71 | 72 | public clear(backgroundColor:Color) { 73 | for (let l=0;l> = [] 11 | 12 | public createFromFile(file:string) { 13 | let objContent = fs.readFileSync(path.join(__dirname, "../../../res/" + file), "utf8") 14 | this.triangles = [] 15 | 16 | let lines:Array = objContent.split(/\r\n|\n/) 17 | let vList:Array =[] 18 | let uvList:Array =[] 19 | let normalList:Array =[] 20 | let faceList:Array =[] 21 | 22 | for (let line of lines) { 23 | if (line != ""){ 24 | if (line.charAt(0) == "#"){ 25 | continue 26 | } 27 | let vals = line.split(/\s+/) 28 | let t = vals[0] 29 | if (t == "v" && vals.length>=4) { 30 | vList.push(new Vector4(parseFloat(vals[1]),parseFloat(vals[2]), parseFloat(vals[3]))) 31 | } else if (t == "vt" && vals.length>=3) { 32 | uvList.push(new Vector2(parseFloat(vals[1]), parseFloat(vals[2])) ) 33 | }else if (t == "vn" && vals.length>=4) { 34 | normalList.push(new Vector4(parseFloat(vals[1]),parseFloat(vals[2]), parseFloat(vals[3]))) 35 | }else if (t == "f" && vals.length>=4) { 36 | let fvals = [ 37 | vals[1].split("/"), 38 | vals[2].split("/"), 39 | vals[3].split("/"), 40 | ] 41 | faceList.push(fvals) //v/vt/vn index 42 | } 43 | } 44 | } 45 | 46 | for (let f of faceList){ 47 | let v1s = f[0] 48 | let v2s = f[1] 49 | let v3s = f[2] 50 | // vertex/uv/normal 51 | let v1 = vList[ parseInt(v1s[0]) -1 ] 52 | let v2 = vList[ parseInt(v2s[0]) -1 ] 53 | let v3 = vList[ parseInt(v3s[0]) -1 ] 54 | 55 | let uv1 = uvList[ parseInt(v1s[1]) -1 ] 56 | let uv2 = uvList[ parseInt(v2s[1]) -1 ] 57 | let uv3 = uvList[ parseInt(v3s[1]) -1 ] 58 | 59 | let n1 = normalList[ parseInt(v1s[2]) -1 ] 60 | let n2 = normalList[ parseInt(v2s[2]) -1 ] 61 | let n3 = normalList[ parseInt(v3s[2]) -1 ] 62 | 63 | this.triangles.push([ 64 | {posModel:v1, color:Color.WHITE, uv:uv1, normal:n1}, 65 | {posModel:v2, color:Color.WHITE, uv:uv2, normal:n2}, 66 | {posModel:v3, color:Color.WHITE, uv:uv3, normal:n3}, 67 | ]) 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /src/core/shading/shader.ts: -------------------------------------------------------------------------------- 1 | import { Matrix } from "../math/matrix"; 2 | import { Vector2 } from "../math/vector2"; 3 | import { Vector4 } from "../math/vector4"; 4 | import { Color } from "./color"; 5 | import { Vertex } from "./vertex"; 6 | 7 | export interface VertexInput { 8 | viewProject:Matrix 9 | } 10 | 11 | export interface FragmentInput { 12 | x:number, //屏幕坐标 13 | y:number, 14 | color?:Color, 15 | varyingVec2Dict?:{[k:string]:Vector2}, //需要插值的所有vec2 16 | varyingVec4Dict?:{[k:string]:Vector4} //需要插值的所有vec4 17 | } 18 | 19 | export interface IShaderProgram { 20 | vertexShading(vertex:Vertex, input:VertexInput):Vector4; 21 | fragmentShading(context:FragmentInput):Color; 22 | } 23 | 24 | export class ShaderVarying { 25 | public static NORMAL = "normal" 26 | public static UV = "uv" 27 | public static EYE = "eye" 28 | public static WORLD_POS = "world_pos" 29 | 30 | } 31 | 32 | export default class Shader { 33 | protected program:IShaderProgram 34 | protected vertexInput: VertexInput 35 | public constructor(program:IShaderProgram){ 36 | this.program = program 37 | this.vertexInput = {viewProject:null} 38 | } 39 | 40 | public setViewProject(vp:Matrix) { 41 | this.vertexInput.viewProject = vp 42 | } 43 | 44 | public vertexShading(vertex:Vertex):Vector4 { 45 | return this.program.vertexShading(vertex, this.vertexInput) 46 | } 47 | 48 | public fragmentShading(input:FragmentInput):Color{ 49 | return this.program.fragmentShading(input) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/core/shading/texture.ts: -------------------------------------------------------------------------------- 1 | import { Vector2 } from "../math/vector2" 2 | import { Vector4 } from "../math/vector4" 3 | import { Color } from "./color" 4 | import fs = require("fs") 5 | import path = require("path") 6 | let decode = require('image-decode') 7 | 8 | export enum TEXTURE_FILTER_MODE { 9 | NEAREST = 1, 10 | BILINEAR = 2, 11 | } 12 | export default class Texture { 13 | public width:number 14 | public height:number 15 | public data:Array = [] 16 | protected tmp:Color = new Color() 17 | 18 | public filterMode:TEXTURE_FILTER_MODE = TEXTURE_FILTER_MODE.BILINEAR 19 | 20 | public static createTextureFromFile(file:string) { 21 | let {data, width, height} = decode(fs.readFileSync(path.join(__dirname, "../../../res/" + file))) 22 | let texture = new Texture(width, height) 23 | for (let y=0;y max){ 57 | return max 58 | } 59 | if (value < min) { 60 | return min 61 | } 62 | return value 63 | } 64 | 65 | protected getPixel(x:number, y:number){ 66 | return this.data[y *this.width + x] 67 | } 68 | 69 | protected samplePos(x:number, y:number):Color{ 70 | if (this.filterMode == TEXTURE_FILTER_MODE.NEAREST) { 71 | x = this.clamp(Math.floor(x), 0, this.width-1) 72 | y = this.clamp(Math.floor(y), 0, this.height-1) 73 | let color = this.getPixel(x, y) 74 | this.tmp.a = color.a 75 | this.tmp.r = color.r 76 | this.tmp.g = color.g 77 | this.tmp.b = color.b 78 | return this.tmp 79 | } else if (this.filterMode == TEXTURE_FILTER_MODE.BILINEAR) { 80 | //双线性插值有大量的浮点运算,在opencv这些框架中会使用整数乘法来优化浮点数运算,我们这里仍旧使用浮点运算 81 | let x1 = this.clamp(Math.floor(x), 0, this.width-1) 82 | let y1 = this.clamp(Math.floor(y), 0, this.height-1) 83 | let x2 = this.clamp(Math.floor(x)+1, 0, this.width-1) 84 | let y2 = this.clamp(Math.floor(y)+1, 0, this.height-1) 85 | let c1 = this.getPixel(x1, y1) 86 | let c2 = this.getPixel(x2, y1) 87 | let c3 = this.getPixel(x1, y2) 88 | let c4 = this.getPixel(x2, y2) 89 | let dx = x - x1 90 | let dy = y - y1 91 | //先在X方向上做2次线性插值,然后在y方向上做一次线性插值 92 | //求得公式 (c1*(1-dx) + c2*dx)(1-dy) + (c3*(1-dx) + c4*dx)*dy 93 | //c1*(1-dx)*(1-dy) + c2* (dx)*(1-dy) + c3* (1-dx)*dy + c4* (dx)*dy 94 | //正好是四个权重w1, w2, w3, w4 95 | let w1 = (1-dx)*(1-dy) 96 | let w2 = dx*(1-dy) 97 | let w3 = (1-dx)*dy 98 | let w4 = dx*dy 99 | Color.getBilinearColor(c1, c2, c3, c4, w1, w2, w3, w4, this.tmp) 100 | return this.tmp 101 | } 102 | 103 | return Color.BLACK 104 | } 105 | 106 | 107 | } 108 | -------------------------------------------------------------------------------- /src/core/shading/vertex.ts: -------------------------------------------------------------------------------- 1 | import { Vector2 } from "../math/vector2"; 2 | import { Vector4 } from "../math/vector4"; 3 | import { Color } from "./color"; 4 | 5 | export interface VertexContext { 6 | posProject:Vector4//冗余字段, 投影坐标, 变换计算时不要修改pos的值, 结果都存储在posTransform里 7 | posScreen:Vector4//冗余字段, 屏幕坐标 8 | rhw:number // 1/w 9 | varyingVec2Dict:{[k:string]:Vector2}, //需要插值的所有vec2 10 | varyingVec4Dict:{[k:string]:Vector4} //需要插值的所有vec4 11 | } 12 | 13 | export interface Vertex { 14 | posModel?:Vector4, 15 | color?:Color,//default White 16 | uv?:Vector2, 17 | normal?:Vector4, 18 | context?:VertexContext 19 | } 20 | -------------------------------------------------------------------------------- /src/examples/draw-box.ts: -------------------------------------------------------------------------------- 1 | import { Vector4 } from "../core/math/vector4" 2 | import { Color} from "../core/shading/color" 3 | import Shader, { FragmentInput, ShaderVarying, VertexInput } from "../core/shading/shader" 4 | import Texture from "../core/shading/texture" 5 | import { Vertex } from "../core/shading/vertex" 6 | import Raster from "../core/raster" 7 | import { IExample } from "../app" 8 | import { Vector2 } from "../core/math/vector2" 9 | 10 | import InputHandler from "../web/input-handler" 11 | import MathUtils from "../core/math/math-utils" 12 | import { Matrix } from "../core/math/matrix" 13 | 14 | export default class DrawBox implements IExample{ 15 | protected texture:Texture 16 | protected renderer:Raster 17 | 18 | protected fovy:number = Math.PI / 2 19 | protected eye:Vector4 = new Vector4(1.5, 0, 2.5, 1) 20 | protected inputHandler:InputHandler 21 | 22 | public constructor(renderer:Raster) { 23 | this.texture = this.createTexture() 24 | this.renderer = renderer 25 | this.inputHandler = new InputHandler(this) 26 | this.init() 27 | } 28 | 29 | protected setCamera() { 30 | let at = new Vector4(0, 0, 0, 1) 31 | let up = new Vector4(0, 1, 0, 1) 32 | let aspect = this.renderer.width / this.renderer.height 33 | let near = 1 34 | let far = 500 35 | this.renderer.setCamera(this.eye, at, up, this.fovy, aspect, near, far) 36 | } 37 | 38 | protected init() { 39 | this.setCamera() 40 | 41 | this.renderer.setBackgroundColor(Color.GRAY) 42 | let texture = this.texture 43 | let shader:Shader = new Shader( 44 | { 45 | vertexShading: function(vertex:Vertex, input:VertexInput):Vector4{ 46 | vertex.posModel.transform(input.viewProject, vertex.context.posProject) 47 | vertex.context.varyingVec2Dict[ShaderVarying.UV] = vertex.uv 48 | return vertex.context.posProject 49 | }, 50 | fragmentShading: function(input:FragmentInput):Color { 51 | let tex = texture.sample(input.varyingVec2Dict[ShaderVarying.UV]) 52 | return Color.multiplyColor(tex, input.color, tex) 53 | } 54 | } 55 | ) 56 | this.renderer.setShader(shader) 57 | } 58 | 59 | public draw() :void{ 60 | let va:Array = [ 61 | new Vector4(-1,-1,1), 62 | new Vector4(1,-1,1), 63 | new Vector4(1,1,1), 64 | new Vector4(-1,1,1), 65 | new Vector4(-1,-1,-1), 66 | new Vector4(1,-1,-1), 67 | new Vector4(1,1,-1), 68 | new Vector4(-1,1,-1), 69 | ] //立方体8个顶点 70 | 71 | let elements = [ 72 | 0, 1, 2, //front 73 | 2, 3, 0, 74 | 7, 6, 5, //back 75 | 5, 4, 7, 76 | 0, 4, 5, //bottom 77 | 5, 1, 0, 78 | 1, 5, 6, //right 79 | 6, 2, 1, 80 | 2, 6, 7, //top 81 | 7, 3, 2, 82 | 3, 7, 4, //left 83 | 4, 0, 3, 84 | ] //24个三角形,立方体外表面 85 | 86 | let uv00 = new Vector2(0, 0) 87 | let uv10 = new Vector2(1, 0) 88 | let uv11 = new Vector2(1, 1) 89 | let uv01 = new Vector2(0, 1) 90 | for (let e=0;e0 ?0.05:-0.05), Math.PI/6, Math.PI*2/3) 110 | this.setCamera() 111 | } 112 | 113 | public onMove(dx:number, dy:number) { 114 | let angleX = -dx/30 * Math.PI/180*10 115 | let angleY = -dy/30 * Math.PI/180*10 116 | 117 | let mat1 = new Matrix() 118 | mat1.setRotateY(angleX) 119 | 120 | let mat2 = new Matrix() 121 | mat2.setRotateX(angleY) 122 | this.eye.transform(mat1.multiply(mat2), this.eye) 123 | 124 | this.setCamera() 125 | } 126 | } -------------------------------------------------------------------------------- /src/examples/draw-mesh.ts: -------------------------------------------------------------------------------- 1 | import { Vector4 } from "../core/math/vector4" 2 | import { Color } from "../core/shading/color" 3 | import Texture from "../core/shading/texture" 4 | import { Vertex } from "../core/shading/vertex" 5 | import Raster from "../core/raster" 6 | import { IExample } from "../app" 7 | import Shader, { VertexInput, FragmentInput, ShaderVarying } from "../core/shading/shader" 8 | import { Vector2 } from "../core/math/vector2" 9 | 10 | 11 | import { Matrix } from "../core/math/matrix" 12 | 13 | 14 | import MathUtils from "../core/math/math-utils" 15 | import Model from "../core/shading/model" 16 | 17 | 18 | 19 | import InputHandler from "../web/input-handler" 20 | 21 | 22 | 23 | export default class DrawMesh implements IExample{ 24 | protected renderer:Raster 25 | 26 | protected model:Model 27 | protected diffuseTexture:Texture 28 | protected normalTexture:Texture 29 | protected specTexture:Texture 30 | // protected usingTangentNormal:boolean=true//normal图是切线空间还是模型空间? 31 | 32 | protected inputHandler:InputHandler 33 | 34 | protected fovy:number = Math.PI / 4 35 | protected eye:Vector4 = new Vector4(1, 1, 3, 1) 36 | protected modelMatrix = new Matrix() 37 | 38 | 39 | public constructor(renderer:Raster) { 40 | this.renderer = renderer 41 | this.inputHandler = new InputHandler(this) 42 | 43 | this.init() 44 | } 45 | 46 | protected setCamera() { 47 | let at = new Vector4(0, 0, 0, 1) 48 | let up = new Vector4(0, 1, 0, 1) 49 | let aspect = this.renderer.width / this.renderer.height 50 | let near = 1 51 | let far = 500 52 | this.renderer.setCamera(this.eye, at, up, this.fovy, aspect, near, far) 53 | } 54 | 55 | protected init() { 56 | this.setCamera() 57 | this.renderer.setBackgroundColor(Color.GRAY) 58 | this.loadObj() 59 | this.loadTextures() 60 | 61 | //shader 62 | let lightDir:Vector4 = (new Vector4(1, 1, 1)).normalize() 63 | let diffuseTexture = this.diffuseTexture 64 | let normalTexture = this.normalTexture 65 | let specTexture = this.specTexture 66 | let fragColor:Color = new Color() 67 | let eye = this.eye 68 | let modelMatrix = this.modelMatrix 69 | let shader:Shader = new Shader( 70 | { 71 | vertexShading: function(vertex:Vertex, input:VertexInput):Vector4{ 72 | let posWorld = vertex.posModel.transform(modelMatrix) 73 | vertex.context.posProject = posWorld.transform(input.viewProject) 74 | vertex.context.varyingVec2Dict[ShaderVarying.UV] = vertex.uv 75 | vertex.context.varyingVec4Dict[ShaderVarying.WORLD_POS] = posWorld 76 | // vertex.context.varyingVec4Dict[ShaderVarying.NORMAL] = vertex.normal 77 | return vertex.context.posProject 78 | }, 79 | fragmentShading: function(input:FragmentInput):Color { 80 | let uv = input.varyingVec2Dict[ShaderVarying.UV] 81 | let diffuseColor = diffuseTexture.sample(uv) 82 | let normal = normalTexture.sampleAsVector(uv) 83 | let specFactor = specTexture.sample(uv).b 84 | let n:Vector4 = normal.normalize() 85 | let worldPos:Vector4 = input.varyingVec4Dict[ShaderVarying.WORLD_POS] 86 | 87 | //diffuse 88 | let diffuseIntense = MathUtils.saturate(n.dot(lightDir)) 89 | 90 | //高光 91 | let viewDir:Vector4 = eye.sub(worldPos).normalize() 92 | let halfDir:Vector4 = lightDir.add(viewDir).normalize() 93 | let specIntense = Math.pow( Math.max(0, n.dot(halfDir)), 5*specFactor) //*0.8 94 | 95 | let factor = diffuseIntense + specIntense 96 | let ambient = 5 97 | fragColor.set(diffuseColor).multiplyRGB(factor).add(ambient) 98 | fragColor.a = 255 99 | return fragColor 100 | } 101 | } 102 | ) 103 | this.renderer.setShader(shader) 104 | } 105 | 106 | protected loadTextures() { 107 | // import normalBuffer from '../../res/african_head_nm_tangent.png' 108 | // import objBuffer from 'raw-loader!../../res/diablo3_pose.obj' 109 | // import diffuseBuffer from '../../res/diablo3_pose_diffuse.png' 110 | // import normalBuffer from '../../res/diablo3_pose_nm.png' 111 | // import specBuffer from '../../res/diablo3_pose_spec.png' 112 | this.diffuseTexture = Texture.createTextureFromFile("african_head_diffuse.png") 113 | this.normalTexture = Texture.createTextureFromFile("african_head_nm.png") 114 | this.specTexture = Texture.createTextureFromFile("african_head_spec.png") 115 | } 116 | 117 | protected loadObj() { 118 | this.model = new Model() 119 | this.model.createFromFile("african_head.obj") 120 | } 121 | 122 | public draw() :void{ 123 | // this.modelMatrix = this.modelMatrix.multiply() 124 | let triangles = this.model.triangles 125 | for (let triangle of triangles) { 126 | this.renderer.drawTriangle(triangle) 127 | } 128 | } 129 | 130 | public onWheel(delta:number){ 131 | this.fovy = MathUtils.clamp(this.fovy + (delta >0 ?0.05:-0.05), Math.PI/6, Math.PI*2/3) 132 | this.setCamera() 133 | } 134 | 135 | public onMove(dx:number, dy:number) { 136 | let angleX = -dx/30 * Math.PI/180*10 137 | let angleY = -dy/30 * Math.PI/180*10 138 | 139 | let mat1 = new Matrix() 140 | mat1.setRotateY(angleX) 141 | 142 | let mat2 = new Matrix() 143 | mat2.setRotateX(angleY) 144 | this.eye.transform(mat1.multiply(mat2), this.eye) 145 | 146 | this.setCamera() 147 | } 148 | 149 | } -------------------------------------------------------------------------------- /src/web/input-handler.ts: -------------------------------------------------------------------------------- 1 | import { IExample } from "../app"; 2 | 3 | export default class InputHandler { 4 | protected example:IExample 5 | protected isMouseDown:boolean = false 6 | protected lastMouseX:number 7 | protected lastMouseY:number 8 | public constructor(example:IExample) { 9 | let self = this 10 | this.example = example 11 | 12 | 13 | window.onmousedown = function(e:MouseEvent){ 14 | self.onMouseDown(e.clientX, e.clientY) 15 | } 16 | 17 | window.onmousemove = function(e:MouseEvent){ 18 | self.onMouseMove(e.clientX, e.clientY) 19 | } 20 | 21 | window.onmouseup = function(e:MouseEvent){ 22 | self.onMouseUp(e.clientX, e.clientY) 23 | } 24 | 25 | window.onmousewheel = function(e:any){ 26 | self.onMouseWheel(e.deltaY) 27 | } 28 | } 29 | 30 | protected onMouseDown(x:number, y:number){ 31 | this.isMouseDown = true 32 | this.lastMouseX = x 33 | this.lastMouseY = y 34 | } 35 | 36 | protected onMouseMove(x:number, y:number){ 37 | if (this.isMouseDown) { 38 | let deltaX = x - this.lastMouseX 39 | let deltaY = y - this.lastMouseY 40 | this.example.onMove(deltaX, deltaY) 41 | this.lastMouseY = y 42 | this.lastMouseX = x 43 | } 44 | 45 | } 46 | 47 | protected onMouseUp(x:number, y:number){ 48 | this.isMouseDown = false 49 | } 50 | 51 | protected onMouseWheel(delta:number){ 52 | if (this.example.onWheel) { 53 | this.example.onWheel(delta) 54 | } 55 | } 56 | 57 | } 58 | 59 | 60 | -------------------------------------------------------------------------------- /src/web/webgl-blitter.ts: -------------------------------------------------------------------------------- 1 | 2 | export class WebGLBlitter { 3 | protected gl:any 4 | protected shaderProgram:any 5 | protected u_Sampler:any 6 | protected canvasTexture:any 7 | protected vertexsBuffer:any 8 | constructor(gl:any) { 9 | this.gl = gl 10 | 11 | this.initShader(); 12 | this.initTexture(); 13 | this.initGeometry(); 14 | } 15 | 16 | 17 | 18 | protected initTexture() { 19 | let gl = this.gl 20 | 21 | this.canvasTexture = gl.createTexture(); 22 | 23 | gl.bindTexture(gl.TEXTURE_2D, this.canvasTexture); 24 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 25 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 26 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 27 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 28 | gl.bindTexture(gl.TEXTURE_2D, null); 29 | 30 | } 31 | 32 | protected initShader() { 33 | let gl = this.gl 34 | let vertexShaderSource = 35 | "attribute vec4 a_Position;" + 36 | "attribute vec2 a_TexCoord;" + 37 | "varying vec2 v_TexCoord;" + 38 | "void main(){" + 39 | "gl_Position = a_Position;" + 40 | "v_TexCoord = a_TexCoord;" + 41 | "}"; 42 | 43 | let fragmentShaderSource = 44 | "precision mediump float;" + 45 | " uniform sampler2D u_Sampler;" + 46 | " varying vec2 v_TexCoord;" + 47 | " void main(){" + 48 | " gl_FragColor = texture2D(u_Sampler, v_TexCoord);" + 49 | "}" 50 | //编译着色器 51 | var vertShader = gl.createShader(gl.VERTEX_SHADER); 52 | gl.shaderSource(vertShader, vertexShaderSource); 53 | gl.compileShader(vertShader); 54 | 55 | var fragShader = gl.createShader(gl.FRAGMENT_SHADER); 56 | gl.shaderSource(fragShader, fragmentShaderSource); 57 | gl.compileShader(fragShader); 58 | //合并程序 59 | this.shaderProgram = gl.createProgram(); 60 | gl.attachShader(this.shaderProgram, vertShader); 61 | gl.attachShader(this.shaderProgram, fragShader); 62 | gl.linkProgram(this.shaderProgram); 63 | 64 | this.u_Sampler = gl.getUniformLocation(this.shaderProgram, "u_Sampler"); 65 | } 66 | 67 | protected initGeometry() { 68 | let gl = this.gl 69 | var vertexs = new Float32Array([ 70 | -1, 1, 0.0, 0.0, 1.0, 71 | -1, -1, 0.0, 0.0, 0.0, 72 | 1, 1, 0.0, 1.0, 1.0, 73 | 1, -1, 0.0, 1.0, 0.0]); 74 | 75 | this.vertexsBuffer = gl.createBuffer(); 76 | 77 | if (this.vertexsBuffer === null) { 78 | console.log("vertexsBuffer is null"); 79 | return false; 80 | } 81 | gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexsBuffer); 82 | 83 | gl.bufferData(gl.ARRAY_BUFFER, vertexs, gl.STATIC_DRAW); 84 | 85 | let a_Position = gl.getAttribLocation(this.shaderProgram, "a_Position"); 86 | if (a_Position < 0) { 87 | console.log("a_Position < 0"); 88 | return false; 89 | } 90 | 91 | let a_TexCoord = gl.getAttribLocation(this.shaderProgram, "a_TexCoord"); 92 | if (a_TexCoord < 0) { 93 | console.log("a_TexCoord < 0"); 94 | return false; 95 | } 96 | 97 | //将顶点坐标的位置赋值 98 | gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, vertexs.BYTES_PER_ELEMENT * 5, 0); 99 | gl.enableVertexAttribArray(a_Position); 100 | 101 | //将纹理坐标赋值 102 | gl.vertexAttribPointer(a_TexCoord, 2, gl.FLOAT, false, vertexs.BYTES_PER_ELEMENT * 5, vertexs.BYTES_PER_ELEMENT * 3); 103 | gl.enableVertexAttribArray(a_TexCoord); 104 | } 105 | 106 | 107 | 108 | protected renderCanvas() { 109 | let gl = this.gl 110 | gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT); 111 | gl.useProgram(this.shaderProgram); 112 | gl.uniform1i(this.u_Sampler, 0); 113 | gl.activeTexture(this.gl.TEXTURE0); 114 | gl.bindTexture(this.gl.TEXTURE_2D, this.canvasTexture); 115 | gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4); 116 | } 117 | 118 | public blitPixels(width:number, height:number, pixels:Uint8Array) { 119 | //upload pixels 120 | this.gl.bindTexture(this.gl.TEXTURE_2D, this.canvasTexture); 121 | this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, width, height, 0, 122 | this.gl.RGBA, this.gl.UNSIGNED_BYTE, pixels); 123 | this.gl.bindTexture(this.gl.TEXTURE_2D, null); 124 | 125 | this.renderCanvas(); 126 | } 127 | 128 | 129 | } 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /tsc.bat: -------------------------------------------------------------------------------- 1 | node .\node_modules\typescript\bin\tsc -w -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "commonjs", 5 | "noImplicitAny": true, 6 | "removeComments": true, 7 | "sourceMap": false, 8 | "outDir": "./build-js" 9 | }, 10 | 11 | "exclude": [ 12 | "node_modules", 13 | "build-js", 14 | "run" 15 | ] 16 | 17 | } --------------------------------------------------------------------------------