void GsMat::operator *= ( const GsMat& m ) { GsMat* t = (this==&m)? new GsMat(GsMat::NoInit) : this; t->setl1 ( E11*m.E11 + E12*m.E21 + E13*m.E31 + E14*m.E41, E11*m.E12 + E12*m.E22 + E13*m.E32 + E14*m.E42, E11*m.E13 + E12*m.E23 + E13*m.E33 + E14*m.E43, E11*m.E14 + E12*m.E24 + E13*m.E34 + E14*m.E44 ); t->setl2 ( E21*m.E11 + E22*m.E21 + E23*m.E31 + E24*m.E41, E21*m.E12 + E22*m.E22 + E23*m.E32 + E24*m.E42, E21*m.E13 + E22*m.E23 + E23*m.E33 + E24*m.E43, E21*m.E14 + E22*m.E24 + E23*m.E34 + E24*m.E44 ); t->setl3 ( E31*m.E11 + E32*m.E21 + E33*m.E31 + E34*m.E41, E31*m.E12 + E32*m.E22 + E33*m.E32 + E34*m.E42, E31*m.E13 + E32*m.E23 + E33*m.E33 + E34*m.E43, E31*m.E14 + E32*m.E24 + E33*m.E34 + E34*m.E44 ); t->setl4 ( E41*m.E11 + E42*m.E21 + E43*m.E31 + E44*m.E41, E41*m.E12 + E42*m.E22 + E43*m.E32 + E44*m.E42, E41*m.E13 + E42*m.E23 + E43*m.E33 + E44*m.E43, E41*m.E14 + E42*m.E24 + E43*m.E34 + E44*m.E44 ); if ( t!=this ) { *this=*t; delete t; } }
void GsMat::mult ( const GsMat& m1, const GsMat& m2 ) { GsMat* m = (this==&m1||this==&m2)? new GsMat(GsMat::NoInit) : this; m->setl1 ( m1.E11*m2.E11 + m1.E12*m2.E21 + m1.E13*m2.E31 + m1.E14*m2.E41, m1.E11*m2.E12 + m1.E12*m2.E22 + m1.E13*m2.E32 + m1.E14*m2.E42, m1.E11*m2.E13 + m1.E12*m2.E23 + m1.E13*m2.E33 + m1.E14*m2.E43, m1.E11*m2.E14 + m1.E12*m2.E24 + m1.E13*m2.E34 + m1.E14*m2.E44 ); m->setl2 ( m1.E21*m2.E11 + m1.E22*m2.E21 + m1.E23*m2.E31 + m1.E24*m2.E41, m1.E21*m2.E12 + m1.E22*m2.E22 + m1.E23*m2.E32 + m1.E24*m2.E42, m1.E21*m2.E13 + m1.E22*m2.E23 + m1.E23*m2.E33 + m1.E24*m2.E43, m1.E21*m2.E14 + m1.E22*m2.E24 + m1.E23*m2.E34 + m1.E24*m2.E44 ); m->setl3 ( m1.E31*m2.E11 + m1.E32*m2.E21 + m1.E33*m2.E31 + m1.E34*m2.E41, m1.E31*m2.E12 + m1.E32*m2.E22 + m1.E33*m2.E32 + m1.E34*m2.E42, m1.E31*m2.E13 + m1.E32*m2.E23 + m1.E33*m2.E33 + m1.E34*m2.E43, m1.E31*m2.E14 + m1.E32*m2.E24 + m1.E33*m2.E34 + m1.E34*m2.E44 ); m->setl4 ( m1.E41*m2.E11 + m1.E42*m2.E21 + m1.E43*m2.E31 + m1.E44*m2.E41, m1.E41*m2.E12 + m1.E42*m2.E22 + m1.E43*m2.E32 + m1.E44*m2.E42, m1.E41*m2.E13 + m1.E42*m2.E23 + m1.E43*m2.E33 + m1.E44*m2.E43, m1.E41*m2.E14 + m1.E42*m2.E24 + m1.E43*m2.E34 + m1.E44*m2.E44 ); if ( m!=this ) { *this=*m; delete m; } }
// here we will redraw the scene according to the current state of the application. void AppWindow::glutDisplay () { // Clear the rendering window glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // Build a cross with some lines (if not built yet): if ( _axis.changed ) // needs update { _axis.build(1.0f); // axis has radius 1.0 } if (sunanim) { sunx = 2 * (cos(2 * M_PI*sunxc / 360) + sin(2 * M_PI*sunxc / 360)); suny = 20.0f; sunz = 2 * (-sin(2 * M_PI*sunxz / 360) + cos(2 * M_PI*sunxz / 360)); } else { sunx = 0.0; suny = 1; sunz = -.5; } // Define our scene transformation: GsMat rx, ry, stransf, barrelroll, leftright, transf, updown, rightwing, leftwing, offsety, centerrwing, centerlwing, rl, rr, backR, backL, centerbackl, centerbackr, br, bl; GsMat rfrot, lfrot, rbrot, lbrot, rollyawpitch, ShadowT; rx.rotx ( _rotx ); ry.roty ( _roty ); stransf = rx*ry; // set the scene transformation matrix offsety.translation(GsVec(0.0f, -5.7f, 0.0f)); //Rotate many degrees barrelroll.rotz(2 * M_PI * rotate / 360); leftright.roty(2 * M_PI * _turnlr / 360); updown.rotx(2 * M_PI * _turnud / 360); rollyawpitch = leftright*updown*barrelroll; //Translate front wings to center centerrwing.translation(GsVec(-0.1f,-0.15f,0.0f)); centerlwing.translation(GsVec(0.1f, -0.15f, 0.0f)); //Translate front wings back to airplane rr.translation(GsVec(0.1f, 0.15f, 0.0f)); rl.translation(GsVec(-0.1f, 0.15f, 0.0f)); //Translate back wings to center centerbackl.translation(GsVec(-0.05f, -0.2f, 0.0f)); centerbackr.translation(GsVec(0.05f, -0.2f, 0.0f)); //Translate back wings to airplane bl.translation(GsVec(0.05f, 0.2f, 0.0f)); br.translation(GsVec(-0.05f, 0.2f, 0.0f)); //Rotate front wings rightwing.rotz(2 * M_PI * _wingsflyR / 360); leftwing.rotz(2 * M_PI * -_wingsflyL / 360); //Rotate back wings backR.rotz(2 * M_PI * _backR / 360); backL.rotz(2 * M_PI * -_backL / 360); //Clean up draw function rfrot = rr*rightwing*centerrwing; lfrot = rl*leftwing*centerlwing; rbrot = br*backR*centerbackr; lbrot = bl*backL*centerbackl; //speed is fast GsVec P = GsVec(0.0f, 0.0f, speed); GsVec bd = leftright*updown*barrelroll*P; R = R + bd; transf.setrans(R); GsVec sbd = leftright*P; SR = SR + sbd; ShadowT.setrans(SR); // Define our projection transformation: // (see demo program in gltutors-projection.7z, we are replicating the same behavior here) GsMat camview, camview2, _birdseye, persp, sproj; GsVec eye(0,0,0), center(0,0,0), up(0,1,0); GsVec eye2(0, 10, 0), center2(0, 0, 0), up2(0, 0, 1); eye += R + leftright*updown*barrelroll*GsVec(0,0,2); center += R + GsVec(0, 0, 0); _sun.build(1.0f, sunx, suny, sunz); float ground[4] = { 0, 1, 0, 4.99 }; float light[4] = { sunx, suny, sunz, 0 }; float dot; GsMat shadowMat; dot = ground[0] * light[0] + ground[1] * light[1] + ground[2] * light[2] + ground[3] * light[3]; shadowMat.setl1(dot - light[0] * ground[0], 0.0 - light[0] * ground[1], 0.0 - light[0] * ground[2], 0.0 - light[0] * ground[3]); shadowMat.setl2(0.0 - light[1] * ground[0], dot - light[1] * ground[1], 0.0 - light[1] * ground[2], 0.0 - light[1] * ground[3]); shadowMat.setl3(0.0 - light[2] * ground[0], 0.0 - light[2] * ground[1], dot - light[2] * ground[2], 0.0 - light[2] * ground[3]); shadowMat.setl4(0.0 - light[3] * ground[0], 0.0 - light[3] * ground[1], 0.0 - light[3] * ground[2], dot - light[3] * ground[3]); //shadowMat = shadowMat*ry*rx; camview.lookat ( eye, center, up ); // set our 4x4 "camera" matrix camview2.lookat(eye2, center2, up2); float aspect=1.0f, znear=0.1f, zfar=5000.0f; persp.perspective ( _fovy, aspect, znear, zfar ); // set our 4x4 perspective matrix // Our matrices are in "line-major" format, so vertices should be multiplied on the // right side of a matrix multiplication, therefore in the expression below camview will // affect the vertex before persp, because v' = (persp*camview)*v = (persp)*(camview*v). if (camera) { sproj = persp * camview; // set final scene projection } else { sproj = persp * camview2; } // Note however that when the shader receives a matrix it will store it in column-major // format, what will cause our values to be transposed, and we will then have in our // shaders vectors on the left side of a multiplication to a matrix. float col = 1; // Draw: //if ( _viewaxis ) _axis.draw ( stransf, sproj ); _model.draw(stransf*transf*rollyawpitch, sproj, _light, 0); _model2.draw(stransf*transf*rollyawpitch*rfrot, sproj, _light, 0); _model3.draw(stransf*transf*rollyawpitch*lfrot, sproj, _light, 0); _model4.draw(stransf*transf*rollyawpitch, sproj, _light, 0); _model5.draw(stransf*transf*rollyawpitch*rbrot, sproj, _light, 0); _model6.draw(stransf*transf*rollyawpitch*lbrot, sproj, _light, 0); _floor.draw(stransf, sproj, _light, textures); _city.draw(stransf*offsety, sproj, _light, 0); _city.draw(stransf*shadowMat*offsety, sproj, _shadow, 0); //Shadow _model.draw(stransf*ShadowT*shadowMat*rollyawpitch, sproj, _shadow, 1); _model2.draw(stransf*ShadowT*shadowMat*rollyawpitch, sproj, _shadow, 1); _model3.draw(stransf*ShadowT*shadowMat*rollyawpitch, sproj, _shadow, 1); _model4.draw(stransf*ShadowT*shadowMat*rollyawpitch, sproj, _shadow, 1); _model5.draw(stransf*ShadowT*shadowMat*rollyawpitch, sproj, _shadow, 1); _model6.draw(stransf*ShadowT*shadowMat*rollyawpitch, sproj, _shadow, 1); _side.draw(stransf, sproj, _light, col, textures); _sun.draw(stransf, sproj); // Swap buffers and draw: glFlush(); // flush the pipeline (usually not necessary) glutSwapBuffers(); // we were drawing to the back buffer, now bring it to the front }