Summary Files Commits Branches @commit @diff @stats
diff options
context:
space:
mode:
Commitcebdee09e597d8aa2b4d69f868cafafe22ede580 (patch)
Author
 Syndamia <kamen@syndamia.com>
2022-11-07 20:18:07 +0200
Committer
 Syndamia <kamen@syndamia.com>
2022-11-07 20:18:07 +0200
Files476181ed7e72bcde1eab4cf08fdc50d3edda278b
uni-projects-cebdee09e597d8aa2b4d69f868cafafe22ede580.tar
uni-projects-cebdee09e597d8aa2b4d69f868cafafe22ede580.tar.gz
uni-projects-cebdee09e597d8aa2b4d69f868cafafe22ede580.zip
Parentfaa737bc5c9edd86f752a3b70716014f25dfee71 (diff)
[WGL/P04] Started working on exercises
diff --git a/Year 2/Computer Graphics with WebGL/04-Pracitce-31.10.2022/Problem 0401.html b/Year 2/Computer Graphics with WebGL/04-Pracitce-31.10.2022/Problem 0401.html
new file mode 100644
index 0000000..d8aafb5
--- /dev/null
+++ b/Year 2/Computer Graphics with WebGL/04-Pracitce-31.10.2022/Problem 0401.html
@@ -0,0 +1,140 @@
+<!DOCTYPE html>
+
+<head>
+ <meta charset="utf-8"/>
+ <title>Кубове по ръбовете</title>
+
+ <script src="webgl-fmi.js"></script>
+
+ <script id="vshader" type="x-shader/x-vertex">
+ uniform mat4 uProjectionMatrix;
+ uniform mat4 uViewMatrix;
+ uniform mat4 uModelMatrix;
+ attribute vec3 aXYZ;
+ void main ()
+ {
+ gl_Position = uProjectionMatrix * uViewMatrix * uModelMatrix * vec4(aXYZ,1);
+ }
+ </script>
+
+ <script id="fshader" type="x-shader/x-fragment">
+ void main( )
+ {
+ gl_FragColor = vec4(1,0,0,1);
+ }
+ </script>
+
+ <script>
+ function drawCube()
+ {
+ useMatrix();
+ gl.drawArrays(gl.LINE_LOOP,0,4);
+ gl.drawArrays(gl.LINE_LOOP,4,4);
+ gl.drawArrays(gl.LINES,8,8);
+ }
+
+ function start( )
+ {
+ var canvas = document.getElementById("picasso");
+ canvas.addEventListener('webglcontextlost',handleContextLost,false);
+ canvas.addEventListener('webglcontextrestored',handleContextRestored,false);
+
+ init();
+ drawFrame();
+ }
+
+ function init()
+ {
+ gl = getContext("picasso");
+ glprog = getProgram("vshader","fshader");
+
+
+ aXYZ = gl.getAttribLocation(glprog,"aXYZ");
+ uProjectionMatrix = gl.getUniformLocation(glprog,"uProjectionMatrix");
+ uViewMatrix = gl.getUniformLocation(glprog,"uViewMatrix");
+ uModelMatrix = gl.getUniformLocation(glprog,"uModelMatrix");
+
+ gl.clearColor(1,1,1,1);
+
+ var proj = perspMatrix(30,gl.canvas.width/gl.canvas.height,1,40000);
+ gl.uniformMatrix4fv(uProjectionMatrix,false,proj);
+
+ view = viewMatrix([4,3,1], [0,0,0], [0,0,1]);
+ gl.uniformMatrix4fv(uViewMatrix,false,view);
+
+ // куб 1x1x1
+ var data = [ 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,
+
+ 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 ];
+ var buf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER,buf);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(aXYZ);
+ gl.vertexAttribPointer(aXYZ,3,gl.FLOAT,false,0,0);
+ }
+
+ var frame = 0;
+
+ var smallCubeSize = 0.2;
+ function drawFrame()
+ {
+ frame++;
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ identity();
+ zRotate(frame);
+ drawCube(frame);
+
+ scale([smallCubeSize, smallCubeSize, smallCubeSize]);
+ var length = 2 + smallCubeSize * 5 / 2;
+ translate([0, 0, length]);
+ for (var i = 0; i < 4; i++) {
+ pushMatrix();
+
+ translate([Math.cos(Math.PI / 2 * i) * length, Math.sin(Math.PI / 2 * i) * length, 0]);
+ drawCube(frame);
+
+ popMatrix();
+ }
+
+ requestAnimationFrame(drawFrame);
+ }
+
+ function handleContextLost(event)
+ {
+ event.preventDefault();
+ }
+
+ function handleContextRestored(event)
+ {
+ init();
+ }
+
+ </script>
+</head>
+
+<body onload="start()">
+ <h2>Кубове по ръбовете</h2>
+
+ <noscript>
+ Искаме JavaScript, но няма!
+ </noscript>
+
+ <canvas id="picasso" width="600" height="400" style="border: solid;">
+ Искаме canvas, но няма!
+ </canvas>
+</body>
diff --git a/Year 2/Computer Graphics with WebGL/04-Pracitce-31.10.2022/Problem 0402.html b/Year 2/Computer Graphics with WebGL/04-Pracitce-31.10.2022/Problem 0402.html
new file mode 100644
index 0000000..74ce342
--- /dev/null
+++ b/Year 2/Computer Graphics with WebGL/04-Pracitce-31.10.2022/Problem 0402.html
@@ -0,0 +1,156 @@
+<!DOCTYPE html>
+
+<head>
+ <meta charset="utf-8"/>
+ <title>Въртящи се кубове по ръбовете</title>
+
+ <script src="webgl-fmi.js"></script>
+
+ <script id="vshader" type="x-shader/x-vertex">
+ uniform mat4 uProjectionMatrix;
+ uniform mat4 uViewMatrix;
+ uniform mat4 uModelMatrix;
+ attribute vec3 aXYZ;
+ void main ()
+ {
+ gl_Position = uProjectionMatrix * uViewMatrix * uModelMatrix * vec4(aXYZ,1);
+ }
+ </script>
+
+ <script id="fshader" type="x-shader/x-fragment">
+ void main( )
+ {
+ gl_FragColor = vec4(1,0,0,1);
+ }
+ </script>
+
+ <script>
+ function start( )
+ {
+ var canvas = document.getElementById("picasso");
+ //canvas = WebGLDebugUtils.makeLostContextSimulatingCanvas(canvas);
+ canvas.addEventListener('webglcontextlost',function(event){event.preventDefault();},false);
+ canvas.addEventListener('webglcontextrestored',function(){init();},false);
+
+ init();
+ drawFrame();
+ }
+
+
+ function init()
+ {
+ gl = getContext("picasso",false);
+ glprog = getProgram("vshader","fshader");
+
+
+ aXYZ = gl.getAttribLocation(glprog,"aXYZ");
+ uProjectionMatrix = gl.getUniformLocation(glprog,"uProjectionMatrix");
+ uViewMatrix = gl.getUniformLocation(glprog,"uViewMatrix");
+ uModelMatrix = gl.getUniformLocation(glprog,"uModelMatrix");
+
+ gl.clearColor(1,1,1,1);
+
+ perspective(30,gl.canvas.width/gl.canvas.height,1,40000);
+
+ // куб 1x1x1
+ var data = [ 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,
+
+ 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 ];
+ var buf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER,buf);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(aXYZ);
+ gl.vertexAttribPointer(aXYZ,3,gl.FLOAT,false,0,0);
+ }
+
+ var frame = 0;
+
+ function drawCube()
+ {
+ useMatrix();
+ gl.drawArrays(gl.LINE_LOOP,0,4);
+ gl.drawArrays(gl.LINE_LOOP,4,4);
+ gl.drawArrays(gl.LINES,8,8);
+ }
+
+ function drawFrame()
+ {
+ frame++;
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ lookAt([3*Math.cos(frame/100),3*Math.sin(frame/100),1], [0,0,-0.1], [0,0,1]);
+
+ // главен куб
+ identity();
+ drawCube(frame);
+
+ // кубчета по вертикалните ръбове
+ for (var i=0; i<4; i++)
+ {
+ pushMatrix();
+ zRotate(90*i);
+ translate([0.5,0.5,0]);
+ scale([0.1,0.1,0.1]);
+ drawCube();
+ popMatrix();
+ }
+
+ // кубчета по горните ръбове
+ for (var i=0; i<4; i++)
+ {
+ pushMatrix();
+ zRotate(90*i);
+ translate([0.5,0,0.5]);
+ scale([0.1,0.1,0.1]);
+ if (i % 2 == 0) {
+ yRotate(frame);
+ translate([(i == 0) ? 0.5 : -0.5, 0, (i == 0) ? 0.5 : -0.5]);
+ } else {
+ xRotate(frame);
+ translate([0, (i == 1) ? 0.5 : -0.5, (i == 1) ? 0.5 : -0.5]);
+ }
+ drawCube();
+ popMatrix();
+ }
+
+ // кубчета по долните ръбове
+ for (var i=0; i<4; i++)
+ {
+ pushMatrix();
+ zRotate(90*i);
+ translate([0.5,0,-0.5]);
+ scale([0.1,0.1,0.1]);
+ drawCube();
+ popMatrix();
+ }
+
+ requestAnimationFrame(drawFrame);
+ }
+ </script>
+</head>
+
+<body onload="start()">
+ <h2>Въртящи се кубове по ръбовете</h2>
+
+ <noscript>
+ Искаме JavaScript, но няма!
+ </noscript>
+
+ <canvas id="picasso" width="600" height="400" style="border: solid;">
+ Искаме canvas, но няма!
+ </canvas>
+</body>
diff --git a/Year 2/Computer Graphics with WebGL/04-Pracitce-31.10.2022/Problem 0403.html b/Year 2/Computer Graphics with WebGL/04-Pracitce-31.10.2022/Problem 0403.html
new file mode 100644
index 0000000..01f8a1b
--- /dev/null
+++ b/Year 2/Computer Graphics with WebGL/04-Pracitce-31.10.2022/Problem 0403.html
@@ -0,0 +1,135 @@
+<!DOCTYPE html>
+
+<head>
+ <meta charset="utf-8"/>
+ <title>Търкалящ се куб</title>
+
+ <script src="webgl-fmi.js"></script>
+
+ <script id="vshader" type="x-shader/x-vertex">
+ uniform mat4 uProjectionMatrix;
+ uniform mat4 uViewMatrix;
+ uniform mat4 uModelMatrix;
+ attribute vec3 aXYZ;
+ void main ()
+ {
+ gl_Position = uProjectionMatrix * uViewMatrix * uModelMatrix * vec4(aXYZ,1);
+ }
+ </script>
+
+ <script id="fshader" type="x-shader/x-fragment">
+ void main( )
+ {
+ gl_FragColor = vec4(1,0,0,1);
+ }
+ </script>
+
+ <script>
+ function start( )
+ {
+ var canvas = document.getElementById("picasso");
+ canvas.addEventListener('webglcontextlost',function(event){event.preventDefault();},false);
+ canvas.addEventListener('webglcontextrestored',function(){init();},false);
+
+ init();
+ drawFrame();
+ }
+
+ function init()
+ {
+ gl = getContext("picasso",false);
+ glprog = getProgram("vshader","fshader");
+
+
+ aXYZ = gl.getAttribLocation(glprog,"aXYZ");
+ uProjectionMatrix = gl.getUniformLocation(glprog,"uProjectionMatrix");
+ uViewMatrix = gl.getUniformLocation(glprog,"uViewMatrix");
+ uModelMatrix = gl.getUniformLocation(glprog,"uModelMatrix");
+
+ gl.clearColor(1,1,1,1);
+
+ perspective(30,gl.canvas.width/gl.canvas.height,1,40000);
+
+ // куб 1x1x1
+ var data = [ 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,
+
+ 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 ];
+ var buf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER,buf);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(aXYZ);
+ gl.vertexAttribPointer(aXYZ,3,gl.FLOAT,false,0,0);
+ }
+
+ var frame = 0;
+
+ function drawCube()
+ {
+ useMatrix();
+ gl.drawArrays(gl.LINE_LOOP,0,4);
+ gl.drawArrays(gl.LINE_LOOP,4,4);
+ gl.drawArrays(gl.LINES,8,8);
+ }
+
+ var angle=0;
+ var y=0;
+ var viewY=0;
+ var cubeY = 0;
+ function drawFrame()
+ {
+ frame++;
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ lookAt([5,y,3], [0,y,0.5], [0,0,1]);
+
+ // главен куб
+ identity();
+ y+=0.01;
+
+ translate([0,cubeY,0]);
+ xRotate(angle);
+ translate([0, -0.5, 0.5]);
+
+ if (angle >= 89)
+ cubeY++;
+ angle = (angle + 0.9) % 90;
+ drawCube();
+
+ // пътека (рисува само частта около куба)
+ for (var v=-15; v<=15; v++)
+ {
+ identity();
+ scale([1.5,1,0.05]);
+ translate([0,v + Math.floor(y / 10) * 10,-0.5]);
+ drawCube();
+ }
+ requestAnimationFrame(drawFrame);
+ }
+ </script>
+</head>
+
+<body onload="start()">
+ <h2>Търкалящ се куб</h2>
+
+ <noscript>
+ Искаме JavaScript, но няма!
+ </noscript>
+
+ <canvas id="picasso" width="600" height="400" style="border: solid;">
+ Искаме canvas, но няма!
+ </canvas>
+</body>
diff --git a/Year 2/Computer Graphics with WebGL/04-Pracitce-31.10.2022/Problem 0404.html b/Year 2/Computer Graphics with WebGL/04-Pracitce-31.10.2022/Problem 0404.html
new file mode 100644
index 0000000..bdf37a4
--- /dev/null
+++ b/Year 2/Computer Graphics with WebGL/04-Pracitce-31.10.2022/Problem 0404.html
@@ -0,0 +1,159 @@
+<!DOCTYPE html>
+
+<head>
+ <meta charset="utf-8"/>
+ <title>Градът</title>
+
+ <script src="webgl-fmi.js"></script>
+
+ <script id="vshader" type="x-shader/x-vertex">
+ uniform mat4 uProjectionMatrix;
+ uniform mat4 uViewMatrix;
+ uniform mat4 uModelMatrix;
+
+ uniform vec3 uAmbientColor;
+ uniform vec3 uDiffuseColor;
+ uniform vec3 uLightDir;
+
+ attribute vec3 aXYZ;
+ attribute vec3 aColor;
+ attribute vec3 aNormal;
+
+ varying vec3 vColor;
+
+ void main ()
+ {
+ mat4 mvMatrix = uViewMatrix * uModelMatrix;
+ gl_Position = uProjectionMatrix * mvMatrix * vec4(aXYZ,1);
+
+ vec3 light = normalize(-uLightDir);
+ vec3 normal = vec3(normalize(mvMatrix*vec4(aNormal,0)));
+ vColor = uAmbientColor*aColor+aColor*uDiffuseColor*max(dot(normal,light),0.0);
+ }
+ </script>
+
+ <script id="fshader" type="x-shader/x-fragment">
+ precision mediump float;
+ varying vec3 vColor;
+ void main( )
+ {
+ gl_FragColor = vec4(vColor,1);
+ }
+ </script>
+
+ <script>
+ function start( )
+ {
+ var canvas = document.getElementById("picasso");
+ canvas.addEventListener('webglcontextlost',function(event){event.preventDefault();},false);
+ canvas.addEventListener('webglcontextrestored',function(){init();},false);
+
+ init();
+ drawFrame();
+ }
+
+ function drawCube()
+ {
+ useMatrix();
+ gl.drawArrays(gl.TRIANGLES,0,36);
+ }
+
+ function init()
+ {
+ gl = getContext("picasso");
+ glprog = getProgram("vshader","fshader");
+
+
+ aXYZ = gl.getAttribLocation(glprog,"aXYZ");
+ uProjectionMatrix = gl.getUniformLocation(glprog,"uProjectionMatrix");
+ uViewMatrix = gl.getUniformLocation(glprog,"uViewMatrix");
+ uModelMatrix = gl.getUniformLocation(glprog,"uModelMatrix");
+
+ aColor = gl.getAttribLocation(glprog,"aColor");
+ uAmbientColor = gl.getUniformLocation(glprog,"uAmbientColor");
+ aNormal = gl.getAttribLocation(glprog,"aNormal");
+ uDiffuseColor = gl.getUniformLocation(glprog,"uDiffuseColor");
+ uLightDir = gl.getUniformLocation(glprog,"uLightDir");
+
+ gl.enable(gl.DEPTH_TEST); // включваме тест за дълбочина
+ gl.clearColor(1,1,1,1);
+
+ identity();
+ perspective(30,gl.canvas.width/gl.canvas.height,1,40000);
+
+ // куб 1x1x1
+ var v = [ [+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] ];
+ var n = [ [1,0,0], [-1,0,0],
+ [0,1,0], [0,-1,0],
+ [0,0,1], [0,0,-1] ];
+ var data = [].concat(
+ v[0],n[0],v[1],n[0],v[4],n[0],
+ v[4],n[0],v[1],n[0],v[5],n[0],
+ v[6],n[1],v[2],n[1],v[7],n[1],
+ v[7],n[1],v[2],n[1],v[3],n[1],
+ v[5],n[2],v[1],n[2],v[6],n[2],
+ v[6],n[2],v[1],n[2],v[2],n[2],
+ v[4],n[3],v[7],n[3],v[0],n[3],
+ v[0],n[3],v[7],n[3],v[3],n[3],
+ v[4],n[4],v[5],n[4],v[7],n[4],
+ v[7],n[4],v[5],n[4],v[6],n[4],
+ v[0],n[5],v[3],n[5],v[1],n[5],
+ v[1],n[5],v[3],n[5],v[2],n[5] );
+
+ var buf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER,buf);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(aXYZ);
+ gl.vertexAttribPointer(aXYZ,3,gl.FLOAT,false,6*FLOATS,0*FLOATS);
+
+ gl.enableVertexAttribArray(aNormal);
+ gl.vertexAttribPointer(aNormal, 3, gl.FLOAT, false, 6 * FLOATS, 3 * FLOATS);
+
+ gl.vertexAttrib3f(aColor,0.5,0.8,1);
+ gl.uniform3f(uAmbientColor,0.2,0,0);
+ gl.uniform3f(uDiffuseColor,1,1,1);
+ gl.uniform3f(uLightDir,0,0,-1);
+ }
+
+ var frame = 0;
+
+ var N = 5;
+ function drawFrame()
+ {
+ frame++;
+ gl.clear(gl.COLOR_BUFFER_BIT+gl.DEPTH_BUFFER_BIT);
+
+ lookAt([20*Math.cos(frame/300),20*Math.sin(frame/300),15], [0,0,0], [0,0,1]);
+
+ identity();
+
+ translate([-N / 2, -N / 2, 0]);
+ for (var x = 0; x < N; x++) {
+ pushMatrix();
+ translate([x, 0, 0]);
+ for (var y = 0; y < N; y++) {
+ translate([0, 1, 0]);
+ drawCube(frame);
+ }
+ popMatrix();
+ }
+
+ requestAnimationFrame(drawFrame);
+ }
+ </script>
+</head>
+
+<body onload="start()">
+ <h2>Градът</h2>
+
+ <noscript>
+ Искаме JavaScript, но няма!
+ </noscript>
+
+ <canvas id="picasso" width="600" height="400" style="border: solid;">
+ Искаме canvas, но няма!
+ </canvas>
+</body>
diff --git a/Year 2/Computer Graphics with WebGL/04-Pracitce-31.10.2022/Problem 0405.html b/Year 2/Computer Graphics with WebGL/04-Pracitce-31.10.2022/Problem 0405.html
new file mode 100644
index 0000000..686b961
--- /dev/null
+++ b/Year 2/Computer Graphics with WebGL/04-Pracitce-31.10.2022/Problem 0405.html
@@ -0,0 +1,171 @@
+<!DOCTYPE html>
+
+<head>
+ <meta charset="utf-8"/>
+ <title>Сенчестият град</title>
+
+ <script src="webgl-fmi.js"></script>
+
+ <script id="vshader" type="x-shader/x-vertex">
+ uniform mat4 uProjectionMatrix;
+ uniform mat4 uViewMatrix;
+ uniform mat4 uModelMatrix;
+
+ uniform vec3 uAmbientColor;
+ uniform vec3 uDiffuseColor;
+ uniform vec3 uLightDir;
+
+ attribute vec3 aXYZ;
+ attribute vec3 aColor;
+ attribute vec3 aNormal;
+
+ varying vec3 vColor;
+
+ void main ()
+ {
+ mat4 mvMatrix = uViewMatrix * uModelMatrix;
+ gl_Position = uProjectionMatrix * mvMatrix * vec4(aXYZ,1);
+
+ vec3 light = normalize(-uLightDir);
+ vec3 normal = vec3(normalize(mvMatrix*vec4(aNormal,0)));
+ vColor = uAmbientColor*aColor+aColor*uDiffuseColor*max(dot(normal,light),0.0);
+ }
+ </script>
+
+ <script id="fshader" type="x-shader/x-fragment">
+ precision mediump float;
+ varying vec3 vColor;
+ void main( )
+ {
+ gl_FragColor = vec4(vColor,1);
+ }
+ </script>
+
+ <script>
+ function start( )
+ {
+ var canvas = document.getElementById("picasso");
+ canvas.addEventListener('webglcontextlost',function(event){event.preventDefault();},false);
+ canvas.addEventListener('webglcontextrestored',function(){init();},false);
+
+ init();
+ drawFrame();
+ }
+
+ var N=20;
+ var building=[]; // глобален масив за параметрите на сградите
+
+ function drawCube()
+ {
+ useMatrix();
+ gl.drawArrays(gl.TRIANGLES,0,36);
+ }
+
+ function init()
+ {
+ gl = getContext("picasso");
+ glprog = getProgram("vshader","fshader");
+
+
+ aXYZ = gl.getAttribLocation(glprog,"aXYZ");
+ uProjectionMatrix = gl.getUniformLocation(glprog,"uProjectionMatrix");
+ uViewMatrix = gl.getUniformLocation(glprog,"uViewMatrix");
+ uModelMatrix = gl.getUniformLocation(glprog,"uModelMatrix");
+
+ aColor = gl.getAttribLocation(glprog,"aColor");
+ uAmbientColor = gl.getUniformLocation(glprog,"uAmbientColor");
+ aNormal = gl.getAttribLocation(glprog,"aNormal");
+ uDiffuseColor = gl.getUniformLocation(glprog,"uDiffuseColor");
+ uLightDir = gl.getUniformLocation(glprog,"uLightDir");
+
+ gl.enable(gl.DEPTH_TEST); // включваме тест за дълбочина
+ gl.clearColor(1,1,1,1);
+
+ identity();
+ perspective(30,gl.canvas.width/gl.canvas.height,1,40000);
+
+ // куб 1x1x1
+ var v = [ [+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] ];
+ var n = [ [1,0,0], [-1,0,0],
+ [0,1,0], [0,-1,0],
+ [0,0,1], [0,0,-1] ];
+ var data = [].concat(
+ v[0],n[0],v[1],n[0],v[4],n[0],
+ v[4],n[0],v[1],n[0],v[5],n[0],
+ v[6],n[1],v[2],n[1],v[7],n[1],
+ v[7],n[1],v[2],n[1],v[3],n[1],
+ v[5],n[2],v[1],n[2],v[6],n[2],
+ v[6],n[2],v[1],n[2],v[2],n[2],
+ v[4],n[3],v[7],n[3],v[0],n[3],
+ v[0],n[3],v[7],n[3],v[3],n[3],
+ v[4],n[4],v[5],n[4],v[7],n[4],
+ v[7],n[4],v[5],n[4],v[6],n[4],
+ v[0],n[5],v[3],n[5],v[1],n[5],
+ v[1],n[5],v[3],n[5],v[2],n[5] );
+
+ var buf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER,buf);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(aXYZ);
+ gl.vertexAttribPointer(aXYZ,3,gl.FLOAT,false,6*FLOATS,0*FLOATS);
+
+ gl.enableVertexAttribArray(aNormal);
+ gl.vertexAttribPointer(aNormal,3,gl.FLOAT,false,6*FLOATS,3*FLOATS);
+
+ gl.vertexAttrib3f(aColor,0.5,0.8,1);
+ gl.uniform3f(uAmbientColor,0.2,0,0);
+ gl.uniform3f(uDiffuseColor,1,1,1);
+ gl.uniform3f(uLightDir,0,0,-1);
+
+ // инициализиране на сградите
+ for (var x=0; x<N; x++)
+ {
+ building[x]=[];
+ for (var y=0; y<N; y++)
+ building[x][y] = {
+ height: random(5,10),
+ speed: random(1/50,1/500),
+ offset: random(0,2*Math.PI) };
+ }
+ }
+
+ var frame = 0;
+
+ function drawFrame()
+ {
+ frame++;
+ gl.clear(gl.COLOR_BUFFER_BIT+gl.DEPTH_BUFFER_BIT);
+
+ lookAt([20*Math.cos(frame/300),20*Math.sin(frame/300),20+15*Math.sin(frame/100)], [0,0,2-2*Math.sin(frame/100)], [0,0,1]);
+
+ // рисуване на града
+ for (var x=0; x<N; x++)
+ for (var y=0; y<N; y++)
+ {
+ var b = building[x][y];
+ var z = b.height*(0.5+0.4*Math.cos(b.offset+b.speed*frame));
+ identity();
+ translate([x-N/2,y-N/2,z/2]);
+ scale([1,1,z]);
+ drawCube(frame);
+ }
+
+ requestAnimationFrame(drawFrame);
+ }
+ </script>
+</head>
+
+<body onload="start()">
+ <h2>Сенчестият град</h2>
+
+ <noscript>
+ Искаме JavaScript, но няма!
+ </noscript>
+
+ <canvas id="picasso" width="600" height="400" style="border: solid;">
+ Искаме canvas, но няма!
+ </canvas>
+</body>
diff --git a/Year 2/Computer Graphics with WebGL/04-Pracitce-31.10.2022/webgl-fmi.js b/Year 2/Computer Graphics with WebGL/04-Pracitce-31.10.2022/webgl-fmi.js
new file mode 100644
index 0000000..e864ad4
--- /dev/null
+++ b/Year 2/Computer Graphics with WebGL/04-Pracitce-31.10.2022/webgl-fmi.js
@@ -0,0 +1,488 @@
+// Библиотека WebGL-FMI v0.07.11-Ex2
+//
+// Работа с контексти и шейдъри
+// getContext(id)
+// getShader(id,type)
+// getProgram(idv,idf)
+//
+// Математически функции
+// random(a,b)
+// radians(degrees)
+//
+// Работа с вектори
+// unitVector(x)
+// vectorProduct(x,y)
+// scalarProduct(x,y)
+// vectorPoints(x,y)
+//
+// Трансформации с матрици
+// unitMatrix();
+// translateMatrix(v)
+// scaleMatrix(v)
+// xRotateMatrix(a)
+// yRotateMatrix(a)
+// zRotateMatrix(a)
+// rotateMatrix(a,v)
+//
+// Трансформации със съставни матрици
+// identity()
+// translate(v)
+// scale(v)
+// xRotate(a)
+// yRotate(a)
+// zRotate(a)
+// useMatrix()
+// pushMatrix()
+// popMatrix()
+// cloneMatrix()
+//
+// Проектиране с матрици
+// viewMatrix (eye, focus, up)
+// orthoMatrix(width, height, near, far)
+// perspMatrix(angle, aspect, near, far)
+// lookAt(eye, focus, up)
+// perspective(angle, aspect, near, far)
+//
+
+
+var gl; // глобален WebGL контекст
+var glprog; // глобална GLSL програма
+var glmat; // глобална матрица на модела
+var glmatnew; // true, ако матрицата е променена, но не е подадена на шейдъра
+var glstack = []; // стек от матрици на модела
+
+
+// брой байтове в един WebGL FLOAT (трябва да са 4 байта)
+var FLOATS = Float32Array.BYTES_PER_ELEMENT;
+
+
+// връща WebGL контекст, свързан с HTML елемент с даден id
+function getContext(id)
+{
+ var canvas = document.getElementById(id);
+ if (!canvas)
+ {
+ alert("Искаме canvas с id=\""+id+"\", а няма!");
+ return null;
+ }
+
+ var context = canvas.getContext("webgl");
+ if (!context)
+ {
+ context = canvas.getContext("experimental-webgl");
+ }
+
+ if (!context)
+ {
+ alert("Искаме WebGL контекст, а няма!");
+ }
+
+ return context;
+}
+
+
+// връща компилиран шейдър
+function getShader(id,type)
+{
+ var source = document.getElementById(id).text;
+ var shader = gl.createShader(type);
+
+ gl.shaderSource(shader,source);
+ gl.compileShader(shader);
+ if (!gl.getShaderParameter(shader,gl.COMPILE_STATUS))
+ {
+ alert(gl.getShaderInfoLog(shader));
+ return null;
+ }
+
+ return shader;
+}
+
+
+// връща готова програма
+function getProgram(idv,idf)
+{
+ var vShader = getShader(idv,gl.VERTEX_SHADER);
+ var fShader = getShader(idf,gl.FRAGMENT_SHADER);
+
+ if (!vShader || !fShader) {return null;}
+
+ var shaderProgram = gl.createProgram();
+ gl.attachShader(shaderProgram,vShader);
+ gl.attachShader(shaderProgram,fShader);
+ gl.linkProgram(shaderProgram);
+
+ if (!gl.getProgramParameter(shaderProgram,gl.LINK_STATUS))
+ {
+ alert(gl.getProgramInfoLog(shaderProgram));
+ return null;
+ }
+
+ gl.useProgram(shaderProgram);
+ return shaderProgram;
+}
+
+
+// случайно дробно число в интервал
+function random(a,b)
+{
+ return a+(b-a)*Math.random();
+}
+
+
+// преобразува градуси в радиани
+function radians(degrees)
+{
+ return degrees*Math.PI/180;
+}
+
+
+// създава матрица за ортографска проекция
+function orthoMatrix(width, height, near, far)
+{
+ var matrix = [
+ 2.0/width, 0, 0, 0,
+ 0, 2.0/height, 0, 0,
+ 0, 0, 2.0/(near-far), 0,
+ 0, 0, (far+near)/(near-far), 1];
+ return new Float32Array(matrix);
+}
+
+
+// създава матрица за перспективна проекция
+// ъгълът на зрителното поле е в градуси
+function perspMatrix(angle, aspect, near, far)
+{
+ var fov = 1/Math.tan(radians(angle)/2);
+ var matrix = [
+ fov/aspect, 0, 0, 0,
+ 0, fov, 0, 0,
+ 0, 0, (far+near)/(near-far), -1,
+ 0, 0, 2.0*near*far/(near-far), 0];
+ return new Float32Array(matrix);
+}
+
+
+// установява перспективна проекция
+function perspective(angle,aspect,near,far)
+{
+ var proj = perspMatrix(angle,aspect,near,far);
+ gl.uniformMatrix4fv(uProjectionMatrix,false,proj);
+}
+
+
+// единичен вектор
+function unitVector(x)
+{
+ var len = 1/Math.sqrt( x[0]*x[0]+x[1]*x[1]+x[2]*x[2] );
+ return [ len*x[0], len*x[1], len*x[2] ];
+}
+
+
+// векторно произведение на два вектора
+function vectorProduct(x,y)
+{
+ return [
+ x[1]*y[2]-x[2]*y[1],
+ x[2]*y[0]-x[0]*y[2],
+ x[0]*y[1]-x[1]*y[0] ];
+}
+
+
+// скаларно произведение на два вектора
+function scalarProduct(x,y)
+{
+ return x[0]*y[0] + x[1]*y[1] + x[2]*y[2];
+}
+
+
+// вектор между две точки
+function vectorPoints(x,y)
+{
+ return [ x[0]-y[0], x[1]-y[1], x[2]-y[2] ];
+}
+
+
+// генерира матрица за гледна точка, параметрите са масиви с по 3 елемента
+function viewMatrix (eye, focus, up)
+{
+ // единичен вектор Z' по посоката на гледане
+ var z = unitVector(vectorPoints(eye,focus));
+
+ // единичен вектор X', перпендикулярен на Z' и на посоката нагоре
+ var x = unitVector(vectorProduct(up,z));
+
+ // единичен вектор Y', перпендикулярен на X' и Z'
+ var y = unitVector(vectorProduct(z,x));
+
+ // резултатът е тези три вектора + транслация
+ var matrix = [
+ x[0], y[0], z[0], 0,
+ x[1], y[1], z[1], 0,
+ x[2], y[2], z[2], 0,
+ -scalarProduct(x,eye),
+ -scalarProduct(y,eye),
+ -scalarProduct(z,eye), 1 ];
+ return new Float32Array(matrix);
+};
+
+
+// установява гледна точка
+function lookAt(eye,target,up)
+{
+ var view = viewMatrix(eye,target,up);
+ gl.uniformMatrix4fv(uViewMatrix,false,view);
+}
+
+
+// единична матрица
+function unitMatrix()
+{
+ var matrix = [
+ 1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1];
+ return new Float32Array(matrix);
+}
+
+// матрица за транслация по вектор V
+function translateMatrix(v)
+{
+ var matrix = [
+ 1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ v[0], v[1], v[2], 1];
+ return new Float32Array(matrix);
+}
+
+
+// матрица за мащабиране с вектор V
+function scaleMatrix(v)
+{
+ var matrix = [
+ v[0], 0, 0, 0,
+ 0, v[1], 0, 0,
+ 0, 0, v[2], 0,
+ 0, 0, 0, 1];
+ return new Float32Array(matrix);
+}
+
+
+// матрица за въртене от X към Y около Z на ъгъл A
+function zRotateMatrix(a)
+{
+ a = radians(a);
+ var c = Math.cos(a);
+ var s = Math.sin(a);
+ var matrix = [
+ c, s, 0, 0,
+ -s, c, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1];
+ return new Float32Array(matrix);
+}
+
+
+// матрица за въртене от Y към Z около X на ъгъл A
+function xRotateMatrix(a)
+{
+ a = radians(a);
+ var c = Math.cos(a);
+ var s = Math.sin(a);
+ var matrix = [
+ 1, 0, 0, 0,
+ 0, c, s, 0,
+ 0,-s, c, 0,
+ 0, 0, 0, 1];
+ return new Float32Array(matrix);
+}
+
+
+// матрица за въртене от X към Z около Y на ъгъл A
+function yRotateMatrix(a)
+{
+ a = radians(a);
+ var c = Math.cos(a);
+ var s = Math.sin(a);
+ var matrix = [
+ c, 0, s, 0,
+ 0, 1, 0, 0,
+ -s, 0, c, 0,
+ 0, 0, 0, 1];
+ return new Float32Array(matrix);
+}
+
+
+// матрица за въртене около вектор V на ъгъл A
+function rotateMatrix(a, v)
+{
+ a = radians(a);
+ v = unitVector(v);
+
+ var c = Math.cos(a);
+ var s = Math.sin(a);
+
+ var xx = v[0]*v[0]*(1-c);
+ var xy = v[0]*v[1]*(1-c);
+ var xz = v[0]*v[2]*(1-c);
+ var yy = v[1]*v[1]*(1-c);
+ var yz = v[1]*v[2]*(1-c);
+ var zz = v[2]*v[2]*(1-c);
+
+ var matrix = [
+ xx+c, xy-v[2]*s, xz+v[1]*s, 0,
+ xy+v[2]*s, yy+c, yz-v[0]*s, 0,
+ xz-v[1]*s, yz+v[0]*s, zz+c, 0,
+ 0, 0, 0, 1];
+ return new Float32Array(matrix);
+}
+
+
+// зарежда единичната матрица в матрицата на модела
+function identity()
+{
+ glmatnew = true;
+ glmat = new Float32Array( [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1] );
+}
+
+
+// добавя транслация към матрицата на модела
+function translate(v)
+{
+ glmatnew = true;
+ glmat[12] += glmat[0]*v[0]+glmat[4]*v[1]+glmat[8]*v[2];
+ glmat[13] += glmat[1]*v[0]+glmat[5]*v[1]+glmat[9]*v[2];
+ glmat[14] += glmat[2]*v[0]+glmat[6]*v[1]+glmat[10]*v[2];
+}
+
+
+// добавя мащабиране към матрицата на модела
+function scale(v)
+{
+ glmatnew = true;
+ glmat[0] *= v[0];
+ glmat[1] *= v[0];
+ glmat[2] *= v[0];
+
+ glmat[4] *= v[1];
+ glmat[5] *= v[1];
+ glmat[6] *= v[1];
+
+ glmat[8] *= v[2];
+ glmat[9] *= v[2];
+ glmat[10] *= v[2];
+}
+
+
+// ако матрицата на модела е променена, изпраща я към шейдъра
+function useMatrix()
+{
+ if (glmatnew)
+ {
+ glmatnew = false;
+ gl.uniformMatrix4fv(uModelMatrix,false,glmat);
+ }
+}
+
+
+// добавя въртене около X към матрицата на модела
+function xRotate(a)
+{
+ glmatnew = true;
+
+ a = radians(a);
+ var s = Math.sin(a);
+ var c = Math.cos(a);
+
+ a = glmat[4]*s+glmat[8]*c;
+ glmat[4]=glmat[4]*c-glmat[8]*s;
+ glmat[8]=a;
+
+ a = glmat[5]*s+glmat[9]*c;
+ glmat[5]=glmat[5]*c-glmat[9]*s;
+ glmat[9]=a;
+
+ a = glmat[6]*s+glmat[10]*c;
+ glmat[6]=glmat[6]*c-glmat[10]*s;
+ glmat[10]=a;
+}
+
+
+// добавя въртене около Y към матрицата на модела
+function yRotate(a)
+{
+ glmatnew = true;
+
+ a = radians(a);
+ var s = Math.sin(a);
+ var c = Math.cos(a);
+
+ a = glmat[0]*s+glmat[8]*c;
+ glmat[0]=glmat[0]*c-glmat[8]*s;
+ glmat[8]=a;
+
+ a = glmat[1]*s+glmat[9]*c;
+ glmat[1]=glmat[1]*c-glmat[9]*s;
+ glmat[9]=a;
+
+ a = glmat[2]*s+glmat[10]*c;
+ glmat[2]=glmat[2]*c-glmat[10]*s;
+ glmat[10]=a;
+}
+
+
+// добавя въртене около Z към матрицата на модела
+function zRotate(a)
+{
+ glmatnew = true;
+
+ a = radians(a);
+ var s = Math.sin(a);
+ var c = Math.cos(a);
+
+ a = glmat[0]*s+glmat[4]*c;
+ glmat[0]=glmat[0]*c-glmat[4]*s;
+ glmat[4]=a;
+
+ a = glmat[1]*s+glmat[5]*c;
+ glmat[1]=glmat[1]*c-glmat[5]*s;
+ glmat[5]=a;
+
+ a = glmat[2]*s+glmat[6]*c;
+ glmat[2]=glmat[2]*c-glmat[6]*s;
+ glmat[6]=a;
+}
+
+
+// добавя текущата матрица на модела в стека за матрици
+function pushMatrix()
+{
+ var mat = new Float32Array(glmat.length);
+ mat.set(glmat);
+ glstack.push(mat);
+}
+
+
+// извлича матрица на модела от стека за матрици
+// при празен стек връща единичната матрица
+function popMatrix()
+{
+ glmatnew = true;
+ if (glstack.length)
+ glmat = glstack.pop();
+ else
+ identity();
+}
+
+
+// клонира матрица като копира всичките ѝ стойности
+function cloneMatrix(a)
+{
+ var b = new Float32Array(a.length);
+ b.set(a);
+ return b;
+}
+
+