Added Mat4, Vec4 and some of the mathematical operations on those

This commit is contained in:
Maciej Samborski 2024-12-24 16:30:00 +01:00
parent 3e9bdcc469
commit 129cf05b90
11 changed files with 523 additions and 221 deletions

View File

@ -71,4 +71,164 @@ class Vec3 {
this.z -= other.z; this.z -= other.z;
} }
} }
export { initializeContext, Vec2, Vec3 }; 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 };

View File

@ -93,4 +93,212 @@ class Vec3 {
} }
} }
export { initializeContext, Vec2, Vec3, Color }; 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 };

View File

@ -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 }

View File

@ -1,4 +1,4 @@
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"; import * as wasm from "./wasm.js";
@ -7,14 +7,13 @@ 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
@ -27,27 +26,20 @@ 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 () => { (async () => {
const canvasId = "game"; const canvasId = "game";
@ -60,20 +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 env = await wasm.loadWasmModule("./src/wasm/module.wasm"); let wasmgl = new wasm.WASMGL(await wasm.loadWasmModule("./src/wasm/module.wasm"));
})(); })();

View File

@ -1,4 +1,4 @@
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"; import * as wasm from "./wasm.js";
@ -9,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);
} }
`; `;
@ -34,32 +33,32 @@ 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 () => { (async () => {
@ -76,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);
} }
@ -97,5 +95,5 @@ function draw(gfx: Graphics, dt: number, pos: Vec2, velocity: Vec2) {
window.requestAnimationFrame(frame); window.requestAnimationFrame(frame);
}); });
let env: any = await wasm.loadWasmModule("./src/wasm/module.wasm"); let wasmgl: wasm.WASMGL = new wasm.WASMGL(await wasm.loadWasmModule("./src/wasm/module.wasm"));
})(); })();

View File

@ -1,4 +1,4 @@
class WASMGLvalue { export class WASMGLvalue {
ptr; ptr;
size; size;
constructor(ptr, size) { constructor(ptr, size) {
@ -6,58 +6,32 @@ class WASMGLvalue {
this.size = size; this.size = size;
} }
} }
async function loadWasmModule(path) { export async function loadWasmModule(path) {
let wasm = await WebAssembly.instantiateStreaming(fetch(path)); return WebAssembly.instantiateStreaming(fetch(path));
const memSize = new Int32Array(wasm.instance.exports.memory.buffer, wasm.instance.exports.WASMGLmemory.value + 4, 1)[0]; }
let memInt = new Int32Array(wasm.instance.exports.memory.buffer, wasm.instance.exports.WASMGLmemory.value, memSize); export class WASMGL {
let memFloat = new Float32Array(wasm.instance.exports.memory.buffer, wasm.instance.exports.WASMGLmemory.value, memSize); exports;
wasm.instance.exports.WASMGLmain(); mem;
const data = [ constructor(wasm) {
1.5, this.exports = wasm.instance.exports;
2.5, const memSize = new Float32Array(this.exports.memory.buffer, this.exports.WASMGLmemory.value + 4, 1).at(0);
3.5, this.mem = new Float32Array(this.exports.memory.buffer, this.exports.WASMGLmemory.value, memSize);
4.5,
5.5,
6.5,
7.5,
8.5,
];
let ptr = sendDataFloat(memFloat, data);
wasm.instance.exports.calc(ptr, data.length);
for (let i = 0; i < data.length; ++i) {
console.log(memFloat[ptr + i]);
} }
return wasm.instance.exports; alloc(size) {
} const head = this.mem[2];
function alloc(mem, size) { this.mem[2] += size;
const head = mem[2]; return head;
mem[2] += size; }
return head; setstr(ptr, str) {
} for (let i = 0; i < str.length; i++) {
function allocFloat(mem, size) { this.mem[ptr] = str.charCodeAt(i);
const head = mem[2]; ++ptr;
mem[2] += size; }
return head; }
} set(ptr, data) {
function setstr(mem, ptr, size, str) { data.forEach((v, i) => {
for (let i = 0; i < size; i++) { this.mem[ptr + i] = v;
mem[ptr] = str.charCodeAt(i); });
++ptr; return ptr;
} }
} }
function sendData(mem, data) {
let ptr = alloc(mem, data.length);
data.forEach((v, i) => {
mem[ptr + i] = v;
});
return ptr;
}
function sendDataFloat(mem, data) {
let ptr = allocFloat(mem, data.length);
data.forEach((v, i) => {
mem[ptr + i] = v;
console.log(mem[ptr + i]);
});
return ptr;
}
export { loadWasmModule, alloc, setstr };

View File

@ -1,4 +1,4 @@
class WASMGLvalue { export class WASMGLvalue {
ptr: number; ptr: number;
size: number; size: number;
@ -8,90 +8,54 @@ class WASMGLvalue {
} }
} }
async function loadWasmModule(path: string): Promise<WebAssembly.Exports> { export interface WASMGLEnvironment {
let wasm: any = await WebAssembly.instantiateStreaming(fetch(path)); exports: any,
mem: Float32Array,
}
const memSize = new Int32Array( export async function loadWasmModule(path: string): Promise<WebAssembly.WebAssemblyInstantiatedSource> {
wasm.instance.exports.memory.buffer, return WebAssembly.instantiateStreaming(fetch(path));
wasm.instance.exports.WASMGLmemory.value + 4, }
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 1
)[0]; ).at(0);
let memInt = new Int32Array( this.mem = new Float32Array(
wasm.instance.exports.memory.buffer, this.exports.memory.buffer,
wasm.instance.exports.WASMGLmemory.value, this.exports.WASMGLmemory.value,
memSize memSize
); );
let memFloat = new Float32Array(
wasm.instance.exports.memory.buffer,
wasm.instance.exports.WASMGLmemory.value,
memSize
);
wasm.instance.exports.WASMGLmain();
const data = [
1.5,
2.5,
3.5,
4.5,
5.5,
6.5,
7.5,
8.5,
];
let ptr = sendDataFloat(memFloat, data);
wasm.instance.exports.calc(ptr, data.length);
for (let i = 0; i < data.length; ++i) {
console.log(memFloat[ptr + i]);
} }
return wasm.instance.exports; alloc(size: number): number {
} const head = this.mem[2];
this.mem[2] += size;
function alloc(mem: Int32Array, size: number): number { return head;
const head = mem[2]; }
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;
}
}
function allocFloat(mem: Float32Array, size: number): number { set(ptr: number, data: number[]): number {
const head = mem[2]; data.forEach((v, i) => {
mem[2] += size; this.mem[ptr + i] = v;
});
return head; return ptr;
}
function setstr(mem: Int32Array, ptr: number, size: number, str: string) {
for (let i = 0; i < size; i++) {
mem[ptr] = str.charCodeAt(i);
++ptr;
} }
} }
function sendData(mem: Int32Array, data: number[]): number {
let ptr = alloc(mem, data.length);
data.forEach((v, i) => {
mem[ptr + i] = v;
});
return ptr;
}
function sendDataFloat(mem: Float32Array, data: number[]): number {
let ptr = allocFloat(mem, data.length);
data.forEach((v, i) => {
mem[ptr + i] = v;
console.log(mem[ptr + i]);
});
return ptr;
}
export { loadWasmModule, alloc, setstr }

View File

@ -1,19 +1,20 @@
#include "wasmgl.h" #include "wasmgl.h"
int WASMGLmemory[WASMGLmemory_size] = { void doubel(WASMGLvalue(0))
[MEM_SIZE] = WASMGLmemory_size,
[MEM_HEAD] = MEM_ELEM_COUNT,
0,
};
void calc(WASMGLvalue(0))
{ {
for (int i = 0; i < size_0; ++i) for (int i = 0; i < size_0; ++i)
WASMGLmemory[ptr_0 + i] = ((float) WASMGLmemory[ptr_0 + i]) * 2.0; WASMGLset(ptr_0 + i, WASMGLmemory[ptr_0 + i] * 2.0);
} }
int main(void) void uppercase(WASMGLvalue(0)) {
{ int val = 0;
return 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.

View File

@ -1,22 +1,26 @@
#include "wasmgl.h" #include "wasmgl.h"
WASMGLptr WASMGLmalloc(int * mem, WASMGLsize size) float WASMGLmemory[WASMGLmemory_size] = {
[MEM_SIZE] = WASMGLmemory_size,
[MEM_HEAD] = MEM_ELEM_COUNT,
0,
};
WASMGLptr WASMGLmalloc(WASMGLsize size)
{ {
WASMGLptr ptr = mem[MEM_HEAD]; WASMGLptr ptr = WASMGLmemory[MEM_HEAD];
mem[MEM_HEAD] += size; WASMGLmemory[MEM_HEAD] += size;
return ptr; return ptr;
} }
void WASMGLset(int * mem, WASMGLptr ptr, int value) void WASMGLset(WASMGLptr ptr, int value)
{ {
mem[ptr] = value; WASMGLmemory[ptr] = value;
} }
void WASMGLsetstr(int * mem, WASMGLptr ptr, const char * cstr, WASMGLsize size) void WASMGLsetstr(WASMGLptr ptr, const char * cstr, WASMGLsize size)
{ {
for (int i = 0; i < size; ++i) for (int i = 0; i < size; ++i)
{ WASMGLset(ptr + i, cstr[i]);
WASMGLset(mem, ptr + i, cstr[i]);
}
} }

View File

@ -12,12 +12,14 @@ typedef enum {
MEM_ELEM_COUNT, MEM_ELEM_COUNT,
} WASMGLmemory_layout; } WASMGLmemory_layout;
extern float WASMGLmemory[WASMGLmemory_size];
typedef unsigned int WASMGLptr; typedef unsigned int WASMGLptr;
typedef unsigned int WASMGLsize; typedef unsigned int WASMGLsize;
#define WASMGLvalue(n) WASMGLptr ptr_##n, WASMGLsize size_##n #define WASMGLvalue(n) WASMGLptr ptr_##n, WASMGLsize size_##n
WASMGLptr WASMGLmalloc(int * mem, WASMGLsize size); WASMGLptr WASMGLmalloc(WASMGLsize size);
void WASMGLset(int * mem, WASMGLptr ptr, int value); void WASMGLset(WASMGLptr ptr, int value);
void WASMGLsetstr(int * mem, WASMGLptr ptr, const char * cstr, WASMGLsize size); void WASMGLsetstr(WASMGLptr ptr, const char * cstr, WASMGLsize size);
#endif // WASMGL_H_ #endif // WASMGL_H_