webgluser February 2016

How to create a Texture from a ArrayBuffer in html5 and WebGL

I am having a image that I am reading in server side and pushing to web browser via AJAX call. I have a requirement where I have to render them line by line using WebGL.

For Example : Image is 640X480 where 640 is width and 480 is height. Now the total number of pixels will be 640*480 = 307200 pixels. So, I want to render the whole image in 640(total width) intervals in a loop using WebGL.

Now I have texture2D(as per my knowledge) in webgl to do so, but not getting any idea of where to start . I also having the ArrayBuffer with me , only thing is using Texture2D I want to render it slowly ,line by line.

I am ready to go for any js libraries ,if they are satisfying the requirements.

Tagging Babylon.js and Three.js ,incase those guys have a answer to my question with what they already have.

Adding some code to explain my requirement :

//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 }

Answers


Qbic February 2016

Ok, below is the working code 1) put it into .html file 2) load image (see comment in initTextures function)

In this code is also added vertex and fragment shaders

<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)

  functi 


webgluser February 2016

So, to write a image line by line we can do something like this.

Vertex Shader

  • attribute vec2 a_position;?
    attribute vec2 a_texCoord;?
    
    void main() {
       ???
    }
    
  • Fragment Shader

     #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 For rendering pixel by pixel

      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 ?
    

Post Status

Asked in February 2016
Viewed 3,714 times
Voted 13
Answered 2 times

Search




Leave an answer