Add resizing
This commit is contained in:
parent
9c7b91000f
commit
058d6014b7
18 changed files with 254 additions and 138 deletions
|
|
@ -6,6 +6,7 @@ import { DiffusionPipeline } from '../pipelines/diffusion/diffusion-pipeline';
|
|||
import { RenderPipeline } from '../pipelines/render/render-pipeline';
|
||||
import { settings } from '../settings';
|
||||
import { DeltaTimeCalculator } from '../utils/delta-time-calculator';
|
||||
import { ResizableTexture } from '../utils/graphics/resizable-texture';
|
||||
import { sleep } from '../utils/sleep';
|
||||
import { spawnAgents } from './spawn-agents';
|
||||
|
||||
|
|
@ -14,6 +15,8 @@ import { vec2 } from 'gl-matrix';
|
|||
export default class GameLoop {
|
||||
private readonly deltaTimeCalculator = new DeltaTimeCalculator();
|
||||
|
||||
private readonly trailMapA: ResizableTexture;
|
||||
private readonly trailMapB: ResizableTexture;
|
||||
private readonly commonState: CommonState;
|
||||
private readonly copyPipeline: CopyPipeline;
|
||||
private readonly agentPipeline: AgentPipeline;
|
||||
|
|
@ -21,11 +24,6 @@ export default class GameLoop {
|
|||
private readonly brushPipeline: BrushPipeline;
|
||||
private readonly diffusionPipeline: DiffusionPipeline;
|
||||
|
||||
private trailMapA?: GPUTexture;
|
||||
private trailMapB?: GPUTexture;
|
||||
private trailMapAView?: GPUTextureView;
|
||||
private trailMapBView?: GPUTextureView;
|
||||
|
||||
private hasFinished = false;
|
||||
private readonly hasFinishedPromise: Promise<void> = new Promise(
|
||||
(resolve) => (this.resolveHasFinished = resolve)
|
||||
|
|
@ -45,6 +43,8 @@ export default class GameLoop {
|
|||
alphaMode: 'premultiplied',
|
||||
});
|
||||
|
||||
this.trailMapA = new ResizableTexture(this.device, this.canvasSize);
|
||||
this.trailMapB = new ResizableTexture(this.device, this.canvasSize);
|
||||
this.resize();
|
||||
|
||||
this.commonState = new CommonState(this.device);
|
||||
|
|
@ -60,8 +60,8 @@ export default class GameLoop {
|
|||
|
||||
window.addEventListener('resize', this.resize.bind(this));
|
||||
|
||||
window.addEventListener('mousemove', this.onSwipe.bind(this));
|
||||
window.addEventListener('mousedown', (e) => {
|
||||
canvas.addEventListener('mousemove', this.onSwipe.bind(this));
|
||||
canvas.addEventListener('mousedown', (e) => {
|
||||
this.brushPipeline.clearSwipes();
|
||||
this.isSwipeActive = true;
|
||||
this.onSwipe(e);
|
||||
|
|
@ -91,31 +91,6 @@ export default class GameLoop {
|
|||
const devicePixelRatio = window.devicePixelRatio || 1;
|
||||
this.canvas.width = this.canvas.clientWidth * devicePixelRatio;
|
||||
this.canvas.height = this.canvas.clientHeight * devicePixelRatio;
|
||||
|
||||
this.trailMapA?.destroy();
|
||||
this.trailMapA = this.createTrailMap();
|
||||
this.trailMapAView = this.trailMapA.createView();
|
||||
|
||||
this.trailMapB?.destroy();
|
||||
this.trailMapB = this.createTrailMap();
|
||||
this.trailMapBView = this.trailMapB.createView();
|
||||
}
|
||||
|
||||
private createTrailMap(): GPUTexture {
|
||||
return this.device.createTexture({
|
||||
format: 'rgba16float',
|
||||
dimension: '2d',
|
||||
mipLevelCount: 1,
|
||||
size: {
|
||||
width: this.canvas.width,
|
||||
height: this.canvas.height,
|
||||
depthOrArrayLayers: 1,
|
||||
},
|
||||
usage:
|
||||
GPUTextureUsage.STORAGE_BINDING |
|
||||
GPUTextureUsage.TEXTURE_BINDING |
|
||||
GPUTextureUsage.RENDER_ATTACHMENT,
|
||||
});
|
||||
}
|
||||
|
||||
private async render(time: DOMHighResTimeStamp) {
|
||||
|
|
@ -137,15 +112,23 @@ export default class GameLoop {
|
|||
const commandEncoder = this.device.createCommandEncoder();
|
||||
|
||||
for (let i = 0; i < settings.renderSpeed; i++) {
|
||||
this.copyPipeline.execute(commandEncoder, this.trailMapAView, this.trailMapBView);
|
||||
this.brushPipeline.execute(commandEncoder, this.trailMapBView);
|
||||
this.agentPipeline.execute(commandEncoder, this.trailMapAView, this.trailMapBView);
|
||||
this.copyPipeline.execute(
|
||||
commandEncoder,
|
||||
this.trailMapA.getTextureView(),
|
||||
this.trailMapB.getTextureView()
|
||||
);
|
||||
this.brushPipeline.execute(commandEncoder, this.trailMapB.getTextureView());
|
||||
this.agentPipeline.execute(
|
||||
commandEncoder,
|
||||
this.trailMapA.getTextureView(),
|
||||
this.trailMapB.getTextureView()
|
||||
);
|
||||
this.diffusionPipeline.execute(
|
||||
commandEncoder,
|
||||
this.trailMapBView,
|
||||
this.trailMapAView
|
||||
this.trailMapB.getTextureView(),
|
||||
this.trailMapA.getTextureView()
|
||||
);
|
||||
this.renderPipeline.execute(commandEncoder, this.trailMapAView);
|
||||
this.renderPipeline.execute(commandEncoder, this.trailMapA.getTextureView());
|
||||
}
|
||||
|
||||
this.device.queue.submit([commandEncoder.finish()]);
|
||||
|
|
@ -157,6 +140,11 @@ export default class GameLoop {
|
|||
if (settings.simulatedDelayMs > 0) {
|
||||
await sleep(settings.simulatedDelayMs);
|
||||
}
|
||||
|
||||
// avoid resizing during rendering
|
||||
this.trailMapA.resize(this.canvasSize);
|
||||
this.trailMapB.resize(this.canvasSize);
|
||||
|
||||
requestAnimationFrame(this.render.bind(this));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,22 +6,19 @@ import { vec2 } from 'gl-matrix';
|
|||
|
||||
export const spawnAgents = (canvasSize: vec2, agentCount: number): Array<Agent> => {
|
||||
const minSize = Math.min(...canvasSize);
|
||||
const ratio = Math.max(...canvasSize) / minSize;
|
||||
const size = vec2.scale(vec2.create(), canvasSize, 1 / minSize);
|
||||
vec2.normalize(size, size);
|
||||
const center = vec2.scale(vec2.create(), canvasSize, 0.5);
|
||||
|
||||
return new Array(agentCount).fill(0).map(() => {
|
||||
const radius = Random.randomBetween(0, settings.startingRadius / ratio);
|
||||
const radius = Random.randomBetween(0, minSize * settings.startingRadius);
|
||||
const angle = Random.randomBetween(0, Math.PI * 2);
|
||||
const center = vec2.fromValues(0.5, 0.5);
|
||||
|
||||
const delta = vec2.fromValues(Math.cos(angle) * radius, Math.sin(angle) * radius);
|
||||
vec2.divide(delta, delta, size);
|
||||
|
||||
const position = vec2.add(vec2.create(), center, delta);
|
||||
|
||||
return {
|
||||
position,
|
||||
angle: angle + Math.PI,
|
||||
direction: vec2.fromValues(Math.cos(angle + Math.PI), Math.sin(angle + Math.PI)),
|
||||
species: 0,
|
||||
timeToLive: Random.randomBetween(10, 15000),
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue