I'm doing a project that I have to move a camera with an object in the scene. I can move the camera correctly in the scene. However there's not the object.
I don't understand which is the error because I transform the object and then I multiply that matrix with the camera matrix and I think it's the steps I have to follow.
Hope you can help me.
const {mat4} = glMatrix;
var examplePlane = { // 4 vértices, 2 triángulos
"vertices" : [-0.5, 0.0, 0.5,
0.5, 0.0, 0.5,
0.5, 0.0,-0.5,
-0.5, 0.0,-0.5],
"indices" : [0, 1, 2, 0, 2, 3]
};
var exampleCube = { // 8 vértices, 12 triángulos
"vertices" : [-0.5,-0.5, 0.5,
0.5,-0.5, 0.5,
0.5, 0.5, 0.5,
-0.5, 0.5, 0.5,
-0.5,-0.5, -0.5,
0.5,-0.5, -0.5,
0.5, 0.5, -0.5,
-0.5, 0.5, -0.5],
"indices" : [ 0, 1, 2, 0, 2, 3,
1, 5, 6, 1, 6, 2,
3, 2, 6, 3, 6, 7,
5, 4, 7, 5, 7, 6,
4, 0, 3, 4, 3, 7,
4, 5, 1, 4, 1, 0]
};
var exampleCover = { // 13 vértices, 12 triángulos
"vertices" : [ 1, 0, 0, 0.866, 0.5, 0, 0.5, 0.866, 0,
0, 1, 0, -0.5, 0.866, 0, -0.86, 0.5, 0,
-1, 0, 0, -0.866, -0.5, 0, -0.5, -0.866, 0,
0, -1, 0, 0.5, -0.866, 0, 0.866, -0.5, 0,
0, 0, 0],
"indices" : [ 0, 1, 12, 1, 2, 12, 2, 3, 12, 3, 4, 12, 4, 5, 12, 5, 6, 12,
6, 7, 12, 7, 8, 12, 8, 9, 12, 9, 10, 12, 10, 11, 12, 11, 0, 12]
};
var exampleCone = { // 13 vértices, 12 triángulos
"vertices" : [ 1, 0, 0, 0.866, 0.5, 0, 0.5, 0.866, 0,
0, 1, 0, -0.5, 0.866, 0, -0.86, 0.5, 0,
-1, 0, 0, -0.866, -0.5, 0, -0.5, -0.866, 0,
0, -1, 0, 0.5, -0.866, 0, 0.866, -0.5, 0,
0, 0, 1],
"indices" : [ 0, 1, 12, 1, 2, 12, 2, 3, 12, 3, 4, 12, 4, 5, 12, 5, 6, 12,
6, 7, 12, 7, 8, 12, 8, 9, 12, 9, 10, 12, 10, 11, 12, 11, 0, 12]
};
var exampleCylinder = { // 24 vértices, 24 triángulos
"vertices" : [ 1, 0, 0, 0.866, 0.5, 0, 0.5, 0.866, 0,
0, 1, 0, -0.5, 0.866, 0, -0.86, 0.5, 0,
-1, 0, 0, -0.866, -0.5, 0, -0.5, -0.866, 0,
0, -1, 0, 0.5, -0.866, 0, 0.866, -0.5, 0,
1, 0, 1, 0.866, 0.5, 1, 0.5, 0.866, 1,
0, 1, 1, -0.5, 0.866, 1, -0.86, 0.5, 1,
-1, 0, 1, -0.866, -0.5, 1, -0.5, -0.866, 1,
0, -1, 1, 0.5, -0.866, 1, 0.866, -0.5, 1],
"indices" : [ 0, 1, 12, 1, 2, 13, 2, 3, 14, 3, 4, 15, 4, 5, 16, 5, 6, 17,
6, 7, 18, 7, 8, 19, 8, 9, 20, 9, 10, 21, 10, 11, 22, 11, 0, 23,
1, 13, 12, 2, 14, 13, 3, 15, 14, 4, 16, 15, 5, 17, 16, 6, 18, 17,
7, 19, 18, 8, 20, 19, 9, 21, 20, 10, 22, 21, 11, 23, 22, 0, 12, 23]
};
var exampleSphere = { // 42 vértices, 80 triángulos
"vertices" : [ 0.000000, 0.850651, 0.525731,
-0.309017, 0.500000, 0.809017,
0.309017, 0.500000, 0.809017,
-0.525731, 0.000000, 0.850651,
0.000000, 0.000000, 1.000000,
0.525731, 0.000000, 0.850651,
-0.850651, 0.525731, 0.000000,
-0.809017, 0.309017, 0.500000,
-0.500000, 0.809017, 0.309017,
0.000000, 0.850651,-0.525731,
-0.500000, 0.809017,-0.309017,
0.000000, 1.000000, 0.000000,
0.500000, 0.809017,-0.309017,
0.500000, 0.809017, 0.309017,
0.850651, 0.525731, 0.000000,
0.809017, 0.309017, 0.500000,
0.850651,-0.525731, 0.000000,
1.000000, 0.000000, 0.000000,
0.809017,-0.309017, 0.500000,
0.525731, 0.000000,-0.850651,
0.809017, 0.309017,-0.500000,
0.809017,-0.309017,-0.500000,
0.309017, 0.500000,-0.809017,
-0.525731, 0.000000,-0.850651,
-0.309017, 0.500000,-0.809017,
0.000000, 0.000000,-1.000000,
0.000000,-0.850651,-0.525731,
-0.309017,-0.500000,-0.809017,
0.309017,-0.500000,-0.809017,
0.500000,-0.809017,-0.309017,
0.000000,-0.850651, 0.525731,
0.000000,-1.000000, 0.000000,
0.500000,-0.809017, 0.309017,
-0.850651,-0.525731, 0.000000,
-0.500000,-0.809017,-0.309017,
-0.500000,-0.809017, 0.309017,
-0.809017,-0.309017, 0.500000,
-0.309017,-0.500000, 0.809017,
0.309017,-0.500000, 0.809017,
-1.000000, 0.000000, 0.000000,
-0.809017,-0.309017,-0.500000,
-0.809017, 0.309017,-0.500000],
"indices" : [ 1, 2, 0, 4, 1, 3, 2, 4, 5, 4, 2, 1, 7, 8, 6, 1, 7, 3, 8, 1, 0, 1, 8, 7,10,11, 9, 8,10, 6,
11, 8, 0, 8,11,10,11,12, 9,13,11, 0,12,13,14,13,12,11,13,15,14, 2,13, 0,15, 2, 5, 2,15,13,
17,18,16,15,17,14,18,15, 5,15,18,17,20,21,19,17,20,14,21,17,16,17,21,20,22,20,19,12,22, 9,
20,12,14,12,20,22,24,25,23,22,24, 9,25,22,19,22,25,24,27,28,26,25,27,23,28,25,19,25,28,27,
29,21,16,28,29,26,21,28,19,28,21,29,31,32,30,29,31,26,32,29,16,29,32,31,34,35,33,31,34,26,
35,31,30,31,35,34,36,37, 3,35,36,33,37,35,30,35,37,36, 4,38, 5,37, 4, 3,38,37,30,37,38, 4,
38,18, 5,32,38,30,18,32,16,32,18,38, 7,36, 3,39, 7, 6,36,39,33,39,36, 7,39,40,33,41,39, 6,
40,41,23,41,40,39,41,24,23,10,41, 6,24,10, 9,10,24,41,27,40,23,34,27,26,40,34,33,34,40,27]
};
function makeTorus (innerRadius, outerRadius, nSides, nRings) {
var torus = {
"vertices" : [],
"indices" : []
};
if (nSides < 3 ) nSides = 3;
if (nRings < 3 ) nRings = 3;
var dpsi = 2.0 * Math.PI / nRings ;
var dphi = -2.0 * Math.PI / nSides ;
var psi = 0.0;
for (var j = 0; j < nRings; j++) {
var cpsi = Math.cos ( psi ) ;
var spsi = Math.sin ( psi ) ;
var phi = 0.0;
for (var i = 0; i < nSides; i++) {
var offset = 3 * ( j * (nSides+1) + i ) ;
var cphi = Math.cos ( phi ) ;
var sphi = Math.sin ( phi ) ;
torus.vertices[offset + 0] = cpsi * ( outerRadius + cphi * innerRadius ) ;
torus.vertices[offset + 1] = spsi * ( outerRadius + cphi * innerRadius ) ;
torus.vertices[offset + 2] = sphi * innerRadius ;
phi += dphi;
}
var offset = torus.vertices.length;
for (var i = 0; i < 3; i++)
torus.vertices[offset + i] = torus.vertices[offset-nSides*3+i];
psi += dpsi;
}
var offset = torus.vertices.length;
for (var i = 0; i < 3*(nSides+1); i++)
torus.vertices[offset+i] = torus.vertices[i];
for (var j = 0; j < nRings; j++){
var desp = j * (nSides + 1);
for (var i = 0; i < nSides; i++){
torus.indices.push(desp + i, desp + i + 1, desp + i + (nSides+1));
torus.indices.push(desp + i + 1, desp + i + (nSides+1) + 1, desp + i + (nSides+1));
}
}
return torus;
}
var gl, program;
var myTorus;
var myZeta = 0.0, myPhi = Math.PI/2.0, radius = 1.4, fovy = 1.4;
function getWebGLContext() {
var canvas = document.getElementById("myCanvas");
try {
return canvas.getContext("webgl2",{antialias:true});
}
catch(e) {
}
return null;
}
function initShaders() {
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, document.getElementById("myVertexShader").text);
gl.compileShader(vertexShader);
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(vertexShader));
return null;
}
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, document.getElementById("myFragmentShader").text);
gl.compileShader(fragmentShader);
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(fragmentShader));
return null;
}
program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
idMyColor = gl.getUniformLocation (program, "myColor" );
program.vertexPositionAttribute = gl.getAttribLocation(program, "VertexPosition");
gl.enableVertexAttribArray(program.vertexPositionAttribute);
program.modelViewMatrixIndex = gl.getUniformLocation(program,"modelViewMatrix");
program.projectionMatrixIndex = gl.getUniformLocation(program,"projectionMatrix");
}
function initRendering() {
gl.clearColor(0.95,0.95,0.95,1.0);
gl.lineWidth(1.5);
gl.enable(gl.DEPTH_TEST);
}
function initBuffers(model) {
model.idBufferVertices = gl.createBuffer ();
gl.bindBuffer (gl.ARRAY_BUFFER, model.idBufferVertices);
gl.bufferData (gl.ARRAY_BUFFER, new Float32Array(model.vertices), gl.STATIC_DRAW);
model.idBufferIndices = gl.createBuffer ();
gl.bindBuffer (gl.ELEMENT_ARRAY_BUFFER, model.idBufferIndices);
gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(model.indices), gl.STATIC_DRAW);
}
function draw(model) {
console.log(model);
gl.bindBuffer(gl.ARRAY_BUFFER, model.idBufferVertices);
gl.vertexAttribPointer(program.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, model.idBufferIndices);
for (var i = 0; i < model.indices.length; i += 3)
// Si paint es true vol dir que volem pintar per tant farem el triangle_fan
gl.drawElements (gl.TRIANGLE_FAN, 3, gl.UNSIGNED_SHORT, i*2);
}
// set projection (apliquem una projecció al dibuix)
function setProjection() {
// obtiene la matriz de transformación de la proyección perspectiva
var projectionMatrix = mat4.create();
// perspective
mat4.perspective(projectionMatrix, Math.PI/4.0, 1., 0.1, 100.0);
// envía la matriz de transformación de la proyección al shader de vértices
gl.uniformMatrix4fv(program.projectionMatrixIndex,false,projectionMatrix);
}
function initPrimitives() {
initBuffers(examplePlane);
initBuffers(exampleCube);
initBuffers(exampleCover);
initBuffers(exampleCone);
initBuffers(exampleCylinder);
initBuffers(exampleSphere);
myTorus = makeTorus(0.4, 1.0, 8, 12);
initBuffers(myTorus);
}
function getCameraMatrix() {
// coordenadas esféricas a rectangulares: https://en.wikipedia.org/wiki/Spherical_coordinate_system
var x = radius * Math.sin(myPhi) * Math.sin(myZeta);
var y = radius * Math.cos(myPhi);
var z = radius * Math.sin(myPhi) * Math.cos(myZeta);
return mat4.lookAt(mat4.create(), [x, y, z], [0, 0, 0], [0, 1, 0]);
}
////////////////////
// move the Eye
////////////////////
var eye = [0, 0, 1.4];
var center = [0, 0, 0];
function moveEye () {
return mat4.lookAt(mat4.create(), eye, center, [0, 1, 0]);
}
///////////////////
///////////////////
function start_draw(model, rx, ry, rz, r1x, r1y, r1z, sx, sy, sz, tx, ty, tz, c1, c2, c3, c4){
// 1. calcula la matriz de transformación
var modelMatrix = mat4.create();
var rotationmatr = mat4.create();
var rotation2 = mat4.create();
var transmatr = mat4.create();
var scalematr = mat4.create();
mat4.fromRotation (rotationmatr, Math.PI/2, [rx, ry, rz]);
mat4.fromRotation (rotation2, Math.PI/2, [r1x, r1y, r1z]);
mat4.fromScaling (scalematr, [sx, sy, sz]);
mat4.multiply (modelMatrix, rotationmatr, rotation2);
mat4.fromTranslation(transmatr,[tx, ty, tz]);
mat4.multiply(modelMatrix, transmatr, modelMatrix);
mat4.multiply(modelMatrix, modelMatrix, scalematr);
var modelMatrixM = mat4.create();
var modelViewMatrixM = mat4.create();
mat4.fromScaling(modelMatrixM, [0.5, 0.5, 0.5]);
mat4.multiply(modelViewMatrixM, moveEye(), modelMatrixM);
mat4.multiply(modelViewMatrixM, getCameraMatrix(), modelViewMatrixM);
var finalProj = mat4.create();
mat4.multiply(finalProj, modelViewMatrixM, modelMatrix);
// 2. establece la matriz modelMatrix en el shader de vértices
console.log(finalProj);
gl.uniformMatrix4fv(program.modelMatrixIndex, false, finalProj);
gl.uniform4f (idMyColor, c1, c2, c3, c4);
setProjection();
draw(model);
}
function drawall(){
start_draw(exampleCylinder, .5, 0, 0, 0, 0, 0, .1, .1, .6, -.6, .1, -3, .5, 0, .5, .7);
}
function drawScene() {
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
drawall();
}
function initHandlers() {
var mouseDown = false;
var lastMouseX;
var lastMouseY;
var canvas = document.getElementById("myCanvas");
var htmlPhi = document.getElementById("Phi");
var htmlZeta = document.getElementById("Zeta");
var htmlRadius = document.getElementById("Radius");
var htmlFovy = document.getElementById("Fovy");
htmlPhi.innerHTML = (myPhi * 180 / Math.PI).toFixed(1);
htmlZeta.innerHTML = (myZeta * 180 / Math.PI).toFixed(1);
htmlRadius.innerHTML = radius.toFixed(1);
htmlFovy.innerHTML = (fovy * 180 / Math.PI).toFixed(1);
canvas.addEventListener("wheel",
function (event) {
var delta = 0.0;
if (event.deltaMode == 0)
delta = event.deltaY * 0.001;
else if (event.deltaMode == 1)
delta = event.deltaY * 0.03;
else
delta = event.deltaY;
if (event.shiftKey == 1) { // fovy
fovy *= Math.exp(-delta)
fovy = Math.max (0.1, Math.min(3.0, fovy));
htmlFovy.innerHTML = (fovy * 180 / Math.PI).toFixed(1);
} else {
radius *= Math.exp(-delta);
radius = Math.max(Math.min(radius, 30), 0.05);
htmlRadius.innerHTML = radius.toFixed(1);
}
event.preventDefault();
requestAnimationFrame(drawScene);
}, false);
}
function handleKeyDown(event) {
console.log(event.keyCode);
switch (event.keyCode) {
//MOVEMENT
case 87: // ’w’ key
eye[2] -= 0.01;
center[2] -=0.01;
break;
// right
case 83: // ’s’ key
eye[2] += 0.01;
center[2] +=0.01;
break;
case 65: // ’a’ key
eye[0] -= 0.01;
center[0] -=0.01;
break;
// right
case 68: // ’d’ key
eye[0] += 0.01;
center[0] +=0.01;
break;
//CAMERA MOVEMENT
case 38: // ’up arrow’ key
myPhi+=0.01;
break;
// right
case 40: // ’down arrow’ key
myPhi-=0.01;
break;
case 37: // ’up arrow’ key
myZeta+=0.01;
break;
// right
case 39: // ’down arrow’ key
myZeta-=0.01;
break;
break;
}
requestAnimationFrame(drawScene);
}
function initWebGL() {
gl = getWebGLContext();
if (!gl) {
alert("WebGL 2.0 no está disponible");
return;
}
document.onkeydown = handleKeyDown;
initShaders();
initPrimitives();
initRendering();
initHandlers();
requestAnimationFrame(drawScene);
}
initWebGL();
canvas {border: 1px solid black;}
<script id="myVertexShader"
type="x-shader/x-vertex">#version 300 es
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
in vec3 VertexPosition;
void main() {
gl_Position = projectionMatrix * modelViewMatrix * vec4(VertexPosition, 1.0);
}
</script>
<script id="myFragmentShader"
type="x-shader/x-fragment">#version 300 es
// Shader de fragmentos
precision mediump float;
uniform vec4 myColor;
out vec4 fragmentColor;
void main() {
fragmentColor = myColor;
}
</script>
<br>
<strong>Phi: </strong><span id="Phi"></span>°
<br>
<strong>Zeta: </strong><span id="Zeta"></span>°
<br>
<strong>Fovy: </strong><span id="Fovy"></span>°
<br>
<strong>Radius: </strong><span id="Radius"></span>
<br>
<canvas id="myCanvas" width="600" height="600">
El Navegador no soporta HTML5
</canvas>
<script src="https://cdn.jsdelivr.net/npm/gl-matrix#3.3.0/gl-matrix-min.js"></script>
So the first thing I did once I got your code to run is add in webgl-lint with
<script src="https://greggman.github.io/webgl-lint/webgl-lint.js" crossorigin></script>
That immediately brought up this error in the JavaScript console
webgl-lint.js:2163 Uncaught Error: https://greggman.github.io/webgl-lint/webgl-lint.js:2942: error in uniformMatrix4fv(undefined, false, [0.05000000074505806, 0, 0, 0, 0, -4.5621650389774436e-26, 0.05000000074505806, 0, 0, -0.30000001192092896, -7.29946406236391e-25, 0, -0.30000001192092896, 0.05000000074505806, -4.300000190734863, 1]): argument 0 is undefined
at reportError (VM9 webgl-lint.js:2163)
at reportFunctionError (VM9 webgl-lint.js:2924)
at checkArgs (VM9 webgl-lint.js:2942)
at WebGL2RenderingContext.ctx. [as uniformMatrix4fv] (VM9 webgl-lint.js:3016)
at start_draw (js:417)
at drawall (js:428)
at drawScene (js:435)\
clicking the first stack trace line related to your code brought me here
// 2. establece la matriz modelMatrix en el shader de vértices
console.log(finalProj);
---> gl.uniformMatrix4fv(program.modelViewMatrix, false, finalProj);
It's not program.modelMatrixIndex it's program.modelViewMatrixIndex
and that got something on the screen
const {mat4} = glMatrix;
var examplePlane = { // 4 vértices, 2 triángulos
"vertices" : [-0.5, 0.0, 0.5,
0.5, 0.0, 0.5,
0.5, 0.0,-0.5,
-0.5, 0.0,-0.5],
"indices" : [0, 1, 2, 0, 2, 3]
};
var exampleCube = { // 8 vértices, 12 triángulos
"vertices" : [-0.5,-0.5, 0.5,
0.5,-0.5, 0.5,
0.5, 0.5, 0.5,
-0.5, 0.5, 0.5,
-0.5,-0.5, -0.5,
0.5,-0.5, -0.5,
0.5, 0.5, -0.5,
-0.5, 0.5, -0.5],
"indices" : [ 0, 1, 2, 0, 2, 3,
1, 5, 6, 1, 6, 2,
3, 2, 6, 3, 6, 7,
5, 4, 7, 5, 7, 6,
4, 0, 3, 4, 3, 7,
4, 5, 1, 4, 1, 0]
};
var exampleCover = { // 13 vértices, 12 triángulos
"vertices" : [ 1, 0, 0, 0.866, 0.5, 0, 0.5, 0.866, 0,
0, 1, 0, -0.5, 0.866, 0, -0.86, 0.5, 0,
-1, 0, 0, -0.866, -0.5, 0, -0.5, -0.866, 0,
0, -1, 0, 0.5, -0.866, 0, 0.866, -0.5, 0,
0, 0, 0],
"indices" : [ 0, 1, 12, 1, 2, 12, 2, 3, 12, 3, 4, 12, 4, 5, 12, 5, 6, 12,
6, 7, 12, 7, 8, 12, 8, 9, 12, 9, 10, 12, 10, 11, 12, 11, 0, 12]
};
var exampleCone = { // 13 vértices, 12 triángulos
"vertices" : [ 1, 0, 0, 0.866, 0.5, 0, 0.5, 0.866, 0,
0, 1, 0, -0.5, 0.866, 0, -0.86, 0.5, 0,
-1, 0, 0, -0.866, -0.5, 0, -0.5, -0.866, 0,
0, -1, 0, 0.5, -0.866, 0, 0.866, -0.5, 0,
0, 0, 1],
"indices" : [ 0, 1, 12, 1, 2, 12, 2, 3, 12, 3, 4, 12, 4, 5, 12, 5, 6, 12,
6, 7, 12, 7, 8, 12, 8, 9, 12, 9, 10, 12, 10, 11, 12, 11, 0, 12]
};
var exampleCylinder = { // 24 vértices, 24 triángulos
"vertices" : [ 1, 0, 0, 0.866, 0.5, 0, 0.5, 0.866, 0,
0, 1, 0, -0.5, 0.866, 0, -0.86, 0.5, 0,
-1, 0, 0, -0.866, -0.5, 0, -0.5, -0.866, 0,
0, -1, 0, 0.5, -0.866, 0, 0.866, -0.5, 0,
1, 0, 1, 0.866, 0.5, 1, 0.5, 0.866, 1,
0, 1, 1, -0.5, 0.866, 1, -0.86, 0.5, 1,
-1, 0, 1, -0.866, -0.5, 1, -0.5, -0.866, 1,
0, -1, 1, 0.5, -0.866, 1, 0.866, -0.5, 1],
"indices" : [ 0, 1, 12, 1, 2, 13, 2, 3, 14, 3, 4, 15, 4, 5, 16, 5, 6, 17,
6, 7, 18, 7, 8, 19, 8, 9, 20, 9, 10, 21, 10, 11, 22, 11, 0, 23,
1, 13, 12, 2, 14, 13, 3, 15, 14, 4, 16, 15, 5, 17, 16, 6, 18, 17,
7, 19, 18, 8, 20, 19, 9, 21, 20, 10, 22, 21, 11, 23, 22, 0, 12, 23]
};
var exampleSphere = { // 42 vértices, 80 triángulos
"vertices" : [ 0.000000, 0.850651, 0.525731,
-0.309017, 0.500000, 0.809017,
0.309017, 0.500000, 0.809017,
-0.525731, 0.000000, 0.850651,
0.000000, 0.000000, 1.000000,
0.525731, 0.000000, 0.850651,
-0.850651, 0.525731, 0.000000,
-0.809017, 0.309017, 0.500000,
-0.500000, 0.809017, 0.309017,
0.000000, 0.850651,-0.525731,
-0.500000, 0.809017,-0.309017,
0.000000, 1.000000, 0.000000,
0.500000, 0.809017,-0.309017,
0.500000, 0.809017, 0.309017,
0.850651, 0.525731, 0.000000,
0.809017, 0.309017, 0.500000,
0.850651,-0.525731, 0.000000,
1.000000, 0.000000, 0.000000,
0.809017,-0.309017, 0.500000,
0.525731, 0.000000,-0.850651,
0.809017, 0.309017,-0.500000,
0.809017,-0.309017,-0.500000,
0.309017, 0.500000,-0.809017,
-0.525731, 0.000000,-0.850651,
-0.309017, 0.500000,-0.809017,
0.000000, 0.000000,-1.000000,
0.000000,-0.850651,-0.525731,
-0.309017,-0.500000,-0.809017,
0.309017,-0.500000,-0.809017,
0.500000,-0.809017,-0.309017,
0.000000,-0.850651, 0.525731,
0.000000,-1.000000, 0.000000,
0.500000,-0.809017, 0.309017,
-0.850651,-0.525731, 0.000000,
-0.500000,-0.809017,-0.309017,
-0.500000,-0.809017, 0.309017,
-0.809017,-0.309017, 0.500000,
-0.309017,-0.500000, 0.809017,
0.309017,-0.500000, 0.809017,
-1.000000, 0.000000, 0.000000,
-0.809017,-0.309017,-0.500000,
-0.809017, 0.309017,-0.500000],
"indices" : [ 1, 2, 0, 4, 1, 3, 2, 4, 5, 4, 2, 1, 7, 8, 6, 1, 7, 3, 8, 1, 0, 1, 8, 7,10,11, 9, 8,10, 6,
11, 8, 0, 8,11,10,11,12, 9,13,11, 0,12,13,14,13,12,11,13,15,14, 2,13, 0,15, 2, 5, 2,15,13,
17,18,16,15,17,14,18,15, 5,15,18,17,20,21,19,17,20,14,21,17,16,17,21,20,22,20,19,12,22, 9,
20,12,14,12,20,22,24,25,23,22,24, 9,25,22,19,22,25,24,27,28,26,25,27,23,28,25,19,25,28,27,
29,21,16,28,29,26,21,28,19,28,21,29,31,32,30,29,31,26,32,29,16,29,32,31,34,35,33,31,34,26,
35,31,30,31,35,34,36,37, 3,35,36,33,37,35,30,35,37,36, 4,38, 5,37, 4, 3,38,37,30,37,38, 4,
38,18, 5,32,38,30,18,32,16,32,18,38, 7,36, 3,39, 7, 6,36,39,33,39,36, 7,39,40,33,41,39, 6,
40,41,23,41,40,39,41,24,23,10,41, 6,24,10, 9,10,24,41,27,40,23,34,27,26,40,34,33,34,40,27]
};
function makeTorus (innerRadius, outerRadius, nSides, nRings) {
var torus = {
"vertices" : [],
"indices" : []
};
if (nSides < 3 ) nSides = 3;
if (nRings < 3 ) nRings = 3;
var dpsi = 2.0 * Math.PI / nRings ;
var dphi = -2.0 * Math.PI / nSides ;
var psi = 0.0;
for (var j = 0; j < nRings; j++) {
var cpsi = Math.cos ( psi ) ;
var spsi = Math.sin ( psi ) ;
var phi = 0.0;
for (var i = 0; i < nSides; i++) {
var offset = 3 * ( j * (nSides+1) + i ) ;
var cphi = Math.cos ( phi ) ;
var sphi = Math.sin ( phi ) ;
torus.vertices[offset + 0] = cpsi * ( outerRadius + cphi * innerRadius ) ;
torus.vertices[offset + 1] = spsi * ( outerRadius + cphi * innerRadius ) ;
torus.vertices[offset + 2] = sphi * innerRadius ;
phi += dphi;
}
var offset = torus.vertices.length;
for (var i = 0; i < 3; i++)
torus.vertices[offset + i] = torus.vertices[offset-nSides*3+i];
psi += dpsi;
}
var offset = torus.vertices.length;
for (var i = 0; i < 3*(nSides+1); i++)
torus.vertices[offset+i] = torus.vertices[i];
for (var j = 0; j < nRings; j++){
var desp = j * (nSides + 1);
for (var i = 0; i < nSides; i++){
torus.indices.push(desp + i, desp + i + 1, desp + i + (nSides+1));
torus.indices.push(desp + i + 1, desp + i + (nSides+1) + 1, desp + i + (nSides+1));
}
}
return torus;
}
var gl, program;
var myTorus;
var myZeta = 0.0, myPhi = Math.PI/2.0, radius = 1.4, fovy = 1.4;
function getWebGLContext() {
var canvas = document.getElementById("myCanvas");
try {
return canvas.getContext("webgl2",{antialias:true});
}
catch(e) {
}
return null;
}
function initShaders() {
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, document.getElementById("myVertexShader").text);
gl.compileShader(vertexShader);
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(vertexShader));
return null;
}
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, document.getElementById("myFragmentShader").text);
gl.compileShader(fragmentShader);
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(fragmentShader));
return null;
}
program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
idMyColor = gl.getUniformLocation (program, "myColor" );
program.vertexPositionAttribute = gl.getAttribLocation(program, "VertexPosition");
gl.enableVertexAttribArray(program.vertexPositionAttribute);
program.modelViewMatrixIndex = gl.getUniformLocation(program,"modelViewMatrix");
program.projectionMatrixIndex = gl.getUniformLocation(program,"projectionMatrix");
}
function initRendering() {
gl.clearColor(0.95,0.95,0.95,1.0);
gl.lineWidth(1.5);
gl.enable(gl.DEPTH_TEST);
}
function initBuffers(model) {
model.idBufferVertices = gl.createBuffer ();
gl.bindBuffer (gl.ARRAY_BUFFER, model.idBufferVertices);
gl.bufferData (gl.ARRAY_BUFFER, new Float32Array(model.vertices), gl.STATIC_DRAW);
model.idBufferIndices = gl.createBuffer ();
gl.bindBuffer (gl.ELEMENT_ARRAY_BUFFER, model.idBufferIndices);
gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(model.indices), gl.STATIC_DRAW);
}
function draw(model) {
console.log(model);
gl.bindBuffer(gl.ARRAY_BUFFER, model.idBufferVertices);
gl.vertexAttribPointer(program.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, model.idBufferIndices);
for (var i = 0; i < model.indices.length; i += 3)
// Si paint es true vol dir que volem pintar per tant farem el triangle_fan
gl.drawElements (gl.TRIANGLE_FAN, 3, gl.UNSIGNED_SHORT, i*2);
}
// set projection (apliquem una projecció al dibuix)
function setProjection() {
// obtiene la matriz de transformación de la proyección perspectiva
var projectionMatrix = mat4.create();
// perspective
mat4.perspective(projectionMatrix, Math.PI/4.0, 1., 0.1, 100.0);
// envía la matriz de transformación de la proyección al shader de vértices
gl.uniformMatrix4fv(program.projectionMatrixIndex,false,projectionMatrix);
}
function initPrimitives() {
initBuffers(examplePlane);
initBuffers(exampleCube);
initBuffers(exampleCover);
initBuffers(exampleCone);
initBuffers(exampleCylinder);
initBuffers(exampleSphere);
myTorus = makeTorus(0.4, 1.0, 8, 12);
initBuffers(myTorus);
}
function getCameraMatrix() {
// coordenadas esféricas a rectangulares: https://en.wikipedia.org/wiki/Spherical_coordinate_system
var x = radius * Math.sin(myPhi) * Math.sin(myZeta);
var y = radius * Math.cos(myPhi);
var z = radius * Math.sin(myPhi) * Math.cos(myZeta);
return mat4.lookAt(mat4.create(), [x, y, z], [0, 0, 0], [0, 1, 0]);
}
////////////////////
// move the Eye
////////////////////
var eye = [0, 0, 1.4];
var center = [0, 0, 0];
function moveEye () {
return mat4.lookAt(mat4.create(), eye, center, [0, 1, 0]);
}
///////////////////
///////////////////
function start_draw(model, rx, ry, rz, r1x, r1y, r1z, sx, sy, sz, tx, ty, tz, c1, c2, c3, c4){
// 1. calcula la matriz de transformación
var modelMatrix = mat4.create();
var rotationmatr = mat4.create();
var rotation2 = mat4.create();
var transmatr = mat4.create();
var scalematr = mat4.create();
mat4.fromRotation (rotationmatr, Math.PI/2, [rx, ry, rz]);
mat4.fromRotation (rotation2, Math.PI/2, [r1x, r1y, r1z]);
mat4.fromScaling (scalematr, [sx, sy, sz]);
mat4.multiply (modelMatrix, rotationmatr, rotation2);
mat4.fromTranslation(transmatr,[tx, ty, tz]);
mat4.multiply(modelMatrix, transmatr, modelMatrix);
mat4.multiply(modelMatrix, modelMatrix, scalematr);
var modelMatrixM = mat4.create();
var modelViewMatrixM = mat4.create();
mat4.fromScaling(modelMatrixM, [0.5, 0.5, 0.5]);
mat4.multiply(modelViewMatrixM, moveEye(), modelMatrixM);
mat4.multiply(modelViewMatrixM, getCameraMatrix(), modelViewMatrixM);
var finalProj = mat4.create();
mat4.multiply(finalProj, modelViewMatrixM, modelMatrix);
// 2. establece la matriz modelMatrix en el shader de vértices
console.log(finalProj);
gl.uniformMatrix4fv(program.modelViewMatrixIndex, false, finalProj);
gl.uniform4f (idMyColor, c1, c2, c3, c4);
setProjection();
draw(model);
}
function drawall(){
start_draw(exampleCylinder, .5, 0, 0, 0, 0, 0, .1, .1, .6, -.6, .1, -3, .5, 0, .5, .7);
}
function drawScene() {
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
drawall();
}
function initHandlers() {
var mouseDown = false;
var lastMouseX;
var lastMouseY;
var canvas = document.getElementById("myCanvas");
var htmlPhi = document.getElementById("Phi");
var htmlZeta = document.getElementById("Zeta");
var htmlRadius = document.getElementById("Radius");
var htmlFovy = document.getElementById("Fovy");
htmlPhi.innerHTML = (myPhi * 180 / Math.PI).toFixed(1);
htmlZeta.innerHTML = (myZeta * 180 / Math.PI).toFixed(1);
htmlRadius.innerHTML = radius.toFixed(1);
htmlFovy.innerHTML = (fovy * 180 / Math.PI).toFixed(1);
canvas.addEventListener("wheel",
function (event) {
var delta = 0.0;
if (event.deltaMode == 0)
delta = event.deltaY * 0.001;
else if (event.deltaMode == 1)
delta = event.deltaY * 0.03;
else
delta = event.deltaY;
if (event.shiftKey == 1) { // fovy
fovy *= Math.exp(-delta)
fovy = Math.max (0.1, Math.min(3.0, fovy));
htmlFovy.innerHTML = (fovy * 180 / Math.PI).toFixed(1);
} else {
radius *= Math.exp(-delta);
radius = Math.max(Math.min(radius, 30), 0.05);
htmlRadius.innerHTML = radius.toFixed(1);
}
event.preventDefault();
requestAnimationFrame(drawScene);
}, false);
}
function handleKeyDown(event) {
console.log(event.keyCode);
switch (event.keyCode) {
//MOVEMENT
case 87: // ’w’ key
eye[2] -= 0.01;
center[2] -=0.01;
break;
// right
case 83: // ’s’ key
eye[2] += 0.01;
center[2] +=0.01;
break;
case 65: // ’a’ key
eye[0] -= 0.01;
center[0] -=0.01;
break;
// right
case 68: // ’d’ key
eye[0] += 0.01;
center[0] +=0.01;
break;
//CAMERA MOVEMENT
case 38: // ’up arrow’ key
myPhi+=0.01;
break;
// right
case 40: // ’down arrow’ key
myPhi-=0.01;
break;
case 37: // ’up arrow’ key
myZeta+=0.01;
break;
// right
case 39: // ’down arrow’ key
myZeta-=0.01;
break;
break;
}
requestAnimationFrame(drawScene);
}
function initWebGL() {
gl = getWebGLContext();
if (!gl) {
alert("WebGL 2.0 no está disponible");
return;
}
document.onkeydown = handleKeyDown;
initShaders();
initPrimitives();
initRendering();
initHandlers();
requestAnimationFrame(drawScene);
}
initWebGL();
canvas {border: 1px solid black;}
<script id="myVertexShader"
type="x-shader/x-vertex">#version 300 es
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
in vec3 VertexPosition;
void main() {
gl_Position = projectionMatrix * modelViewMatrix * vec4(VertexPosition, 1.0);
}
</script>
<script id="myFragmentShader"
type="x-shader/x-fragment">#version 300 es
// Shader de fragmentos
precision mediump float;
uniform vec4 myColor;
out vec4 fragmentColor;
void main() {
fragmentColor = myColor;
}
</script>
<br>
<strong>Phi: </strong><span id="Phi"></span>°
<br>
<strong>Zeta: </strong><span id="Zeta"></span>°
<br>
<strong>Fovy: </strong><span id="Fovy"></span>°
<br>
<strong>Radius: </strong><span id="Radius"></span>
<br>
<canvas id="myCanvas" width="600" height="600">
El Navegador no soporta HTML5
</canvas>
<script src="https://cdn.jsdelivr.net/npm/gl-matrix#3.3.0/gl-matrix-min.js"></script>
PS: Please learn how to use snippets and CDNs for libraries
Also, just FYI, getContext never throws so this code
function getWebGLContext() {
var canvas = document.getElementById("myCanvas");
try {
return canvas.getContext("webgl2",{antialias:true});
}
catch(e) {
}
return null;
}
makes no sense. It should just be
function getWebGLContext() {
var canvas = document.getElementById("myCanvas");
return canvas.getContext("webgl2",{antialias:true});
}
and further, antialias: true is the default so
function getWebGLContext() {
var canvas = document.getElementById("myCanvas");
return canvas.getContext("webgl2");
}