From ac8f5cfaa7a1752e7ba0e62aa40d4bc785e5be34 Mon Sep 17 00:00:00 2001 From: Syndamia Date: Tue, 25 Oct 2022 18:32:17 +0300 Subject: [WGL/P04] Solved exercises 2-5 --- .../03-Practice-24.10.2022/Problem 0302.html | 17 +- .../03-Practice-24.10.2022/Problem 0303.html | 103 ++++++ .../03-Practice-24.10.2022/Problem 0304.html | 100 ++++++ .../03-Practice-24.10.2022/Problem 0305.html | 126 ++++++++ .../03-Practice-24.10.2022/webgl-fmi.js | 360 ++++++++++++++++++++- 5 files changed, 696 insertions(+), 10 deletions(-) create mode 100644 Year 2/Computer Graphics with WebGL/03-Practice-24.10.2022/Problem 0303.html create mode 100644 Year 2/Computer Graphics with WebGL/03-Practice-24.10.2022/Problem 0304.html create mode 100644 Year 2/Computer Graphics with WebGL/03-Practice-24.10.2022/Problem 0305.html diff --git a/Year 2/Computer Graphics with WebGL/03-Practice-24.10.2022/Problem 0302.html b/Year 2/Computer Graphics with WebGL/03-Practice-24.10.2022/Problem 0302.html index 9d60b02..cffaab6 100644 --- a/Year 2/Computer Graphics with WebGL/03-Practice-24.10.2022/Problem 0302.html +++ b/Year 2/Computer Graphics with WebGL/03-Practice-24.10.2022/Problem 0302.html @@ -10,16 +10,16 @@ // отвън се подава само ъгъла attribute float aAngle; #define PI 3.14159 - #define TEETH 30.0 - #define RADIUS 0.8 - + #define eps 0.0001 + #define TEETH 35.0 + #define RADIUS 0.7 + #define TEETH_DEPTH 0.1 + #define LEDGE_MODIFIER 2.0 + void main () { - // тук трябва да се сметне точния радиус - float r = RADIUS - mod(aAngle, 2.0 * PI / TEETH) * 0.4; - float angle = aAngle; - if (r == RADIUS) angle -= 100.0; - if (angle < 0.0) angle = 0.0; // ugly + float r = RADIUS + mod(aAngle, 2.0 * PI / TEETH) / ((360.0 / TEETH - 1.0) * PI / 180.0) * TEETH_DEPTH;; + float angle = aAngle - LEDGE_MODIFIER * r; gl_Position = vec4(r*cos(angle)/1.5,r*sin(angle),0,1); } @@ -52,6 +52,7 @@ var data = [ ]; for(var i=0; i + + + + Зъбно колело + + + + + + + + + + + +

Зъбно колело

+ + + + + Искаме canvas, но няма! + + diff --git a/Year 2/Computer Graphics with WebGL/03-Practice-24.10.2022/Problem 0304.html b/Year 2/Computer Graphics with WebGL/03-Practice-24.10.2022/Problem 0304.html new file mode 100644 index 0000000..de68f89 --- /dev/null +++ b/Year 2/Computer Graphics with WebGL/03-Practice-24.10.2022/Problem 0304.html @@ -0,0 +1,100 @@ + + + + + Реотан + + + + + + + + + + + +

Реотан

+ + + + + Искаме canvas, но няма! + + diff --git a/Year 2/Computer Graphics with WebGL/03-Practice-24.10.2022/Problem 0305.html b/Year 2/Computer Graphics with WebGL/03-Practice-24.10.2022/Problem 0305.html new file mode 100644 index 0000000..c75901a --- /dev/null +++ b/Year 2/Computer Graphics with WebGL/03-Practice-24.10.2022/Problem 0305.html @@ -0,0 +1,126 @@ + + + + + Пирамида + + + + + + + + + + + +

Пирамида

+ + + + + Искаме canvas, но няма! + + diff --git a/Year 2/Computer Graphics with WebGL/03-Practice-24.10.2022/webgl-fmi.js b/Year 2/Computer Graphics with WebGL/03-Practice-24.10.2022/webgl-fmi.js index 62bfda8..0009854 100644 --- a/Year 2/Computer Graphics with WebGL/03-Practice-24.10.2022/webgl-fmi.js +++ b/Year 2/Computer Graphics with WebGL/03-Practice-24.10.2022/webgl-fmi.js @@ -1,10 +1,55 @@ - +// Библиотека WebGL-FMI v0.07.01 +// +// Работа с контексти и шейдъри +// 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() +// +// Проектиране с матрици +// viewMatrix (eye, focus, up) +// orthoMatrix(width, height, near, far) +// perspMatrix(angle, aspect, near, far) +// + + var gl; // глобален WebGL контекст var glprog; // глобална GLSL програма +var glmat; // глобална матрица на модела +var glmatnew; // true, ако матрицата е променена, но не е подадена на шейдъра + // брой байтове в един WebGL FLOAT (трябва да са 4 байта) var FLOATS = Float32Array.BYTES_PER_ELEMENT; + // връща WebGL контекст, свързан с HTML елемент с даден id function getContext(id) { @@ -29,6 +74,7 @@ function getContext(id) return context; } + // връща компилиран шейдър function getShader(id,type) { @@ -75,4 +121,314 @@ function getProgram(idv,idf) function random(a,b) { return a+(b-a)*Math.random(); -} \ No newline at end of file +} + + +// преобразува градуси в радиани +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 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 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; +} -- cgit v1.3.1-26-gb76a