Skip to content
Snippets Groups Projects
Commit f7b83658 authored by jorge.josegonc's avatar jorge.josegonc
Browse files

rotation and shadow with ponct light good but have not directionnal and...

rotation and shadow with ponct light good but have not directionnal and ambient and a good method for select hourglass
parent b572fe65
No related branches found
No related tags found
No related merge requests found
...@@ -2,167 +2,145 @@ ...@@ -2,167 +2,145 @@
Author : Jorge José Goncalves Author : Jorge José Goncalves
*/ */
// variable for camera and light // Vertex shader program for generating a shadow map
var eyeX = 2; var SHADOW_VSHADER_SOURCE =
var eyeY = 4;
var eyeZ = 6;
const STEP = 0.1;
var lightDirectionnalX = 0.5;
var lightDirectionnalY = 3.0;
var lightDirectionnalZ = 4.0;
var lightPositionX = 0.0;
var lightPositionY = 5.0;
var lightPositionZ = 0.0;
var OFFSCREEN_WIDTH = 2048;
var OFFSCREEN_HEIGHT = 2048;
var clicked_canvas = false;
var x_clicked = 0;
var y_clicked = 0;
var VSHADER_SOURCE_DIRECTIONNAL_LIGHT =
'attribute vec4 a_Position;\n' + 'attribute vec4 a_Position;\n' +
'attribute vec4 a_Color;\n' + 'uniform mat4 u_MvpMatrix;\n' +
'attribute vec4 a_Normal;\n' +
'uniform mat4 mMVP;\n' +
'uniform mat4 mNormal;\n' +
'uniform vec3 vLightDirection;\n' +
'varying vec4 v_Color;\n' +
'void main() {\n' + 'void main() {\n' +
' gl_Position = mMVP * a_Position;\n' + ' gl_Position = u_MvpMatrix * a_Position;\n' +
' vec4 normal = mNormal * a_Normal;\n' +
' float nDotL = max(dot(normalize(normal.xyz), vLightDirection), 0.0);\n' +
' v_Color = vec4(a_Color.xyz * nDotL, a_Color.a);\n' +
'}\n'; '}\n';
var FSHADER_SOURCE_DIRECTIONNAL_LIGHT = // Fragment shader program for generating a shadow map
var SHADOW_FSHADER_SOURCE =
'#ifdef GL_ES\n' + '#ifdef GL_ES\n' +
'precision mediump float;\n' + 'precision mediump float;\n' +
'#endif\n' + '#endif\n' +
'varying vec4 v_Color;\n' +
'void main() {\n' + 'void main() {\n' +
' gl_FragColor = v_Color;\n' + ' gl_FragColor = vec4(gl_FragCoord.z, 0.0, 0.0, 0.0);\n' + // Write the z-value in R
'}\n'; '}\n';
var VSHADER_SOURCE_PONCTUAL_LIGHT = // Vertex shader program for regular drawing
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' + 'attribute vec4 a_Position;\n' +
'attribute vec4 a_Color;\n' + 'attribute vec4 a_Color;\n' +
'attribute vec4 a_Normal;\n' + 'attribute vec4 a_Normal;\n' +
'uniform mat4 mMVP;\n' + 'uniform mat4 u_MvpMatrix;\n' +
'uniform mat4 mModel;\n' +
'uniform mat4 mNormal;\n' +
'varying vec4 v_Color;\n' +
'varying vec3 normal;\n' +
'varying vec4 vertexPosition;\n' +
'uniform bool u_Clicked;\n' +
'uniform bool u_is_hourglass;\n' +
'uniform mat4 u_MvpMatrixFromLight;\n' + 'uniform mat4 u_MvpMatrixFromLight;\n' +
'varying vec4 v_PositionFromLight;\n' + 'varying vec4 v_PositionFromLight;\n' +
'varying vec4 v_Color;\n' +
'varying vec3 v_normal;\n' +
'uniform mat4 u_NormalMatrix;\n' +
'uniform bool u_Clicked;\n' +
'varying vec4 v_VertexPosition;\n' +
'uniform mat4 u_ModelMatrix;\n' +
'void main() {\n' + 'void main() {\n' +
' gl_Position = mMVP * a_Position;\n' + ' gl_Position = u_MvpMatrix * a_Position;\n' +
' normal = normalize(vec3(mNormal * a_Normal));\n' + ' v_normal = normalize(vec3(u_NormalMatrix * a_Normal));\n' +
' vertexPosition = mModel * a_Position;\n' + ' v_VertexPosition = u_ModelMatrix * a_Position;\n' +
' if(u_Clicked && u_is_hourglass) {\n' + ' v_PositionFromLight = u_MvpMatrixFromLight * a_Position;\n' +
' if(u_Clicked && a_Color != vec4(1.0, 1.0, 1.0, 1.0)) {\n' +
' v_Color = vec4(0.0, 1.0, 0.0, 1.0);\n' + ' v_Color = vec4(0.0, 1.0, 0.0, 1.0);\n' +
' } else {\n' + ' } else {\n' +
' v_Color = a_Color;\n' + ' v_Color = a_Color;\n' +
' }\n' + ' }\n' +
'}\n'; '}\n';
var FSHADER_SOURCE_PONCTUAL_LIGHT = // Fragment shader program for regular drawing
var FSHADER_SOURCE =
'#ifdef GL_ES\n' + '#ifdef GL_ES\n' +
'precision mediump float;\n' + 'precision mediump float;\n' +
'#endif\n' + '#endif\n' +
'varying vec4 v_Color;\n' + 'uniform sampler2D u_ShadowMap;\n' +
'uniform vec3 vLightColor;\n' +
'uniform vec3 vLightPosition;\n' +
'varying vec3 normal;\n' +
'varying vec4 vertexPosition;\n' +
'varying vec4 v_PositionFromLight;\n' + 'varying vec4 v_PositionFromLight;\n' +
'varying vec4 v_Color;\n' +
'varying vec3 v_normal;\n' +
'varying vec4 v_VertexPosition;\n' +
'uniform vec3 u_LightPosition;\n' +
'uniform vec3 u_LightColor;\n' +
'void main() {\n' + 'void main() {\n' +
' vec3 vLightDirection = normalize(vLightPosition - vec3(vertexPosition));\n' + ' vec3 lightDirection = normalize(u_LightPosition - vec3(v_VertexPosition));\n' +
' float nDotL = max(dot(normal, vLightDirection), 0.0);\n' + ' float nDotL = max(dot(v_normal, lightDirection), 0.0);\n' +
' vec3 diffuse = vLightColor * v_Color.rgb * nDotL;\n' + ' vec3 diffuse = u_LightColor * v_Color.rgb * nDotL;\n' +
' gl_FragColor = vec4(diffuse, v_Color.a);\n' + ' vec3 shadowCoord = (v_PositionFromLight.xyz/v_PositionFromLight.w)/2.0 + 0.5;\n' +
' vec4 rgbaDepth = texture2D(u_ShadowMap, shadowCoord.xy);\n' +
' float depth = rgbaDepth.r;\n' + // Retrieve the z-value from R
' float visibility = (shadowCoord.z > depth + 0.005) ? 0.0 : 1.0;\n' +
' gl_FragColor = vec4(diffuse * visibility, v_Color.a);\n' +
'}\n'; '}\n';
var SHADOW_VSHADER_SOURCE = const PERSPECTIVE_WIDTH_FROM_LIGHT = 2048
'attribute vec4 a_Position;\n' + const PERSPECTIVE_HEIGHT_FROM_LIGHT = 2048
'uniform mat4 u_MvpMatrix;\n' +
'void main() {\n' +
' gl_Position = u_MvpMatrix * a_Position;\n' +
'}\n';
var SHADOW_FSHADER_SOURCE = // Step when change with keys
'#ifdef GL_ES\n' + const STEP = 0.1;
'precision mediump float;\n' +
'#endif\n' +
'void main() {\n' +
' gl_FragColor = vec4(gl_FragCoord.z, 0.0, 0.0, 0.0);\n' + // Write the z-value in R
'}\n';
function main() { // For light position
//directionnal_light(); var light_x = 0
ponctual_light(); var light_y = 1
// Control camera or lights var light_z = 2;
document.addEventListener("keydown", (event) => {
switch (event.key) { // For camera position
case 'a': var eye_x = 2;
eyeX -= STEP; var eye_y = 4;
break; var eye_z = 6;
case 'd':
eyeX += STEP; // Coordinate transformation matrix
break; var tmp_modelMatrix = new Matrix4();
case 's': var tmp_mvpMatrix = new Matrix4();
eyeY -= STEP; var tmp_normalMatrix = new Matrix4();
break; var rotationSecFrustrumMatrix = new Matrix4();
case 'w': var translateFrustrumMatrix = new Matrix4();
eyeY += STEP;
break; // Event of key down, move camera or light positions
case 'r': document.addEventListener("keydown", (event) => {
eyeZ -= STEP; switch (event.key) {
break; case 'a':
case 'f': eye_x -= STEP;
eyeZ += STEP; break;
break; case 'd':
case 'ArrowRight': eye_x += STEP;
lightDirectionnalX += STEP; break;
lightPositionX += STEP; case 's':
break; eye_y -= STEP;
case 'ArrowLeft': break;
lightDirectionnalX -= STEP; case 'w':
lightPositionX -= STEP; eye_y += STEP;
break; break;
case 'ArrowDown': case 'r':
lightDirectionnalY -= STEP; eye_z -= STEP;
lightPositionY -= STEP; break;
break; case 'f':
case 'ArrowUp': eye_z += STEP;
lightDirectionnalY += STEP; break;
lightPositionY += STEP; case 'ArrowRight':
break; light_x += STEP;
case 'z': break;
lightDirectionnalZ += STEP; case 'ArrowLeft':
lightPositionZ += STEP; light_x -= STEP;
break; break;
case 'h': case 'ArrowDown':
lightDirectionnalZ -= STEP; light_y -= STEP;
lightPositionZ -= STEP; break;
break; case 'ArrowUp':
default: light_y += STEP;
break; break;
} case 'z':
light_z += STEP;
break;
case 'h':
light_z -= STEP;
break;
default:
break;
}
// update html document.getElementById("light_x_point").textContent = "Light X point : " + light_x
document.getElementById("light_x_dir").textContent = "Light X directionnal : " + lightDirectionnalX document.getElementById("light_y_point").textContent = "Light Y point : " + light_y
document.getElementById("light_y_dir").textContent = "Light Y directionnal : " + lightDirectionnalY document.getElementById("light_z_point").textContent = "Light Z point : " + light_z
document.getElementById("light_z_dir").textContent = "Light Z directionnal : : " + lightDirectionnalZ });
document.getElementById("light_x_point").textContent = "Light X point : " + lightPositionX
document.getElementById("light_y_point").textContent = "Light Y point : " + lightPositionY
document.getElementById("light_z_point").textContent = "Light Z point : " + lightPositionZ
});
}
function directionnal_light() { function main() {
// Retrieve <canvas> element
var canvas = document.getElementById('my-canvas'); var canvas = document.getElementById('my-canvas');
// Get the rendering context for WebGL // Get the rendering context for WebGL
...@@ -172,67 +150,40 @@ function directionnal_light() { ...@@ -172,67 +150,40 @@ function directionnal_light() {
return; return;
} }
// Initialize shaders for light directionnal // Create a program for generating a shadow map
if (!initShaders(gl, VSHADER_SOURCE_DIRECTIONNAL_LIGHT, FSHADER_SOURCE_DIRECTIONNAL_LIGHT)) { var shadowProgram = createProgram(gl, SHADOW_VSHADER_SOURCE, SHADOW_FSHADER_SOURCE);
console.log('Failed to intialize shaders.'); shadowProgram.a_Position = gl.getAttribLocation(shadowProgram, 'a_Position');
return; shadowProgram.u_MvpMatrix = gl.getUniformLocation(shadowProgram, 'u_MvpMatrix');
} if (shadowProgram.a_Position < 0 || !shadowProgram.u_MvpMatrix) {
console.log('Failed to get the storage location of attribute or uniform variable from shadowProgram');
// Set the clear color and enable the depth test
gl.clearColor(0, 0, 0, 1);
gl.enable(gl.DEPTH_TEST);
// Get the storage locations
var mMVP = gl.getUniformLocation(gl.program, 'mMVP');
var mNormal = gl.getUniformLocation(gl.program, 'mNormal');
var vLightDirection = gl.getUniformLocation(gl.program, 'vLightDirection');
if (!mMVP || !mNormal || !vLightDirection) {
console.log('Failed to get the storage location');
return;
}
var vpMatrix = new Matrix4(); // View projection matrix
var tick = function () {
// Set perspective and camera
vpMatrix.setPerspective(50, canvas.width / canvas.height, 1, 100);
vpMatrix.lookAt(eyeX, eyeY, eyeZ, 0, 0, 0, 0, 1, 0);
// Set the light direction
var lightDirection = new Vector3([lightDirectionnalX, lightDirectionnalY, lightDirectionnalZ]);
lightDirection.normalize(); // Normalize
gl.uniform3fv(vLightDirection, lightDirection.elements);
// Clear color and depth buffer
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// Draw
drawHourGlass(gl, vpMatrix, mMVP, mNormal, null, false);
drawPlaneBase(gl, vpMatrix, mMVP, mNormal, null, false);
requestAnimationFrame(tick, canvas);
};
tick();
}
function ponctual_light() {
var canvas = document.getElementById('my-canvas2');
// Get the rendering context for WebGL
var gl = getWebGLContext(canvas);
if (!gl) {
console.log('Failed to get the rendering context for WebGL');
return; return;
} }
// Initialize shaders shadow // Create the normal program
if (!initShaders(gl, SHADOW_VSHADER_SOURCE, SHADOW_FSHADER_SOURCE)) { var normalProgram = createProgram(gl, VSHADER_SOURCE, FSHADER_SOURCE);
console.log('Failed to intialize shaders.'); normalProgram.a_Position = gl.getAttribLocation(normalProgram, 'a_Position');
normalProgram.a_Color = gl.getAttribLocation(normalProgram, 'a_Color');
normalProgram.a_Normal = gl.getAttribLocation(normalProgram, 'a_Normal');
normalProgram.u_MvpMatrix = gl.getUniformLocation(normalProgram, 'u_MvpMatrix');
normalProgram.u_MvpMatrixFromLight = gl.getUniformLocation(normalProgram, 'u_MvpMatrixFromLight');
normalProgram.u_ShadowMap = gl.getUniformLocation(normalProgram, 'u_ShadowMap');
normalProgram.u_Clicked = gl.getUniformLocation(normalProgram, 'u_Clicked');
normalProgram.u_NormalMatrix = gl.getUniformLocation(normalProgram, 'u_NormalMatrix');
normalProgram.u_ModelMatrix = gl.getUniformLocation(normalProgram, 'u_ModelMatrix');
normalProgram.u_LightPosition = gl.getUniformLocation(normalProgram, 'u_LightPosition');
normalProgram.u_LightColor = gl.getUniformLocation(normalProgram, 'u_LightColor');
if (normalProgram.a_Position < 0 || normalProgram.a_Color < 0 || normalProgram.a_Normal < 0 || !normalProgram.u_MvpMatrix ||
!normalProgram.u_MvpMatrixFromLight || !normalProgram.u_ShadowMap || !normalProgram.u_Clicked || !normalProgram.u_NormalMatrix ||
!normalProgram.u_ModelMatrix || !normalProgram.u_LightPosition || !normalProgram.u_LightColor) {
console.log('Failed to get the storage location of attribute or uniform variable from normalProgram');
return; return;
} }
// Initialize shaders // Set the vertex information of objects for the draw
if (!initShaders(gl, VSHADER_SOURCE_PONCTUAL_LIGHT, FSHADER_SOURCE_PONCTUAL_LIGHT)) { var frustrum = initVertexBuffersForFrustrum(gl);
console.log('Failed to intialize shaders.'); var plane = initVertexBuffersForPlane(gl);
if (!frustrum || !plane) {
console.log('Failed to set the vertex information');
return; return;
} }
...@@ -242,27 +193,42 @@ function ponctual_light() { ...@@ -242,27 +193,42 @@ function ponctual_light() {
console.log('Failed to initialize frame buffer object'); console.log('Failed to initialize frame buffer object');
return; return;
} }
gl.activeTexture(gl.TEXTURE0); // Set a texture object to the texture unit
// Set a texture object to the texture unit
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, fbo.texture); gl.bindTexture(gl.TEXTURE_2D, fbo.texture);
// Set the clear color and enable the depth test // Set the clear color and enable the depth test
gl.clearColor(0, 0, 0, 1); gl.clearColor(0, 0, 0, 1);
gl.enable(gl.DEPTH_TEST); gl.enable(gl.DEPTH_TEST);
// Get the storage locations // View project for shadow map
var mModel = gl.getUniformLocation(gl.program, 'mModel'); var viewProjMatrixFromLight = new Matrix4();
var mMVP = gl.getUniformLocation(gl.program, 'mMVP'); viewProjMatrixFromLight.setPerspective(200.0, PERSPECTIVE_WIDTH_FROM_LIGHT/PERSPECTIVE_HEIGHT_FROM_LIGHT, 1.0, 100.0);
var mNormal = gl.getUniformLocation(gl.program, 'mNormal'); viewProjMatrixFromLight.lookAt(light_x, light_y, light_z, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
var vLightColor = gl.getUniformLocation(gl.program, 'vLightColor');
var vLightPosition = gl.getUniformLocation(gl.program, 'vLightPosition'); // View project for normal program
var u_Clicked = gl.getUniformLocation(gl.program, 'u_Clicked'); var viewProjMatrix = new Matrix4();
var u_is_hourglass = gl.getUniformLocation(gl.program, 'u_is_hourglass'); viewProjMatrix.setPerspective(45, canvas.width/canvas.height, 1.0, 100.0);
if (!mMVP || !mNormal || !vLightColor || !vLightPosition || !mModel || !u_Clicked) { viewProjMatrix.lookAt(eye_x, eye_y, eye_z, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
console.log('Failed to get the storage location');
return; // For the animation of hourglass
} var animateHourGlass = false;
var currentAngle = 0.0;
canvas.onmousedown = function(ev) { // Mouse is pressed var oldAngle = 0.0;
// A mvp for the 3 objects (2 frustrum and 1 plane)
var mvpMatrixFromLight_f = new Matrix4();
var mvpMatrixFromLight_f2 = new Matrix4();
var mvpMatrixFromLight_p = new Matrix4();
// Save data when event mouse clicked is active
var clicked_canvas = false;
var x_clicked = 0;
var y_clicked = 0;
// Event when mouse is clicked
canvas.onmousedown = function(ev) {
var x = ev.clientX, y = ev.clientY; var x = ev.clientX, y = ev.clientY;
var rect = ev.target.getBoundingClientRect(); var rect = ev.target.getBoundingClientRect();
if (rect.left <= x && x < rect.right && rect.top <= y && y < rect.bottom) { if (rect.left <= x && x < rect.right && rect.top <= y && y < rect.bottom) {
...@@ -272,162 +238,184 @@ function ponctual_light() { ...@@ -272,162 +238,184 @@ function ponctual_light() {
} }
} }
var vpMatrix = new Matrix4(); // View projection matrix // Tick for create a shadow map and drawing
var tick = function() {
// View project for light
viewProjMatrixFromLight.setPerspective(200.0, PERSPECTIVE_WIDTH_FROM_LIGHT/PERSPECTIVE_HEIGHT_FROM_LIGHT, 1.0, 100.0);
viewProjMatrixFromLight.lookAt(light_x, light_y, light_z, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
// View project for camera
viewProjMatrix.setPerspective(45, canvas.width/canvas.height, 1.0, 100.0);
viewProjMatrix.lookAt(eye_x, eye_y, eye_z, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
// Animate 180 degrees and change color of hourglass
if(animateHourGlass){
oldAngle = currentAngle
currentAngle += 1.0;
if(oldAngle >= 359 && gl.getUniform(normalProgram, normalProgram.u_Clicked) == 0){
animateHourGlass = false;
currentAngle = 0;
} else if(oldAngle >= 179 && gl.getUniform(normalProgram, normalProgram.u_Clicked) == 1){
animateHourGlass = false;
currentAngle = 180;
}
}
// Use of framebuffer object for shadow map
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.viewport(0, 0, PERSPECTIVE_WIDTH_FROM_LIGHT, PERSPECTIVE_HEIGHT_FROM_LIGHT);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
var tick = function () { // Use the programm shadow for generating a shadow map
// Set perspective and camera gl.useProgram(shadowProgram);
vpMatrix.setPerspective(50, canvas.width / canvas.height, 1, 100);
vpMatrix.lookAt(eyeX, eyeY, eyeZ, 0, 0, 0, 0, 1, 0);
// Set the light color (white) // Draw the two frustrum and plane for the shadow map
gl.uniform3f(vLightColor, 1.0, 1.0, 1.0); drawFrustrum(gl, shadowProgram, frustrum, currentAngle, viewProjMatrixFromLight, false);
// Set the light position mvpMatrixFromLight_f.set(tmp_mvpMatrix);
gl.uniform3f(vLightPosition, lightPositionX, lightPositionY, lightPositionZ); drawFrustrum(gl, shadowProgram, frustrum, currentAngle, viewProjMatrixFromLight, true);
mvpMatrixFromLight_f2.set(tmp_mvpMatrix);
drawPlane(gl, shadowProgram, plane, viewProjMatrixFromLight);
mvpMatrixFromLight_p.set(tmp_mvpMatrix);
// Clear color and depth buffer // Use the normal program and the default framebuffer
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.viewport(0, 0, canvas.width, canvas.height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
drawHourGlass(gl, vpMatrix, mMVP, mNormal, mModel, true, u_Clicked, u_is_hourglass); gl.useProgram(normalProgram);
drawPlaneBase(gl, vpMatrix, mMVP, mNormal, mModel, true, u_is_hourglass); gl.uniform3f(normalProgram.u_LightColor, 1.0, 1.0, 1.0); // The light is white
gl.uniform3f(normalProgram.u_LightPosition, light_x, light_y, light_z);
gl.uniform1i(normalProgram.u_ShadowMap, 0); // Pass 0 because gl.TEXTURE0 is enabled
// Draw the two frustrum and plane for the normal program
gl.uniformMatrix4fv(normalProgram.u_MvpMatrixFromLight, false, mvpMatrixFromLight_f.elements);
drawFrustrum(gl, normalProgram, frustrum, currentAngle, viewProjMatrix, false);
gl.uniformMatrix4fv(normalProgram.u_MvpMatrixFromLight, false, mvpMatrixFromLight_f2.elements);
drawFrustrum(gl, normalProgram, frustrum, currentAngle, viewProjMatrix, true);
gl.uniformMatrix4fv(normalProgram.u_MvpMatrixFromLight, false, mvpMatrixFromLight_p.elements);
drawPlane(gl, normalProgram, plane, viewProjMatrix);
// Change color and animate when clicked
if(clicked_canvas && animateHourGlass == false){
var pixels = new Uint8Array(4);
gl.readPixels(x_clicked, y_clicked, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
if(pixels[0] > 0 && pixels[1] == 0 && pixels[2] == 0){
gl.uniform1i(normalProgram.u_Clicked, 1);
animateHourGlass = true;
}
else if(pixels[0] == 0 && pixels[1] > 0 && pixels[2] == 0){
gl.uniform1i(normalProgram.u_Clicked, 0);
animateHourGlass = true;
}
clicked_canvas = false;
}
requestAnimationFrame(tick, canvas); window.requestAnimationFrame(tick, canvas);
}; };
tick(); tick();
} }
function drawPlaneBase(gl, vpMatrix, mMVP, mNormal, mModel, isPonct, u_is_hourglass) { function drawFrustrum(gl, program, frustrum, angle, viewProjMatrix, is_second) {
gl.uniform1i(u_is_hourglass, 0); // Rotate for the animation
var n = initVertexBuffersPlaneBase(gl); tmp_modelMatrix.setRotate(angle, 1, 0, 0);
if (n < 0) {
console.log('Failed to set the vertex information'); // Rotate the second frustrum
return; if(is_second){
rotationSecFrustrumMatrix.setRotate(180, 1, 0, 0)
tmp_modelMatrix.multiply(rotationSecFrustrumMatrix);
} }
var modelMatrixTranslate = new Matrix4(); // Change translate to have a good rotate animation
var mvpMatrix = new Matrix4(); translateFrustrumMatrix.setTranslate(0, -1, 0);
var normalMatrix = new Matrix4(); tmp_modelMatrix.multiply(translateFrustrumMatrix);
draw(gl, program, frustrum, viewProjMatrix);
modelMatrixTranslate.setTranslate(0, -0.001, 0); }
if (isPonct) {
gl.uniformMatrix4fv(mModel, false, modelMatrixTranslate.elements);
}
mvpMatrix.set(vpMatrix).multiply(modelMatrixTranslate);
gl.uniformMatrix4fv(mMVP, false, mvpMatrix.elements);
normalMatrix.setInverseOf(modelMatrixTranslate);
normalMatrix.transpose();
gl.uniformMatrix4fv(mNormal, false, normalMatrix.elements);
gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0); function drawPlane(gl, program, plane, viewProjMatrix) {
// translate the plane to be good with the hourglass
tmp_modelMatrix.setTranslate(0, -1, 0);
draw(gl, program, plane, viewProjMatrix);
} }
var angle = 0; function draw(gl, program, o, viewProjMatrix) {
var trans = 0; initAttributeVariable(gl, program.a_Position, o.vertexBuffer);
function drawHourGlass(gl, vpMatrix, mMVP, mNormal, mModel, isPonct, u_Clicked, u_is_hourglass) {
//angle += 1; // If programm shadow, he can't have the color buffer or normal buffer
gl.uniform1i(u_is_hourglass, 1); if (program.a_Color != undefined){
var n = initVertexBuffersHourglass(gl); initAttributeVariable(gl, program.a_Color, o.colorBuffer);
if (n < 0) {
console.log('Failed to set the vertex information');
return;
} }
var modelMatrixRotate = new Matrix4(); // Model matrix if (program.a_Normal != undefined){
var modelMatrixTranslate = new Matrix4(); initAttributeVariable(gl, program.a_Normal, o.normalsBuffer);
var modelMatrixScale = new Matrix4();
var mvpMatrix = new Matrix4(); // Model view projection matrix
var normalMatrix = new Matrix4(); // Transformation matrix for normals
// First frustrum
modelMatrixRotate.setRotate(0 + angle, 1, 0, 0); // Rotate around the y-axis
modelMatrixTranslate.setTranslate(0, 0.0 - trans, 0);
var finalModelMatrix = modelMatrixRotate.multiply(modelMatrixTranslate).multiply(modelMatrixScale);
if (isPonct) {
gl.uniformMatrix4fv(mModel, false, finalModelMatrix.elements);
} }
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, o.indexBuffer);
mvpMatrix.set(vpMatrix).multiply(modelMatrixRotate); // Calculate the mvp matrix and pass it to u_MvpMatrix
gl.uniformMatrix4fv(mMVP, false, mvpMatrix.elements); tmp_mvpMatrix.set(viewProjMatrix);
normalMatrix.setInverseOf(modelMatrixRotate); tmp_mvpMatrix.multiply(tmp_modelMatrix);
normalMatrix.transpose(); gl.uniformMatrix4fv(program.u_MvpMatrix, false, tmp_mvpMatrix.elements);
gl.uniformMatrix4fv(mNormal, false, normalMatrix.elements);
// Calculate normals
gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0); tmp_normalMatrix.setInverseOf(tmp_modelMatrix);
tmp_normalMatrix.transpose();
// Second frustrum gl.uniformMatrix4fv(program.u_NormalMatrix, false, tmp_normalMatrix.elements);
modelMatrixRotate.setRotate(180 + angle, 1, 0, 0);
modelMatrixTranslate.setTranslate(0, -2.0 + trans, 0); // Stock the model matrix
modelMatrixScale.setScale(-1, 1, -1); gl.uniformMatrix4fv(program.u_ModelMatrix, false, tmp_modelMatrix.elements);
var finalModelMatrix = modelMatrixRotate.multiply(modelMatrixTranslate).multiply(modelMatrixScale);
if (isPonct) { gl.drawElements(gl.TRIANGLES, o.numIndices, gl.UNSIGNED_BYTE, 0);
gl.uniformMatrix4fv(mModel, false, finalModelMatrix.elements);
}
mvpMatrix.set(vpMatrix).multiply(finalModelMatrix)
gl.uniformMatrix4fv(mMVP, false, mvpMatrix.elements);
normalMatrix.setInverseOf(finalModelMatrix);
normalMatrix.transpose();
gl.uniformMatrix4fv(mNormal, false, normalMatrix.elements);
gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);
if(clicked_canvas){
var pixels = new Uint8Array(4); // Array for storing the pixel value
gl.readPixels(x_clicked, y_clicked, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
console.log(pixels);
if(pixels[0] > 0){
console.log("Rouge");
if(isPonct){
gl.getUniform(gl.program, u_Clicked);
}
gl.uniform1i(u_Clicked, 1);
}
else if(pixels[1] > 0){
console.log("Vert");
gl.uniform1i(u_Clicked, 0);
}
clicked_canvas = false;
}
} }
function initVertexBuffersPlaneBase(gl) { // Assign the buffer objects and enable the assignment
var vertices_position = new Float32Array([ function initAttributeVariable(gl, a_attribute, buffer) {
-2.0, -0.5, -2.0, 2.0, -0.5, 2.0, -2.0, -0.5, 2.0, 2.0, -0.5, -2.0 gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.vertexAttribPointer(a_attribute, buffer.num, buffer.type, false, 0, 0);
gl.enableVertexAttribArray(a_attribute);
}
function initVertexBuffersForPlane(gl) {
// Vertex coordinates
var vertices = new Float32Array([
-5.0, -0.5, -5.0, 5.0, -0.5, 5.0, -5.0, -0.5, 5.0, 5.0, -0.5, -5.0
]); ]);
// Colors only white for this tp // Colors
var colors = new Float32Array([ var colors = new Float32Array([
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0
]); ]);
// Normals
var normals = new Float32Array([ var normals = new Float32Array([
0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0
]); ]);
var indices = new Uint8Array([ // Indices of the vertices
0, 1, 2, 0, 1, 3 var indices = new Uint8Array([0, 1, 2, 0, 1, 3]);
]);
var o = new Object(); // Utilize Object object to return multiple buffer objects together
// Write the vertex property to buffers (positions, colors and normals) // Write vertex information to buffer object
if (!initArrayBuffer(gl, 'a_Position', vertices_position, 3, gl.FLOAT)) return -1; o.vertexBuffer = initArrayBufferForLaterUse(gl, vertices, 3, gl.FLOAT);
if (!initArrayBuffer(gl, 'a_Color', colors, 3, gl.FLOAT)) return -1; o.colorBuffer = initArrayBufferForLaterUse(gl, colors, 3, gl.FLOAT);
if (!initArrayBuffer(gl, 'a_Normal', normals, 3, gl.FLOAT)) return -1; o.normalsBuffer = initArrayBufferForLaterUse(gl, normals, 3, gl.FLOAT);
o.indexBuffer = initElementArrayBufferForLaterUse(gl, indices, gl.UNSIGNED_BYTE);
if (!o.vertexBuffer || !o.colorBuffer || !o.indexBuffer || !o.normalsBuffer) return null;
o.numIndices = indices.length;
// Unbind the buffer object // Unbind the buffer object
gl.bindBuffer(gl.ARRAY_BUFFER, null); gl.bindBuffer(gl.ARRAY_BUFFER, null);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
// Write the indices to the buffer object return o;
var indexBuffer = gl.createBuffer();
if (!indexBuffer) {
console.log('Failed to create the buffer object');
return false;
}
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
return indices.length;
} }
function initVertexBuffersHourglass(gl) { function initVertexBuffersForFrustrum(gl) {
var vertices_position = new Float32Array([ // Vertex coordinates
var vertices = new Float32Array([
-0.25, 1.0, 0.25, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.25, 1.0, 0.25, // front face -0.25, 1.0, 0.25, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.25, 1.0, 0.25, // front face
0.25, 1.0, 0.25, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.25, 1.0, -0.25,// right face 0.25, 1.0, 0.25, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.25, 1.0, -0.25,// right face
-0.25, 1.0, -0.25, 0.25, 1.0, 0.25, -0.25, 1.0, 0.25, 0.25, 1.0, -0.25, // Up face -0.25, 1.0, -0.25, 0.25, 1.0, 0.25, -0.25, 1.0, 0.25, 0.25, 1.0, -0.25, // Up face
...@@ -436,7 +424,7 @@ function initVertexBuffersHourglass(gl) { ...@@ -436,7 +424,7 @@ function initVertexBuffersHourglass(gl) {
0.25, 1.0, -0.25, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.25, 1.0, -0.25 // back face 0.25, 1.0, -0.25, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.25, 1.0, -0.25 // back face
]); ]);
// Colors only red for this tp // Colors
var colors = new Float32Array([ var colors = new Float32Array([
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,
...@@ -445,17 +433,18 @@ function initVertexBuffersHourglass(gl) { ...@@ -445,17 +433,18 @@ function initVertexBuffersHourglass(gl) {
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0
]); ]);
var normals = new Float32Array([ var normals = new Float32Array([
0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, // front face 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, // front face
1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, // right face 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, // right face
0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, // up face 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, // up face
-1.0, 1.0, 0.0, -1.0, 1.0, 0.0, -1.0, 1.0, 0.0, -1.0, 1.0, 0.0, // left face -1.0, 1.0, 0.0, -1.0, 1.0, 0.0, -1.0, 1.0, 0.0, -1.0, 1.0, 0.0, // left face
0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, // down face 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, // down face
0.0, 1.0, -1.0, 0.0, 1.0, -1.0, 0.0, 1.0, -1.0, 0.0, 1.0, -1.0, // back face 0.0, 1.0, -1.0, 0.0, 1.0, -1.0, 0.0, 1.0, -1.0, 0.0, 1.0, -1.0 // back face
]); ]);
var indices = new Uint8Array([ // Indices of the vertices
var indices = new Uint8Array([
0, 1, 2, 0, 1, 3, // front Face 0, 1, 2, 0, 1, 3, // front Face
4, 5, 6, 4, 5, 7, // right face 4, 5, 6, 4, 5, 7, // right face
8, 9, 10, 8, 9, 11, // up face 8, 9, 10, 8, 9, 11, // up face
...@@ -464,49 +453,59 @@ function initVertexBuffersHourglass(gl) { ...@@ -464,49 +453,59 @@ function initVertexBuffersHourglass(gl) {
20, 21, 22, 20, 21, 23 // back face 20, 21, 22, 20, 21, 23 // back face
]); ]);
// Write the vertex property to buffers (positions, colors and normals) var o = new Object(); // Utilize Object object to return multiple buffer objects together
if (!initArrayBuffer(gl, 'a_Position', vertices_position, 3, gl.FLOAT)) return -1;
if (!initArrayBuffer(gl, 'a_Color', colors, 3, gl.FLOAT)) return -1; // Write vertex information to buffer object
if (!initArrayBuffer(gl, 'a_Normal', normals, 3, gl.FLOAT)) return -1; o.vertexBuffer = initArrayBufferForLaterUse(gl, vertices, 3, gl.FLOAT);
o.colorBuffer = initArrayBufferForLaterUse(gl, colors, 3, gl.FLOAT);
o.normalsBuffer = initArrayBufferForLaterUse(gl, normals, 3, gl.FLOAT);
o.indexBuffer = initElementArrayBufferForLaterUse(gl, indices, gl.UNSIGNED_BYTE);
if (!o.vertexBuffer || !o.colorBuffer || !o.indexBuffer || !o.normalsBuffer) return null;
o.numIndices = indices.length;
// Unbind the buffer object // Unbind the buffer object
gl.bindBuffer(gl.ARRAY_BUFFER, null); gl.bindBuffer(gl.ARRAY_BUFFER, null);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
// Write the indices to the buffer object return o;
var indexBuffer = gl.createBuffer();
if (!indexBuffer) {
console.log('Failed to create the buffer object');
return false;
}
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
return indices.length;
} }
function initArrayBuffer(gl, attribute, data, num, type) { function initArrayBufferForLaterUse(gl, data, num, type) {
// Create a buffer object // Create a buffer object
var buffer = gl.createBuffer(); var buffer = gl.createBuffer();
if (!buffer) { if (!buffer) {
console.log('Failed to create the buffer object'); console.log('Failed to create the buffer object');
return false; return null;
} }
// Write date into the buffer object // Write date into the buffer object
gl.bindBuffer(gl.ARRAY_BUFFER, buffer); gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW); gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
// Assign the buffer object to the attribute variable
var a_attribute = gl.getAttribLocation(gl.program, attribute); // Store the necessary information to assign the object to the attribute variable later
if (a_attribute < 0) { buffer.num = num;
console.log('Failed to get the storage location of ' + attribute); buffer.type = type;
return false;
return buffer;
}
function initElementArrayBufferForLaterUse(gl, data, type) {
// Create a buffer object
var buffer = gl.createBuffer();
if (!buffer) {
console.log('Failed to create the buffer object');
return null;
} }
gl.vertexAttribPointer(a_attribute, num, type, false, 0, 0); // Write date into the buffer object
// Enable the assignment of the buffer object to the attribute variable gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);
gl.enableVertexAttribArray(a_attribute); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, data, gl.STATIC_DRAW);
buffer.type = type;
return true; return buffer;
} }
// Create the framebuffer fbo for shadow map
function initFramebufferObject(gl) { function initFramebufferObject(gl) {
var framebuffer, texture, depthBuffer; var framebuffer, texture, depthBuffer;
...@@ -531,8 +530,9 @@ function initFramebufferObject(gl) { ...@@ -531,8 +530,9 @@ function initFramebufferObject(gl) {
console.log('Failed to create texture object'); console.log('Failed to create texture object');
return error(); return error();
} }
gl.bindTexture(gl.TEXTURE_2D, texture); gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, OFFSCREEN_WIDTH, OFFSCREEN_HEIGHT, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, PERSPECTIVE_WIDTH_FROM_LIGHT, PERSPECTIVE_HEIGHT_FROM_LIGHT, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
// Create a renderbuffer object and Set its size and parameters // Create a renderbuffer object and Set its size and parameters
...@@ -542,7 +542,7 @@ function initFramebufferObject(gl) { ...@@ -542,7 +542,7 @@ function initFramebufferObject(gl) {
return error(); return error();
} }
gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer); gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, OFFSCREEN_WIDTH, OFFSCREEN_HEIGHT); gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, PERSPECTIVE_WIDTH_FROM_LIGHT, PERSPECTIVE_HEIGHT_FROM_LIGHT);
// Attach the texture and the renderbuffer object to the FBO // Attach the texture and the renderbuffer object to the FBO
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment