? Browser Support ?
WebGL
>Vindmølle
Vindmølle
Du finner noen litt mer fancy framstillinger på sidene:
Geometrien i vidmølla er bygget opp av tre typer elementer: cone, skive, halvkule, der en cone er en sylinder med forskjellig diameter i de to endene. Vi kjenner disse grunnformene, untatt cone, fra de andre WGL-eksemplene i dette materialet. Det er heller ikke noe spesielt ved shaderprogrammene som skiller dem fra de andre eksemplene.
Shaderene er slik (merk at de er laget for textur, som ikke er brukt her):
_Fragmentshader
#ifdef GL_ES
precision mediump float;
#endif
varying vec3 vTransformedNormal;
varying vec4 vPosition;
// texture related
varying mediump vec2 vTextureCoord;
varying float vIsTextured;
uniform sampler2D uSampler;
uniform vec3 uMaterialAmbientColor;
uniform vec3 uMaterialDiffuseColor;
uniform vec3 uMaterialSpecularColor;
uniform float uMaterialShininess;
uniform vec3 uMaterialEmissiveColor;
uniform vec3 uAmbientLightingColor;
uniform vec3 uPointLightingDiffuseColor;
uniform vec3 uPointLightingSpecularColor;
uniform vec3 uPointLightingLocation;
void main(void) {
vec3 ambientLightWeighting = uAmbientLightingColor;
vec3 lightDirection = normalize(uPointLightingLocation - vPosition.xyz);
vec3 normal = normalize(vTransformedNormal);
vec3 specularLightWeighting = vec3(0.0, 0.0, 0.0);
vec3 eyeDirection = normalize(-vPosition.xyz);
vec3 reflectionDirection = reflect(-lightDirection, normal);
float specularLightBrightness =
pow(max(dot(reflectionDirection, eyeDirection), 0.0), uMaterialShininess);
specularLightWeighting = uPointLightingSpecularColor * specularLightBrightness;
float diffuseLightBrightness = max(dot(normal, lightDirection), 0.0);
vec3 diffuseLightWeighting = uPointLightingDiffuseColor * diffuseLightBrightness;
vec3 materialAmbientColor = uMaterialAmbientColor;
vec3 materialDiffuseColor = uMaterialDiffuseColor;
vec3 materialSpecularColor = uMaterialSpecularColor;
vec3 materialEmissiveColor = uMaterialEmissiveColor;
float alpha = 1.0;
gl_FragColor = vec4(
materialAmbientColor * ambientLightWeighting
+ materialDiffuseColor * diffuseLightWeighting
+ materialSpecularColor * specularLightWeighting
+ materialEmissiveColor,
alpha
);
}
_Vertexshader
attribute mediump vec3 aVertexNormal; // or in
attribute mediump vec3 aVertexPosition;
attribute mediump vec2 aTextureCoord;
uniform mediump mat4 uNormalMatrix;
uniform mediump mat4 uMVMatrix;
uniform mediump mat4 uPMatrix;
uniform float uIsTextured;
varying vec3 vTransformedNormal;
varying vec4 vPosition;
//varying lowp vec4 vColor;
//varying mediump vec3 vLighting;
varying float vIsTextured;
varying mediump vec2 vTextureCoord;
void main(void) {
vPosition = uMVMatrix * vec4(aVertexPosition, 1.0);
gl_Position = uPMatrix * vPosition;
vTransformedNormal=(uNormalMatrix * vec4(aVertexNormal, 1.0)).xyz;
vIsTextured=uIsTextured;
vTextureCoord = aTextureCoord;
}
Andre involverte javascript
_mainscript.js
//globals
var canvas;
var gl;
var shaderProgram;
var perspectiveMatrix;
// drawing precision on shape nets
var Precision=40;
//shapes
var aCone;
var aDisk;
var aCylinder;
var aHat;
var aTower;
var windMill;
// tower
var towerLength=18.0;
var towerRadiusBottom=2.0;
var towerRadiusFactor=0.5; // top is towerRadiusFactor of bottom
// house on top
var houseLength=4.0;
var houseRadius=1.2;
// wing rotation speed
var delta_wRot=2.0;
// mill rotations
var mRot=0.0;
//start
function start() {
canvas = document.getElementById("glcanvas");
initWebGL(canvas);
if (gl) {
gl.clearColor(1.0, 1.0, 1.0, 1.0);
gl.clearDepth(1.0);
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
initBuffers();
initShaders();
tick();
}
}
//eofstart
function tick() {
// using webgl-utils.js
requestAnimFrame(tick,canvas);
drawScene();
}
//initWebGL
function initWebGL() {
gl = null;
// browser and versions reckognize webgl differently ?
var names = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"];
for(var i = 0; i < names.length; i++){
try {gl = canvas.getContext("experimental-webgl");}
catch(e) {}
if(gl){break;}
}
if (!gl) {
alert("Unable to initialize WebGL. Your browser may not support it.");
}
}
//eofinitWebGL
//initBuffers
function initBuffers() {
// set up all shapes
aTower=new Cone(1.0,towerRadiusFactor,1.0,Precision);
aCone=new Cone(1.0,1.0,1.0,Precision);
aCylinder=new Cylinder(1.0,1.0,Precision);
aDisk=new Disk(1.0,Precision);
aHat=new Hat(1.0,Precision);
windMill=new WindMill();
}
//eofinitBuffers
//drawScene
function drawScene() {
gl.viewport(0, 0, canvas.width, canvas.height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
perspectiveMatrix = makePerspective(45, canvas.width / canvas.height, 0.1, 1000.0);
mvMatrix=makeIdentity();
setLight();
setWhiteMaterial();
// Move the drawing a bit from default eye-pos (0,0,0)
// overall rotation
mvTranslate([1.0, -5.0, -50.0]);
mvRotate(-90.0, [1, 0, 0]);
mvRotate(90.0, [0, 0, 1]);
mvTranslate([0.0, 0.0, -10.0]);
windMill.draw();
// speed
windMill.rotate(delta_wRot);
}
//eofdrawScene
//initShaders
function initShaders() {
var fragmentShader = getShader(gl, "shader-fs");
var vertexShader = getShader(gl, "shader-vs");
// Create the shader program
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
// ok?
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Unable to initialize the shader program.");
}
gl.useProgram(shaderProgram);
// let the shaderprogram remember the addresses
// so we can use when we fill the attribute buffers
shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
shaderProgram.vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal");
gl.enableVertexAttribArray(shaderProgram.vertexNormalAttribute);
// mark light and material
shaderProgram.materialAmbientColorUniform =
gl.getUniformLocation(shaderProgram, "uMaterialAmbientColor");
shaderProgram.materialDiffuseColorUniform =
gl.getUniformLocation(shaderProgram, "uMaterialDiffuseColor");
shaderProgram.materialSpecularColorUniform =
gl.getUniformLocation(shaderProgram, "uMaterialSpecularColor");
shaderProgram.materialShininessUniform =
gl.getUniformLocation(shaderProgram, "uMaterialShininess");
shaderProgram.materialEmissiveColorUniform =
gl.getUniformLocation(shaderProgram, "uMaterialEmissiveColor");
shaderProgram.showSpecularHighlightsUniform =
gl.getUniformLocation(shaderProgram, "uShowSpecularHighlights");
shaderProgram.ambientLightingColorUniform =
gl.getUniformLocation(shaderProgram, "uAmbientLightingColor");
shaderProgram.pointLightingLocationUniform =
gl.getUniformLocation(shaderProgram, "uPointLightingLocation");
shaderProgram.pointLightingDiffuseColorUniform =
gl.getUniformLocation(shaderProgram, "uPointLightingDiffuseColor");
shaderProgram.pointLightingSpecularColorUniform =
gl.getUniformLocation(shaderProgram, "uPointLightingSpecularColor");
}
//eofinitShaders
//getShader
function getShader(gl, id) {
var shaderScript = document.getElementById(id);
// ok?
if (!shaderScript) {
return null;
}
// Building the shader source string.
var theSource = "";
var currentChild = shaderScript.firstChild;
while(currentChild) {
if (currentChild.nodeType == 3) {
theSource += currentChild.textContent;
}
currentChild = currentChild.nextSibling;
}
// What type of shader, based on its MIME type.
var shader;
if (shaderScript.type == "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (shaderScript.type == "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else {
return null; // Unknown shader type
}
// Send the source to the shader object
gl.shaderSource(shader, theSource);
// Compile the shader program
gl.compileShader(shader);
// See if it compiled successfully
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert("An error occurred compiling the shaders: " + gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
//eofgetShader
//set light and color
function setLight()
{
gl.uniform3f(shaderProgram.pointLightingLocationUniform, 100.0, 50.0, 0.0);
gl.uniform3f(shaderProgram.ambientLightingColorUniform, 1.0, 1.0, 1.0);
gl.uniform3f(shaderProgram.pointLightingDiffuseColorUniform, 1.0, 1.0, 1.0);
gl.uniform3f(shaderProgram.pointLightingSpecularColorUniform, 1.0, 1.0, 1.0);
gl.uniform1i(shaderProgram.showSpecularHighlightsUniform, true);
}
function setWhiteMaterial()
{
// material: White rubber, modified
gl.uniform3f(shaderProgram.materialAmbientColorUniform, 0.3,0.3,0.3);
gl.uniform3f(shaderProgram.materialDiffuseColorUniform, 0.5,0.5,0.5);
gl.uniform3f(shaderProgram.materialSpecularColorUniform, 0.7,0.7,0.7);
gl.uniform1f(shaderProgram.materialShininessUniform, 30.0);
gl.uniform3f(shaderProgram.materialEmissiveColorUniform, 0.0, 0.0, 0.0);
}
//eofsetlightandcolor
//setMatrixUniforms
function setMatrixUniforms() {
// set all the transformation matrices (ModelView, perspective and normal
var pUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
gl.uniformMatrix4fv(pUniform, false, new Float32Array(perspectiveMatrix.flatten()));
var mvUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
gl.uniformMatrix4fv(mvUniform, false, new Float32Array(mvMatrix.flatten()));
var normalMatrix = mvMatrix.inverse();
normalMatrix = normalMatrix.transpose();
var nUniform = gl.getUniformLocation(shaderProgram, "uNormalMatrix");
gl.uniformMatrix4fv(nUniform, false, new Float32Array(normalMatrix.flatten()));
}
//eofsetMatrixUniforms
//requestFrame
//requestAnimationFrame in a cross browser way, from Googles webgl-lib
window.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
window.setTimeout(callback, 1000.0/60);
};
})();
//eofrequestFrame
_millshapes.js
//cone
function Cone(r1,r2,H,n)
{
// radius1, radius2, height, precision (both ways)
// produce a cone without ends
var vertices=[]; //each points coordinates
var normals=[]; //each points normal
var indices=[]; //each drawobjects index to points (Gl_TRIANGLE_STRIPS)
// calculate
var dw=2*Math.PI/(1.0*n);
var dh=H/(1.0*n);
var w=0.0;
var h=0.0;
var index=0;
// along the length
while(h < H)
{
w=0.0;
// round the cone
while(w < 2*Math.PI+0.001)
{
var R1=r1+(r2-r1)*(h/H);
var P1=[R1*Math.cos(w),R1*Math.sin(w),h];
var R2=r1+(r2-r1)*((h+dh)/H);
var P2=[R2*Math.cos(w),R2*Math.sin(w),h+dh];
var P3=[R1*Math.cos(w+dw),R1*Math.sin(w+dw),h];
var A=[P3[0]-P1[0],P3[1]-P1[1],P3[2]-P1[2]];
var B=[P2[0]-P1[0],P2[1]-P1[1],P2[2]-P1[2]];
// C=AxB=(a1b2-a2b1,a2b0-a0b2, a0b1-a1b0)
var N1=[A[1]*B[2]-A[2]*B[1],A[2]*B[0]-A[0]*B[2],A[0]*B[1]-A[1]*B[0]];
A=[P3[0]-P2[0],P3[1]-P2[1],P3[2]-P2[2]];
B=[B[0],B[1],B[2]];
var N2=[A[1]*B[2]-A[2]*B[1],A[2]*B[0]-A[0]*B[2],A[0]*B[1]-A[1]*B[0]];
vertices=vertices.concat(P1);
normals=normals.concat(N1);
indices=indices.concat(index++);
vertices=vertices.concat(P2);
normals=normals.concat(N2);
indices=indices.concat(index++);
w+=dw;
}
h+=dh;
}
// prepare buffers once and for all
this.verticesBuffer= gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
this.verticesNormalBuffer= gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesNormalBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normals), gl.STATIC_DRAW);
this.verticesIndexBuffer= gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.verticesIndexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
this.verticesIndexBuffer.COUNT=indices.length;
this.draw=function()
{
gl.bindBuffer(gl.ARRAY_BUFFER,this.verticesBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,3,gl.FLOAT,false,0,0);
// Set the normal attribute for the vertices.
gl.bindBuffer(gl.ARRAY_BUFFER,this.verticesNormalBuffer);
gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute,3,gl.FLOAT,false,0,0);
// Draw the cylinder.
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.verticesIndexBuffer);
gl.drawElements(gl.TRIANGLE_STRIP,this.verticesIndexBuffer.COUNT,gl.UNSIGNED_SHORT,0);
}
}
//eofcone
// cylinder
function Cylinder(R,H,n)
{
// produce a cylinder without ends
var vertices=[]; //each points coordinates
var normals=[]; //each points normal
var indices=[]; //each drawobjects index to points (Gl_TRIANGLE_STRIPS)
// calculate
var dw=2*Math.PI/(1.0*n);
var dh=H/(1.0*n);
var w=0.0;
var h=0.0;
var index=0;
// along the length
while(h < H+0.0001)
{
w=0.0;
// round the cylinder
while(w < 2*Math.PI+0.0001)
{
vertices=vertices.concat([R*Math.cos(w),R*Math.sin(w),h]);
normals=normals.concat([R*Math.cos(w),R*Math.sin(w),0]);
vertices=vertices.concat([R*Math.cos(w),R*Math.sin(w),h+dh]);
normals=normals.concat([R*Math.cos(w),R*Math.sin(w),0]);
indices=indices.concat(index++);
indices=indices.concat(index++);
w+=dw;
}
h+=dh;
}
// prepare buffers once and for all
this.verticesBuffer= gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
this.verticesNormalBuffer= gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesNormalBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normals), gl.STATIC_DRAW);
this.verticesIndexBuffer= gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.verticesIndexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
this.verticesIndexBuffer.COUNT=indices.length;
this.draw=function()
{
gl.bindBuffer(gl.ARRAY_BUFFER,this.verticesBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,3,gl.FLOAT,false,0,0);
// Set the normal attribute for the vertices.
gl.bindBuffer(gl.ARRAY_BUFFER,this.verticesNormalBuffer);
gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute,3,gl.FLOAT,false,0,0);
// Draw the cylinder.
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.verticesIndexBuffer);
gl.drawElements(gl.TRIANGLE_STRIP,this.verticesIndexBuffer.COUNT,gl.UNSIGNED_SHORT,0);
}
}
// eofcylinder
function Hat(R,n)
{
// produce a half sphere
var vertices=[]; //each points coordinates
var normals=[]; //each points normal
var indices=[]; //each drawobjects index to points (Gl_TRIANGLE_STRIPS)
// calculate
var dw=2*Math.PI/(1.0*n);
var dv=(0.5)*Math.PI/(1.0*n);
var w=0.0;
var index=0;
var v=0.0;
// outer loop
while(v < (0.5)*Math.PI+0.0001)
{
w=0.0;
// inner loop, round the hat
while(w < 2*Math.PI+0.0001)
{
vertices=vertices.concat([R*Math.sin(w)*Math.cos(v),
R*Math.cos(w)*Math.cos(v),
R*Math.sin(v)]);
normals=normals.concat( [R*Math.sin(w)*Math.cos(v),
R*Math.cos(w)*Math.cos(v),
R*Math.sin(v)]);
vertices=vertices.concat([R*Math.sin(w)*Math.cos(v+dv),
R*Math.cos(w)*Math.cos(v+dv),
R*Math.sin(v+dv)]);
normals=normals.concat( [R*Math.sin(w)*Math.cos(v+dv),
R*Math.cos(w)*Math.cos(v+dv),
R*Math.sin(v+dv)]);
indices=indices.concat(index++);
indices=indices.concat(index++);
w+=dw;
}
v+=dv;
}
// prepare buffers once and for all
this.verticesBuffer= gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
this.verticesNormalBuffer= gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesNormalBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normals), gl.STATIC_DRAW);
this.verticesIndexBuffer= gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.verticesIndexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
this.verticesIndexBuffer.COUNT=indices.length;
this.draw=function()
{
gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
// Set the normal attribute for the vertices.
gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesNormalBuffer);
gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute, 3, gl.FLOAT, false, 0, 0);
// Draw the hat.
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.verticesIndexBuffer);
gl.drawElements(gl.TRIANGLE_STRIP, this.verticesIndexBuffer.COUNT, gl.UNSIGNED_SHORT, 0);
}
}
function Disk(R,n)
{
// produce a simple disk
var vertices=[]; //each points coordinates
var normals=[]; //each points normal
var indices=[]; //each drawobjects index to points (Gl_TIANGLE_FAN)
var dw=2*Math.PI/(1.0*n);
var w=0.0;
var index=0;
vertices=vertices.concat([0.0,0.0,0.0]);
normals=normals.concat([0.0,0.0,-1.0]);
indices=indices.concat(index++);
while(w < 2*Math.PI+0.0001)
{
vertices=vertices.concat([R*Math.cos(w),R*Math.sin(w),0.0]);
normals=normals.concat([0.0,0.0,-1.0]);
indices=indices.concat(index++);
w+=dw;
}
// prepare buffers once and for all
this.verticesBuffer= gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
this.verticesNormalBuffer= gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesNormalBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normals), gl.STATIC_DRAW);
this.verticesIndexBuffer= gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.verticesIndexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
this.verticesIndexBuffer.COUNT=indices.length;
this.draw=function()
{
gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
// Set the normal attribute for the vertices.
gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesNormalBuffer);
gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute, 3, gl.FLOAT, false, 0, 0);
// Draw the disk.
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.verticesIndexBuffer);
gl.drawElements(gl.TRIANGLE_FAN, this.verticesIndexBuffer.COUNT, gl.UNSIGNED_SHORT, 0);
}
}
_windmill.js
function WindMill()
{
this.wRot=Math.random()*100;
this.rotate=function(r){
this.wRot=this.wRot+r*1.0;
}
this.draw=function()
{
//mvRotate(mRot,[0.0, 0.0, 1.0]);
// Draw the tower.
pushMatrix();
mvScale([towerRadiusBottom,towerRadiusBottom,towerLength]);
setMatrixUniforms();
aTower.draw();
pushMatrix();
mvRotate(180.0,[1.0, 0.0, 0.0]);
setMatrixUniforms();
aDisk.draw();
popMatrix();
popMatrix();
pushMatrix();
mvTranslate([0.0, 0.0, towerLength]);
mvScale([towerRadiusBottom*towerRadiusFactor,
towerRadiusBottom*towerRadiusFactor,
towerLength]);
setMatrixUniforms();
aDisk.draw();
popMatrix();
// Draw the house
// some adjustments are going on here
mvRotate(mRot,[0.0, 0.0, 1.0]);
mvTranslate([0.0, 0.0, towerLength]);
mvRotate(180.0,[1.0, 0.0, 1.0]);
mvTranslate([0.0, 0.0,-houseLength/4 ]);
mvScale([houseRadius,houseRadius,houseLength]);
setMatrixUniforms();
aCylinder.draw();
pushMatrix();
mvRotate(180.0,[1.0, 0.0, 0.0]);
setMatrixUniforms();
aHat.draw();
// draw wings
pushMatrix();
mvTranslate([0.0, 0.0,houseLength/6 ]);
mvRotate(this.wRot,[0.0, 0.0, 1.0]);
pushMatrix();
mvRotate(90.0,[1.0, 0.0, 0.0]);
mvScale([0.2,0.2,9.0]);
setMatrixUniforms();
aCylinder.draw();
mvScale([1.0,1.0,0.45]);
mvTranslate([0.0,0.0,2.1]);
setMatrixUniforms();
aHat.draw();
popMatrix();
mvRotate(120.0,[0.0, 0.0, 1.0]);
pushMatrix();
mvRotate(90.0,[1.0, 0.0, 0.0]);
mvScale([0.2,0.2,9.0]);
setMatrixUniforms();
aCylinder.draw();
mvScale([1.0,1.0,0.45]);
mvTranslate([0.0,0.0,2.1]);
setMatrixUniforms();
aHat.draw();
popMatrix();
mvRotate(120.0,[0.0, 0.0, 1.0]);
pushMatrix();
mvRotate(90.0,[1.0, 0.0, 0.0]);
mvScale([0.2,0.2,9.0]);
setMatrixUniforms();
aCylinder.draw();
mvScale([1.0,1.0,0.45]);
mvTranslate([0.0,0.0,2.1]);
setMatrixUniforms();
aHat.draw();
popMatrix();
// finnished wings
popMatrix();
// close the house end
mvTranslate([0.0, 0.0, -1]);// since it is scaled
setMatrixUniforms();
aDisk.draw();
// finnished house
popMatrix();
}
}