mirror of
https://github.com/greggman/twgl.js.git
synced 2026-02-01 16:00:22 +00:00
360 lines
12 KiB
HTML
360 lines
12 KiB
HTML
<!DOCTYPE html>
|
|
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>TWGL Index</title>
|
|
|
|
<!--[if lt IE 9]>
|
|
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
<![endif]-->
|
|
<link type="text/css" rel="stylesheet" href="styles/sunlight.default.css">
|
|
|
|
<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>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>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>Compare the code for a point lit cube.</p>
|
|
<h3>Compiling a Shader and looking up locations</h3>
|
|
<p>TWGL</p>
|
|
<pre><code>var programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);</code></pre>
|
|
<p>WebGL</p>
|
|
<pre><code>// Note: I'm conceding that you'll likely already have the 30 lines of
|
|
// code for compiling GLSL
|
|
var program = twgl.createProgramFromScripts(gl, ["vs", "fs"]);
|
|
|
|
var u_lightWorldPosLoc = gl.getUniformLocation(program, "u_lightWorldPos");
|
|
var u_lightColorLoc = gl.getUniformLocation(program, "u_lightColor");
|
|
var u_ambientLoc = gl.getUniformLocation(program, "u_ambient");
|
|
var u_specularLoc = gl.getUniformLocation(program, "u_specular");
|
|
var u_shininessLoc = gl.getUniformLocation(program, "u_shininess");
|
|
var u_specularFactorLoc = gl.getUniformLocation(program, "u_specularFactor");
|
|
var u_diffuseLoc = gl.getUniformLocation(program, "u_diffuse");
|
|
var u_worldLoc = gl.getUniformLocation(program, "u_world");
|
|
var u_worldInverseTransposeLoc = gl.getUniformLocation(program, "u_worldInverseTranspose");
|
|
var u_worldViewProjectionLoc = gl.getUniformLocation(program, "u_worldViewProjection");
|
|
var u_viewInverseLoc = gl.getUniformLocation(program, "u_viewInverse");
|
|
|
|
var positionLoc = gl.getAttribLocation(program, "a_position");
|
|
var normalLoc = gl.getAttribLocation(program, "a_normal");
|
|
var texcoordLoc = gl.getAttribLocation(program, "a_texcoord");</code></pre>
|
|
<h3>Creating Buffers for a Cube</h3>
|
|
<p>TWGL</p>
|
|
<pre><code>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>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>twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);</code></pre>
|
|
<p>WebGL</p>
|
|
<pre><code>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>// 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>// 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>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>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>Docs</h2>
|
|
<p><a href="http://twgljs.org/docs/">Docs are here</a>.</p>
|
|
<h2>Rational 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>.</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>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);</code></pre>
|
|
<p><code>setAttributes</code> is just the simplest code to do that for you.</p>
|
|
<pre><code>// make attributes for TWGL manually
|
|
var attribs = {
|
|
a_position: { buffer: positionBuffer, size: 3 },
|
|
a_normal: { buffer: normalBuffer, size: 3 },
|
|
a_texcoord: { buffer: texcoord: size: 2, },
|
|
};
|
|
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.</p>
|
|
<h2>Future</h2>
|
|
<ul>
|
|
<li>What needs to change for WebGL 2.0?</li>
|
|
<li>Consider adding texture related stuff<ul>
|
|
<li>loading a list of textures from URLs</li>
|
|
<li>setting filtering for NPOT</li>
|
|
</ul>
|
|
</li>
|
|
<li>Consider adding framebuffer related stuff</li>
|
|
</ul></article>
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
<div class="clearfix"></div>
|
|
<footer>
|
|
|
|
|
|
<span class="copyright">
|
|
copyright Gregg Tavares
|
|
</span>
|
|
<br />
|
|
|
|
<span class="jsdoc-message">
|
|
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.2</a>
|
|
on Tue Mar 31st 2015 using the <a
|
|
href="https://github.com/terryweiss/docstrap">DocStrap template</a>.
|
|
</span>
|
|
</footer>
|
|
</div>
|
|
|
|
|
|
<div class="span3">
|
|
<div id="toc"></div>
|
|
</div>
|
|
|
|
<br clear="both">
|
|
</div>
|
|
|
|
</div>
|
|
<!--<script src="scripts/sunlight.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( "$", "__" ) );
|
|
} );
|
|
|
|
$( "#toc" ).toc( {
|
|
anchorName : function ( i, heading, prefix ) {
|
|
return $( heading ).attr( "id" ) || ( prefix + i );
|
|
},
|
|
selectors : "h1,h2,h3,h4",
|
|
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" ).addClass( "sunlight-highlight-javascript" ).addClass( "linenums" );
|
|
|
|
$( ".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( "sunlight-highlight-" + lang )
|
|
.addClass( "linenums" )
|
|
.html( example.html() );
|
|
|
|
}
|
|
} );
|
|
|
|
Sunlight.highlightAll( {
|
|
lineNumbers : true,
|
|
showMenu : true,
|
|
enableDoclinks : true
|
|
} );
|
|
} );
|
|
</script>
|
|
|
|
|
|
|
|
<!--Navigation and Symbol Display-->
|
|
|
|
|
|
|
|
<!--Google Analytics-->
|
|
|
|
|
|
</body>
|
|
</html> |