return id
}
+const programMap = new Map()
+var currentProgramId = 0
+function createProgramId() {
+ const id = currentProgramId
+ currentProgramId += 1
+ return id
+}
+
+const bufferMap = new Map()
+var currentBufferId = 0
+function createBufferId() {
+ const id = currentBufferId
+ currentBufferId += 1
+ return id
+}
+
+
var memory
var decoder = new TextDecoder('utf-8')
-function readUint32(buffer, addr) {
- const view = new DataView(buffer)
+function getUint32(addr) {
+ const view = new DataView(memory.buffer)
return view.getUint32(addr, true)
}
+function setUint32(addr, val) {
+ const view = new DataView(memory.buffer)
+ view.setUint32(addr, val, true)
+}
+
+function getString(addr) {
+ const view = new DataView(memory.buffer)
+ var len = 0
+ while (view.getUint8(addr + len) != 0) len++
+ return decoder.decode(memory.buffer.slice(addr, addr + len))
+}
+
const imports = {
env: {
glCreateShader: shaderType => {
var totalSource = ''
for (let i = 0; i < numSrcs; i++) {
const addr = srcs + i * 4
- const src = readUint32(memory.buffer, addr)
- const len = readUint32(memory.buffer, lens + i * 4)
+ const src = getUint32(addr)
+ const len = getUint32(lens + i * 4)
totalSource += decoder.decode(memory.buffer.slice(src, src + len))
}
gl.shaderSource(shader, totalSource)
},
- glCompileShader: a => gl.compileShader(shaderMap.get(a))
+ glCompileShader: id => gl.compileShader(shaderMap.get(id)),
+ glCreateProgram: () => {
+ const id = createProgramId()
+ const prog = gl.createProgram()
+ programMap.set(id, prog)
+ return id
+ },
+ glAttachShader: (progId, shaderId) => {
+ gl.attachShader(programMap.get(progId), shaderMap.get(shaderId))
+ },
+ glLinkProgram: (progId) => gl.linkProgram(programMap.get(progId)),
+ glUseProgram: (progId) => gl.useProgram(programMap.get(progId)),
+ glGetAttribLocation: (progId, name) => {
+ const prog = programMap.get(progId)
+ return gl.getAttribLocation(prog, getString(name))
+ },
+ glEnableVertexAttribArray: (loc) => gl.enableVertexAttribArray(loc),
+ glVertexAttribPointer: (loc, size, type, normalized, stride, offset) => {
+ gl.vertexAttribPointer(loc, size, type, normalized, stride, offset)
+ },
+ glGenBuffers: (num, addr) => {
+ for (let i = 0; i < num; i++) {
+ const id = createBufferId()
+ const buffer = gl.createBuffer()
+ bufferMap.set(id, buffer)
+ setUint32(addr + i * 4, id)
+ }
+ },
+ glBindBuffer: (target, bufferId) => gl.bindBuffer(target, bufferMap.get(bufferId)),
+ glBufferData: (target, size, addr, usage) => {
+ const data = new Float32Array(memory.buffer.slice(addr, addr + size * 4))
+ gl.bufferData(target, data, usage)
+ }
}
}
const inst = new WebAssembly.Instance(m, imports)
memory = inst.exports.memory
return inst
- });
+ })
}
fetch('test.wasm')
.then(response => response.arrayBuffer())
.then(bytes => instantiate(bytes))
- .then(instance => console.log(instance.exports.foo()));
+ .then(instance => {
+ instance.exports.setup()
+ gl.drawArrays(gl.TRIANGLES, 0, 3)
+ })