Skip to content

Commit

Permalink
fix(genericrenderwindow): support WebGPU backend
Browse files Browse the repository at this point in the history
Allow passing defaultViewAPI in vtkFullscreenRenderWindow
newInstance.

vtkFullscreenRenderWindow, vtkGenericRenderWindow and vtkViewProxy are
now exposing `getApiSpecificRenderWindow()` instead of
`getOpenGLRenderWindow()`.
`OpenGL/vtkBufferObject` and `OpenGL/vtkHardwareSelector` still expose
`getOpenGLRenderWindow()`.
  • Loading branch information
finetjul authored and floryst committed Oct 26, 2023
1 parent 5b9fc3a commit fae07e4
Show file tree
Hide file tree
Showing 15 changed files with 42 additions and 27 deletions.
3 changes: 3 additions & 0 deletions BREAKING_CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## From 28.x to 29

- **getOpenGLRenderWindow**: `getOpenGLRenderWindow` has been renamed to `getApiSpecificRenderWindow` in `vtkFullScreenRenderWindow`, `vtkGenericRenderWindow` and `vtkViewProxy` to support WebGL and WebGPU backend.
## From 27.x to 28

- **vtkManipulator.handleEvent**: Change all `handleEvent` signatures of manipulators. Used to be `handleEvent(callData, glRenderWindow): vec3`, it is now `handleEvent(callData, glRenderWindow): { worldCoords: Nullable<vec3>, worldDirection?: mat3 }`.
Expand Down
4 changes: 2 additions & 2 deletions Examples/Applications/SkyboxViewer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,8 @@ function createVisualization(container, mapReader) {
}

if (grid) {
console.log(fullScreenRenderer.getOpenGLRenderWindow().getSize());
createGrid(...fullScreenRenderer.getOpenGLRenderWindow().getSize());
console.log(fullScreenRenderer.getApiSpecificRenderWindow().getSize());
createGrid(...fullScreenRenderer.getApiSpecificRenderWindow().getSize());
}
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/IO/Core/ImageStream/example/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ smartConnect.onConnectionReady((connection) => {
// Image
imageStream.connect(session);
const viewStream = imageStream.createViewStream('-1');
fullScreenRenderer.getOpenGLRenderWindow().setViewStream(viewStream);
fullScreenRenderer.getApiSpecificRenderWindow().setViewStream(viewStream);
// Configure image quality
viewStream.setInteractiveQuality(75);
Expand Down
4 changes: 2 additions & 2 deletions Sources/Proxy/Core/ProxyManager/example/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ view2DContainer.className = 'viewContainer';
const view3DProxy = proxyManager.createProxy('Views', 'View3D');
view3DProxy.setContainer(view3DContainer);
view3DProxy
.getOpenGLRenderWindow()
.getApiSpecificRenderWindow()
.setSize([view3DContainer.clientWidth, view3DContainer.clientHeight]);

// ----------------------------------------------------------------------------
Expand All @@ -79,7 +79,7 @@ view3DProxy
const view2DProxy = proxyManager.createProxy('Views', 'View2D', { axis: 2 });
view2DProxy.setContainer(view2DContainer);
view2DProxy
.getOpenGLRenderWindow()
.getApiSpecificRenderWindow()
.setSize([view2DContainer.clientWidth, view2DContainer.clientHeight]);

// ----------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion Sources/Proxy/Core/View2DProxy/example/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const view2DProxy = proxyManager.createProxy('Views', 'View2D', {
});
view2DProxy.setContainer(mainContainer);
view2DProxy
.getOpenGLRenderWindow()
.getApiSpecificRenderWindow()
.setSize(mainContainer.clientWidth, mainContainer.clientHeight);

fitCameraButton.addEventListener('click', () => {
Expand Down
3 changes: 2 additions & 1 deletion Sources/Proxy/Core/ViewProxy/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { vtkSubscription, vtkObject } from '../../../interfaces';
import vtkRenderer from '../../../Rendering/Core/Renderer';
import vtkRenderWindow from '../../../Rendering/Core/RenderWindow';
import vtkOpenGLRenderWindow from '../../../Rendering/OpenGL/RenderWindow';
import vtkWebGPURenderWindow from '../../../Rendering/WebGPU/RenderWindow';
import { VtkProxy } from '../../../macros';

export interface vtkViewProxy extends VtkProxy {
Expand Down Expand Up @@ -66,7 +67,7 @@ export interface vtkViewProxy extends VtkProxy {
getInteractor(): vtkRenderWindowInteractor;
getInteractorStyle2D(): vtkInteractorStyle;
getInteractorStyle3D(): vtkInteractorStyle;
getOpenGLRenderWindow(): vtkOpenGLRenderWindow;
getApiSpecificRenderWindow(): vtkOpenGLRenderWindow|vtkWebGPURenderWindow;
getOrientationAxesType(): string;
getPresetToOrientationAxes(): any;
getRenderer(): vtkRenderer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const view2DProxy = proxyManager.createProxy('Views', 'View2D', {
});
view2DProxy.setContainer(mainContainer);
view2DProxy
.getOpenGLRenderWindow()
.getApiSpecificRenderWindow()
.setSize(mainContainer.clientWidth, mainContainer.clientHeight);

fitCameraButton.addEventListener('click', () => {
Expand Down
1 change: 1 addition & 0 deletions Sources/Rendering/Core/RenderWindow/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ export interface vtkRenderWindow extends vtkObject {
* Switch the rendering backend between WebGL and WebGPU.
* By default, the WebGL backend is used. To switch, to WebGPU call
* `renderWindow.setDefaultViewAPI('WebGPU')` before calling `render`.
* Must be called before `newAPISpecificView()` is called.
* @param defaultViewAPI (default: 'WebGL')
*/
setDefaultViewAPI(defaultViewAPI: DEFAULT_VIEW_API): boolean;
Expand Down
5 changes: 4 additions & 1 deletion Sources/Rendering/Misc/FullScreenRenderWindow/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface IFullScreenRenderWindowInitialValues {
containerStyle?: object;
controlPanelStyle?: object;
controllerVisibility?: boolean;
defaultViewAPI?: boolean;
listenWindowResize?: boolean;
resizeCallback?: any;
}
Expand All @@ -42,7 +43,9 @@ export interface vtkFullScreenRenderWindow extends vtkObject {
delete(): void;

/**
*
* Returns vtkWebGPURenderWindow if ?viewAPI='WebGPU' is in URL, or if
* vtkFullScreenRenderWindow has been created with "defaultViewAPI: 'WebGPU",
* otherwise vtkOpenGLRenderWindow is returned.
*/
getApiSpecificRenderWindow(): any; // vtkOpenGLRenderWindow || vtkWebGPURenderWindow

Expand Down
3 changes: 2 additions & 1 deletion Sources/Rendering/Misc/FullScreenRenderWindow/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ function vtkFullScreenRenderWindow(publicAPI, model) {

// apiSpecificRenderWindow
model.apiSpecificRenderWindow = model.renderWindow.newAPISpecificView(
userParams.viewAPI
userParams.viewAPI ?? model.defaultViewAPI
);
model.apiSpecificRenderWindow.setContainer(model.container);
model.renderWindow.addView(model.apiSpecificRenderWindow);
Expand Down Expand Up @@ -192,6 +192,7 @@ const DEFAULT_VALUES = {
background: [0.32, 0.34, 0.43],
containerStyle: null,
controlPanelStyle: null,
// defaultViewAPI: undefined,
listenWindowResize: true,
resizeCallback: null,
controllerVisibility: true,
Expand Down
5 changes: 3 additions & 2 deletions Sources/Rendering/Misc/GenericRenderWindow/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import vtkRenderer from "../../Core/Renderer";
import vtkRenderWindow from "../../Core/RenderWindow";
import vtkRenderWindowInteractor from "../../Core/RenderWindowInteractor";
import vtkOpenGLRenderWindow from "../../OpenGL/RenderWindow";
import vtkWebGPURenderWindow from "../../WebGPU/RenderWindow";


/**
Expand Down Expand Up @@ -33,9 +34,9 @@ export interface vtkGenericRenderWindow extends vtkObject {
getInteractor(): vtkRenderWindowInteractor;

/**
*
* Get the render back-end specific render window.
*/
getOpenGLRenderWindow(): vtkOpenGLRenderWindow;
getApiSpecificRenderWindow(): vtkOpenGLRenderWindow|vtkWebGPURenderWindow;

/**
*
Expand Down
23 changes: 14 additions & 9 deletions Sources/Rendering/Misc/GenericRenderWindow/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import macro from 'vtk.js/Sources/macros';
import vtkOpenGLRenderWindow from 'vtk.js/Sources/Rendering/OpenGL/RenderWindow';
import vtkRenderer from 'vtk.js/Sources/Rendering/Core/Renderer';
import vtkRenderWindow from 'vtk.js/Sources/Rendering/Core/RenderWindow';
import vtkRenderWindowInteractor from 'vtk.js/Sources/Rendering/Core/RenderWindowInteractor';
import vtkInteractorStyleTrackballCamera from 'vtk.js/Sources/Interaction/Style/InteractorStyleTrackballCamera';
import vtkURLExtract from 'vtk.js/Sources/Common/Core/URLExtract';

// Load basic classes for vtk() factory
import 'vtk.js/Sources/Common/Core/Points';
Expand All @@ -12,6 +12,9 @@ import 'vtk.js/Sources/Common/DataModel/PolyData';
import 'vtk.js/Sources/Rendering/Core/Actor';
import 'vtk.js/Sources/Rendering/Core/Mapper';

// Process arguments from URL
const userParams = vtkURLExtract.extractURLParameters();

function vtkGenericRenderWindow(publicAPI, model) {
// Capture resize trigger method to remove from publicAPI
const invokeResize = publicAPI.invokeResize;
Expand All @@ -23,15 +26,17 @@ function vtkGenericRenderWindow(publicAPI, model) {
model.renderWindow.addRenderer(model.renderer);

// OpenGLRenderWindow
model._openGLRenderWindow = vtkOpenGLRenderWindow.newInstance();
model.renderWindow.addView(model._openGLRenderWindow);
model._apiSpecificRenderWindow = model.renderWindow.newAPISpecificView(
userParams.viewAPI ?? model.defaultViewAPI
);
model.renderWindow.addView(model._apiSpecificRenderWindow);

// Interactor
model.interactor = vtkRenderWindowInteractor.newInstance();
model.interactor.setInteractorStyle(
vtkInteractorStyleTrackballCamera.newInstance()
);
model.interactor.setView(model._openGLRenderWindow);
model.interactor.setView(model._apiSpecificRenderWindow);
model.interactor.initialize();

// Expose background
Expand All @@ -45,7 +50,7 @@ function vtkGenericRenderWindow(publicAPI, model) {
if (model.container) {
const dims = model.container.getBoundingClientRect();
const devicePixelRatio = window.devicePixelRatio || 1;
model._openGLRenderWindow.setSize(
model._apiSpecificRenderWindow.setSize(
Math.floor(dims.width * devicePixelRatio),
Math.floor(dims.height * devicePixelRatio)
);
Expand All @@ -62,7 +67,7 @@ function vtkGenericRenderWindow(publicAPI, model) {

// Switch container
model.container = el;
model._openGLRenderWindow.setContainer(model.container);
model._apiSpecificRenderWindow.setContainer(model.container);

// Bind to new container
if (model.container) {
Expand All @@ -73,7 +78,7 @@ function vtkGenericRenderWindow(publicAPI, model) {
// Properly release GL context
publicAPI.delete = macro.chain(
publicAPI.setContainer,
model._openGLRenderWindow.delete,
model._apiSpecificRenderWindow.delete,
publicAPI.delete
);

Expand Down Expand Up @@ -104,11 +109,11 @@ export function extend(publicAPI, model, initialValues = {}) {
macro.get(publicAPI, model, [
'renderWindow',
'renderer',
'_openGLRenderWindow',
'_apiSpecificRenderWindow',
'interactor',
'container',
]);
macro.moveToProtected(publicAPI, model, ['openGLRenderWindow']);
macro.moveToProtected(publicAPI, model, ['_apiSpecificRenderWindow']);
macro.event(publicAPI, model, 'resize');

// Object specific methods
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ test('Test vtkGenericRenderWindow create/delete', (t) => {
grw.setContainer(rwContainer);
grw.getRenderer().addActor(actor);

images.push(grw.getOpenGLRenderWindow().captureNextImage());
images.push(grw.getApiSpecificRenderWindow().captureNextImage());
grw.getRenderWindow().render();

grw.delete();
Expand Down
8 changes: 4 additions & 4 deletions Sources/Widgets/Core/WidgetManager/test/testWidgetManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ test.onlyIfWebGL('Test getPixelWorldHeightAtCoord', (t) => {
resolve = res;
});
grw
.getOpenGLRenderWindow()
.getApiSpecificRenderWindow()
.captureNextImage()
.then((image) => {
testUtils.compareImages(
Expand Down Expand Up @@ -102,7 +102,7 @@ test.onlyIfWebGL('Test getPixelWorldHeightAtCoord', (t) => {
resolve = res;
});
grw
.getOpenGLRenderWindow()
.getApiSpecificRenderWindow()
.captureNextImage()
.then((image) => {
testUtils.compareImages(
Expand Down Expand Up @@ -132,7 +132,7 @@ test.onlyIfWebGL('Test getPixelWorldHeightAtCoord', (t) => {
resolve = res;
});
grw
.getOpenGLRenderWindow()
.getApiSpecificRenderWindow()
.captureNextImage()
.then((image) => {
testUtils.compareImages(
Expand All @@ -159,7 +159,7 @@ test.onlyIfWebGL('Test getPixelWorldHeightAtCoord', (t) => {
resolve = res;
});
grw
.getOpenGLRenderWindow()
.getApiSpecificRenderWindow()
.captureNextImage()
.then((image) => {
testUtils.compareImages(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ for (let i = 0; i < 4; i++) {
const obj = {
renderWindow: grw.getRenderWindow(),
renderer: grw.getRenderer(),
GLWindow: grw.getOpenGLRenderWindow(),
GLWindow: grw.getApiSpecificRenderWindow(),
interactor: grw.getInteractor(),
widgetManager: vtkWidgetManager.newInstance(),
orientationWidget: null,
Expand Down

0 comments on commit fae07e4

Please sign in to comment.