The HTML file:
<html>
<head>
<script id="vertex-shader" type="x-shader/x-vertex" >
attribute vec4 vPosition;
attribute vec4 vColor;
varying vec4 color;
void main() {
float d = 0.2;
// send the new color down the pipeline
color = vColor;
// translate matrix
mat4 translate = mat4(
vec4(1.0, 0.0, 0.0, 0.0),
vec4(0.0, 1.0, 0.0, 0.0),
vec4(0.0, 0.0, 1.0, 0.0),
vec4(0.0, 0.25, 0.75, 1.0));
// pinhole camera projection matrix.
mat4 project = mat4(
vec4(1.0, 0.0, 0.0, 0.0),
vec4(0.0, 1.0, 0.0, 0.0),
vec4(0.0, 0.0, 0.0, 1.0/d),
vec4(0.0, 0.0, 0.0, 0.0));
// apply the transformations
gl_Position = project * translate * vPosition;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
precision highp float;
varying vec4 color;
void main(){
gl_FragColor = color;
}
</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="Widget.js"></script>
<script type="text/javascript" src="Program.js"></script>
<script type="text/javascript" src="GLCanvas.js"></script>
<body>
<script>
'use strict'
var canvas = new Canvas(500, 500,Keypress);
var Objects = [];
MakeItems();
Display();
</script>
</body>
GLCanvas.js
'use strict'
class Canvas {
constructor (width, height, Keypress) {
this.height = height;
this.width = width;
this.MakeCanvas();
this.canvas.addEventListener("keypress", Keypress);
this.SetupGL();
this.MakeShaders();
this.Init();
}
MakeCanvas() {
if (this.width == undefined || this.width < 0) {
this.width = 300;
}
if (this.height == undefined || this.height < 0) {
this.height = 300;
}
this.canvas = document.createElement('canvas')
this.canvas.tabIndex=0;
this.canvas.height = this.height;
this.canvas.width = this.width;
this.canvas.style="border:1px solid #000000;"
document.body.appendChild(this.canvas);
}
SetupGL() {
this.gl = WebGLUtils.setupWebGL(this.canvas);
if (!this.gl) {
alert ("WebGL isn't available");
return;
}
this.gl.getExtension('OES_standard_derivatives');
}
MakeShaders() {
this.program = initShaders(this.gl, "vertex-shader","fragment-shader");
this.gl.useProgram(this.program);
}
Init() {
this.gl.clearColor(1.0, 1.0, 1.0, 1.0);
this.gl.viewport(0,0, this.width, this.height);
}
Program() {
return this.program;
}
GL() {
return this.gl;
}
Clear() {
this.gl.clear(this.gl.COLOR_BUFFER_BIT);
}
};
Program.js
'use strict'
const RED = [1.0, 0.0, 0.0]
const GREEN = [0.0, 1.0, 0.0]
const CP1 = [-0.5, -0.5, -0.5]
const CP2 = [ 0.5, -0.5, -0.5]
const CP3 = [ 0.5, 0.5, -0.5]
const CP4 = [-0.5, 0.5, -0.5]
const CP5 = [-0.5, -0.5, 0.5]
const CP6 = [ 0.5, -0.5, 0.5]
const CP7 = [ 0.5, 0.5, 0.5]
const CP8 = [-0.5, 0.5, 0.5]
const CUBE=[
CP1, RED, CP2, RED, CP3, RED, CP4, RED, //front
CP1, RED, CP5, GREEN, CP8, GREEN, CP4, RED, // left
CP3, RED, CP7, GREEN, CP8, GREEN, //top
CP5, GREEN, CP6, GREEN, CP7, GREEN, // back
CP3, RED, CP2, RED, CP6, GREEN, //right
CP5, GREEN, CP1, RED // go home
];
const TP1 = [-0.5, -0.5, -0.5]
const TP2 = [0.5, -0.5, -0.5]
const TP3 = [0.0, -0.5, 0.5]
const TP4 = [0.0, 0.5, 0.0]
const TET=[ TP1, RED, TP2, RED, TP3, RED,
TP1, RED, TP2, RED, TP4, GREEN,
TP2, RED, TP3, RED, TP4, GREEN,
TP3, RED, TP1, RED, TP4, GREEN
];
function MakeItems() {
let cube = new Widget(canvas.GL(), canvas.Program(),
"vPosition", "vColor", CUBE);
let tet = new Widget(canvas.GL(), canvas.Program(),
"vPosition", "vColor", TET);
tet.Hide();
Objects.push(cube);
Objects.push(tet);
}
function Keypress(evnt) {
if (evnt.key >= '0' && evnt.key <= '9') {
ToggleItemVis(evnt.key-'0');
}
Display();
}
function ToggleItemVis(id) {
if (id < Objects.length) {
if (Objects[id].Visible() ) {
Objects[id].Hide();
} else {
Objects[id].Show();
}
}
}
function DisplayItem(item) {
item.Display(canvas.GL());
}
function Display() {
canvas.Clear();
Objects.forEach(DisplayItem);
}
Widget.js
'use strict'
class Widget {
constructor(gl, program, posName, colorName, edges) {
this.visible = true;
this.size = edges.length/2;
this.SetupVBO(gl, edges);
this.vpos = gl.getAttribLocation(program, posName);
this.cpos = gl.getAttribLocation(program, colorName);
}
SetupVBO(gl, edges) {
this.vbuf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.vbuf);
gl.bufferData(gl.ARRAY_BUFFER,flatten(edges),gl.STATIC_DRAW);
}
Show() {
this.visible = true;
}
Hide() {
this.visible = false;
}
Visible() {
return this.visible;
}
Display(gl) {
if (this.visible) {
gl.bindBuffer(gl.ARRAY_BUFFER, this.vbuf);
gl.vertexAttribPointer(this.vpos, 3, gl.FLOAT, false, 24, 0);
gl.enableVertexAttribArray(this.vpos);
gl.vertexAttribPointer(this.cpos, 3, gl.FLOAT, false, 24, 12);
gl.enableVertexAttribArray(this.cpos);
gl.drawArrays(gl.LINE_LOOP, 0, this.size);
}
}
}