twgl.js/docs/index.html
2015-10-09 18:14:43 +03:00

600 lines
22 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>TWGL Index</title>
<link type="text/css" rel="stylesheet" href="styles/site.cerulean.css">
</head>
<body>
<div class="container-fluid">
<div class="navbar navbar-fixed-top navbar-inverse">
<div class="navbar-inner">
<a class="brand" href="index.html">TWGL</a>
<ul class="nav">
<li class="dropdown">
<a href="modules.list.html" class="dropdown-toggle" data-toggle="dropdown">Modules<b
class="caret"></b></a>
<ul class="dropdown-menu ">
<li>
<a href="module-twgl.html">twgl</a>
</li>
<li>
<a href="m4.html">twgl/m4</a>
</li>
<li>
<a href="primitives.html">twgl/primitives</a>
</li>
<li>
<a href="v3.html">twgl/v3</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
<div class="row-fluid">
<div class="span8">
<div id="main">
<span class="page-title">Index</span>
<section class="readme-section">
<article><h1>TWGL: A Tiny WebGL helper Library<div id="pronouce">[rhymes with wiggle]</div></h1>
<p><a href="https://travis-ci.org/greggman/twgl.js"><img src="https://travis-ci.org/greggman/twgl.js.svg?branch=master" alt="Build Status"></a></p>
<p>This library's sole purpose is to make using the WebGL API less verbose.</p>
<h2>TL;DR</h2>
<p>If you want to get shit done use <a href="http://threejs.org">three.js</a>. If you want
to do stuff low-level with WebGL consider using <a href="http://github.com/greggman/twgl.js/">TWGL</a>.</p>
<h2>The tiniest example</h2>
<p>Not including the shaders (which is a simple quad shader) here's the entire code</p>
<pre><code class="lang-html">&lt;canvas id=&quot;c&quot;&gt;&lt;/canvas&gt;
&lt;script src=&quot;../dist/twgl-full.min.js&quot;&gt;&lt;/script&gt;
&lt;script&gt;
var gl = twgl.getWebGLContext(document.getElementById(&quot;c&quot;));
var programInfo = twgl.createProgramInfo(gl, [&quot;vs&quot;, &quot;fs&quot;]);
var arrays = {
position: [-1, -1, 0, 1, -1, 0, -1, 1, 0, -1, 1, 0, 1, -1, 0, 1, 1, 0],
};
var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);
function render(time) {
twgl.resizeCanvasToDisplaySize(gl.canvas);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
var uniforms = {
time: time * 0.001,
resolution: [gl.canvas.width, gl.canvas.height],
};
gl.useProgram(programInfo.program);
twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
twgl.setUniforms(programInfo, uniforms);
twgl.drawBufferInfo(gl, gl.TRIANGLES, bufferInfo);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
&lt;/script&gt;</code></pre>
<p><a href="http://twgljs.org/examples/tiny.html">And here it is live</a>.</p>
<h2>Why? What? How?</h2>
<p>WebGL is a very verbose API. Setting up shaders, buffers, attributes and uniforms
takes a lot of code. A simple lit cube in WebGL might easily take over 60 calls into WebGL.</p>
<p>At its core there's really only a few main functions</p>
<ul>
<li><code>twgl.createProgramInfo</code> compiles a shader and creates setters for attribs and uniforms</li>
<li><code>twgl.createBufferInfoFromArrays</code> creates buffers and attribute settings</li>
<li><code>twgl.setBuffersAndAttributes</code> binds buffers and sets attributes</li>
<li><code>twgl.setUniforms</code> sets the uniforms</li>
<li><code>twgl.createTextures</code> creates textures of various sorts</li>
</ul>
<p>There's a few extra helpers and lower-level functions if you need them but those 5 functions are the core of TWGL.</p>
<p>Compare the TWGL vs WebGL code for a point lit cube.</p>
<h3>Compiling a Shader and looking up locations</h3>
<p>TWGL</p>
<pre><code class="lang-javascript">var programInfo = twgl.createProgramInfo(gl, [&quot;vs&quot;, &quot;fs&quot;]);</code></pre>
<p>WebGL</p>
<pre><code class="lang-javascript">// Note: I'm conceding that you'll likely already have the 30 lines of
// code for compiling GLSL
var program = twgl.createProgramFromScripts(gl, [&quot;vs&quot;, &quot;fs&quot;]);
var u_lightWorldPosLoc = gl.getUniformLocation(program, &quot;u_lightWorldPos&quot;);
var u_lightColorLoc = gl.getUniformLocation(program, &quot;u_lightColor&quot;);
var u_ambientLoc = gl.getUniformLocation(program, &quot;u_ambient&quot;);
var u_specularLoc = gl.getUniformLocation(program, &quot;u_specular&quot;);
var u_shininessLoc = gl.getUniformLocation(program, &quot;u_shininess&quot;);
var u_specularFactorLoc = gl.getUniformLocation(program, &quot;u_specularFactor&quot;);
var u_diffuseLoc = gl.getUniformLocation(program, &quot;u_diffuse&quot;);
var u_worldLoc = gl.getUniformLocation(program, &quot;u_world&quot;);
var u_worldInverseTransposeLoc = gl.getUniformLocation(program, &quot;u_worldInverseTranspose&quot;);
var u_worldViewProjectionLoc = gl.getUniformLocation(program, &quot;u_worldViewProjection&quot;);
var u_viewInverseLoc = gl.getUniformLocation(program, &quot;u_viewInverse&quot;);
var positionLoc = gl.getAttribLocation(program, &quot;a_position&quot;);
var normalLoc = gl.getAttribLocation(program, &quot;a_normal&quot;);
var texcoordLoc = gl.getAttribLocation(program, &quot;a_texcoord&quot;);</code></pre>
<h3>Creating Buffers for a Cube</h3>
<p>TWGL</p>
<pre><code class="lang-javascript">var arrays = {
position: [1,1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1],
normal: [1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1],
texcoord: [1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1],
indices: [0,1,2,0,2,3,4,5,6,4,6,7,8,9,10,8,10,11,12,13,14,12,14,15,16,17,18,16,18,19,20,21,22,20,22,23],
};
var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);</code></pre>
<p>WebGL</p>
<pre><code class="lang-javascript">var positions = [1,1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1];
var normals = [1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1];
var texcoords = [1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1];
var indices = [0,1,2,0,2,3,4,5,6,4,6,7,8,9,10,8,10,11,12,13,14,12,14,15,16,17,18,16,18,19,20,21,22,20,22,23];
var positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
var normalBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normals), gl.STATIC_DRAW);
var texcoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texcoords), gl.STATIC_DRAW);
var indicesBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indicesBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);</code></pre>
<h3>Setting Attributes and Indices for a Cube</h3>
<p>TWGL</p>
<pre><code class="lang-javascript">twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);</code></pre>
<p>WebGL</p>
<pre><code class="lang-javascript">gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(positionLoc, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionLoc);
gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(normalLoc);
gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
gl.vertexAttribPointer(texcoordLoc, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(texcoordLoc);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indicesBuffer);</code></pre>
<h3>Setting Uniforms for a Lit Cube</h3>
<p>TWGL</p>
<pre><code class="lang-javascript">// At Init time
var uniforms = {
u_lightWorldPos: [1, 8, -10],
u_lightColor: [1, 0.8, 0.8, 1],
u_ambient: [0, 0, 0, 1],
u_specular: [1, 1, 1, 1],
u_shininess: 50,
u_specularFactor: 1,
u_diffuse: tex,
};
// At render time
uniforms.u_viewInverse = camera;
uniforms.u_world = world;
uniforms.u_worldInverseTranspose = m4.transpose(m4.inverse(world));
uniforms.u_worldViewProjection = m4.multiply(world, viewProjection);
twgl.setUniforms(programInfo, uniforms);</code></pre>
<p>WebGL</p>
<pre><code class="lang-javascript">// At Init time
var u_lightWorldPos = [1, 8, -10];
var u_lightColor = [1, 0.8, 0.8, 1];
var u_ambient = [0, 0, 0, 1];
var u_specular = [1, 1, 1, 1];
var u_shininess = 50;
var u_specularFactor = 1;
var u_diffuse = 0;
// At render time
gl.uniform3fv(u_lightWorldPosLoc, u_lightWorldPos);
gl.uniform4fv(u_lightColorLoc, u_lightColor);
gl.uniform4fv(u_ambientLoc, u_ambient);
gl.uniform4fv(u_specularLoc, u_specular);
gl.uniform1f(u_shininessLoc, u_shininess);
gl.uniform1f(u_specularFactorLoc, u_specularFactor);
gl.uniform1i(u_diffuseLoc, u_diffuse);
gl.uniformMatrix4fv(u_viewInverseLoc, false, camera);
gl.uniformMatrix4fv(u_worldLoc, false, world);
gl.uniformMatrix4fv(u_worldInverseTransposeLoc, false, m4.transpose(m4.inverse(world)));
gl.uniformMatrix4fv(u_worldViewProjectionLoc, false, m4.multiply(world, viewProjection));</code></pre>
<h3>Loading / Setting up textures</h3>
<p>TWGL</p>
<pre><code class="lang-javascript">var textures = twgl.createTextures(gl, {
// a power of 2 image
hftIcon: { src: &quot;images/hft-icon-16.png&quot;, mag: gl.NEAREST },
// a non-power of 2 image
clover: { src: &quot;images/clover.jpg&quot; },
// From a canvas
fromCanvas: { src: ctx.canvas },
// A cubemap from 6 images
yokohama: {
target: gl.TEXTURE_CUBE_MAP,
src: [
'images/yokohama/posx.jpg',
'images/yokohama/negx.jpg',
'images/yokohama/posy.jpg',
'images/yokohama/negy.jpg',
'images/yokohama/posz.jpg',
'images/yokohama/negz.jpg',
],
},
// A cubemap from 1 image (can be 1x6, 2x3, 3x2, 6x1)
goldengate: {
target: gl.TEXTURE_CUBE_MAP,
src: 'images/goldengate.jpg',
},
// A 2x2 pixel texture from a JavaScript array
checker: {
mag: gl.NEAREST,
min: gl.LINEAR,
src: [
255,255,255,255,
192,192,192,255,
192,192,192,255,
255,255,255,255,
],
},
// a 1x8 pixel texture from a typed array.
stripe: {
mag: gl.NEAREST,
min: gl.LINEAR,
format: gl.LUMINANCE,
src: new Uint8Array([
255,
128,
255,
128,
255,
128,
255,
128,
]),
width: 1,
},
});</code></pre>
<p>WebGL</p>
<pre><code class="lang-javascript">// Let's assume I already loaded all the images
// a power of 2 image
var hftIconTex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, hftIconImg);
gl.generateMipmaps(gl.TEXTURE_2D);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
// a non-power of 2 image
var cloverTex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, hftIconImg);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
// From a canvas
var cloverTex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, ctx.canvas);
gl.generateMipmaps(gl.TEXTURE_2D);
// A cubemap from 6 images
var yokohamaTex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, posXImg);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, negXImg);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, posYImg);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, negYImg);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, posZImg);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, negZImg);
gl.generateMipmaps(gl.TEXTURE_CUBE_MAP);
// A cubemap from 1 image (can be 1x6, 2x3, 3x2, 6x1)
var goldengateTex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
var size = goldengate.width / 3; // assume it's a 3x2 texture
var slices = [0, 0, 1, 0, 2, 0, 0, 1, 1, 1, 2, 1];
var tempCtx = document.createElement(&quot;canvas&quot;).getContext(&quot;2d&quot;);
tempCtx.canvas.width = size;
tempCtx.canvas.height = size;
for (var ii = 0; ii &lt; 6; ++ii) {
var xOffset = slices[ii * 2 + 0] * size;
var yOffset = slices[ii * 2 + 1] * size;
tempCtx.drawImage(element, xOffset, yOffset, size, size, 0, 0, size, size);
gl.texImage2D(faces[ii], 0, format, format, type, tempCtx.canvas);
}
gl.generateMipmaps(gl.TEXTURE_CUBE_MAP);
// A 2x2 pixel texture from a JavaScript array
var checkerTex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([
255,255,255,255,
192,192,192,255,
192,192,192,255,
255,255,255,255,
]));
gl.generateMipmaps(gl.TEXTURE_2D);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
// a 1x8 pixel texture from a typed array.
var stripeTex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, gl.LUMINANCE, gl.UNSIGNED_BYTE, new Uint8Array([
255,
128,
255,
128,
255,
128,
255,
128,
]));
gl.generateMipmaps(gl.TEXTURE_2D);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);</code></pre>
<h3>Creating Framebuffers and attachments</h3>
<p>TWGL</p>
<pre><code class="lang-javascript">var attachments = [
{ format: RGBA, type: UNSIGNED_BYTE, min: LINEAR, wrap: CLAMP_TO_EDGE },
{ format: DEPTH_STENCIL, },
];
var fbi = twgl.createFramebufferInfo(gl, attachments);</code></pre>
<p>WebGL</p>
<pre><code class="lang-javascript">var fb = gl.createFramebuffer(gl.FRAMEBUFFER);
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.drawingBufferWidth, gl.drawingBufferHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
var rb = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, rb);</code></pre>
<h3>Compare</h3>
<p><a href="http://twgljs.org/examples/twgl-cube.html">TWGL example</a> vs <a href="http://twgljs.org/examples/webgl-cube.html">WebGL example</a></p>
<h2>Examples</h2>
<ul>
<li><a href="http://twgljs.org/examples/tiny.html">tiny</a></li>
<li><a href="http://twgljs.org/examples/twgl-cube.html">twgl cube</a></li>
<li><a href="http://twgljs.org/examples/textures.html">textures</a></li>
<li><a href="http://twgljs.org/examples/primitives.html">primitives</a></li>
<li><a href="http://twgljs.org/examples/2d-lines.html">2d-lines</a></li>
<li><a href="http://twgljs.org/examples/dynamic-buffers.html">dynamic-buffers</a></li>
<li><a href="http://twgljs.org/examples/zoom-around.html">zoom-around</a></li>
<li><a href="http://twgljs.org/examples/text.html">text</a></li>
<li><a href="http://twgljs.org/examples/kaleidoscope.html">kaleidoscope</a></li>
<li><a href="http://twgljs.org/examples/tunnel.html">tunnel</a></li>
<li><a href="http://twgljs.org/examples/itemlist.html">item list</a></li>
<li><a href="http://twgljs.org/examples/no-box-skybox.html">no box skybox</a></li>
</ul>
<h2>AMD support</h2>
<ul>
<li><a href="http://twgljs.org/examples/amd.html">amd</a></li>
<li><a href="http://twgljs.org/examples/amd-compiled.html">amd-compiled</a></li>
</ul>
<h2>CommonJS / Browserify support</h2>
<ul>
<li><a href="http://twgljs.org/examples/browserify.html">browserify</a></li>
</ul>
<h2>Other Features</h2>
<ul>
<li><p>Includes some optional 3d math functions (full version)</p>
<p>You are welcome to use any math library as long as it stores matrices as flat Float32Array
or JavaScript arrays.</p>
</li>
<li><p>Includes some optional primitive generators (full version)</p>
<p>planes, cubes, spheres, ... Just to help get started</p>
</li>
</ul>
<h2>Usage</h2>
<p>See the examples. Otherwise there's a few different versions</p>
<ul>
<li><code>twgl-full.min.js</code> the minified full version</li>
<li><code>twgl-full.js</code> the concatinated full version</li>
<li><code>twgl.min.js</code> the minimum version (no 3d math, no primitives)</li>
<li><code>twgl.js</code> the concatinated minimum version (no 3d math, no primitives)</li>
</ul>
<h2>API Docs</h2>
<p><a href="http://twgljs.org/docs/">API Docs are here</a>.</p>
<h2>Download</h2>
<ul>
<li><p>from github</p>
<p><a href="http://github.com/greggman/twgl.js"><a href="http://github.com/greggman/twgl.js">http://github.com/greggman/twgl.js</a></a></p>
</li>
<li><p>from bower</p>
<pre><code class="lang-bash">bower install twgl.js</code></pre>
</li>
<li><p>from git</p>
<pre><code class="lang-bash">git clone https://github.com/greggman/twgl.js.git</code></pre>
</li>
</ul>
<h2>Rationale and other chit-chat</h2>
<p>TWGL's is an attempt to make WebGL simpler by providing a few tiny helper functions
that make it much less verbose and remove the tedium. TWGL is <strong>NOT</strong> trying to help
with the complexity of managing shaders and writing GLSL. Nor is it a 3D library like
<a href="http://threejs.org">three.js</a>. It's just trying to make WebGL less verbose.</p>
<p>TWGL can be considered a spiritual successor to <a href="http://github.com/greggman/tdl">TDL</a>. Where
as TDL created several <em>classes</em> that wrapped WebGL, TWGL tries not to wrap anything. In fact
you can manually create nearly all TWGL data structures.</p>
<p>For example the function <code>setAttributes</code> takes an object of attributes.
In WebGL you might write code like this</p>
<pre><code class="lang-javascript">gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(positionLoc, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionLoc);
gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(normalLoc);
gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
gl.vertexAttribPointer(texcoordLoc, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(texcoordLoc);
gl.bindBuffer(gl.ARRAY_BUFFER, colorsBuffer);
gl.vertexAttribPointer(colorLoc, 4, gl.UNSIGNED_BYTE, true, 0, 0);
gl.enableVertexAttribArray(colorLoc);</code></pre>
<p><code>setAttributes</code> is just the simplest code to do that for you.</p>
<pre><code class="lang-javascript">// make attributes for TWGL manually
var attribs = {
a_position: { buffer: positionBuffer, size: 3, },
a_normal: { buffer: normalBuffer, size: 3, },
a_texcoord: { buffer: texcoordBuffer, size: 2, },
a_color: { buffer: colorBuffer, size: 4, type: gl.UNSIGNED_BYTE, normalize: true, },
};
setAttributes(attribSetters, attribs);</code></pre>
<p>The point of the example above is TWGL is a <strong>thin</strong> wrapper. All it's doing is trying
to make common WebGL operations easier and less verbose. Feel free to mix it with raw WebGL.</p>
<h2>Want to learn WebGL?</h2>
<p>Try <a href="http://webglfundamentals.org">webglfundamentals.org</a></p>
<h2>Future</h2>
<ul>
<li>What needs to change for WebGL 2.0?</li>
</ul></article>
</section>
</div>
<div class="clearfix"></div>
<footer>
</footer>
</div>
<div class="span3">
<div id="toc"></div>
</div>
<br clear="both">
</div>
</div>
<script src="scripts/prettify/prettify.js"></script>
<script src="scripts/docstrap.lib.js"></script>
<script src="scripts/bootstrap-dropdown.js"></script>
<script src="scripts/toc.js"></script>
<script>
$( function () {
$( "[id*='$']" ).each( function () {
var $this = $( this );
$this.attr( "id", $this.attr( "id" ).replace( "$", "__" ) );
} );
$(".dropdown-menu a").each(function() {
var text = $(this).text();
$(this).text(text.replace(/\//g, '.'));
});
$( "#toc" ).toc( {
showAndHide : false,
scrollTo : "100px"
} );
$( "#toc>ul" ).addClass( "nav nav-pills nav-stacked" );
$( "#main span[id^='toc']" ).addClass( "toc-shim" );
$( '.dropdown-toggle' ).dropdown();
$( ".tutorial-section pre, .readme-section pre" ).each( function () {
var $this = $( this );
var example = $this.find( "code" );
exampleText = example.html();
var lang = /{@lang (.*?)}/.exec( exampleText );
if ( lang && lang[1] ) {
exampleText = exampleText.replace( lang[0], "" );
example.html( exampleText );
lang = lang[1];
} else {
lang = "javascript";
}
if ( lang ) {
$this
.addClass( "prettyprint" )
.html( example.html() );
}
} );
$('pre>code')
.unwrap()
.replaceWith(function() {
return $('<pre class="prettyprint showlinemods">' + this.innerHTML + '</pre>')
});
prettyPrint();
} );
</script>
<!--Navigation and Symbol Display-->
<!--Google Analytics-->
<script>
(function ( i, s, o, g, r, a, m ) {
i['GoogleAnalyticsObject'] = r;
i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push( arguments )
}, i[r].l = 1 * new Date();
a = s.createElement( o ),
m = s.getElementsByTagName( o )[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore( a, m )
})( window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga' );
ga( 'create', 'UA-61260681-1', 'auto' );
ga( 'send', 'pageview' );
</script>
</body>
</html>