javascript - babylon - three js descargar
Cómo crear una textura desde un ArrayBuffer en html5 y WebGL (2)
Bien, debajo está el código de trabajo 1) ponlo en el archivo .html 2) carga la imagen (mira el comentario en la función initTextures)
En este código también se agrega sombreados de vértices y fragmentos
<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>
Estoy teniendo una imagen que estoy leyendo en el lado del servidor y presionando al navegador web a través de la llamada AJAX. Tengo un requisito donde tengo que renderizarlos línea por línea usando WebGL.
Por ejemplo: la imagen es 640X480 donde 640 es ancho y 480 es alto. Ahora el número total de píxeles será 640 * 480 = 307200 píxeles. Entonces, quiero renderizar toda la imagen en intervalos de 640 (ancho total) en un bucle usando WebGL.
Ahora tengo texture2D (según mi conocimiento) en webgl para hacerlo, pero no tengo una idea de por dónde empezar. También tengo el ArrayBuffer conmigo, solo está usando Texture2D. Quiero renderizarlo lentamente, línea por línea.
Estoy listo para ir a cualquier biblioteca js, si cumplen los requisitos.
Etiquetando Babylon.js y Three.js, en caso de que esos tipos tengan una respuesta a mi pregunta con lo que ya tienen.
Agregar un código para explicar mi requerimiento:
// Datos var imageDataFromServer = single line data from server; var imageLineData = new ArrayBuffer(imageDataFromServer.length); var imageUintArray = new Uint8Array(imageLineData); for (var i = 0; i < width(ie640) ;i++) //because I know one line length =640. { //how to put data in texture2D using Three.js or Babylon.js or just plain WebGL }
Código: var imageDataFromServer = single line data from server; var imageLineData = new ArrayBuffer(imageDataFromServer.length); var imageUintArray = new Uint8Array(imageLineData); for (var i = 0; i < width(ie640) ;i++) //because I know one line length =640. { //how to put data in texture2D using Three.js or Babylon.js or just plain WebGL }
var imageDataFromServer = single line data from server; var imageLineData = new ArrayBuffer(imageDataFromServer.length); var imageUintArray = new Uint8Array(imageLineData); for (var i = 0; i < width(ie640) ;i++) //because I know one line length =640. { //how to put data in texture2D using Three.js or Babylon.js or just plain WebGL }
Entonces, para escribir una imagen línea por línea podemos hacer algo como esto.
Vertex Shader
attribute vec2 a_position;? attribute vec2 a_texCoord;? void main() { ??? }
Fragmento 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 Para renderizar píxel por píxel
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 ?