| Direction is: | |
|
Face to Remove: |
Note, this is somewhat of a step back oop wise. I want to keep everything uniform with the display, so it is placed in the canvas, not with the objects.
<html>
<head>
<script id="vertex-shader" type="x-shader/x-vertex" >
precision mediump float;
attribute vec4 vPosition;
attribute vec3 vBC;
attribute vec4 vColor;
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">
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 = vec4(1.0, 1.0, 1.0, 1.0);
}
}
</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="GLCanvas.js"></script>
<script type="text/javascript" src="triangle.js"></script>
<style>
input {
text-align: right;
}
</style>
</head>
<body>
<h1>Barycentric Coordinates</h1>
<table>
<tr><td rowspan=3>
<canvas id="triangle" width="200" height="200" style="border:1px solid #000000;"></canvas>
<script>
let canv = document.getElementById("triangle");
let ctx = canv.getContext('2d');
let w = canv.width;
let h = canv.height;
ctx.strokeStyle="black";
ctx.beginPath();
ctx.moveTo(0,h/2);
ctx.lineTo(w,h/2);
ctx.moveTo(w/2,h);
ctx.lineTo(w/2,0);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(20,h-20);
ctx.lineTo(w/2-10,h/2+10);
ctx.lineTo(20,h/2+10);
ctx.lineTo(20,h-20);
ctx.stroke();
ctx.strokeStyle="red";
ctx.beginPath();
ctx.moveTo(25,h-15);
ctx.lineTo(w/2-5,h/2+15);
ctx.lineTo(w/2-10,h/2+30);
ctx.stroke();
ctx.strokeStyle="black";
ctx.beginPath();
ctx.moveTo(w/2+20,h/2-20);
ctx.lineTo(180, 20);
ctx.lineTo(180, h/2-20);
ctx.lineTo(w/2+20,h/2-20);
ctx.stroke();
ctx.strokeStyle="red";
ctx.beginPath();
ctx.moveTo(w/2+10,h/2-20);
ctx.lineTo(170, 20);
ctx.lineTo(165, 35);
ctx.stroke();
</script>
</td><td>
Direction is:
<input type="button" id="direction"
onclick="canvas.FlipDir(),Redisplay()"> </input>
</td></tr>
<tr><td>
<button type="button" onclick="canvas.ChangeShader(),Redisplay()">
Change Shader
</button>
</td></tr>
<tr><td>
<p>
Face to Remove:
<form >
<input type="radio" name="face" value="0" checked
onchange="canvas.ChangeFace(this.value), Redisplay()">
BACK
</input>
<input type="radio" name="face" value="1"
onchange="canvas.ChangeFace(this.value), Redisplay()">
FRONT
</input>
<input type="radio" name="face" value="2"
onchange="canvas.ChangeFace(this.value), Redisplay()">
FRONT_AND_BACK
</input>
<input type="radio" name="face" value="3"
onchange="canvas.ChangeFace(this.value), Redisplay()">
none
</input>
</form>
</td></tr>
</table>
<script>
var canvas = new Canvas(400, 400);
var triangle = new Triangle(canvas.GL(), canvas.Program());
function Redisplay() {
canvas.Clear();
triangle.Display(canvas.GL());
}
Redisplay();
</script>
<p>
Note, this is somewhat of a step back oop wise. I want to keep everything uniform with the display, so it is placed in the canvas, not with the objects.
</body>
'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);
this.shaderLoc = this.gl.getUniformLocation(this.program, "vShader");
}
Init() {
this.gl.clearColor(1.0, 1.0, 1.0, 1.0);
this.gl.viewport(0,0, this.width, this.height);
this.gl.enable(this.gl.BLEND);
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA,
this.gl.ONE, this.gl.ONE_MINUS_SRC_ALPHA);
this.gl.enable(this.gl.DEPTH_TEST);
//this.gl.depthFunc(this.gl.LESS);
//this.gl.depthMask(true);
this.ChangeShader();
this.FlipDir();
this.ChangeFace(0);
}
FlipDir() {
if (this.direction == this.gl.CCW) {
this.direction = this.gl.CW;
// bad but I need a quick fix.
document.getElementById("direction").value = "gl.CW";
} else {
document.getElementById("direction").value = "gl.CCW";
this.direction = this.gl.CCW;
}
this.gl.frontFace(this.direction);
}
ChangeShader() {
if (this.shaderChoice === 0 || this.shaderChoice === undefined ) {
this.shaderChoice = 1
} else {
this.shaderChoice = 0;
}
this.gl.uniform1i(this.shaderLoc, this.shaderChoice);
}
ChangeFace(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;
}
}
Program() {
return this.program;
}
GL() {
return this.gl;
}
Clear() {
this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
}
};
'use strict'
class Triangle {
constructor(gl, program) {
this.SetupBuffers(gl, program)
this.MakeList(gl)
}
SetupBuffers(gl, 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);
}
MakeList(gl) {
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(gl);
}
UpdateBuffers(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);
}
Display(gl) {
gl.drawArrays(gl.TRIANGLES, 0, this.verts.length);
}
}