Spaces:
Running
Running
🗑️ Deprecate timing file and update state creation
Browse files- index.js +72 -79
- wgpu-config.js +6 -0
- wgpu-state.js +6 -7
- wgpu-timing.js +0 -14
index.js
CHANGED
@@ -1,5 +1,3 @@
|
|
1 |
-
// index.js
|
2 |
-
|
3 |
import { mat4 } from 'https://webgpufundamentals.org/3rdparty/wgpu-matrix.module.js';
|
4 |
|
5 |
import { CANVAS, CTX, COLORS, RENDER_PASS_DESCRIPTOR } from './wgpu-constants.js';
|
@@ -8,7 +6,6 @@ import { config } from './wgpu-config.js';
|
|
8 |
import { createState } from './wgpu-state.js';
|
9 |
import { initializeDevice } from './wgpu-device.js';
|
10 |
import { CreateBuffers } from './wgpu-buffer.js';
|
11 |
-
import { initializeTiming } from './wgpu-timing.js';
|
12 |
import { createPipeline } from './wgpu-pipeline.js';
|
13 |
|
14 |
import { generateGlyphTextureAtlas, createTextureFromSource } from './wgpu-utility.js';
|
@@ -16,88 +13,84 @@ import { InitializeShaders } from './wgpu-shader.js';
|
|
16 |
import { GenerateVertexDataAndTexture } from './wgpu-texture.js';
|
17 |
import { generateGlyphVerticesForText } from './wgpu-text.js';
|
18 |
|
19 |
-
async
|
20 |
-
state
|
21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
|
23 |
-
|
24 |
-
|
|
|
25 |
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
}
|
30 |
-
}
|
31 |
-
|
32 |
-
async function InitializeResources(state) {
|
33 |
-
state.webgpu.pipeline = await createPipeline(state.webgpu.device, state.webgpu.presentationFormat, state.webgpu.vertexSize, state.webgpu.shaderCode);
|
34 |
-
|
35 |
-
const glyphCanvas = generateGlyphTextureAtlas(CANVAS, CTX, config);
|
36 |
-
document.body.appendChild(glyphCanvas);
|
37 |
-
glyphCanvas.style.backgroundColor = '#222';
|
38 |
-
|
39 |
-
CreateBuffers(state, config);
|
40 |
-
GenerateVertexDataAndTexture(state, glyphCanvas, generateGlyphVerticesForText, COLORS, config, createTextureFromSource);
|
41 |
-
}
|
42 |
-
|
43 |
-
function FixedUpdate(state) {
|
44 |
-
state.timing.time += state.timing.fixedDeltaTime;
|
45 |
-
}
|
46 |
-
|
47 |
-
function Render(state) {
|
48 |
-
const fov = 60 * Math.PI / 180;
|
49 |
-
const aspect = state.canvas.clientWidth / state.canvas.clientHeight;
|
50 |
-
const projectionMatrix = mat4.perspective(fov, aspect, config.render.zNear, config.render.zFar);
|
51 |
-
const viewMatrix = mat4.lookAt([0, 0, 5], [0, 0, 0], [0, 1, 0]);
|
52 |
-
const viewProjectionMatrix = mat4.multiply(projectionMatrix, viewMatrix);
|
53 |
-
|
54 |
-
RENDER_PASS_DESCRIPTOR.colorAttachments[0].view = state.webgpu.context.getCurrentTexture().createView();
|
55 |
-
const encoder = state.webgpu.device.createCommandEncoder();
|
56 |
-
const pass = encoder.beginRenderPass(RENDER_PASS_DESCRIPTOR);
|
57 |
-
|
58 |
-
pass.setPipeline(state.webgpu.pipeline);
|
59 |
-
mat4.rotateY(viewProjectionMatrix, state.timing.time, state.matrices.matrix);
|
60 |
-
mat4.translate(state.matrices.matrix, [-state.glyphs.width / 2, -state.glyphs.height / 2, 0], state.matrices.matrix);
|
61 |
-
|
62 |
-
state.webgpu.device.queue.writeBuffer(state.webgpu.uniformBuffer, 0, state.matrices.uniformValues);
|
63 |
-
|
64 |
-
pass.setBindGroup(0, state.webgpu.bindGroup);
|
65 |
-
pass.setVertexBuffer(0, state.webgpu.vertexBuffer);
|
66 |
-
pass.setIndexBuffer(state.webgpu.indexBuffer, 'uint32');
|
67 |
-
pass.drawIndexed(state.glyphs.numGlyphs * 6);
|
68 |
-
pass.end();
|
69 |
-
|
70 |
-
state.webgpu.device.queue.submit([encoder.finish()]);
|
71 |
-
}
|
72 |
-
|
73 |
-
function GameLoop(state) {
|
74 |
-
function Tick() {
|
75 |
-
state.timing.currentTime = performance.now();
|
76 |
-
state.timing.frameTime = (state.timing.currentTime - state.timing.lastTime) / 1000;
|
77 |
-
state.timing.lastTime = state.timing.currentTime;
|
78 |
-
state.timing.deltaTime = Math.min(state.timing.frameTime, state.timing.maxFrameTime);
|
79 |
-
state.timing.accumulator += state.timing.deltaTime;
|
80 |
-
|
81 |
-
while (state.timing.accumulator >= state.timing.fixedDeltaTime) {
|
82 |
-
FixedUpdate(state);
|
83 |
-
state.timing.accumulator -= state.timing.fixedDeltaTime;
|
84 |
-
}
|
85 |
|
86 |
-
|
87 |
-
|
88 |
}
|
89 |
|
90 |
-
|
91 |
-
|
|
|
|
|
|
|
|
|
92 |
|
93 |
-
|
|
|
|
|
94 |
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
|
103 |
-
Main();
|
|
|
|
|
|
|
|
1 |
import { mat4 } from 'https://webgpufundamentals.org/3rdparty/wgpu-matrix.module.js';
|
2 |
|
3 |
import { CANVAS, CTX, COLORS, RENDER_PASS_DESCRIPTOR } from './wgpu-constants.js';
|
|
|
6 |
import { createState } from './wgpu-state.js';
|
7 |
import { initializeDevice } from './wgpu-device.js';
|
8 |
import { CreateBuffers } from './wgpu-buffer.js';
|
|
|
9 |
import { createPipeline } from './wgpu-pipeline.js';
|
10 |
|
11 |
import { generateGlyphTextureAtlas, createTextureFromSource } from './wgpu-utility.js';
|
|
|
13 |
import { GenerateVertexDataAndTexture } from './wgpu-texture.js';
|
14 |
import { generateGlyphVerticesForText } from './wgpu-text.js';
|
15 |
|
16 |
+
(async () => {
|
17 |
+
const state = createState(config);
|
18 |
+
|
19 |
+
async function Main() {
|
20 |
+
await InitializeCanvas(state);
|
21 |
+
await initializeDevice(state);
|
22 |
+
await InitializeShaders(state);
|
23 |
+
await InitializeResources(state);
|
24 |
+
GameLoop(state);
|
25 |
+
}
|
26 |
|
27 |
+
async function InitializeCanvas(state) {
|
28 |
+
state.canvas.width = config.canvas.width;
|
29 |
+
state.canvas.height = config.canvas.height;
|
30 |
|
31 |
+
state.webgpu.adapter = await navigator.gpu.requestAdapter();
|
32 |
+
}
|
33 |
+
|
34 |
+
async function InitializeResources(state) {
|
35 |
+
state.webgpu.pipeline = await createPipeline(state.webgpu.device, state.webgpu.presentationFormat, state.webgpu.vertexSize, state.webgpu.shaderCode);
|
36 |
+
|
37 |
+
state.webgpu.glyphCanvas = generateGlyphTextureAtlas(CANVAS, CTX, config);
|
38 |
+
document.body.appendChild(state.webgpu.glyphCanvas);
|
39 |
+
state.webgpu.glyphCanvas.style.backgroundColor = '#222';
|
40 |
+
|
41 |
+
CreateBuffers(state, config);
|
42 |
+
GenerateVertexDataAndTexture(state, state.webgpu.glyphCanvas, generateGlyphVerticesForText, COLORS, config, createTextureFromSource);
|
43 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
|
45 |
+
function FixedUpdate(state) {
|
46 |
+
state.timing.time += state.timing.fixedDeltaTime;
|
47 |
}
|
48 |
|
49 |
+
function Render(state) {
|
50 |
+
const fov = 60 * Math.PI / 180;
|
51 |
+
const aspect = state.canvas.clientWidth / state.canvas.clientHeight;
|
52 |
+
const projectionMatrix = mat4.perspective(fov, aspect, config.render.zNear, config.render.zFar);
|
53 |
+
const viewMatrix = mat4.lookAt([0, 0, 5], [0, 0, 0], [0, 1, 0]);
|
54 |
+
const viewProjectionMatrix = mat4.multiply(projectionMatrix, viewMatrix);
|
55 |
|
56 |
+
RENDER_PASS_DESCRIPTOR.colorAttachments[0].view = state.webgpu.context.getCurrentTexture().createView();
|
57 |
+
const encoder = state.webgpu.device.createCommandEncoder();
|
58 |
+
const pass = encoder.beginRenderPass(RENDER_PASS_DESCRIPTOR);
|
59 |
|
60 |
+
pass.setPipeline(state.webgpu.pipeline);
|
61 |
+
mat4.rotateY(viewProjectionMatrix, state.timing.time, state.matrices.matrix);
|
62 |
+
mat4.translate(state.matrices.matrix, [-state.glyphs.width / 2, -state.glyphs.height / 2, 0], state.matrices.matrix);
|
63 |
+
|
64 |
+
state.webgpu.device.queue.writeBuffer(state.webgpu.uniformBuffer, 0, state.matrices.uniformValues);
|
65 |
+
|
66 |
+
pass.setBindGroup(0, state.webgpu.bindGroup);
|
67 |
+
pass.setVertexBuffer(0, state.webgpu.vertexBuffer);
|
68 |
+
pass.setIndexBuffer(state.webgpu.indexBuffer, 'uint32');
|
69 |
+
pass.drawIndexed(state.glyphs.numGlyphs * 6);
|
70 |
+
pass.end();
|
71 |
+
|
72 |
+
state.webgpu.device.queue.submit([encoder.finish()]);
|
73 |
+
}
|
74 |
+
|
75 |
+
function GameLoop(state) {
|
76 |
+
function Tick() {
|
77 |
+
state.timing.currentTime = performance.now();
|
78 |
+
state.timing.frameTime = (state.timing.currentTime - state.timing.lastTime) / 1000;
|
79 |
+
state.timing.lastTime = state.timing.currentTime;
|
80 |
+
state.timing.deltaTime = Math.min(state.timing.frameTime, state.timing.maxFrameTime);
|
81 |
+
state.timing.accumulator += state.timing.deltaTime;
|
82 |
+
|
83 |
+
while (state.timing.accumulator >= state.timing.fixedDeltaTime) {
|
84 |
+
FixedUpdate(state);
|
85 |
+
state.timing.accumulator -= state.timing.fixedDeltaTime;
|
86 |
+
}
|
87 |
+
|
88 |
+
Render(state);
|
89 |
+
setTimeout(Tick, state.timing.frameDuration);
|
90 |
+
}
|
91 |
+
|
92 |
+
Tick();
|
93 |
+
}
|
94 |
|
95 |
+
await Main();
|
96 |
+
})();
|
wgpu-config.js
CHANGED
@@ -23,5 +23,11 @@ export const config = {
|
|
23 |
zNear: 0.001,
|
24 |
zFar: 50
|
25 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
maxFPS: 60
|
27 |
};
|
|
|
23 |
zNear: 0.001,
|
24 |
zFar: 50
|
25 |
},
|
26 |
+
timing: {
|
27 |
+
fixedDeltaTime: 1 / 60,
|
28 |
+
maxFrameTime: 0.25,
|
29 |
+
targetFps: 60,
|
30 |
+
frameDuration: 1000 / 60
|
31 |
+
},
|
32 |
maxFPS: 60
|
33 |
};
|
wgpu-state.js
CHANGED
@@ -1,5 +1,3 @@
|
|
1 |
-
// wgpu-state.js
|
2 |
-
|
3 |
export function createState(config) {
|
4 |
return {
|
5 |
webgpu: {
|
@@ -16,6 +14,7 @@ export function createState(config) {
|
|
16 |
bindGroup: null,
|
17 |
shaderCode: null,
|
18 |
vertexSize: config.floatsPerVertex * config.vertexMultiplier,
|
|
|
19 |
},
|
20 |
matrices: {
|
21 |
uniformValues: new Float32Array(config.floatsInUniformBuffer),
|
@@ -29,15 +28,15 @@ export function createState(config) {
|
|
29 |
canvas: document.querySelector('canvas') || document.body.appendChild(document.createElement('canvas')),
|
30 |
timing: {
|
31 |
time: 0,
|
32 |
-
fixedDeltaTime:
|
33 |
-
maxFrameTime:
|
34 |
-
targetFps:
|
35 |
-
frameDuration:
|
36 |
accumulator: 0,
|
37 |
deltaTime: 0,
|
38 |
currentTime: 0,
|
39 |
frameTime: 0,
|
40 |
-
lastTime:
|
41 |
}
|
42 |
};
|
43 |
}
|
|
|
|
|
|
|
1 |
export function createState(config) {
|
2 |
return {
|
3 |
webgpu: {
|
|
|
14 |
bindGroup: null,
|
15 |
shaderCode: null,
|
16 |
vertexSize: config.floatsPerVertex * config.vertexMultiplier,
|
17 |
+
glyphCanvas: null
|
18 |
},
|
19 |
matrices: {
|
20 |
uniformValues: new Float32Array(config.floatsInUniformBuffer),
|
|
|
28 |
canvas: document.querySelector('canvas') || document.body.appendChild(document.createElement('canvas')),
|
29 |
timing: {
|
30 |
time: 0,
|
31 |
+
fixedDeltaTime: config.timing.fixedDeltaTime,
|
32 |
+
maxFrameTime: config.timing.maxFrameTime,
|
33 |
+
targetFps: config.timing.targetFps,
|
34 |
+
frameDuration: config.timing.frameDuration,
|
35 |
accumulator: 0,
|
36 |
deltaTime: 0,
|
37 |
currentTime: 0,
|
38 |
frameTime: 0,
|
39 |
+
lastTime: performance.now()
|
40 |
}
|
41 |
};
|
42 |
}
|
wgpu-timing.js
DELETED
@@ -1,14 +0,0 @@
|
|
1 |
-
// wgpu-timing.js
|
2 |
-
|
3 |
-
export function initializeTiming(state) {
|
4 |
-
state.timing.fixedDeltaTime = 1 / 60;
|
5 |
-
state.timing.maxFrameTime = 0.25;
|
6 |
-
state.timing.targetFps = 60;
|
7 |
-
state.timing.frameDuration = 1000 / 60;
|
8 |
-
state.timing.lastTime = performance.now();
|
9 |
-
state.timing.accumulator = 0;
|
10 |
-
state.timing.currentTime = 0;
|
11 |
-
state.timing.frameTime = 0;
|
12 |
-
state.timing.deltaTime = 0;
|
13 |
-
state.timing.time = 0;
|
14 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|