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