| Color | Red | Green | Blue |
|---|---|---|---|
| Ambient | |||
| Diffuse | |||
| Specular |
Value of alpha:
| Key | ActioN |
|---|---|
| S | Swap Shaders |
| x | rotate Item about X axis |
| y | rotate Item about Y axis |
| z | rotate Item about Z axis |
| s | Toggle Specular |
| a | Toggle Ambient |
| d | Toggle Diffuse |
<html>
<head>
<script id="vertex-shader" type="x-shader/x-vertex" >
precision mediump float;
attribute vec4 attributePosition;
attribute float attributeBC;
attribute vec3 surfaceNormal;
attribute vec3 vertexNormal;
uniform mat4 uniformTransform;
uniform mat4 worldTransform;
uniform mat4 uniformProject;
uniform float shadingType;
uniform float uAmbient;
uniform float uSpecular;
uniform float uDiffuse;
uniform float uAlpha;
uniform vec3 uSurfaceAmbient;
uniform vec3 uSurfaceSpecular;
uniform vec3 uSurfaceDiffuse;
varying vec3 varyingBC;
varying vec4 color;
varying vec3 varNormal;
varying vec3 lightVector;
varying vec3 halfAngle;
varying float fade;
void main() {
vec4 here = worldTransform * uniformTransform * attributePosition;
gl_Position = uniformProject * here;
vec4 tmp = worldTransform * uniformTransform * vec4(surfaceNormal,1);
vec3 normal = normalize(tmp.xyz);
varNormal = normal.xyz;
here = -here;
vec4 light = vec4(0.0 ,-1.0 ,4.0, 0.0);
light = worldTransform * light;
lightVector = normalize(light-here).xyz;
halfAngle = normalize(vec4(0.0, 0.0, -4.0, 0.0)+ light).xyz;
/*
float a = 1.0;
float b = 0.0;
float c = 0.0;
float dist = distance(light.xyz,here.xyz);
fade = 1.0/(a+b*dist + c *dist*dist);
*/
fade = 1.0;
if (attributeBC == 0.0) {
varyingBC = vec3(1.0, 0.0, 0.0);
} else if (attributeBC == 1.0) {
varyingBC = vec3(0.0, 1.0, 0.0);
} else {
varyingBC = vec3(0.0, 0.0, 1.0);
}
if (shadingType < 0.5) {
vec3 lightAmbient = vec3(1.0,1.0, 1.0);
vec3 lightDiffuse = vec3(1.0, 1.0, 1.0);
vec3 lightSpecular = vec3(1.0, 1.0, 1.0);
vec3 zero = vec3(0.0, 0.0, 0.0);
vec3 one = vec3(1.0, 1.0, 1.0);
vec3 ambient = lightAmbient * uSurfaceAmbient;
vec3 diffuse = max(dot(lightVector, normal),0.0)
* lightDiffuse * uSurfaceDiffuse ;
diffuse = clamp(diffuse, zero, one);
vec3 specular = max(pow(dot(halfAngle,normal),uAlpha),0.0)
* lightSpecular * uSurfaceSpecular;
specular = clamp(specular,zero,one);
if (uAmbient > .5) {
ambient = zero;
}
if (uDiffuse > .5) {
diffuse = zero;
}
if (uSpecular > .5) {
specular = zero;
}
color = vec4(clamp(ambient + fade*(diffuse + specular), zero,one),1.0);
} else {
vec4 tmp = worldTransform * uniformTransform * vec4(vertexNormal,1);
varNormal = normalize(tmp.xyz);
}
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;
varying vec3 varyingBC;
uniform vec4 uniformEdgeColor;
uniform float shadingType;
uniform float uAmbient;
uniform float uSpecular;
uniform float uDiffuse;
uniform float uAlpha;
uniform vec3 uSurfaceAmbient;
uniform vec3 uSurfaceSpecular;
uniform vec3 uSurfaceDiffuse;
varying vec4 color;
varying vec3 varNormal;
varying vec3 lightVector;
varying vec3 halfAngle;
varying float fade;
void main(){
if (shadingType < 0.5) {
gl_FragColor= color;
} else {
vec3 lightAmbient = vec3(1.0,1.0, 1.0);
vec3 lightDiffuse = vec3(1.0, 1.0, 1.0);
vec3 lightSpecular = vec3(1.0, 1.0, 1.0);
vec3 zero = vec3(0.0, 0.0, 0.0);
vec3 one = vec3(1.0, 1.0, 1.0);
// because they may have become denormailzed in interpolation
vec3 L = normalize(lightVector);
vec3 N = normalize (varNormal);
vec3 H = normalize(halfAngle);
vec3 ambient = lightAmbient * uSurfaceAmbient;
vec3 diffuse = max(dot(L,N),0.0) * lightDiffuse * uSurfaceDiffuse ;
diffuse = clamp(diffuse, zero, one);
vec3 specular = max(pow(dot(H,N),uAlpha),0.0)
* lightSpecular * uSurfaceSpecular;
specular = clamp(specular,zero,one);
if (uAmbient > .5) {
ambient = zero;
}
if (uDiffuse > .5) {
diffuse = zero;
}
if (uSpecular > .5) {
specular = zero;
}
gl_FragColor = vec4(clamp(ambient + fade*(diffuse + specular),
zero,one),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="../Models/teapot.js"></script>
<script type="text/javascript" src="../Models/bunny.js"> </script>
<script type="text/javascript" src="../Models/cone.js"> </script>
<script type="text/javascript" src="../Models/dragon.js"> </script>
<script type="text/javascript" src="../Models/head.js"></script>
<script type="text/javascript" src="../Models/stego.js"></script>
<script type="text/javascript" src="../Models/xwing.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/lizard.js"></script>
<script type="text/javascript" src="../Models/tank.js"></script>
<script type="text/javascript" src="../Models/cube.js"></script>
<script type="text/javascript" src="../Models/epcot.js"></script>
<script type="text/javascript" src="../Models/plane.js"></script>
<script type="text/javascript" src="GLCanvas.js"></script>
<script type="text/javascript" src="utils.js"></script>
<script type="text/javascript" src="Widget.js"></script>
<style>
input {
text-align: right;
}
</style>
</head>
<body>
<h1>Lights</h1>
<select onchange="MakeItem(this.value);Redisplay()">
<option value="teapot">Teapot</option>
<option value="lizard">lizard</option>
<option value="bunny">bunny</option>
<option value="epcot">epcot</option>
</select>
<script>
'use strict'
var canvas = new Canvas(400, 400, Keypress);
var item;
var camera, at, up, theta, phi;
var orx=0, ory=0,orz=0;
MakeItem("teapot")
ResetCamera();
canvas.NewView(camera, at, up);
Redisplay();
</script>
<p>
<table>
<tr><th>Color</th><th> Red</th><th> Green</th><th> Blue</th></td>
<tr><td> Ambient</td>
<td>
<input type="range" min="1" max="100" value="5" class="slider"
id="ambientRed" onchange="FixColor()" list="ticks">
<output for="ambientRedInput" id="ambientRedInputValue"></output>
</td>
<td>
<input type="range" min="1" max="100" value="5" class="slider"
id="ambientGreen" onchange="FixColor()" list="ticks">
<output for="ambientGreenInput" id="ambientGreenInputValue"></output>
</td>
<td>
<input type="range" min="1" max="100" value="5" class="slider"
id="ambientBlue" onchange="FixColor()" list="ticks">
<output for="ambientBlueInput" id="ambientBlueInputValue"></output>
</td></tr>
<tr><td> Diffuse</td>
<td>
<input type="range" min="1" max="100" value="80" class="slider"
id="diffuseRed" onchange="FixColor()" list="ticks">
<output for="diffuseRedInput" id="diffuseRedInputValue"></output>
</td>
<td>
<input type="range" min="1" max="100" value="0" class="slider"
id="diffuseGreen" onchange="FixColor()" list="ticks">
<output for="diffuseGreenInput" id="diffuseGreenInputValue"></output>
</td>
<td>
<input type="range" min="1" max="100" value="0" class="slider"
id="diffuseBlue" onchange="FixColor()" list="ticks">
<output for="diffuseBlueInput" id="diffuseBlueInputValue"></output>
</td></tr>
<tr><td> Specular</td>
<td>
<input type="range" min="1" max="100" value="70" class="slider"
id="specularRed" onchange="FixColor()" list="ticks">
<output for="specularRedInput" id="specularRedInputValue"></output>
</td>
<td>
<input type="range" min="1" max="100" value="10" class="slider"
id="specularGreen" onchange="FixColor()" list="ticks">
<output for="specularGreenInput" id="specularGreenInputValue"></output>
</td>
<td>
<input type="range" min="1" max="100" value="10" class="slider"
id="specularBlue" onchange="FixColor()" list="ticks">
<output for="specularBlueInput" id="specularBlueInputValue"></output>
</td></tr>
</table>
<p>
Value of alpha:
<input type="range" min="1" max="500" value="100" class="slider"
id="alphaInput" onchange="FixAlpha()" list="ticks">
<output for="alphaInput" id="alphaInputValue"></output>
<datalist id="ticks">
<option value="1"></option>
<option value="120"></option>
<option value="250"></option>
<option value="360"></option>
<option value="500"></option>
</datalist>
<p>
<table>
<tr><th> Key</td><td> ActioN</td></tr>
<tr><td> S</td><td> Swap Shaders</td></tr>
<tr><td> x</td><td> rotate Item about X axis</td></tr>
<tr><td> y</td><td> rotate Item about Y axis</td></tr>
<tr><td> z</td><td> rotate Item about Z axis</td></tr>
<tr><td> s</td><td> Toggle Specular</td></tr>
<tr><td> a</td><td> Toggle Ambient</td></tr>
<tr><td> d</td><td> Toggle Diffuse</td></tr>
</table>
</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();
this.NewView([0,0,-1], [0,0,0],[0,1,0]);
}
NewView( camera, at, up) {
var eye = lookAt(camera, at, up);
var proj = this.Frustum(-1, 1, -1, 1,2 ,20);
this.gl.uniformMatrix4fv(this.worldTrans, false,flatten(eye));
this.gl.uniformMatrix4fv(this.projLoc, false,flatten(proj));
}
Frustum(l,r,b,t,n,f) {
var m = mat4(1);
m[0][0] = 2 * n / (r - l);
m[0][1] = 0;
m[0][2] = (r + l) / (r - l);
m[0][3] = 0;
m[1][0] = 0;
m[1][1] = 2 * n / (t - b);
m[1][2] = (t + b) / (t - b);
m[1][3] = 0;
m[2][0] = 0;
m[2][1] = 0;
m[2][2] = -(f + n) / (f - n);
m[2][3] = -2 * f * n / (f - n);
m[3][0] = 0;
m[3][1] = 0;
m[3][2] = -1;
m[3][3] = 0;
return m;
}
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 #000';
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() {
var gl = this.gl;
this.program = initShaders(gl, "vertex-shader","fragment-shader");
gl.useProgram(this.program);
this.projLoc = gl.getUniformLocation(this.program, "uniformProject");
this.worldTrans = gl.getUniformLocation(this.program, "worldTransform");
this.transLoc = gl.getUniformLocation(this.program, "uniformTransform");
this.edgeColorLoc = gl.getUniformLocation(this.program, "uniformEdgeColor");
this.surfaceColorLoc = gl.getUniformLocation(this.program, "uniformSurfaceColor");
this.shadingType = gl.getUniformLocation(this.program,"shadingType");
this.uAmbient = gl.getUniformLocation(this.program,"uAmbient");
this.uSpecular = gl.getUniformLocation(this.program,"uSpecular");
this.uDiffuse = gl.getUniformLocation(this.program,"uDiffuse");
this.uAlpha = gl.getUniformLocation(this.program,"uAlpha");
this.uSurfaceAmbient = gl.getUniformLocation(this.program,"uSurfaceAmbient");
this.uSurfaceSpecular = gl.getUniformLocation(this.program,"uSurfaceSpecular");
this.uSurfaceDiffuse = gl.getUniformLocation(this.program,"uSurfaceDiffuse");
}
SurfaceAmbient(r,g,b) {
this.gl.uniform3f(this.uSurfaceAmbient,r,g,b);
}
SurfaceSpecular(r,g,b) {
this.gl.uniform3f(this.uSurfaceSpecular,r,g,b);
}
SurfaceDiffuse(r,g,b) {
this.gl.uniform3f(this.uSurfaceDiffuse,r,g,b);
}
ToggleAmbient() {
if (this.ambientV == 1) {
this.ambientV = 0;
} else {
this.ambientV = 1;
}
this.gl.uniform1f(this.uAmbient,this.ambientV);
}
ToggleSpecular() {
if (this.specularV == 1) {
this.specularV = 0;
} else {
this.specularV = 1;
}
this.gl.uniform1f(this.uSpecular,this.specularV);
}
ToggleDiffuse() {
if (this.diffuseV == 1) {
this.diffuseV = 0;
} else {
this.diffuseV = 1;
}
this.gl.uniform1f(this.uDiffuse,this.diffuseV);
}
SwapShaders() {
if (this.shadingTypeV == 1.0) {
this.shadingTypeV = 0.0;
} else {
this.shadingTypeV = 1.0;
}
this.gl.uniform1f(this.shadingType,this.shadingTypeV);
}
SetAlpha(d) {
if (d >0 && d <= 500) {
this.gl.uniform1f(this.uAlpha,d);
}
}
Init() {
var gl = this.gl;
gl.clearColor(1.0, 1.0, 1.0, 1.0);
gl.viewport(0,0, this.width, this.height);
gl.enable(gl.BLEND);
gl.blendFuncSeparate(gl.SRC_ALPHA,
gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
gl.enable(gl.DEPTH_TEST);
gl.frontFace(gl.CW);
// set the default edge color for everything
this.NewEdgeColor([0.0, 0.0, 0.0, 1.0]);
this.NewSurfaceColor([1.0, 0.0, 0.0, 1.0]);
this.shadingTypeV =1;
this.SwapShaders();
this.ambientV = 1;
this.ToggleAmbient();
this.specularV = 1;
this.ToggleSpecular();
this.diffuseV = 1;
this.ToggleDiffuse();
this.SetAlpha(100);
this.SurfaceSpecular(0.7, 0.1, 0.1);
this.SurfaceAmbient(0.05, 0.05, 0.05);
this.SurfaceDiffuse(0.8, 0.0, 0.0);
}
NewSurfaceColor(c) {
this.gl.uniform4fv(this.surfaceColorLoc, c);
}
NewEdgeColor(c) {
this.gl.uniform4fv(this.edgeColorLoc, c);
}
Program() {
return this.program;
}
GL() {
return this.gl;
}
Translate() {
return this.transLoc;
}
Clear() {
this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
}
};
'use strict'
class Widget {
constructor(gl, program, tris,cw) {
this.size = tris.length;
var bcs = []
for (var i=0;i<tris.length/3;i++) {
bcs.push([0.0,1.0,2.0]);
}
this.SetupVBO(gl, program, tris, bcs);
this.SurfaceNormals(gl,program,tris,cw);
this.VertexNormals(gl,program,tris,cw);
this.Reset();
this.Transform();
}
SurfaceNormals(gl, program,tris,cw){
let i;
let sn=[];
for(i=0;i<tris.length;i+=3) {
let j=0;
let normal;
let a = subtract(vec3(tris[i]) , vec3(tris[i+1]));
let b = subtract(vec3(tris[i]) , vec3(tris[i+2]));
if (equal(a, vec3(0,0,0))) {
a = vec3(1,0,0);
}
a = normalize(a);
if (equal(b, vec3(0,0,0))) {
b = vec3(1,0,0);
}
b = normalize(b)
if (cw) {
normal = normalize(cross(a,b));
} else {
normal = normalize(cross(b,a));
}
for(j=0;j<3;j++ ) {
sn.push(normal);
}
}
this.vSN = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.vSN);
this.aSN = gl.getAttribLocation(program, "surfaceNormal");
if (this.aSN ==-1) {
console.log("failed to get attribute for surfaceNormal")
} else {
gl.vertexAttribPointer(this.aSN,3,gl.FLOAT, false,0,0);
gl.enableVertexAttribArray(this.aSN);
gl.bufferData(gl.ARRAY_BUFFER,flatten(sn),gl.STATIC_DRAW);
}
}
VertexNormals(gl,program,tris,cw) {
var verts = new Map();
let i;
let sn=[];
for(i=0;i<tris.length;i+=3) {
let j=0;
let normal;
let a = subtract(vec3(tris[i]) , vec3(tris[i+1]));
let b = subtract(vec3(tris[i]) , vec3(tris[i+2]));
if (equal(a, vec3(0,0,0))) {
a = vec3(1,0,0);
}
a = normalize(a);
if (equal(b, vec3(0,0,0))) {
b = vec3(1,0,0);
}
b = normalize(b)
if (cw) {
normal = normalize(cross(a,b));
} else {
normal = normalize(cross(b,a));
}
for (let j=0;j<3;j++) {
if (verts.has(tris[i+j])) {
verts[tris[i+j]] = add(verts[tris[i+j]],normal);
} else {
verts[tris[i+j]] = normal;
}
}
}
for (let k of verts.keys()) {
verts[k] = normalize(verts[k]);
}
for(i=0;i<tris.length;i+=3) {
for (let j=0;j<3;j++) {
sn.push(verts[tris[i+j]]);
}
}
this.vVN = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.vVN);
this.aVN = gl.getAttribLocation(program, "vertexNormal");
if (this.aVN ==-1) {
console.log("failed to get attribute for vertexNormal")
} else {
gl.vertexAttribPointer(this.aVN,3,gl.FLOAT, false,0,0);
gl.enableVertexAttribArray(this.aVN);
gl.bufferData(gl.ARRAY_BUFFER,flatten(sn),gl.STATIC_DRAW);
}
}
// things we might want to have to totally reset the item.
Reset() {
this.visible = true;
this.rx = 0;
this.ry = 0;
this.rz = 0;
this.sx = 1;
this.sy = 1;
this.sz = 1;
this.tx = 0;
this.ty = 0;
this.tz = 0;
}
SetupVBO(gl, program, tris, bcs) {
this.vPos = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.vPos);
this.aPos = gl.getAttribLocation(program, "attributePosition");
if (this.aPos == -1) {
console.log("Faild to get attributePosition") ;
} else {
gl.vertexAttribPointer(this.aPos, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(this.aPos);
gl.bufferData(gl.ARRAY_BUFFER,flatten(tris),gl.STATIC_DRAW);
}
this.vBC = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.vBC);
this.aBC = gl.getAttribLocation(program, "attributeBC");
if (this.aBC == -1) {
console.log("Faild to get attributeBC") ;
} else {
gl.vertexAttribPointer(this.aBC,1,gl.FLOAT, false,0,0);
gl.enableVertexAttribArray(this.aBC);
gl.bufferData(gl.ARRAY_BUFFER,flatten(bcs),gl.STATIC_DRAW);
}
}
Show() {
this.visible = true;
}
Hide() {
this.visible = false;
}
Visible() {
return this.visible;
}
Transform() {
var tmp = translate(this.tx, this.ty, this.tz);
tmp = mult(tmp, scalem(this.sx, this.sy, this.sz));
tmp = mult(tmp, rotate(this.rz, [0,0,1]));
tmp = mult(tmp, rotate(this.ry, [0,1,0]));
tmp = mult(tmp, rotate(this.rx, [1,0,0]));
this.transform = tmp;
}
Display(gl, transform, transLoc) {
if (this.visible) {
// make sure that the transform matrix is up to date.
this.Transform();
// multiply it by any incoming transformation matrix
let tx =
mult(transform, this.transform);
// use it
gl.uniformMatrix4fv(transLoc, false, flatten(tx));
gl.bindBuffer(gl.ARRAY_BUFFER, this.vPos);
gl.vertexAttribPointer(this.aPos, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this.vBC);
gl.vertexAttribPointer(this.aBC, 1, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this.vSN);
gl.vertexAttribPointer(this.aSN, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this.vVN);
gl.vertexAttribPointer(this.aVN, 3, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.TRIANGLES, 0, this.size);
}
}
}
'use strict'
const FA = [-10, -1, -10];
const FB = [ 10, -1.5, -10];
const FC = [0, -1.5, 0];
const FD = [ 10, -1.5, 10];
const FE = [-10, -1.5, 10];
const CA = [-10, 3, -10];
const CB = [ 10, 3, -10];
const CC = [ 0, 3, 0];
const CD = [ 10, 3, 10];
const CE = [-10, 3, 10];
const Floor= [FA, FB, FC, FB, FD, FC, FD, FE, FC, FE, FA, FC];
const Roof = [CB, CA, CC, CD, CB, CC, CE, CD, CC, CA, CE, CC];
function MakeTeapot() {
let teapot =new Widget(canvas.GL(), canvas.Program(),
Teapot_Triangles,false);
teapot.tz = .5
teapot.rx = -90
orx = -90;
teapot.sx = 2; teapot.sy = 2; teapot.sz = 2;
return teapot;
}
function MakeLizard() {
let lizard =new Widget(canvas.GL(), canvas.Program(),
Lizard_Triangles,false);
lizard.tz = .5
lizard.ty = -1.3
lizard.rx = -90
orx = -90;
lizard.sx = 3.4; lizard.sy = 3.4; lizard.sz = 3.4;
return lizard;
}
function MakeBunny() {
let bunny =new Widget(canvas.GL(), canvas.Program(),
Bunny_Triangles,false);
bunny.tz = 1.0
bunny.ty = 0
bunny.ry = 90
orx = 90;
bunny.sx = 3.4; bunny.sy = 3.4; bunny.sz = 3.4;
return bunny;
}
function MakeEpcot() {
let epcot =new Widget(canvas.GL(), canvas.Program(),
Epcot_Triangles,false);
epcot.tz = 1.0
epcot.ty = 0
epcot.sx = 3.4; epcot.sy = 3.4; epcot.sz = 3.4;
return epcot;
}
function MakeItem(key) {
if (key == "teapot") {
item = MakeTeapot();
} else if (key == "lizard") {
item = MakeLizard();
} else if (key == "bunny") {
item = MakeBunny();
} else if (key == "epcot") {
item = MakeEpcot();
}
}
function ResetCamera() {
up = [0,1,0];
theta = 0;
phi = 90;
camera = [0,0,-3.0];
MoveAt(0.5);
}
function Fix(angle) {
while (angle < 0) {
angle += 360;
}
angle %= 360;
return angle;
}
function Offset(delta) {
let x,y,z;
theta = Fix(theta);
phi = Fix(phi);
let rphi = phi * Math.PI/180;
let rtheta = theta * Math.PI/180;
z = delta * Math.sin(rphi) * Math.cos(rtheta);
y = delta * Math.cos(rphi)
x = delta * Math.sin(rphi) * Math.sin(rtheta);
return ([x,y,z]);
}
function MoveAt(delta) {
let offset = Offset(delta);
at = add(camera, offset);
}
function MoveAll(delta) {
let offset = Offset(delta);
camera = add(camera , offset);
at = add(camera, offset);
}
function Keypress(evnt) {
switch(evnt.key) {
case 'S': canvas.SwapShaders();
break;
case 'R': item.rx = orx;
item.ry = ory;
item.rz = orz;
break;
case 'x': item.rx ++;
break;
case 'y': item.ry ++;
break;
case 'z': item.rz ++;
break;
case 'a': canvas.ToggleAmbient();
break;
case 's': canvas.ToggleSpecular();
break;
case 'd': canvas.ToggleDiffuse();
break;
}
Redisplay();
}
function FixAlpha() {
let alpha = document.getElementById('alphaInput').value
canvas.SetAlpha(alpha);
Redisplay();
}
function FixColor() {
let aR = document.getElementById('ambientRed').value
let aG = document.getElementById('ambientGreen').value
let aB = document.getElementById('ambientBlue').value
canvas.SurfaceAmbient(aR/100,aG/100,aB/100);
let dR = document.getElementById('diffuseRed').value
let dG = document.getElementById('diffuseGreen').value
let dB = document.getElementById('diffuseBlue').value
canvas.SurfaceDiffuse(dR/100,dG/100,dB/100);
let sR = document.getElementById('specularRed').value
let sG = document.getElementById('specularGreen').value
let sB = document.getElementById('specularBlue').value
canvas.SurfaceSpecular(sR/100,sG/100,sB/100);
Redisplay();
}
function Redisplay() {
canvas.Clear();
canvas.NewEdgeColor([0.0, 0.0, 0.0, 1.0]);
canvas.NewSurfaceColor([1.0, 0.0, 0.0, 1.0]);
canvas.GL().frontFace(canvas.GL().CW);
item.Display(canvas.GL(), mat4(), canvas.Translate());
}