2

サーバー側で読み取り、AJAX 呼び出しを介して Web ブラウザーにプッシュしている画像があります。WebGL を使用して 1 行ずつレンダリングする必要があるという要件があります。

例: 画像は 640X480 で、640 は幅、480 は高さです。これで、ピクセルの総数は 640*480 = 307200 ピクセルになります。そこで、WebGLを使って画像全体をループで640(全幅)間隔でレンダリングしたい。

今、webgl に texture2D (私の知る限り) がありますが、どこから始めればよいかわかりません。私もArrayBufferを持っています.Texture2Dを使用しているのは1行ずつゆっくりとレンダリングしたいだけです.

要件を満たしている場合は、任意の js ライブラリを使用する準備ができています。

Babylon.js と Three.js にタグを付けて、彼らがすでに持っているもので私の質問に答えている場合に備えて。

私の要件を説明するためにいくつかのコードを追加します:

//Recieve data
Code : 
var imageDataFromServer = single line data from server;
var imageLineData = new ArrayBuffer(imageDataFromServer.length);
var imageUintArray = new Uint8Array(imageLineData);
for (var i = 0; i < width(i.e.640) ;i++) //because I know one line length =640.
{
   //how to put data in texture2D using Three.js or Babylon.js or just plain WebGL
}
4

2 に答える 2

1

OK、以下は作業コードです1).htmlファイルに入れます2)画像をロードします(initTextures関数のコメントを参照)

このコードには、頂点シェーダーとフラグメント シェーダーも追加されています。

<canvas width="400" height="400"></canvas>

<script>
function initShaders(gl, vshader, fshader) {
  var program = createProgram(gl, vshader, fshader);    
  gl.useProgram(program);
  gl.program = program;

  return true;
}

function createProgram(gl, vshader, fshader) {
  var vertexShader = loadShader(gl, gl.VERTEX_SHADER, vshader);
  var fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fshader);
  var program = gl.createProgram();

  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);

  gl.linkProgram(program);
  return program;
}

function loadShader(gl, type, source) {
  var shader = gl.createShader(type);
  gl.shaderSource(shader, source);
  gl.compileShader(shader);
  return shader;
}

function getWebGLContext(canvas, opt_debug) {
  return canvas.getContext('webgl');
}

var VSHADER_SOURCE =
  'attribute vec4 a_Position;\n' +
  'attribute vec2 a_TexCoord;\n' +
  'varying vec2 uv;\n' +
  'void main() {\n' +
  '  gl_Position = a_Position;\n' +
  '  uv = a_TexCoord;\n' +
  '}\n';

var FSHADER_SOURCE =
  '#ifdef GL_ES\n' +
  'precision mediump float;\n' +
  '#endif\n' +
  'uniform sampler2D uImage0;\n' +
  'uniform vec2 resolution;\n' +
  'uniform float time;\n' +
  'varying vec2 uv;\n' +
  'void main() {\n' +
      'vec2 position = 1.0 - gl_FragCoord.xy / resolution;\n' +
      'vec3 color = vec3(1.0);\n' +

      'if (time > position.y * 10.0) {\n' +
          'color = vec3(texture2D(uImage0, uv));\n' +
      '}\n' +
  '  gl_FragColor = vec4(color, 1.0);\n' +
  '}\n';

function main() {
  var canvas = document.querySelector('canvas');
  var gl = getWebGLContext(canvas);
  initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE);

  var n = initVertexBuffers(gl);
  gl.clearColor(0.0, 0.0, 0.0, 1.0);
  initTextures(gl, n)

  function render (dt) {
    gl.uniform1f(time, dt / 1000);
    draw();
    requestAnimationFrame(render);
  }

  render();
}

function initVertexBuffers(gl) {
  var verticesTexCoords = new Float32Array([
    -0.5,  0.5,   0.0, 1.0,
    -0.5, -0.5,   0.0, 0.0,
     0.5,  0.5,   1.0, 1.0,
     0.5, -0.5,   1.0, 0.0,
  ]);
  var n = 4;
  var vertexTexCoordBuffer = gl.createBuffer();

  gl.bindBuffer(gl.ARRAY_BUFFER, vertexTexCoordBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, verticesTexCoords, gl.STATIC_DRAW);

  var FSIZE = verticesTexCoords.BYTES_PER_ELEMENT;
  var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
  gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 4, 0);
  gl.enableVertexAttribArray(a_Position);

  var a_TexCoord = gl.getAttribLocation(gl.program, 'a_TexCoord');
  gl.vertexAttribPointer(a_TexCoord, 2, gl.FLOAT, false, FSIZE * 4, FSIZE * 2);
  gl.enableVertexAttribArray(a_TexCoord);

  return n;
}

function initTextures(gl, n) {
  var texture = gl.createTexture();
  resolution = gl.getUniformLocation(gl.program, 'resolution');
  gl.uniform2f(resolution, 256, 256);
  time = gl.getUniformLocation(gl.program, 'time');

  var uImage0 = gl.getUniformLocation(gl.program, 'uImage0');

  var image = new Image();
  image.onload = function(){ loadTexture(gl, n, texture, uImage0, image); };

  // load this file: http://www.html5rocks.com/static/images/tutorials/easy-hidpi/chrome1x.png
  // to the same folder as this .html file
  image.src = 'chrome1x.png';

  return true;
}

function loadTexture(gl, n, texture, uImage0, image) {
  count = n;
  GL = gl;

  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
  gl.activeTexture(gl.TEXTURE0);
  gl.bindTexture(gl.TEXTURE_2D, texture);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
  gl.uniform1i(uImage0, 0);

  draw();
}

function draw () {
  if (!window.GL) {
    return;
  }
  GL.clear(GL.COLOR_BUFFER_BIT);
  GL.drawArrays(GL.TRIANGLE_STRIP, 0, count);
}

main();
</script>
于 2016-02-08T16:29:27.800 に答える
0

したがって、画像を 1 行ずつ書き込むには、次のようなことができます。

頂点シェーダー

  • attribute vec2 a_position;?
    attribute vec2 a_texCoord;?
    
    void main() {
       ???
    }
    
  • フラグメントシェーダー

     #ifdef GL_ES
     precision mediump float;
     #endif
    
    uniform float time;
    uniform vec2 mouse;
    uniform vec2 resolution;
    
    void main( void ) {
      vec2 position = 1.0 - gl_FragCoord.xy / resolution;
      vec3 color = vec3(1.0);
    
      if (time > position.y * 10.0) {
          color = texture2D(uImage0, uv);
      }
    
     gl_FragColor = vec4(color, 1.0);
    
    }
    
  • Javascript ピクセルごとのレンダリング用

      function createTextureFromArray(gl, dataArray, type, width, height) {
            var data = new Uint8Array(dataArray);
            var texture = gl.createTexture();
            gl.bindTexture(gl.TEXTURE_2D, texture);
            gl.texImage2D(gl.TEXTURE_2D, 0, type, width, height, 0, type, gl.UNSIGNED_BYTE, data);
            return texture;
     }
    
       var arrayBuffer = new ArrayBuffer(640*480);
       for (var i=0; i < 640; i++) {
           for (var j=0; j < 480; j++) {
               arrayBuffer[i] = Math.floor(Math.random() * 255) + 0;     //filling buffer with random data between 0 and 255 which will be further filled to the texture 
               //NOTE : above data is just dummy data , I will get this data from server pixel by pixel.
           }
       }
       var gl = canvas.getContext('webgl');
       // setup GLSL program
       var program = createProgramFromScripts(gl, ["2d-vertex-shader", "2d-fragment-shader"]);
       gl.useProgram(program);
       //what should I add after this ?
    
于 2016-02-10T07:30:12.350 に答える