From 2e63d5c4e26464e75583f2525cf578fac6092be5 Mon Sep 17 00:00:00 2001 From: ggetz Date: Mon, 30 Sep 2024 14:22:37 -0400 Subject: [PATCH] Fix issue with copying to a texture from a HTMLVideoElement --- CHANGES.md | 1 + packages/engine/Source/Renderer/Texture.js | 19 ++++++++++-- packages/engine/Specs/Renderer/TextureSpec.js | 31 +++++++++++++++++++ 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index a12796cd079..091574b9f8e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,7 @@ ##### Fixes :wrench: +- Fix Texture errors when using a `HTMLVideoElement`. [#12219](https://github.com/CesiumGS/cesium/issues/12219) - Use first geometryBuffer if no best match found in I3SNode [#12132](https://github.com/CesiumGS/cesium/pull/12132) - Update type definitions to allow undefined for optional parameters [#12193](https://github.com/CesiumGS/cesium/pull/12193) - Reverts Firefox OIT temporary fix [#4815] and Firefox test failure fix [#5047] diff --git a/packages/engine/Source/Renderer/Texture.js b/packages/engine/Source/Renderer/Texture.js index 0c9071c3032..b8b8124410a 100644 --- a/packages/engine/Source/Renderer/Texture.js +++ b/packages/engine/Source/Renderer/Texture.js @@ -60,11 +60,12 @@ function Texture(options) { let { width, height } = options; if (defined(source)) { + // Make sure we are using the element's intrinsic width and height where available if (!defined(width)) { - width = defaultValue(source.videoWidth, source.width); + width = source.videoWidth ?? source.naturalWidth ?? source.width; } if (!defined(height)) { - height = defaultValue(source.videoHeight, source.height); + height = source.videoHeight ?? source.naturalHeight ?? source.height; } } @@ -810,7 +811,19 @@ Texture.prototype.copyFrom = function (options) { gl.activeTexture(gl.TEXTURE0); gl.bindTexture(target, this._texture); - const { width, height, arrayBufferView } = source; + let { width, height } = source; + const arrayBufferView = source.arrayBufferView; + + // Make sure we are using the element's intrinsic width and height where available + if (defined(source.naturalWidth) && defined(source.naturalHeight)) { + width = source.naturalWidth; + height = source.naturalHeight; + } + + if (defined(source.videoWidth) && defined(source.videoHeight)) { + width = source.videoWidth; + height = source.videoHeight; + } const textureWidth = this._width; const textureHeight = this._height; diff --git a/packages/engine/Specs/Renderer/TextureSpec.js b/packages/engine/Specs/Renderer/TextureSpec.js index 5482c762c53..609a6a95da4 100644 --- a/packages/engine/Specs/Renderer/TextureSpec.js +++ b/packages/engine/Specs/Renderer/TextureSpec.js @@ -114,7 +114,15 @@ describe( context.destroyForSpecs(); }); + let blueImageHeight, blueImageWidth; + beforeEach(function () { + blueImageHeight = blueImage.height; + blueImageWidth = blueImage.width; + }); + afterEach(function () { + blueImage.height = blueImageHeight; + blueImage.width = blueImageWidth; texture = texture && texture.destroy(); }); @@ -670,6 +678,29 @@ describe( }).contextToRender([0, 0, 255, 255]); }); + it("can copy from a DOM element when display dimensions are 0", function () { + blueImage.height = 0; + blueImage.width = 0; + + texture = new Texture({ + context: context, + pixelFormat: PixelFormat.RGB, + pixelDatatype: PixelDatatype.UNSIGNED_BYTE, + source: blueImage, + }); + + texture.copyFrom({ + source: blueImage, + }); + + expect({ + context: context, + fragmentShader: fs, + uniformMap: uniformMap, + epsilon: 1, + }).contextToRender([0, 0, 255, 255]); + }); + it("can replace a subset of a texture", function () { texture = new Texture({ context: context,