@zephyr3d/device 0.2.8 → 0.2.9

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.
@@ -1 +1 @@
1
- {"version":3,"file":"drawtext.js","sources":["../../src/helpers/drawtext.ts"],"sourcesContent":["import type { Immutable, Nullable } from '@zephyr3d/base';\r\nimport { Matrix4x4, parseColor, Vector3, Vector4 } from '@zephyr3d/base';\r\nimport { Font } from './font';\r\nimport { GlyphManager } from './glyphmanager';\r\nimport type { RenderStateSet } from '../render_states';\r\nimport type { AbstractDevice } from '../base_types';\r\nimport type { BindGroup, GPUProgram, StructuredBuffer, VertexLayout } from '../gpuobject';\r\n\r\nconst MAX_GLYPH_COUNT = 1024;\r\n\r\n/**\r\n * Helper class to draw some text onto the screen\r\n * @public\r\n */\r\nexport class DrawText {\r\n /** @internal */\r\n private static readonly GLYPH_COUNT = MAX_GLYPH_COUNT;\r\n /** @internal */\r\n private static glyphManager: Nullable<GlyphManager> = null;\r\n /** @internal */\r\n private static prepared = false;\r\n /** @internal */\r\n private static textVertexBuffer: Nullable<StructuredBuffer> = null;\r\n /** @internal */\r\n private static textVertexLayout: Nullable<VertexLayout> = null;\r\n /** @internal */\r\n private static textProgram: Nullable<GPUProgram> = null;\r\n /** @internal */\r\n private static textBindGroup: Nullable<BindGroup> = null;\r\n /** @internal */\r\n private static textRenderStates: Nullable<RenderStateSet> = null;\r\n /** @internal */\r\n private static textOffset = 0;\r\n /** @internal */\r\n private static readonly textMatrix = new Matrix4x4();\r\n /** @internal */\r\n private static font: Nullable<Font> = null;\r\n /** @internal */\r\n private static vertexCache: Nullable<Float32Array<ArrayBuffer>> = null;\r\n /** @internal */\r\n private static readonly colorValue: Vector4 = new Vector4();\r\n /** @internal */\r\n private static calculateTextMatrix(\r\n device: AbstractDevice,\r\n matrix: Matrix4x4,\r\n viewport?: Immutable<number[]>\r\n ) {\r\n const viewportWidth = viewport ? viewport[2] : device.getViewport().width;\r\n const viewportHeight = viewport ? viewport[3] : device.getViewport().height;\r\n matrix.identity();\r\n const projectionMatrix = Matrix4x4.ortho(0, viewportWidth, 0, viewportHeight, 1, 100);\r\n const flipMatrix = Matrix4x4.translation(new Vector3(0, viewportHeight, 0)).scaleRight(\r\n new Vector3(1, -1, 1)\r\n );\r\n Matrix4x4.multiply(projectionMatrix, flipMatrix, matrix);\r\n }\r\n /**\r\n * Set the font that will be used to draw strings\r\n * @param device - The render device\r\n * @param name - The font name\r\n */\r\n static setFont(device: AbstractDevice, name: string) {\r\n const scale = device.getScaleY();\r\n this.font = Font.fetchFont(name, scale) || Font.fetchFont('12px arial', scale);\r\n }\r\n /**\r\n * Draw text onto the screen\r\n * @param device - The render device\r\n * @param text - The text to be drawn\r\n * @param color - The text color\r\n * @param x - X coordinate of the text\r\n * @param y - Y coordinate of the text\r\n */\r\n static drawText(\r\n device: AbstractDevice,\r\n text: string,\r\n color: string,\r\n x: number,\r\n y: number,\r\n viewport?: Immutable<number[]>\r\n ) {\r\n if (text.length > 0) {\r\n device.pushDeviceStates();\r\n this.prepareDrawText(device);\r\n this.calculateTextMatrix(device, this.textMatrix, viewport);\r\n const colorValue = parseColor(color);\r\n this.colorValue.x = colorValue.r;\r\n this.colorValue.y = colorValue.g;\r\n this.colorValue.z = colorValue.b;\r\n this.colorValue.w = colorValue.a;\r\n this.textBindGroup!.setValue('flip', device.type === 'webgpu' && device.getFramebuffer() ? 1 : 0);\r\n this.textBindGroup!.setValue('srgbOut', device.getFramebuffer() ? 0 : 1);\r\n this.textBindGroup!.setValue('textMatrix', this.textMatrix);\r\n this.textBindGroup!.setValue('textColor', this.colorValue);\r\n device.setProgram(this.textProgram!);\r\n device.setVertexLayout(this.textVertexLayout!);\r\n device.setRenderStates(this.textRenderStates!);\r\n device.setBindGroup(0, this.textBindGroup!);\r\n let drawn = 0;\r\n const total = text.length;\r\n while (drawn < total) {\r\n const count = Math.min(total - drawn, this.GLYPH_COUNT - this.textOffset);\r\n if (count > 0) {\r\n x = this.drawTextNoOverflow(device, text, drawn, count, x, y);\r\n drawn += count;\r\n this.textOffset += count;\r\n }\r\n if (this.GLYPH_COUNT === this.textOffset) {\r\n this.textOffset = 0;\r\n device.flush();\r\n }\r\n }\r\n device.popDeviceStates();\r\n }\r\n }\r\n /** @internal */\r\n private static drawTextNoOverflow(\r\n device: AbstractDevice,\r\n text: string,\r\n start: number,\r\n count: number,\r\n x: number,\r\n y: number\r\n ) {\r\n let drawn = 0;\r\n let atlasIndex = -1;\r\n let i = 0;\r\n const vertexCache = this.vertexCache!;\r\n for (; i < count; i++) {\r\n const glyph =\r\n this.glyphManager!.getGlyphInfo(text[i + start], this.font!) ||\r\n this.glyphManager!.getGlyphInfo('?', this.font!)!;\r\n if (atlasIndex >= 0 && glyph.atlasIndex !== atlasIndex) {\r\n this.textVertexBuffer!.bufferSubData(\r\n (this.textOffset + drawn) * 16 * 4,\r\n this.vertexCache!,\r\n (this.textOffset + drawn) * 16,\r\n (i - drawn) * 16\r\n );\r\n this.textBindGroup!.setTexture('tex', this.glyphManager!.getAtlasTexture(atlasIndex)!);\r\n device.draw('triangle-list', (this.textOffset + drawn) * 6, (i - drawn) * 6);\r\n drawn = i;\r\n }\r\n atlasIndex = glyph.atlasIndex;\r\n const base = (this.textOffset + i) * 16;\r\n vertexCache[base + 0] = x;\r\n vertexCache[base + 1] = y;\r\n vertexCache[base + 2] = glyph.uMin;\r\n vertexCache[base + 3] = glyph.vMin;\r\n vertexCache[base + 4] = x + glyph.width;\r\n vertexCache[base + 5] = y;\r\n vertexCache[base + 6] = glyph.uMax;\r\n vertexCache[base + 7] = glyph.vMin;\r\n vertexCache[base + 8] = x + glyph.width;\r\n vertexCache[base + 9] = y + glyph.height;\r\n vertexCache[base + 10] = glyph.uMax;\r\n vertexCache[base + 11] = glyph.vMax;\r\n vertexCache[base + 12] = x;\r\n vertexCache[base + 13] = y + glyph.height;\r\n vertexCache[base + 14] = glyph.uMin;\r\n vertexCache[base + 15] = glyph.vMax;\r\n x += glyph.width;\r\n }\r\n this.textVertexBuffer!.bufferSubData(\r\n (this.textOffset + drawn) * 16 * 4,\r\n vertexCache,\r\n (this.textOffset + drawn) * 16,\r\n (i - drawn) * 16\r\n );\r\n this.textBindGroup!.setTexture('tex', this.glyphManager!.getAtlasTexture(atlasIndex)!);\r\n device.draw('triangle-list', (this.textOffset + drawn) * 6, (i - drawn) * 6);\r\n return x;\r\n }\r\n /** @internal */\r\n private static prepareDrawText(device: AbstractDevice) {\r\n if (!this.prepared) {\r\n this.prepared = true;\r\n this.font = this.font || Font.fetchFont('12px arial', device.getScaleY());\r\n this.glyphManager = new GlyphManager(device, 1024, 1024, 1);\r\n this.vertexCache = new Float32Array(this.GLYPH_COUNT * 16);\r\n this.textVertexBuffer = device.createInterleavedVertexBuffer(\r\n ['position_f32x2', 'tex0_f32x2'],\r\n this.vertexCache,\r\n {\r\n dynamic: true\r\n }\r\n );\r\n const indices = new Uint16Array(this.GLYPH_COUNT * 6);\r\n for (let i = 0; i < this.GLYPH_COUNT; i++) {\r\n const base = i * 4;\r\n indices[i * 6 + 0] = base + 0;\r\n indices[i * 6 + 1] = base + 1;\r\n indices[i * 6 + 2] = base + 2;\r\n indices[i * 6 + 3] = base + 0;\r\n indices[i * 6 + 4] = base + 2;\r\n indices[i * 6 + 5] = base + 3;\r\n }\r\n const textIndexBuffer = device.createIndexBuffer(indices);\r\n this.textVertexLayout = device.createVertexLayout({\r\n vertexBuffers: [{ buffer: this.textVertexBuffer! }],\r\n indexBuffer: textIndexBuffer\r\n });\r\n this.textOffset = 0;\r\n this.textProgram = device.buildRenderProgram({\r\n vertex(pb) {\r\n this.$inputs.pos = pb.vec2().attrib('position');\r\n this.$inputs.uv = pb.vec2().attrib('texCoord0');\r\n this.$outputs.uv = pb.vec2();\r\n this.flip = pb.int(0).uniform(0);\r\n this.textMatrix = pb.mat4().uniform(0);\r\n pb.main(function () {\r\n this.$builtins.position = pb.mul(this.textMatrix, pb.vec4(this.$inputs.pos, -50, 1));\r\n this.$if(pb.notEqual(this.flip, 0), function () {\r\n this.$builtins.position.y = pb.neg(this.$builtins.position.y);\r\n });\r\n this.$outputs.uv = this.$inputs.uv;\r\n });\r\n },\r\n fragment(pb) {\r\n this.$outputs.color = pb.vec4();\r\n this.textColor = pb.vec4().uniform(0);\r\n this.tex = pb.tex2D().uniform(0);\r\n this.srgbOut = pb.int().uniform(0);\r\n pb.main(function () {\r\n this.alpha = pb.mul(pb.textureSample(this.tex, this.$inputs.uv).a, this.textColor.a);\r\n this.$if(pb.notEqual(this.srgbOut, 0), function () {\r\n this.$outputs.color = pb.vec4(\r\n pb.mul(pb.pow(this.textColor.rgb, pb.vec3(1 / 2.2)), this.alpha),\r\n this.alpha\r\n );\r\n }).$else(function () {\r\n this.$outputs.color = pb.vec4(pb.mul(this.textColor.rgb, this.alpha), this.alpha);\r\n });\r\n });\r\n }\r\n });\r\n this.textProgram!.name = '@DrawText';\r\n this.textBindGroup = device.createBindGroup(this.textProgram!.bindGroupLayouts[0]);\r\n this.textRenderStates = device.createRenderStateSet();\r\n this.textRenderStates\r\n .useBlendingState()\r\n .enable(true)\r\n .setBlendFuncRGB('one', 'inv-src-alpha')\r\n .setBlendFuncAlpha('zero', 'one');\r\n this.textRenderStates.useDepthState().enableTest(false).enableWrite(false);\r\n this.textRenderStates.useRasterizerState().setCullMode('none');\r\n }\r\n }\r\n}\r\n"],"names":["MAX_GLYPH_COUNT","DrawText","GLYPH_COUNT","glyphManager","prepared","textVertexBuffer","textVertexLayout","textProgram","textBindGroup","textRenderStates","textOffset","textMatrix","Matrix4x4","font","vertexCache","colorValue","Vector4","calculateTextMatrix","device","matrix","viewport","viewportWidth","getViewport","width","viewportHeight","height","identity","projectionMatrix","ortho","flipMatrix","translation","Vector3","scaleRight","multiply","setFont","name","scale","getScaleY","Font","fetchFont","drawText","text","color","x","y","length","pushDeviceStates","prepareDrawText","parseColor","r","g","z","b","w","a","setValue","type","getFramebuffer","setProgram","setVertexLayout","setRenderStates","setBindGroup","drawn","total","count","Math","min","drawTextNoOverflow","flush","popDeviceStates","start","atlasIndex","i","glyph","getGlyphInfo","bufferSubData","setTexture","getAtlasTexture","draw","base","uMin","vMin","uMax","vMax","GlyphManager","Float32Array","createInterleavedVertexBuffer","dynamic","indices","Uint16Array","textIndexBuffer","createIndexBuffer","createVertexLayout","vertexBuffers","buffer","indexBuffer","buildRenderProgram","vertex","pb","$inputs","pos","vec2","attrib","uv","$outputs","flip","int","uniform","mat4","main","$builtins","position","mul","vec4","$if","notEqual","neg","fragment","textColor","tex","tex2D","srgbOut","alpha","textureSample","pow","rgb","vec3","$else","createBindGroup","bindGroupLayouts","createRenderStateSet","useBlendingState","enable","setBlendFuncRGB","setBlendFuncAlpha","useDepthState","enableTest","enableWrite","useRasterizerState","setCullMode"],"mappings":"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"}
1
+ {"version":3,"file":"drawtext.js","sources":["../../src/helpers/drawtext.ts"],"sourcesContent":["import type { Immutable, Nullable, Rect } from '@zephyr3d/base';\r\nimport { Matrix4x4, parseColor, splitStringByGraphemes, Vector3, Vector4 } from '@zephyr3d/base';\r\nimport { Font } from './font';\r\nimport { GlyphManager } from './glyphmanager';\r\nimport type { RenderStateSet } from '../render_states';\r\nimport type {\r\n AbstractDevice,\r\n DrawTextLayoutOptions,\r\n TextHorizontalAlignment,\r\n TextVerticalAlignment\r\n} from '../base_types';\r\nimport type { BindGroup, GPUProgram, StructuredBuffer, VertexLayout } from '../gpuobject';\r\n\r\nconst MAX_GLYPH_COUNT = 1024;\r\n\r\ntype TextLayoutLine = {\r\n text: string;\r\n width: number;\r\n};\r\n\r\ntype ResolvedTextLayoutOptions = {\r\n halign: TextHorizontalAlignment;\r\n valign: TextVerticalAlignment;\r\n wordWrap: boolean;\r\n};\r\n\r\n/**\r\n * Helper class to draw some text onto the screen\r\n * @public\r\n */\r\nexport class DrawText {\r\n /** @internal */\r\n private static readonly GLYPH_COUNT = MAX_GLYPH_COUNT;\r\n /** @internal */\r\n private static glyphManager: Nullable<GlyphManager> = null;\r\n /** @internal */\r\n private static prepared = false;\r\n /** @internal */\r\n private static textVertexBuffer: Nullable<StructuredBuffer> = null;\r\n /** @internal */\r\n private static textVertexLayout: Nullable<VertexLayout> = null;\r\n /** @internal */\r\n private static textProgram: Nullable<GPUProgram> = null;\r\n /** @internal */\r\n private static textBindGroup: Nullable<BindGroup> = null;\r\n /** @internal */\r\n private static textRenderStates: Nullable<RenderStateSet> = null;\r\n /** @internal */\r\n private static textOffset = 0;\r\n /** @internal */\r\n private static readonly textMatrix = new Matrix4x4();\r\n /** @internal */\r\n private static font: Nullable<Font> = null;\r\n /** @internal */\r\n private static overrideRenderStates: Nullable<RenderStateSet> = null;\r\n /** @internal */\r\n private static vertexCache: Nullable<Float32Array<ArrayBuffer>> = null;\r\n /** @internal */\r\n private static readonly colorValue: Vector4 = new Vector4();\r\n /** @internal */\r\n private static readonly defaultLayoutOptions: ResolvedTextLayoutOptions = {\r\n halign: 'left',\r\n valign: 'top',\r\n wordWrap: false\r\n };\r\n /** @internal */\r\n private static calculateTextMatrix(device: AbstractDevice, matrix: Matrix4x4) {\r\n const viewportWidth = device.getViewport().width;\r\n const viewportHeight = device.getViewport().height;\r\n matrix.identity();\r\n const projectionMatrix = Matrix4x4.ortho(0, viewportWidth, 0, viewportHeight, 1, 100);\r\n const flipMatrix = Matrix4x4.translation(new Vector3(0, viewportHeight, 0)).scaleRight(\r\n new Vector3(1, -1, 1)\r\n );\r\n Matrix4x4.multiply(projectionMatrix, flipMatrix, matrix);\r\n }\r\n /**\r\n * Set the font that will be used to draw strings\r\n * @param device - The render device\r\n * @param name - The font name\r\n */\r\n static setFont(device: AbstractDevice, name: Nullable<string>) {\r\n const scale = device.getScaleY();\r\n this.font = name ? Font.fetchFont(name, scale) : Font.fetchFont('12px arial', scale);\r\n }\r\n /**\r\n * Set render states to be used when drawing text. If not set, default states will be used.\r\n * @param renderStates - The render states to use when drawing text. If null, default states will be used.\r\n */\r\n static setRenderStates(renderStates: Nullable<RenderStateSet>) {\r\n this.overrideRenderStates = renderStates ?? null;\r\n }\r\n /**\r\n * Draw text onto the screen\r\n * @param device - The render device\r\n * @param text - The text to be drawn\r\n * @param color - The text color\r\n * @param x - X coordinate of the text\r\n * @param y - Y coordinate of the text\r\n */\r\n static drawText(\r\n device: AbstractDevice,\r\n text: string,\r\n color: string | Vector3 | Vector4,\r\n x: number,\r\n y: number\r\n ): void;\r\n /**\r\n * Draw text inside a rectangle with layout and clipping\r\n * @param device - The render device\r\n * @param text - The text to be drawn\r\n * @param color - The text color\r\n * @param rect - The layout rectangle\r\n * @param options - Layout options\r\n */\r\n static drawText(\r\n device: AbstractDevice,\r\n text: string,\r\n color: string | Vector3 | Vector4,\r\n rect: Immutable<Rect>,\r\n options?: DrawTextLayoutOptions\r\n ): void;\r\n static drawText(\r\n device: AbstractDevice,\r\n text: string,\r\n color: string | Vector3 | Vector4,\r\n xOrRect: number | Immutable<Rect>,\r\n yOrOptions?: number | DrawTextLayoutOptions\r\n ) {\r\n this.colorToVec4(color, this.colorValue);\r\n if (typeof xOrRect === 'number') {\r\n if (text.length > 0) {\r\n device.pushDeviceStates();\r\n try {\r\n this.beginDrawText(device);\r\n this.drawPreparedText(device, text, xOrRect, yOrOptions as number);\r\n } finally {\r\n device.popDeviceStates();\r\n }\r\n }\r\n return;\r\n }\r\n this.drawTextRect(device, text, xOrRect, yOrOptions as DrawTextLayoutOptions);\r\n }\r\n /** @internal */\r\n private static drawTextRect(\r\n device: AbstractDevice,\r\n text: string,\r\n rect: Immutable<Rect>,\r\n options?: DrawTextLayoutOptions\r\n ) {\r\n if (text.length > 0 && rect.width > 0 && rect.height > 0) {\r\n device.pushDeviceStates();\r\n try {\r\n this.beginDrawText(device);\r\n const viewport = device.getViewport();\r\n const resolved = this.resolveLayoutOptions(options);\r\n const lines = this.layoutText(text, rect.width, resolved.wordWrap);\r\n if (lines.length === 0) {\r\n return;\r\n }\r\n const lineHeight = this.font!.maxHeight;\r\n const blockHeight = lines.length * lineHeight;\r\n let startY = rect.y;\r\n if (resolved.valign === 'center') {\r\n startY += (rect.height - blockHeight) * 0.5;\r\n } else if (resolved.valign === 'bottom') {\r\n startY += rect.height - blockHeight;\r\n }\r\n const absoluteScissorRect = {\r\n x: viewport.x + rect.x,\r\n y: viewport.y + viewport.height - rect.y - rect.height,\r\n width: rect.width,\r\n height: rect.height\r\n };\r\n const currentScissor = device.getScissor();\r\n const clipX = Math.max(absoluteScissorRect.x, currentScissor.x);\r\n const clipY = Math.max(absoluteScissorRect.y, currentScissor.y);\r\n const clipRight = Math.min(\r\n absoluteScissorRect.x + absoluteScissorRect.width,\r\n currentScissor.x + currentScissor.width\r\n );\r\n const clipBottom = Math.min(\r\n absoluteScissorRect.y + absoluteScissorRect.height,\r\n currentScissor.y + currentScissor.height\r\n );\r\n const clipWidth = Math.max(0, clipRight - clipX);\r\n const clipHeight = Math.max(0, clipBottom - clipY);\r\n if (clipWidth <= 0 || clipHeight <= 0) {\r\n return;\r\n }\r\n device.setScissor([clipX, clipY, clipWidth, clipHeight]);\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i];\r\n const lineY = startY + i * lineHeight;\r\n if (lineY + lineHeight <= rect.y || lineY >= rect.y + rect.height) {\r\n continue;\r\n }\r\n let lineX = rect.x;\r\n if (resolved.halign === 'center') {\r\n lineX += (rect.width - line.width) * 0.5;\r\n } else if (resolved.halign === 'right') {\r\n lineX += rect.width - line.width;\r\n }\r\n this.drawPreparedText(device, line.text, lineX, lineY);\r\n }\r\n } finally {\r\n device.popDeviceStates();\r\n }\r\n }\r\n }\r\n /** @internal */\r\n private static drawTextNoOverflow(\r\n device: AbstractDevice,\r\n text: string[],\r\n start: number,\r\n count: number,\r\n x: number,\r\n y: number\r\n ) {\r\n let drawn = 0;\r\n let atlasIndex = -1;\r\n let i = 0;\r\n const vertexCache = this.vertexCache!;\r\n for (; i < count; i++) {\r\n const glyph =\r\n this.glyphManager!.getGlyphInfo(text[i + start], this.font!) ||\r\n this.glyphManager!.getGlyphInfo('?', this.font!)!;\r\n if (atlasIndex >= 0 && glyph.atlasIndex !== atlasIndex) {\r\n this.textVertexBuffer!.bufferSubData(\r\n (this.textOffset + drawn) * 16 * 4,\r\n this.vertexCache!,\r\n (this.textOffset + drawn) * 16,\r\n (i - drawn) * 16\r\n );\r\n this.textBindGroup!.setTexture('tex', this.glyphManager!.getAtlasTexture(atlasIndex)!);\r\n device.draw('triangle-list', (this.textOffset + drawn) * 6, (i - drawn) * 6);\r\n drawn = i;\r\n }\r\n atlasIndex = glyph.atlasIndex;\r\n const base = (this.textOffset + i) * 16;\r\n vertexCache[base + 0] = x;\r\n vertexCache[base + 1] = y;\r\n vertexCache[base + 2] = glyph.uMin;\r\n vertexCache[base + 3] = glyph.vMin;\r\n vertexCache[base + 4] = x + glyph.width;\r\n vertexCache[base + 5] = y;\r\n vertexCache[base + 6] = glyph.uMax;\r\n vertexCache[base + 7] = glyph.vMin;\r\n vertexCache[base + 8] = x + glyph.width;\r\n vertexCache[base + 9] = y + glyph.height;\r\n vertexCache[base + 10] = glyph.uMax;\r\n vertexCache[base + 11] = glyph.vMax;\r\n vertexCache[base + 12] = x;\r\n vertexCache[base + 13] = y + glyph.height;\r\n vertexCache[base + 14] = glyph.uMin;\r\n vertexCache[base + 15] = glyph.vMax;\r\n x += glyph.width;\r\n }\r\n this.textVertexBuffer!.bufferSubData(\r\n (this.textOffset + drawn) * 16 * 4,\r\n vertexCache,\r\n (this.textOffset + drawn) * 16,\r\n (i - drawn) * 16\r\n );\r\n this.textBindGroup!.setTexture('tex', this.glyphManager!.getAtlasTexture(atlasIndex)!);\r\n device.draw('triangle-list', (this.textOffset + drawn) * 6, (i - drawn) * 6);\r\n return x;\r\n }\r\n /** @internal */\r\n private static colorToVec4(color: string | Vector3 | Vector4, out: Vector4): Vector4 {\r\n if (typeof color === 'string') {\r\n const colorValue = parseColor(color);\r\n out.setXYZW(colorValue.r, colorValue.g, colorValue.b, colorValue.a);\r\n } else if (color instanceof Vector3) {\r\n out.setXYZW(color.x, color.y, color.z, 1);\r\n } else {\r\n out.set(color);\r\n }\r\n return out;\r\n }\r\n /** @internal */\r\n private static beginDrawText(device: AbstractDevice) {\r\n this.prepareDrawText(device);\r\n this.calculateTextMatrix(device, this.textMatrix);\r\n this.textBindGroup!.setValue('flip', device.type === 'webgpu' && device.getFramebuffer() ? 1 : 0);\r\n this.textBindGroup!.setValue('srgbOut', device.getFramebuffer() ? 0 : 1);\r\n this.textBindGroup!.setValue('textMatrix', this.textMatrix);\r\n this.textBindGroup!.setValue('textColor', this.colorValue);\r\n device.setProgram(this.textProgram!);\r\n device.setVertexLayout(this.textVertexLayout!);\r\n device.setRenderStates(this.overrideRenderStates ?? this.textRenderStates!);\r\n device.setBindGroup(0, this.textBindGroup!);\r\n }\r\n /** @internal */\r\n private static drawPreparedText(device: AbstractDevice, text: string, x: number, y: number) {\r\n let drawn = 0;\r\n const splitted = splitStringByGraphemes(text);\r\n const total = splitted.length;\r\n while (drawn < total) {\r\n const count = Math.min(total - drawn, this.GLYPH_COUNT - this.textOffset);\r\n if (count > 0) {\r\n x = this.drawTextNoOverflow(device, splitted, drawn, count, x, y);\r\n drawn += count;\r\n this.textOffset += count;\r\n }\r\n if (this.GLYPH_COUNT === this.textOffset) {\r\n this.textOffset = 0;\r\n device.flush();\r\n }\r\n }\r\n }\r\n /** @internal */\r\n private static resolveLayoutOptions(options?: DrawTextLayoutOptions): ResolvedTextLayoutOptions {\r\n return {\r\n halign: options?.halign ?? this.defaultLayoutOptions.halign,\r\n valign: options?.valign ?? this.defaultLayoutOptions.valign,\r\n wordWrap: options?.wordWrap ?? this.defaultLayoutOptions.wordWrap\r\n };\r\n }\r\n /** @internal */\r\n private static layoutText(text: string, maxWidth: number, wordWrap: boolean): TextLayoutLine[] {\r\n const result: TextLayoutLine[] = [];\r\n const paragraphs = text.split(/\\r\\n|\\r|\\n/);\r\n for (const paragraph of paragraphs) {\r\n if (!wordWrap) {\r\n result.push({\r\n text: paragraph,\r\n width: this.measureLineWidth(paragraph)\r\n });\r\n continue;\r\n }\r\n this.layoutWrappedParagraph(paragraph, maxWidth, result);\r\n }\r\n return result;\r\n }\r\n /** @internal */\r\n private static layoutWrappedParagraph(text: string, maxWidth: number, out: TextLayoutLine[]) {\r\n if (text.length === 0) {\r\n out.push({ text: '', width: 0 });\r\n return;\r\n }\r\n const chars = splitStringByGraphemes(text);\r\n let start = 0;\r\n while (start < chars.length) {\r\n let width = 0;\r\n let breakPos = start;\r\n let lastWhitespaceBreak = -1;\r\n while (breakPos < chars.length) {\r\n const ch = chars[breakPos];\r\n const charWidth = this.glyphManager!.getCharWidth(ch, this.font!);\r\n if (breakPos > start && width + charWidth > maxWidth) {\r\n break;\r\n }\r\n width += charWidth;\r\n breakPos++;\r\n if (/^\\s$/u.test(ch)) {\r\n lastWhitespaceBreak = breakPos;\r\n }\r\n }\r\n if (breakPos < chars.length && lastWhitespaceBreak > start) {\r\n const lineText = chars.slice(start, lastWhitespaceBreak).join('').replace(/\\s+$/u, '');\r\n out.push({\r\n text: lineText,\r\n width: this.measureLineWidth(lineText)\r\n });\r\n start = lastWhitespaceBreak;\r\n while (start < chars.length && /^\\s$/u.test(chars[start])) {\r\n start++;\r\n }\r\n } else {\r\n const lineText = chars.slice(start, breakPos).join('');\r\n out.push({\r\n text: lineText,\r\n width\r\n });\r\n start = Math.max(breakPos, start + 1);\r\n }\r\n }\r\n }\r\n /** @internal */\r\n private static measureLineWidth(text: string) {\r\n if (!text) {\r\n return 0;\r\n }\r\n let width = 0;\r\n for (const ch of splitStringByGraphemes(text)) {\r\n width += this.glyphManager!.getCharWidth(ch, this.font!);\r\n }\r\n return width;\r\n }\r\n /** @internal */\r\n private static prepareDrawText(device: AbstractDevice) {\r\n if (!this.prepared) {\r\n this.prepared = true;\r\n this.font = this.font || Font.fetchFont('12px arial', device.getScaleY());\r\n this.glyphManager = new GlyphManager(device, 1024, 1024, 1);\r\n this.vertexCache = new Float32Array(this.GLYPH_COUNT * 16);\r\n this.textVertexBuffer = device.createInterleavedVertexBuffer(\r\n ['position_f32x2', 'tex0_f32x2'],\r\n this.vertexCache,\r\n {\r\n dynamic: true\r\n }\r\n );\r\n const indices = new Uint16Array(this.GLYPH_COUNT * 6);\r\n for (let i = 0; i < this.GLYPH_COUNT; i++) {\r\n const base = i * 4;\r\n indices[i * 6 + 0] = base + 0;\r\n indices[i * 6 + 1] = base + 1;\r\n indices[i * 6 + 2] = base + 2;\r\n indices[i * 6 + 3] = base + 0;\r\n indices[i * 6 + 4] = base + 2;\r\n indices[i * 6 + 5] = base + 3;\r\n }\r\n const textIndexBuffer = device.createIndexBuffer(indices);\r\n this.textVertexLayout = device.createVertexLayout({\r\n vertexBuffers: [{ buffer: this.textVertexBuffer! }],\r\n indexBuffer: textIndexBuffer\r\n });\r\n this.textOffset = 0;\r\n this.textProgram = device.buildRenderProgram({\r\n vertex(pb) {\r\n this.$inputs.pos = pb.vec2().attrib('position');\r\n this.$inputs.uv = pb.vec2().attrib('texCoord0');\r\n this.$outputs.uv = pb.vec2();\r\n this.flip = pb.int(0).uniform(0);\r\n this.textMatrix = pb.mat4().uniform(0);\r\n pb.main(function () {\r\n this.$builtins.position = pb.mul(this.textMatrix, pb.vec4(this.$inputs.pos, -50, 1));\r\n this.$if(pb.notEqual(this.flip, 0), function () {\r\n this.$builtins.position.y = pb.neg(this.$builtins.position.y);\r\n });\r\n this.$outputs.uv = this.$inputs.uv;\r\n });\r\n },\r\n fragment(pb) {\r\n this.$outputs.color = pb.vec4();\r\n this.textColor = pb.vec4().uniform(0);\r\n this.tex = pb.tex2D().uniform(0);\r\n this.srgbOut = pb.int().uniform(0);\r\n pb.main(function () {\r\n this.alpha = pb.mul(pb.textureSample(this.tex, this.$inputs.uv).a, this.textColor.a);\r\n this.$if(pb.notEqual(this.srgbOut, 0), function () {\r\n this.$outputs.color = pb.vec4(\r\n pb.mul(pb.pow(this.textColor.rgb, pb.vec3(1 / 2.2)), this.alpha),\r\n this.alpha\r\n );\r\n }).$else(function () {\r\n this.$outputs.color = pb.vec4(pb.mul(this.textColor.rgb, this.alpha), this.alpha);\r\n });\r\n });\r\n }\r\n });\r\n this.textProgram!.name = '@DrawText';\r\n this.textBindGroup = device.createBindGroup(this.textProgram!.bindGroupLayouts[0]);\r\n this.textRenderStates = device.createRenderStateSet();\r\n this.textRenderStates\r\n .useBlendingState()\r\n .enable(true)\r\n .setBlendFuncRGB('one', 'inv-src-alpha')\r\n .setBlendFuncAlpha('zero', 'one');\r\n this.textRenderStates.useDepthState().enableTest(false).enableWrite(false);\r\n this.textRenderStates.useRasterizerState().setCullMode('none');\r\n }\r\n }\r\n}\r\n"],"names":["MAX_GLYPH_COUNT","DrawText","GLYPH_COUNT","glyphManager","prepared","textVertexBuffer","textVertexLayout","textProgram","textBindGroup","textRenderStates","textOffset","textMatrix","Matrix4x4","font","overrideRenderStates","vertexCache","colorValue","Vector4","defaultLayoutOptions","halign","valign","wordWrap","calculateTextMatrix","device","matrix","viewportWidth","getViewport","width","viewportHeight","height","identity","projectionMatrix","ortho","flipMatrix","translation","Vector3","scaleRight","multiply","setFont","name","scale","getScaleY","Font","fetchFont","setRenderStates","renderStates","drawText","text","color","xOrRect","yOrOptions","colorToVec4","length","pushDeviceStates","beginDrawText","drawPreparedText","popDeviceStates","drawTextRect","rect","options","viewport","resolved","resolveLayoutOptions","lines","layoutText","lineHeight","maxHeight","blockHeight","startY","y","absoluteScissorRect","x","currentScissor","getScissor","clipX","Math","max","clipY","clipRight","min","clipBottom","clipWidth","clipHeight","setScissor","i","line","lineY","lineX","drawTextNoOverflow","start","count","drawn","atlasIndex","glyph","getGlyphInfo","bufferSubData","setTexture","getAtlasTexture","draw","base","uMin","vMin","uMax","vMax","out","parseColor","setXYZW","r","g","b","a","z","set","prepareDrawText","setValue","type","getFramebuffer","setProgram","setVertexLayout","setBindGroup","splitted","splitStringByGraphemes","total","flush","maxWidth","result","paragraphs","split","paragraph","push","measureLineWidth","layoutWrappedParagraph","chars","breakPos","lastWhitespaceBreak","ch","charWidth","getCharWidth","test","lineText","slice","join","replace","GlyphManager","Float32Array","createInterleavedVertexBuffer","dynamic","indices","Uint16Array","textIndexBuffer","createIndexBuffer","createVertexLayout","vertexBuffers","buffer","indexBuffer","buildRenderProgram","vertex","pb","$inputs","pos","vec2","attrib","uv","$outputs","flip","int","uniform","mat4","main","$builtins","position","mul","vec4","$if","notEqual","neg","fragment","textColor","tex","tex2D","srgbOut","alpha","textureSample","pow","rgb","vec3","$else","createBindGroup","bindGroupLayouts","createRenderStateSet","useBlendingState","enable","setBlendFuncRGB","setBlendFuncAlpha","useDepthState","enableTest","enableWrite","useRasterizerState","setCullMode"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { RectsPacker } from '@zephyr3d/base';
1
+ import { RectsPacker, DRef } from '@zephyr3d/base';
2
2
 
3
3
  /**
4
4
  * Texture atlas manager
@@ -47,7 +47,22 @@ import { RectsPacker } from '@zephyr3d/base';
47
47
  * @param index - Index of the atlas bin
48
48
  * @returns Atlas texture for given index
49
49
  */ getAtlasTexture(index) {
50
- return this._atlasList[index];
50
+ return this._atlasList[index]?.get() ?? undefined;
51
+ }
52
+ /**
53
+ * Width of each atlas bin in texels.
54
+ */ get binWidth() {
55
+ return this._binWidth;
56
+ }
57
+ /**
58
+ * Height of each atlas bin in texels.
59
+ */ get binHeight() {
60
+ return this._binHeight;
61
+ }
62
+ /**
63
+ * Border reserved around each packed rectangle in texels.
64
+ */ get rectBorderWidth() {
65
+ return this._rectBorderWidth;
51
66
  }
52
67
  /**
53
68
  * Gets the information about specified atlas
@@ -145,9 +160,9 @@ import { RectsPacker } from '@zephyr3d/base';
145
160
  let textureAtlas;
146
161
  if (atlasIndex === this._atlasList.length) {
147
162
  textureAtlas = this._createAtlasTexture();
148
- this._atlasList.push(textureAtlas);
163
+ this._atlasList.push(new DRef(textureAtlas));
149
164
  } else {
150
- textureAtlas = this._atlasList[atlasIndex];
165
+ textureAtlas = this._atlasList[atlasIndex].get();
151
166
  }
152
167
  textureAtlas.updateFromElement(ctx.canvas, x, y, xOffset, yOffset, w, h);
153
168
  }
@@ -155,9 +170,9 @@ import { RectsPacker } from '@zephyr3d/base';
155
170
  let textureAtlas;
156
171
  if (atlasIndex === this._atlasList.length) {
157
172
  textureAtlas = this._createAtlasTexture();
158
- this._atlasList.push(textureAtlas);
173
+ this._atlasList.push(new DRef(textureAtlas));
159
174
  } else {
160
- textureAtlas = this._atlasList[atlasIndex];
175
+ textureAtlas = this._atlasList[atlasIndex].get();
161
176
  }
162
177
  if (bitmap instanceof ImageBitmap) {
163
178
  textureAtlas.updateFromElement(bitmap, x, y, 0, 0, bitmap.width, bitmap.height);
@@ -1 +1 @@
1
- {"version":3,"file":"textureatlas.js","sources":["../../src/helpers/textureatlas.ts"],"sourcesContent":["import type { Nullable } from '@zephyr3d/base';\r\nimport { RectsPacker } from '@zephyr3d/base';\r\nimport type { AbstractDevice, TextureFormat } from '../base_types';\r\nimport type { BaseTexture, Texture2D } from '../gpuobject';\r\n\r\n/**\r\n * Information of a texture atlas\r\n * @public\r\n */\r\nexport interface AtlasInfo {\r\n atlasIndex: number;\r\n width: number;\r\n height: number;\r\n uMin: number;\r\n vMin: number;\r\n uMax: number;\r\n vMax: number;\r\n}\r\n\r\n/**\r\n * Texture atlas manager\r\n * @public\r\n */\r\nexport class TextureAtlasManager {\r\n /** @internal */\r\n protected static readonly ATLAS_WIDTH = 1024;\r\n /** @internal */\r\n protected static readonly ATLAS_HEIGHT = 1024;\r\n /** @internal */\r\n protected _packer: RectsPacker;\r\n /** @internal */\r\n protected _device: AbstractDevice;\r\n /** @internal */\r\n protected _binWidth: number;\r\n /** @internal */\r\n protected _binHeight: number;\r\n /** @internal */\r\n protected _rectBorderWidth: number;\r\n /** @internal */\r\n protected _linearSpace: boolean;\r\n /** @internal */\r\n protected _atlasList: Partial<Texture2D[]>;\r\n /** @internal */\r\n protected _atlasInfoMap: Partial<Record<string, AtlasInfo>>;\r\n /** @internal */\r\n protected _atlasRestoreHandler: Nullable<(tex: BaseTexture) => void>;\r\n /**\r\n * Creates a new texture atlas manager instance\r\n * @param device - The render device\r\n * @param binWidth - Width of an atlas bin\r\n * @param binHeight - Height of an atlas bin\r\n * @param rectBorderWidth - Border width of an atlas\r\n * @param linearSpace - true if the texture space is linear\r\n */\r\n constructor(\r\n device: AbstractDevice,\r\n binWidth: number,\r\n binHeight: number,\r\n rectBorderWidth: number,\r\n linearSpace?: boolean\r\n ) {\r\n this._device = device;\r\n this._binWidth = binWidth;\r\n this._binHeight = binHeight;\r\n this._rectBorderWidth = rectBorderWidth;\r\n this._linearSpace = !!linearSpace;\r\n this._packer = new RectsPacker(this._binWidth, this._binHeight);\r\n this._atlasList = [];\r\n this._atlasInfoMap = {};\r\n this._atlasRestoreHandler = null;\r\n }\r\n /**\r\n * The texture restore handler callback function\r\n * This callback function will be called whenever the device has been restored\r\n */\r\n get atlasTextureRestoreHandler() {\r\n return this._atlasRestoreHandler;\r\n }\r\n set atlasTextureRestoreHandler(f) {\r\n this._atlasRestoreHandler = f;\r\n }\r\n /**\r\n * Gets the atlas texture of a given index\r\n * @param index - Index of the atlas bin\r\n * @returns Atlas texture for given index\r\n */\r\n getAtlasTexture(index: number) {\r\n return this._atlasList[index];\r\n }\r\n /**\r\n * Gets the information about specified atlas\r\n * @param key - Key of the atlas\r\n * @returns Information of the atlas\r\n */\r\n getAtlasInfo(key: string) {\r\n return this._atlasInfoMap[key] || null;\r\n }\r\n /**\r\n * Check if no atlas has been created\r\n * @returns true if no atlas has been created\r\n */\r\n isEmpty() {\r\n return this._atlasList.length === 0;\r\n }\r\n /**\r\n * Removes all created atlases\r\n */\r\n clear() {\r\n this._packer.clear();\r\n for (const tex of this._atlasList) {\r\n tex!.dispose();\r\n }\r\n this._atlasList = [];\r\n this._atlasInfoMap = {};\r\n }\r\n /**\r\n * Inserts a rectangle of a canvas to the atlas texture\r\n * @param key - Key of the atlas\r\n * @param ctx - The canvas context\r\n * @param x - x offset of the rectangle\r\n * @param y - y offset of the rectangle\r\n * @param w - width of the rectangle\r\n * @param h - height of the rectangle\r\n * @returns The atals info or null if insert failed\r\n */\r\n pushCanvas(key: string, ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number) {\r\n const rc = this._packer.insert(w + 2 * this._rectBorderWidth, h + 2 * this._rectBorderWidth);\r\n if (rc) {\r\n const atlasX = rc.x + this._rectBorderWidth;\r\n const atlasY = rc.y + this._rectBorderWidth;\r\n this._updateAtlasTextureCanvas(rc.binIndex, ctx, atlasX, atlasY, w, h, x, y);\r\n const info: AtlasInfo = {\r\n atlasIndex: rc.binIndex,\r\n uMin: atlasX / this._binWidth,\r\n vMin: atlasY / this._binHeight,\r\n uMax: (atlasX + w) / this._binWidth,\r\n vMax: (atlasY + h) / this._binHeight,\r\n width: w,\r\n height: h\r\n };\r\n this._atlasInfoMap[key] = info;\r\n return info;\r\n }\r\n return null;\r\n }\r\n /**\r\n * Inserts a bitmap to the atlas texture\r\n * @param key - Key of the atlas\r\n * @param bitmap - The bitmap object\r\n * @returns The atals info or null if insert failed\r\n */\r\n pushBitmap(key: string, bitmap: ImageData | ImageBitmap) {\r\n const rc = this._packer.insert(\r\n bitmap.width + 2 * this._rectBorderWidth,\r\n bitmap.height + 2 * this._rectBorderWidth\r\n );\r\n if (rc) {\r\n const atlasX = rc.x + this._rectBorderWidth;\r\n const atlasY = rc.y + this._rectBorderWidth;\r\n this._updateAtlasTexture(rc.binIndex, bitmap, atlasX, atlasY);\r\n const info: AtlasInfo = {\r\n atlasIndex: rc.binIndex,\r\n uMin: atlasX / this._binWidth,\r\n vMin: atlasY / this._binHeight,\r\n uMax: (atlasX + bitmap.width) / this._binWidth,\r\n vMax: (atlasY + bitmap.height) / this._binHeight,\r\n width: bitmap.width,\r\n height: bitmap.height\r\n };\r\n this._atlasInfoMap[key] = info;\r\n return info;\r\n }\r\n return null;\r\n }\r\n /** @internal */\r\n protected _createAtlasTexture() {\r\n const format: TextureFormat = 'rgba8unorm';\r\n const tex = this._device.createTexture2D(format, this._binWidth, this._binHeight, {\r\n mipmapping: false\r\n });\r\n if (!tex) {\r\n throw new Error(`Create 2D texture failed: ${format}-${this._binWidth}x${this._binHeight}`);\r\n }\r\n tex.update(new Uint8Array(tex.width * tex.height * 4), 0, 0, tex.width, tex.height);\r\n tex.restoreHandler = () => {\r\n tex.update(new Uint8Array(tex.width * tex.height * 4), 0, 0, tex.width, tex.height);\r\n this._atlasRestoreHandler?.(tex);\r\n };\r\n return tex;\r\n }\r\n /** @internal */\r\n private _updateAtlasTextureCanvas(\r\n atlasIndex: number,\r\n ctx: CanvasRenderingContext2D,\r\n x: number,\r\n y: number,\r\n w: number,\r\n h: number,\r\n xOffset: number,\r\n yOffset: number\r\n ) {\r\n let textureAtlas: Texture2D;\r\n if (atlasIndex === this._atlasList.length) {\r\n textureAtlas = this._createAtlasTexture();\r\n this._atlasList.push(textureAtlas);\r\n } else {\r\n textureAtlas = this._atlasList[atlasIndex]!;\r\n }\r\n textureAtlas.updateFromElement(ctx.canvas, x, y, xOffset, yOffset, w, h);\r\n }\r\n /** @internal */\r\n private _updateAtlasTexture(atlasIndex: number, bitmap: ImageData | ImageBitmap, x: number, y: number) {\r\n let textureAtlas: Texture2D;\r\n if (atlasIndex === this._atlasList.length) {\r\n textureAtlas = this._createAtlasTexture();\r\n this._atlasList.push(textureAtlas);\r\n } else {\r\n textureAtlas = this._atlasList[atlasIndex]!;\r\n }\r\n if (bitmap instanceof ImageBitmap) {\r\n textureAtlas.updateFromElement(bitmap, x, y, 0, 0, bitmap.width, bitmap.height);\r\n } else {\r\n const originValues = new Uint8Array(bitmap.data.buffer);\r\n textureAtlas.update(originValues, x, y, bitmap.width, bitmap.height);\r\n }\r\n }\r\n}\r\n"],"names":["TextureAtlasManager","ATLAS_WIDTH","ATLAS_HEIGHT","device","binWidth","binHeight","rectBorderWidth","linearSpace","_device","_binWidth","_binHeight","_rectBorderWidth","_linearSpace","_packer","RectsPacker","_atlasList","_atlasInfoMap","_atlasRestoreHandler","atlasTextureRestoreHandler","f","getAtlasTexture","index","getAtlasInfo","key","isEmpty","length","clear","tex","dispose","pushCanvas","ctx","x","y","w","h","rc","insert","atlasX","atlasY","_updateAtlasTextureCanvas","binIndex","info","atlasIndex","uMin","vMin","uMax","vMax","width","height","pushBitmap","bitmap","_updateAtlasTexture","format","createTexture2D","mipmapping","Error","update","Uint8Array","restoreHandler","xOffset","yOffset","textureAtlas","_createAtlasTexture","push","updateFromElement","canvas","ImageBitmap","originValues","data","buffer"],"mappings":"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"}
1
+ {"version":3,"file":"textureatlas.js","sources":["../../src/helpers/textureatlas.ts"],"sourcesContent":["import type { Nullable } from '@zephyr3d/base';\r\nimport { DRef } from '@zephyr3d/base';\r\nimport { RectsPacker } from '@zephyr3d/base';\r\nimport type { AbstractDevice, TextureFormat } from '../base_types';\r\nimport type { BaseTexture, Texture2D } from '../gpuobject';\r\n\r\n/**\r\n * Information of a texture atlas\r\n * @public\r\n */\r\nexport interface AtlasInfo {\r\n atlasIndex: number;\r\n width: number;\r\n height: number;\r\n uMin: number;\r\n vMin: number;\r\n uMax: number;\r\n vMax: number;\r\n}\r\n\r\n/**\r\n * Texture atlas manager\r\n * @public\r\n */\r\nexport class TextureAtlasManager {\r\n /** @internal */\r\n protected static readonly ATLAS_WIDTH = 1024;\r\n /** @internal */\r\n protected static readonly ATLAS_HEIGHT = 1024;\r\n /** @internal */\r\n protected _packer: RectsPacker;\r\n /** @internal */\r\n protected _device: AbstractDevice;\r\n /** @internal */\r\n protected _binWidth: number;\r\n /** @internal */\r\n protected _binHeight: number;\r\n /** @internal */\r\n protected _rectBorderWidth: number;\r\n /** @internal */\r\n protected _linearSpace: boolean;\r\n /** @internal */\r\n protected _atlasList: DRef<Texture2D>[];\r\n /** @internal */\r\n protected _atlasInfoMap: Partial<Record<string, AtlasInfo>>;\r\n /** @internal */\r\n protected _atlasRestoreHandler: Nullable<(tex: BaseTexture) => void>;\r\n /**\r\n * Creates a new texture atlas manager instance\r\n * @param device - The render device\r\n * @param binWidth - Width of an atlas bin\r\n * @param binHeight - Height of an atlas bin\r\n * @param rectBorderWidth - Border width of an atlas\r\n * @param linearSpace - true if the texture space is linear\r\n */\r\n constructor(\r\n device: AbstractDevice,\r\n binWidth: number,\r\n binHeight: number,\r\n rectBorderWidth: number,\r\n linearSpace?: boolean\r\n ) {\r\n this._device = device;\r\n this._binWidth = binWidth;\r\n this._binHeight = binHeight;\r\n this._rectBorderWidth = rectBorderWidth;\r\n this._linearSpace = !!linearSpace;\r\n this._packer = new RectsPacker(this._binWidth, this._binHeight);\r\n this._atlasList = [];\r\n this._atlasInfoMap = {};\r\n this._atlasRestoreHandler = null;\r\n }\r\n /**\r\n * The texture restore handler callback function\r\n * This callback function will be called whenever the device has been restored\r\n */\r\n get atlasTextureRestoreHandler() {\r\n return this._atlasRestoreHandler;\r\n }\r\n set atlasTextureRestoreHandler(f) {\r\n this._atlasRestoreHandler = f;\r\n }\r\n /**\r\n * Gets the atlas texture of a given index\r\n * @param index - Index of the atlas bin\r\n * @returns Atlas texture for given index\r\n */\r\n getAtlasTexture(index: number) {\r\n return this._atlasList[index]?.get() ?? undefined;\r\n }\r\n /**\r\n * Width of each atlas bin in texels.\r\n */\r\n get binWidth() {\r\n return this._binWidth;\r\n }\r\n /**\r\n * Height of each atlas bin in texels.\r\n */\r\n get binHeight() {\r\n return this._binHeight;\r\n }\r\n /**\r\n * Border reserved around each packed rectangle in texels.\r\n */\r\n get rectBorderWidth() {\r\n return this._rectBorderWidth;\r\n }\r\n /**\r\n * Gets the information about specified atlas\r\n * @param key - Key of the atlas\r\n * @returns Information of the atlas\r\n */\r\n getAtlasInfo(key: string) {\r\n return this._atlasInfoMap[key] || null;\r\n }\r\n /**\r\n * Check if no atlas has been created\r\n * @returns true if no atlas has been created\r\n */\r\n isEmpty() {\r\n return this._atlasList.length === 0;\r\n }\r\n /**\r\n * Removes all created atlases\r\n */\r\n clear() {\r\n this._packer.clear();\r\n for (const tex of this._atlasList) {\r\n tex!.dispose();\r\n }\r\n this._atlasList = [];\r\n this._atlasInfoMap = {};\r\n }\r\n /**\r\n * Inserts a rectangle of a canvas to the atlas texture\r\n * @param key - Key of the atlas\r\n * @param ctx - The canvas context\r\n * @param x - x offset of the rectangle\r\n * @param y - y offset of the rectangle\r\n * @param w - width of the rectangle\r\n * @param h - height of the rectangle\r\n * @returns The atals info or null if insert failed\r\n */\r\n pushCanvas(key: string, ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number) {\r\n const rc = this._packer.insert(w + 2 * this._rectBorderWidth, h + 2 * this._rectBorderWidth);\r\n if (rc) {\r\n const atlasX = rc.x + this._rectBorderWidth;\r\n const atlasY = rc.y + this._rectBorderWidth;\r\n this._updateAtlasTextureCanvas(rc.binIndex, ctx, atlasX, atlasY, w, h, x, y);\r\n const info: AtlasInfo = {\r\n atlasIndex: rc.binIndex,\r\n uMin: atlasX / this._binWidth,\r\n vMin: atlasY / this._binHeight,\r\n uMax: (atlasX + w) / this._binWidth,\r\n vMax: (atlasY + h) / this._binHeight,\r\n width: w,\r\n height: h\r\n };\r\n this._atlasInfoMap[key] = info;\r\n return info;\r\n }\r\n return null;\r\n }\r\n /**\r\n * Inserts a bitmap to the atlas texture\r\n * @param key - Key of the atlas\r\n * @param bitmap - The bitmap object\r\n * @returns The atals info or null if insert failed\r\n */\r\n pushBitmap(key: string, bitmap: ImageData | ImageBitmap) {\r\n const rc = this._packer.insert(\r\n bitmap.width + 2 * this._rectBorderWidth,\r\n bitmap.height + 2 * this._rectBorderWidth\r\n );\r\n if (rc) {\r\n const atlasX = rc.x + this._rectBorderWidth;\r\n const atlasY = rc.y + this._rectBorderWidth;\r\n this._updateAtlasTexture(rc.binIndex, bitmap, atlasX, atlasY);\r\n const info: AtlasInfo = {\r\n atlasIndex: rc.binIndex,\r\n uMin: atlasX / this._binWidth,\r\n vMin: atlasY / this._binHeight,\r\n uMax: (atlasX + bitmap.width) / this._binWidth,\r\n vMax: (atlasY + bitmap.height) / this._binHeight,\r\n width: bitmap.width,\r\n height: bitmap.height\r\n };\r\n this._atlasInfoMap[key] = info;\r\n return info;\r\n }\r\n return null;\r\n }\r\n /** @internal */\r\n protected _createAtlasTexture() {\r\n const format: TextureFormat = 'rgba8unorm';\r\n const tex = this._device.createTexture2D(format, this._binWidth, this._binHeight, {\r\n mipmapping: false\r\n });\r\n if (!tex) {\r\n throw new Error(`Create 2D texture failed: ${format}-${this._binWidth}x${this._binHeight}`);\r\n }\r\n tex.update(new Uint8Array(tex.width * tex.height * 4), 0, 0, tex.width, tex.height);\r\n tex.restoreHandler = () => {\r\n tex.update(new Uint8Array(tex.width * tex.height * 4), 0, 0, tex.width, tex.height);\r\n this._atlasRestoreHandler?.(tex);\r\n };\r\n return tex;\r\n }\r\n /** @internal */\r\n private _updateAtlasTextureCanvas(\r\n atlasIndex: number,\r\n ctx: CanvasRenderingContext2D,\r\n x: number,\r\n y: number,\r\n w: number,\r\n h: number,\r\n xOffset: number,\r\n yOffset: number\r\n ) {\r\n let textureAtlas: Texture2D;\r\n if (atlasIndex === this._atlasList.length) {\r\n textureAtlas = this._createAtlasTexture();\r\n this._atlasList.push(new DRef(textureAtlas));\r\n } else {\r\n textureAtlas = this._atlasList[atlasIndex]!.get()!;\r\n }\r\n textureAtlas.updateFromElement(ctx.canvas, x, y, xOffset, yOffset, w, h);\r\n }\r\n /** @internal */\r\n private _updateAtlasTexture(atlasIndex: number, bitmap: ImageData | ImageBitmap, x: number, y: number) {\r\n let textureAtlas: Texture2D;\r\n if (atlasIndex === this._atlasList.length) {\r\n textureAtlas = this._createAtlasTexture();\r\n this._atlasList.push(new DRef(textureAtlas));\r\n } else {\r\n textureAtlas = this._atlasList[atlasIndex]!.get()!;\r\n }\r\n if (bitmap instanceof ImageBitmap) {\r\n textureAtlas.updateFromElement(bitmap, x, y, 0, 0, bitmap.width, bitmap.height);\r\n } else {\r\n const originValues = new Uint8Array(bitmap.data.buffer);\r\n textureAtlas.update(originValues, x, y, bitmap.width, bitmap.height);\r\n }\r\n }\r\n}\r\n"],"names":["TextureAtlasManager","ATLAS_WIDTH","ATLAS_HEIGHT","device","binWidth","binHeight","rectBorderWidth","linearSpace","_device","_binWidth","_binHeight","_rectBorderWidth","_linearSpace","_packer","RectsPacker","_atlasList","_atlasInfoMap","_atlasRestoreHandler","atlasTextureRestoreHandler","f","getAtlasTexture","index","get","undefined","getAtlasInfo","key","isEmpty","length","clear","tex","dispose","pushCanvas","ctx","x","y","w","h","rc","insert","atlasX","atlasY","_updateAtlasTextureCanvas","binIndex","info","atlasIndex","uMin","vMin","uMax","vMax","width","height","pushBitmap","bitmap","_updateAtlasTexture","format","createTexture2D","mipmapping","Error","update","Uint8Array","restoreHandler","xOffset","yOffset","textureAtlas","_createAtlasTexture","push","DRef","updateFromElement","canvas","ImageBitmap","originValues","data","buffer"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Nullable, Immutable, TypedArray, IDisposable, CubeFace, VectorBase, MaybeArray, IEventTarget, Vector4, Observable } from '@zephyr3d/base';
1
+ import { Nullable, Immutable, TypedArray, IDisposable, CubeFace, VectorBase, MaybeArray, IEventTarget, Vector3, Vector4, Rect, Observable } from '@zephyr3d/base';
2
2
 
3
3
  /**
4
4
  * Struct layout types
@@ -3359,6 +3359,28 @@ type DeviceViewport = {
3359
3359
  */
3360
3360
  default: boolean;
3361
3361
  };
3362
+ /**
3363
+ * Horizontal alignment for text layout
3364
+ * @public
3365
+ */
3366
+ type TextHorizontalAlignment = 'left' | 'center' | 'right';
3367
+ /**
3368
+ * Vertical alignment for text layout
3369
+ * @public
3370
+ */
3371
+ type TextVerticalAlignment = 'top' | 'center' | 'bottom';
3372
+ /**
3373
+ * Layout options for drawing text inside a rectangle
3374
+ * @public
3375
+ */
3376
+ interface DrawTextLayoutOptions {
3377
+ /** Horizontal alignment of each line */
3378
+ halign?: TextHorizontalAlignment;
3379
+ /** Vertical alignment of the text block */
3380
+ valign?: TextVerticalAlignment;
3381
+ /** Whether to wrap text automatically to fit the rectangle width */
3382
+ wordWrap?: boolean;
3383
+ }
3362
3384
  /**
3363
3385
  * Abstract interface for the rendering device.
3364
3386
  * @public
@@ -3397,7 +3419,9 @@ interface AbstractDevice extends IEventTarget<DeviceEventMap> {
3397
3419
  /** Cancel schedule next frame */
3398
3420
  cancelNextFrame(handle: number): void;
3399
3421
  /** Set font for drawText function */
3400
- setFont(fontName: string): void;
3422
+ setFont(fontName: Nullable<string>): void;
3423
+ /** Set render states to be used when drawing text. If not set, default states will be used. */
3424
+ setTextRenderStates(states: Nullable<RenderStateSet>): void;
3401
3425
  /**
3402
3426
  * Draw a string
3403
3427
  * @param text - The string that will be drawn
@@ -3405,7 +3429,15 @@ interface AbstractDevice extends IEventTarget<DeviceEventMap> {
3405
3429
  * @param y - y coordinate in pixels related to the viewport origin
3406
3430
  * @param color - A CSS color value
3407
3431
  */
3408
- drawText(text: string, x: number, y: number, color: string, viewport?: Immutable<number[]>): void;
3432
+ drawText(text: string, x: number, y: number, color: string | Vector3 | Vector4): void;
3433
+ /**
3434
+ * Draw a string inside a rectangle with layout and clipping
3435
+ * @param text - The string that will be drawn
3436
+ * @param rect - Layout rectangle in pixels related to the viewport origin
3437
+ * @param color - A CSS color value
3438
+ * @param options - Text layout options
3439
+ */
3440
+ drawText(text: string, rect: Immutable<Rect>, color: string | Vector3 | Vector4, options?: DrawTextLayoutOptions): void;
3409
3441
  /**
3410
3442
  * Clears the current frame buffer
3411
3443
  * @param clearColor - If not null, the color buffer will be cleared to this value.
@@ -3986,8 +4018,10 @@ declare abstract class BaseDevice extends Observable<DeviceEventMap> {
3986
4018
  get programBuilder(): ProgramBuilder;
3987
4019
  poolExists(key: string | symbol): boolean;
3988
4020
  getPool(key: string | symbol): Pool;
3989
- setFont(fontName: string): void;
3990
- drawText(text: string, x: number, y: number, color: string, viewport?: Immutable<number[]>): void;
4021
+ setFont(fontName: Nullable<string>): void;
4022
+ setTextRenderStates(renderStates: Nullable<RenderStateSet>): void;
4023
+ drawText(text: string, x: number, y: number, color: string | Vector3 | Vector4): void;
4024
+ drawText(text: string, rect: Immutable<Rect>, color: string | Vector3 | Vector4, options?: DrawTextLayoutOptions): void;
3991
4025
  setFramebuffer(rt: Nullable<FrameBuffer>): void;
3992
4026
  setFramebuffer(color: BaseTexture[], depth?: BaseTexture, sampleCount?: number): void;
3993
4027
  disposeObject(obj: GPUObject, remove?: boolean): void;
@@ -4078,6 +4112,18 @@ declare class TextureAtlasManager {
4078
4112
  * @returns Atlas texture for given index
4079
4113
  */
4080
4114
  getAtlasTexture(index: number): Texture2D<unknown> | undefined;
4115
+ /**
4116
+ * Width of each atlas bin in texels.
4117
+ */
4118
+ get binWidth(): number;
4119
+ /**
4120
+ * Height of each atlas bin in texels.
4121
+ */
4122
+ get binHeight(): number;
4123
+ /**
4124
+ * Border reserved around each packed rectangle in texels.
4125
+ */
4126
+ get rectBorderWidth(): number;
4081
4127
  /**
4082
4128
  * Gets the information about specified atlas
4083
4129
  * @param key - Key of the atlas
@@ -4214,7 +4260,12 @@ declare class DrawText {
4214
4260
  * @param device - The render device
4215
4261
  * @param name - The font name
4216
4262
  */
4217
- static setFont(device: AbstractDevice, name: string): void;
4263
+ static setFont(device: AbstractDevice, name: Nullable<string>): void;
4264
+ /**
4265
+ * Set render states to be used when drawing text. If not set, default states will be used.
4266
+ * @param renderStates - The render states to use when drawing text. If null, default states will be used.
4267
+ */
4268
+ static setRenderStates(renderStates: Nullable<RenderStateSet>): void;
4218
4269
  /**
4219
4270
  * Draw text onto the screen
4220
4271
  * @param device - The render device
@@ -4223,7 +4274,16 @@ declare class DrawText {
4223
4274
  * @param x - X coordinate of the text
4224
4275
  * @param y - Y coordinate of the text
4225
4276
  */
4226
- static drawText(device: AbstractDevice, text: string, color: string, x: number, y: number, viewport?: Immutable<number[]>): void;
4277
+ static drawText(device: AbstractDevice, text: string, color: string | Vector3 | Vector4, x: number, y: number): void;
4278
+ /**
4279
+ * Draw text inside a rectangle with layout and clipping
4280
+ * @param device - The render device
4281
+ * @param text - The text to be drawn
4282
+ * @param color - The text color
4283
+ * @param rect - The layout rectangle
4284
+ * @param options - Layout options
4285
+ */
4286
+ static drawText(device: AbstractDevice, text: string, color: string | Vector3 | Vector4, rect: Immutable<Rect>, options?: DrawTextLayoutOptions): void;
4227
4287
  }
4228
4288
 
4229
4289
  /**
@@ -4251,4 +4311,4 @@ declare class StructuredBufferData {
4251
4311
  set(name: string, value: StructuredValue): void;
4252
4312
  }
4253
4313
 
4254
- export { type AbstractDevice, type ArrayTypeDetail, type AtlasInfo, type AtomicTypeInfoDetail, type BaseCreationOptions, BaseDevice, type BaseTexture, type BindGroup, type BindGroupLayout, type BindGroupLayoutEntry, type BindPointInfo, type BlendEquation, type BlendFunc, type BlendingState, type BufferBindingLayout, type BufferCreationOptions, type BufferUsage, CPUTimer, type ColorState, type CompareFunc, type ComputeProgramConstructParams, type DataType, type DepthState, type DeviceBackend, type DeviceCaps, type DeviceEventMap, type DeviceOptions, type DeviceViewport, DrawText, type ExpValueNonArrayType, type ExpValueType, type ExternalTextureBindingLayout, type FaceMode, type FaceWinding, Font, type FrameBuffer, type FrameBufferOptions, type FrameBufferTextureAttachment, type FrameInfo, type FramebufferCaps, type FunctionTypeDetail, type GPUDataBuffer, type GPUObject, type GPUObjectList, type GPUProgram, type GPUProgramConstructParams, GPUResourceUsageFlags, GlyphManager, type ITimer, type IndexBuffer, MAX_BINDING_GROUPS, MAX_TEXCOORD_INDEX_COUNT, MAX_VERTEX_ATTRIBUTES, type MiscCaps, PBAddressSpace, PBAnyTypeInfo, PBArrayTypeInfo, PBAtomicI32TypeInfo, PBAtomicU32TypeInfo, PBBuiltinScope, type PBComputeOptions, PBDoWhileScope, PBForScope, PBFunctionScope, PBFunctionTypeInfo, PBGlobalScope, PBIfScope, PBInputScope, PBInsideFunctionScope, PBLocalScope, PBNakedScope, PBOutputScope, PBPointerTypeInfo, PBPrimitiveType, PBPrimitiveTypeInfo, PBReflection, type PBReflectionTagGetter, type PBRenderOptions, PBSamplerAccessMode, PBSamplerTypeInfo, PBScope, PBShaderExp, type PBStructLayout, PBStructTypeInfo, PBTextureType, PBTextureTypeInfo, PBTypeInfo, PBVoidTypeInfo, PBWhileScope, type PointerTypeDetail, Pool, type PrimitiveType, type PrimitiveTypeDetail, ProgramBuilder, Proxiable, type RasterizerState, type RenderBundle, type RenderProgramConstructParams, type RenderStateSet, type SamplerBindingLayout, type SamplerOptions, type SamplerTypeDetail, type ShaderCaps, type ShaderExpTagRecord, type ShaderExpTagValue, type ShaderKind, ShaderType, type ShaderTypeFunc, type StencilOp, type StencilState, type StorageTextureBindingLayout, type StructTypeDetail, type StructuredBuffer, StructuredBufferData, type StructuredValue, type Texture2D, type Texture2DArray, type Texture3D, type TextureAddressMode, TextureAtlasManager, type TextureBindingLayout, type TextureCaps, type TextureColorSpace, type TextureCreationOptions, type TextureCube, type TextureFilterMode, type TextureFormat, type TextureFormatInfo, type TextureImageElement, type TextureMipmapData, type TextureMipmapLevelData, type TextureSampler, type TextureType, type TextureTypeDetail, type TextureVideo, type TypeDetailInfo, type UniformBufferLayout, type UniformLayout, VERTEX_ATTRIB_BLEND_INDICES, VERTEX_ATTRIB_BLEND_WEIGHT, VERTEX_ATTRIB_DIFFUSE, VERTEX_ATTRIB_NORMAL, VERTEX_ATTRIB_POSITION, VERTEX_ATTRIB_TANGENT, VERTEX_ATTRIB_TEXCOORD0, VERTEX_ATTRIB_TEXCOORD1, VERTEX_ATTRIB_TEXCOORD2, VERTEX_ATTRIB_TEXCOORD3, VERTEX_ATTRIB_TEXCOORD4, VERTEX_ATTRIB_TEXCOORD5, VERTEX_ATTRIB_TEXCOORD6, VERTEX_ATTRIB_TEXCOORD7, type VertexAttribFormat, type VertexBufferInfo, VertexData, type VertexLayout, type VertexLayoutOptions, type VertexSemantic, type VertexStepMode, type WebGLContext, genDefaultName, getTextureFormatBlockHeight, getTextureFormatBlockSize, getTextureFormatBlockWidth, getVertexAttribByName, getVertexAttribFormat, getVertexAttribName, getVertexAttributeFormat, getVertexAttributeIndex, getVertexBufferAttribType, getVertexBufferAttribTypeBySemantic, getVertexBufferLength, getVertexBufferStride, getVertexFormatComponentCount, getVertexFormatSize, hasAlphaChannel, hasBlueChannel, hasDepthChannel, hasGreenChannel, hasRedChannel, hasStencilChannel, isCompressedTextureFormat, isFloatTextureFormat, isIntegerTextureFormat, isSRGBTextureFormat, isSignedTextureFormat, linearTextureFormatToSRGB, makeVertexBufferType, matchVertexBuffer, semanticList };
4314
+ export { type AbstractDevice, type ArrayTypeDetail, type AtlasInfo, type AtomicTypeInfoDetail, type BaseCreationOptions, BaseDevice, type BaseTexture, type BindGroup, type BindGroupLayout, type BindGroupLayoutEntry, type BindPointInfo, type BlendEquation, type BlendFunc, type BlendingState, type BufferBindingLayout, type BufferCreationOptions, type BufferUsage, CPUTimer, type ColorState, type CompareFunc, type ComputeProgramConstructParams, type DataType, type DepthState, type DeviceBackend, type DeviceCaps, type DeviceEventMap, type DeviceOptions, type DeviceViewport, DrawText, type DrawTextLayoutOptions, type ExpValueNonArrayType, type ExpValueType, type ExternalTextureBindingLayout, type FaceMode, type FaceWinding, Font, type FrameBuffer, type FrameBufferOptions, type FrameBufferTextureAttachment, type FrameInfo, type FramebufferCaps, type FunctionTypeDetail, type GPUDataBuffer, type GPUObject, type GPUObjectList, type GPUProgram, type GPUProgramConstructParams, GPUResourceUsageFlags, GlyphManager, type ITimer, type IndexBuffer, MAX_BINDING_GROUPS, MAX_TEXCOORD_INDEX_COUNT, MAX_VERTEX_ATTRIBUTES, type MiscCaps, PBAddressSpace, PBAnyTypeInfo, PBArrayTypeInfo, PBAtomicI32TypeInfo, PBAtomicU32TypeInfo, PBBuiltinScope, type PBComputeOptions, PBDoWhileScope, PBForScope, PBFunctionScope, PBFunctionTypeInfo, PBGlobalScope, PBIfScope, PBInputScope, PBInsideFunctionScope, PBLocalScope, PBNakedScope, PBOutputScope, PBPointerTypeInfo, PBPrimitiveType, PBPrimitiveTypeInfo, PBReflection, type PBReflectionTagGetter, type PBRenderOptions, PBSamplerAccessMode, PBSamplerTypeInfo, PBScope, PBShaderExp, type PBStructLayout, PBStructTypeInfo, PBTextureType, PBTextureTypeInfo, PBTypeInfo, PBVoidTypeInfo, PBWhileScope, type PointerTypeDetail, Pool, type PrimitiveType, type PrimitiveTypeDetail, ProgramBuilder, Proxiable, type RasterizerState, type RenderBundle, type RenderProgramConstructParams, type RenderStateSet, type SamplerBindingLayout, type SamplerOptions, type SamplerTypeDetail, type ShaderCaps, type ShaderExpTagRecord, type ShaderExpTagValue, type ShaderKind, ShaderType, type ShaderTypeFunc, type StencilOp, type StencilState, type StorageTextureBindingLayout, type StructTypeDetail, type StructuredBuffer, StructuredBufferData, type StructuredValue, type TextHorizontalAlignment, type TextVerticalAlignment, type Texture2D, type Texture2DArray, type Texture3D, type TextureAddressMode, TextureAtlasManager, type TextureBindingLayout, type TextureCaps, type TextureColorSpace, type TextureCreationOptions, type TextureCube, type TextureFilterMode, type TextureFormat, type TextureFormatInfo, type TextureImageElement, type TextureMipmapData, type TextureMipmapLevelData, type TextureSampler, type TextureType, type TextureTypeDetail, type TextureVideo, type TypeDetailInfo, type UniformBufferLayout, type UniformLayout, VERTEX_ATTRIB_BLEND_INDICES, VERTEX_ATTRIB_BLEND_WEIGHT, VERTEX_ATTRIB_DIFFUSE, VERTEX_ATTRIB_NORMAL, VERTEX_ATTRIB_POSITION, VERTEX_ATTRIB_TANGENT, VERTEX_ATTRIB_TEXCOORD0, VERTEX_ATTRIB_TEXCOORD1, VERTEX_ATTRIB_TEXCOORD2, VERTEX_ATTRIB_TEXCOORD3, VERTEX_ATTRIB_TEXCOORD4, VERTEX_ATTRIB_TEXCOORD5, VERTEX_ATTRIB_TEXCOORD6, VERTEX_ATTRIB_TEXCOORD7, type VertexAttribFormat, type VertexBufferInfo, VertexData, type VertexLayout, type VertexLayoutOptions, type VertexSemantic, type VertexStepMode, type WebGLContext, genDefaultName, getTextureFormatBlockHeight, getTextureFormatBlockSize, getTextureFormatBlockWidth, getVertexAttribByName, getVertexAttribFormat, getVertexAttribName, getVertexAttributeFormat, getVertexAttributeIndex, getVertexBufferAttribType, getVertexBufferAttribTypeBySemantic, getVertexBufferLength, getVertexBufferStride, getVertexFormatComponentCount, getVertexFormatSize, hasAlphaChannel, hasBlueChannel, hasDepthChannel, hasGreenChannel, hasRedChannel, hasStencilChannel, isCompressedTextureFormat, isFloatTextureFormat, isIntegerTextureFormat, isSRGBTextureFormat, isSignedTextureFormat, linearTextureFormatToSRGB, makeVertexBufferType, matchVertexBuffer, semanticList };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zephyr3d/device",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
4
4
  "description": "Device API for zephyr3d",
5
5
  "homepage": "https://github.com/gavinyork/zephyr3d#readme",
6
6
  "type": "module",
@@ -68,7 +68,7 @@
68
68
  "@rollup/plugin-commonjs": "~28.0.2",
69
69
  "@types/node": "^22.12.0",
70
70
  "@webgpu/types": "^0.1.65",
71
- "@zephyr3d/base": "^0.2.3",
71
+ "@zephyr3d/base": "^0.2.5",
72
72
  "rollup-plugin-import-css": "~3.5.8"
73
73
  },
74
74
  "scripts": {