Things are shaping up.
The HTML file:
<html>
<head>
<script id="vertex-shader" type="x-shader/x-vertex" >
attribute vec4 aPosition;
attribute vec3 aBC;
uniform mat4 uTransform;
varying vec3 vBC;
void main() {
gl_Position = uTransform * aPosition;
vBC = aBC;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
#extension GL_OES_standard_derivatives : enable
precision mediump float;
varying vec3 vBC;
float edgeFactor(){
vec3 d = fwidth(vBC);
vec3 a3 = smoothstep(vec3(0.0), d*1.5, vBC);
return min(min(a3.x, a3.y), a3.z);
}
void main(){
if (gl_FrontFacing) {
gl_FragColor = vec4(0.0, 0.0, 0.0, (1.0-edgeFactor())*0.95);
} else {
discard;
}
}
</script>
<script type="text/javascript" src="../Common/webgl-utils.js"></script>
<script type="text/javascript" src="../Common/initShaders.js"></script>
<script type="text/javascript" src="../Common/MV.js"></script>
<script type="text/javascript" src="../Models/cone.js"></script>
<script type="text/javascript" src="../Models/cube.js"></script>
<script type="text/javascript" src="../Models/dragon.js"></script>
<script type="text/javascript" src="../Models/epcot.js"></script>
<script type="text/javascript" src="../Models/lizard.js"></script>
<script type="text/javascript" src="../Models/tank.js"></script>
<script type="text/javascript" src="../Models/teapot.js"></script>
<script type="text/javascript" src="../Models/butterfly.js"></script>
<script type="text/javascript" src="../Models/copter.js"></script>
<script type="text/javascript" src="../Models/enterprise.js"></script>
<script type="text/javascript" src="../Models/head.js"></script>
<script type="text/javascript" src="../Models/plane.js"></script>
<script type="text/javascript" src="../Models/xwing.js"></script>
<script type="text/javascript" src="../Models/stego.js"></script>
<script type="text/javascript" src="../Models/bunny.js"></script>
<script type="text/javascript" src="../Models/N64.js"></script>
<script type="text/javascript" src="../Models/cheetah.js"></script>
<script type="text/javascript" src="../Models/ganster.js"></script>
<script type="text/javascript" src="../Models/nightmare.js"></script>
<script type="text/javascript" src="../Models/skeleton.js"></script>
<script type="text/javascript" src="../Models/spider.js"></script>
<script type="text/javascript" src="../Models/womanInDress.js"></script>
<script type="text/javascript" src="basic.js"></script>
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>
</head>
<body>
<h1>Things are shaping up.</h1>
<script>
var canvas = new Canvas(500, 500);
models = [];
cube = new cubeModel();
models.push(cube);
cone = new coneModel();
models.push(cone);
dragon= new dragonModel();
models.push(dragon);
epcot= new epcotModel();
models.push(epcot);
lizard= new lizardModel();
models.push(lizard);
tank= new tankModel();
models.push(tank);
teapot= new teapotModel();
models.push(teapot);
butterfly = new butterflyModel();
models.push(butterfly);
copter = new copterModel();
models.push(copter);
enterprise = new enterpriseModel();
models.push(enterprise);
head = new headModel();
models.push(head);
plane = new planeModel();
models.push(plane);
xwing = new xwingModel();
models.push(xwing);
stego = new stegoModel();
models.push(stego);
bunny = new bunnyModel();
models.push(bunny);
N64 = new N64Model();
models.push(N64);
cheetah = new cheetahModel();
models.push(cheetah);
ganster = new gansterModel();
models.push(ganster);
nightmare = new nightmareModel();
models.push(nightmare);
skeleton = new skeletonModel();
models.push(skeleton);
spider = new spiderModel();
models.push(spider);
womanInDress = new womanInDressModel();
models.push(womanInDress);
canvas.SetModel(models[0]);
canvas.Redisplay();
// a function to chose which model we are looking at.
function NewModel(choice) {
console.log(choice);
canvas.SetModel(models[choice-1]);
canvas.Redisplay();
}
</script>
<p>
<select onchange="NewModel(this.value)">
<option value=1>Cube</option>
<option value=2>Cone</option>
<option value=3>Dragon</option>
<option value=4>Epcot</option>
<option value=5>lizard</option>
<option value=6>tank</option>
<option value=7>Teapot</option>
<option value=8>Butterfly</option>
<option value=9>Copter</option>
<option value=10>Enterprise</option>
<option value=11>Head</option>
<option value=12>Plane</option>
<option value=13>X-Wing</option>
<option value=14>Stego</option>
<option value=15>Bunny</option>
<option value=16>N64</option>
<option value=17>Cheetah</option>
<option value=18>Ganster</option>
<option value=19>Nightmare</option>
<option value=20>Skeleton</option>
<option value=21>Spider</option>
<option value=22>Woman In Dress</option>
</select>
</body>
The Javascript file:
'use strict';
function MakeCanvas(width, height, locID) {
if (width == undefined || width < 0) {
width = 300;
}
if (height == undefined || height < 0) {
height = 300;
}
var canvas = document.createElement('canvas')
canvas.tabIndex = 0;
canvas.height = height;
canvas.width = width;
canvas.style.border = "1px solid #0000FF";
if(locID == undefined) {
document.body.appendChild(canvas);
} else {
div = document.getElementById(locID);
if (null == div) {
document.body.appendChild(canvas);
} else {
div.appendChild(canvas);
}
}
document.body.appendChild(canvas);
return canvas;
}
function InitGL(canvas) {
var gl = WebGLUtils.setupWebGL(canvas,'OES_standard_derivatives');
if (!gl) {
alert ("WebGL isn't available");
}
// required to turn on fwidth and such.
gl.getExtension('OES_standard_derivatives');
return gl;
}
function Canvas(width, height, locID) {
var canvas = MakeCanvas(width, height, locID);
var gl = InitGL(canvas);
this.gl = gl;
var tmpCanvas = this;
this.x = canvas.offsetLeft;
this.y = canvas.offsetTop;
canvas.addEventListener("keypress",
function(evnt) {
tmpCanvas.KeyFunc(tmpCanvas, evnt);
}
);
gl.viewport(0,0, width, height);
var program = initShaders(gl, "vertex-shader","fragment-shader");
gl.useProgram(program);
this.vPos = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.vPos);
var vPos = gl.getAttribLocation(program, "aPosition");
gl.vertexAttribPointer(vPos,3,gl.FLOAT, false,0,0);
gl.enableVertexAttribArray(vPos);
this.vBC = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.vBC);
var vBC = gl.getAttribLocation(program, "aBC");
gl.vertexAttribPointer(vBC,3,gl.FLOAT, false,0,0);
gl.enableVertexAttribArray(vBC);
this.transformLoc = gl.getUniformLocation(program, "uTransform");
this.Init();
return this;
}
Canvas.prototype = {
Init: function() {
this.gl.clearColor(1.0, 1.0, 1.0, 1.0);
this.gl.enable(this.gl.BLEND);
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
this.gl.enable(this.gl.DEPTH_TEST);
this.gl.depthFunc(this.gl.LESS);
this.gl.depthMask(this.gl.TRUE);
this.shaderChoice = false;
this.gl.uniform1f(this.shaderLoc, 0.0);
this.Reset();
},
Reset: function() {
this.xr = 0;
this.yr = 0;
this.zr = 0;
this.gl.enable(this.gl.CULL_FACE);
this.gl.frontFace(this.gl.CCW);
this.gl.cullFace(this.gl.BACK);
},
SetModel: function(model) {
var gl = this.gl;
this.pointCount = model.Triangles.length;
// change the vertex data
gl.bindBuffer(gl.ARRAY_BUFFER, this.vBC);
gl.bufferData(gl.ARRAY_BUFFER,flatten(model.BC),gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, this.vPos);
gl.bufferData(gl.ARRAY_BUFFER,flatten(model.Triangles),gl.STATIC_DRAW);
},
KeyFunc: function(me, evnt) {
switch(evnt.key) {
case 'X': me.xr += -5; break;
case 'Y': me.yr += -5; break;
case 'Z': me.zr += -5; break;
case 'x': me.xr += 5; break;
case 'y': me.yr += 5; break;
case 'z': me.zr += 5; break;
case 'r': me.Reset(); break;
}
me.Redisplay();
},
Redisplay: function() {
var transform = mat4(1);
// this probably doesn't belong here
transform = mult(transform, rotate(this.xr, [1,0,0]));
transform = mult(transform, rotate(this.yr, [0,1,0]));
transform = mult(transform, rotate(this.zr, [0,0,1]));
this.gl.uniformMatrix4fv(this.transformLoc,false, flatten(transform ));
this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
if (this.pointCount > 0) {
this.gl.drawArrays(this.gl.TRIANGLES, 0, this.pointCount);
}
return;
}
};