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(); // възстановяваме матрицата
}
|