@kitware/vtk.js 34.0.0 → 34.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -246,7 +246,14 @@ export interface vtkOpenGLTexture extends vtkViewNode {
246
246
  * @param image The image to use for the texture.
247
247
  * @returns {boolean} True if the texture was successfully created, false otherwise.
248
248
  */
249
- create2DFromImage(image: any): boolean;
249
+ create2DFromImage(image: HTMLImageElement): boolean;
250
+
251
+ /**
252
+ * Creates a 2D texture from an ImageBitmap.
253
+ * @param imageBitmap The ImageBitmap to use for the texture.
254
+ * @returns {boolean} True if the texture was successfully created, false otherwise.
255
+ */
256
+ create2DFromImageBitmap(imageBitmap: ImageBitmap): boolean;
250
257
 
251
258
  /**
252
259
  * Creates a 2D filterable texture from raw data, with a preference for size over accuracy if necessary.
@@ -75,6 +75,19 @@ function vtkOpenGLTexture(publicAPI, model) {
75
75
  }
76
76
  // create the texture if it is not done already
77
77
  if (!model.handle || model.renderable.getMTime() > model.textureBuildTime.getMTime()) {
78
+ if (model.renderable.getImageBitmap() !== null) {
79
+ if (model.renderable.getInterpolate()) {
80
+ model.generateMipmap = true;
81
+ publicAPI.setMinificationFilter(Filter.LINEAR_MIPMAP_LINEAR);
82
+ }
83
+ // Have an Image which may not be complete
84
+ if (model.renderable.getImageBitmap() && model.renderable.getImageLoaded()) {
85
+ publicAPI.create2DFromImageBitmap(model.renderable.getImageBitmap());
86
+ publicAPI.activate();
87
+ publicAPI.sendParameters();
88
+ model.textureBuildTime.modified();
89
+ }
90
+ }
78
91
  // if we have an Image
79
92
  if (model.renderable.getImage() !== null) {
80
93
  if (model.renderable.getInterpolate()) {
@@ -1013,7 +1026,7 @@ function vtkOpenGLTexture(publicAPI, model) {
1013
1026
 
1014
1027
  //----------------------------------------------------------------------------
1015
1028
  publicAPI.create2DFromImage = image => {
1016
- // Now determine the texture parameters using the arguments.
1029
+ // Determine the texture parameters using the arguments.
1017
1030
  publicAPI.getOpenGLDataType(VtkDataTypes.UNSIGNED_CHAR);
1018
1031
  publicAPI.getInternalFormat(VtkDataTypes.UNSIGNED_CHAR, 4);
1019
1032
  publicAPI.getFormat(VtkDataTypes.UNSIGNED_CHAR, 4);
@@ -1028,30 +1041,79 @@ function vtkOpenGLTexture(publicAPI, model) {
1028
1041
  model._openGLRenderWindow.activateTexture(publicAPI);
1029
1042
  publicAPI.createTexture();
1030
1043
  publicAPI.bind();
1044
+ const needNearestPowerOfTwo = !model._openGLRenderWindow.getWebgl2() && (!isPowerOfTwo(image.width) || !isPowerOfTwo(image.height));
1045
+ let textureSource = image;
1046
+ let targetWidth = image.width;
1047
+ let targetHeight = image.height;
1048
+ let flipY = true;
1049
+
1050
+ // For WebGL1, we need to scale the image to the nearest power of two
1051
+ // dimensions if the image is not already a power of two. For WebGL2, we can
1052
+ // use the image as is. Note: Chrome has a perf issue where the path
1053
+ // HTMLImageElement -> Canvas -> texSubImage2D is faster than
1054
+ // HTMLImageElement -> texSubImage2D directly. See
1055
+ // https://issues.chromium.org/issues/41311312#comment7
1056
+ // Tested on Chrome 137.0.7151.104 Windows 11
1057
+ const isChrome = window.chrome;
1058
+ if (needNearestPowerOfTwo || isChrome) {
1059
+ const canvas = new OffscreenCanvas(nearestPowerOfTwo(image.width), nearestPowerOfTwo(image.height));
1060
+ targetWidth = canvas.width;
1061
+ targetHeight = canvas.height;
1062
+ const ctx = canvas.getContext('2d');
1063
+ ctx.translate(0, canvas.height);
1064
+ ctx.scale(1, -1);
1065
+ ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height);
1066
+ textureSource = canvas;
1067
+ flipY = false; // we are flipping the image manually using translate/scale
1068
+ }
1069
+
1070
+ model.width = targetWidth;
1071
+ model.height = targetHeight;
1031
1072
 
1032
1073
  // Source texture data from the PBO.
1033
- // model.context.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
1074
+ model.context.pixelStorei(model.context.UNPACK_FLIP_Y_WEBGL, flipY);
1034
1075
  model.context.pixelStorei(model.context.UNPACK_ALIGNMENT, 1);
1076
+ if (useTexStorage(VtkDataTypes.UNSIGNED_CHAR)) {
1077
+ model.context.texStorage2D(model.target, 1, model.internalFormat, model.width, model.height);
1078
+ model.context.texSubImage2D(model.target, 0, 0, 0, model.width, model.height, model.format, model.openGLDataType, textureSource);
1079
+ } else {
1080
+ model.context.texImage2D(model.target, 0, model.internalFormat, model.width, model.height, 0, model.format, model.openGLDataType, textureSource);
1081
+ }
1082
+ if (model.generateMipmap) {
1083
+ model.context.generateMipmap(model.target);
1084
+ }
1085
+ model.allocatedGPUMemoryInBytes = model.width * model.height * model.depth * model.components * model._openGLRenderWindow.getDefaultTextureByteSize(VtkDataTypes.UNSIGNED_CHAR, getNorm16Ext(), publicAPI.useHalfFloat());
1086
+ publicAPI.deactivate();
1087
+ return true;
1088
+ };
1035
1089
 
1036
- // Scale up the texture to the next highest power of two dimensions (if needed) and flip y.
1037
- const needNearestPowerOfTwo = !model._openGLRenderWindow.getWebgl2() && (!isPowerOfTwo(image.width) || !isPowerOfTwo(image.height));
1038
- const canvas = document.createElement('canvas');
1039
- canvas.width = needNearestPowerOfTwo ? nearestPowerOfTwo(image.width) : image.width;
1040
- canvas.height = needNearestPowerOfTwo ? nearestPowerOfTwo(image.height) : image.height;
1041
- model.width = canvas.width;
1042
- model.height = canvas.height;
1043
- const ctx = canvas.getContext('2d');
1044
- ctx.translate(0, canvas.height);
1045
- ctx.scale(1, -1);
1046
- ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height);
1047
- const safeImage = canvas;
1090
+ //----------------------------------------------------------------------------
1091
+ publicAPI.create2DFromImageBitmap = imageBitmap => {
1092
+ // Determine the texture parameters.
1093
+ publicAPI.getOpenGLDataType(VtkDataTypes.UNSIGNED_CHAR);
1094
+ publicAPI.getInternalFormat(VtkDataTypes.UNSIGNED_CHAR, 4);
1095
+ publicAPI.getFormat(VtkDataTypes.UNSIGNED_CHAR, 4);
1096
+ if (!model.internalFormat || !model.format || !model.openGLDataType) {
1097
+ vtkErrorMacro('Failed to determine texture parameters.');
1098
+ return false;
1099
+ }
1100
+ model.target = model.context.TEXTURE_2D;
1101
+ model.components = 4;
1102
+ model.depth = 1;
1103
+ model.numberOfDimensions = 2;
1104
+ model._openGLRenderWindow.activateTexture(publicAPI);
1105
+ publicAPI.createTexture();
1106
+ publicAPI.bind();
1107
+
1108
+ // Prepare texture unpack alignment
1109
+ model.context.pixelStorei(model.context.UNPACK_ALIGNMENT, 1);
1110
+ model.width = imageBitmap.width;
1111
+ model.height = imageBitmap.height;
1048
1112
  if (useTexStorage(VtkDataTypes.UNSIGNED_CHAR)) {
1049
1113
  model.context.texStorage2D(model.target, 1, model.internalFormat, model.width, model.height);
1050
- if (safeImage != null) {
1051
- model.context.texSubImage2D(model.target, 0, 0, 0, model.width, model.height, model.format, model.openGLDataType, safeImage);
1052
- }
1114
+ model.context.texSubImage2D(model.target, 0, 0, 0, model.width, model.height, model.format, model.openGLDataType, imageBitmap);
1053
1115
  } else {
1054
- model.context.texImage2D(model.target, 0, model.internalFormat, model.width, model.height, 0, model.format, model.openGLDataType, safeImage);
1116
+ model.context.texImage2D(model.target, 0, model.internalFormat, model.width, model.height, 0, model.format, model.openGLDataType, imageBitmap);
1055
1117
  }
1056
1118
  if (model.generateMipmap) {
1057
1119
  model.context.generateMipmap(model.target);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitware/vtk.js",
3
- "version": "34.0.0",
3
+ "version": "34.1.0",
4
4
  "description": "Visualization Toolkit for the Web",
5
5
  "keywords": [
6
6
  "3d",