untitled-game-engine/src/plugins/renderer/mesh/vertex-format.js
2025-03-28 18:06:18 -05:00

116 lines
4.1 KiB
JavaScript

// https://www.w3.org/TR/webgpu/#enumdef-gpuvertexformat
import { Union } from '/public/vendor/kojima/union.js'
import { capitalizen } from '/src/utils/index'
/** @typedef {Uint8ArrayConstructor | Int8ArrayConstructor | Uint16ArrayConstructor | Int16ArrayConstructor | Uint32ArrayConstructor | Int32ArrayConstructor | Float32ArrayConstructor | Float64ArrayConstructor} TypedArrayConstructor */
/** @type {GPUVertexFormat[]} */
export const GPUVertexFormats = ['uint8', 'uint8x2', 'uint8x4', 'sint8', 'sint8x2', 'sint8x4', 'unorm8', 'unorm8x2', 'unorm8x4', 'snorm8', 'snorm8x2', 'snorm8x4', 'uint16', 'uint16x2', 'uint16x4', 'sint16', 'sint16x2', 'sint16x4', 'unorm16', 'unorm16x2', 'unorm16x4', 'snorm16', 'snorm16x2', 'snorm16x4', 'float16', 'float16x2', 'float16x4', 'float32', 'float32x2', 'float32x3', 'float32x4', 'uint32', 'uint32x2', 'uint32x3', 'uint32x4', 'sint32', 'sint32x2', 'sint32x3', 'sint32x4', 'unorm10-10-10-2', 'unorm8x4-bgra']
export class MeshAttributeData {
#format
#buffer
/**
* @param {VertexFormat} format
* @param {ArrayBufferLike} buffer
*/
constructor(format, buffer) {
this.#format = format
this.#buffer = buffer
}
get format() { return this.#format }
get buffer() { return this.#buffer }
}
export class VertexFormat {
#name
#components
#size
#bufferType
/**
* @param {GPUVertexFormat} name
* @param {number} components
* @param {number} size
* @param {TypedArrayConstructor} bufferType
*/
constructor(name, components, size, bufferType) {
this.#name = name
this.#components = components
this.#size = size
this.#bufferType = bufferType
}
get name() { return this.#name }
get components() { return this.#components }
get size() { return this.#size }
get bufferType() { return this.#bufferType }
}
// INFO: ugly initialization code for VertexFormat statics
// this is for doing VertexFormat.Uint8 to get that format
(() => {
/** @type {[GPUVertexFormat, number, number, TypedArrayConstructor][]} */
const formats = [
['uint8', 1, 1, Uint8Array],
['uint8x2', 2, 2, Uint8Array],
['uint8x4', 4, 4, Uint8Array],
['sint8', 1, 1, Int8Array],
['sint8x2', 2, 2, Int8Array],
['sint8x4', 4, 4, Int8Array],
['unorm8', 1, 1, Uint8Array],
['unorm8x2', 2, 2, Uint8Array],
['unorm8x4', 4, 4, Uint8Array],
['snorm8', 1, 1, Int8Array],
['snorm8x2', 2, 2, Int8Array],
['snorm8x4', 4, 4, Int8Array],
['uint16', 1, 2, Uint16Array],
['uint16x2', 2, 4, Uint16Array],
['uint16x4', 4, 8, Uint16Array],
['sint16', 1, 2, Int16Array],
['sint16x2', 2, 4, Int16Array],
['sint16x4', 4, 8, Int16Array],
['unorm16', 1, 2, Uint16Array],
['unorm16x2', 2, 4, Uint16Array],
['unorm16x4', 4, 8, Uint16Array],
['snorm16', 1, 2, Int16Array],
['snorm16x2', 2, 4, Int16Array],
['snorm16x4', 4, 8, Int16Array],
['float16', 1, 2, Uint16Array],
['float16x2', 2, 4, Uint16Array],
['float16x4', 4, 8, Uint16Array],
['float32', 1, 4, Float32Array],
['float32x2', 2, 8, Float32Array],
['float32x3', 3, 12, Float32Array],
['float32x4', 4, 16, Float32Array],
['uint32', 1, 4, Uint32Array],
['uint32x2', 2, 8, Uint32Array],
['uint32x3', 3, 12, Uint32Array],
['uint32x4', 4, 16, Uint32Array],
['sint32', 1, 4, Int32Array],
['sint32x2', 2, 8, Int32Array],
['sint32x3', 3, 12, Int32Array],
['sint32x4', 4, 16, Int32Array],
['unorm10-10-10-2', 4, 4, Uint32Array],
['unorm8x4-bgra', 4, 4, Uint8Array]
]
/**
* @param {string} name
*/
const capitalize = name => name.charAt(0).toUpperCase() + name.slice(1)
formats.forEach(([name, components, size]) => {
Object.defineProperty(VertexFormat, capitalize(value.name), {
value: new VertexFormat(name, components, size),
writable: false,
configurable: false
})
})
})()