Compare commits
2 Commits
Author | SHA1 | Date |
---|---|---|
|
129cf05b90 | |
|
3e9bdcc469 |
74
common.js
74
common.js
|
@ -1,74 +0,0 @@
|
||||||
function initializeContext(canvasId) {
|
|
||||||
const canvas = document.getElementById(canvasId);
|
|
||||||
const ctx = canvas.getContext("webgl2", { antialias: false });
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
class Vec2 {
|
|
||||||
x;
|
|
||||||
y;
|
|
||||||
constructor(x, y) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
}
|
|
||||||
add(other) {
|
|
||||||
this.x += other.x;
|
|
||||||
this.y += other.y;
|
|
||||||
}
|
|
||||||
addScalar(scalar) {
|
|
||||||
this.x += scalar;
|
|
||||||
this.y += scalar;
|
|
||||||
}
|
|
||||||
addNew(other) {
|
|
||||||
return new Vec2(this.x + other.x, this.y + other.y);
|
|
||||||
}
|
|
||||||
addScalarNew(scalar) {
|
|
||||||
return new Vec2(this.x + scalar, this.y + scalar);
|
|
||||||
}
|
|
||||||
sub(other) {
|
|
||||||
this.x -= other.x;
|
|
||||||
this.y -= other.y;
|
|
||||||
}
|
|
||||||
mult(scalar) {
|
|
||||||
this.x *= scalar;
|
|
||||||
this.y *= scalar;
|
|
||||||
}
|
|
||||||
multNew(scalar) {
|
|
||||||
return new Vec2(this.x * scalar, this.y * scalar);
|
|
||||||
}
|
|
||||||
splatToArray() {
|
|
||||||
return [this.x, this.y];
|
|
||||||
}
|
|
||||||
static angle(angle) {
|
|
||||||
const eps = 1e-6;
|
|
||||||
let x = Math.cos(angle);
|
|
||||||
let y = Math.sin(angle);
|
|
||||||
if ((x > 0 && x < eps)
|
|
||||||
|| (x < 0 && x > -eps))
|
|
||||||
x = 0;
|
|
||||||
if ((y > 0 && y < eps)
|
|
||||||
|| (y < 0 && y > -eps))
|
|
||||||
y = 0;
|
|
||||||
return new Vec2(x, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
class Vec3 {
|
|
||||||
x;
|
|
||||||
y;
|
|
||||||
z;
|
|
||||||
constructor(x, y, z) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.z = z;
|
|
||||||
}
|
|
||||||
add(other) {
|
|
||||||
this.x += other.x;
|
|
||||||
this.y += other.y;
|
|
||||||
this.z += other.z;
|
|
||||||
}
|
|
||||||
sub(other) {
|
|
||||||
this.x -= other.x;
|
|
||||||
this.y -= other.y;
|
|
||||||
this.z -= other.z;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export { initializeContext, Vec2, Vec3 };
|
|
96
common.ts
96
common.ts
|
@ -1,96 +0,0 @@
|
||||||
function initializeContext(canvasId: string): WebGL2RenderingContext | null {
|
|
||||||
const canvas = document.getElementById(canvasId) as HTMLCanvasElement;
|
|
||||||
const ctx = canvas.getContext("webgl2", {antialias: false});
|
|
||||||
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
type Color = [number, number, number, number]
|
|
||||||
|
|
||||||
class Vec2 {
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
|
|
||||||
constructor(x: number, y: number) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
add(other: Vec2) {
|
|
||||||
this.x += other.x;
|
|
||||||
this.y += other.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
addScalar(scalar: number) {
|
|
||||||
this.x += scalar;
|
|
||||||
this.y += scalar;
|
|
||||||
}
|
|
||||||
|
|
||||||
addNew(other: Vec2): Vec2 {
|
|
||||||
return new Vec2(this.x + other.x, this.y + other.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
addScalarNew(scalar: number): Vec2 {
|
|
||||||
return new Vec2(this.x + scalar, this.y + scalar);
|
|
||||||
}
|
|
||||||
|
|
||||||
sub(other: Vec2) {
|
|
||||||
this.x -= other.x;
|
|
||||||
this.y -= other.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
mult(scalar: number) {
|
|
||||||
this.x *= scalar;
|
|
||||||
this.y *= scalar;
|
|
||||||
}
|
|
||||||
|
|
||||||
multNew(scalar: number): Vec2 {
|
|
||||||
return new Vec2(this.x * scalar, this.y * scalar);
|
|
||||||
}
|
|
||||||
|
|
||||||
splatToArray(): Array<number> {
|
|
||||||
return [this.x, this.y];
|
|
||||||
}
|
|
||||||
|
|
||||||
static angle(angle: number): Vec2 {
|
|
||||||
const eps = 1e-6;
|
|
||||||
let x = Math.cos(angle);
|
|
||||||
let y = Math.sin(angle);
|
|
||||||
|
|
||||||
if ((x > 0 && x < eps)
|
|
||||||
|| (x < 0 && x > -eps))
|
|
||||||
x = 0;
|
|
||||||
|
|
||||||
if ((y > 0 && y < eps)
|
|
||||||
|| (y < 0 && y > -eps))
|
|
||||||
y = 0;
|
|
||||||
|
|
||||||
return new Vec2(x, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Vec3 {
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
z: number;
|
|
||||||
|
|
||||||
constructor(x: number, y: number, z: number) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.z = z;
|
|
||||||
}
|
|
||||||
|
|
||||||
add(other: Vec3) {
|
|
||||||
this.x += other.x;
|
|
||||||
this.y += other.y;
|
|
||||||
this.z += other.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub(other: Vec3) {
|
|
||||||
this.x -= other.x;
|
|
||||||
this.y -= other.y;
|
|
||||||
this.z -= other.z;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export { initializeContext, Vec2, Vec3, Color };
|
|
|
@ -6,7 +6,7 @@
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||||
<meta name="description" content="" />
|
<meta name="description" content="" />
|
||||||
<link rel="stylesheet" href="style.css"></link>
|
<link rel="stylesheet" href="style.css"></link>
|
||||||
<script type="module" src="script.js" defer> var exports = {}; </script>
|
<script type="module" src="src/js/script.js" defer> var exports = {}; </script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<canvas id="game"></canvas>
|
<canvas id="game"></canvas>
|
||||||
|
|
|
@ -0,0 +1,234 @@
|
||||||
|
function initializeContext(canvasId) {
|
||||||
|
const canvas = document.getElementById(canvasId);
|
||||||
|
const ctx = canvas.getContext("webgl2", { antialias: false });
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
class Vec2 {
|
||||||
|
x;
|
||||||
|
y;
|
||||||
|
constructor(x, y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
add(other) {
|
||||||
|
this.x += other.x;
|
||||||
|
this.y += other.y;
|
||||||
|
}
|
||||||
|
addScalar(scalar) {
|
||||||
|
this.x += scalar;
|
||||||
|
this.y += scalar;
|
||||||
|
}
|
||||||
|
addNew(other) {
|
||||||
|
return new Vec2(this.x + other.x, this.y + other.y);
|
||||||
|
}
|
||||||
|
addScalarNew(scalar) {
|
||||||
|
return new Vec2(this.x + scalar, this.y + scalar);
|
||||||
|
}
|
||||||
|
sub(other) {
|
||||||
|
this.x -= other.x;
|
||||||
|
this.y -= other.y;
|
||||||
|
}
|
||||||
|
mult(scalar) {
|
||||||
|
this.x *= scalar;
|
||||||
|
this.y *= scalar;
|
||||||
|
}
|
||||||
|
multNew(scalar) {
|
||||||
|
return new Vec2(this.x * scalar, this.y * scalar);
|
||||||
|
}
|
||||||
|
splatToArray() {
|
||||||
|
return [this.x, this.y];
|
||||||
|
}
|
||||||
|
static angle(angle) {
|
||||||
|
const eps = 1e-6;
|
||||||
|
let x = Math.cos(angle);
|
||||||
|
let y = Math.sin(angle);
|
||||||
|
if ((x > 0 && x < eps)
|
||||||
|
|| (x < 0 && x > -eps))
|
||||||
|
x = 0;
|
||||||
|
if ((y > 0 && y < eps)
|
||||||
|
|| (y < 0 && y > -eps))
|
||||||
|
y = 0;
|
||||||
|
return new Vec2(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class Vec3 {
|
||||||
|
x;
|
||||||
|
y;
|
||||||
|
z;
|
||||||
|
constructor(x, y, z) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
}
|
||||||
|
add(other) {
|
||||||
|
this.x += other.x;
|
||||||
|
this.y += other.y;
|
||||||
|
this.z += other.z;
|
||||||
|
}
|
||||||
|
sub(other) {
|
||||||
|
this.x -= other.x;
|
||||||
|
this.y -= other.y;
|
||||||
|
this.z -= other.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class Vec4 {
|
||||||
|
x;
|
||||||
|
y;
|
||||||
|
z;
|
||||||
|
w;
|
||||||
|
constructor(x, y, z, w) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.w = w;
|
||||||
|
}
|
||||||
|
add(other) {
|
||||||
|
this.x += other.x;
|
||||||
|
this.y += other.y;
|
||||||
|
this.z += other.z;
|
||||||
|
this.w += other.w;
|
||||||
|
}
|
||||||
|
sub(other) {
|
||||||
|
this.x -= other.x;
|
||||||
|
this.y -= other.y;
|
||||||
|
this.z -= other.z;
|
||||||
|
this.w -= other.w;
|
||||||
|
}
|
||||||
|
div(other) {
|
||||||
|
if (other.x == 0 ||
|
||||||
|
other.y == 0 ||
|
||||||
|
other.z == 0 ||
|
||||||
|
other.w == 0) {
|
||||||
|
throw new Error("Division by zero in Vec4");
|
||||||
|
}
|
||||||
|
this.x /= other.x;
|
||||||
|
this.y /= other.y;
|
||||||
|
this.z /= other.z;
|
||||||
|
this.w /= other.w;
|
||||||
|
}
|
||||||
|
divNew(other) {
|
||||||
|
if (other.x == 0 ||
|
||||||
|
other.y == 0 ||
|
||||||
|
other.z == 0 ||
|
||||||
|
other.w == 0) {
|
||||||
|
throw new Error("Division by zero in Vec4");
|
||||||
|
}
|
||||||
|
let vec = new Vec4(this.x, this.y, this.z, this.w);
|
||||||
|
vec.x /= other.x;
|
||||||
|
vec.y /= other.y;
|
||||||
|
vec.z /= other.z;
|
||||||
|
vec.w /= other.w;
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class Mat4 {
|
||||||
|
data;
|
||||||
|
constructor(i) {
|
||||||
|
if (i instanceof Float32Array) {
|
||||||
|
this.data = i;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (typeof (i) === 'number') {
|
||||||
|
this.data = new Float32Array(16).fill(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.data = new Float32Array(16);
|
||||||
|
}
|
||||||
|
static orthographic(left, right, bottom, top, near, far) {
|
||||||
|
let data = new Float32Array([
|
||||||
|
2 / (right - left), 0, 0, 0,
|
||||||
|
0, 2 / (top - bottom), 0, 0,
|
||||||
|
0, 0, -2 / (far - near), 0,
|
||||||
|
-(right + left) / (right - left),
|
||||||
|
-(top + bottom) / (top - bottom),
|
||||||
|
-(far + near) / (far - near),
|
||||||
|
1,
|
||||||
|
]);
|
||||||
|
return new Mat4(data);
|
||||||
|
}
|
||||||
|
static rotation_x(angle) {
|
||||||
|
let data = new Float32Array([
|
||||||
|
1, 0, 0, 0,
|
||||||
|
0, Math.cos(angle), -Math.sin(angle), 0,
|
||||||
|
0, Math.sin(angle), Math.cos(angle), 0,
|
||||||
|
0, 0, 0, 1,
|
||||||
|
]);
|
||||||
|
return new Mat4(data);
|
||||||
|
}
|
||||||
|
static rotation_y(angle) {
|
||||||
|
let data = new Float32Array([
|
||||||
|
Math.cos(angle), 0, Math.sin(angle), 0,
|
||||||
|
0, 1, 0, 0,
|
||||||
|
-Math.sin(angle), 0, Math.cos(angle), 0,
|
||||||
|
0, 0, 0, 1,
|
||||||
|
]);
|
||||||
|
return new Mat4(data);
|
||||||
|
}
|
||||||
|
static rotation_z(angle) {
|
||||||
|
let data = new Float32Array([
|
||||||
|
Math.cos(angle), -Math.sin(angle), 0, 0,
|
||||||
|
Math.sin(angle), Math.cos(angle), 0, 0,
|
||||||
|
0, 0, 1, 0,
|
||||||
|
0, 0, 0, 1,
|
||||||
|
]);
|
||||||
|
return new Mat4(data);
|
||||||
|
}
|
||||||
|
x(n) {
|
||||||
|
return this.data[n];
|
||||||
|
}
|
||||||
|
y(n) {
|
||||||
|
return this.data[n + 4];
|
||||||
|
}
|
||||||
|
z(n) {
|
||||||
|
return this.data[n + 8];
|
||||||
|
}
|
||||||
|
w(n) {
|
||||||
|
return this.data[n + 12];
|
||||||
|
}
|
||||||
|
splat() {
|
||||||
|
return Array.from(this.data);
|
||||||
|
}
|
||||||
|
row(row, data) {
|
||||||
|
for (let i = 0; i < data.length; ++i)
|
||||||
|
this.data[i + 4 * row] = data[i];
|
||||||
|
}
|
||||||
|
col(col, data) {
|
||||||
|
for (let i = 0; i < data.length; ++i)
|
||||||
|
this.data[i * 4 + col] = data[i];
|
||||||
|
}
|
||||||
|
transform(v) {
|
||||||
|
let x = v.x * this.x(0) + v.x * this.x(1) + v.x * this.x(2) + v.x * this.x(3);
|
||||||
|
let y = v.y * this.y(0) + v.y * this.y(1) + v.y * this.y(2) + v.y * this.y(3);
|
||||||
|
let z = v.z * this.z(0) + v.z * this.z(1) + v.z * this.z(2) + v.z * this.z(3);
|
||||||
|
let w = v.w * this.w(0) + v.w * this.w(1) + v.w * this.w(2) + v.w * this.w(3);
|
||||||
|
v.x = x;
|
||||||
|
v.y = y;
|
||||||
|
v.z = z;
|
||||||
|
v.w = w;
|
||||||
|
}
|
||||||
|
transformNew(v) {
|
||||||
|
let vec = new Vec4(v.x, v.y, v.z, v.w);
|
||||||
|
let x = v.x * this.x(0) + v.y * this.x(1) + v.z * this.x(2) + v.w * this.x(3);
|
||||||
|
let y = v.x * this.y(0) + v.y * this.y(1) + v.z * this.y(2) + v.w * this.y(3);
|
||||||
|
let z = v.x * this.z(0) + v.y * this.z(1) + v.z * this.z(2) + v.w * this.z(3);
|
||||||
|
let w = v.x * this.w(0) + v.y * this.w(1) + v.z * this.w(2) + v.w * this.w(3);
|
||||||
|
vec.x = x;
|
||||||
|
vec.y = y;
|
||||||
|
vec.z = z;
|
||||||
|
vec.w = w;
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
mult(other) {
|
||||||
|
let m = new Mat4(0);
|
||||||
|
for (let i = 0; i < 4; ++i) {
|
||||||
|
for (let j = 0; j < 4; ++j) {
|
||||||
|
m.data[(i * 4) + j] += this.data[(i * 4) + 0] * other.data[j + 0];
|
||||||
|
m.data[(i * 4) + j] += this.data[(i * 4) + 1] * other.data[j + 4];
|
||||||
|
m.data[(i * 4) + j] += this.data[(i * 4) + 2] * other.data[j + 8];
|
||||||
|
m.data[(i * 4) + j] += this.data[(i * 4) + 3] * other.data[j + 12];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export { initializeContext, Mat4, Vec2, Vec3, Vec4 };
|
|
@ -0,0 +1,304 @@
|
||||||
|
function initializeContext(canvasId: string): WebGL2RenderingContext | null {
|
||||||
|
const canvas = document.getElementById(canvasId) as HTMLCanvasElement;
|
||||||
|
const ctx = canvas.getContext("webgl2", {antialias: false});
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Color = [number, number, number, number]
|
||||||
|
|
||||||
|
class Vec2 {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
|
||||||
|
constructor(x: number, y: number) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
add(other: Vec2) {
|
||||||
|
this.x += other.x;
|
||||||
|
this.y += other.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
addScalar(scalar: number) {
|
||||||
|
this.x += scalar;
|
||||||
|
this.y += scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
addNew(other: Vec2): Vec2 {
|
||||||
|
return new Vec2(this.x + other.x, this.y + other.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
addScalarNew(scalar: number): Vec2 {
|
||||||
|
return new Vec2(this.x + scalar, this.y + scalar);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub(other: Vec2) {
|
||||||
|
this.x -= other.x;
|
||||||
|
this.y -= other.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
mult(scalar: number) {
|
||||||
|
this.x *= scalar;
|
||||||
|
this.y *= scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
multNew(scalar: number): Vec2 {
|
||||||
|
return new Vec2(this.x * scalar, this.y * scalar);
|
||||||
|
}
|
||||||
|
|
||||||
|
splatToArray(): Array<number> {
|
||||||
|
return [this.x, this.y];
|
||||||
|
}
|
||||||
|
|
||||||
|
static angle(angle: number): Vec2 {
|
||||||
|
const eps = 1e-6;
|
||||||
|
let x = Math.cos(angle);
|
||||||
|
let y = Math.sin(angle);
|
||||||
|
|
||||||
|
if ((x > 0 && x < eps)
|
||||||
|
|| (x < 0 && x > -eps))
|
||||||
|
x = 0;
|
||||||
|
|
||||||
|
if ((y > 0 && y < eps)
|
||||||
|
|| (y < 0 && y > -eps))
|
||||||
|
y = 0;
|
||||||
|
|
||||||
|
return new Vec2(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Vec3 {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
z: number;
|
||||||
|
|
||||||
|
constructor(x: number, y: number, z: number) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
add(other: Vec3) {
|
||||||
|
this.x += other.x;
|
||||||
|
this.y += other.y;
|
||||||
|
this.z += other.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub(other: Vec3) {
|
||||||
|
this.x -= other.x;
|
||||||
|
this.y -= other.y;
|
||||||
|
this.z -= other.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Vec4 {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
z: number;
|
||||||
|
w: number;
|
||||||
|
|
||||||
|
constructor(x: number, y: number, z: number, w: number) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.w = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
add(other: Vec4) {
|
||||||
|
this.x += other.x;
|
||||||
|
this.y += other.y;
|
||||||
|
this.z += other.z;
|
||||||
|
this.w += other.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub(other: Vec4) {
|
||||||
|
this.x -= other.x;
|
||||||
|
this.y -= other.y;
|
||||||
|
this.z -= other.z;
|
||||||
|
this.w -= other.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
div(other: Vec4) {
|
||||||
|
if ( other.x == 0 ||
|
||||||
|
other.y == 0 ||
|
||||||
|
other.z == 0 ||
|
||||||
|
other.w == 0)
|
||||||
|
{
|
||||||
|
throw new Error("Division by zero in Vec4");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.x /= other.x;
|
||||||
|
this.y /= other.y;
|
||||||
|
this.z /= other.z;
|
||||||
|
this.w /= other.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
divNew(other: Vec4): Vec4 {
|
||||||
|
if ( other.x == 0 ||
|
||||||
|
other.y == 0 ||
|
||||||
|
other.z == 0 ||
|
||||||
|
other.w == 0)
|
||||||
|
{
|
||||||
|
throw new Error("Division by zero in Vec4");
|
||||||
|
}
|
||||||
|
|
||||||
|
let vec = new Vec4(this.x, this.y, this.z, this.w);
|
||||||
|
|
||||||
|
vec.x /= other.x;
|
||||||
|
vec.y /= other.y;
|
||||||
|
vec.z /= other.z;
|
||||||
|
vec.w /= other.w;
|
||||||
|
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Mat4Init = number | Float32Array;
|
||||||
|
|
||||||
|
type Mat4Row = 0 | 1 | 2 | 3
|
||||||
|
type Mat4Col = Mat4Row
|
||||||
|
type Mat4X = Mat4Row
|
||||||
|
type Mat4Y = Mat4Row
|
||||||
|
type Mat4Z = Mat4Row
|
||||||
|
type Mat4W = Mat4Row
|
||||||
|
|
||||||
|
class Mat4 {
|
||||||
|
data: Float32Array;
|
||||||
|
|
||||||
|
constructor(i: Mat4Init) {
|
||||||
|
if (i instanceof Float32Array) {
|
||||||
|
this.data = i;
|
||||||
|
return;
|
||||||
|
} else if (typeof(i) === 'number') {
|
||||||
|
this.data = new Float32Array(16).fill(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.data = new Float32Array(16);
|
||||||
|
}
|
||||||
|
|
||||||
|
static orthographic(left: number, right: number, bottom: number, top: number, near: number, far: number): Mat4 {
|
||||||
|
let data = new Float32Array([
|
||||||
|
2 / (right - left), 0, 0, 0,
|
||||||
|
0, 2 / (top - bottom), 0, 0,
|
||||||
|
0, 0, -2 / (far - near), 0,
|
||||||
|
|
||||||
|
-(right + left)/(right - left),
|
||||||
|
-(top + bottom)/(top - bottom),
|
||||||
|
-(far + near)/(far - near),
|
||||||
|
1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return new Mat4(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static rotation_x(angle: number): Mat4 {
|
||||||
|
let data = new Float32Array([
|
||||||
|
1, 0, 0, 0,
|
||||||
|
0, Math.cos(angle), -Math.sin(angle), 0,
|
||||||
|
0, Math.sin(angle), Math.cos(angle), 0,
|
||||||
|
0, 0, 0, 1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return new Mat4(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static rotation_y(angle: number): Mat4 {
|
||||||
|
let data = new Float32Array([
|
||||||
|
Math.cos(angle), 0, Math.sin(angle), 0,
|
||||||
|
0, 1, 0, 0,
|
||||||
|
-Math.sin(angle), 0, Math.cos(angle), 0,
|
||||||
|
0, 0, 0, 1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return new Mat4(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static rotation_z(angle: number): Mat4 {
|
||||||
|
let data = new Float32Array([
|
||||||
|
Math.cos(angle), -Math.sin(angle), 0, 0,
|
||||||
|
Math.sin(angle), Math.cos(angle), 0, 0,
|
||||||
|
0, 0, 1, 0,
|
||||||
|
0, 0, 0, 1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return new Mat4(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
x(n: Mat4X) {
|
||||||
|
return this.data[n];
|
||||||
|
}
|
||||||
|
|
||||||
|
y(n: Mat4Y) {
|
||||||
|
return this.data[n + 4];
|
||||||
|
}
|
||||||
|
|
||||||
|
z(n: Mat4Z) {
|
||||||
|
return this.data[n + 8];
|
||||||
|
}
|
||||||
|
|
||||||
|
w(n: Mat4W) {
|
||||||
|
return this.data[n + 12];
|
||||||
|
}
|
||||||
|
|
||||||
|
splat() {
|
||||||
|
return Array.from(this.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
row(row: Mat4Row, data: [number, number, number, number]) {
|
||||||
|
for (let i = 0; i < data.length; ++i)
|
||||||
|
this.data[i + 4 * row] = data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
col(col: Mat4Col, data: [number, number, number, number]) {
|
||||||
|
for (let i = 0; i < data.length; ++i)
|
||||||
|
this.data[i*4 + col] = data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
transform(v: Vec4) {
|
||||||
|
let x = v.x * this.x(0) + v.x * this.x(1) + v.x * this.x(2) + v.x * this.x(3);
|
||||||
|
let y = v.y * this.y(0) + v.y * this.y(1) + v.y * this.y(2) + v.y * this.y(3);
|
||||||
|
let z = v.z * this.z(0) + v.z * this.z(1) + v.z * this.z(2) + v.z * this.z(3);
|
||||||
|
let w = v.w * this.w(0) + v.w * this.w(1) + v.w * this.w(2) + v.w * this.w(3);
|
||||||
|
|
||||||
|
v.x = x;
|
||||||
|
v.y = y;
|
||||||
|
v.z = z;
|
||||||
|
v.w = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
transformNew(v: Vec4): Vec4 {
|
||||||
|
let vec = new Vec4(v.x, v.y, v.z, v.w);
|
||||||
|
|
||||||
|
let x = v.x * this.x(0) + v.y * this.x(1) + v.z * this.x(2) + v.w * this.x(3);
|
||||||
|
let y = v.x * this.y(0) + v.y * this.y(1) + v.z * this.y(2) + v.w * this.y(3);
|
||||||
|
let z = v.x * this.z(0) + v.y * this.z(1) + v.z * this.z(2) + v.w * this.z(3);
|
||||||
|
let w = v.x * this.w(0) + v.y * this.w(1) + v.z * this.w(2) + v.w * this.w(3);
|
||||||
|
|
||||||
|
vec.x = x;
|
||||||
|
vec.y = y;
|
||||||
|
vec.z = z;
|
||||||
|
vec.w = w;
|
||||||
|
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
mult(other: Mat4): Mat4 {
|
||||||
|
let m = new Mat4(0);
|
||||||
|
|
||||||
|
for (let i = 0; i < 4; ++i) {
|
||||||
|
for (let j = 0; j < 4; ++j) {
|
||||||
|
m.data[(i * 4) + j] += this.data[(i * 4) + 0] * other.data[j + 0]
|
||||||
|
m.data[(i * 4) + j] += this.data[(i * 4) + 1] * other.data[j + 4]
|
||||||
|
m.data[(i * 4) + j] += this.data[(i * 4) + 2] * other.data[j + 8]
|
||||||
|
m.data[(i * 4) + j] += this.data[(i * 4) + 3] * other.data[j + 12]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { initializeContext, Mat4, Vec2, Vec3, Vec4, Color };
|
|
@ -1,6 +1,5 @@
|
||||||
import { Vec2 } from "./common.js"
|
import { Vec2, Color } from "./common.js"
|
||||||
import { Graphics } from "./graphics.js";
|
import { Graphics } from "./graphics.js";
|
||||||
import { Color } from "./common.js";
|
|
||||||
|
|
||||||
function drawTriangle(gfx: Graphics, positions: [Vec2, Vec2, Vec2], color: Color) {
|
function drawTriangle(gfx: Graphics, positions: [Vec2, Vec2, Vec2], color: Color) {
|
||||||
const a_position = gfx.getAttribute("a_position");
|
const a_position = gfx.getAttribute("a_position");
|
||||||
|
@ -113,4 +112,4 @@ function drawLine(gfx: Graphics, A: Vec2, B: Vec2, color: Color) {
|
||||||
gfx.ctx.drawArrays(gfx.ctx.LINES, 0, 2);
|
gfx.ctx.drawArrays(gfx.ctx.LINES, 0, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
export { drawTriangle, drawTriangleExts, drawRectangle, drawCircle, drawLine }
|
export { drawTriangle, drawTriangleExts, drawRectangle, drawCircle, drawLine }
|
|
@ -1,19 +1,19 @@
|
||||||
import { initializeContext, Vec2 } from "./common.js";
|
import { initializeContext, Vec2, Mat4 } from "./common.js";
|
||||||
import { Graphics, fullscreenCanvas } from "./graphics.js";
|
import { Graphics, fullscreenCanvas } from "./graphics.js";
|
||||||
import * as drawing from "./draw.js";
|
import * as drawing from "./draw.js";
|
||||||
|
import * as wasm from "./wasm.js";
|
||||||
const vertexShader = `#version 300 es
|
const vertexShader = `#version 300 es
|
||||||
|
|
||||||
in vec2 a_position;
|
in vec2 a_position;
|
||||||
in vec4 a_color;
|
in vec4 a_color;
|
||||||
out vec4 color;
|
out vec4 color;
|
||||||
uniform vec2 u_resolution;
|
uniform mat4 u_matrix;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 clipSpace = (a_position / u_resolution) * 2.0 - 1.0;
|
vec4 transformed = u_matrix * vec4(a_position.xy, 0.0, 1.0);
|
||||||
|
|
||||||
|
gl_Position = transformed;
|
||||||
color = a_color;
|
color = a_color;
|
||||||
|
|
||||||
gl_Position = vec4(clipSpace.xy, 0.0, 1.0);
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
const fragmentShader = `#version 300 es
|
const fragmentShader = `#version 300 es
|
||||||
|
@ -26,29 +26,22 @@ const fragmentShader = `#version 300 es
|
||||||
outColor = color;
|
outColor = color;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
function draw(gfx, dt, pos, velocity) {
|
function draw(gfx, angle) {
|
||||||
gfx.clear(0, 0, 0, 0);
|
gfx.clear(0, 0, 0, 0);
|
||||||
gfx.ctx.uniform2f(gfx.getUniform("u_resolution"), gfx.ctx.canvas.width, gfx.ctx.canvas.height);
|
let left = 0;
|
||||||
drawing.drawCircle(gfx, pos, 200, [1, 0, 0, 1]);
|
let right = gfx.ctx.canvas.width;
|
||||||
if (pos.x + 200 >= gfx.ctx.canvas.width) {
|
let bottom = 0;
|
||||||
pos.x = gfx.ctx.canvas.width - 200;
|
let top = gfx.ctx.canvas.height;
|
||||||
velocity.x *= -1;
|
let near = -1;
|
||||||
}
|
let far = 1;
|
||||||
else if (pos.x - 200 <= 0) {
|
let m = Mat4.orthographic(left, right, bottom, top, near, far);
|
||||||
pos.x = 200;
|
m = m.mult(Mat4.rotation_x(angle));
|
||||||
velocity.x *= -1;
|
m = m.mult(Mat4.rotation_y(angle));
|
||||||
}
|
m = m.mult(Mat4.rotation_z(angle));
|
||||||
if (pos.y + 200 >= gfx.ctx.canvas.height) {
|
gfx.ctx.uniformMatrix4fv(gfx.getUniform("u_matrix"), false, m.splat());
|
||||||
pos.y = gfx.ctx.canvas.height - 200;
|
drawing.drawRectangle(gfx, new Vec2(gfx.ctx.canvas.width / 2 - 50, gfx.ctx.canvas.height / 2 - 50), new Vec2(100, 100), [1, 0, 0, 1]);
|
||||||
velocity.y *= -1;
|
|
||||||
}
|
|
||||||
else if (pos.y - 200 <= 0) {
|
|
||||||
pos.y = 200;
|
|
||||||
velocity.y *= -1;
|
|
||||||
}
|
|
||||||
pos.add(velocity.multNew(dt));
|
|
||||||
}
|
}
|
||||||
(() => {
|
(async () => {
|
||||||
const canvasId = "game";
|
const canvasId = "game";
|
||||||
const ctx = initializeContext(canvasId);
|
const ctx = initializeContext(canvasId);
|
||||||
if (ctx === null)
|
if (ctx === null)
|
||||||
|
@ -59,19 +52,20 @@ function draw(gfx, dt, pos, velocity) {
|
||||||
a_position.format(2, gfx.ctx.FLOAT, false, 0, 0);
|
a_position.format(2, gfx.ctx.FLOAT, false, 0, 0);
|
||||||
const a_color = gfx.createAttribute("a_color");
|
const a_color = gfx.createAttribute("a_color");
|
||||||
a_color.format(4, gfx.ctx.FLOAT, false, 0, 0);
|
a_color.format(4, gfx.ctx.FLOAT, false, 0, 0);
|
||||||
gfx.createUniform("u_resolution");
|
gfx.createUniform("u_matrix");
|
||||||
let pos = new Vec2(300, 300);
|
let angle = 0;
|
||||||
let velocity = new Vec2(200, 200);
|
|
||||||
let prevTimestamp = 0;
|
let prevTimestamp = 0;
|
||||||
const frame = (timestamp) => {
|
const frame = (timestamp) => {
|
||||||
const deltaTime = (timestamp - prevTimestamp) / 1000;
|
const deltaTime = (timestamp - prevTimestamp) / 1000;
|
||||||
prevTimestamp = timestamp;
|
prevTimestamp = timestamp;
|
||||||
fullscreenCanvas(gfx, "game");
|
fullscreenCanvas(gfx, "game");
|
||||||
draw(gfx, deltaTime, pos, velocity);
|
draw(gfx, angle);
|
||||||
|
angle += Math.PI * deltaTime * 0.5;
|
||||||
window.requestAnimationFrame(frame);
|
window.requestAnimationFrame(frame);
|
||||||
};
|
};
|
||||||
window.requestAnimationFrame((timestamp) => {
|
window.requestAnimationFrame((timestamp) => {
|
||||||
prevTimestamp = timestamp;
|
prevTimestamp = timestamp;
|
||||||
window.requestAnimationFrame(frame);
|
window.requestAnimationFrame(frame);
|
||||||
});
|
});
|
||||||
|
let wasmgl = new wasm.WASMGL(await wasm.loadWasmModule("./src/wasm/module.wasm"));
|
||||||
})();
|
})();
|
|
@ -1,6 +1,7 @@
|
||||||
import { initializeContext, Vec2 } from "./common.js";
|
import { initializeContext, Vec2, Mat4, Vec4 } from "./common.js";
|
||||||
import { Graphics, fullscreenCanvas } from "./graphics.js";
|
import { Graphics, fullscreenCanvas } from "./graphics.js";
|
||||||
import * as drawing from "./draw.js";
|
import * as drawing from "./draw.js";
|
||||||
|
import * as wasm from "./wasm.js";
|
||||||
|
|
||||||
const vertexShader =
|
const vertexShader =
|
||||||
`#version 300 es
|
`#version 300 es
|
||||||
|
@ -8,14 +9,13 @@ const vertexShader =
|
||||||
in vec2 a_position;
|
in vec2 a_position;
|
||||||
in vec4 a_color;
|
in vec4 a_color;
|
||||||
out vec4 color;
|
out vec4 color;
|
||||||
uniform vec2 u_resolution;
|
uniform mat4 u_matrix;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 clipSpace = (a_position / u_resolution) * 2.0 - 1.0;
|
vec4 transformed = u_matrix * vec4(a_position.xy, 0.0, 1.0);
|
||||||
|
|
||||||
|
gl_Position = transformed;
|
||||||
color = a_color;
|
color = a_color;
|
||||||
|
|
||||||
gl_Position = vec4(clipSpace.xy, 0.0, 1.0);
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -33,35 +33,35 @@ const fragmentShader =
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function draw(gfx: Graphics, dt: number, pos: Vec2, velocity: Vec2) {
|
function draw(gfx: Graphics, angle: number) {
|
||||||
gfx.clear(0, 0, 0, 0);
|
gfx.clear(0, 0, 0, 0);
|
||||||
gfx.ctx.uniform2f(gfx.getUniform("u_resolution"), gfx.ctx.canvas.width, gfx.ctx.canvas.height);
|
|
||||||
drawing.drawCircle(gfx, pos, 200, [1, 0, 0, 1]);
|
|
||||||
|
|
||||||
if (pos.x + 200 >= gfx.ctx.canvas.width)
|
let left = 0;
|
||||||
{
|
let right = gfx.ctx.canvas.width;
|
||||||
pos.x = gfx.ctx.canvas.width - 200;
|
let bottom = 0;
|
||||||
velocity.x *= -1;
|
let top = gfx.ctx.canvas.height;
|
||||||
} else if (pos.x - 200 <= 0)
|
let near = -1;
|
||||||
{
|
let far = 1;
|
||||||
pos.x = 200;
|
|
||||||
velocity.x *= -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pos.y + 200 >= gfx.ctx.canvas.height)
|
let m = Mat4.orthographic(left, right, bottom, top, near, far);
|
||||||
{
|
m = m.mult(Mat4.rotation_x(angle));
|
||||||
pos.y = gfx.ctx.canvas.height - 200;
|
m = m.mult(Mat4.rotation_y(angle));
|
||||||
velocity.y *= -1;
|
m = m.mult(Mat4.rotation_z(angle));
|
||||||
} else if (pos.y - 200 <= 0)
|
|
||||||
{
|
|
||||||
pos.y = 200;
|
|
||||||
velocity.y *= -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pos.add(velocity.multNew(dt));
|
gfx.ctx.uniformMatrix4fv(
|
||||||
|
gfx.getUniform("u_matrix"),
|
||||||
|
false,
|
||||||
|
m.splat()
|
||||||
|
);
|
||||||
|
|
||||||
|
drawing.drawRectangle(
|
||||||
|
gfx,
|
||||||
|
new Vec2(gfx.ctx.canvas.width / 2 - 50, gfx.ctx.canvas.height / 2 - 50),
|
||||||
|
new Vec2(100, 100),
|
||||||
|
[1, 0, 0, 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
(() => {
|
(async () => {
|
||||||
const canvasId = "game";
|
const canvasId = "game";
|
||||||
const ctx = initializeContext(canvasId);
|
const ctx = initializeContext(canvasId);
|
||||||
if (ctx === null) return;
|
if (ctx === null) return;
|
||||||
|
@ -75,18 +75,17 @@ function draw(gfx: Graphics, dt: number, pos: Vec2, velocity: Vec2) {
|
||||||
const a_color = gfx.createAttribute("a_color");
|
const a_color = gfx.createAttribute("a_color");
|
||||||
a_color.format(4, gfx.ctx.FLOAT, false, 0, 0);
|
a_color.format(4, gfx.ctx.FLOAT, false, 0, 0);
|
||||||
|
|
||||||
gfx.createUniform("u_resolution");
|
gfx.createUniform("u_matrix");
|
||||||
|
|
||||||
let pos = new Vec2(300, 300);
|
let angle = 0;
|
||||||
let velocity = new Vec2(200, 200);
|
|
||||||
|
|
||||||
let prevTimestamp = 0;
|
let prevTimestamp = 0;
|
||||||
const frame = (timestamp: number) => {
|
const frame = (timestamp: number) => {
|
||||||
const deltaTime = (timestamp - prevTimestamp)/1000;
|
const deltaTime = (timestamp - prevTimestamp)/1000;
|
||||||
prevTimestamp = timestamp;
|
prevTimestamp = timestamp;
|
||||||
|
|
||||||
fullscreenCanvas(gfx, "game");
|
fullscreenCanvas(gfx, "game");
|
||||||
draw(gfx, deltaTime, pos, velocity);
|
draw(gfx, angle);
|
||||||
|
angle += Math.PI * deltaTime * 0.5;
|
||||||
|
|
||||||
window.requestAnimationFrame(frame);
|
window.requestAnimationFrame(frame);
|
||||||
}
|
}
|
||||||
|
@ -95,4 +94,6 @@ function draw(gfx: Graphics, dt: number, pos: Vec2, velocity: Vec2) {
|
||||||
prevTimestamp = timestamp;
|
prevTimestamp = timestamp;
|
||||||
window.requestAnimationFrame(frame);
|
window.requestAnimationFrame(frame);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let wasmgl: wasm.WASMGL = new wasm.WASMGL(await wasm.loadWasmModule("./src/wasm/module.wasm"));
|
||||||
})();
|
})();
|
|
@ -0,0 +1,37 @@
|
||||||
|
export class WASMGLvalue {
|
||||||
|
ptr;
|
||||||
|
size;
|
||||||
|
constructor(ptr, size) {
|
||||||
|
this.ptr = ptr;
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export async function loadWasmModule(path) {
|
||||||
|
return WebAssembly.instantiateStreaming(fetch(path));
|
||||||
|
}
|
||||||
|
export class WASMGL {
|
||||||
|
exports;
|
||||||
|
mem;
|
||||||
|
constructor(wasm) {
|
||||||
|
this.exports = wasm.instance.exports;
|
||||||
|
const memSize = new Float32Array(this.exports.memory.buffer, this.exports.WASMGLmemory.value + 4, 1).at(0);
|
||||||
|
this.mem = new Float32Array(this.exports.memory.buffer, this.exports.WASMGLmemory.value, memSize);
|
||||||
|
}
|
||||||
|
alloc(size) {
|
||||||
|
const head = this.mem[2];
|
||||||
|
this.mem[2] += size;
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
setstr(ptr, str) {
|
||||||
|
for (let i = 0; i < str.length; i++) {
|
||||||
|
this.mem[ptr] = str.charCodeAt(i);
|
||||||
|
++ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set(ptr, data) {
|
||||||
|
data.forEach((v, i) => {
|
||||||
|
this.mem[ptr + i] = v;
|
||||||
|
});
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
export class WASMGLvalue {
|
||||||
|
ptr: number;
|
||||||
|
size: number;
|
||||||
|
|
||||||
|
constructor(ptr: number, size: number) {
|
||||||
|
this.ptr = ptr;
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WASMGLEnvironment {
|
||||||
|
exports: any,
|
||||||
|
mem: Float32Array,
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function loadWasmModule(path: string): Promise<WebAssembly.WebAssemblyInstantiatedSource> {
|
||||||
|
return WebAssembly.instantiateStreaming(fetch(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
export class WASMGL {
|
||||||
|
exports: any;
|
||||||
|
mem: Float32Array;
|
||||||
|
|
||||||
|
constructor(wasm: WebAssembly.WebAssemblyInstantiatedSource) {
|
||||||
|
this.exports = wasm.instance.exports;
|
||||||
|
|
||||||
|
const memSize = new Float32Array(
|
||||||
|
this.exports.memory.buffer,
|
||||||
|
this.exports.WASMGLmemory.value + 4,
|
||||||
|
1
|
||||||
|
).at(0);
|
||||||
|
|
||||||
|
this.mem = new Float32Array(
|
||||||
|
this.exports.memory.buffer,
|
||||||
|
this.exports.WASMGLmemory.value,
|
||||||
|
memSize
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
alloc(size: number): number {
|
||||||
|
const head = this.mem[2];
|
||||||
|
this.mem[2] += size;
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
setstr(ptr: number, str: string) {
|
||||||
|
for (let i = 0; i < str.length; i++) {
|
||||||
|
this.mem[ptr] = str.charCodeAt(i);
|
||||||
|
++ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set(ptr: number, data: number[]): number {
|
||||||
|
data.forEach((v, i) => {
|
||||||
|
this.mem[ptr + i] = v;
|
||||||
|
});
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -xe
|
||||||
|
|
||||||
|
CC="clang"
|
||||||
|
|
||||||
|
CLIBS=""
|
||||||
|
CFLAGS="--target=wasm32 -flto -Wl,--lto-O3 -nostdlib -Wl,--no-entry -Wl,--export-all"
|
||||||
|
|
||||||
|
$CC $CFLAGS -o module.wasm *.c $CLIBS
|
|
@ -0,0 +1,12 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>aaa</title>
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||||
|
<meta name="description" content="" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script src="test.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,20 @@
|
||||||
|
#include "wasmgl.h"
|
||||||
|
|
||||||
|
void doubel(WASMGLvalue(0))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < size_0; ++i)
|
||||||
|
WASMGLset(ptr_0 + i, WASMGLmemory[ptr_0 + i] * 2.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uppercase(WASMGLvalue(0)) {
|
||||||
|
int val = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < size_0; ++i)
|
||||||
|
{
|
||||||
|
val = WASMGLmemory[ptr_0 + i] - 32;
|
||||||
|
|
||||||
|
if (val < 65 || val > 122) val = WASMGLmemory[ptr_0 + i];
|
||||||
|
|
||||||
|
WASMGLset(ptr_0 + i, val);
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,34 @@
|
||||||
|
(async () => {
|
||||||
|
let instance = await WebAssembly.instantiateStreaming(fetch("module.wasm"));
|
||||||
|
const memSize = new Int32Array(
|
||||||
|
instance.instance.exports.memory.buffer,
|
||||||
|
instance.instance.exports.WASMGLmemory.value + 4,
|
||||||
|
1
|
||||||
|
)[0]
|
||||||
|
|
||||||
|
let mem = new Int32Array(
|
||||||
|
instance.instance.exports.memory.buffer,
|
||||||
|
instance.instance.exports.WASMGLmemory.value,
|
||||||
|
memSize
|
||||||
|
);
|
||||||
|
|
||||||
|
let ptr = alloc(mem, 4);
|
||||||
|
setstr(mem, ptr, 4, "game");
|
||||||
|
|
||||||
|
console.log(String.fromCharCode(instance.instance.exports.initialize(ptr, 4)));
|
||||||
|
})();
|
||||||
|
|
||||||
|
function alloc(mem, size) {
|
||||||
|
const head = mem[2];
|
||||||
|
console.log(head);
|
||||||
|
mem[2] += size;
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setstr(mem, ptr, size, str) {
|
||||||
|
for (let i = 0; i < size; i++) {
|
||||||
|
mem[ptr] = str.charCodeAt(i);
|
||||||
|
++ptr;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
#include "wasmgl.h"
|
||||||
|
|
||||||
|
float WASMGLmemory[WASMGLmemory_size] = {
|
||||||
|
[MEM_SIZE] = WASMGLmemory_size,
|
||||||
|
[MEM_HEAD] = MEM_ELEM_COUNT,
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
|
WASMGLptr WASMGLmalloc(WASMGLsize size)
|
||||||
|
{
|
||||||
|
WASMGLptr ptr = WASMGLmemory[MEM_HEAD];
|
||||||
|
WASMGLmemory[MEM_HEAD] += size;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WASMGLset(WASMGLptr ptr, int value)
|
||||||
|
{
|
||||||
|
WASMGLmemory[ptr] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WASMGLsetstr(WASMGLptr ptr, const char * cstr, WASMGLsize size)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < size; ++i)
|
||||||
|
WASMGLset(ptr + i, cstr[i]);
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef WASMGL_H_
|
||||||
|
#define WASMGL_H_
|
||||||
|
|
||||||
|
#define main WASMGLmain
|
||||||
|
|
||||||
|
#define WASMGLmemory_size (1024 * 1024)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MEM_NULL = 0,
|
||||||
|
MEM_SIZE = 1,
|
||||||
|
MEM_HEAD,
|
||||||
|
MEM_ELEM_COUNT,
|
||||||
|
} WASMGLmemory_layout;
|
||||||
|
|
||||||
|
extern float WASMGLmemory[WASMGLmemory_size];
|
||||||
|
|
||||||
|
typedef unsigned int WASMGLptr;
|
||||||
|
typedef unsigned int WASMGLsize;
|
||||||
|
|
||||||
|
#define WASMGLvalue(n) WASMGLptr ptr_##n, WASMGLsize size_##n
|
||||||
|
|
||||||
|
WASMGLptr WASMGLmalloc(WASMGLsize size);
|
||||||
|
void WASMGLset(WASMGLptr ptr, int value);
|
||||||
|
void WASMGLsetstr(WASMGLptr ptr, const char * cstr, WASMGLsize size);
|
||||||
|
#endif // WASMGL_H_
|
Loading…
Reference in New Issue