textmode.js 0.4.0 → 0.6.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/dist/textmode.esm.js +2868 -2164
  2. package/dist/textmode.esm.min.js +2863 -2159
  3. package/dist/textmode.umd.js +11 -8
  4. package/dist/textmode.umd.min.js +11 -8
  5. package/dist/types/Textmode.d.ts +13 -22
  6. package/dist/types/index.d.ts +8 -6
  7. package/dist/types/rendering/index.d.ts +3 -3
  8. package/dist/types/rendering/webgl/batching/DrawQueue.d.ts +89 -0
  9. package/dist/types/rendering/webgl/{VAOManager.d.ts → batching/GeometryAttributeCache.d.ts} +4 -4
  10. package/dist/types/rendering/webgl/batching/InstanceAttributeBinder.d.ts +87 -0
  11. package/dist/types/rendering/webgl/{InstanceBatch.d.ts → batching/InstanceBatch.d.ts} +25 -34
  12. package/dist/types/rendering/webgl/batching/InstanceBuffer.d.ts +78 -0
  13. package/dist/types/rendering/webgl/{InstanceData.d.ts → batching/InstanceData.d.ts} +11 -18
  14. package/dist/types/rendering/webgl/batching/InstanceWriter.d.ts +70 -0
  15. package/dist/types/rendering/webgl/{Framebuffer.d.ts → core/Framebuffer.d.ts} +37 -39
  16. package/dist/types/rendering/webgl/core/Renderer.d.ts +64 -0
  17. package/dist/types/rendering/webgl/{Shader.d.ts → core/Shader.d.ts} +2 -23
  18. package/dist/types/rendering/webgl/core/interfaces/IFramebuffer.d.ts +103 -0
  19. package/dist/types/rendering/webgl/core/interfaces/IRenderer.d.ts +210 -0
  20. package/dist/types/rendering/webgl/geometries/{Arc.d.ts → 2d/Arc.d.ts} +5 -4
  21. package/dist/types/rendering/webgl/geometries/{BezierCurve.d.ts → 2d/BezierCurve.d.ts} +5 -4
  22. package/dist/types/rendering/webgl/geometries/{Ellipse.d.ts → 2d/Ellipse.d.ts} +6 -5
  23. package/dist/types/rendering/webgl/geometries/{Line.d.ts → 2d/Line.d.ts} +5 -4
  24. package/dist/types/rendering/webgl/geometries/{Rectangle.d.ts → 2d/Rectangle.d.ts} +5 -4
  25. package/dist/types/rendering/webgl/geometries/{Triangle.d.ts → 2d/Triangle.d.ts} +5 -4
  26. package/dist/types/rendering/webgl/geometries/BaseGeometry.d.ts +30 -26
  27. package/dist/types/rendering/webgl/geometries/immediate/ImmediateQuad.d.ts +33 -0
  28. package/dist/types/rendering/webgl/geometries/index.d.ts +6 -6
  29. package/dist/types/rendering/webgl/geometries/utils/GeometryDescriptors.d.ts +31 -0
  30. package/dist/types/rendering/webgl/geometries/utils/GeometryGenerator.d.ts +16 -0
  31. package/dist/types/rendering/webgl/index.d.ts +15 -14
  32. package/dist/types/rendering/webgl/materials/Material.d.ts +26 -0
  33. package/dist/types/rendering/webgl/materials/MaterialManager.d.ts +63 -0
  34. package/dist/types/rendering/webgl/materials/index.d.ts +2 -0
  35. package/dist/types/rendering/webgl/pipeline/MaterialBatchPipeline.d.ts +63 -0
  36. package/dist/types/rendering/webgl/pipeline/index.d.ts +7 -0
  37. package/dist/types/rendering/webgl/state/RenderState.d.ts +143 -0
  38. package/dist/types/rendering/webgl/types/DrawCommand.d.ts +5 -3
  39. package/dist/types/rendering/webgl/types/GeometryTypes.d.ts +10 -10
  40. package/dist/types/rendering/webgl/types/RenderTypes.d.ts +1 -1
  41. package/dist/types/rendering/webgl/utils/GLUtils.d.ts +45 -0
  42. package/dist/types/rendering/webgl/utils/hash.d.ts +118 -0
  43. package/dist/types/textmode/AnimationController.d.ts +11 -21
  44. package/dist/types/textmode/Canvas.d.ts +10 -2
  45. package/dist/types/textmode/Grid.d.ts +2 -0
  46. package/dist/types/textmode/TextmodeColor.d.ts +57 -0
  47. package/dist/types/textmode/Textmodifier.d.ts +40 -212
  48. package/dist/types/textmode/interfaces/ITextmodifier.d.ts +272 -0
  49. package/dist/types/textmode/interfaces/index.d.ts +1 -0
  50. package/dist/types/textmode/loadables/TextmodeImage.d.ts +21 -0
  51. package/dist/types/textmode/loadables/TextmodeSource.d.ts +130 -0
  52. package/dist/types/textmode/loadables/TextmodeVideo.d.ts +237 -0
  53. package/dist/types/textmode/{font → loadables/font}/CharacterColorMapper.d.ts +1 -1
  54. package/dist/types/textmode/{font → loadables/font}/CharacterExtractor.d.ts +0 -10
  55. package/dist/types/textmode/{font → loadables/font}/TextmodeFont.d.ts +6 -3
  56. package/dist/types/textmode/{font → loadables/font}/TextureAtlas.d.ts +4 -11
  57. package/dist/types/textmode/{font → loadables/font}/typr/types.d.ts +0 -6
  58. package/dist/types/textmode/loadables/index.d.ts +5 -0
  59. package/dist/types/textmode/loading/LoadingPhaseTracker.d.ts +20 -0
  60. package/dist/types/textmode/loading/LoadingScreenManager.d.ts +170 -0
  61. package/dist/types/textmode/loading/LoadingScreenState.d.ts +22 -0
  62. package/dist/types/textmode/loading/LoadingScreenTheme.d.ts +26 -0
  63. package/dist/types/textmode/loading/LoadingScreenTransition.d.ts +17 -0
  64. package/dist/types/textmode/loading/index.d.ts +6 -0
  65. package/dist/types/textmode/loading/templates/SpinnerTemplate.d.ts +2 -0
  66. package/dist/types/textmode/loading/templates/index.d.ts +1 -0
  67. package/dist/types/textmode/loading/types.d.ts +251 -0
  68. package/dist/types/textmode/managers/KeyboardManager.d.ts +2 -3
  69. package/dist/types/textmode/managers/MouseManager.d.ts +1 -1
  70. package/dist/types/textmode/{plugins → managers}/PluginManager.d.ts +12 -15
  71. package/dist/types/textmode/managers/TouchManager.d.ts +0 -2
  72. package/dist/types/textmode/mixins/AnimationMixin.d.ts +2 -122
  73. package/dist/types/textmode/mixins/FontMixin.d.ts +2 -77
  74. package/dist/types/textmode/mixins/KeyboardMixin.d.ts +3 -85
  75. package/dist/types/textmode/mixins/MouseMixin.d.ts +3 -130
  76. package/dist/types/textmode/mixins/RenderingMixin.d.ts +2 -749
  77. package/dist/types/textmode/mixins/TextmodifierMixin.d.ts +2 -44
  78. package/dist/types/textmode/mixins/TouchMixin.d.ts +2 -187
  79. package/dist/types/textmode/mixins/index.d.ts +8 -8
  80. package/dist/types/textmode/mixins/interfaces/IAnimationMixin.d.ts +167 -0
  81. package/dist/types/textmode/mixins/interfaces/IFontMixin.d.ts +46 -0
  82. package/dist/types/textmode/mixins/interfaces/IKeyboardMixin.d.ts +235 -0
  83. package/dist/types/textmode/mixins/interfaces/IMouseMixin.d.ts +457 -0
  84. package/dist/types/textmode/mixins/interfaces/IRenderingMixin.d.ts +1085 -0
  85. package/dist/types/textmode/mixins/interfaces/ITouchMixin.d.ts +186 -0
  86. package/dist/types/textmode/types.d.ts +49 -0
  87. package/dist/types/textmode/utils/cssColor.d.ts +8 -0
  88. package/dist/types/utils/array.d.ts +34 -0
  89. package/dist/types/utils/math.d.ts +69 -0
  90. package/package.json +1 -1
  91. package/dist/types/rendering/webgl/DrawQueue.d.ts +0 -30
  92. package/dist/types/rendering/webgl/RenderPipeline.d.ts +0 -30
  93. package/dist/types/rendering/webgl/RenderState.d.ts +0 -73
  94. package/dist/types/rendering/webgl/Renderer.d.ts +0 -158
  95. package/dist/types/rendering/webgl/ShaderManager.d.ts +0 -66
  96. package/dist/types/rendering/webgl/geometries/NoiseGrid.d.ts +0 -1
  97. package/dist/types/textmode/TextmodeImage.d.ts +0 -161
  98. package/dist/types/textmode/mixins/ShaderMixin.d.ts +0 -1
  99. /package/dist/types/rendering/webgl/{StateCache.d.ts → utils/ViewportCache.d.ts} +0 -0
  100. /package/dist/types/textmode/{font → loadables/font}/MetricsCalculator.d.ts +0 -0
  101. /package/dist/types/textmode/{font → loadables/font}/index.d.ts +0 -0
  102. /package/dist/types/textmode/{font → loadables/font}/types.d.ts +0 -0
  103. /package/dist/types/textmode/{font → loadables/font}/typr/Typr.d.ts +0 -0
  104. /package/dist/types/textmode/{font → loadables/font}/utils/FontTableReader.d.ts +0 -0
  105. /package/dist/types/textmode/{font → loadables/font}/utils/index.d.ts +0 -0
@@ -0,0 +1,89 @@
1
+ import { RenderState } from '../state/RenderState';
2
+ import type { DrawCommand } from '../types/DrawCommand';
3
+ import type { Material } from '../materials/Material';
4
+ import type { RectangleParams, LineParams, EllipseParams, ArcParams, TriangleParams, BezierCurveParams } from '../types/GeometryTypes';
5
+ /**
6
+ * Global draw queue preserving user-issued draw order across geometry types.
7
+ *
8
+ * Performance optimizations:
9
+ * - Object pooling: Command slots are reused across frames to eliminate allocations
10
+ * - Direct property assignment: Maintains V8 hidden classes for optimal JIT performance
11
+ * - Type-specific enqueue methods: Eliminates conditional branching
12
+ */
13
+ export declare class DrawQueue implements Iterable<DrawCommand> {
14
+ private _commands;
15
+ private _nextId;
16
+ private _size;
17
+ /** Reserve or reuse a pooled slot */
18
+ private _acquireSlot;
19
+ /**
20
+ * Enqueue a rectangle draw command.
21
+ * Zero-allocation in steady state (reuses pooled slots).
22
+ * Direct property assignment preserves V8 hidden classes for optimal performance.
23
+ *
24
+ * @param params Rectangle parameters
25
+ * @param renderState Current render state
26
+ * @param material Material to use for rendering
27
+ * @returns Command ID
28
+ */
29
+ $enqueueRectangle(params: RectangleParams, renderState: RenderState, material: Material): number;
30
+ /**
31
+ * Enqueue a line draw command.
32
+ * Zero-allocation in steady state (reuses pooled slots).
33
+ * Direct property assignment preserves V8 hidden classes for optimal performance.
34
+ *
35
+ * @param params Line parameters
36
+ * @param renderState Current render state
37
+ * @param material Material to use for rendering
38
+ * @returns Command ID
39
+ */
40
+ $enqueueLine(params: LineParams, renderState: RenderState, material: Material): number;
41
+ /**
42
+ * Enqueue an ellipse draw command.
43
+ * Zero-allocation in steady state (reuses pooled slots).
44
+ * Direct property assignment preserves V8 hidden classes for optimal performance.
45
+ *
46
+ * @param params Ellipse parameters
47
+ * @param renderState Current render state
48
+ * @param material Material to use for rendering
49
+ * @returns Command ID
50
+ */
51
+ $enqueueEllipse(params: EllipseParams, renderState: RenderState, material: Material): number;
52
+ /**
53
+ * Enqueue an arc draw command.
54
+ * Zero-allocation in steady state (reuses pooled slots).
55
+ * Direct property assignment preserves V8 hidden classes for optimal performance.
56
+ *
57
+ * @param params Arc parameters
58
+ * @param renderState Current render state
59
+ * @param material Material to use for rendering
60
+ * @returns Command ID
61
+ */
62
+ $enqueueArc(params: ArcParams, renderState: RenderState, material: Material): number;
63
+ /**
64
+ * Enqueue a triangle draw command.
65
+ * Zero-allocation in steady state (reuses pooled slots).
66
+ * Direct property assignment preserves V8 hidden classes for optimal performance.
67
+ *
68
+ * @param params Triangle parameters
69
+ * @param renderState Current render state
70
+ * @param material Material to use for rendering
71
+ * @returns Command ID
72
+ */
73
+ $enqueueTriangle(params: TriangleParams, renderState: RenderState, material: Material): number;
74
+ /**
75
+ * Enqueue a bezier curve draw command.
76
+ * Zero-allocation in steady state (reuses pooled slots).
77
+ * Direct property assignment preserves V8 hidden classes for optimal performance.
78
+ *
79
+ * @param params Bezier curve parameters
80
+ * @param renderState Current render state
81
+ * @param material Material to use for rendering
82
+ * @returns Command ID
83
+ */
84
+ $enqueueBezierCurve(params: BezierCurveParams, renderState: RenderState, material: Material): number;
85
+ /** Clear all queued commands */
86
+ $clear(): void;
87
+ /** Iterate in the exact order of insertion */
88
+ [Symbol.iterator](): Iterator<DrawCommand>;
89
+ }
@@ -3,10 +3,10 @@
3
3
  * It binds only non-instanced attributes (a_position, a_texCoord). Instanced attributes are
4
4
  * still configured by InstanceBatch per draw to keep buffers flexible.
5
5
  */
6
- import type { UnitGeometryData } from './types/GeometryTypes';
7
- export declare class VAOManager {
8
- private readonly _gl;
9
- private readonly _cache;
6
+ import type { UnitGeometryData } from '../types/GeometryTypes';
7
+ export declare class GeometryAttributeCache {
8
+ private _gl;
9
+ private _cache;
10
10
  constructor(gl: WebGL2RenderingContext);
11
11
  /** Bind or create a VAO for the given program and geometry key. */
12
12
  $bind(program: WebGLProgram, geometryKey: string, unit: UnitGeometryData, geometryBuffer: WebGLBuffer): void;
@@ -0,0 +1,87 @@
1
+ import { GLShader } from '../core/Shader';
2
+ /**
3
+ * Manages WebGL attribute binding and GPU buffer synchronization.
4
+ *
5
+ * Responsibilities:
6
+ * - WebGL buffer creation and management
7
+ * - GPU data upload (full buffer or sub-buffer updates)
8
+ * - Attribute location caching per shader program
9
+ * - Vertex attribute binding/unbinding
10
+ *
11
+ * This class is the ONLY one that knows about WebGL state.
12
+ * It has NO knowledge of instance data layout details (delegates to InstanceAttributeLayout).
13
+ */
14
+ export declare class InstanceAttributeBinder {
15
+ private _gl;
16
+ private _glBuffer;
17
+ private _bufferCapacity;
18
+ private _attributeLocationCache;
19
+ /**
20
+ * Create a new attribute binder.
21
+ * @param gl WebGL2 rendering context
22
+ * @param initialCapacity Initial GPU buffer capacity in instances
23
+ */
24
+ constructor(gl: WebGL2RenderingContext, initialCapacity?: number);
25
+ /**
26
+ * Create or recreate the WebGL buffer with specified capacity.
27
+ * @param capacity Buffer capacity in number of instances
28
+ */
29
+ private _createBuffer;
30
+ /**
31
+ * Recreate GPU buffer with new capacity.
32
+ * Called when CPU buffer grows beyond current GPU buffer capacity.
33
+ *
34
+ * @param newCapacity New capacity in number of instances
35
+ */
36
+ recreateBuffer(newCapacity: number): void;
37
+ /**
38
+ * Get the current GPU buffer capacity in instances.
39
+ */
40
+ get capacity(): number;
41
+ /**
42
+ * Upload instance data to GPU buffer.
43
+ *
44
+ * Performance-critical: This uploads data to the GPU every frame.
45
+ * Optimizations applied:
46
+ * - Only uploads used portion of buffer (not full capacity)
47
+ * - Uses bufferSubData for partial updates (faster than bufferData)
48
+ * - Binds buffer once and keeps it bound for attribute setup
49
+ *
50
+ * Pattern follows modern graphics engines (three.js, babylon.js):
51
+ * - Minimize data transfer size
52
+ * - Avoid redundant buffer bindings
53
+ * - Use streaming pattern for per-frame data
54
+ *
55
+ * @param data Float32Array containing instance data to upload
56
+ * @param instanceCount Number of instances in the data
57
+ */
58
+ upload(data: Float32Array, instanceCount: number): void;
59
+ /**
60
+ * Get cached attribute locations for a shader program.
61
+ * Queries locations once per program and caches them for performance.
62
+ *
63
+ * @param program WebGL shader program
64
+ * @returns Map of attribute name to location
65
+ */
66
+ private _getAttributeLocations;
67
+ /**
68
+ * Bind instance buffer and configure vertex attributes for instanced rendering.
69
+ *
70
+ * IMPORTANT: Assumes instance buffer is already bound to gl.ARRAY_BUFFER from upload().
71
+ * If upload() was not called immediately before this, the buffer will not be bound correctly.
72
+ * The buffer remains bound after this call for use by the draw command.
73
+ *
74
+ * @param shader The shader program to bind attributes for
75
+ */
76
+ bindAttributes(shader: GLShader): void;
77
+ /**
78
+ * Unbind instance attributes to clean up WebGL state.
79
+ *
80
+ * @param shader The shader program to unbind attributes for
81
+ */
82
+ unbindAttributes(shader: GLShader): void;
83
+ /**
84
+ * Dispose of WebGL resources.
85
+ */
86
+ dispose(): void;
87
+ }
@@ -1,26 +1,32 @@
1
1
  import type { InstanceData } from './InstanceData';
2
- import { GLShader } from './Shader';
2
+ import { GLShader } from '../core/Shader';
3
+ import { type InstanceWriteData } from './InstanceWriter';
4
+ export type { InstanceWriteData };
3
5
  /**
4
6
  * High-performance instance batch manager for WebGL instanced rendering.
5
- * Handles efficient buffer management, automatic capacity growth, and WebGL attribute setup.
7
+ *
8
+ * This is a facade that orchestrates three specialized components:
9
+ * - InstanceBuffer: CPU-side memory management
10
+ * - InstanceWriter: Zero-allocation instance data writing
11
+ * - InstanceAttributeBinder: WebGL state and attribute binding
6
12
  *
7
13
  * Features:
14
+ * - Direct Float32Array writing (zero allocations per instance)
8
15
  * - Automatic buffer growth with configurable growth factor
9
- * - Double buffering for smooth updates
10
16
  * - Efficient sub-buffer updates for animated content
11
17
  * - Optimized WebGL attribute binding
12
- * - Memory pooling to reduce garbage collection
18
+ * - Struct-of-arrays layout for maximum GPU efficiency
19
+ *
20
+ * Architecture:
21
+ * This class maintains the same public API as before but delegates work
22
+ * to specialized components. This improves maintainability and testability
23
+ * while preserving performance.
13
24
  */
14
25
  export declare class InstanceBatch {
15
26
  private _gl;
16
- private _instances;
17
- private _capacity;
18
- private _growthFactor;
19
- private _instanceBuffer;
20
- private _needsUpload;
21
- private _lastUploadedCount;
22
- private _attributeLocationCache;
23
- private _packedDataCache;
27
+ private readonly _buffer;
28
+ private readonly _writer;
29
+ private readonly _binder;
24
30
  /**
25
31
  * Creates a new instance batch.
26
32
  * @param gl WebGL2 rendering context
@@ -29,11 +35,17 @@ export declare class InstanceBatch {
29
35
  */
30
36
  constructor(gl: WebGL2RenderingContext, initialCapacity?: number, growthFactor?: number);
31
37
  /**
32
- * Add a new instance to the batch.
38
+ * Add a new instance to the batch (legacy object-based path).
33
39
  * @param instance Instance data to add
34
40
  * @returns Index of the added instance
35
41
  */
36
42
  $addInstance(instance: InstanceData): number;
43
+ /**
44
+ * Write instance data directly to the buffer (zero-allocation fast path).
45
+ * @param data Instance write data
46
+ * @returns Index of the written instance
47
+ */
48
+ $writeInstance(data: InstanceWriteData): number;
37
49
  /**
38
50
  * Get the current number of instances in the batch.
39
51
  */
@@ -46,27 +58,6 @@ export declare class InstanceBatch {
46
58
  * Clear all instances from the batch.
47
59
  */
48
60
  clear(): void;
49
- /**
50
- * Ensure buffer capacity can handle the specified number of instances.
51
- * Automatically grows buffer if needed.
52
- * @param requiredInstances Number of instances that need to fit
53
- */
54
- private _ensureCapacity;
55
- /**
56
- * Create or recreate the WebGL instance buffer.
57
- */
58
- private _createBuffer;
59
- /**
60
- * Upload instance data to GPU buffer.
61
- * Uses efficient sub-buffer updates when possible.
62
- */
63
- $upload(): void;
64
- /**
65
- * Get cached attribute locations for a shader program.
66
- * @param program WebGL shader program
67
- * @returns Map of attribute name to location
68
- */
69
- private _getAttributeLocations;
70
61
  /**
71
62
  * Bind instance buffer and configure vertex attributes for instanced rendering.
72
63
  * @param shader The shader program to bind attributes for
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Manages raw Float32Array buffer with automatic capacity growth.
3
+ *
4
+ * Responsibilities:
5
+ * - Memory allocation and reallocation
6
+ * - Capacity management with configurable growth factor
7
+ * - Write pointer tracking
8
+ * - Buffer access for GPU upload
9
+ *
10
+ * This class has NO knowledge of WebGL or GPU state.
11
+ * It's purely a CPU-side memory manager.
12
+ */
13
+ export declare class InstanceBuffer {
14
+ private _buffer;
15
+ private _capacity;
16
+ private _growthFactor;
17
+ private _writeIndex;
18
+ private _instanceCount;
19
+ /**
20
+ * Create a new instance buffer.
21
+ * @param initialCapacity Initial capacity in number of instances
22
+ * @param growthFactor Multiplier for capacity growth (default: 1.5)
23
+ */
24
+ constructor(initialCapacity?: number, growthFactor?: number);
25
+ /**
26
+ * Ensure buffer has capacity for the specified number of instances.
27
+ * Automatically grows buffer if needed, preserving existing data.
28
+ *
29
+ * @param requiredInstances Number of instances that need to fit
30
+ */
31
+ ensureCapacity(requiredInstances: number): void;
32
+ /**
33
+ * Get write pointer for direct buffer writing.
34
+ * Returns the current buffer and offset for zero-allocation writes.
35
+ *
36
+ * @returns Object containing buffer reference and current write offset
37
+ */
38
+ getWritePointer(): {
39
+ buffer: Float32Array;
40
+ offset: number;
41
+ };
42
+ /**
43
+ * Commit a write operation, advancing the write pointer.
44
+ * Call this after writing floats to the buffer obtained from getWritePointer().
45
+ *
46
+ * @param floatsWritten Number of floats written (should be FLOATS_PER_INSTANCE)
47
+ */
48
+ commitWrite(floatsWritten: number): void;
49
+ /**
50
+ * Reset buffer to empty state.
51
+ * Does not deallocate memory, just resets write pointer.
52
+ */
53
+ reset(): void;
54
+ /**
55
+ * Get a subarray of the buffer containing used data.
56
+ *
57
+ * @param start Starting float index (default: 0)
58
+ * @param end Ending float index (default: current write position)
59
+ * @returns Float32Array view of the specified range
60
+ */
61
+ subarray(start?: number, end?: number): Float32Array;
62
+ /**
63
+ * Get the number of instances currently in the buffer.
64
+ */
65
+ get instanceCount(): number;
66
+ /**
67
+ * Get the current buffer capacity in instances.
68
+ */
69
+ get capacity(): number;
70
+ /**
71
+ * Get the current write index in floats.
72
+ */
73
+ get writeIndex(): number;
74
+ /**
75
+ * Check if buffer is empty.
76
+ */
77
+ get isEmpty(): boolean;
78
+ }
@@ -8,12 +8,13 @@ export interface InstanceData {
8
8
  _character: [number, number, number];
9
9
  _charColor: [number, number, number, number];
10
10
  _cellColor: [number, number, number, number];
11
- _charRotation: [number, number];
11
+ _charRotation: number;
12
12
  _charTransform: [number, number, number];
13
- _rotationX: number;
14
- _rotationY: number;
15
- _rotationZ: number;
16
- _rotationCenter: [number, number];
13
+ _translation: [number, number, number];
14
+ _rotation: [number, number, number];
15
+ _depth?: number;
16
+ _baseZ?: number;
17
+ _geometryType?: number;
17
18
  _arcAngles?: [number, number];
18
19
  _bezierControlPoint1?: [number, number];
19
20
  _bezierControlPoint2?: [number, number];
@@ -24,30 +25,22 @@ export interface InstanceData {
24
25
  * Optimized packed instance data layout for GPU upload.
25
26
  * Designed for efficient WebGL attribute binding and minimal memory usage.
26
27
  *
27
- * Total size: 132 bytes per instance (with Arc + Bezier support)
28
- * Layout designed to minimize GPU bandwidth and maximize cache efficiency.
28
+ * Total size: 144 bytes per instance (with Arc + Bezier + Translation + 3D support + Geometry Type)
29
29
  */
30
30
  export declare class PackedInstanceData {
31
- static readonly BYTES_PER_INSTANCE = 140;
32
- static readonly FLOATS_PER_INSTANCE = 35;
31
+ static readonly BYTES_PER_INSTANCE = 144;
32
+ static readonly FLOATS_PER_INSTANCE = 36;
33
33
  /**
34
34
  * Pack instance data into a Float32Array for efficient GPU upload.
35
- * @param instance The instance data to pack
36
- * @param target Optional target array to write into (for reuse)
37
- * @param offset Offset in the target array to start writing
38
- * @returns Float32Array containing packed instance data
39
35
  */
40
36
  static $pack(instance: InstanceData, target?: Float32Array, offset?: number): Float32Array;
41
37
  /**
42
38
  * Pack multiple instances into a single Float32Array for batch upload.
43
- * @param instances Array of instance data to pack
44
- * @returns Float32Array containing all packed instance data
45
39
  */
46
- static $packBatch(instances: InstanceData[]): Float32Array;
40
+ static $packBatch(instances: InstanceData[], targetBuffer?: Float32Array): Float32Array;
47
41
  }
48
42
  /**
49
43
  * WebGL attribute configuration for instance data.
50
- * Defines how packed instance data maps to vertex shader attributes.
51
44
  */
52
45
  export interface InstanceAttributeConfig {
53
46
  location: number;
@@ -62,6 +55,6 @@ export interface InstanceAttributeConfig {
62
55
  * Pre-configured attribute layouts for efficient WebGL setup.
63
56
  */
64
57
  export declare class InstanceAttributeLayout {
65
- static readonly STRIDE = 140;
58
+ static readonly STRIDE = 144;
66
59
  static readonly ATTRIBUTES: Record<string, InstanceAttributeConfig>;
67
60
  }
@@ -0,0 +1,70 @@
1
+ import type { InstanceBuffer } from './InstanceBuffer';
2
+ /**
3
+ * Data structure for direct instance writing (zero-allocation hot path).
4
+ * All fields are primitives to avoid object creation during rendering.
5
+ */
6
+ export interface InstanceWriteData {
7
+ x: number;
8
+ y: number;
9
+ width: number;
10
+ height: number;
11
+ char0: number;
12
+ char1: number;
13
+ char2: number;
14
+ r1: number;
15
+ g1: number;
16
+ b1: number;
17
+ a1: number;
18
+ r2: number;
19
+ g2: number;
20
+ b2: number;
21
+ a2: number;
22
+ invert: number;
23
+ flipX: number;
24
+ flipY: number;
25
+ charRot: number;
26
+ translationX: number;
27
+ translationY: number;
28
+ translationZ: number;
29
+ rotationX: number;
30
+ rotationY: number;
31
+ rotationZ: number;
32
+ curveParams0: [number, number, number, number];
33
+ curveParams1: [number, number, number, number];
34
+ depth: number;
35
+ baseZ: number;
36
+ geometryType: number;
37
+ }
38
+ /**
39
+ * High-performance instance writer for zero-allocation rendering.
40
+ *
41
+ * Responsibilities:
42
+ * - Direct Float32Array writing without intermediate allocations
43
+ * - Instance data packing according to GPU layout
44
+ * - Write coordination with InstanceBuffer
45
+ *
46
+ * This class knows about the instance data layout but has NO knowledge
47
+ * of WebGL, GPU buffers, or attribute binding.
48
+ */
49
+ export declare class InstanceWriter {
50
+ private _buffer;
51
+ /**
52
+ * Create a new instance writer.
53
+ * @param buffer The buffer to write instances into
54
+ */
55
+ constructor(buffer: InstanceBuffer);
56
+ /**
57
+ * Write instance data directly to the buffer (zero-allocation fast path).
58
+ *
59
+ * This is the hot path for rendering - optimized for minimal overhead.
60
+ * Writes directly to Float32Array without any intermediate allocations.
61
+ *
62
+ * @param data Instance write data
63
+ * @returns Index of the written instance
64
+ */
65
+ writeInstance(data: InstanceWriteData): number;
66
+ /**
67
+ * Get the current number of instances written.
68
+ */
69
+ get instanceCount(): number;
70
+ }
@@ -1,4 +1,6 @@
1
1
  import type { GLRenderer } from './Renderer';
2
+ import type { Material } from '../materials/Material';
3
+ import type { IFramebuffer } from './interfaces/IFramebuffer';
2
4
  export type FramebufferOptions = {
3
5
  /** Texture filtering mode */
4
6
  filter?: 'nearest' | 'linear';
@@ -8,24 +10,39 @@ export type FramebufferOptions = {
8
10
  format?: 'rgba' | 'rgb';
9
11
  /** Data type for texture data */
10
12
  type?: 'unsigned_byte' | 'float';
13
+ /** Enable depth buffer (defaults to true for 3D support) */
14
+ depth?: boolean;
15
+ };
16
+ /**
17
+ * Options for creating a framebuffer.
18
+ */
19
+ export type TextmodeFramebufferOptions = {
20
+ /** Width of the framebuffer in grid cells */
21
+ width: number;
22
+ /** Height of the framebuffer in grid cells */
23
+ height: number;
11
24
  };
12
25
  /**
13
26
  * Framebuffer class for managing offscreen rendering targets initialized via {@link Textmodifier.createFramebuffer}.
27
+ *
28
+ * `TextmodeFramebuffer` instances contain 3 attachments to support the rendering pipeline:
29
+ * - Attachment 0: Character and transform data *(RGBA)*
30
+ * - Attachment 1: Primary color data *(RGBA)*
31
+ * - Attachment 2: Secondary color data *(RGBA)*
14
32
  */
15
- export declare class GLFramebuffer {
33
+ export declare class GLFramebuffer implements IFramebuffer {
16
34
  protected _width: number;
17
35
  protected _height: number;
18
36
  protected _options: FramebufferOptions;
19
- protected _pixels: Uint8Array | null;
20
37
  private _gl;
21
38
  private _framebuffer;
22
39
  private _textures;
40
+ private _depthRenderbuffer;
23
41
  private _attachmentCount;
24
- private _previousState;
25
- private _attachmentPixels;
26
42
  private _renderer;
27
- private _isolatedState;
28
- private _stateForFBO;
43
+ private _material;
44
+ private _pixelCache;
45
+ private static _copyShader;
29
46
  /**
30
47
  * Create a new GLFramebuffer instance.
31
48
  * @param gl WebGL2 rendering context
@@ -34,28 +51,14 @@ export declare class GLFramebuffer {
34
51
  * @param attachmentCount Number of color attachments
35
52
  * @param options Framebuffer options
36
53
  * @param renderer Optional GLRenderer instance for state management
37
- * @param isolatedState Optional flag to isolate framebuffer state from renderer
38
54
  * @ignore
39
55
  */
40
- constructor(gl: WebGL2RenderingContext, width: number, height?: number, attachmentCount?: number, options?: FramebufferOptions, renderer?: GLRenderer | null, isolatedState?: boolean);
56
+ constructor(gl: WebGL2RenderingContext, width: number, height: number | undefined, attachmentCount: number | undefined, options: FramebufferOptions | undefined, renderer: GLRenderer);
41
57
  private _createTextures;
42
58
  private _attachTextures;
43
- /**
44
- * Update the framebuffer texture with canvas or video content
45
- * Note: Only updates the first attachment in multi-attachment mode
46
- * @ignore
47
- */
59
+ private _createDepthRenderbuffer;
48
60
  $update(source: HTMLCanvasElement | HTMLVideoElement): void;
49
- /**
50
- * Resize the framebuffer.
51
- * @param width New width
52
- * @param height New height
53
- */
54
61
  resize(width: number, height: number): void;
55
- /**
56
- * Read pixels from a specific color attachment into an RGBA Uint8Array.
57
- * @ignore
58
- */
59
62
  readPixels(attachmentIndex: number): Uint8Array;
60
63
  /**
61
64
  * Begin rendering to this framebuffer.
@@ -66,27 +69,22 @@ export declare class GLFramebuffer {
66
69
  */
67
70
  end(): void;
68
71
  /**
69
- * Dispose of WebGL resources used by this framebuffer.
70
- * This method is idempotent and safe to call multiple times.
72
+ * Get or create the material for rendering this framebuffer.
73
+ * @ignore
74
+ */
75
+ $getMaterial(): Material;
76
+ /**
77
+ * Update the material with current framebuffer textures.
71
78
  * @ignore
72
79
  */
80
+ private _updateMaterial;
73
81
  $dispose(): void;
74
- /** Get the current framebuffer width. */
82
+ /** Get the width of the framebuffer */
75
83
  get width(): number;
76
- /** Get the current framebuffer height. */
84
+ /** Get the height of the framebuffer */
77
85
  get height(): number;
78
- /**
79
- * Get all textures associated with this framebuffer.
80
- *
81
- * Useful for binding textures for reading in shaders.
82
- *
83
- * TextmodeFramebuffers have 5 attachments:
84
- * - 0: Character colors that encode the character to display via red and green channels
85
- * - 1: Character colors
86
- * - 2: Cell background colors
87
- * - 3: Rotation of each character encoded in red and green channels
88
- * - 4: Inversion, horizontal, and vertical flip flags encoded in red, green, blue channels
89
- *
90
- */
86
+ /** Get the WebGL textures associated with this framebuffer */
91
87
  get textures(): WebGLTexture[];
88
+ /** Get the number of color attachments in this framebuffer */
89
+ get attachmentCount(): number;
92
90
  }
@@ -0,0 +1,64 @@
1
+ import { GLFramebuffer } from "./Framebuffer";
2
+ import type { FramebufferOptions } from './Framebuffer';
3
+ import { GLShader } from "./Shader";
4
+ import { RenderState } from "../state/RenderState";
5
+ import type { TextmodeImage } from "../../../textmode/loadables/TextmodeImage";
6
+ import type { IRenderer } from "./interfaces/IRenderer";
7
+ export declare class GLRenderer implements IRenderer {
8
+ private _gl;
9
+ private _currentShader;
10
+ private readonly _renderPipeline;
11
+ private readonly _materialManager;
12
+ private _renderState;
13
+ private _drawQueue;
14
+ private readonly _immediateQuad;
15
+ private _userShader;
16
+ private _userUniforms;
17
+ private _framebufferBindingStack;
18
+ private _viewportStack;
19
+ private _currentFramebuffer;
20
+ private _currentViewport;
21
+ constructor(gl: WebGL2RenderingContext);
22
+ /**
23
+ * Push current framebuffer and viewport state onto the stack.
24
+ * Used by framebuffer begin() to save state before binding.
25
+ * @internal
26
+ */
27
+ $pushFramebufferState(): void;
28
+ /**
29
+ * Pop framebuffer and viewport state from the stack.
30
+ * Used by framebuffer end() to restore previous state.
31
+ * @internal
32
+ */
33
+ $popFramebufferState(): {
34
+ framebuffer: WebGLFramebuffer | null;
35
+ viewport: [number, number, number, number];
36
+ };
37
+ /**
38
+ * Bind a framebuffer and update CPU-side tracking.
39
+ * @internal
40
+ */
41
+ $bindFramebuffer(framebuffer: WebGLFramebuffer | null, width: number, height: number): void;
42
+ $shader(shader: GLShader): void;
43
+ $createShader(vertexSource: string, fragmentSource: string): GLShader;
44
+ $setUserShader(shader: GLShader | null): void;
45
+ $setUniform(name: string, value: any): void;
46
+ $setUserUniforms(uniforms: Record<string, any>): void;
47
+ $createFilterShader(fragmentSource: string): GLShader;
48
+ $image(source: GLFramebuffer | TextmodeImage, width?: number, height?: number): void;
49
+ $quad(x: number, y: number, width: number, height: number): void;
50
+ $rect(width: number, height: number): void;
51
+ $line(x1: number, y1: number, x2: number, y2: number): void;
52
+ $ellipse(width: number, height: number): void;
53
+ $triangle(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number): void;
54
+ $bezierCurve(x1: number, y1: number, cp1x: number, cp1y: number, cp2x: number, cp2y: number, x2: number, y2: number): void;
55
+ $arc(width: number, height: number, start: number, stop: number): void;
56
+ $createFramebuffer(width: number, height: number, attachmentCount?: number, options?: FramebufferOptions): GLFramebuffer;
57
+ $background(r: number, g?: number, b?: number, a?: number): void;
58
+ $clear(r?: number, g?: number, b?: number, a?: number): void;
59
+ $resetViewport(): void;
60
+ $flushInstances(): void;
61
+ $dispose(): void;
62
+ get context(): WebGLRenderingContext;
63
+ get state(): RenderState;
64
+ }