diff --git a/webgl/video_test/6.1.01.basis b/webgl/video_test/6.1.01.basis new file mode 100644 index 0000000..d3a06dc Binary files /dev/null and b/webgl/video_test/6.1.01.basis differ diff --git a/webgl/video_test/index.html b/webgl/video_test/index.html new file mode 100644 index 0000000..ef4a0f7 --- /dev/null +++ b/webgl/video_test/index.html @@ -0,0 +1,695 @@ + + + + + + + + + + + +
+
+ Basis Universal ETC1S GPU Texture Video Transcoding Test +
+ +
+
This demo uses the Basis C++ transcoder (compiled to WebAssembly using Emscripten) to transcode a .basis Universal Texture Video file directly to GPU texture data. +
.basis universal GPU texture files can be quickly transcoded directly to any other GPU texture format with little to no quality loss. +
Thanks to Evan Parker for providing webgl-texture-utils and this test bed. Go back. +
+ Transcode Format: FORMAT +
+
+
+ .basis file: + + +
+
+ + + +
+ + + + + +
+
+ Development (only on GPU's supporting BC1): +
+ +
+
+ + + +
+ +
+ +
+ +

+
+ + + + + diff --git a/webgl/video_test/renderer.js b/webgl/video_test/renderer.js new file mode 100644 index 0000000..9dc2129 --- /dev/null +++ b/webgl/video_test/renderer.js @@ -0,0 +1,297 @@ +/** + * Constructs a renderer object. + * @param {WebGLRenderingContext} gl The GL context. + * @constructor + */ +var Renderer = function(gl) { + /** + * The GL context. + * @type {WebGLRenderingContext} + * @private + */ + this.gl_ = gl; + + /** + * The WebGLProgram. + * @type {WebGLProgram} + * @private + */ + this.program_ = gl.createProgram(); + + /** + * @type {WebGLShader} + * @private + */ + this.vertexShader_ = this.compileShader_( + Renderer.vertexShaderSource_, gl.VERTEX_SHADER); + + /** + * @type {WebGLShader} + * @private + */ + this.fragmentShader_ = this.compileShader_( + Renderer.fragmentShaderSource_, gl.FRAGMENT_SHADER); + + /** + * Cached uniform locations. + * @type {Object.} + * @private + */ + this.uniformLocations_ = {}; + + /** + * Cached attribute locations. + * @type {Object.} + * @private + */ + this.attribLocations_ = {}; + + /** + * A vertex buffer containing a single quad with xy coordinates from [-1,-1] + * to [1,1] and uv coordinates from [0,0] to [1,1]. + * @private + */ + this.quadVertexBuffer_ = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVertexBuffer_); + var vertices = new Float32Array( + [-1.0, -1.0, 0.0, 1.0, + +1.0, -1.0, 1.0, 1.0, + -1.0, +1.0, 0.0, 0.0, + 1.0, +1.0, 1.0, 0.0]); + gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); + + + // init shaders + + gl.attachShader(this.program_, this.vertexShader_); + gl.attachShader(this.program_, this.fragmentShader_); + gl.bindAttribLocation(this.program_, 0, 'vert'); + gl.linkProgram(this.program_); + gl.useProgram(this.program_); + gl.enableVertexAttribArray(0); + + gl.enable(gl.DEPTH_TEST); + gl.disable(gl.CULL_FACE); + + var count = gl.getProgramParameter(this.program_, gl.ACTIVE_UNIFORMS); + for (var i = 0; i < /** @type {number} */(count); i++) { + var info = gl.getActiveUniform(this.program_, i); + var result = gl.getUniformLocation(this.program_, info.name); + this.uniformLocations_[info.name] = result; + } + + count = gl.getProgramParameter(this.program_, gl.ACTIVE_ATTRIBUTES); + for (var i = 0; i < /** @type {number} */(count); i++) { + var info = gl.getActiveAttrib(this.program_, i); + var result = gl.getAttribLocation(this.program_, info.name); + this.attribLocations_[info.name] = result; + } +}; + + +Renderer.prototype.finishInit = function() { + this.draw(); +}; + + +Renderer.prototype.createDxtTexture = function(dxtData, width, height, format) { + var gl = this.gl_; + var tex = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex); + gl.compressedTexImage2D( + gl.TEXTURE_2D, + 0, + format, + width, + height, + 0, + dxtData); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + 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); + //gl.generateMipmap(gl.TEXTURE_2D) + gl.bindTexture(gl.TEXTURE_2D, null); + return tex; +}; + +Renderer.prototype.deleteTexture = function(tex) +{ + var gl = this.gl_; + + gl.bindTexture(gl.TEXTURE_2D, null); + + gl.deleteTexture(tex); +} + +Renderer.prototype.createCompressedTexture = function(data, width, height, format) { + var gl = this.gl_; + var tex = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex); + gl.compressedTexImage2D( + gl.TEXTURE_2D, + 0, + format, + width, + height, + 0, + data); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + 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); + gl.bindTexture(gl.TEXTURE_2D, null); + return tex; +}; + +Renderer.prototype.updateCompressedTexture = function(texture, data, width, height, format) { + var gl = this.gl_; + + // Bind the existing texture + gl.bindTexture(gl.TEXTURE_2D, texture); + + // Update the compressed texture with new data + gl.compressedTexSubImage2D( + gl.TEXTURE_2D, // target + 0, // level of detail (0 is base image level) + 0, // x offset + 0, // y offset + width, // width of the texture + height, // height of the texture + format, // internal format of the compressed texture + data // new data + ); + + // Unbind the texture + gl.bindTexture(gl.TEXTURE_2D, null); +}; + +Renderer.prototype.createRgb565Texture = function(rgb565Data, width, height) { + var gl = this.gl_; + var tex = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex); + gl.texImage2D( + gl.TEXTURE_2D, + 0, + gl.RGB, + width, + height, + 0, + gl.RGB, + gl.UNSIGNED_SHORT_5_6_5, + rgb565Data); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + 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); + //gl.generateMipmap(gl.TEXTURE_2D) + gl.bindTexture(gl.TEXTURE_2D, null); + return tex; +}; + +Renderer.prototype.updateRgb565Texture = function(texture, rgb565Data, width, height) { + var gl = this.gl_; + + // Bind the existing texture + gl.bindTexture(gl.TEXTURE_2D, texture); + + // Update the texture with new uncompressed data + gl.texSubImage2D( + gl.TEXTURE_2D, // target + 0, // level of detail (0 is base image level) + 0, // x offset + 0, // y offset + width, // width of the texture + height, // height of the texture + gl.RGB, // format of the texture + gl.UNSIGNED_SHORT_5_6_5, // data type of the texture data + rgb565Data // new data + ); + + // Unbind the texture + gl.bindTexture(gl.TEXTURE_2D, null); +}; + +Renderer.prototype.drawTexture = function(texture, width, height, mode) { + var gl = this.gl_; + // draw scene + gl.clearColor(0, 0, 0, 1); + gl.clearDepth(1.0); + gl.viewport(0, 0, width, height); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); + + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.uniform1i(this.uniformLocations_.texSampler, 0); + + var x = 0.0; + var y = 0.0; + if (mode == 1) + x = 1.0; + else if (mode == 2) + y = 1.0; + + gl.uniform4f(this.uniformLocations_.control, x, y, 0.0, 0.0); + + gl.enableVertexAttribArray(this.attribLocations_.vert); + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVertexBuffer_); + gl.vertexAttribPointer(this.attribLocations_.vert, 4, gl.FLOAT, + false, 0, 0); + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); +}; + + +/** + * Compiles a GLSL shader and returns a WebGLShader. + * @param {string} shaderSource The shader source code string. + * @param {number} type Either VERTEX_SHADER or FRAGMENT_SHADER. + * @return {WebGLShader} The new WebGLShader. + * @private + */ +Renderer.prototype.compileShader_ = function(shaderSource, type) { + var gl = this.gl_; + var shader = gl.createShader(type); + gl.shaderSource(shader, shaderSource); + gl.compileShader(shader); + return shader; +}; + + +/** + * @type {string} + * @private + */ +Renderer.vertexShaderSource_ = [ + 'attribute vec4 vert;', + 'varying vec2 v_texCoord;', + 'void main() {', + ' gl_Position = vec4(vert.xy, 0.0, 1.0);', + ' v_texCoord = vert.zw;', + '}' + ].join('\n'); + + +/** + * @type {string} + * @private ' gl_FragColor = texture2D(texSampler, v_texCoord);', + */ +Renderer.fragmentShaderSource_ = [ + 'precision highp float;', + 'uniform sampler2D texSampler;', + 'uniform vec4 control;', + 'varying vec2 v_texCoord;', + 'void main() {', + ' vec4 c;', + ' c = texture2D(texSampler, v_texCoord);', + ' if (control.x > 0.0)', + ' {', + ' c.w = 1.0;', + ' }', + ' else if (control.y > 0.0)', + ' {', + ' c.rgb = c.aaa; c.w = 1.0;', + ' }', + ' gl_FragColor = c;', + '}' + ].join('\n'); +