1
votes

I'm learning WebGL from this tutorial: https://developer.mozilla.org/en-US/docs/WebGL/Animating_textures_in_WebGL and in the last lesson it shows how to use video object as a texture. There's a live example here: https://developer.mozilla.org/samples/webgl/sample8/index.html which works just fine (I'm using Firefox). The problem is when I tried to do that myself I ran into problems. Ever more weird, I have different error messages at my pc (offline) and at my hosting (online). Offline error:

file:///C:/Users/NPS/Desktop/gallery/video.html(351): SecurityError: The operation is insecure.

where line 351 is:

gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, videoElement);

Firefox developer toolbar says additionally:

Error: WebGL: It is forbidden to load a WebGL texture from a cross-domain element that has not been validated with CORS. See https://developer.mozilla.org/en/WebGL/Cross-Domain_Textures

I've read about that error and it seems strange that it doesn't work since the html and video files are both in the same place. Also when I open the page the sound from the video file is actually played (but that's about it). On the other hand, the online version's error is different (but I can't place it here because it's in polish and I'm not sure what's the exact english counterpart. But if you have Firefox you can check it here: http://nps.netarteria.pl/gallery/video.html (I'm using firefox developer bar for that). Of course, you can check the page's source code and everything I'm using there too.

Any idea what can I do to make it work? I'd really like to have video textures in my project and right now I'm stuck.

2

2 Answers

6
votes

The problem with your sample is that your video texture is not a power of 2 and you haven't setup texture filtering to handle that.

Change line 353 from

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);

to

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);

and add these 2 lines

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);

Also remove the call to gl.generateMipmap(GL_TEXTURE_2D) as you can't generate mips for non-power-of-2 textures.

You can read about the issues with non-power-of-2 textures on the WebGL Wiki

The sample on the MDN site has been broken for a long time and no one has bothered to fix it :-( It used to work because of a bug in Firefox that has long since been fixed.

Note: Chrome 25 (Chrome Canary) will print some messages that make help point this out. When I run your sample on Chrome 25 I get the following messages

WebGL: INVALID_OPERATION: generateMipmap: level 0 not power of 2 or not all the same size video.html:1
WebGL: drawElements: texture bound to texture unit 0 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete' 
0
votes

For Chrome you can try shortcut with parameter "chrome.exe --allow-file-access-from-files"