Press x,y and z to rotate.
<html>
<head>
<script id="vertex-shader" type="x-shader/x-vertex" >
precision mediump float;
attribute vec4 vPosition;
attribute vec3 vBC;
attribute vec4 vColor;
//uniform float vFillType;
varying vec3 f_BC;
varying vec4 f_Color;
varying vec4 e_Color;
void main() {
gl_Position = vPosition;
f_BC = vBC;
f_Color = vColor;
e_Color = vec4(0.0, 0.0, 0.0, 1.0);
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
#extension GL_OES_standard_derivatives : enable
precision mediump float;
varying vec4 f_Color;
varying vec3 f_BC;
varying vec4 e_Color;
uniform int vShader;
// filled with edge shader
void Shader0() {
if (any(lessThan(f_BC, vec3(0.005)))) {
// edge, draw it with the edge color
gl_FragColor= e_Color;
} else {
if (gl_FrontFacing) {
// front face, draw it with the face color
gl_FragColor = f_Color;
} else {
// back face, draw it grey
gl_FragColor = vec4(0.5, 0.5, 0.5, 1.0);
}
}
}
// wireframe shader
void Shader1() {
if (gl_FrontFacing) {
// front face
if (any(lessThan(f_BC, vec3(0.05)))) {
// wide border
gl_FragColor= e_Color;
} else {
// no interior
discard;
}
} else {
// back facing
if (any(lessThan(f_BC, vec3(0.005)))) {
// narrow border
gl_FragColor= e_Color;
} else {
// partially obscuring
gl_FragColor = vec4(0.2, 0.2, 0.2, 0.3);
}
}
}
void main(){
if (vShader == 0) {
Shader0();
} else if (vShader == 1) {
Shader1();
} else {
gl_FragColor = f_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="b2.js"></script>
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>
<style>
input {
text-align: right;
}
</style>
</head>
<body>
<h1>It's a Hollow Feeling II</h1>
<script>
var canvas = new Canvas(500, 500);
canvas.Redisplay();
</script>
<p>
<button type="button" onclick="canvas.FlipDir(),canvas.Redisplay()">
Triangle Dir
</button>
<button type="button" onclick="canvas.ChangeShader(),canvas.Redisplay()">
Change Shader
</button>
<form >
<input type="radio" name="face" value="0" checked
onchange="canvas.ChangeFace(this.value), canvas.Redisplay()">
BACK
</input>
<input type="radio" name="face" value="1"
onchange="canvas.ChangeFace(this.value), canvas.Redisplay()">
FRONT
</input>
<input type="radio" name="face" value="2"
onchange="canvas.ChangeFace(this.value), canvas.Redisplay()">
FRONT_AND_BACK
</input>
<input type="radio" name="face" value="3"
onchange="canvas.ChangeFace(this.value), canvas.Redisplay()">
none
</input>
</form>
<p>
Press x,y and z to rotate.
</body>
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;
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;
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, "vPosition");
gl.vertexAttribPointer(vPos,2,gl.FLOAT, false,0,0);
gl.enableVertexAttribArray(vPos);
this.vBC = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.vBC);
var vBC = gl.getAttribLocation(program, "vBC");
gl.vertexAttribPointer(vBC,3,gl.FLOAT, false,0,0);
gl.enableVertexAttribArray(vBC);
// a buffer for the colors
this.cBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.cBuffer);
var colorAttribute = gl.getAttribLocation(program, "vColor");
gl.vertexAttribPointer(colorAttribute,3,gl.FLOAT, false,0,0);
gl.enableVertexAttribArray(colorAttribute);
this.shaderLoc = gl.getUniformLocation(program, "vShader");
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.uniform1i(this.shaderLoc, 0);
this.direction = this.gl.CCW;
this.gl.frontFace(this.direction);
this.gl.enable(this.gl.CULL_FACE);
this.gl.cullFace(this.gl.BACK);
this.MakeList();
},
FlipDir: function() {
if (this.direction == this.gl.CCW) {
this.direction = this.gl.CW;
} else {
this.direction = this.gl.CCW;
}
this.gl.frontFace(this.direction);
},
MakeList: function() {
var p1 = vec2(-0.8, -0.8);
var p2 = vec2(-0.1, -0.1);
var p3 = vec2(-0.8, -0.1);
this.verts= [p1, p2, p3] ;
p1 = vec2(0.1, 0.1);
p3 = vec2(0.8, 0.1);
p2 = vec2(0.8, 0.8);
this.verts.push(p1);
this.verts.push(p2);
this.verts.push(p3);
var c1 = vec3(Math.random(), Math.random(),Math.random())
var c2 = vec3(Math.random(), Math.random(),Math.random())
var c3 = vec3(Math.random(), Math.random(),Math.random())
this.colors = [c1, c2, c3];
c1 = vec3(Math.random(), Math.random(),Math.random())
c2 = vec3(Math.random(), Math.random(),Math.random())
c3 = vec3(Math.random(), Math.random(),Math.random())
this.colors.push(c1);
this.colors.push(c2);
this.colors.push(c3);
this.bc = [[1,0,0],[0,1,0],[0,0,1],[1,0,0],[0,1,0],[0,0,1]];
this.UpdateBuffers();
},
UpdateBuffers: function() {
var gl = this.gl;
// change the vertex data
gl.bindBuffer(gl.ARRAY_BUFFER, this.vBC);
gl.bufferData(gl.ARRAY_BUFFER,flatten(this.bc),gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, this.vPos);
gl.bufferData(gl.ARRAY_BUFFER,flatten(this.verts),gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, this.cBuffer);
gl.bufferData(gl.ARRAY_BUFFER,flatten(this.colors),gl.STATIC_DRAW);
},
ChangeShader: function() {
if (this.shaderChoice == 0) {
this.shaderChoice = 1
} else {
this.shaderChoice = 0;
}
this.gl.uniform1i(this.shaderLoc, this.shaderChoice);
console.log(this.shaderChoice);
this.Redisplay();
},
ChangeFace: function(value) {
switch(value) {
default:
case '0':
this.gl.enable(this.gl.CULL_FACE);
this.gl.cullFace(this.gl.BACK);
break;
case '1':
this.gl.enable(this.gl.CULL_FACE);
this.gl.cullFace(this.gl.FRONT);
break;
case '2':
this.gl.enable(this.gl.CULL_FACE);
this.gl.cullFace(this.gl.FRONT_AND_BACK);
break;
case '3':
this.gl.disable(this.gl.CULL_FACE);
break;
}
},
Redisplay: function() {
this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT );
this.gl.drawArrays(this.gl.TRIANGLES, 0, this.verts.length);
return;
}
};