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
3 changes: 2 additions & 1 deletion packages/graphics-2d/src/components/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export abstract class NfgComponent {
private readonly _pipelineLayout: GPUPipelineLayout;
private readonly _label: string;
private _bindGroup: GPUBindGroup;
protected _duplicate: number = 1;

constructor(core: GraphicsCore) {
this._core = core;
Expand Down Expand Up @@ -48,7 +49,7 @@ export abstract class NfgComponent {
pass.setPipeline(this._pipeline);
pass.setBindGroup(0, this._bindGroup);
pass.setVertexBuffer(0, this._vertexBuffer);
pass.draw(this._vertices.length / this._vertexLength);
pass.draw(this._vertices.length / this._vertexLength, this._duplicate);
}

protected abstract _init(): Promise<void>;
Expand Down
1 change: 1 addition & 0 deletions packages/graphics-2d/src/components/shape/shapes/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { NfgCircle } from "./circle.shape";
export { NfgRectangle } from "./rectangle.shape";
122 changes: 122 additions & 0 deletions packages/graphics-2d/src/components/shape/shapes/rectangle.shape.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { type GraphicsCore } from "../../../core";
import { ShadersEnum } from "../../../shader/shaders.enum";
import { type IColor, type IRectangleOptions, type IVertex2D } from "../../../types";
import { NfgShape } from "../common/shape";

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

private _min: IVertex2D;
private _max: IVertex2D;
private _color: IColor;

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

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

this._duplicate = 1;

this._min = options?.min ?? { x: 0, y: 0 };
this._max = options?.max ?? { x: 0, y: 0 };
this._color = options?.color ?? { r: 0, g: 0, b: 0, a: 1 };
this._updateVertices();
}

public setMin(pos: IVertex2D): NfgRectangle {
this._min = pos;
this._updateVertices();
return this;
}

public setMax(pos: IVertex2D): NfgRectangle {
this._max = pos;
this._updateVertices();
return this;
}

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

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

protected _updateVertices(): void {
this._setVertices([
this._min.x,
this._min.y,
this._max.x,
this._max.y,
this._color.r,
this._color.g,
this._color.b,
this._color.a,
this._min.x,
this._min.y,
this._max.x,
this._max.y,
this._color.r,
this._color.g,
this._color.b,
this._color.a,
this._min.x,
this._min.y,
this._max.x,
this._max.y,
this._color.r,
this._color.g,
this._color.b,
this._color.a,
this._min.x,
this._min.y,
this._max.x,
this._max.y,
this._color.r,
this._color.g,
this._color.b,
this._color.a,
this._min.x,
this._min.y,
this._max.x,
this._max.y,
this._color.r,
this._color.g,
this._color.b,
this._color.a,
this._min.x,
this._min.y,
this._max.x,
this._max.y,
this._color.r,
this._color.g,
this._color.b,
this._color.a,
]);
}
}
8 changes: 6 additions & 2 deletions packages/graphics-2d/src/factory.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { NfgCircle } from "./components";
import { NfgCircle, NfgRectangle } from "./components";
import { type GraphicsCore } from "./core";
import { type ICircleOptions } from "./types";
import { type ICircleOptions, type IRectangleOptions } from "./types";

export class GraphicsFactory {
private readonly _core: GraphicsCore;
Expand All @@ -12,4 +12,8 @@ export class GraphicsFactory {
createCircle(options?: Partial<ICircleOptions>): Promise<NfgCircle> {
return new NfgCircle(this._core, options).init();
}

createRectangle(options?: Partial<IRectangleOptions>): Promise<NfgRectangle> {
return new NfgRectangle(this._core, options).init();
}
}
4 changes: 2 additions & 2 deletions packages/graphics-2d/src/shader/shaders.const.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { ShadersEnum } from "./shaders.enum";

export const SHADER_PATHS: Record<ShadersEnum, string> = {
// [ShadersEnum.RECTANGLE]: "rectangle.wgsl",
[ShadersEnum.RECTANGLE]: "rectangle.wgsl",
[ShadersEnum.CIRCLE]: "circle.wgsl",
};

export const SHADER_NAMES: Record<ShadersEnum, string> = {
// [ShadersEnum.RECTANGLE]: "Rectangle shader",
[ShadersEnum.RECTANGLE]: "Rectangle shader",
[ShadersEnum.CIRCLE]: "Circle shader",
};
2 changes: 1 addition & 1 deletion packages/graphics-2d/src/shader/shaders.enum.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export enum ShadersEnum {
// RECTANGLE = 0,
RECTANGLE = 0,
CIRCLE = 1,
}
1 change: 1 addition & 0 deletions packages/graphics-2d/src/shader/shaders/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
import "./circle.wgsl";
import "./rectangle.wgsl";
54 changes: 54 additions & 0 deletions packages/graphics-2d/src/shader/shaders/rectangle.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
struct View {
position: vec4<f32>,
scale: vec2<f32>,
size: vec2<f32>,
};

@group(0)
@binding(0)
var<uniform> view: View;

struct VertexInput {
@builtin(vertex_index) index: u32
};

struct InstanceInput {
@location(0) min: vec2<f32>,
@location(1) max: vec2<f32>,
@location(2) color: vec4<f32>,
};

struct VertexOutput {
@builtin(position) clip_space: vec4<f32>,
@location(0) color: vec4<f32>,
};

@vertex
fn vertex_main(
vertex: VertexInput,
instance: InstanceInput,
) -> VertexOutput {
var result: VertexOutput;

let x = view.size.x;
let y = view.size.y;
let aspect = y / x;

var local_space = vec2<f32>(f32(vertex.index & 1u), f32(vertex.index >> 1u));
if vertex.index >= 3 {
local_space = vec2<f32>(f32(vertex.index & 1u), f32((vertex.index >> 1u) - 1u));
}
let position = instance.min + local_space * (instance.max - instance.min);

let view_space = (position - view.position.xy) / view.scale.x;
let clip_space = vec4<f32>(view_space.x * aspect, view_space.y, 0.0, 1.0);

result.clip_space = clip_space;
result.color = instance.color;
return result;
}

@fragment
fn fragment_main(vertex: VertexOutput) -> @location(0) vec4<f32> {
return vertex.color;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { type IVertex2D } from "../../common";
import { type IColorOption } from "../base/color.type";
import { type IPositionOption } from "../base/position.type";
import { type ISizeOption } from "../base/size.type";

export interface IRectangleOptions extends IColorOption, IPositionOption, ISizeOption {}
export interface IRectangleOptions extends IColorOption {
min: IVertex2D;
max: IVertex2D;
}
Loading