webgl.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. function Texture(gl) {
  2. this.gl = gl;
  3. this.texture = gl.createTexture();
  4. gl.bindTexture(gl.TEXTURE_2D, this.texture);
  5. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  6. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  7. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  8. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  9. }
  10. Texture.prototype.bind = function (n, program, name) {
  11. var gl = this.gl;
  12. gl.activeTexture([gl.TEXTURE0, gl.TEXTURE1, gl.TEXTURE2][n]);
  13. gl.bindTexture(gl.TEXTURE_2D, this.texture);
  14. gl.uniform1i(gl.getUniformLocation(program, name), n);
  15. };
  16. Texture.prototype.fill = function (width, height, data) {
  17. var gl = this.gl;
  18. gl.bindTexture(gl.TEXTURE_2D, this.texture);
  19. gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, width, height, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, data);
  20. };
  21. function WebGLPlayer(canvas, options) {
  22. this.canvas = canvas;
  23. this.gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
  24. this.initGL(options);
  25. }
  26. WebGLPlayer.prototype.initGL = function (options) {
  27. if (!this.gl) {
  28. console.log("[ER] WebGL not supported.");
  29. return;
  30. }
  31. var gl = this.gl;
  32. gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
  33. var program = gl.createProgram();
  34. var vertexShaderSource = [
  35. "attribute highp vec4 aVertexPosition;",
  36. "attribute vec2 aTextureCoord;",
  37. "varying highp vec2 vTextureCoord;",
  38. "void main(void) {",
  39. " gl_Position = aVertexPosition;",
  40. " vTextureCoord = aTextureCoord;",
  41. "}"
  42. ].join("\n");
  43. var vertexShader = gl.createShader(gl.VERTEX_SHADER);
  44. gl.shaderSource(vertexShader, vertexShaderSource);
  45. gl.compileShader(vertexShader);
  46. var fragmentShaderSource = [
  47. "precision highp float;",
  48. "varying lowp vec2 vTextureCoord;",
  49. "uniform sampler2D YTexture;",
  50. "uniform sampler2D UTexture;",
  51. "uniform sampler2D VTexture;",
  52. "const mat4 YUV2RGB = mat4",
  53. "(",
  54. " 1.1643828125, 0, 1.59602734375, -.87078515625,",
  55. " 1.1643828125, -.39176171875, -.81296875, .52959375,",
  56. " 1.1643828125, 2.017234375, 0, -1.081390625,",
  57. " 0, 0, 0, 1",
  58. ");",
  59. "void main(void) {",
  60. " gl_FragColor = vec4( texture2D(YTexture, vTextureCoord).x, texture2D(UTexture, vTextureCoord).x, texture2D(VTexture, vTextureCoord).x, 1) * YUV2RGB;",
  61. "}"
  62. ].join("\n");
  63. var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
  64. gl.shaderSource(fragmentShader, fragmentShaderSource);
  65. gl.compileShader(fragmentShader);
  66. gl.attachShader(program, vertexShader);
  67. gl.attachShader(program, fragmentShader);
  68. gl.linkProgram(program);
  69. gl.useProgram(program);
  70. if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
  71. console.log("[ER] Shader link failed.");
  72. }
  73. var vertexPositionAttribute = gl.getAttribLocation(program, "aVertexPosition");
  74. gl.enableVertexAttribArray(vertexPositionAttribute);
  75. var textureCoordAttribute = gl.getAttribLocation(program, "aTextureCoord");
  76. gl.enableVertexAttribArray(textureCoordAttribute);
  77. var verticesBuffer = gl.createBuffer();
  78. gl.bindBuffer(gl.ARRAY_BUFFER, verticesBuffer);
  79. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 1.0, -1.0, 0.0, -1.0, -1.0, 0.0]), gl.STATIC_DRAW);
  80. gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
  81. var texCoordBuffer = gl.createBuffer();
  82. gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
  83. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0]), gl.STATIC_DRAW);
  84. gl.vertexAttribPointer(textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
  85. gl.y = new Texture(gl);
  86. gl.u = new Texture(gl);
  87. gl.v = new Texture(gl);
  88. gl.y.bind(0, program, "YTexture");
  89. gl.u.bind(1, program, "UTexture");
  90. gl.v.bind(2, program, "VTexture");
  91. }
  92. WebGLPlayer.prototype.renderFrame = function (videoFrame, width, height, uOffset, vOffset) {
  93. if (!this.gl) {
  94. console.log("[ER] Render frame failed due to WebGL not supported.");
  95. return;
  96. }
  97. var gl = this.gl;
  98. gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
  99. gl.clearColor(0.0, 0.0, 0.0, 0.0);
  100. gl.clear(gl.COLOR_BUFFER_BIT);
  101. gl.y.fill(width, height, videoFrame.subarray(0, uOffset));
  102. gl.u.fill(width >> 1, height >> 1, videoFrame.subarray(uOffset, uOffset + vOffset));
  103. gl.v.fill(width >> 1, height >> 1, videoFrame.subarray(uOffset + vOffset, videoFrame.length));
  104. gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  105. };
  106. WebGLPlayer.prototype.fullscreen = function () {
  107. var canvas = this.canvas;
  108. if (canvas.RequestFullScreen) {
  109. canvas.RequestFullScreen();
  110. } else if (canvas.webkitRequestFullScreen) {
  111. canvas.webkitRequestFullScreen();
  112. } else if (canvas.mozRequestFullScreen) {
  113. canvas.mozRequestFullScreen();
  114. } else if (canvas.msRequestFullscreen) {
  115. canvas.msRequestFullscreen();
  116. } else {
  117. alert("This browser doesn't supporter fullscreen");
  118. }
  119. };
  120. WebGLPlayer.prototype.exitfullscreen = function (){
  121. if (document.exitFullscreen) {
  122. document.exitFullscreen();
  123. } else if (document.webkitExitFullscreen) {
  124. document.webkitExitFullscreen();
  125. } else if (document.mozCancelFullScreen) {
  126. document.mozCancelFullScreen();
  127. } else if (document.msExitFullscreen) {
  128. document.msExitFullscreen();
  129. } else {
  130. alert("Exit fullscreen doesn't work");
  131. }
  132. }