Skip to content

Commit fc5b18b

Browse files
dakerfloryst
authored andcommitted
feat(Texture): add support for ImageBitmap texture in WebGL
1 parent b5a456f commit fc5b18b

File tree

2 files changed

+102
-1
lines changed

2 files changed

+102
-1
lines changed

Sources/Rendering/OpenGL/Texture/index.d.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,14 @@ export interface vtkOpenGLTexture extends vtkViewNode {
246246
* @param image The image to use for the texture.
247247
* @returns {boolean} True if the texture was successfully created, false otherwise.
248248
*/
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;
250257

251258
/**
252259
* Creates a 2D filterable texture from raw data, with a preference for size over accuracy if necessary.

Sources/Rendering/OpenGL/Texture/index.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,22 @@ function vtkOpenGLTexture(publicAPI, model) {
7171
!model.handle ||
7272
model.renderable.getMTime() > model.textureBuildTime.getMTime()
7373
) {
74+
if (model.renderable.getImageBitmap() !== null) {
75+
if (model.renderable.getInterpolate()) {
76+
model.generateMipmap = true;
77+
publicAPI.setMinificationFilter(Filter.LINEAR_MIPMAP_LINEAR);
78+
}
79+
// Have an Image which may not be complete
80+
if (
81+
model.renderable.getImageBitmap() &&
82+
model.renderable.getImageLoaded()
83+
) {
84+
publicAPI.create2DFromImageBitmap(model.renderable.getImageBitmap());
85+
publicAPI.activate();
86+
publicAPI.sendParameters();
87+
model.textureBuildTime.modified();
88+
}
89+
}
7490
// if we have an Image
7591
if (model.renderable.getImage() !== null) {
7692
if (model.renderable.getInterpolate()) {
@@ -1410,6 +1426,84 @@ function vtkOpenGLTexture(publicAPI, model) {
14101426
return true;
14111427
};
14121428

1429+
//----------------------------------------------------------------------------
1430+
publicAPI.create2DFromImageBitmap = (imageBitmap) => {
1431+
// Determine the texture parameters.
1432+
publicAPI.getOpenGLDataType(VtkDataTypes.UNSIGNED_CHAR);
1433+
publicAPI.getInternalFormat(VtkDataTypes.UNSIGNED_CHAR, 4);
1434+
publicAPI.getFormat(VtkDataTypes.UNSIGNED_CHAR, 4);
1435+
1436+
if (!model.internalFormat || !model.format || !model.openGLDataType) {
1437+
vtkErrorMacro('Failed to determine texture parameters.');
1438+
return false;
1439+
}
1440+
1441+
model.target = model.context.TEXTURE_2D;
1442+
model.components = 4;
1443+
model.depth = 1;
1444+
model.numberOfDimensions = 2;
1445+
model._openGLRenderWindow.activateTexture(publicAPI);
1446+
publicAPI.createTexture();
1447+
publicAPI.bind();
1448+
1449+
// Prepare texture unpack alignment
1450+
model.context.pixelStorei(model.context.UNPACK_ALIGNMENT, 1);
1451+
1452+
model.width = imageBitmap.width;
1453+
model.height = imageBitmap.height;
1454+
1455+
if (useTexStorage(VtkDataTypes.UNSIGNED_CHAR)) {
1456+
model.context.texStorage2D(
1457+
model.target,
1458+
1,
1459+
model.internalFormat,
1460+
model.width,
1461+
model.height
1462+
);
1463+
model.context.texSubImage2D(
1464+
model.target,
1465+
0,
1466+
0,
1467+
0,
1468+
model.width,
1469+
model.height,
1470+
model.format,
1471+
model.openGLDataType,
1472+
imageBitmap
1473+
);
1474+
} else {
1475+
model.context.texImage2D(
1476+
model.target,
1477+
0,
1478+
model.internalFormat,
1479+
model.width,
1480+
model.height,
1481+
0,
1482+
model.format,
1483+
model.openGLDataType,
1484+
imageBitmap
1485+
);
1486+
}
1487+
1488+
if (model.generateMipmap) {
1489+
model.context.generateMipmap(model.target);
1490+
}
1491+
1492+
model.allocatedGPUMemoryInBytes =
1493+
model.width *
1494+
model.height *
1495+
model.depth *
1496+
model.components *
1497+
model._openGLRenderWindow.getDefaultTextureByteSize(
1498+
VtkDataTypes.UNSIGNED_CHAR,
1499+
getNorm16Ext(),
1500+
publicAPI.useHalfFloat()
1501+
);
1502+
1503+
publicAPI.deactivate();
1504+
return true;
1505+
};
1506+
14131507
// Compute scale and offset per component from min and max per component
14141508
function computeScaleOffsets(min, max, numComps) {
14151509
const offset = new Array(numComps);

0 commit comments

Comments
 (0)