UNPKG

@thewtex/vtk.js-esm

Version:

Visualization Toolkit for the Web

214 lines (170 loc) 7.41 kB
import macro from '../../macro.js'; import vtkWebGPUBufferManager from './BufferManager.js'; import vtkWebGPUTextureView from './TextureView.js'; import vtkWebGPUTypes from './Types.js'; var BufferUsage = vtkWebGPUBufferManager.BufferUsage; // ---------------------------------------------------------------------------- // Global methods // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // vtkWebGPUTexture methods // ---------------------------------------------------------------------------- function vtkWebGPUTexture(publicAPI, model) { // Set our className model.classHierarchy.push('vtkWebGPUTexture'); publicAPI.create = function (device, options) { model.device = device; model.width = options.width; model.height = options.height; model.depth = options.depth ? options.depth : 1; var dimension = model.depth === 1 ? '2d' : '3d'; model.format = options.format ? options.format : 'rgbaunorm'; /* eslint-disable no-undef */ /* eslint-disable no-bitwise */ model.usage = options.usage ? options.usage : GPUTextureUsage.SAMPLED | GPUTextureUsage.COPY_DST; /* eslint-enable no-undef */ /* eslint-enable no-bitwise */ model.handle = model.device.getHandle().createTexture({ size: [model.width, model.height, model.depth], format: model.format, // 'rgba8unorm', usage: model.usage, dimension: dimension }); }; publicAPI.assignFromHandle = function (device, handle, options) { model.device = device; model.handle = handle; model.width = options.width; model.height = options.height; model.depth = options.depth ? options.depth : 1; model.format = options.format ? options.format : 'rgbaunorm'; /* eslint-disable no-undef */ /* eslint-disable no-bitwise */ model.usage = options.usage ? options.usage : GPUTextureUsage.SAMPLED | GPUTextureUsage.COPY_DST; /* eslint-enable no-undef */ /* eslint-enable no-bitwise */ }; // set the data publicAPI.writeImageData = function (req) { var tDetails = vtkWebGPUTypes.getDetailsFromTextureFormat(model.format); var bufferBytesPerRow = model.width * tDetails.stride; if (req.nativeArray) { // create and write the buffer var buffRequest = { /* eslint-disable no-undef */ usage: BufferUsage.Texture /* eslint-enable no-undef */ }; if (req.dataArray) { buffRequest.dataArray = req.dataArray; buffRequest.time = req.dataArray.getMTime(); } buffRequest.nativeArray = req.nativeArray; // bytesPerRow must be a multiple of 256 so we might need to rebuild // the data here before passing to the buffer. e.g. if it is unorm8x4 then // we need to have width be a multiple of 64 var currWidthInBytes = model.width * tDetails.stride; if (currWidthInBytes % 256) { var oArray = req.dataArray.getData(); var bufferWidthInBytes = 256 * Math.floor((currWidthInBytes + 255) / 256); var bufferWidth = bufferWidthInBytes / oArray.BYTES_PER_ELEMENT; var oWidth = currWidthInBytes / oArray.BYTES_PER_ELEMENT; var nArray = macro.newTypedArray(oArray.name, bufferWidth * model.height * model.depth); for (var v = 0; v < model.height * model.depth; v++) { nArray.set(oArray.subarray(v * oWidth, (v + 1) * oWidth), v * bufferWidth); } buffRequest.nativeArray = nArray; bufferBytesPerRow = bufferWidthInBytes; } var buff = model.device.getBufferManager().getBuffer(buffRequest); model.buffer = buff; } if (req.image) { var canvas = document.createElement('canvas'); canvas.width = req.image.width; canvas.height = req.image.height; var ctx = canvas.getContext('2d'); ctx.translate(0, canvas.height); ctx.scale(1, -1); ctx.drawImage(req.image, 0, 0, req.image.width, req.image.height, 0, 0, canvas.width, canvas.height); var imageData = ctx.getImageData(0, 0, req.image.width, req.image.height); // create and write the buffer var _buffRequest = { nativeArray: imageData.data, time: 0, /* eslint-disable no-undef */ usage: BufferUsage.Texture, /* eslint-enable no-undef */ format: 'unorm8x4' }; var _buff = model.device.getBufferManager().getBuffer(_buffRequest); model.buffer = _buff; } // get a buffer for the image var cmdEnc = model.device.createCommandEncoder(); cmdEnc.copyBufferToTexture({ buffer: model.buffer.getHandle(), offset: 0, bytesPerRow: bufferBytesPerRow, rowsPerImage: model.height }, { texture: model.handle }, [model.width, model.height, model.depth]); model.device.submitCommandEncoder(cmdEnc); model.ready = true; }; publicAPI.resizeToMatch = function (tex) { if (tex.getWidth() !== model.width || tex.getHeight() !== model.height || tex.getDepth() !== model.depth) { model.width = tex.getWidth(); model.height = tex.getHeight(); model.depth = tex.getDepth(); model.handle = model.device.getHandle().createTexture({ size: [model.width, model.height, model.depth], format: model.format, usage: model.usage }); } }; publicAPI.resize = function (width, height) { var depth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; if (width !== model.width || height !== model.height || depth !== model.depth) { model.width = width; model.height = height; model.depth = depth; model.handle = model.device.getHandle().createTexture({ size: [model.width, model.height, model.depth], format: model.format, usage: model.usage }); } }; publicAPI.createView = function () { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; // if options is missing values try to add them in if (!options.dimension) { options.dimension = model.depth === 1 ? '2d' : '3d'; } var view = vtkWebGPUTextureView.newInstance(); view.create(publicAPI, options); return view; }; } // ---------------------------------------------------------------------------- // Object factory // ---------------------------------------------------------------------------- var DEFAULT_VALUES = { device: null, handle: null, buffer: null, ready: false }; // ---------------------------------------------------------------------------- function extend(publicAPI, model) { var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; Object.assign(model, DEFAULT_VALUES, initialValues); // Object methods macro.obj(publicAPI, model); macro.get(publicAPI, model, ['handle', 'ready', 'width', 'height', 'depth', 'format', 'usage']); macro.setGet(publicAPI, model, ['device']); vtkWebGPUTexture(publicAPI, model); } // ---------------------------------------------------------------------------- var newInstance = macro.newInstance(extend); // ---------------------------------------------------------------------------- var vtkWebGPUTexture$1 = { newInstance: newInstance, extend: extend }; export default vtkWebGPUTexture$1; export { extend, newInstance };