Skip to content

Commit

Permalink
feat(rw): WIP Share GPU ressources accross render windows
Browse files Browse the repository at this point in the history
  • Loading branch information
bruyeret committed Apr 3, 2024
1 parent f3d3910 commit f500ef1
Show file tree
Hide file tree
Showing 5 changed files with 372 additions and 167 deletions.
131 changes: 36 additions & 95 deletions Examples/Rendering/ManyRenderers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,45 +95,6 @@ rootContainer.style.top = 0;
rootContainer.style.pointerEvents = 'none';
document.body.appendChild(rootContainer);

renderWindowView.setContainer(rootContainer);

const interactor = vtkRenderWindowInteractor.newInstance();
interactor.setView(renderWindowView);
interactor.initialize();
interactor.setInteractorStyle(vtkInteractorStyleTrackballCamera.newInstance());

function updateViewPort(element, renderer) {
const { innerHeight, innerWidth } = window;
const { x, y, width, height } = element.getBoundingClientRect();
const viewport = [
x / innerWidth,
1 - (y + height) / innerHeight,
(x + width) / innerWidth,
1 - y / innerHeight,
];
renderer.setViewport(...viewport);
}

function recomputeViewports() {
const rendererElems = document.querySelectorAll('.renderer');
for (let i = 0; i < rendererElems.length; i++) {
const elem = rendererElems[i];
const { id } = elem;
const renderer = RENDERERS[id];
updateViewPort(elem, renderer);
}
renderWindow.render();
}

function resize() {
rootContainer.style.width = `${window.innerWidth}px`;
renderWindowView.setSize(window.innerWidth, window.innerHeight);
recomputeViewports();
}

new ResizeObserver(resize).observe(document.body);
document.addEventListener('scroll', recomputeViewports);

// ----------------------------------------------------------------------------
// Renderers
// ----------------------------------------------------------------------------
Expand All @@ -144,46 +105,21 @@ let bgIndex = 0;
let rendererId = 1;

function applyStyle(element) {
const width = Math.floor(100 + Math.random() * 200);
const height = Math.floor(100 + Math.random() * 200);
element.classList.add('renderer');
element.style.width = '200px';
element.style.height = '200px';
element.style.width = `${width}px`;
element.style.height = `${height}px`;
element.style.margin = '20px';
element.style.border = 'solid 1px #333';
element.style.display = 'inline-block';
element.style.display = 'inline-flex';
element.style['align-items'] = 'center';
element.style['flex-flow'] = 'column';
element.style.boxSizing = 'border';
element.style.textAlign = 'center';
element.style.color = 'white';
return element;
}

let captureCurrentRenderer = false;

function setCaptureCurrentRenderer(yn) {
captureCurrentRenderer = yn;
if (yn && interactor.getCurrentRenderer()) {
// fix the current renderer to, well, the current renderer
interactor.setCurrentRenderer(interactor.getCurrentRenderer());
} else {
// remove the fixed current renderer
interactor.setCurrentRenderer(null);
}
}

function bindInteractor(renderer, el) {
// only change the interactor's container if needed
if (interactor.getContainer() !== el) {
if (interactor.getContainer()) {
interactor.unbindEvents();
}
if (captureCurrentRenderer) {
interactor.setCurrentRenderer(renderer);
}
if (el) {
interactor.bindEvents(el);
}
}
}

function addRenderer() {
const mesh = meshes[meshIndex];
const prop = properties[propertyIndex];
Expand All @@ -196,6 +132,11 @@ function addRenderer() {
container.id = rendererId++;
document.body.appendChild(container);

const nameDiv = document.createElement('div');
nameDiv.innerHTML = `${mesh.name} ${prop.name}`;
nameDiv.style.position = 'absolute';
container.appendChild(nameDiv);

const actor = vtkActor.newInstance();
actor.setMapper(mesh.mapper);
actor.getProperty().set(prop.properties);
Expand All @@ -204,16 +145,32 @@ function addRenderer() {
actor.getProperty().setSpecularPower(30);
actor.getProperty().setSpecularColor(1.0, 1.0, 1.0);
const renderer = vtkRenderer.newInstance({ background });
container.innerHTML = `${mesh.name} ${prop.name}`;

container.addEventListener('pointerenter', () =>
bindInteractor(renderer, container)
renderer.addActor(actor);
// Create a new renderwindow
const childRenderWindow = vtkRenderWindow.newInstance();
renderWindow.addRenderWindow(childRenderWindow); // add the child RW to its parent
renderWindowView.addMissingNode(childRenderWindow); // create the OpenGLRenderWindow for the child
const childrenViews = renderWindowView.getChildren();
const childRenderWindowView = childrenViews[childrenViews.length - 1]; // get the child's OpenGLRenderWindow

childRenderWindow.addRenderer(renderer);
childRenderWindowView.setContainer(container);
const containerBounds = container.getBoundingClientRect();
const pixRatio = window.devicePixelRatio;
childRenderWindowView.setSize(
containerBounds.width * pixRatio,
containerBounds.height * pixRatio
);

const interactor = vtkRenderWindowInteractor.newInstance();
interactor.setView(childRenderWindowView);
interactor.initialize();
interactor.bindEvents(childRenderWindowView.getCanvas());
interactor.setInteractorStyle(
vtkInteractorStyleTrackballCamera.newInstance()
);
container.addEventListener('pointerleave', () => bindInteractor(null, null));

renderer.addActor(actor);
renderWindow.addRenderer(renderer);
updateViewPort(container, renderer);
renderer.resetCamera();

// Keep track of renderer
Expand All @@ -224,25 +181,9 @@ function addRenderer() {
// Fill up page
// ----------------------------------------------------------------------------

const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.name = 'singleRendererCapture';
const label = document.createElement('label');
label.for = checkbox.name;
label.innerText = 'Enable single renderer capture';

checkbox.addEventListener('input', (ev) => {
setCaptureCurrentRenderer(ev.target.checked);
});

document.body.appendChild(checkbox);
document.body.appendChild(label);
document.body.appendChild(document.createElement('br'));

for (let i = 0; i < 64; i++) {
for (let i = 0; i < 4; i++) {
addRenderer();
}
resize();

function updateCamera(renderer) {
const camera = renderer.getActiveCamera();
Expand Down
Loading

0 comments on commit f500ef1

Please sign in to comment.