Expand material data structure, renderer class
This commit is contained in:
parent
ddf586990a
commit
d0c1ecbd5d
@ -35,7 +35,7 @@ export class CameraOrthographic {
|
|||||||
_farPlane: number;
|
_farPlane: number;
|
||||||
|
|
||||||
/** backreference */
|
/** backreference */
|
||||||
_node: Node | undefined;
|
_node: Node | null;
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
name = "",
|
name = "",
|
||||||
@ -51,16 +51,16 @@ export class CameraOrthographic {
|
|||||||
this._nearPlane = nearPlane;
|
this._nearPlane = nearPlane;
|
||||||
this._farPlane = farPlane;
|
this._farPlane = farPlane;
|
||||||
|
|
||||||
this._node = undefined;
|
this._node = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
detach(): Camera {
|
detach(): Camera {
|
||||||
if (this._node === undefined) {
|
if (this._node === null) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._node._camera = undefined;
|
this._node._camera = null;
|
||||||
this._node = undefined;
|
this._node = null;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,7 +76,7 @@ export class CameraPerspective {
|
|||||||
_farPlane: number;
|
_farPlane: number;
|
||||||
|
|
||||||
/** backreference */
|
/** backreference */
|
||||||
_node: Node | undefined;
|
_node: Node | null;
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
name = "",
|
name = "",
|
||||||
@ -92,16 +92,16 @@ export class CameraPerspective {
|
|||||||
this._nearPlane = nearPlane;
|
this._nearPlane = nearPlane;
|
||||||
this._farPlane = farPlane;
|
this._farPlane = farPlane;
|
||||||
|
|
||||||
this._node = undefined;
|
this._node = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
detach(): Camera {
|
detach(): Camera {
|
||||||
if (this._node === undefined) {
|
if (this._node === null) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._node._camera = undefined;
|
this._node._camera = null;
|
||||||
this._node = undefined;
|
this._node = null;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,20 +4,23 @@
|
|||||||
* obtain one at http://mozilla.org/MPL/2.0/.
|
* obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { Renderer } from "./Renderer";
|
||||||
|
|
||||||
export const INDEX_SIZE = 2;
|
export const INDEX_SIZE = 2;
|
||||||
|
|
||||||
export class IndexBuffer {
|
export class IndexBuffer {
|
||||||
|
|
||||||
readonly type!: "IndexBuffer";
|
readonly type!: "IndexBuffer";
|
||||||
|
_renderer: Renderer;
|
||||||
|
|
||||||
_device: GPUDevice;
|
|
||||||
_buffer: GPUBuffer;
|
_buffer: GPUBuffer;
|
||||||
|
|
||||||
constructor(device: GPUDevice, indexCount: number) {
|
constructor(renderer: Renderer, indexCount: number) {
|
||||||
Object.defineProperty(this, "type", { value: "IndexBuffer" });
|
Object.defineProperty(this, "type", { value: "IndexBuffer" });
|
||||||
|
|
||||||
this._device = device;
|
this._renderer = renderer;
|
||||||
this._buffer = device.createBuffer({
|
|
||||||
|
this._buffer = renderer._device.createBuffer({
|
||||||
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.INDEX,
|
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.INDEX,
|
||||||
size: indexCount * INDEX_SIZE,
|
size: indexCount * INDEX_SIZE,
|
||||||
});
|
});
|
||||||
@ -34,12 +37,12 @@ export class IndexBuffer {
|
|||||||
|
|
||||||
writeArray(offset: number, indices: readonly number[]): IndexBuffer {
|
writeArray(offset: number, indices: readonly number[]): IndexBuffer {
|
||||||
const array = new Uint16Array(indices);
|
const array = new Uint16Array(indices);
|
||||||
this._device.queue.writeBuffer(this._buffer, offset * INDEX_SIZE | 0, array);
|
this._renderer._device.queue.writeBuffer(this._buffer, offset * INDEX_SIZE | 0, array);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
writeTypedArray(offset: number, indices: Uint16Array): IndexBuffer {
|
writeTypedArray(offset: number, indices: Uint16Array): IndexBuffer {
|
||||||
this._device.queue.writeBuffer(this._buffer, offset * INDEX_SIZE | 0, indices);
|
this._renderer._device.queue.writeBuffer(this._buffer, offset * INDEX_SIZE | 0, indices);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,69 +5,111 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Color, ColorObject } from "./Color";
|
import { Color, ColorObject } from "./Color";
|
||||||
|
import { Renderer } from "./Renderer";
|
||||||
|
import { Texture2D } from "./Texture2D";
|
||||||
|
|
||||||
|
export const UNIFORM_BUFFER_SIZE = 64;
|
||||||
|
|
||||||
export interface MaterialProps {
|
export interface MaterialProps {
|
||||||
name?: string;
|
name?: string;
|
||||||
|
|
||||||
baseColor?: ColorObject;
|
baseColor?: ColorObject;
|
||||||
|
partialCoverage?: number;
|
||||||
|
occlusionTextureStrength?: number;
|
||||||
metallic?: number;
|
metallic?: number;
|
||||||
roughness?: number;
|
roughness?: number;
|
||||||
|
normalScale?: number;
|
||||||
emissive?: ColorObject;
|
emissive?: ColorObject;
|
||||||
partialCoverage?: number;
|
|
||||||
transmission?: ColorObject;
|
transmission?: ColorObject;
|
||||||
collimation?: number;
|
collimation?: number;
|
||||||
ior?: number;
|
ior?: number;
|
||||||
|
|
||||||
|
baseColorPartialCoverageTexture?: Texture2D | null;
|
||||||
|
occlusionMetallicRoughnessTexture?: Texture2D | null;
|
||||||
|
normalTexture?: Texture2D | null;
|
||||||
|
emissiveTexture?: Texture2D | null;
|
||||||
|
transmissionCollimationTexture?: Texture2D | null;
|
||||||
|
|
||||||
|
transparent?: boolean;
|
||||||
doubleSided?: boolean;
|
doubleSided?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Material {
|
export class Material {
|
||||||
|
|
||||||
readonly type!: "Material";
|
readonly type!: "Material";
|
||||||
|
_renderer: Renderer;
|
||||||
|
|
||||||
_name: string;
|
_name: string;
|
||||||
|
|
||||||
_baseColor: Color;
|
_baseColor: Color;
|
||||||
|
_partialCoverage: number;
|
||||||
|
_occlusionTextureStrength: number;
|
||||||
_metallic: number;
|
_metallic: number;
|
||||||
_roughness: number;
|
_roughness: number;
|
||||||
|
_normalScale: number;
|
||||||
_emissive: Color;
|
_emissive: Color;
|
||||||
_partialCoverage: number;
|
|
||||||
_transmission: Color;
|
_transmission: Color;
|
||||||
_collimation: number;
|
_collimation: number;
|
||||||
_ior: number;
|
_ior: number;
|
||||||
|
|
||||||
|
_baseColorPartialCoverageTexture: Texture2D | null;
|
||||||
|
_occlusionMetallicRoughnessTexture: Texture2D | null;
|
||||||
|
_normalTexture: Texture2D | null;
|
||||||
|
_emissiveTexture: Texture2D | null;
|
||||||
|
_transmissionCollimationTexture: Texture2D | null;
|
||||||
|
|
||||||
|
_transparent: boolean;
|
||||||
_doubleSided: boolean;
|
_doubleSided: boolean;
|
||||||
|
|
||||||
constructor({
|
constructor(renderer: Renderer, {
|
||||||
name = "",
|
name = "",
|
||||||
baseColor,
|
baseColor,
|
||||||
|
partialCoverage = 1,
|
||||||
|
occlusionTextureStrength = 1,
|
||||||
metallic = 1,
|
metallic = 1,
|
||||||
roughness = 1,
|
roughness = 1,
|
||||||
|
normalScale = 1,
|
||||||
emissive,
|
emissive,
|
||||||
partialCoverage = 1,
|
|
||||||
transmission,
|
transmission,
|
||||||
collimation = 1,
|
collimation = 1,
|
||||||
ior = 1.45,
|
ior = 1.45,
|
||||||
|
baseColorPartialCoverageTexture = null,
|
||||||
|
occlusionMetallicRoughnessTexture = null,
|
||||||
|
normalTexture = null,
|
||||||
|
emissiveTexture = null,
|
||||||
|
transmissionCollimationTexture = null,
|
||||||
|
transparent = false,
|
||||||
doubleSided = false,
|
doubleSided = false,
|
||||||
}: MaterialProps) {
|
}: MaterialProps) {
|
||||||
Object.defineProperty(this, "type", { value: "Material" });
|
Object.defineProperty(this, "type", { value: "Material" });
|
||||||
|
|
||||||
|
this._renderer = renderer;
|
||||||
|
|
||||||
this._name = name;
|
this._name = name;
|
||||||
|
|
||||||
this._baseColor = baseColor !== undefined ? Color.fromObject(baseColor) : Color.white();
|
this._baseColor = baseColor !== undefined ? Color.fromObject(baseColor) : Color.white();
|
||||||
|
this._partialCoverage = partialCoverage;
|
||||||
|
this._occlusionTextureStrength = occlusionTextureStrength;
|
||||||
this._metallic = metallic;
|
this._metallic = metallic;
|
||||||
this._roughness = roughness;
|
this._roughness = roughness;
|
||||||
|
this._normalScale = normalScale;
|
||||||
this._emissive = emissive !== undefined ? Color.fromObject(emissive) : Color.black();
|
this._emissive = emissive !== undefined ? Color.fromObject(emissive) : Color.black();
|
||||||
this._partialCoverage = partialCoverage;
|
|
||||||
this._transmission = transmission !== undefined ? Color.fromObject(transmission) : Color.black();
|
this._transmission = transmission !== undefined ? Color.fromObject(transmission) : Color.black();
|
||||||
this._collimation = collimation;
|
this._collimation = collimation;
|
||||||
this._ior = ior;
|
this._ior = ior;
|
||||||
|
|
||||||
|
this._baseColorPartialCoverageTexture = baseColorPartialCoverageTexture;
|
||||||
|
this._occlusionMetallicRoughnessTexture = occlusionMetallicRoughnessTexture;
|
||||||
|
this._normalTexture = normalTexture;
|
||||||
|
this._emissiveTexture = emissiveTexture;
|
||||||
|
this._transmissionCollimationTexture = transmissionCollimationTexture;
|
||||||
|
|
||||||
|
this._transparent = transparent;
|
||||||
this._doubleSided = doubleSided;
|
this._doubleSided = doubleSided;
|
||||||
}
|
}
|
||||||
|
|
||||||
get isTransparent(): boolean {
|
dispose(): Material {
|
||||||
return this._partialCoverage < 1 || this._transmission.r > 0 || this._transmission.g > 0 || this._transmission.b > 0;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
src/Mesh.ts
13
src/Mesh.ts
@ -7,11 +7,17 @@
|
|||||||
import { IndexBuffer } from "./IndexBuffer";
|
import { IndexBuffer } from "./IndexBuffer";
|
||||||
import { VertexBuffer } from "./VertexBuffer";
|
import { VertexBuffer } from "./VertexBuffer";
|
||||||
|
|
||||||
|
export type Submesh = {
|
||||||
|
start: number,
|
||||||
|
length: number,
|
||||||
|
};
|
||||||
|
|
||||||
export interface MeshProps {
|
export interface MeshProps {
|
||||||
readonly name?: string;
|
readonly name?: string;
|
||||||
|
|
||||||
readonly vertexBuffer: VertexBuffer;
|
readonly vertexBuffer: VertexBuffer;
|
||||||
readonly indexBuffer: IndexBuffer;
|
readonly indexBuffer: IndexBuffer;
|
||||||
|
readonly submeshes: Submesh[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Mesh {
|
export class Mesh {
|
||||||
@ -22,11 +28,13 @@ export class Mesh {
|
|||||||
|
|
||||||
_vertexBuffer: VertexBuffer;
|
_vertexBuffer: VertexBuffer;
|
||||||
_indexBuffer: IndexBuffer;
|
_indexBuffer: IndexBuffer;
|
||||||
|
_submeshes: Submesh[];
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
name = "",
|
name = "",
|
||||||
vertexBuffer,
|
vertexBuffer,
|
||||||
indexBuffer,
|
indexBuffer,
|
||||||
|
submeshes,
|
||||||
}: MeshProps) {
|
}: MeshProps) {
|
||||||
Object.defineProperty(this, "type", { value: "Mesh" });
|
Object.defineProperty(this, "type", { value: "Mesh" });
|
||||||
|
|
||||||
@ -34,6 +42,11 @@ export class Mesh {
|
|||||||
|
|
||||||
this._vertexBuffer = vertexBuffer;
|
this._vertexBuffer = vertexBuffer;
|
||||||
this._indexBuffer = indexBuffer
|
this._indexBuffer = indexBuffer
|
||||||
|
this._submeshes = submeshes;
|
||||||
|
}
|
||||||
|
|
||||||
|
get submeshCount(): number {
|
||||||
|
return this._submeshes.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
26
src/Node.ts
26
src/Node.ts
@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Camera } from "./Camera";
|
import { Camera } from "./Camera";
|
||||||
|
import { Material } from "./Material";
|
||||||
import { Mesh } from "./Mesh";
|
import { Mesh } from "./Mesh";
|
||||||
import { Quaternion, QuaternionObject } from "./Quaternion";
|
import { Quaternion, QuaternionObject } from "./Quaternion";
|
||||||
import { Vector3, Vector3Object } from "./Vector3";
|
import { Vector3, Vector3Object } from "./Vector3";
|
||||||
@ -16,8 +17,9 @@ export interface NodeProps {
|
|||||||
readonly rotation?: QuaternionObject;
|
readonly rotation?: QuaternionObject;
|
||||||
readonly scale?: Vector3Object;
|
readonly scale?: Vector3Object;
|
||||||
|
|
||||||
readonly camera?: Camera;
|
readonly camera?: Camera | null;
|
||||||
readonly mesh?: Mesh;
|
readonly mesh?: Mesh | null;
|
||||||
|
readonly materials?: Material[];
|
||||||
|
|
||||||
readonly children?: Node[];
|
readonly children?: Node[];
|
||||||
}
|
}
|
||||||
@ -33,23 +35,26 @@ export class Node {
|
|||||||
_scale: Vector3;
|
_scale: Vector3;
|
||||||
|
|
||||||
/** unique */
|
/** unique */
|
||||||
_camera: Camera | undefined;
|
_camera: Camera | null;
|
||||||
/** shared */
|
/** shared */
|
||||||
_mesh: Mesh | undefined;
|
_mesh: Mesh | null;
|
||||||
|
/** shared */
|
||||||
|
_materials: Material[];
|
||||||
|
|
||||||
/** unique */
|
/** unique */
|
||||||
_children: Node[];
|
_children: Node[];
|
||||||
|
|
||||||
/** backreference */
|
/** backreference */
|
||||||
_parent: Node | undefined;
|
_parent: Node | null;
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
name = "",
|
name = "",
|
||||||
translation,
|
translation,
|
||||||
rotation,
|
rotation,
|
||||||
scale,
|
scale,
|
||||||
camera,
|
camera = null,
|
||||||
mesh,
|
mesh = null,
|
||||||
|
materials = [],
|
||||||
children = [],
|
children = [],
|
||||||
}: NodeProps) {
|
}: NodeProps) {
|
||||||
Object.defineProperty(this, "type", { value: "Node" });
|
Object.defineProperty(this, "type", { value: "Node" });
|
||||||
@ -62,16 +67,17 @@ export class Node {
|
|||||||
|
|
||||||
this._camera = camera;
|
this._camera = camera;
|
||||||
this._mesh = mesh;
|
this._mesh = mesh;
|
||||||
|
this._materials = materials;
|
||||||
|
|
||||||
this._children = children;
|
this._children = children;
|
||||||
|
|
||||||
this._parent = undefined;
|
this._parent = null;
|
||||||
|
|
||||||
if (this._camera !== undefined) {
|
if (this._camera !== null) {
|
||||||
this._camera._node = this;
|
this._camera._node = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._children !== undefined) {
|
if (this._children !== null) {
|
||||||
for (const child of this._children) {
|
for (const child of this._children) {
|
||||||
child._parent = this;
|
child._parent = this;
|
||||||
}
|
}
|
||||||
|
91
src/Renderer.ts
Normal file
91
src/Renderer.ts
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/*!
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public License,
|
||||||
|
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||||
|
* obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { IndexBuffer } from "./IndexBuffer";
|
||||||
|
import { Material, MaterialProps } from "./Material";
|
||||||
|
import { Texture2D, Texture2DProps } from "./Texture2D";
|
||||||
|
import { VertexBuffer } from "./VertexBuffer";
|
||||||
|
|
||||||
|
export class Renderer {
|
||||||
|
|
||||||
|
_adapter: GPUAdapter;
|
||||||
|
_device: GPUDevice;
|
||||||
|
_context: GPUCanvasContext;
|
||||||
|
_format: GPUTextureFormat;
|
||||||
|
|
||||||
|
_textureWhite: Texture2D; // 1×1 rgba8unorm of [255, 255, 255, 255]
|
||||||
|
_textureBlack: Texture2D; // 1×1 rgba8unorm of [0, 0, 0, 255]
|
||||||
|
_textureNormal: Texture2D; // 1×1 rgba8unorm of [128, 128, 128, 255]
|
||||||
|
|
||||||
|
private constructor (
|
||||||
|
adapter: GPUAdapter,
|
||||||
|
device: GPUDevice,
|
||||||
|
context: GPUCanvasContext,
|
||||||
|
format: GPUTextureFormat,
|
||||||
|
) {
|
||||||
|
this._adapter = adapter;
|
||||||
|
this._device = device;
|
||||||
|
this._context = context;
|
||||||
|
this._format = format;
|
||||||
|
|
||||||
|
this._textureWhite = new Texture2D(this, {
|
||||||
|
width: 1,
|
||||||
|
height: 1,
|
||||||
|
});
|
||||||
|
this._textureWhite.writeTypedArray(new Uint8Array([255, 255, 255, 255]));
|
||||||
|
|
||||||
|
this._textureBlack = new Texture2D(this, {
|
||||||
|
width: 1,
|
||||||
|
height: 1,
|
||||||
|
});
|
||||||
|
this._textureBlack.writeTypedArray(new Uint8Array([0, 0, 0, 255]));
|
||||||
|
|
||||||
|
this._textureNormal = new Texture2D(this, {
|
||||||
|
width: 1,
|
||||||
|
height: 1,
|
||||||
|
});
|
||||||
|
this._textureNormal.writeTypedArray(new Uint8Array([128, 128, 128, 255]));
|
||||||
|
}
|
||||||
|
|
||||||
|
static async init(canvas: HTMLCanvasElement) {
|
||||||
|
if (!navigator.gpu) {
|
||||||
|
throw new Error("WebGPU is not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
const adapter = await navigator.gpu.requestAdapter({
|
||||||
|
powerPreference: "high-performance",
|
||||||
|
});
|
||||||
|
if (adapter === null) {
|
||||||
|
throw new Error("GPUAdapter is not available");
|
||||||
|
}
|
||||||
|
|
||||||
|
const device = await adapter.requestDevice();
|
||||||
|
|
||||||
|
const context = canvas.getContext("webgpu");
|
||||||
|
if (context === null) {
|
||||||
|
throw new Error("GPUCanvasContext is not available");
|
||||||
|
}
|
||||||
|
|
||||||
|
const format = navigator.gpu.getPreferredCanvasFormat();
|
||||||
|
context.configure({ device, format });
|
||||||
|
}
|
||||||
|
|
||||||
|
createTexture(props: Texture2DProps): Texture2D {
|
||||||
|
return new Texture2D(this, props);
|
||||||
|
}
|
||||||
|
|
||||||
|
createIndexBuffer(indexCount: number): IndexBuffer {
|
||||||
|
return new IndexBuffer(this, indexCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
createMaterial(props: MaterialProps): Material {
|
||||||
|
return new Material(this, props);
|
||||||
|
}
|
||||||
|
|
||||||
|
createVertexBuffer(vertexCount: number): VertexBuffer {
|
||||||
|
return new VertexBuffer(this, vertexCount);
|
||||||
|
}
|
||||||
|
}
|
@ -16,7 +16,7 @@ export class Scene {
|
|||||||
|
|
||||||
readonly type!: "Scene";
|
readonly type!: "Scene";
|
||||||
|
|
||||||
_name: string | undefined;
|
_name: string;
|
||||||
|
|
||||||
_nodes: Node[];
|
_nodes: Node[];
|
||||||
|
|
||||||
|
@ -4,41 +4,47 @@
|
|||||||
* obtain one at http://mozilla.org/MPL/2.0/.
|
* obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { Renderer } from "./Renderer";
|
||||||
|
|
||||||
export interface Texture2DProps {
|
export interface Texture2DProps {
|
||||||
name?: string;
|
name?: string;
|
||||||
device: GPUDevice;
|
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
|
|
||||||
|
sRGB?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Texture2D {
|
export class Texture2D {
|
||||||
|
|
||||||
readonly type!: "Texture2D";
|
readonly type!: "Texture2D";
|
||||||
|
_renderer: Renderer;
|
||||||
|
|
||||||
_name: string;
|
_name: string;
|
||||||
|
|
||||||
_device: GPUDevice;
|
|
||||||
_texture: GPUTexture;
|
_texture: GPUTexture;
|
||||||
_textureView: GPUTextureView;
|
_textureView: GPUTextureView;
|
||||||
|
|
||||||
constructor({
|
constructor(renderer: Renderer, {
|
||||||
name = "",
|
name = "",
|
||||||
device,
|
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
|
sRGB = false,
|
||||||
}: Texture2DProps) {
|
}: Texture2DProps) {
|
||||||
Object.defineProperty(this, "type", { value: "Texture2D" });
|
Object.defineProperty(this, "type", { value: "Texture2D" });
|
||||||
|
|
||||||
|
this._renderer = renderer;
|
||||||
|
|
||||||
this._name = name;
|
this._name = name;
|
||||||
|
|
||||||
this._device = device;
|
this._renderer = renderer;
|
||||||
this._texture = device.createTexture({
|
this._texture = renderer._device.createTexture({
|
||||||
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,
|
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,
|
||||||
size: { width, height },
|
size: { width, height },
|
||||||
format: "rgba8unorm",
|
format: sRGB ? "rgba8unorm-srgb" : "rgba8unorm",
|
||||||
});
|
});
|
||||||
this._textureView = this._texture.createView({
|
this._textureView = this._texture.createView({
|
||||||
format: "rgba8unorm",
|
format: sRGB ? "rgba8unorm-srgb" : "rgba8unorm",
|
||||||
dimension: "2d",
|
dimension: "2d",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -57,7 +63,7 @@ export class Texture2D {
|
|||||||
}
|
}
|
||||||
|
|
||||||
writeTypedArray(data: Uint8Array): Texture2D {
|
writeTypedArray(data: Uint8Array): Texture2D {
|
||||||
this._device.queue.writeTexture(
|
this._renderer._device.queue.writeTexture(
|
||||||
{ texture: this._texture },
|
{ texture: this._texture },
|
||||||
data,
|
data,
|
||||||
{ bytesPerRow: 4 * this._texture.width },
|
{ bytesPerRow: 4 * this._texture.width },
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
* obtain one at http://mozilla.org/MPL/2.0/.
|
* obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { Renderer } from "./Renderer";
|
||||||
import { Vector3Object } from "./Vector3";
|
import { Vector3Object } from "./Vector3";
|
||||||
|
|
||||||
export const VERTEX_SIZE = 12;
|
export const VERTEX_SIZE = 12;
|
||||||
@ -11,15 +12,16 @@ export const VERTEX_SIZE = 12;
|
|||||||
export class VertexBuffer {
|
export class VertexBuffer {
|
||||||
|
|
||||||
readonly type!: "VertexBuffer";
|
readonly type!: "VertexBuffer";
|
||||||
|
_renderer: Renderer;
|
||||||
|
|
||||||
_device: GPUDevice;
|
|
||||||
_buffer: GPUBuffer;
|
_buffer: GPUBuffer;
|
||||||
|
|
||||||
constructor(device: GPUDevice, vertexCount: number) {
|
constructor(renderer: Renderer, vertexCount: number) {
|
||||||
Object.defineProperty(this, "type", { value: "VertexBuffer" });
|
Object.defineProperty(this, "type", { value: "VertexBuffer" });
|
||||||
|
|
||||||
this._device = device;
|
this._renderer = renderer;
|
||||||
this._buffer = device.createBuffer({
|
|
||||||
|
this._buffer = renderer._device.createBuffer({
|
||||||
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.VERTEX,
|
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.VERTEX,
|
||||||
size: vertexCount * VERTEX_SIZE,
|
size: vertexCount * VERTEX_SIZE,
|
||||||
});
|
});
|
||||||
@ -42,12 +44,12 @@ export class VertexBuffer {
|
|||||||
array[ptr++] = vertex.y;
|
array[ptr++] = vertex.y;
|
||||||
array[ptr++] = vertex.z;
|
array[ptr++] = vertex.z;
|
||||||
}
|
}
|
||||||
this._device.queue.writeBuffer(this._buffer, offset * VERTEX_SIZE | 0, array);
|
this._renderer._device.queue.writeBuffer(this._buffer, offset * VERTEX_SIZE | 0, array);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
writeTypedArray(offset: number, vertices: Float32Array): VertexBuffer {
|
writeTypedArray(offset: number, vertices: Float32Array): VertexBuffer {
|
||||||
this._device.queue.writeBuffer(this._buffer, offset * VERTEX_SIZE | 0, vertices);
|
this._renderer._device.queue.writeBuffer(this._buffer, offset * VERTEX_SIZE | 0, vertices);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ export * from "./Matrix4x4";
|
|||||||
export * from "./Mesh";
|
export * from "./Mesh";
|
||||||
export * from "./Node";
|
export * from "./Node";
|
||||||
export * from "./Quaternion";
|
export * from "./Quaternion";
|
||||||
|
export * from "./Renderer";
|
||||||
export * from "./Scene";
|
export * from "./Scene";
|
||||||
export * from "./Texture2D";
|
export * from "./Texture2D";
|
||||||
export * from "./Vector3";
|
export * from "./Vector3";
|
||||||
|
Loading…
Reference in New Issue
Block a user