Skip to content

Commit

Permalink
Texture supports continuous update from HTMLVideoElement (#1418)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pessimistress committed Nov 30, 2020
1 parent db47d90 commit 4d6926f
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 13 deletions.
7 changes: 6 additions & 1 deletion docs/api-reference/webgl/texture.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ Note: does not allocate storage
See also [gl.compressedTexSubImage2D](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/compressedTexSubImage2D), [gl.texSubImage2D](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/texSubImage2D), [gl.bindTexture](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bindTexture), [gl.bindBuffer](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bindBuffer)


### update()

Update this texture if `HTMLVideoElement` is used as the data source. This method is automatically called before every draw call if this texture is bound to a uniform.


### getActiveUnit()

Returns number of active textures.
Expand Down Expand Up @@ -205,7 +210,7 @@ WebGL allows textures to be created from a number of different data sources.
| `typed array` | Bytes will be interpreted according to format/type parameters and pixel store parameters. |
| `Buffer` or `WebGLBuffer` (`WebGL 2`) | Bytes will be interpreted according to format/type parameters and pixel store parameters. |
| `Image` (`HTMLImageElement`) | image will be used to fill the texture. width and height will be deduced. |
| `Video` (`HTMLVideoElement`) | video will be played, continously updating the texture. width and height will be deduced. |
| `Video` (`HTMLVideoElement`) | video will be used to continously update the texture. width and height will be deduced. |
| `Canvas` (`HTMLCanvasElement`) | canvas will be used to fill the texture. width and height will be deduced. |
| `ImageData` | `canvas.getImageData()` - Used to fill the texture. width and height will be deduced. |

Expand Down
8 changes: 8 additions & 0 deletions docs/whats-new.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# What's New

## Version 8.4

Date: TBD

### Texture

Supports continuous update from HTMLVideoElement

## Version 8.3

Date: Oct 12, 2020
Expand Down
17 changes: 5 additions & 12 deletions modules/webgl/src/classes/program.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ export default class Program extends Resource {
this.uniforms = {};

this._textureUniforms = {};
this._texturesRenderable = true;

// Setup varyings if supplied
if (varyings && varyings.length > 0) {
Expand Down Expand Up @@ -227,10 +226,6 @@ export default class Program extends Resource {
texture.bind(textureIndex);
value = textureIndex;

if (!texture.loaded) {
this._texturesRenderable = false;
}

this._textureUniforms[uniformName] = texture;
} else {
value = uniformSetter.textureIndex;
Expand All @@ -253,20 +248,18 @@ export default class Program extends Resource {
// PRIVATE METHODS

// Checks if all texture-values uniforms are renderable (i.e. loaded)
// Update a texture if needed (e.g. from video)
// Note: This is currently done before every draw call
_areTexturesRenderable() {
if (this._texturesRenderable) {
return true;
}

this._texturesRenderable = true;
let texturesRenderable = true;

for (const uniformName in this._textureUniforms) {
const texture = this._textureUniforms[uniformName];
this._texturesRenderable = this._texturesRenderable && texture.loaded;
texture.update();
texturesRenderable = texturesRenderable && texture.loaded;
}

return this._texturesRenderable;
return texturesRenderable;
}

// Binds textures
Expand Down
29 changes: 29 additions & 0 deletions modules/webgl/src/classes/texture.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ export default class Texture extends Resource {
);
return this;
}
const isVideo = typeof HTMLVideoElement !== 'undefined' && data instanceof HTMLVideoElement;
if (isVideo && data.readyState < HTMLVideoElement.HAVE_METADATA) {
data.addEventListener('loadedmetadata', () => this.initialize(props));
return this;
}

const {
pixels = null,
Expand Down Expand Up @@ -173,10 +178,34 @@ export default class Texture extends Resource {
if (recreate) {
this.data = data;
}
if (isVideo) {
this._video = {
video: data,
parameters,
lastTime: data.readyState >= HTMLVideoElement.HAVE_CURRENT_DATA ? data.currentTime : -1
};
}

return this;
}

update() {
if (this._video) {
const {video, parameters, lastTime} = this._video;
if (lastTime === video.currentTime || video.readyState < HTMLVideoElement.HAVE_CURRENT_DATA) {
return;
}
this.setSubImageData({
data: video,
parameters
});
if (this.mipmaps) {
this.generateMipmap();
}
this._video.lastTime = video.currentTime;
}
}

// If size has changed, reinitializes with current format
// note clears image and mipmaps
resize({height, width, mipmaps = false}) {
Expand Down

0 comments on commit 4d6926f

Please sign in to comment.