@kitware/vtk.js
Version:
Visualization Toolkit for the Web
225 lines (213 loc) • 8.39 kB
JavaScript
import { n as newInstance$1, o as obj, r as vtkErrorMacro, k as getArray } from '../../macros2.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 = () => model.context.FRAMEBUFFER;
// publicAPI.getDrawMode = () => model.context.DRAW_FRAMEBUFFER;
// publicAPI.getReadMode = () => model.context.READ_FRAMEBUFFER;
publicAPI.saveCurrentBindingsAndBuffers = modeIn => {
const mode = typeof modeIn !== 'undefined' ? modeIn : publicAPI.getBothMode();
publicAPI.saveCurrentBindings(mode);
publicAPI.saveCurrentBuffers(mode);
};
publicAPI.saveCurrentBindings = modeIn => {
if (!model.context) {
vtkErrorMacro('you must set the OpenGLRenderWindow before calling saveCurrentBindings');
return;
}
const gl = model.context;
model.previousDrawBinding = gl.getParameter(model.context.FRAMEBUFFER_BINDING);
model.previousActiveFramebuffer = model._openGLRenderWindow.getActiveFramebuffer();
};
publicAPI.saveCurrentBuffers = modeIn => {
// noop on webgl 1
};
publicAPI.restorePreviousBindingsAndBuffers = modeIn => {
const mode = typeof modeIn !== 'undefined' ? modeIn : publicAPI.getBothMode();
publicAPI.restorePreviousBindings(mode);
publicAPI.restorePreviousBuffers(mode);
};
publicAPI.restorePreviousBindings = modeIn => {
if (!model.context) {
vtkErrorMacro('you must set the OpenGLRenderWindow before calling restorePreviousBindings');
return;
}
const gl = model.context;
gl.bindFramebuffer(gl.FRAMEBUFFER, model.previousDrawBinding);
model._openGLRenderWindow.setActiveFramebuffer(model.previousActiveFramebuffer);
};
publicAPI.restorePreviousBuffers = modeIn => {
// currently a noop on webgl1
};
publicAPI.bind = (modeArg = null) => {
let mode = modeArg;
if (mode === null) {
mode = model.context.FRAMEBUFFER;
}
model.context.bindFramebuffer(mode, model.glFramebuffer);
for (let i = 0; i < model.colorBuffers.length; i++) {
model.colorBuffers[i].bind();
}
model._openGLRenderWindow.setActiveFramebuffer(publicAPI);
};
publicAPI.create = (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 = (texture, attachment = 0) => {
const gl = model.context;
if (!gl) {
vtkErrorMacro('you must set the OpenGLRenderWindow before calling setColorBuffer');
return;
}
let 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 = (attachment = 0) => {
const gl = model.context;
if (!gl) {
vtkErrorMacro('you must set the OpenGLRenderWindow before calling removeColorBuffer');
return;
}
let 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 = texture => {
if (!model.context) {
vtkErrorMacro('you must set the OpenGLRenderWindow before calling setDepthBuffer');
return;
}
if (model._openGLRenderWindow.getWebgl2()) {
const 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 = () => {
if (!model.context) {
vtkErrorMacro('you must set the OpenGLRenderWindow before calling removeDepthBuffer');
return;
}
if (model._openGLRenderWindow.getWebgl2()) {
const 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 = () => model.glFramebuffer;
publicAPI.setOpenGLRenderWindow = rw => {
if (model._openGLRenderWindow === rw) {
return;
}
publicAPI.releaseGraphicsResources();
model._openGLRenderWindow = rw;
model.context = null;
if (rw) {
model.context = model._openGLRenderWindow.getContext();
}
};
publicAPI.releaseGraphicsResources = () => {
if (model.glFramebuffer) {
model.context.deleteFramebuffer(model.glFramebuffer);
}
};
publicAPI.getSize = () => {
if (model.glFramebuffer == null) return null;
return [model.glFramebuffer.width, model.glFramebuffer.height];
};
publicAPI.populateFramebuffer = () => {
if (!model.context) {
vtkErrorMacro('you must set the OpenGLRenderWindow before calling populateFrameBuffer');
return;
}
publicAPI.bind();
const gl = model.context;
const texture = vtkOpenGLTexture.newInstance();
texture.setOpenGLRenderWindow(model._openGLRenderWindow);
texture.setMinificationFilter(Filter.LINEAR);
texture.setMagnificationFilter(Filter.LINEAR);
texture.create2DFromRaw({
width: model.glFramebuffer.width,
height: model.glFramebuffer.height,
numComps: 4,
dataType: VtkDataTypes.UNSIGNED_CHAR,
data: 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 = () => model.colorBuffers[0];
}
// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------
const DEFAULT_VALUES = {
// _openGLRenderWindow: null,
glFramebuffer: null,
colorBuffers: null,
depthTexture: null,
previousDrawBinding: 0,
previousReadBinding: 0,
previousDrawBuffer: 0,
previousReadBuffer: 0,
previousActiveFramebuffer: null
};
// ----------------------------------------------------------------------------
function extend(publicAPI, model, initialValues = {}) {
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);
}
// ----------------------------------------------------------------------------
const newInstance = newInstance$1(extend, 'vtkFramebuffer');
// ----------------------------------------------------------------------------
var vtkOpenGLFramebuffer = {
newInstance,
extend
};
export { vtkOpenGLFramebuffer as default, extend, newInstance };