2017-10-23 18:31:42 +00:00
|
|
|
// Prénoms, noms et matricule des membres de l'équipe:
|
|
|
|
// - Prénom1 NOM1 (matricule1)
|
|
|
|
// - Prénom2 NOM2 (matricule2)
|
|
|
|
|
|
|
|
|
|
|
|
// déclaration d'une structure pour contenir toutes les variables globales
|
|
|
|
var glob = { };
|
2017-12-10 04:53:20 +00:00
|
|
|
addTransformation(null, "rotation");
|
|
|
|
addTransformation(null, "translation");
|
|
|
|
addTransformation(null, "scale");
|
|
|
|
|
|
|
|
function addTrans(event)
|
|
|
|
{
|
|
|
|
var div = document.createElement("div");
|
|
|
|
var text = document.createTextNode("Plopiloup");
|
|
|
|
var transdiv = document.getElementById("transformations");
|
|
|
|
div.appendChild(text);
|
|
|
|
transdiv.appendChild(div);
|
|
|
|
}
|
|
|
|
|
|
|
|
function addTransformation(event, type)
|
|
|
|
{
|
|
|
|
var table = document.getElementById("trans-list");
|
|
|
|
var glyphClass;
|
|
|
|
switch (type) {
|
|
|
|
case "rotation":
|
|
|
|
glyphClass = "glyphicon-repeat";
|
|
|
|
break;
|
|
|
|
case "translation":
|
|
|
|
glyphClass = "glyphicon-move";
|
|
|
|
break;
|
|
|
|
case "scale":
|
|
|
|
glyphClass = "glyphicon-resize-small";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
glyphClass = "glyphicon-alert";
|
|
|
|
console.log("Unknown transformation type " + type);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
var tr = table.insertRow(-1);
|
|
|
|
tr.classList.add(type);
|
|
|
|
var span = document.createElement("span");
|
|
|
|
span.classList.add("glyphicon", glyphClass);
|
|
|
|
var td = tr.insertCell(-1);
|
|
|
|
td.appendChild(span);
|
|
|
|
var param = ["x", "y", "z", "𝜃"];
|
|
|
|
for (var i in param) {
|
|
|
|
td = tr.insertCell(-1);
|
|
|
|
if (param[i] === "𝜃" && type !== "rotation")
|
|
|
|
break;
|
|
|
|
var input = document.createElement("input");
|
|
|
|
input.setAttribute("type", "text");
|
|
|
|
input.setAttribute("value", type === "scale" ? "1" : "0");
|
|
|
|
input.setAttribute("name", param[i]);
|
|
|
|
input.setAttribute("class", "form-control");
|
|
|
|
input.addEventListener("change", updateTransformations, false);
|
|
|
|
input.addEventListener("keyup", updateTransformations, false);
|
|
|
|
td.appendChild(input);
|
|
|
|
}
|
|
|
|
var button = document.createElement('button');
|
|
|
|
button.classList.add("btn", "btn-danger", "btn-sm");
|
|
|
|
button.setAttribute("type", "button");
|
|
|
|
button.addEventListener("click", removeTransformation, false);
|
|
|
|
span = document.createElement("span");
|
|
|
|
span.classList.add("glyphicon", "glyphicon-trash");
|
|
|
|
button.appendChild(span);
|
|
|
|
tr.insertCell(-1).appendChild(button);
|
|
|
|
}
|
|
|
|
|
|
|
|
function removeTransformation(event)
|
|
|
|
{
|
|
|
|
var tr = event.target.parentNode.parentNode;
|
|
|
|
tr.parentNode.removeChild(tr);
|
|
|
|
updateTransformations(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
function updateTransformations(event)
|
|
|
|
{
|
|
|
|
glob.transformations = [];
|
|
|
|
var table = document.getElementById("trans-list");
|
|
|
|
var x,y,z,𝜃,row,type;
|
|
|
|
for (var i = 1; i < table.rows.length; i++) {
|
|
|
|
row = table.rows[i];
|
|
|
|
x = row.querySelector('input[name="x"]').value;
|
|
|
|
y = row.querySelector('input[name="y"]').value;
|
|
|
|
z = row.querySelector('input[name="z"]').value;
|
|
|
|
𝜃 = row.querySelector('input[name="𝜃"]');
|
|
|
|
if (𝜃 !== null)
|
|
|
|
𝜃 = 𝜃.value;
|
|
|
|
type = row.className;
|
|
|
|
glob.transformations.push({type: type, x: x, y: y, z: z, 𝜃: 𝜃});
|
|
|
|
}
|
|
|
|
}
|
2017-10-23 18:31:42 +00:00
|
|
|
|
|
|
|
function handleMouseDown(event)
|
|
|
|
{
|
|
|
|
glob.mouseDown = true;
|
2017-12-10 04:53:20 +00:00
|
|
|
var rect = glob.canevas.getBoundingClientRect();
|
|
|
|
glob.positionSourisX = event.clientX - rect.left;
|
|
|
|
glob.positionSourisY = event.clientY - rect.top;
|
2017-10-23 18:31:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function handleMouseUp(event)
|
|
|
|
{
|
|
|
|
glob.mouseDown = false;
|
|
|
|
glob.positionSourisX = null;
|
|
|
|
glob.positionSourisY = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
function handleMouseMove(event)
|
|
|
|
{
|
|
|
|
if (!glob.mouseDown) return;
|
2017-12-10 04:53:20 +00:00
|
|
|
var rect = glob.canevas.getBoundingClientRect();
|
|
|
|
glob.positionSourisX = event.clientX - rect.left;
|
|
|
|
glob.positionSourisY = event.clientY - rect.top;
|
2017-10-23 18:31:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// makeRepere
|
|
|
|
//
|
|
|
|
// Create a repere with vertices, normals and texCoords. Create VBOs for each as well as the index array.
|
|
|
|
// Return an object with the following properties:
|
|
|
|
//
|
|
|
|
// normalObject WebGLBuffer object for normals
|
|
|
|
// texCoordObject WebGLBuffer object for texCoords
|
|
|
|
// vertexObject WebGLBuffer object for vertices
|
|
|
|
// indexObject WebGLBuffer object for indices
|
|
|
|
// numIndices The number of indices in the indexObject
|
|
|
|
//
|
|
|
|
function makeRepere(ctx)
|
|
|
|
{
|
|
|
|
// box
|
|
|
|
// v2
|
|
|
|
// |
|
|
|
|
// |
|
|
|
|
// |
|
|
|
|
// v0 o------v1
|
|
|
|
// /
|
|
|
|
// v3
|
|
|
|
//
|
|
|
|
// vertex coords array
|
|
|
|
var vertices = new Float32Array(
|
|
|
|
[ 0, 0, 0, 1, 0, 0, // v0 -> v1 vec X
|
|
|
|
0, 0, 0, 0, 1, 0, // v0 -> v2 vec Y
|
|
|
|
0, 0, 0, 0, 0, 1 ]// v0 -> v3 vec Z
|
|
|
|
);
|
|
|
|
|
|
|
|
// colors array
|
|
|
|
var colors = new Float32Array(
|
|
|
|
[ 1, 0, 0, 1, 0, 0, // v0 -> v1 vec X
|
|
|
|
0, 1, 0, 0, 1, 0, // v0 -> v2 vec Y
|
|
|
|
0, 0, 1, 0, 0, 1 ]// v0 -> v3 vec Z
|
|
|
|
);
|
|
|
|
|
|
|
|
// index array
|
|
|
|
var indices = new Uint8Array(
|
|
|
|
[ 0, 1,
|
|
|
|
2, 3,
|
|
|
|
4, 5 ]
|
|
|
|
);
|
|
|
|
|
|
|
|
var retval = { };
|
|
|
|
|
|
|
|
retval.vertexObject = ctx.createBuffer();
|
|
|
|
ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.vertexObject);
|
|
|
|
ctx.bufferData(ctx.ARRAY_BUFFER, vertices, ctx.STATIC_DRAW);
|
|
|
|
|
|
|
|
retval.colorObject = ctx.createBuffer();
|
|
|
|
ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.colorObject);
|
|
|
|
ctx.bufferData(ctx.ARRAY_BUFFER, colors, ctx.STATIC_DRAW);
|
|
|
|
|
|
|
|
ctx.bindBuffer(ctx.ARRAY_BUFFER, null);
|
|
|
|
|
|
|
|
retval.indexObject = ctx.createBuffer();
|
|
|
|
ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, retval.indexObject);
|
|
|
|
ctx.bufferData(ctx.ELEMENT_ARRAY_BUFFER, indices, ctx.STATIC_DRAW);
|
|
|
|
ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, null);
|
|
|
|
|
|
|
|
retval.numIndices = indices.length;
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
function TPchargerTextures()
|
|
|
|
{
|
|
|
|
// Charger une image utilisée comme texture. (Retourne un objet WebGLTexture)
|
2017-12-10 04:53:20 +00:00
|
|
|
//glob.texture1 = loadImageTexture( gl, "images/Brouillard.jpg" );
|
|
|
|
//glob.texture2 = loadImageTexture( gl, "images/Exploration.jpg" );
|
2017-10-23 18:31:42 +00:00
|
|
|
//glob.texture3 = loadImageTexture( gl, "images/Modelisation.jpg" );
|
|
|
|
}
|
|
|
|
|
|
|
|
function TPcreerModele()
|
|
|
|
{
|
|
|
|
// Créer une boîte. Au retour, 'glob.box' contient une structure avec
|
|
|
|
// les VBOs pour les sommets, normales, coordonnées de texture et connectivité.
|
|
|
|
glob.box = makeRepere( gl );
|
|
|
|
|
|
|
|
// Initialiser les attributs pour les sommets, les normales et les coordonnées de texture
|
|
|
|
// (dans le même ordre qu'à l'appel à simpleSetup() dans la fonction TPinitialiser())
|
|
|
|
gl.enableVertexAttribArray( 0 );
|
|
|
|
gl.bindBuffer( gl.ARRAY_BUFFER, glob.box.vertexObject );
|
|
|
|
gl.vertexAttribPointer( 0, 3, gl.FLOAT, false, 0, 0 );
|
|
|
|
|
|
|
|
gl.enableVertexAttribArray( 1 );
|
|
|
|
gl.bindBuffer( gl.ARRAY_BUFFER, glob.box.colorObject );
|
|
|
|
gl.vertexAttribPointer( 1, 3, gl.FLOAT, false, 0, 0 );
|
|
|
|
|
|
|
|
// Lier le tableau de connectivité
|
|
|
|
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, glob.box.indexObject );
|
|
|
|
}
|
|
|
|
|
|
|
|
function TPinitialiser()
|
|
|
|
{
|
|
|
|
// Initialiser webgl
|
|
|
|
var gl = initWebGL( "tp-canevas" ); // L'identificateur du canevas
|
|
|
|
if (!gl) return;
|
|
|
|
|
|
|
|
glob.program = simpleSetup( gl,
|
|
|
|
// Les identificateurs des deux nuanceurs
|
|
|
|
"nuanceurSommets", "nuanceurFragments",
|
|
|
|
// Les attributs utilisés par les nuanceurs (donnés dans le même ordre que leur indice)
|
|
|
|
[ "vPosition", "vColor" ],
|
|
|
|
// La couleur de fond et la profondeur
|
2017-12-10 04:53:20 +00:00
|
|
|
[ 0x00/255, 0x2b/255, 0x36/255, 1 ], 100);
|
2017-10-23 18:31:42 +00:00
|
|
|
|
|
|
|
// Les angles courants de rotation
|
|
|
|
glob.angleRotX = 0, glob.angleRotY = 0, glob.angleRotZ = 0;
|
|
|
|
// Les incréments à chaque affichage
|
|
|
|
glob.incrRotX = 0.2; glob.incrRotY = 0.3; glob.incrRotZ = 0.4;
|
|
|
|
|
|
|
|
// Créer les matrices nécessaires et assigner les assigner dans le programme
|
2017-12-10 04:53:20 +00:00
|
|
|
glob.modelMatrix = mat4.create();
|
|
|
|
glob.viewMatrix = mat4.create();
|
2017-10-23 21:34:21 +00:00
|
|
|
glob.modelMatLoc = gl.getUniformLocation( glob.program, "mmodel" );
|
|
|
|
glob.viewMatLoc = gl.getUniformLocation( glob.program, "mview" );
|
|
|
|
glob.projMatLoc = gl.getUniformLocation( glob.program, "mproj" );
|
2017-10-23 18:31:42 +00:00
|
|
|
|
|
|
|
// terminer l'initialisation
|
|
|
|
TPchargerTextures();
|
|
|
|
TPcreerModele();
|
|
|
|
|
|
|
|
glob.mouseDown = false;
|
|
|
|
glob.positionSourisX = null;
|
|
|
|
glob.positionSourisY = null;
|
|
|
|
glob.canevas.onmousedown = handleMouseDown;
|
|
|
|
glob.canevas.onmouseup = handleMouseUp;
|
|
|
|
glob.canevas.onmousemove = handleMouseMove;
|
2017-12-10 04:53:20 +00:00
|
|
|
glob.transformations = [];
|
2017-10-23 18:31:42 +00:00
|
|
|
|
|
|
|
// Initialiser les variables uniformes pour les nuanceurs
|
|
|
|
gl.uniform3f( gl.getUniformLocation( glob.program, "lightDir" ), 0, 0, 1 );
|
|
|
|
gl.uniform1i( gl.getUniformLocation( glob.program, "laTexture" ), 0 );
|
|
|
|
gl.uniform2f( gl.getUniformLocation( glob.program, "positionSouris" ), glob.positionSourisX, glob.positionSourisY );
|
|
|
|
|
|
|
|
return gl;
|
|
|
|
}
|
|
|
|
|
2017-10-23 21:34:21 +00:00
|
|
|
function TPafficherModele( gl )
|
2017-10-23 18:31:42 +00:00
|
|
|
{
|
|
|
|
gl.uniform2f( gl.getUniformLocation( glob.program, "positionSouris" ), glob.positionSourisX, glob.canevas.height-glob.positionSourisY );
|
|
|
|
|
|
|
|
// Tracer le cube
|
|
|
|
gl.drawElements( gl.LINES, glob.box.numIndices, gl.UNSIGNED_BYTE, 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
function TPafficherScene(gl)
|
|
|
|
{
|
2017-12-10 04:53:20 +00:00
|
|
|
glob.perspectiveMatrix = mat4.create();
|
|
|
|
glob.perspectiveMatrix = mat4.perspective(glob.perspectiveMatrix, 70. * 3.14159 / 180., glob.canevas.width / glob.canevas.height, 0.01, 10 );
|
|
|
|
gl.uniformMatrix4fv(glob.projMatLoc, false, glob.perspectiveMatrix);
|
2017-10-23 18:31:42 +00:00
|
|
|
|
|
|
|
// Effacer le canevas
|
|
|
|
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
|
|
|
|
|
|
|
|
// Définir la clôture 1
|
|
|
|
gl.viewport( 0, 0, glob.canevas.width, glob.canevas.height );
|
2017-10-23 21:34:21 +00:00
|
|
|
|
|
|
|
// Incrémenter les angles de rotation
|
|
|
|
glob.angleRotX += glob.incrRotX; if ( glob.angleRotX >= 360.0 ) glob.angleRotX -= 360.0;
|
|
|
|
glob.angleRotY += glob.incrRotY; if ( glob.angleRotY >= 360.0 ) glob.angleRotY -= 360.0;
|
|
|
|
glob.angleRotZ += glob.incrRotZ; if ( glob.angleRotZ >= 360.0 ) glob.angleRotZ -= 360.0;
|
|
|
|
|
|
|
|
// Construire la matrice de modélisation
|
2017-12-10 04:53:20 +00:00
|
|
|
mat4.lookAt( glob.viewMatrix, [5, 5, 5], [0, 0, 0], [0, 1, 0] );
|
|
|
|
gl.uniformMatrix4fv(glob.viewMatLoc, false, glob.viewMatrix);
|
2017-10-23 21:34:21 +00:00
|
|
|
|
2017-12-10 04:53:20 +00:00
|
|
|
mat4.identity(glob.modelMatrix);
|
|
|
|
gl.uniformMatrix4fv(glob.modelMatLoc, false, glob.modelMatrix);
|
2017-10-23 21:34:21 +00:00
|
|
|
TPafficherModele( gl );
|
|
|
|
|
2017-12-10 04:53:20 +00:00
|
|
|
for (var i = 0; glob.transformations.length > i; i++) {
|
|
|
|
var t = glob.transformations[i];
|
|
|
|
var v = vec3.fromValues(t.x, t.y, t.z);
|
|
|
|
switch(t.type) {
|
|
|
|
case "rotation":
|
|
|
|
mat4.rotate(glob.modelMatrix, glob.modelMatrix, glMatrix.toRadian(t.𝜃), v);
|
|
|
|
break;
|
|
|
|
case "translation":
|
|
|
|
mat4.translate(glob.modelMatrix, glob.modelMatrix, v);
|
|
|
|
break;
|
|
|
|
case "scale":
|
|
|
|
mat4.scale(glob.modelMatrix, glob.modelMatrix, v);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
console.log("Unknown transformation type : " + t.type);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
gl.uniformMatrix4fv(glob.modelMatLoc, false, glob.modelMatrix);
|
|
|
|
TPafficherModele( gl );
|
|
|
|
}
|
|
|
|
|
|
|
|
//glob.modelMatrix.rotate( glob.angleRotX, 1.0, 0.0, 0.0 );
|
|
|
|
//glob.modelMatrix.setUniform(gl, glob.modelMatLoc, false);
|
|
|
|
//TPafficherModele(gl);
|
|
|
|
|
|
|
|
//glob.modelMatrix.rotate( glob.angleRotY, 0.0, 1.0, 0.0 );
|
|
|
|
//glob.modelMatrix.setUniform(gl, glob.modelMatLoc, false);
|
|
|
|
//TPafficherModele(gl);
|
|
|
|
|
|
|
|
//glob.modelMatrix.rotate( glob.angleRotZ, 0.0, 0.0, 1.0 );
|
|
|
|
//glob.modelMatrix.setUniform(gl, glob.modelMatLoc, false);
|
|
|
|
//TPafficherModele( gl );
|
2017-10-23 18:31:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var requestId;
|
|
|
|
function TPdebut()
|
|
|
|
{
|
|
|
|
glob.canevas = document.getElementById('tp-canevas');
|
|
|
|
//glob.canevas = WebGLDebugUtils.makeLostContextSimulatingCanvas(c);
|
|
|
|
// indiquer de perdre le contexte afin de tester
|
|
|
|
//glob.canevas.loseContextInNCalls(15);
|
|
|
|
glob.canevas.addEventListener('webglcontextlost', handleContextLost, false);
|
|
|
|
glob.canevas.addEventListener('webglcontextrestored', handleContextRestored, false);
|
|
|
|
|
|
|
|
var gl = TPinitialiser();
|
|
|
|
if ( !gl ) return;
|
|
|
|
|
|
|
|
var displayFunc = function()
|
|
|
|
{
|
|
|
|
TPafficherScene(gl);
|
|
|
|
requestId = window.requestAnimFrame( displayFunc, glob.canevas );
|
|
|
|
};
|
|
|
|
displayFunc();
|
|
|
|
|
|
|
|
function handleContextLost(e)
|
|
|
|
{
|
|
|
|
e.preventDefault();
|
|
|
|
clearLoadingImages();
|
|
|
|
if ( requestId !== undefined )
|
|
|
|
{
|
|
|
|
window.cancelAnimFrame(requestId);
|
|
|
|
requestId = undefined;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function handleContextRestored()
|
|
|
|
{
|
|
|
|
TPinitialiser();
|
|
|
|
displayFunc();
|
|
|
|
}
|
|
|
|
}
|