@@ -14,20 +14,7 @@ import {
14
14
deepEq ,
15
15
} from "./utils"
16
16
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 >
31
18
32
19
export class Texture {
33
20
@@ -96,11 +83,11 @@ export class Texture {
96
83
}
97
84
98
85
bind ( ) {
99
- this . ctx . pushTexture ( this . ctx . gl . TEXTURE_2D , this . glTex )
86
+ this . ctx . pushTexture2D ( this . glTex )
100
87
}
101
88
102
89
unbind ( ) {
103
- this . ctx . popTexture ( this . ctx . gl . TEXTURE_2D )
90
+ this . ctx . popTexture2D ( )
104
91
}
105
92
106
93
free ( ) {
@@ -185,15 +172,15 @@ export class FrameBuffer {
185
172
}
186
173
187
174
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 } )
191
178
}
192
179
193
180
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 ( )
197
184
}
198
185
199
186
free ( ) {
@@ -247,11 +234,11 @@ export class Shader {
247
234
}
248
235
249
236
bind ( ) {
250
- this . ctx . gl . useProgram ( this . glProgram )
237
+ this . ctx . pushProgram ( this . glProgram )
251
238
}
252
239
253
240
unbind ( ) {
254
- this . ctx . gl . useProgram ( null )
241
+ this . ctx . popProgram ( )
255
242
}
256
243
257
244
send ( uniform : Uniform ) {
@@ -313,14 +300,14 @@ export class BatchRenderer {
313
300
this . maxIndices = maxIndices
314
301
315
302
this . glVBuf = gl . createBuffer ( )
316
- ctx . pushBuffer ( gl . ARRAY_BUFFER , this . glVBuf )
303
+ ctx . pushArrayBuffer ( this . glVBuf )
317
304
gl . bufferData ( gl . ARRAY_BUFFER , maxVertices * 4 , gl . DYNAMIC_DRAW )
318
- ctx . popBuffer ( gl . ARRAY_BUFFER )
305
+ ctx . popArrayBuffer ( )
319
306
320
307
this . glIBuf = gl . createBuffer ( )
321
- ctx . pushBuffer ( gl . ELEMENT_ARRAY_BUFFER , this . glIBuf )
308
+ ctx . pushElementArrayBuffer ( this . glIBuf )
322
309
gl . bufferData ( gl . ELEMENT_ARRAY_BUFFER , maxIndices * 4 , gl . DYNAMIC_DRAW )
323
- ctx . popBuffer ( gl . ELEMENT_ARRAY_BUFFER )
310
+ ctx . popElementArrayBuffer ( )
324
311
325
312
}
326
313
@@ -368,9 +355,9 @@ export class BatchRenderer {
368
355
369
356
const gl = this . ctx . gl
370
357
371
- this . ctx . pushBuffer ( gl . ARRAY_BUFFER , this . glVBuf )
358
+ this . ctx . pushArrayBuffer ( this . glVBuf )
372
359
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 )
374
361
gl . bufferSubData ( gl . ELEMENT_ARRAY_BUFFER , 0 , new Uint16Array ( this . iqueue ) )
375
362
this . ctx . setVertexFormat ( this . vertexFormat )
376
363
this . curShader . bind ( )
@@ -380,8 +367,8 @@ export class BatchRenderer {
380
367
this . curTex ?. unbind ( )
381
368
this . curShader . unbind ( )
382
369
383
- this . ctx . popBuffer ( gl . ARRAY_BUFFER )
384
- this . ctx . popBuffer ( gl . ELEMENT_ARRAY_BUFFER )
370
+ this . ctx . popArrayBuffer ( )
371
+ this . ctx . popElementArrayBuffer ( )
385
372
386
373
this . vqueue = [ ]
387
374
this . iqueue = [ ]
@@ -413,27 +400,27 @@ export class Mesh {
413
400
this . ctx = ctx
414
401
415
402
this . glVBuf = gl . createBuffer ( )
416
- ctx . pushBuffer ( gl . ARRAY_BUFFER , this . glVBuf )
403
+ ctx . pushArrayBuffer ( this . glVBuf )
417
404
gl . bufferData ( gl . ARRAY_BUFFER , new Float32Array ( verts ) , gl . STATIC_DRAW )
418
- ctx . popBuffer ( gl . ARRAY_BUFFER )
405
+ ctx . popArrayBuffer ( )
419
406
420
407
this . glIBuf = gl . createBuffer ( )
421
- ctx . pushBuffer ( gl . ELEMENT_ARRAY_BUFFER , this . glIBuf )
408
+ ctx . pushElementArrayBuffer ( this . glIBuf )
422
409
gl . bufferData ( gl . ELEMENT_ARRAY_BUFFER , new Uint16Array ( indices ) , gl . STATIC_DRAW )
423
- ctx . popBuffer ( gl . ELEMENT_ARRAY_BUFFER )
410
+ ctx . popElementArrayBuffer ( )
424
411
425
412
this . count = indices . length
426
413
427
414
}
428
415
429
416
draw ( primitive ?: GLenum ) {
430
417
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 )
433
420
this . ctx . setVertexFormat ( this . vertexFormat )
434
421
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 ( )
437
424
}
438
425
439
426
free ( ) {
@@ -445,36 +432,22 @@ export class Mesh {
445
432
446
433
}
447
434
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 )
469
440
}
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
470
447
}
471
448
472
- export default ( gl : WebGLRenderingContext ) : GfxCtx => {
449
+ export default function initGfx ( gl : WebGLRenderingContext ) {
473
450
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 ) )
478
451
const gc : Array < ( ) => void > = [ ]
479
452
480
453
function onDestroy ( action ) {
@@ -499,18 +472,48 @@ export default (gl: WebGLRenderingContext): GfxCtx => {
499
472
} , 0 )
500
473
}
501
474
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
+
502
499
return {
503
500
gl,
504
501
onDestroy,
505
502
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,
514
517
setVertexFormat,
515
518
}
516
519
0 commit comments