Skip to content
This repository was archived by the owner on Nov 12, 2024. It is now read-only.

Commit fbc6136

Browse files
committed
start adding offscreen canvas
1 parent 8d1027c commit fbc6136

File tree

4 files changed

+186
-182
lines changed

4 files changed

+186
-182
lines changed

src/gfx.ts

+77-74
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,7 @@ import {
1414
deepEq,
1515
} from "./utils"
1616

17-
export type GfxCtx = {
18-
gl: WebGLRenderingContext,
19-
onDestroy: (action: () => void) => void,
20-
pushTexture: (ty: GLenum, tex: WebGLTexture) => void,
21-
popTexture: (ty: GLenum) => void,
22-
pushBuffer: (ty: GLenum, tex: WebGLBuffer) => void,
23-
popBuffer: (ty: GLenum) => void,
24-
pushFramebuffer: (ty: GLenum, tex: WebGLFramebuffer) => void,
25-
popFramebuffer: (ty: GLenum) => void,
26-
pushRenderbuffer: (ty: GLenum, tex: WebGLRenderbuffer) => void,
27-
popRenderbuffer: (ty: GLenum) => void,
28-
setVertexFormat: (fmt: VertexFormat) => void,
29-
destroy: () => void,
30-
}
17+
export type GfxCtx = ReturnType<typeof initGfx>
3118

3219
export class Texture {
3320

@@ -96,11 +83,11 @@ export class Texture {
9683
}
9784

9885
bind() {
99-
this.ctx.pushTexture(this.ctx.gl.TEXTURE_2D, this.glTex)
86+
this.ctx.pushTexture2D(this.glTex)
10087
}
10188

10289
unbind() {
103-
this.ctx.popTexture(this.ctx.gl.TEXTURE_2D)
90+
this.ctx.popTexture2D()
10491
}
10592

10693
free() {
@@ -185,15 +172,15 @@ export class FrameBuffer {
185172
}
186173

187174
bind() {
188-
const gl = this.ctx.gl
189-
this.ctx.pushFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer)
190-
this.ctx.pushRenderbuffer(gl.RENDERBUFFER, this.glRenderbuffer)
175+
this.ctx.pushFramebuffer(this.glFramebuffer)
176+
this.ctx.pushRenderbuffer(this.glRenderbuffer)
177+
this.ctx.pushViewport({ x: 0, y: 0, w: this.width, h: this.height })
191178
}
192179

193180
unbind() {
194-
const gl = this.ctx.gl
195-
this.ctx.popFramebuffer(gl.FRAMEBUFFER)
196-
this.ctx.popRenderbuffer(gl.RENDERBUFFER)
181+
this.ctx.popFramebuffer()
182+
this.ctx.popRenderbuffer()
183+
this.ctx.popViewport()
197184
}
198185

199186
free() {
@@ -247,11 +234,11 @@ export class Shader {
247234
}
248235

249236
bind() {
250-
this.ctx.gl.useProgram(this.glProgram)
237+
this.ctx.pushProgram(this.glProgram)
251238
}
252239

253240
unbind() {
254-
this.ctx.gl.useProgram(null)
241+
this.ctx.popProgram()
255242
}
256243

257244
send(uniform: Uniform) {
@@ -313,14 +300,14 @@ export class BatchRenderer {
313300
this.maxIndices = maxIndices
314301

315302
this.glVBuf = gl.createBuffer()
316-
ctx.pushBuffer(gl.ARRAY_BUFFER, this.glVBuf)
303+
ctx.pushArrayBuffer(this.glVBuf)
317304
gl.bufferData(gl.ARRAY_BUFFER, maxVertices * 4, gl.DYNAMIC_DRAW)
318-
ctx.popBuffer(gl.ARRAY_BUFFER)
305+
ctx.popArrayBuffer()
319306

320307
this.glIBuf = gl.createBuffer()
321-
ctx.pushBuffer(gl.ELEMENT_ARRAY_BUFFER, this.glIBuf)
308+
ctx.pushElementArrayBuffer(this.glIBuf)
322309
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, maxIndices * 4, gl.DYNAMIC_DRAW)
323-
ctx.popBuffer(gl.ELEMENT_ARRAY_BUFFER)
310+
ctx.popElementArrayBuffer()
324311

325312
}
326313

@@ -368,9 +355,9 @@ export class BatchRenderer {
368355

369356
const gl = this.ctx.gl
370357

371-
this.ctx.pushBuffer(gl.ARRAY_BUFFER, this.glVBuf)
358+
this.ctx.pushArrayBuffer(this.glVBuf)
372359
gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array(this.vqueue))
373-
this.ctx.pushBuffer(gl.ELEMENT_ARRAY_BUFFER, this.glIBuf)
360+
this.ctx.pushElementArrayBuffer(this.glIBuf)
374361
gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, new Uint16Array(this.iqueue))
375362
this.ctx.setVertexFormat(this.vertexFormat)
376363
this.curShader.bind()
@@ -380,8 +367,8 @@ export class BatchRenderer {
380367
this.curTex?.unbind()
381368
this.curShader.unbind()
382369

383-
this.ctx.popBuffer(gl.ARRAY_BUFFER)
384-
this.ctx.popBuffer(gl.ELEMENT_ARRAY_BUFFER)
370+
this.ctx.popArrayBuffer()
371+
this.ctx.popElementArrayBuffer()
385372

386373
this.vqueue = []
387374
this.iqueue = []
@@ -413,27 +400,27 @@ export class Mesh {
413400
this.ctx = ctx
414401

415402
this.glVBuf = gl.createBuffer()
416-
ctx.pushBuffer(gl.ARRAY_BUFFER, this.glVBuf)
403+
ctx.pushArrayBuffer(this.glVBuf)
417404
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW)
418-
ctx.popBuffer(gl.ARRAY_BUFFER)
405+
ctx.popArrayBuffer()
419406

420407
this.glIBuf = gl.createBuffer()
421-
ctx.pushBuffer(gl.ELEMENT_ARRAY_BUFFER, this.glIBuf)
408+
ctx.pushElementArrayBuffer(this.glIBuf)
422409
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW)
423-
ctx.popBuffer(gl.ELEMENT_ARRAY_BUFFER)
410+
ctx.popElementArrayBuffer()
424411

425412
this.count = indices.length
426413

427414
}
428415

429416
draw(primitive?: GLenum) {
430417
const gl = this.ctx.gl
431-
this.ctx.pushBuffer(gl.ARRAY_BUFFER, this.glVBuf)
432-
this.ctx.pushBuffer(gl.ELEMENT_ARRAY_BUFFER, this.glIBuf)
418+
this.ctx.pushArrayBuffer(this.glVBuf)
419+
this.ctx.pushElementArrayBuffer(this.glIBuf)
433420
this.ctx.setVertexFormat(this.vertexFormat)
434421
gl.drawElements(primitive ?? gl.TRIANGLES, this.count, gl.UNSIGNED_SHORT, 0)
435-
this.ctx.popBuffer(gl.ARRAY_BUFFER)
436-
this.ctx.popBuffer(gl.ELEMENT_ARRAY_BUFFER)
422+
this.ctx.popArrayBuffer()
423+
this.ctx.popElementArrayBuffer()
437424
}
438425

439426
free() {
@@ -445,36 +432,22 @@ export class Mesh {
445432

446433
}
447434

448-
// TODO: support useProgram
449-
function genBinder<T>(func: (ty: GLenum, item: T) => void) {
450-
const bindings = {}
451-
return {
452-
cur: (ty: GLenum) => {
453-
const stack = bindings[ty] ?? []
454-
return stack[stack.length - 1]
455-
},
456-
push: (ty: GLenum, item: T) => {
457-
if (!bindings[ty]) bindings[ty] = []
458-
const stack = bindings[ty]
459-
stack.push(item)
460-
func(ty, item)
461-
},
462-
pop: (ty: GLenum) => {
463-
const stack = bindings[ty]
464-
if (!stack) throw new Error(`Unknown WebGL type: ${ty}`)
465-
if (stack.length <= 0) throw new Error("Can't unbind texture when there's no texture bound")
466-
stack.pop()
467-
func(ty, stack[stack.length - 1] ?? null)
468-
},
435+
function genStack<T>(setFunc: (item: T) => void) {
436+
const stack: T[] = []
437+
const push = (item: T) => {
438+
stack.push(item)
439+
setFunc(item)
469440
}
441+
const pop = () => {
442+
stack.pop()
443+
setFunc(cur() ?? null)
444+
}
445+
const cur = () => stack[stack.length - 1]
446+
return [push, pop, cur] as const
470447
}
471448

472-
export default (gl: WebGLRenderingContext): GfxCtx => {
449+
export default function initGfx(gl: WebGLRenderingContext) {
473450

474-
const textureBinder = genBinder(gl.bindTexture.bind(gl))
475-
const bufferBinder = genBinder(gl.bindBuffer.bind(gl))
476-
const framebufferBinder = genBinder(gl.bindFramebuffer.bind(gl))
477-
const renderbufferBinder = genBinder(gl.bindRenderbuffer.bind(gl))
478451
const gc: Array<() => void> = []
479452

480453
function onDestroy(action) {
@@ -499,18 +472,48 @@ export default (gl: WebGLRenderingContext): GfxCtx => {
499472
}, 0)
500473
}
501474

475+
const [ pushTexture2D, popTexture2D ] =
476+
genStack<WebGLTexture>((t) => gl.bindTexture(gl.TEXTURE_2D, t))
477+
478+
const [ pushArrayBuffer, popArrayBuffer ] =
479+
genStack<WebGLBuffer>((b) => gl.bindBuffer(gl.ARRAY_BUFFER, b))
480+
481+
const [ pushElementArrayBuffer, popElementArrayBuffer ] =
482+
genStack<WebGLBuffer>((b) => gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, b))
483+
484+
const [ pushFramebuffer, popFramebuffer ] =
485+
genStack<WebGLFramebuffer>((b) => gl.bindFramebuffer(gl.FRAMEBUFFER, b))
486+
487+
const [ pushRenderbuffer, popRenderbuffer ] =
488+
genStack<WebGLRenderbuffer>((b) => gl.bindRenderbuffer(gl.RENDERBUFFER, b))
489+
490+
const [ pushViewport, popViewport ] =
491+
genStack<{ x: number, y: number, w: number, h: number }>(({ x, y, w, h }) => {
492+
gl.viewport(x, y, w, h)
493+
})
494+
495+
const [ pushProgram, popProgram ] = genStack<WebGLProgram>((p) => gl.useProgram(p))
496+
497+
pushViewport({ x: 0, y: 0, w: gl.drawingBufferWidth, h: gl.drawingBufferHeight })
498+
502499
return {
503500
gl,
504501
onDestroy,
505502
destroy,
506-
pushTexture: textureBinder.push,
507-
popTexture: textureBinder.pop,
508-
pushBuffer: bufferBinder.push,
509-
popBuffer: bufferBinder.pop,
510-
pushFramebuffer: framebufferBinder.push,
511-
popFramebuffer: framebufferBinder.pop,
512-
pushRenderbuffer: renderbufferBinder.push,
513-
popRenderbuffer: renderbufferBinder.pop,
503+
pushTexture2D,
504+
popTexture2D,
505+
pushArrayBuffer,
506+
popArrayBuffer,
507+
pushElementArrayBuffer,
508+
popElementArrayBuffer,
509+
pushFramebuffer,
510+
popFramebuffer,
511+
pushRenderbuffer,
512+
popRenderbuffer,
513+
pushViewport,
514+
popViewport,
515+
pushProgram,
516+
popProgram,
514517
setVertexFormat,
515518
}
516519

0 commit comments

Comments
 (0)