Spaces:
Running
Running
File size: 4,402 Bytes
922216d 6d53e86 922216d bc152ba 922216d effc3a3 d13e19f 922216d effc3a3 d998663 6d53e86 6af9568 922216d 6af9568 41fe030 6af9568 9905bd0 0391f6c 6af9568 effc3a3 d13e19f 1cc5c8d d998663 551d60d 6d53e86 b27f287 f15ce4c 538ade1 6af9568 d998663 6802c16 538ade1 6af9568 effc3a3 538ade1 9905bd0 538ade1 922216d 9905bd0 538ade1 922216d 9905bd0 922216d 9905bd0 922216d 9905bd0 538ade1 922216d 9905bd0 6d53e86 922216d 6af9568 6802c16 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
// index.js
import { mat4 } from 'https://webgpufundamentals.org/3rdparty/wgpu-matrix.module.js';
import { CANVAS, CTX, COLORS, RENDER_PASS_DESCRIPTOR } from './wgpu-constants.js';
import { config } from './wgpu-config.js';
import { createState } from './wgpu-state.js';
import { initializeDevice } from './wgpu-device.js';
import { CreateBuffers } from './wgpu-buffer.js';
import { initializeTiming } from './wgpu-timing.js';
import { createPipeline } from './wgpu-pipeline.js';
import { generateGlyphTextureAtlas, createTextureFromSource } from './wgpu-utility.js';
import { InitializeShaders } from './wgpu-shader.js';
import { GenerateVertexDataAndTexture } from './wgpu-texture.js';
import { generateGlyphVerticesForText } from './wgpu-text.js';
// Initialize Canvas function
async function InitializeCanvas(state) {
const canvas = document.createElement('canvas');
canvas.width = config.canvas.width;
canvas.height = config.canvas.height;
document.body.appendChild(canvas);
const adapter = await navigator.gpu.requestAdapter();
const { device, context, presentationFormat } = await initializeDevice(navigator, adapter, canvas);
if (!device) {
alert('Failed to initialize WebGPU');
return;
}
state.canvas = canvas;
state.webgpu.device = device;
state.webgpu.context = context;
state.webgpu.presentationFormat = presentationFormat;
}
// Initialize Resources function
async function InitializeResources(state) {
const vertexSize = config.floatsPerVertex * 4;
state.webgpu.pipeline = await createPipeline(state.webgpu.device, state.webgpu.presentationFormat, vertexSize, state.webgpu.shaderCode);
const glyphCanvas = generateGlyphTextureAtlas(CANVAS, CTX, config);
document.body.appendChild(glyphCanvas);
glyphCanvas.style.backgroundColor = '#222';
CreateBuffers(state, config);
GenerateVertexDataAndTexture(state, glyphCanvas, generateGlyphVerticesForText, COLORS, config, createTextureFromSource);
}
// Fixed Update function
function FixedUpdate(state) {
state.timing.time += state.timing.fixedDeltaTime;
}
// Render function
function Render(state) {
const fov = 60 * Math.PI / 180;
const aspect = state.canvas.clientWidth / state.canvas.clientHeight;
const projectionMatrix = mat4.perspective(fov, aspect, config.render.zNear, config.render.zFar);
const viewMatrix = mat4.lookAt([0, 0, 5], [0, 0, 0], [0, 1, 0]);
const viewProjectionMatrix = mat4.multiply(projectionMatrix, viewMatrix);
RENDER_PASS_DESCRIPTOR.colorAttachments[0].view = state.webgpu.context.getCurrentTexture().createView();
const encoder = state.webgpu.device.createCommandEncoder();
const pass = encoder.beginRenderPass(RENDER_PASS_DESCRIPTOR);
pass.setPipeline(state.webgpu.pipeline);
mat4.rotateY(viewProjectionMatrix, state.timing.time, state.matrices.matrix);
mat4.translate(state.matrices.matrix, [-state.glyphs.width / 2, -state.glyphs.height / 2, 0], state.matrices.matrix);
state.webgpu.device.queue.writeBuffer(state.webgpu.uniformBuffer, 0, state.matrices.uniformValues);
pass.setBindGroup(0, state.webgpu.bindGroup);
pass.setVertexBuffer(0, state.webgpu.vertexBuffer);
pass.setIndexBuffer(state.webgpu.indexBuffer, 'uint32');
pass.drawIndexed(state.glyphs.numGlyphs * 6);
pass.end();
state.webgpu.device.queue.submit([encoder.finish()]);
}
// Game Loop function
function GameLoop(state) {
function Tick() {
state.timing.currentTime = performance.now();
state.timing.frameTime = (state.timing.currentTime - state.timing.lastTime) / 1000;
state.timing.lastTime = state.timing.currentTime;
state.timing.deltaTime = Math.min(state.timing.frameTime, state.timing.maxFrameTime);
state.timing.accumulator += state.timing.deltaTime;
while (state.timing.accumulator >= state.timing.fixedDeltaTime) {
FixedUpdate(state);
state.timing.accumulator -= state.timing.fixedDeltaTime;
}
Render(state);
setTimeout(Tick, state.timing.frameDuration);
}
Tick();
}
// Main function
const state = createState(config);
async function Main() {
await InitializeCanvas(state);
initializeTiming(state);
await InitializeShaders(state);
await InitializeResources(state);
GameLoop(state);
}
// Start the main function
Main();
|