UNPKG

@kitware/vtk.js

Version:

Visualization Toolkit for the Web

267 lines (209 loc) 8.79 kB
import { newInstance as newInstance$1, obj, vtkErrorMacro, getArray } from '../../macros.js'; import vtkOpenGLTexture from './Texture.js'; import { VtkDataTypes } from '../../Common/Core/DataArray/Constants.js'; import { Filter } from './Texture/Constants.js'; // vtkFramebuffer methods // ---------------------------------------------------------------------------- function vtkFramebuffer(publicAPI, model) { // Set our className model.classHierarchy.push('vtkFramebuffer'); publicAPI.getBothMode = function () { return model.context.FRAMEBUFFER; }; // publicAPI.getDrawMode = () => model.context.DRAW_FRAMEBUFFER; // publicAPI.getReadMode = () => model.context.READ_FRAMEBUFFER; publicAPI.saveCurrentBindingsAndBuffers = function (modeIn) { var mode = typeof modeIn !== 'undefined' ? modeIn : publicAPI.getBothMode(); publicAPI.saveCurrentBindings(mode); publicAPI.saveCurrentBuffers(mode); }; publicAPI.saveCurrentBindings = function (modeIn) { if (!model.context) { vtkErrorMacro('you must set the OpenGLRenderWindow before calling saveCurrentBindings'); return; } var gl = model.context; model.previousDrawBinding = gl.getParameter(model.context.FRAMEBUFFER_BINDING); model.previousActiveFramebuffer = model._openGLRenderWindow.getActiveFramebuffer(); }; publicAPI.saveCurrentBuffers = function (modeIn) {// noop on webgl 1 }; publicAPI.restorePreviousBindingsAndBuffers = function (modeIn) { var mode = typeof modeIn !== 'undefined' ? modeIn : publicAPI.getBothMode(); publicAPI.restorePreviousBindings(mode); publicAPI.restorePreviousBuffers(mode); }; publicAPI.restorePreviousBindings = function (modeIn) { if (!model.context) { vtkErrorMacro('you must set the OpenGLRenderWindow before calling restorePreviousBindings'); return; } var gl = model.context; gl.bindFramebuffer(gl.FRAMEBUFFER, model.previousDrawBinding); model._openGLRenderWindow.setActiveFramebuffer(model.previousActiveFramebuffer); }; publicAPI.restorePreviousBuffers = function (modeIn) {// currently a noop on webgl1 }; publicAPI.bind = function () { var modeArg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; var mode = modeArg; if (mode === null) { mode = model.context.FRAMEBUFFER; } model.context.bindFramebuffer(mode, model.glFramebuffer); for (var i = 0; i < model.colorBuffers.length; i++) { model.colorBuffers[i].bind(); } model._openGLRenderWindow.setActiveFramebuffer(publicAPI); }; publicAPI.create = function (width, height) { if (!model.context) { vtkErrorMacro('you must set the OpenGLRenderWindow before calling create'); return; } model.glFramebuffer = model.context.createFramebuffer(); model.glFramebuffer.width = width; model.glFramebuffer.height = height; }; publicAPI.setColorBuffer = function (texture) { var attachment = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var gl = model.context; if (!gl) { vtkErrorMacro('you must set the OpenGLRenderWindow before calling setColorBuffer'); return; } var glAttachment = gl.COLOR_ATTACHMENT0; if (attachment > 0) { if (model._openGLRenderWindow.getWebgl2()) { glAttachment += attachment; } else { vtkErrorMacro('Using multiple framebuffer attachments requires WebGL 2'); return; } } model.colorBuffers[attachment] = texture; gl.framebufferTexture2D(gl.FRAMEBUFFER, glAttachment, gl.TEXTURE_2D, texture.getHandle(), 0); }; publicAPI.removeColorBuffer = function () { var attachment = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; var gl = model.context; if (!gl) { vtkErrorMacro('you must set the OpenGLRenderWindow before calling removeColorBuffer'); return; } var glAttachment = gl.COLOR_ATTACHMENT0; if (attachment > 0) { if (model._openGLRenderWindow.getWebgl2()) { glAttachment += attachment; } else { vtkErrorMacro('Using multiple framebuffer attachments requires WebGL 2'); return; } } gl.framebufferTexture2D(gl.FRAMEBUFFER, glAttachment, gl.TEXTURE_2D, null, 0); model.colorBuffers = model.colorBuffers.splice(attachment, 1); }; publicAPI.setDepthBuffer = function (texture) { if (!model.context) { vtkErrorMacro('you must set the OpenGLRenderWindow before calling setDepthBuffer'); return; } if (model._openGLRenderWindow.getWebgl2()) { var gl = model.context; gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, texture.getHandle(), 0); } else { vtkErrorMacro('Attaching depth buffer textures to fbo requires WebGL 2'); } }; publicAPI.removeDepthBuffer = function () { if (!model.context) { vtkErrorMacro('you must set the OpenGLRenderWindow before calling removeDepthBuffer'); return; } if (model._openGLRenderWindow.getWebgl2()) { var gl = model.context; gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, null, 0); } else { vtkErrorMacro('Attaching depth buffer textures to framebuffers requires WebGL 2'); } }; publicAPI.getGLFramebuffer = function () { return model.glFramebuffer; }; publicAPI.setOpenGLRenderWindow = function (rw) { if (model._openGLRenderWindow === rw) { return; } publicAPI.releaseGraphicsResources(); model._openGLRenderWindow = rw; model.context = null; if (rw) { model.context = model._openGLRenderWindow.getContext(); } }; publicAPI.releaseGraphicsResources = function () { if (model.glFramebuffer) { model.context.deleteFramebuffer(model.glFramebuffer); } }; publicAPI.getSize = function () { var size = [0, 0]; if (model.glFramebuffer !== null) { size[0] = model.glFramebuffer.width; size[1] = model.glFramebuffer.height; } return size; }; publicAPI.populateFramebuffer = function () { if (!model.context) { vtkErrorMacro('you must set the OpenGLRenderWindow before calling populateFrameBuffer'); return; } publicAPI.bind(); var gl = model.context; var texture = vtkOpenGLTexture.newInstance(); texture.setOpenGLRenderWindow(model._openGLRenderWindow); texture.setMinificationFilter(Filter.LINEAR); texture.setMagnificationFilter(Filter.LINEAR); texture.create2DFromRaw(model.glFramebuffer.width, model.glFramebuffer.height, 4, VtkDataTypes.UNSIGNED_CHAR, null); publicAPI.setColorBuffer(texture); // for now do not count on having a depth buffer texture // as they are not standard webgl 1 model.depthTexture = gl.createRenderbuffer(); gl.bindRenderbuffer(gl.RENDERBUFFER, model.depthTexture); gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, model.glFramebuffer.width, model.glFramebuffer.height); gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, model.depthTexture); }; // For backwards compatibility. Use getColorBuffers()[0] going forward. publicAPI.getColorTexture = function () { return model.colorBuffers[0]; }; } // ---------------------------------------------------------------------------- // Object factory // ---------------------------------------------------------------------------- var DEFAULT_VALUES = { // _openGLRenderWindow: null, glFramebuffer: null, colorBuffers: null, depthTexture: null, previousDrawBinding: 0, previousReadBinding: 0, previousDrawBuffer: 0, previousReadBuffer: 0, previousActiveFramebuffer: null }; // ---------------------------------------------------------------------------- function extend(publicAPI, model) { var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; Object.assign(model, DEFAULT_VALUES, initialValues); // Build VTK API obj(publicAPI, model); if (model.colorBuffers) { vtkErrorMacro('you cannot initialize colorBuffers through the constructor. You should call setColorBuffer() instead.'); } model.colorBuffers = []; getArray(publicAPI, model, ['colorBuffers']); // For more macro methods, see "Sources/macros.js" // Object specific methods vtkFramebuffer(publicAPI, model); } // ---------------------------------------------------------------------------- var newInstance = newInstance$1(extend, 'vtkFramebuffer'); // ---------------------------------------------------------------------------- var vtkOpenGLFramebuffer = { newInstance: newInstance, extend: extend }; export { vtkOpenGLFramebuffer as default, extend, newInstance };