yuvBehavior.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. const yuvBehavior = Behavior({
  2. methods: {
  3. initShader() {
  4. const gl = this.gl = this.renderer.getContext()
  5. const currentProgram = gl.getParameter(gl.CURRENT_PROGRAM)
  6. const vs = `
  7. attribute vec2 a_position;
  8. attribute vec2 a_texCoord;
  9. uniform mat3 displayTransform;
  10. varying vec2 v_texCoord;
  11. void main() {
  12. vec3 p = displayTransform * vec3(a_position, 0);
  13. gl_Position = vec4(p, 1);
  14. v_texCoord = a_texCoord;
  15. }
  16. `
  17. const fs = `
  18. precision highp float;
  19. uniform sampler2D y_texture;
  20. uniform sampler2D uv_texture;
  21. varying vec2 v_texCoord;
  22. void main() {
  23. vec4 y_color = texture2D(y_texture, v_texCoord);
  24. vec4 uv_color = texture2D(uv_texture, v_texCoord);
  25. float Y, U, V;
  26. float R ,G, B;
  27. Y = y_color.r;
  28. U = uv_color.r - 0.5;
  29. V = uv_color.a - 0.5;
  30. R = Y + 1.402 * V;
  31. G = Y - 0.344 * U - 0.714 * V;
  32. B = Y + 1.772 * U;
  33. gl_FragColor = vec4(R, G, B, 1.0);
  34. }
  35. `
  36. const vertShader = gl.createShader(gl.VERTEX_SHADER)
  37. gl.shaderSource(vertShader, vs)
  38. gl.compileShader(vertShader)
  39. const fragShader = gl.createShader(gl.FRAGMENT_SHADER)
  40. gl.shaderSource(fragShader, fs)
  41. gl.compileShader(fragShader)
  42. const program = this._program = gl.createProgram()
  43. this._program.gl = gl
  44. gl.attachShader(program, vertShader)
  45. gl.attachShader(program, fragShader)
  46. gl.deleteShader(vertShader)
  47. gl.deleteShader(fragShader)
  48. gl.linkProgram(program)
  49. gl.useProgram(program)
  50. const uniformYTexture = gl.getUniformLocation(program, 'y_texture')
  51. gl.uniform1i(uniformYTexture, 5)
  52. const uniformUVTexture = gl.getUniformLocation(program, 'uv_texture')
  53. gl.uniform1i(uniformUVTexture, 6)
  54. this._dt = gl.getUniformLocation(program, 'displayTransform')
  55. gl.useProgram(currentProgram)
  56. },
  57. initVAO() {
  58. const gl = this.renderer.getContext()
  59. const ext = gl.getExtension('OES_vertex_array_object')
  60. this.ext = ext
  61. const currentVAO = gl.getParameter(gl.VERTEX_ARRAY_BINDING)
  62. const vao = ext.createVertexArrayOES()
  63. ext.bindVertexArrayOES(vao)
  64. const posAttr = gl.getAttribLocation(this._program, 'a_position')
  65. const pos = gl.createBuffer()
  66. gl.bindBuffer(gl.ARRAY_BUFFER, pos)
  67. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 1, -1, 1, 1, -1, -1, -1]), gl.STATIC_DRAW)
  68. gl.vertexAttribPointer(posAttr, 2, gl.FLOAT, false, 0, 0)
  69. gl.enableVertexAttribArray(posAttr)
  70. vao.posBuffer = pos
  71. const texcoordAttr = gl.getAttribLocation(this._program, 'a_texCoord')
  72. const texcoord = gl.createBuffer()
  73. gl.bindBuffer(gl.ARRAY_BUFFER, texcoord)
  74. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 1, 0, 1, 1, 0, 0, 0]), gl.STATIC_DRAW)
  75. gl.vertexAttribPointer(texcoordAttr, 2, gl.FLOAT, false, 0, 0)
  76. gl.enableVertexAttribArray(texcoordAttr)
  77. vao.texcoordBuffer = texcoord
  78. ext.bindVertexArrayOES(currentVAO)
  79. this._vao = vao
  80. },
  81. initGL() {
  82. this.initShader()
  83. this.initVAO()
  84. },
  85. renderGL(frame) {
  86. const gl = this.renderer.getContext()
  87. gl.disable(gl.DEPTH_TEST)
  88. const {
  89. yTexture,
  90. uvTexture
  91. } = frame.getCameraTexture(gl, 'yuv')
  92. const displayTransform = frame.getDisplayTransform()
  93. if (yTexture && uvTexture) {
  94. const currentProgram = gl.getParameter(gl.CURRENT_PROGRAM)
  95. const currentActiveTexture = gl.getParameter(gl.ACTIVE_TEXTURE)
  96. const currentVAO = gl.getParameter(gl.VERTEX_ARRAY_BINDING)
  97. gl.useProgram(this._program)
  98. this.ext.bindVertexArrayOES(this._vao)
  99. gl.uniformMatrix3fv(this._dt, false, displayTransform)
  100. gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1)
  101. gl.activeTexture(gl.TEXTURE0 + 5)
  102. const bindingTexture5 = gl.getParameter(gl.TEXTURE_BINDING_2D)
  103. gl.bindTexture(gl.TEXTURE_2D, yTexture)
  104. gl.activeTexture(gl.TEXTURE0 + 6)
  105. const bindingTexture6 = gl.getParameter(gl.TEXTURE_BINDING_2D)
  106. gl.bindTexture(gl.TEXTURE_2D, uvTexture)
  107. gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4)
  108. gl.bindTexture(gl.TEXTURE_2D, bindingTexture6)
  109. gl.activeTexture(gl.TEXTURE0 + 5)
  110. gl.bindTexture(gl.TEXTURE_2D, bindingTexture5)
  111. gl.useProgram(currentProgram)
  112. gl.activeTexture(currentActiveTexture)
  113. this.ext.bindVertexArrayOES(currentVAO)
  114. }
  115. },
  116. },
  117. })
  118. export default yuvBehavior