Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions packages/asset-manager/src/file.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { type IFile } from "@nanoforge/common";

export class NfFile implements IFile {
export class NfFile {
private readonly _path: string;

constructor(path: string) {
Expand Down
6 changes: 3 additions & 3 deletions packages/asset-manager/test/asset-manager.library.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe("Asset Manager Library", () => {
library.init(context);

it("Should get asset", async () => {
await expect(library.getAsset("test.png")).resolves.toEqual(
expect((await library.getAsset("test.png")).path).toEqual(
"blob:http://localhost:3000/test.png",
);
});
Expand All @@ -28,7 +28,7 @@ describe("Asset Manager Library", () => {
});

it("Should get wasm", async () => {
await expect(library.getWasm("test.wasm")).resolves.toEqual(
expect((await library.getWasm("test.wasm")).path).toEqual(
"blob:http://localhost:3000/test.wasm",
);
});
Expand All @@ -38,7 +38,7 @@ describe("Asset Manager Library", () => {
});

it("Should get wgsl", async () => {
await expect(library.getWgsl("test.wgsl")).resolves.toEqual(
expect((await library.getWgsl("test.wgsl")).path).toEqual(
"blob:http://localhost:3000/test.wgsl",
);
});
Expand Down
2 changes: 1 addition & 1 deletion packages/common/src/library/libraries/interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export { IExposedLibrary } from "./bases/exposed.library.type";
export { IRunnerLibrary } from "./bases/runner.library.type";
export { IAssetManagerLibrary, IFile } from "./finals/asset-manager.library.type";
export { IAssetManagerLibrary } from "./finals/asset-manager.library.type";
export { IComponentSystemLibrary } from "./finals/component-system.library.type";
export { IGraphicsLibrary } from "./finals/graphics.library.type";
export { INetworkLibrary } from "./finals/network.library.type";
115 changes: 115 additions & 0 deletions packages/graphics-2d/src/components/component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import type { GraphicsCore } from "../core";
import type { ShaderManager } from "../shader/shader.manager";

export abstract class NfgComponent {
private readonly _core: GraphicsCore;
protected readonly _shaderManager: ShaderManager;
private _vertices: Float32Array;
protected _vertexBuffer: GPUBuffer;
protected abstract _vertexLength: number;
protected abstract readonly _vertexBufferLayout: GPUVertexBufferLayout;
private _uniformBuffer: GPUBuffer;
protected abstract _shader: GPUShaderModule;
private _pipeline: GPURenderPipeline;
private readonly _pipelineLayout: GPUPipelineLayout;
private readonly _label: string;
private _bindGroup: GPUBindGroup;

constructor(core: GraphicsCore) {
this._core = core;
this._shaderManager = core.shaderManager;
this._label = `${this.constructor.name} - ${Date.now()}`;

const bindGroupLayout = this._core.device.createBindGroupLayout({
label: `${this._label} Bind Group Layout`,
entries: [
{
binding: 0,
visibility: GPUShaderStage.VERTEX | GPUShaderStage.COMPUTE | GPUShaderStage.FRAGMENT,
buffer: {},
},
],
});

this._pipelineLayout = this._core.device.createPipelineLayout({
label: `${this._label} Pipeline Layout`,
bindGroupLayouts: [bindGroupLayout],
});
}

public async init(): Promise<NfgComponent> {
await this._init();
this._updateUniforms();
this._updatePipeline();
return this;
}

public draw(pass: GPURenderPassEncoder): void {
pass.setPipeline(this._pipeline);
pass.setBindGroup(0, this._bindGroup);
pass.setVertexBuffer(0, this._vertexBuffer);
pass.draw(this._vertices.length / this._vertexLength);
}

protected abstract _init(): Promise<void>;

protected _setVertices(raw: number[]): void {
this._vertices = new Float32Array(raw);
this._updateVertexBuffer();
}

protected _updateVertexBuffer(): void {
this._core.device.queue.writeBuffer(this._vertexBuffer, 0, this._vertices);
}

protected _updatePipeline(): void {
this._pipeline = this._core.device.createRenderPipeline({
label: `${this._label} pipeline`,
layout: this._pipelineLayout,
vertex: {
module: this._shader,
entryPoint: "vertex_main",
buffers: [this._vertexBufferLayout],
},
fragment: {
module: this._shader,
entryPoint: "fragment_main",
targets: [
{
format: this._core.render.canvasFormat,
},
],
},
});
this._updateBindGroup();
}

protected _updateUniforms(): void {
const uniformArray = new Float32Array([
0,
0,
1,
this._core.initContext.canvas.width,
this._core.initContext.canvas.height,
]);
this._uniformBuffer = this._core.device.createBuffer({
label: "View Uniforms",
size: uniformArray.byteLength,
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, // Une uniform est une valeur constante pour le gpu
});
this._core.device.queue.writeBuffer(this._uniformBuffer, 0, uniformArray);
}

protected _updateBindGroup(): void {
this._bindGroup = this._core.device.createBindGroup({
label: `${this._label} renderer bind group`,
layout: this._pipeline.getBindGroupLayout(0),
entries: [
{
binding: 0,
resource: { buffer: this._uniformBuffer },
},
],
});
}
}
11 changes: 2 additions & 9 deletions packages/graphics-2d/src/components/shape/common/shape.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
import { type GraphicsCore } from "../../../core";
import { type ShaderManager } from "../../../shader/shader.manager";
import { NfgComponent } from "../../component";

export class NfShape {
private readonly _shaderManager: ShaderManager;

constructor(core: GraphicsCore) {
this._shaderManager = core.shaderManager;
}
}
export abstract class NfgShape extends NfgComponent {}
50 changes: 48 additions & 2 deletions packages/graphics-2d/src/components/shape/shapes/circle.shape.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,75 @@
import { type GraphicsCore } from "../../../core";
import { ShadersEnum } from "../../../shader/shaders.enum";
import { type ICircleOptions, type IColor, type IVertex2D } from "../../../types";
import { NfShape } from "../common/shape";
import { NfgShape } from "../common/shape";

export class NfgCircle extends NfgShape {
protected _shader: GPUShaderModule;
protected readonly _vertexBufferLayout: GPUVertexBufferLayout;
protected _vertexLength: number;

export class NfCircle extends NfShape {
private _pos: IVertex2D;
private _radius: number;
private _color: IColor;

constructor(core: GraphicsCore, options?: Partial<ICircleOptions>) {
super(core);

this._vertexBufferLayout = {
arrayStride: 28,
attributes: [
{
format: "float32x2",
offset: 0,
shaderLocation: 0,
},
{
format: "float32",
offset: 8,
shaderLocation: 1,
},
{
format: "float32x4",
offset: 12,
shaderLocation: 2,
},
],
};
this._vertexLength = 7;

this._pos = options?.pos ?? { x: 0, y: 0 };
this._radius = options?.radius ?? 1;
this._color = options?.color ?? { r: 0, g: 0, b: 0, a: 1 };
}

public setPosition(pos: IVertex2D): void {
this._pos = pos;
this._updateVertices();
}

public setRadius(radius: number): void {
this._radius = radius;
this._updateVertices();
}

public setColor(color: IColor): void {
this._color = color;
this._updateVertices();
}

protected async _init(): Promise<void> {
this._shader = await this._shaderManager.get(ShadersEnum.CIRCLE);
}

protected _updateVertices(): void {
this._setVertices([
this._pos.x,
this._pos.y,
this._radius,
this._color.r,
this._color.g,
this._color.b,
this._color.a,
]);
}
}
4 changes: 4 additions & 0 deletions packages/graphics-2d/src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ export class GraphicsCore {
return this._shaderManager;
}

get render(): GraphicsRender {
return this._render;
}

public async init(): Promise<void> {
if (!navigator.gpu) {
throw new Error("WebGPU not supported on this browser.");
Expand Down
4 changes: 0 additions & 4 deletions packages/graphics-2d/src/graphics-2d.library.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { BaseGraphicsLibrary, type ExecutionContext, type InitContext } from "@nanoforge/common";

import { type ICircleOptions } from "./types";

export class Graphics2DLibrary extends BaseGraphicsLibrary {
get name(): string {
return "Graphics2DLibrary";
Expand All @@ -13,8 +11,6 @@ export class Graphics2DLibrary extends BaseGraphicsLibrary {
}
}

public createCircle(options: ICircleOptions): void {}

public async run(context: ExecutionContext): Promise<void> {
console.log(context);
}
Expand Down
8 changes: 8 additions & 0 deletions packages/graphics-2d/src/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,12 @@ export class GraphicsRender {
format: this._canvasFormat,
});
}

get canvasContext(): GPUCanvasContext {
return this._canvasContext;
}

get canvasFormat(): GPUTextureFormat {
return this._canvasFormat;
}
}
3 changes: 2 additions & 1 deletion packages/graphics-2d/test/graphics-2d.library.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ describe("Graphics 2D Library", () => {
canvas: null,
files: {
assets: new Map([["/test.png", "blob:http://localhost:3000/test.png"]]),
scripts: new Map([["/test.wasm", "blob:http://localhost:3000/test.wasm"]]),
wasm: new Map([["/test.wasm", "blob:http://localhost:3000/test.wasm"]]),
wgsl: new Map([["/test.wgsl", "blob:http://localhost:3000/test.wgsl"]]),
},
});

Expand Down
Loading