Summary Files Commits Branches @commit @diff @stats
path: root / Year 2 / Computer Graphics with WebGL / Project / skybox.js
blob: 5f5e010ba11af7f8b9d88ae8b9a4d41a101da6b6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// This code is ALMOST IDENTICAL as that for CanonicalCube and Cube from webgl-fmi.js
// The only difference is that in the CanonicalSkyboxCube, the normal vectors are reversed,
// since the camera will always stay inside the skybox.
// All cubes share a canonical cube instance, so I didn't want to mess with it, in case I add
// an actual cube in the scene later down the line.


CanonicalSkyboxCube = function() {
	// върхове
	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],0,0, v[1],n[0],1,0, v[4],n[0],0,1, // предна стена
			  v[4],n[0],0,1, v[1],n[0],1,0, v[5],n[0],1,1,
			  v[6],n[1],0,1, v[2],n[1],0,0, v[7],n[1],1,1, // задна стена
			  v[7],n[1],1,1, v[2],n[1],0,0, v[3],n[1],1,0, 
			  v[5],n[2],0,1, v[1],n[2],0,0, v[6],n[2],1,1, // дясна стена 
			  v[6],n[2],1,1, v[1],n[2],0,0, v[2],n[2],1,0, 
			  v[4],n[3],1,1, v[7],n[3],0,1, v[0],n[3],1,0, // лява стена 
			  v[0],n[3],1,0, v[7],n[3],0,1, v[3],n[3],0,0, 
			  v[4],n[4],0,0, v[5],n[4],1,0, v[7],n[4],0,1, // горна стена
			  v[7],n[4],0,1, v[5],n[4],1,0, v[6],n[4],1,1, 
			  v[0],n[5],0,0, v[3],n[5],0,1, v[1],n[5],1,0, // долна стена 
			  v[1],n[5],1,0, v[3],n[5],0,1, v[2],n[5],1,1 );
	// локална променлива за инстанцията с WebGL буфер
	var buf = gl.createBuffer();
	gl.bindBuffer(gl.ARRAY_BUFFER,buf);
	gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW);
	// запомняме буфера в текущата инстанция
	this.buf = buf;
}

// каноничен куб - метод за рисуване
CanonicalSkyboxCube.prototype.draw = function(texture) {
	// активираме буфера, създаден от конструктора
	gl.bindBuffer(gl.ARRAY_BUFFER,this.buf);
	// казваме къде са координатите
	gl.enableVertexAttribArray(aXYZ);
	gl.vertexAttribPointer(aXYZ,3,gl.FLOAT,false,8*FLOATS,0*FLOATS);
	// казваме къде са нормалите
	gl.enableVertexAttribArray(aNormal);
	gl.vertexAttribPointer(aNormal,3,gl.FLOAT,false,8*FLOATS,3*FLOATS);
	// казваме къде са текстурите
	if (gl.isTexture(texture))
	{
		gl.bindTexture(gl.TEXTURE_2D,texture);
		gl.enableVertexAttribArray(aST);
		gl.vertexAttribPointer(aST,2,gl.FLOAT,false,8*FLOATS,6*FLOATS);
	}
	else
	{
		if (texture) gl.disableVertexAttribArray(aST);
	}
	// рисуваме
	gl.drawArrays(gl.TRIANGLES,0,36);
}

var canonicalSkyboxCube;

// куб - конструктор с параметри център и размер
Skybox = function(size, color, texture) {
	// съхраняваме центъра и размера на куба
	this.size = size;
	this.color = (color === undefined) ? [1,0.75,0] : color;

	this.texture = texture; // неизвестна текстура
	this.texMatrix = new Float32Array([1,0,0,0,1,0,0,0,1]); // текстурна матрица

	// създаваме еднократно канонична инстанция
	if (!canonicalSkyboxCube)
		canonicalSkyboxCube = new CanonicalSkyboxCube();
}

// куб - рисуване
Skybox.prototype.draw = function() {
	pushMatrix(); // запомняме матрицата
		gl.vertexAttrib3fv(aColor,this.color); // подаваме цвета
		scale([this.size,this.size,this.size]); // и размера
		useMatrix();
		if (this.texture) gl.uniformMatrix3fv(uTexMatrix,false,this.texMatrix);
		canonicalSkyboxCube.draw(this.texture); // самото рисуване
	popMatrix(); // възстановяваме матрицата
}