@kitware/vtk.js
Version:
Visualization Toolkit for the Web
267 lines (209 loc) • 8.79 kB
JavaScript
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 };