2017-12-11 17 views
1

Ich versuche, Kugel mit Dreiecken und 2 Puffer zu zeichnen (gl.ARRAY_BUFFER und gl.ELEMENT_ARRAY_BUFFER), aber etwas falsch.Ich sehe nur leere Anzeige ... Ich benutze einige dieser Code http://learningwebgl.com/blog/?p=1253 und diese https://github.com/davidwparker/programmingtil-webgl/blob/master/0078-3d-sphere/index.js.WebGL versuchen Zeichenkugel

var VSHADER_SOURCE = 
    'attribute vec4 a_Position;\n' + 
    'void main() {\n' + 
    ' gl_Position = a_Position;\n' + 
    ' gl_PointSize = 10.0;\n' + 
    '}\n'; 

var FSHADER_SOURCE = 
    'void main() {\n' + 
    ' gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' + 
    '}\n'; 

function resize(canvas) 
{ 
    var displayWidth = canvas.clientWidth; 
    var displayHeight = canvas.clientHeight; 
    if (canvas.width != displayWidth || canvas.height != displayHeight) 
    { 
    canvas.width = displayWidth; 
    canvas.height = displayHeight; 
    } 
} 

function initArrayBuffers(gl) 
{ 
    var SPHERE_DIV = 6; 
    var i, ai, si, ci; 
    var j, aj, sj, cj; 
    var p1, p2; 
    var vertices = [],indices = []; 
    for (j = 0; j <= SPHERE_DIV; j++) 
    { 
    aj = j * Math.PI/SPHERE_DIV; 
    sj = Math.sin(aj); 
    cj = Math.cos(aj); 
    for (i = 0; i <= SPHERE_DIV; i++) 
    { 
     ai = i * 2 * Math.PI/SPHERE_DIV; 
     si = Math.sin(ai); 
     ci = Math.cos(ai); 
     vertices.push(si * sj); // X 
     vertices.push(cj);  // Y 
     vertices.push(ci * sj); // Z 
    } 

    for (j = 0; j < SPHERE_DIV; j++) 
    { 
     for (i = 0; i < SPHERE_DIV; i++) 
     { 
     p1 = j * (SPHERE_DIV+1) + i; 
     p2 = p1 + (SPHERE_DIV+1); 
     indices.push(p1); 
     indices.push(p2); 
     indices.push(p1 + 1); 
     indices.push(p1 + 1); 
     indices.push(p2); 
     indices.push(p2 + 1); 
     } 
    } 
    var vertexBuffer = gl.createBuffer(); 
    if (!vertexBuffer) 
    { 
     console.log('Failed to create the buffer object'); 
     return -1; 
    } 
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); 
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); 
    var indexBuffer = gl.createBuffer(); 
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); 
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW); 
    } 
    return indices.length; 
} 

function main() 
{ 
    var canvas = document.getElementById('webgl'); 
    var gl = getWebGLContext(canvas); 
    resize(gl.canvas); 
    gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); 
    var n=initArrayBuffers(gl); 
    if (!gl) 
    { 
    console.log('Failed to retrieve the <canvas> element'); 
    return; 
    } 
    if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) 
    { 
    console.log('Failed to intialize shaders.'); 
    return; 
    } 
    gl.clearColor(0.0, 0.0, 0.0, 0.0); 
    gl.clear(gl.COLOR_BUFFER_BIT); 
    var a_Position = gl.getAttribLocation(gl.program, 'a_Position'); 
    if (a_Position < 0) 
     { 
     console.log('Failed to get the storage location of a_Position'); 
     return -1; 
     } 
    gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_SHORT, 0); 
} 

Antwort

2

Ther sind 2 Problem in Ihrem Code:

Sie haben das Feld von generischen Vertexattributdaten (gl.vertexAttribPointer) und Sie zu definieren, haben das Vertexattribut (gl.enableVertexAttribArray) zu ermöglichen, vor dem Sie das Netz ziehen:

var a_Position = gl.getAttribLocation(gl.program, 'a_Position'); 
gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, 0, 0); 
gl.enableVertexAttribArray(a_Position); 
gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_SHORT, 0); 


Und es gibt eine Fehlausrichtung der geschweiften Klammern in der Funktion initArrayBuffers

function initArrayBuffers(gl) 
{ 
    var SPHERE_DIV = 6; 
    var i, ai, si, ci; 
    var j, aj, sj, cj; 
    var p1, p2; 
    var vertices = [],indices = []; 
    for (j = 0; j <= SPHERE_DIV; j++) 
    { 
    aj = j * Math.PI/SPHERE_DIV; 
    sj = Math.sin(aj); 
    cj = Math.cos(aj); 
    for (i = 0; i <= SPHERE_DIV; i++) 
    { 
     ai = i * 2 * Math.PI/SPHERE_DIV; 
     si = Math.sin(ai); 
     ci = Math.cos(ai); 
     vertices.push(si * sj); // X 
     vertices.push(cj);  // Y 
     vertices.push(ci * sj); // Z 
    } 
    } // <------------------------------------------------------------- ADD 

    for (j = 0; j < SPHERE_DIV; j++) 
    { 
    for (i = 0; i < SPHERE_DIV; i++) 
    { 
     p1 = j * (SPHERE_DIV+1) + i; 
     p2 = p1 + (SPHERE_DIV+1); 
     indices.push(p1); 
     indices.push(p2); 
     indices.push(p1 + 1); 
     indices.push(p1 + 1); 
     indices.push(p2); 
     indices.push(p2 + 1); 
    } 
    } 
    var vertexBuffer = gl.createBuffer(); 
    if (!vertexBuffer) 
    { 
    console.log('Failed to create the buffer object'); 
    return -1; 
    } 
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); 
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); 
    var indexBuffer = gl.createBuffer(); 
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); 
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW); 

    // } <------------------------------------------------------ REMOVE 

    return indices.length; 
} 

Siehe Code-Schnipsel:

var VSHADER_SOURCE = 
 
    'attribute vec4 a_Position;\n' + 
 
    'void main() {\n' + 
 
    ' gl_Position = a_Position;\n' + 
 
    ' gl_PointSize = 10.0;\n' + 
 
    '}\n'; 
 

 
var FSHADER_SOURCE = 
 
    'void main() {\n' + 
 
    ' gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' + 
 
    '}\n'; 
 

 
var ShaderProgram = {}; 
 
ShaderProgram.Create = function(shaderList) { 
 
    var shaderObjs = []; 
 
    for (var i_sh = 0; i_sh < shaderList.length; ++ i_sh) { 
 
     var shderObj = this.CompileShader(shaderList[i_sh].source, shaderList[i_sh].stage); 
 
     if (shderObj == 0) 
 
      return 0; 
 
     shaderObjs.push(shderObj); 
 
    } 
 
    var progObj = this.LinkProgram(shaderObjs) 
 
    if (progObj != 0) { 
 
     progObj.attribIndex = {}; 
 
     var noOfAttributes = gl.getProgramParameter(progObj, gl.ACTIVE_ATTRIBUTES); 
 
     for (var i_n = 0; i_n < noOfAttributes; ++ i_n) { 
 
      var name = gl.getActiveAttrib(progObj, i_n).name; 
 
      progObj.attribIndex[name] = gl.getAttribLocation(progObj, name); 
 
     } 
 
     progObj.unifomLocation = {}; 
 
     var noOfUniforms = gl.getProgramParameter(progObj, gl.ACTIVE_UNIFORMS); 
 
     for (var i_n = 0; i_n < noOfUniforms; ++ i_n) { 
 
      var name = gl.getActiveUniform(progObj, i_n).name; 
 
      progObj.unifomLocation[name] = gl.getUniformLocation(progObj, name); 
 
     } 
 
    } 
 
    return progObj; 
 
} 
 
ShaderProgram.AttributeIndex = function(progObj, name) { return progObj.attribIndex[name]; } 
 
ShaderProgram.UniformLocation = function(progObj, name) { return progObj.unifomLocation[name]; } 
 
ShaderProgram.Use = function(progObj) { gl.useProgram(progObj); } 
 
ShaderProgram.SetUniformI1 = function(progObj, name, val) { if(progObj.unifomLocation[name]) gl.uniform1i(progObj.unifomLocation[name], val); } 
 
ShaderProgram.SetUniformF1 = function(progObj, name, val) { if(progObj.unifomLocation[name]) gl.uniform1f(progObj.unifomLocation[name], val); } 
 
ShaderProgram.SetUniformF2 = function(progObj, name, arr) { if(progObj.unifomLocation[name]) gl.uniform2fv(progObj.unifomLocation[name], arr); } 
 
ShaderProgram.SetUniformF3 = function(progObj, name, arr) { if(progObj.unifomLocation[name]) gl.uniform3fv(progObj.unifomLocation[name], arr); } 
 
ShaderProgram.SetUniformF4 = function(progObj, name, arr) { if(progObj.unifomLocation[name]) gl.uniform4fv(progObj.unifomLocation[name], arr); } 
 
ShaderProgram.SetUniformM33 = function(progObj, name, mat) { if(progObj.unifomLocation[name]) gl.uniformMatrix3fv(progObj.unifomLocation[name], false, mat); } 
 
ShaderProgram.SetUniformM44 = function(progObj, name, mat) { if(progObj.unifomLocation[name]) gl.uniformMatrix4fv(progObj.unifomLocation[name], false, mat); } 
 
ShaderProgram.CompileShader = function(source, shaderStage) { 
 
    var shaderScript = document.getElementById(source); 
 
    if (shaderScript) { 
 
     source = ""; 
 
     var node = shaderScript.firstChild; 
 
     while (node) { 
 
     if (node.nodeType == 3) source += node.textContent; 
 
     node = node.nextSibling; 
 
     } 
 
    } 
 
    var shaderObj = gl.createShader(shaderStage); 
 
    gl.shaderSource(shaderObj, source); 
 
    gl.compileShader(shaderObj); 
 
    var status = gl.getShaderParameter(shaderObj, gl.COMPILE_STATUS); 
 
    if (!status) alert(gl.getShaderInfoLog(shaderObj)); 
 
    return status ? shaderObj : 0; 
 
} 
 
ShaderProgram.LinkProgram = function(shaderObjs) { 
 
    var prog = gl.createProgram(); 
 
    for (var i_sh = 0; i_sh < shaderObjs.length; ++ i_sh) 
 
     gl.attachShader(prog, shaderObjs[i_sh]); 
 
    gl.linkProgram(prog); 
 
    status = gl.getProgramParameter(prog, gl.LINK_STATUS); 
 
    if (!status) alert("Could not initialise shaders"); 
 
    gl.useProgram(null); 
 
    return status ? prog : 0; 
 
} 
 

 
function initShaders(gl, vert_code, frag_code) 
 
{ 
 
    var progDraw = ShaderProgram.Create( 
 
     [ { source : VSHADER_SOURCE, stage : gl.VERTEX_SHADER }, 
 
     { source : FSHADER_SOURCE, stage : gl.FRAGMENT_SHADER } 
 
     ]); 
 
    progDraw.inPos = gl.getAttribLocation(progDraw, "a_Position"); 
 
    if (progDraw == 0) 
 
     return false; 
 
    ShaderProgram.Use(progDraw); 
 
    gl.program = progDraw; 
 
    return true;  
 
} 
 

 
    function initArrayBuffers(gl) 
 
    { 
 
     var SPHERE_DIV = 6; 
 
     var i, ai, si, ci; 
 
     var j, aj, sj, cj; 
 
     var p1, p2; 
 
     var vertices = [],indices = []; 
 
     for (j = 0; j <= SPHERE_DIV; j++) 
 
     { 
 
     aj = j * Math.PI/SPHERE_DIV; 
 
     sj = Math.sin(aj); 
 
     cj = Math.cos(aj); 
 
     for (i = 0; i <= SPHERE_DIV; i++) 
 
     { 
 
      ai = i * 2 * Math.PI/SPHERE_DIV; 
 
      si = Math.sin(ai); 
 
      ci = Math.cos(ai); 
 
      vertices.push(si * sj); // X 
 
      vertices.push(cj);  // Y 
 
      vertices.push(ci * sj); // Z 
 
     } 
 
     } 
 

 
     for (j = 0; j < SPHERE_DIV; j++) 
 
     { 
 
     for (i = 0; i < SPHERE_DIV; i++) 
 
     { 
 
      p1 = j * (SPHERE_DIV+1) + i; 
 
      p2 = p1 + (SPHERE_DIV+1); 
 
      indices.push(p1); 
 
      indices.push(p2); 
 
      indices.push(p1 + 1); 
 
      indices.push(p1 + 1); 
 
      indices.push(p2); 
 
      indices.push(p2 + 1); 
 
     } 
 
     } 
 
     var vertexBuffer = gl.createBuffer(); 
 
     if (!vertexBuffer) 
 
     { 
 
     console.log('Failed to create the buffer object'); 
 
     return -1; 
 
     } 
 
     gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); 
 
     gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); 
 
     var indexBuffer = gl.createBuffer(); 
 
     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); 
 
     gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW); 
 

 
     return indices.length; 
 
    } 
 

 
var n = 0;   
 
function drawScene(){ 
 

 
    var canvas = document.getElementById("glow-canvas"); 
 
    gl.viewport(0, 0, canvas.width, canvas.height); 
 
    gl.enable(gl.DEPTH_TEST); 
 
    
 
    gl.clearColor(0.0, 0.0, 0.0, 0.0); 
 
    gl.clear(gl.COLOR_BUFFER_BIT); 
 
    var a_Position = gl.getAttribLocation(gl.program, 'a_Position'); 
 
    if (a_Position < 0) 
 
    { 
 
     console.log('Failed to get the storage location of a_Position'); 
 
     return -1; 
 
    } 
 
    gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, 0, 0); 
 
    gl.enableVertexAttribArray(a_Position); 
 
    gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_SHORT, 0); 
 
} 
 

 
var gl; 
 
function sceneStart() { 
 

 
    var canvas = document.getElementById("glow-canvas"); 
 
    var vp = [canvas.width, canvas.height]; 
 
    gl = canvas.getContext("experimental-webgl"); 
 
    if (!gl) 
 
     return; 
 

 
    n = initArrayBuffers(gl); 
 
    if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) 
 
    { 
 
     console.log('Failed to intialize shaders.'); 
 
     return; 
 
    } 
 

 
    setInterval(drawScene, 50); 
 
}
<body onload="sceneStart();"> 
 
    <canvas id="glow-canvas" style="border: none;" width="512" height="512"></canvas> 
 
</body>

0

<!doctype html> 
 
<html> 
 
\t <head> 
 
\t \t <meta charset="utf-8"> 
 
\t \t <style> 
 
\t \t \t body { 
 
\t \t \t \t background-color: black; 
 
\t \t \t } 
 
\t \t \t 
 
\t \t \t canvas { 
 
\t \t \t \t position: absolute; 
 
\t \t \t \t margin-left: auto; 
 
\t \t \t \t margin-right: auto; 
 
\t \t \t \t left: 0; 
 
\t \t \t \t right: 0; 
 
\t \t \t \t border: solid 1px white; 
 
\t \t \t \t border-radius: 10px; 
 
\t \t \t } 
 
\t \t </style> 
 
\t \t 
 
\t \t <canvas id="canvas"></canvas> 
 
\t \t <script type="application/javascript"> 
 
\t \t 
 
\t \t var imageWidth = 180; 
 
\t \t var imageHeight = 160; 
 
\t \t var canvas = null; 
 
\t \t var gl = null; 
 
\t \t var indexBuffer = null; // element array buffer 
 
\t \t var vertexBuffer = null; // array buffer 
 
\t \t var program = null; 
 
\t \t var uAngle = null; 
 
\t \t 
 
\t \t var circleAngle = 0.0; 
 
\t \t var circleRadius = 0.75; 
 
\t \t var circleVertexCount = 5; // No of verticies going around the circle's edge 
 
\t \t 
 
\t \t // ES6 has handy dandy `` syntax for strings, they allow for multiple lines. 
 
\t \t var vsCode = ` 
 
\t \t \t precision lowp float; 
 
\t \t \t 
 
\t \t \t attribute vec2 aPosition; 
 
\t \t \t attribute vec3 aColour; 
 
\t \t \t 
 
\t \t \t varying vec3 vColour; 
 
\t \t \t 
 
\t \t \t uniform float uAngle; 
 
\t \t \t 
 
\t \t \t void main() { 
 
\t \t \t \t float s = sin(uAngle); 
 
\t \t \t \t float c = cos(uAngle); 
 
\t \t \t \t mat2 rot = mat2(
 
\t \t \t \t \t c,-s, 
 
\t \t \t \t \t s,c 
 
\t \t \t \t); 
 
\t \t \t \t 
 
\t \t \t \t vColour = aColour; 
 
\t \t \t \t gl_Position = vec4(rot * aPosition,0.0,1.0); 
 
\t \t \t } 
 
\t \t `; 
 
\t \t 
 
\t \t var fsCode = ` 
 
\t \t \t precision lowp float; 
 
\t \t \t 
 
\t \t \t varying vec3 vColour; 
 
\t \t \t 
 
\t \t \t void main() { 
 
\t \t \t \t gl_FragColor = vec4(vColour,1.0); 
 
\t \t \t } 
 
\t \t `; 
 
\t \t 
 
\t \t function loop() { 
 
\t \t \t circleAngle += 0.05; 
 
\t \t \t if (circleAngle > 2.0 * Math.PI) { circleAngle = 0.0; } 
 
\t \t \t gl.uniform1f(uAngle,circleAngle); 
 
\t \t \t 
 
\t \t \t gl.clear(gl.COLOR_BUFFER_BIT); 
 
\t \t \t gl.drawElements(gl.TRIANGLES,circleVertexCount * 3,gl.UNSIGNED_SHORT,0); 
 
\t \t \t requestAnimationFrame(loop); 
 
\t \t } 
 
\t \t 
 
\t \t window.onload = function() { 
 
\t \t \t canvas = document.getElementById("canvas"); 
 
\t \t \t canvas.width = imageWidth; 
 
\t \t \t canvas.height = imageHeight; 
 
\t \t \t 
 
\t \t \t gl = canvas.getContext("webgl") || console.error("Couldn't get WebGL context"); 
 
\t \t \t gl.clearColor(0.5,0.5,0.5,1.0); 
 
\t \t \t 
 
\t \t \t // generate verticies 
 
\t \t \t // There will be one vertex in the center of the circle, 
 
\t \t \t // with the rest covering the outer edge. 
 
\t \t \t // vec2 + vec3 per vertex = 5 floats per vertex 
 
\t \t \t var circleVerticies = new Float32Array(circleVertexCount * 5 + 5); 
 
\t \t \t 
 
\t \t \t // add an extra point for the center 
 
\t \t \t 
 
\t \t \t // position 
 
\t \t \t circleVerticies[0] = 0.0; 
 
\t \t \t circleVerticies[1] = 0.0; 
 
\t \t \t 
 
\t \t \t // colour 
 
\t \t \t circleVerticies[2] = 0.5; 
 
\t \t \t circleVerticies[3] = 0.5; 
 
\t \t \t circleVerticies[4] = 0.5; 
 
\t \t \t 
 
\t \t \t for (
 
\t \t \t \t var i = 5, angle = 0.0; 
 
\t \t \t \t i < circleVerticies.length; 
 
\t \t \t \t i += 5, angle += (2.0 * Math.PI)/circleVertexCount 
 
\t \t \t) { 
 
\t \t \t \t // position 
 
\t \t \t \t circleVerticies[i ] = Math.sin(angle) * circleRadius; 
 
\t \t \t \t circleVerticies[i+1] = Math.cos(angle) * circleRadius; 
 
\t \t \t \t 
 
\t \t \t \t // colour 
 
\t \t \t \t circleVerticies[i+2] = Math.random(); 
 
\t \t \t \t circleVerticies[i+3] = Math.random(); 
 
\t \t \t \t circleVerticies[i+4] = Math.random(); 
 
\t \t \t } 
 
\t \t \t 
 
\t \t \t // generate indexes 
 
\t \t \t var circleIndicies = new Uint16Array(circleVertexCount * 3); 
 
\t \t \t 
 
\t \t \t for (var i = 0, j = 1; i < circleIndicies.length - 3; i += 3, ++j) { 
 
\t \t \t \t circleIndicies[i ] = 0; 
 
\t \t \t \t circleIndicies[i+1] = j; 
 
\t \t \t \t circleIndicies[i+2] = j + 1; 
 
\t \t \t } 
 
\t \t \t 
 
\t \t \t // Last triangle to connect the edge to the start 
 
\t \t \t /* 
 
\t \t \t \t  |\ 
 
\t \t \t \t > | \ 
 
\t \t \t \t --- | 
 
\t \t \t \t \ /
 
\t \t \t \t \/
 
\t \t \t */ 
 
\t \t \t circleIndicies[circleIndicies.length - 3] = 0; 
 
\t \t \t circleIndicies[circleIndicies.length - 2] = j; 
 
\t \t \t circleIndicies[circleIndicies.length - 1] = 1; 
 
\t \t \t 
 
\t \t \t // upload buffers to gpu 
 
\t \t \t vertexBuffer = gl.createBuffer(); 
 
\t \t \t gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer); 
 
\t \t \t gl.bufferData(gl.ARRAY_BUFFER,circleVerticies,gl.STATIC_DRAW); 
 
\t \t \t 
 
\t \t \t indexBuffer = gl.createBuffer(); 
 
\t \t \t gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indexBuffer); 
 
\t \t \t gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,circleIndicies,gl.STATIC_DRAW); 
 
\t \t \t 
 
\t \t \t // create program 
 
\t \t \t var vertexShader = gl.createShader(gl.VERTEX_SHADER); 
 
\t \t \t var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); 
 
\t \t \t 
 
\t \t \t gl.shaderSource(vertexShader,vsCode); 
 
\t \t \t gl.shaderSource(fragmentShader,fsCode); 
 
\t \t \t gl.compileShader(vertexShader); 
 
\t \t \t gl.compileShader(fragmentShader); 
 
\t \t \t 
 
\t \t \t console.log(gl.getShaderInfoLog(vertexShader)); 
 
\t \t \t console.log(gl.getShaderInfoLog(fragmentShader)); 
 
\t \t \t 
 
\t \t \t program = gl.createProgram(); 
 
\t \t \t gl.attachShader(program,vertexShader); 
 
\t \t \t gl.attachShader(program,fragmentShader); 
 
\t \t \t gl.linkProgram(program); 
 
\t \t \t gl.deleteShader(vertexShader); 
 
\t \t \t gl.deleteShader(fragmentShader); 
 
\t \t \t 
 
\t \t \t uAngle = gl.getUniformLocation(program,"uAngle"); 
 
\t \t \t 
 
\t \t \t // set state for rendering 
 
\t \t \t gl.useProgram(program); 
 
\t \t \t 
 
\t \t \t gl.vertexAttribPointer(
 
\t \t \t \t 0, // attrib location 
 
\t \t \t \t 2, // attrib size 
 
\t \t \t \t gl.FLOAT, // value type 
 
\t \t \t \t gl.FALSE, // normalize? 
 
\t \t \t \t 5 * Float32Array.BYTES_PER_ELEMENT, // total vertex size in bytes (5 * 4) 
 
\t \t \t \t 0 * Float32Array.BYTES_PER_ELEMENT // offset from the start of the vertex in bytes 
 
\t \t \t); 
 
\t \t \t 
 
\t \t \t gl.vertexAttribPointer(
 
\t \t \t \t 1, // attrib location 
 
\t \t \t \t 3, // attrib size 
 
\t \t \t \t gl.FLOAT, // value type 
 
\t \t \t \t gl.FALSE, // normalize? 
 
\t \t \t \t 5 * Float32Array.BYTES_PER_ELEMENT, // total vertex size in bytes (5 * 4) 
 
\t \t \t \t 2 * Float32Array.BYTES_PER_ELEMENT // offset from the start of the vertex in bytes 
 
\t \t \t); 
 
\t \t \t 
 
\t \t \t // Enable these attributes on the bound buffer for use 
 
\t \t \t gl.enableVertexAttribArray(0); 
 
\t \t \t gl.enableVertexAttribArray(1); 
 
\t \t \t 
 
\t \t \t requestAnimationFrame(loop); 
 
\t \t } 
 
\t \t 
 
\t \t window.onunload = function() { 
 
\t \t \t gl.deleteBuffer(indexBuffer); 
 
\t \t \t gl.deleteBuffer(vertexBuffer); 
 
\t \t \t gl = null; 
 
\t \t } 
 
\t \t 
 
\t \t </script> 
 
\t </head> 
 
</html>