Spaces:
Running
Running
File size: 4,727 Bytes
6d53e86 6af9568 bc152ba effc3a3 d13e19f effc3a3 d998663 bc152ba b27f287 6d53e86 6af9568 41fe030 6af9568 d13e19f 6d53e86 6802c16 6af9568 9905bd0 538ade1 b27f287 ffea1eb 1cc5c8d effc3a3 0391f6c effc3a3 0391f6c 6af9568 effc3a3 d13e19f 1cc5c8d d998663 551d60d 6d53e86 b27f287 538ade1 f15ce4c 538ade1 6af9568 effc3a3 d998663 ffea1eb 1614d87 ffea1eb 538ade1 9905bd0 d998663 9905bd0 538ade1 d998663 effc3a3 6802c16 1cc5c8d 9eb5291 1cc5c8d 538ade1 6af9568 d998663 6802c16 538ade1 6af9568 effc3a3 538ade1 9905bd0 538ade1 9905bd0 538ade1 9905bd0 538ade1 9905bd0 6d53e86 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 121 |
import { mat4 } from 'https://webgpufundamentals.org/3rdparty/wgpu-matrix.module.js';
import { initializeDevice } from './wgpu-device.js';
import { createState } from './wgpu-state.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';
import { config } from './wgpu-config.js';
import { CANVAS, CTX, COLORS, RENDER_PASS_DESCRIPTOR } from './wgpu-constants.js';
import { CreateBuffers } from './wgpu-buffer.js';
// Initialize Canvas function
async function InitializeCanvas(config) {
// Create and configure the canvas element
const canvas = document.createElement('canvas');
canvas.width = config.canvas.width;
canvas.height = config.canvas.height;
document.body.appendChild(canvas);
// Request WebGPU adapter and device
const adapter = await navigator.gpu.requestAdapter();
// Use the existing initializeDevice function
const { device, context, presentationFormat } = await initializeDevice(navigator, adapter, canvas);
if (!device) {
alert('Failed to initialize WebGPU');
return;
}
// Return essential components for further setup
return { canvas, device, context, presentationFormat };
}
// Main function
const state = createState(config);
async function Main() {
const { canvas, device, context, presentationFormat } = await InitializeCanvas(config);
state.canvas = canvas;
state.webgpu.device = device;
state.webgpu.context = context;
state.webgpu.presentationFormat = presentationFormat;
initializeTiming(state);
await InitializeShaders(state);
await InitializeResources(state);
GameLoop(state);
}
// 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);
}
// Game Loop function
function GameLoop(state) {
function Tick(state) {
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), state.timing.frameDuration);
}
Tick(state);
}
// 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()]);
}
// Start the main function
Main();
|