弱智实验
<!DOCTYPE html>
<html>
<script type="text/javascript" src="initShaders.js"></script>
<script type="text/javascript" src="MVnew.js"></script>
<script type="text/javascript" src="t.js"></script>
<script id="vertex-shader" type="x-shader/x-vertex">
#version 300 es
in vec4 aPosition;
in vec3 aNormal;
out vec4 vColor;
uniform vec4 uAmbientProduct, uDiffuseProduct, uSpecularProduct;
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
uniform vec4 uLightPosition;
uniform float uShininess;
void main()
{
vec3 pos = -(uModelViewMatrix * aPosition).xyz;
vec3 light = uLightPosition.xyz;
vec3 L = normalize( light - pos );
vec3 E = normalize(-pos);
vec3 H = normalize(L + E);
vec4 NN = vec4(aNormal,0);
// Transform vertex normal into eye coordinates
vec3 N = normalize((uModelViewMatrix*NN).xyz);
// Compute terms in the illumination equation
vec4 ambient = uAmbientProduct;
float Kd = max( dot(L, N), 0.0 );
vec4 diffuse = Kd*uDiffuseProduct;
float Ks = pow( max(dot(N, H), 0.0), uShininess );
vec4 specular = Ks * uSpecularProduct;
if( dot(L, N) < 0.0 ) {
specular = vec4(0.0, 0.0, 0.0, 1.0);
}
gl_Position = uProjectionMatrix * uModelViewMatrix * aPosition;
vColor = ambient + diffuse +specular;
vColor.a = 3.0;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
#version 300 es
precision mediump float;
uniform int uColorIndex;
in vec4 vColor;
out vec4 fColor;
void
main()
{
vec4 c[7];
c[0] = vColor;
c[1] = vec4(1.0, 0.0, 0.0, 1.0);
c[2] = vec4(0.0, 1.0, 0.0, 1.0);
c[3] = vec4(0.0, 0.0, 1.0, 1.0);
c[4] = vec4(1.0, 1.0, 0.0, 1.0);
c[5] = vec4(0.0, 1.0, 1.0, 1.0);
c[6] = vec4(1.0, 0.0, 1.0, 1.0);
if(uColorIndex==0) fColor = c[0];
else fColor = c[uColorIndex];
}
</script>
<body>
<div>
<canvas id="gl-canvas" width="512" height="512">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</div>
<div>
<button id = "ButtonX">Rotate X</button>
<button id = "ButtonY">Rotate Y</button>
<button id = "ButtonZ">Rotate Z</button>
<button id = "ButtonT">Toggle Rotation</button>
</div>
</body>
</html>
t.js
"use strict";
var canvas;
var gl;
var program;
var numPositions = 36;
var positionsArray = [];
var normalsArray = [];
var framebuffer;
var flag = false;
var color = new Uint8Array(4);
var vertices = [
vec4( -0.5, -0.5, 0.5, 1.0 ),
vec4( -0.5, 0.5, 0.5, 1.0 ),
vec4( 0.5, 0.5, 0.5, 1.0 ),
vec4( 0.5, -0.5, 0.5, 1.0 ),
vec4( -0.5, -0.5, -0.5, 1.0 ),
vec4( -0.5, 0.5, -0.5, 1.0 ),
vec4( 0.5, 0.5, -0.5, 1.0 ),
vec4( 0.5, -0.5, -0.5, 1.0 ),
];
var lightPosition = vec4(1.0, 1.0, 1.0, 0.0 );
var lightAmbient = vec4(0.2, 0.2, 0.2, 1.0 );
var lightDiffuse = vec4( 1.0, 1.0, 1.0, 1.0 );
var lightSpecular = vec4( 1.0, 1.0, 1.0, 1.0 );
var materialAmbient = vec4( 1.0, 0.0, 1.0, 1.0 );
var materialDiffuse = vec4( 1.0, 0.8, 0.0, 1.0);
var materialSpecular = vec4( 1.0, 0.8, 0.0, 1.0 );
var materialShininess = 100.0;
var ctm;
var ambientColor, diffuseColor, specularColor;
var modelViewMatrix, projectionMatrix;
var viewerPos;
var program;
var xAxis = 0;
var yAxis = 1;
var zAxis = 2;
var axis = xAxis;
var theta = vec3(45.0, 45.0, 45.0);
var thetaLoc;
var Index = 0;
function quad(a, b, c, d) {
var t1 = subtract(vertices[b], vertices[a]);
var t2 = subtract(vertices[c], vertices[b]);
var normal = cross(t1, t2);
normal = normalize(normal);
positionsArray.push(vertices[a]);
normalsArray.push(normal);
positionsArray.push(vertices[b]);
normalsArray.push(normal);
positionsArray.push(vertices[c]);
normalsArray.push(normal);
positionsArray.push(vertices[a]);
normalsArray.push(normal);
positionsArray.push(vertices[c]);
normalsArray.push(normal);
positionsArray.push(vertices[d]);
normalsArray.push(normal);
}
function colorCube()
{
quad(1, 0, 3, 2);
quad(2, 3, 7, 6);
quad(3, 0, 4, 7);
quad(6, 5, 1, 2);
quad(4, 5, 6, 7);
quad(5, 4, 0, 1);
}
window.onload = function init() {
canvas = document.getElementById("gl-canvas");
gl = canvas.getContext('webgl2');
if (!gl) alert("WebGL 2.0 isn't available");
gl.viewport(0, 0, canvas.width, canvas.height);
gl.clearColor(0.5, 0.5, 0.5, 1.0);
gl.enable(gl.CULL_FACE);
var texture = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, texture );
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 512, 512, 0,
gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.generateMipmap(gl.TEXTURE_2D);
// Allocate a frame buffer object
framebuffer = gl.createFramebuffer();
gl.bindFramebuffer( gl.FRAMEBUFFER, framebuffer);
// Attach color buffer
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
// check for completeness
//var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
//if(status != gl.FRAMEBUFFER_COMPLETE) alert('Frame Buffer Not Complete');
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
//
// Load shaders and initialize attribute buffers
//
program = initShaders(gl, "vertex-shader", "fragment-shader");
gl.useProgram( program );
colorCube();
var nBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, nBuffer );
gl.bufferData(gl.ARRAY_BUFFER, flatten(normalsArray), gl.STATIC_DRAW);
var normalLoc = gl.getAttribLocation(program, "aNormal");
gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(normalLoc);
var vBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vBuffer);
gl.bufferData(gl.ARRAY_BUFFER, flatten(positionsArray), gl.STATIC_DRAW);
var positionLoc = gl.getAttribLocation(program, "aPosition");
gl.vertexAttribPointer(positionLoc, 4, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionLoc);
thetaLoc = gl.getUniformLocation(program, "theta");
viewerPos = vec3(0.0, 0.0, -20.0);
projectionMatrix = ortho(-1, 1, -1, 1, -100, 100);
var ambientProduct = mult(lightAmbient, materialAmbient);
var diffuseProduct = mult(lightDiffuse, materialDiffuse);
var specularProduct = mult(lightSpecular, materialSpecular);
document.getElementById("ButtonX").onclick = function(){axis = xAxis;};
document.getElementById("ButtonY").onclick = function(){axis = yAxis;};
document.getElementById("ButtonZ").onclick = function(){axis = zAxis;};
document.getElementById("ButtonT").onclick = function(){flag = !flag};
document.addEventListener('keypress', function(event) {
//keyboardEvent= event
console.log(event.key)
switch (event.key) {
case 'w':
axis = xAxis;
break
case 's':
axis = xAxis;
break
case 'a':
axis = zAxis;
break
case 'd':
axis = yAxis;
break
default :
break
}
})
gl.uniform4fv(gl.getUniformLocation(program, "uAmbientProduct"),
ambientProduct);
gl.uniform4fv(gl.getUniformLocation(program, "uDiffuseProduct"),
diffuseProduct );
gl.uniform4fv(gl.getUniformLocation(program, "uSpecularProduct"),
specularProduct );
gl.uniform4fv(gl.getUniformLocation(program, "uLightPosition"),
lightPosition );
gl.uniform1f(gl.getUniformLocation(program,
"uShininess"), materialShininess);
gl.uniformMatrix4fv( gl.getUniformLocation(program, "uProjectionMatrix"),
false, flatten(projectionMatrix) );
canvas.addEventListener("mousedown", function(event){
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.clear( gl.COLOR_BUFFER_BIT);
gl.uniform3fv(thetaLoc, theta);
for(var i=0; i<6; i++) {
gl.uniform1i(gl.getUniformLocation(program, "uColorIndex"), i+1);
gl.drawArrays( gl.TRIANGLES, 6*i, 6 );
}
var x = event.clientX;
var y = canvas.height-event.clientY;
gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, color);
if(color[0]==255)
if(color[1]==255) console.log("front");
else if(color[2]==255) console.log("back");
else console.log("right");
else if(color[1]==255)
if(color[2]==255) console.log("left");
else console.log("top");
else if(color[2]==255) console.log("bottom");
else console.log("background");
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.uniform1i(gl.getUniformLocation(program, "uColorIndex"), 0);
gl.clear( gl.COLOR_BUFFER_BIT );
gl.uniform3fv(thetaLoc, theta);
gl.drawArrays(gl.TRIANGLES, 0, numPositions);
});
render();
}
var render = function(){
gl.clear( gl.COLOR_BUFFER_BIT );
if(flag) theta[axis] += 2.0;
modelViewMatrix = mat4();
modelViewMatrix = mult(modelViewMatrix, rotate(theta[xAxis], vec3(1, 0, 0)));
modelViewMatrix = mult(modelViewMatrix, rotate(theta[yAxis], vec3(0, 1, 0)));
modelViewMatrix = mult(modelViewMatrix, rotate(theta[zAxis], vec3(0, 0, 1)));
gl.uniformMatrix4fv(gl.getUniformLocation(program,
"uModelViewMatrix"), false, flatten(modelViewMatrix));
gl.uniform1i(gl.getUniformLocation(program, "uColorIndex"),0);
gl.drawArrays(gl.TRIANGLES, 0, numPositions);
requestAnimationFrame(render);
}