Added NodeJS Demo.
This commit is contained in:
304
demos/NodeJS/index.js
Normal file
304
demos/NodeJS/index.js
Normal file
@@ -0,0 +1,304 @@
|
||||
import sdl from '@kmamal/sdl'
|
||||
|
||||
import gpu from '@kmamal/gpu'
|
||||
|
||||
import Shader from "../../framework/WebGpu_node.js"
|
||||
|
||||
import Matrix4 from "../../framework/Matrix4.js"
|
||||
|
||||
import Vector3 from "../../framework/Vector3.js"
|
||||
|
||||
import Camera from "../../framework/Camera.js";
|
||||
|
||||
import EventManager from "../../framework/eventManager_node.js";
|
||||
|
||||
import { readFileSync } from "node:fs";
|
||||
|
||||
|
||||
const window = sdl.video.createWindow({ webgpu: true })
|
||||
|
||||
var canvas = window;
|
||||
|
||||
const instance = gpu.create([ 'verbose=1' ])
|
||||
|
||||
console.log("devices", gpu)
|
||||
|
||||
const adapter = await instance.requestAdapter()
|
||||
|
||||
const device = await adapter.requestDevice()
|
||||
|
||||
|
||||
const renderer = gpu.renderGPUDeviceToWindow({ device, window })
|
||||
|
||||
|
||||
canvas.getContext = function() {
|
||||
|
||||
return renderer;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
var renderShader = new Shader( device );
|
||||
|
||||
|
||||
renderShader.setCanvas( canvas );
|
||||
|
||||
renderShader.topology = "triangle-list";
|
||||
|
||||
await renderShader.setup( "../../shaders/triangle-list.wgsl");
|
||||
|
||||
async function loadJSON( pathName ) {
|
||||
|
||||
const json = await readFileSync( pathName, 'utf8' )
|
||||
|
||||
return JSON.parse( json );
|
||||
}
|
||||
|
||||
var camera = new Camera( [0, 0, 1115], [0, -.3, 0], [0, 1, 0] );
|
||||
|
||||
|
||||
|
||||
var eventManager = new EventManager( canvas );
|
||||
|
||||
eventManager.setup( canvas, camera );
|
||||
|
||||
eventManager.registerEventListenersNode();
|
||||
|
||||
var frameCount = 0;
|
||||
|
||||
|
||||
|
||||
var model = await loadJSON("../../models/demo.json");
|
||||
|
||||
var mesh = model.meshes[0];
|
||||
|
||||
|
||||
const instanceCount = 100;
|
||||
const instancePositions = new Float32Array(instanceCount * 4); // vec4 per instance
|
||||
|
||||
for (let i = 0; i < instanceCount; i++) {
|
||||
|
||||
const x = (i % 10) * 300.0;
|
||||
const y = Math.floor(i / 10) * 350.0;
|
||||
|
||||
instancePositions[i * 4 + 0] = x - 500;
|
||||
instancePositions[i * 4 + 1] = 0;
|
||||
instancePositions[i * 4 + 2] = y - 500;
|
||||
instancePositions[i * 4 + 3] = 0;
|
||||
}
|
||||
|
||||
|
||||
renderShader.setAttribute( "position", mesh.vertices );
|
||||
|
||||
renderShader.setAttribute( "normal", mesh.normals );
|
||||
|
||||
renderShader.setVariable( "instancePositions", instancePositions );
|
||||
|
||||
|
||||
var faces = mesh.faces;
|
||||
|
||||
const indexArray = new Uint32Array(faces.length * 3);
|
||||
|
||||
for (let i = 0; i < faces.length; i++) {
|
||||
|
||||
indexArray[i * 3 + 0] = faces[i][0];
|
||||
|
||||
indexArray[i * 3 + 1] = faces[i][1];
|
||||
|
||||
indexArray[i * 3 + 2] = faces[i][2];
|
||||
|
||||
}
|
||||
|
||||
renderShader.setIndices( indexArray );
|
||||
|
||||
var lastFrameTime = 0;
|
||||
|
||||
|
||||
|
||||
function updateTimeDelta() {
|
||||
|
||||
const now = performance.now();
|
||||
|
||||
deltaTimeValue = ( now - lastFrameTime ) / 1000;
|
||||
|
||||
lastFrameTime = now;
|
||||
|
||||
}
|
||||
|
||||
var frameCount = 0;
|
||||
|
||||
var deltaTimeValue = 0;
|
||||
|
||||
var vertexCount = 1;
|
||||
|
||||
const render = () => {
|
||||
|
||||
if (window.destroyed) { return }
|
||||
|
||||
updateTimeDelta();
|
||||
|
||||
const viewMatrixData = camera.getViewMatrix();
|
||||
|
||||
const projectionMatrixData = Matrix4.createProjectionMatrix( camera, canvas )
|
||||
|
||||
const viewProjectionMatrix = Matrix4.multiply( projectionMatrixData, viewMatrixData );
|
||||
|
||||
const cameraWorldMatrix = Matrix4.invert( viewMatrixData );
|
||||
|
||||
const cameraPosition = Matrix4.getColumn( cameraWorldMatrix, 3 );
|
||||
|
||||
renderShader.setVariable( "viewProjectionMatrix", viewProjectionMatrix );
|
||||
|
||||
renderShader.setVariable( "cameraPosition", cameraPosition );
|
||||
|
||||
frameCount++;
|
||||
|
||||
|
||||
renderShader.renderToCanvas( vertexCount, 60, 0, frameCount )
|
||||
|
||||
|
||||
renderer.swap()
|
||||
|
||||
|
||||
frameCount++;
|
||||
|
||||
setTimeout(render, 0)
|
||||
}
|
||||
|
||||
render();
|
||||
|
||||
|
||||
window.on('close', () => {
|
||||
device.destroy()
|
||||
gpu.destroy(instance)
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//console.log(model);
|
||||
|
||||
/*
|
||||
const renderer = gpu.renderGPUDeviceToWindow({ device, window })
|
||||
|
||||
const positions = new Float32Array([
|
||||
...[ 1.0, -1.0, 0.0 ],
|
||||
...[ -1.0, -1.0, 0.0 ],
|
||||
...[ 0.0, 1.0, 0.0 ],
|
||||
])
|
||||
|
||||
const colors = new Float32Array([
|
||||
...[ 1.0, 0.0, 0.0 ],
|
||||
...[ 0.0, 1.0, 0.0 ],
|
||||
...[ 0.0, 0.0, 1.0 ],
|
||||
])
|
||||
|
||||
const indices = new Uint16Array([ 0, 1, 2 ])
|
||||
|
||||
const createBuffer = (arr, usage) => {
|
||||
const buffer = device.createBuffer({
|
||||
size: (arr.byteLength + 3) & ~3,
|
||||
usage,
|
||||
mappedAtCreation: true,
|
||||
})
|
||||
|
||||
const writeArray = arr instanceof Uint16Array
|
||||
? new Uint16Array(buffer.getMappedRange())
|
||||
: new Float32Array(buffer.getMappedRange())
|
||||
writeArray.set(arr)
|
||||
buffer.unmap()
|
||||
return buffer
|
||||
}
|
||||
|
||||
const positionBuffer = createBuffer(positions, gpu.GPUBufferUsage.VERTEX)
|
||||
const colorBuffer = createBuffer(colors, gpu.GPUBufferUsage.VERTEX)
|
||||
const indexBuffer = createBuffer(indices, gpu.GPUBufferUsage.INDEX)
|
||||
|
||||
const vertexShaderFile = path.join(__dirname, 'vertex.wgsl')
|
||||
const vertexShaderCode = await fs.promises.readFile(vertexShaderFile, 'utf8')
|
||||
|
||||
const fragmentShaderFile = path.join(__dirname, 'fragment.wgsl')
|
||||
const fragmentShaderCode = await fs.promises.readFile(fragmentShaderFile, 'utf8')
|
||||
|
||||
const pipeline = device.createRenderPipeline({
|
||||
layout: 'auto',
|
||||
vertex: {
|
||||
module: device.createShaderModule({ code: vertexShaderCode }),
|
||||
entryPoint: 'main',
|
||||
buffers: [
|
||||
{
|
||||
attributes: [
|
||||
{
|
||||
shaderLocation: 0,
|
||||
offset: 0,
|
||||
format: 'float32x3',
|
||||
},
|
||||
],
|
||||
arrayStride: 3 * Float32Array.BYTES_PER_ELEMENT,
|
||||
stepMode: 'vertex',
|
||||
},
|
||||
{
|
||||
attributes: [
|
||||
{
|
||||
shaderLocation: 1,
|
||||
offset: 0,
|
||||
format: 'float32x3',
|
||||
},
|
||||
],
|
||||
arrayStride: 3 * Float32Array.BYTES_PER_ELEMENT,
|
||||
stepMode: 'vertex',
|
||||
},
|
||||
],
|
||||
},
|
||||
fragment: {
|
||||
module: device.createShaderModule({ code: fragmentShaderCode }),
|
||||
entryPoint: 'main',
|
||||
targets: [ { format: renderer.getPreferredFormat() } ],
|
||||
},
|
||||
primitive: {
|
||||
topology: 'triangle-list',
|
||||
},
|
||||
})
|
||||
|
||||
const render = () => {
|
||||
if (window.destroyed) { return }
|
||||
|
||||
const commandEncoder = device.createCommandEncoder()
|
||||
|
||||
const renderPass = commandEncoder.beginRenderPass({
|
||||
colorAttachments: [
|
||||
{
|
||||
view: renderer.getCurrentTextureView(),
|
||||
clearValue: { r: 0.0, g: 0.0, b: 0.0, a: 1.0 },
|
||||
loadOp: 'clear',
|
||||
storeOp: 'store',
|
||||
},
|
||||
],
|
||||
})
|
||||
renderPass.setPipeline(pipeline)
|
||||
renderPass.setViewport(0, 0, width, height, 0, 1)
|
||||
renderPass.setScissorRect(0, 0, width, height)
|
||||
renderPass.setVertexBuffer(0, positionBuffer)
|
||||
renderPass.setVertexBuffer(1, colorBuffer)
|
||||
renderPass.setIndexBuffer(indexBuffer, 'uint16')
|
||||
renderPass.drawIndexed(3)
|
||||
renderPass.end()
|
||||
|
||||
device.queue.submit([ commandEncoder.finish() ])
|
||||
|
||||
renderer.swap()
|
||||
|
||||
setTimeout(render, 0)
|
||||
}
|
||||
|
||||
render()
|
||||
|
||||
window.on('close', () => {
|
||||
device.destroy()
|
||||
gpu.destroy(instance)
|
||||
})
|
||||
|
||||
*/
|
||||
Reference in New Issue
Block a user