a3979b9300
Les fichiers de resources ont été bougés dans leur dossiers propres (css, js, fonts). La position de la souris dans le canvas est maintenant correcte quelle que soit la position du canvas dans la page.
360 lines
12 KiB
JavaScript
360 lines
12 KiB
JavaScript
// 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 = { };
|
|
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, 𝜃: 𝜃});
|
|
}
|
|
}
|
|
|
|
function handleMouseDown(event)
|
|
{
|
|
glob.mouseDown = true;
|
|
var rect = glob.canevas.getBoundingClientRect();
|
|
glob.positionSourisX = event.clientX - rect.left;
|
|
glob.positionSourisY = event.clientY - rect.top;
|
|
}
|
|
|
|
function handleMouseUp(event)
|
|
{
|
|
glob.mouseDown = false;
|
|
glob.positionSourisX = null;
|
|
glob.positionSourisY = null;
|
|
}
|
|
|
|
function handleMouseMove(event)
|
|
{
|
|
if (!glob.mouseDown) return;
|
|
var rect = glob.canevas.getBoundingClientRect();
|
|
glob.positionSourisX = event.clientX - rect.left;
|
|
glob.positionSourisY = event.clientY - rect.top;
|
|
}
|
|
|
|
//
|
|
// 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)
|
|
//glob.texture1 = loadImageTexture( gl, "images/Brouillard.jpg" );
|
|
//glob.texture2 = loadImageTexture( gl, "images/Exploration.jpg" );
|
|
//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
|
|
[ 0x00/255, 0x2b/255, 0x36/255, 1 ], 100);
|
|
|
|
// 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
|
|
glob.modelMatrix = mat4.create();
|
|
glob.viewMatrix = mat4.create();
|
|
glob.modelMatLoc = gl.getUniformLocation( glob.program, "mmodel" );
|
|
glob.viewMatLoc = gl.getUniformLocation( glob.program, "mview" );
|
|
glob.projMatLoc = gl.getUniformLocation( glob.program, "mproj" );
|
|
|
|
// 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;
|
|
glob.transformations = [];
|
|
|
|
// 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;
|
|
}
|
|
|
|
function TPafficherModele( gl )
|
|
{
|
|
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)
|
|
{
|
|
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);
|
|
|
|
// 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 );
|
|
|
|
// 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
|
|
mat4.lookAt( glob.viewMatrix, [5, 5, 5], [0, 0, 0], [0, 1, 0] );
|
|
gl.uniformMatrix4fv(glob.viewMatLoc, false, glob.viewMatrix);
|
|
|
|
mat4.identity(glob.modelMatrix);
|
|
gl.uniformMatrix4fv(glob.modelMatLoc, false, glob.modelMatrix);
|
|
TPafficherModele( gl );
|
|
|
|
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 );
|
|
}
|
|
|
|
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();
|
|
}
|
|
}
|